/** * This function perform the reset sequence to the given devcfg interface by * configuring the appropriate control bits in the devcfg specifc registers * the devcfg reset squence involves the following steps * Disable all the interuupts * Clear the status * Update relevant config registers with reset values * Disbale the looopback mode and pcap rate enable * * @param BaseAddress of the interface * * @return N/A * * @note * This function will not modify the slcr registers that are relavant for * devcfg controller ******************************************************************************/ void XDcfg_ResetHw(u32 BaseAddr) { u32 Regval = 0; /* Mask the interrupts */ XDcfg_WriteReg(BaseAddr, XDCFG_INT_MASK_OFFSET, XDCFG_IXR_ALL_MASK); /* Clear the interuupt status */ Regval = XDcfg_ReadReg(BaseAddr, XDCFG_INT_STS_OFFSET); XDcfg_WriteReg(BaseAddr, XDCFG_INT_STS_OFFSET, Regval); /* Clear the source address register */ XDcfg_WriteReg(BaseAddr, XDCFG_DMA_SRC_ADDR_OFFSET, 0x0); /* Clear the destination address register */ XDcfg_WriteReg(BaseAddr, XDCFG_DMA_DEST_ADDR_OFFSET, 0x0); /* Clear the source length register */ XDcfg_WriteReg(BaseAddr, XDCFG_DMA_SRC_LEN_OFFSET, 0x0); /* Clear the destination length register */ XDcfg_WriteReg(BaseAddr, XDCFG_DMA_DEST_LEN_OFFSET, 0x0); /* Clear the loopback enable bit */ Regval = XDcfg_ReadReg(BaseAddr, XDCFG_MCTRL_OFFSET); Regval = Regval & ~XDCFG_MCTRL_PCAP_LPBK_MASK; XDcfg_WriteReg(BaseAddr, XDCFG_MCTRL_OFFSET, Regval); /*Reset the configuration register to reset value */ XDcfg_WriteReg(BaseAddr, XDCFG_CFG_OFFSET, XDCFG_CONFIG_RESET_VALUE); /*Disable the PCAP rate enable bit */ Regval = XDcfg_ReadReg(BaseAddr, XDCFG_CTRL_OFFSET); Regval = Regval & ~XDCFG_CTRL_PCAP_RATE_EN_MASK; XDcfg_WriteReg(BaseAddr, XDCFG_CTRL_OFFSET, Regval); }
/** * The interrupt handler for the Device Config Interface. * * Events are signaled to upper layer for proper handling. * * * @param InstancePtr is a pointer to the XDcfg instance. * * @return None. * * @note None. * ****************************************************************************/ void XDcfg_InterruptHandler(XDcfg *InstancePtr) { u32 IntrStatusReg; /* * Assert validates the input arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Read the Interrupt status register. */ IntrStatusReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_INT_STS_OFFSET); /* * Write the status back to clear the interrupts so that no * subsequent interrupts are missed while processing this interrupt. * This also does the DMA acknowledgment automatically. */ XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_INT_STS_OFFSET, IntrStatusReg); /* * Signal application that there are events to handle. */ InstancePtr->StatusHandler(InstancePtr->CallBackRef, IntrStatusReg); }
/** * * This function initiates the DMA transfer. * * @param InstancePtr is a pointer to the XDcfg instance. * @param SourcePtr contains a pointer to the source memory where the data * is to be transferred from. * @param SrcWordLength is the number of words (32 bit) to be transferred * for the source transfer. * @param DestPtr contains a pointer to the destination memory * where the data is to be transferred to. * @param DestWordLength is the number of words (32 bit) to be transferred * for the Destination transfer. * * @return None. * * @note It is the responsibility of the caller function to ensure that * correct values are passed to this function. * * The 2 LSBs of the SourcePtr (Source)/ DestPtr (Destination) * address when equal to 2’b01 indicates the last DMA command of * an overall transfer. * ****************************************************************************/ void XDcfg_InitiateDma(XDcfg *InstancePtr, u32 SourcePtr, u32 DestPtr, u32 SrcWordLength, u32 DestWordLength) { XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_DMA_SRC_ADDR_OFFSET, SourcePtr); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_DMA_DEST_ADDR_OFFSET, DestPtr); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_DMA_SRC_LEN_OFFSET, SrcWordLength); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_DMA_DEST_LEN_OFFSET, DestWordLength); }
/** * * The function sets the contents of the Status Register. * * @param InstancePtr is a pointer to the XDcfg instance. * @param Data is the 32 bit data to be written to the Register. * * @return None. * * @note None. * *****************************************************************************/ void XDcfg_SetStatusRegister(XDcfg *InstancePtr, u32 Data) { /* * Assert the arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_STATUS_OFFSET, Data); }
/** * * This function clears the specified interrupts in the Interrupt Status * Register. * * @param InstancePtr is a pointer to the XDcfg instance. * @param Mask is the bit-mask of the interrupts to be cleared. * Bit positions of 1 will be cleared. Bit positions of 0 will not * change the previous interrupt status. This mask is formed by * OR'ing XDCFG_INT_* bits which are defined in xdevcfg_hw.h. * * @return None. * * @note None. * *****************************************************************************/ void XDcfg_IntrClear(XDcfg *InstancePtr, u32 Mask) { /* * Assert the arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_INT_STS_OFFSET, Mask); }
/** * * The function sets the bit mask for the feature in Miscellaneous Control * Register. * * @param InstancePtr is a pointer to the XDcfg instance. * @param Mask is the bit-mask of the feature to be set. * * @return None. * * @note None * *****************************************************************************/ void XDcfg_SetMiscControlRegister(XDcfg *InstancePtr, u32 Mask) { u32 RegData; /* * Assert the arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); RegData = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET, (RegData | Mask)); }
/** * * The functions disables the PCAP interface by clearing the PCAP mode bit in * the control register. * * @param InstancePtr is a pointer to the XDcfg instance. * * @return None. * * @note None. * *****************************************************************************/ void XDcfg_DisablePCAP(XDcfg *InstancePtr) { u32 CtrlReg; /* * Assert the arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, (CtrlReg & ( ~XDCFG_CTRL_PCAP_MODE_MASK))); }
/** * * The function Clears the specified bit positions of the Control Register. * * @param InstancePtr is a pointer to the XDcfg instance. * @param Mask is the 32 bit value which holds the bit positions to be cleared. * * @return None. * * @note None. * *****************************************************************************/ void XDcfg_ClearControlRegister(XDcfg *InstancePtr, u32 Mask) { u32 CtrlReg; /* * Assert the arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, (CtrlReg & ~Mask)); }
static XDcfg *XDcfg_Initialize(u16 DeviceId) { u32 CtrlReg; u32 Status; XDcfg *Instance = malloc(sizeof *Instance); XDcfg_Config *Config = XDcfg_LookupConfig(DeviceId); Status = XDcfg_CfgInitialize(Instance, Config, Config->BaseAddr); if(Status != XST_SUCCESS){ print("Device configuration initialisation failed\n\r"); exit(0); } // Disable PCAP interface for partial reconfiguration XDcfg_DisablePCAP(Instance); CtrlReg = XDcfg_ReadReg(Instance->Config.BaseAddr,XDCFG_CTRL_OFFSET); XDcfg_WriteReg(Instance->Config.BaseAddr, XDCFG_CTRL_OFFSET,(CtrlReg & XDCFG_CTRL_ICAP_PR_MASK)); return Instance; }
/** * * This function enables the specified interrupts in the device. * * @param InstancePtr is a pointer to the XDcfg instance. * @param Mask is the bit-mask of the interrupts to be enabled. * Bit positions of 1 will be enabled. Bit positions of 0 will * keep the previous setting. This mask is formed by OR'ing * XDCFG_INT_* bits defined in xdevcfg_hw.h. * * @return None. * * @note None. * *****************************************************************************/ void XDcfg_IntrEnable(XDcfg *InstancePtr, u32 Mask) { u32 RegValue; /* * Assert the arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Enable the specified interrupts in the Interrupt Mask Register. */ RegValue = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_INT_MASK_OFFSET); RegValue &= ~(Mask & XDCFG_IXR_ALL_MASK); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_INT_MASK_OFFSET, RegValue); }
/** * * This function programs the Fabric for use. * * @param None * * @return None * - XST_SUCCESS if the Fabric initialization is successful * - XST_FAILURE if the Fabric initialization fails * @note None * ****************************************************************************/ void FabricInit(void) { u32 PcapReg; u32 PcapCtrlRegVal; u32 StatusReg; /* * Set Level Shifters DT618760 - PS to PL enabling */ Xil_Out32(PS_LVL_SHFTR_EN, LVL_PS_PL); fsbl_printf(DEBUG_INFO,"Level Shifter Value = 0x%x \r\n", Xil_In32(PS_LVL_SHFTR_EN)); /* * Get DEVCFG controller settings */ PcapReg = XDcfg_ReadReg(DcfgInstPtr->Config.BaseAddr, XDCFG_CTRL_OFFSET); /* * Setting PCFG_PROG_B signal to high */ XDcfg_WriteReg(DcfgInstPtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, (PcapReg | XDCFG_CTRL_PCFG_PROG_B_MASK)); /* * Check for AES source key */ PcapCtrlRegVal = XDcfg_GetControlRegister(DcfgInstPtr); if (PcapCtrlRegVal & XDCFG_CTRL_PCFG_AES_FUSE_MASK) { /* * 5msec delay */ usleep(5000); } /* * Setting PCFG_PROG_B signal to low */ XDcfg_WriteReg(DcfgInstPtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, (PcapReg & ~XDCFG_CTRL_PCFG_PROG_B_MASK)); /* * Check for AES source key */ if (PcapCtrlRegVal & XDCFG_CTRL_PCFG_AES_FUSE_MASK) { /* * 5msec delay */ usleep(5000); } /* * Polling the PCAP_INIT status for Reset */ while(XDcfg_GetStatusRegister(DcfgInstPtr) & XDCFG_STATUS_PCFG_INIT_MASK); /* * Setting PCFG_PROG_B signal to high */ XDcfg_WriteReg(DcfgInstPtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, (PcapReg | XDCFG_CTRL_PCFG_PROG_B_MASK)); /* * Polling the PCAP_INIT status for Set */ while(!(XDcfg_GetStatusRegister(DcfgInstPtr) & XDCFG_STATUS_PCFG_INIT_MASK)); /* * Get Device configuration status */ StatusReg = XDcfg_GetStatusRegister(DcfgInstPtr); fsbl_printf(DEBUG_INFO,"Devcfg Status register = 0x%x \r\n",StatusReg); fsbl_printf(DEBUG_INFO,"PCAP:Fabric is Initialized done\r\n"); }
/** * * This function starts the DMA transfer. This function only starts the * operation and returns before the operation may be completed. * If the interrupt is enabled, an interrupt will be generated when the * operation is completed, otherwise it is necessary to poll the Status register * to determine when it is completed. It is the responsibility of the caller to * determine when the operation is completed by handling the generated interrupt * or polling the Status Register. * * @param InstancePtr is a pointer to the XDcfg instance. * @param SourcePtr contains a pointer to the source memory where the data * is to be transferred from. * @param SrcWordLength is the number of words (32 bit) to be transferred * for the source transfer. * @param DestPtr contains a pointer to the destination memory * where the data is to be transferred to. * @param DestWordLength is the number of words (32 bit) to be transferred * for the Destination transfer. * @param TransferType contains the type of PCAP transfer being requested. * The definitions can be found in the xdevcfg.h file. * @return * - XST_SUCCESS.if DMA transfer initiated successfully * - XST_DEVICE_BUSY if DMA is busy * - XST_INVALID_PARAM if invalid Source / Destination address * is sent or an invalid Source / Destination length is * sent * * @note It is the responsibility of the caller to ensure that the cache * is flushed and invalidated both before the DMA operation is * started and after the DMA operation completes if the memory * pointed to is cached. The caller must also ensure that the * pointers contain physical address rather than a virtual address * if address translation is being used. * * The 2 LSBs of the SourcePtr (Source)/ DestPtr (Destination) * address when equal to 2’b01 indicates the last DMA command of * an overall transfer. * *****************************************************************************/ u32 XDcfg_Transfer(XDcfg *InstancePtr, void *SourcePtr, u32 SrcWordLength, void *DestPtr, u32 DestWordLength, u32 TransferType) { u32 CtrlReg; Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); if (XDcfg_IsDmaBusy(InstancePtr) == XST_SUCCESS) { return XST_DEVICE_BUSY; } /* * Check whether the fabric is in initialized state */ if ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_STATUS_OFFSET) & XDCFG_STATUS_PCFG_INIT_MASK) == 0) { /* * We don't need to check PCFG_INIT to be high for * non-encrypted loopback transfers. */ if (TransferType != XDCFG_CONCURRENT_NONSEC_READ_WRITE) { return XST_FAILURE; } } if ((TransferType == XDCFG_SECURE_PCAP_WRITE) || (TransferType == XDCFG_NON_SECURE_PCAP_WRITE)) { /* Check for valid source pointer and length */ if ((!SourcePtr) || (SrcWordLength == 0)) { return XST_INVALID_PARAM; } /* Clear internal PCAP loopback */ CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET, (CtrlReg & ~(XDCFG_MCTRL_PCAP_LPBK_MASK))); if (TransferType == XDCFG_NON_SECURE_PCAP_WRITE) { /* * Clear QUARTER_PCAP_RATE_EN bit * so that the PCAP data is transmitted every clock */ CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, (CtrlReg & ~XDCFG_CTRL_PCAP_RATE_EN_MASK)); } if (TransferType == XDCFG_SECURE_PCAP_WRITE) { /* * AES engine handles only 8 bit data every clock cycle. * Hence, Encrypted PCAP data which is 32 bit data can * only be sent in every 4 clock cycles. Set the control * register QUARTER_PCAP_RATE_EN bit to achieve this * operation. */ XDcfg_SetControlRegister(InstancePtr, XDCFG_CTRL_PCAP_RATE_EN_MASK); } XDcfg_InitiateDma(InstancePtr, (u32)SourcePtr, (u32)DestPtr, SrcWordLength, DestWordLength); } if (TransferType == XDCFG_PCAP_READBACK) { if ((!DestPtr) || (DestWordLength == 0)) { return XST_INVALID_PARAM; } /* Clear internal PCAP loopback */ CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET, (CtrlReg & ~(XDCFG_MCTRL_PCAP_LPBK_MASK))); /* * For PCAP readback of FPGA configuration register or memory, * the read command is first sent (written) to the FPGA fabric * which responds by returning the required read data. Read data * from the FPGA is captured if pcap_radata_v is active.A DMA * read transfer is required to obtain the readback command, * which is then sent to the FPGA, followed by a DMA write * transfer to support this mode of operation. */ return XDcfg_PcapReadback(InstancePtr, (u32)SourcePtr, SrcWordLength, (u32)DestPtr, DestWordLength); } if ((TransferType == XDCFG_CONCURRENT_SECURE_READ_WRITE) || (TransferType == XDCFG_CONCURRENT_NONSEC_READ_WRITE)) { if ((!SourcePtr) || (SrcWordLength == 0) || (!DestPtr) || (DestWordLength == 0)) { return XST_INVALID_PARAM; } if (TransferType == XDCFG_CONCURRENT_NONSEC_READ_WRITE) { /* Enable internal PCAP loopback */ CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET, (CtrlReg | XDCFG_MCTRL_PCAP_LPBK_MASK)); /* * Clear QUARTER_PCAP_RATE_EN bit * so that the PCAP data is transmitted every clock */ CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET, (CtrlReg & ~XDCFG_CTRL_PCAP_RATE_EN_MASK)); } if (TransferType == XDCFG_CONCURRENT_SECURE_READ_WRITE) { /* Clear internal PCAP loopback */ CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET); XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET, (CtrlReg & ~(XDCFG_MCTRL_PCAP_LPBK_MASK))); /* * Set the QUARTER_PCAP_RATE_EN bit * so that the PCAP data is transmitted every 4 clock * cycles, this is required for encrypted data. */ XDcfg_SetControlRegister(InstancePtr, XDCFG_CTRL_PCAP_RATE_EN_MASK); } XDcfg_InitiateDma(InstancePtr, (u32)SourcePtr, (u32)DestPtr, SrcWordLength, DestWordLength); } return XST_SUCCESS; }
int main (void) { XGpio sw, led; int i, pshb_check, sw_check; XGpioPs_Config*GpioConfigPtr; int xStatus; int iPinNumberEMIO = 54; u32 uPinDirectionEMIO = 0x0; u32 uPinDirection = 0x1; xil_printf("-- Start of the Program --\r\n"); // AXI GPIO switches Intialization XGpio_Initialize(&sw, XPAR_SWITCHES_DEVICE_ID); // AXI GPIO leds Intialization XGpio_Initialize(&led, XPAR_LEDS_DEVICE_ID); // PS GPIO Intialization GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID); if(GpioConfigPtr == NULL) return XST_FAILURE; xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr, GpioConfigPtr, GpioConfigPtr->BaseAddr); if(XST_SUCCESS != xStatus) print(" PS GPIO INIT FAILED \n\r"); //PS GPIO pin setting to Output XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber,uPinDirection); XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1); //EMIO PIN Setting to Input port XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumberEMIO,uPinDirectionEMIO); XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumberEMIO,0); xil_printf("-- Press BTNR (Zedboard) or BTN3 (Zybo) to see the LED light --\r\n"); xil_printf("-- Change slide switches to see corresponding output on LEDs --\r\n"); xil_printf("-- Set slide switches to 0x0F to exit the program --\r\n"); while (1) { sw_check = XGpio_DiscreteRead(&sw, 1); XGpio_DiscreteWrite(&led, 1, sw_check); pshb_check = XGpioPs_ReadPin(&psGpioInstancePtr,iPinNumberEMIO); XGpioPs_WritePin(&psGpioInstancePtr,iPinNumber,pshb_check); if((sw_check & 0x0f)==0x0F) break; for (i=0; i<9999999; i++); // delay loop } xil_printf("-- End of Program --\r\n"); #ifdef MULTIBOOT // Driver Instantiations XDcfg XDcfg_0; u32 MultiBootReg = 0; #define PS_RST_CTRL_REG (XPS_SYS_CTRL_BASEADDR + 0x200) #define PS_RST_MASK 0x1 /* PS software reset */ #define SLCR_UNLOCK_OFFSET 0x08 // Initialize Device Configuration Interface XDcfg_Config *Config = XDcfg_LookupConfig(XPAR_XDCFG_0_DEVICE_ID); XDcfg_CfgInitialize(&XDcfg_0, Config, Config->BaseAddr); MultiBootReg = 0; // Once done, boot the master image stored at 0xfc00_0000 Xil_Out32(0xF8000000 + SLCR_UNLOCK_OFFSET, 0xDF0DDF0D); // unlock SLCR XDcfg_WriteReg(XDcfg_0.Config.BaseAddr, XDCFG_MULTIBOOT_ADDR_OFFSET, MultiBootReg); // write to multiboot reg // synchronize __asm__( "dsb\n\t" "isb" ); Xil_Out32(PS_RST_CTRL_REG, PS_RST_MASK); #endif return 0; }