11
当前的问题就是函数和寄存器不了解,慢慢来吧
/****************************************************************************/ /** * * Set the Output Enable of the specified pin. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Pin is the pin number to which the Data is to be written. * Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. * @param OpEnable specifies whether the Output Enable for the specified * pin should be enabled. * Valid values are 0 for Disabling Output Enable, * 1 for Enabling Output Enable. * * @return None. * * @note None. * *****************************************************************************/ void XGpioPs_SetOutputEnablePin(XGpioPs *InstancePtr, u32 Pin, u32 OpEnable) { u8 Bank; u8 PinNumber; u32 OpEnableReg; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); Xil_AssertVoid(OpEnable <= (u32)1); /* Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); OpEnableReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_OUTEN_OFFSET); if (OpEnable != (u32)0) { /* Enable Output Enable */ OpEnableReg |= ((u32)1 << (u32)PinNumber); } else { /* Disable Output Enable */ OpEnableReg &= ~ ((u32)1 << (u32)PinNumber); } XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_OUTEN_OFFSET, OpEnableReg); }
/****************************************************************************/ /** * * Set the Direction of the specified pin. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Pin is the pin number to which the Data is to be written. * Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. * @param Direction is the direction to be set for the specified pin. * Valid values are 0 for Input Direction, 1 for Output Direction. * * @return None. * *****************************************************************************/ void XGpioPs_SetDirectionPin(XGpioPs *InstancePtr, u32 Pin, u32 Direction) { u8 Bank; u8 PinNumber; u32 DirModeReg; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); Xil_AssertVoid(Direction <= (u32)1); /* Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); DirModeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_DIRM_OFFSET); if (Direction!=(u32)0) { /* Output Direction */ DirModeReg |= ((u32)1 << (u32)PinNumber); } else { /* Input Direction */ DirModeReg &= ~ ((u32)1 << (u32)PinNumber); } XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_DIRM_OFFSET, DirModeReg); }
/*****************************************************************************/ /* * * This function initializes a XGpioPs instance/driver. * All members of the XGpioPs instance structure are initialized and * StubHandlers are assigned to the Bank Status Handlers. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param ConfigPtr points to the XGpioPs device configuration structure. * @param EffectiveAddr is the device base address in the virtual memory * address space. If the address translation is not used then the * physical address should be passed. * Unexpected errors may occur if the address mapping is changed * after this function is invoked. * * @return XST_SUCCESS always. * * @note None. * ******************************************************************************/
s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, XGpioPs_Config *ConfigPtr, u32 EffectiveAddr) { s32 Status = XST_SUCCESS; u8 i; Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(ConfigPtr != NULL); Xil_AssertNonvoid(EffectiveAddr != (u32)0); /* * Set some default values for instance data, don't indicate the device * is ready to use until everything has been initialized successfully. */ InstancePtr->IsReady = 0U; InstancePtr->GpioConfig.BaseAddr = EffectiveAddr; InstancePtr->GpioConfig.DeviceId = ConfigPtr->DeviceId; InstancePtr->Handler = StubHandler; InstancePtr->Platform = XGetPlatform_Info(); /* Initialize the Bank data based on platform */ if (InstancePtr->Platform == XPLAT_ZYNQ_ULTRA_MP) { /* * Max pins in the ZynqMP GPIO device * 0 - 25, Bank 0 * 26 - 51, Bank 1 * 52 - 77, Bank 2 * 78 - 109, Bank 3 * 110 - 141, Bank 4 * 142 - 173, Bank 5 */ InstancePtr->MaxPinNum = (u32)174; InstancePtr->MaxBanks = (u8)6; } else { /* * Max pins in the GPIO device * 0 - 31, Bank 0 * 32 - 53, Bank 1 * 54 - 85, Bank 2 * 86 - 117, Bank 3 */ InstancePtr->MaxPinNum = (u32)118; InstancePtr->MaxBanks = (u8)4; } /* * By default, interrupts are not masked in GPIO. Disable * interrupts for all pins in all the 4 banks. */ for (i=0;i<InstancePtr->MaxBanks;i++) { XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((u32)(i) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU); } /* Indicate the component is now ready to use. */ InstancePtr->IsReady = XIL_COMPONENT_IS_READY; return Status; }
typedef struct { XGpioPs_Config GpioConfig; /**< Device configuration */ u32 IsReady; /**< Device is initialized and ready */ XGpioPs_Handler Handler; /**< Status handlers for all banks */ void *CallBackRef; /**< Callback ref for bank handlers */ u32 Platform; /**< Platform data */ u32 MaxPinNum; /**< Max pins in the GPIO device */ u8 MaxBanks; /**< Max banks in a GPIO device */ } XGpioPs;
/*****************************************************************************/ /** * * This function looks for the device configuration based on the unique device * ID. The table XGpioPs_ConfigTable[] contains the configuration information * for each device in the system. * * @param DeviceId is the unique device ID of the device being looked up. * * @return A pointer to the configuration table entry corresponding to the * given device ID, or NULL if no match is found. * * @note None. * ******************************************************************************/
XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId) { XGpioPs_Config *CfgPtr = NULL; u32 Index; for (Index = 0U; Index < (u32)XPAR_XGPIOPS_NUM_INSTANCES; Index++) { if (XGpioPs_ConfigTable[Index].DeviceId == DeviceId) { CfgPtr = &XGpioPs_ConfigTable[Index]; break; } } return (XGpioPs_Config *)CfgPtr; }
#include "xparameters.h" #include "xgpiops.h" int main(void){ static XGpioPs psGpioInstancePtr; XGpioPs_Config *GpioConfigPtr; int xStatus; GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);//根据唯一的设备号ID号DEVICEID,该函数查找设备配置,根据DECICEID号,该函数返回一个配置表入口
/*
配置表应该是这部分
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddr; /**< Register base address */
} XGpioPs_Config;
*/
if(GpioConfigPtr == NULL) return XST_FAILURE; xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr,GpioConfigPtr->BaseAddr);//初始化GPIO实例成员 if(XST_SUCCESS != xStatus) print(" PS GPIO INIT FAILED \n\r"); XGpioPs_SetDirectionPin(&psGpioInstancePtr, 51,1);//设置51引脚 XGpioPs_SetDirectionPin(&psGpioInstancePtr, 50,0);//设置50引脚 XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 51,1);//设置51引脚输出使能 while(1){ if(XGpioPs_ReadPin(&psGpioInstancePtr,50)==1){//从50引脚读取 XGpioPs_WritePin(&psGpioInstancePtr,51,1);//该函数向指定引脚写数据 } else{ XGpioPs_WritePin(&psGpioInstancePtr,51,0); } } return 0; }
关于GPIO的读写
/****************************************************************************/ /** * * Write data to the specified pin. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Pin is the pin number to which the Data is to be written. * Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. * @param Data is the data to be written to the specified pin (0 or 1). * * @return None. * * @note This function does a masked write to the specified pin of * the specified GPIO bank. The previous state of other pins * is maintained. * *****************************************************************************/ void XGpioPs_WritePin(XGpioPs *InstancePtr, u32 Pin, u32 Data) { u32 RegOffset; u32 Value; u8 Bank; u8 PinNumber; u32 DataVar = Data; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Pin < InstancePtr->MaxPinNum); /* Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); if (PinNumber > 15U) { /* There are only 16 data bits in bit maskable register. */ PinNumber -= (u8)16; RegOffset = XGPIOPS_DATA_MSW_OFFSET; } else { RegOffset = XGPIOPS_DATA_LSW_OFFSET; } /* * Get the 32 bit value to be written to the Mask/Data register where * the upper 16 bits is the mask and lower 16 bits is the data. */ DataVar &= (u32)0x01; Value = ~((u32)1 << (PinNumber + 16U)) & ((DataVar << PinNumber) | 0xFFFF0000U); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((u32)(Bank) * XGPIOPS_DATA_MASK_OFFSET) + RegOffset, Value); }
/****************************************************************************/ /** * * Read Data from the specified pin. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Pin is the pin number for which the data has to be read. * Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP. * See xgpiops.h for the mapping of the pin numbers in the banks. * * @return Current value of the Pin (0 or 1). * * @note This function is used for reading the state of the specified * GPIO pin. * *****************************************************************************/ u32 XGpioPs_ReadPin(XGpioPs *InstancePtr, u32 Pin) { u8 Bank; u8 PinNumber; Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum); /* Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber); return (XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, ((u32)(Bank) * XGPIOPS_DATA_BANK_OFFSET) + XGPIOPS_DATA_RO_OFFSET) >> (u32)PinNumber) & (u32)1; }