/** * * This function clears the specified pending interrupt. This function should be * called after the software has serviced the interrupts that are pending. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Pin is the pin number for which the interrupt status is to be * cleared. Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1. * * @note None. * *****************************************************************************/ void XGpioPs_IntrClearPin(XGpioPs *InstancePtr, int Pin) { u8 Bank; u8 PinNumber; u32 IntrReg; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM); /* * Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin(Pin, &Bank, &PinNumber); /* * Clear the specified pending interrupts. */ IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTSTS_OFFSET); IntrReg &= (1 << Pin); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTSTS_OFFSET, IntrReg); }
/** * * 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 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1. * @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, int Pin, int Direction) { u8 Bank; u8 PinNumber; u32 DirModeReg; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM); Xil_AssertVoid((Direction == 0) || (Direction == 1)); /* * Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin(Pin, &Bank, &PinNumber); DirModeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_DIRM_OFFSET); if (Direction) { /* Output Direction */ DirModeReg |= (1 << PinNumber); } else { /* Input Direction */ DirModeReg &= ~ (1 << PinNumber); } XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_DIRM_OFFSET, DirModeReg); }
/** * * 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 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1. * @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, int Pin, int OpEnable) { u8 Bank; u8 PinNumber; u32 OpEnableReg; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM); Xil_AssertVoid((OpEnable == 0) || (OpEnable == 1)); /* * Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin(Pin, &Bank, &PinNumber); OpEnableReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_OUTEN_OFFSET); if (OpEnable) { /* Enable Output Enable */ OpEnableReg |= (1 << PinNumber); } else { /* Disable Output Enable */ OpEnableReg &= ~ (1 << PinNumber); } XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_OUTEN_OFFSET, OpEnableReg); }
/** * * This function enables the interrupts for the specified pins in the specified * bank. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Bank is the bank number of the GPIO to operate on. * Valid values are 0 to XGPIOPS_MAX_BANKS - 1. * @param Mask is the bit mask of the pins for which interrupts are to * be enabled. Bit positions of 1 will be enabled. Bit positions * of 0 will keep the previous setting. * * @return None. * * @note None. * *****************************************************************************/ void XGpioPs_IntrEnable(XGpioPs *InstancePtr, u8 Bank, u32 Mask) { Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTEN_OFFSET, Mask); }
/** * * This function is used for setting the Interrupt Type, Interrupt Polarity and * Interrupt On Any for the specified GPIO Bank pins. * * @param InstancePtr is a pointer to an XGpioPs instance. * @param Bank is the bank number of the GPIO to operate on. * Valid values are 0 to XGPIOPS_MAX_BANKS - 1. * @param IntrType is the 32 bit mask of the interrupt type. * 0 means Level Sensitive and 1 means Edge Sensitive. * @param IntrPolarity is the 32 bit mask of the interrupt polarity. * 0 means Active Low or Falling Edge and 1 means Active High or * Rising Edge. * @param IntrOnAny is the 32 bit mask of the interrupt trigger for * edge triggered interrupts. 0 means trigger on single edge using * the configured interrupt polarity and 1 means trigger on both * edges. * * @return None. * * @note This function is used for setting the interrupt related * properties of all the pins in the specified bank. The previous * state of the pins is not maintained. * To change the Interrupt properties of a single GPIO pin, use the * function XGpioPs_SetPinIntrType(). * *****************************************************************************/ void XGpioPs_SetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 IntrType, u32 IntrPolarity, u32 IntrOnAny) { Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET, IntrType); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTPOL_OFFSET, IntrPolarity); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTANY_OFFSET, IntrOnAny); }
/** * * Set the Direction of the pins of the specified GPIO Bank. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Bank is the bank number of the GPIO to operate on. * Valid values are 0 to XGPIOPS_MAX_BANKS - 1. * @param Direction is the 32 bit mask of the Pin direction to be set for * all the pins in the Bank. Bits with 0 are set to Input mode, * bits with 1 are set to Output Mode. * * @return None. * * @note This function is used for setting the direction of all the pins * in the specified bank. The previous state of the pins is * not maintained. * *****************************************************************************/ void XGpioPs_SetDirection(XGpioPs *InstancePtr, u8 Bank, u32 Direction) { Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_DIRM_OFFSET, Direction); }
/** * * Write to the Data register of the specified GPIO bank. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Bank is the bank number of the GPIO to operate on. * Valid values are 0 to XGPIOPS_MAX_BANKS - 1. * @param Data is the value to be written to the Data register. * * @return None. * * @note This function is used for writing to all the GPIO pins of * the bank. The previous state of the pins is not maintained. * *****************************************************************************/ void XGpioPs_Write(XGpioPs *InstancePtr, u8 Bank, u32 Data) { Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_DATA_BANK_OFFSET) + XGPIOPS_DATA_OFFSET, Data); }
/* * * 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. * ******************************************************************************/ int XGpioPs_CfgInitialize(XGpioPs *InstancePtr, XGpioPs_Config *ConfigPtr, u32 EffectiveAddr) { Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(ConfigPtr != NULL); /* * Set some default values for instance data, don't indicate the device * is ready to use until everything has been initialized successfully. */ InstancePtr->IsReady = 0; InstancePtr->GpioConfig.BaseAddr = EffectiveAddr; InstancePtr->GpioConfig.DeviceId = ConfigPtr->DeviceId; InstancePtr->Handler = StubHandler; /* * By default, interrupts are not masked in GPIO. Disable * interrupts for all pins in all the 4 banks. */ XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFF); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((1) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFF); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((2) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFF); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((3) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFF); /* * Indicate the component is now ready to use. */ InstancePtr->IsReady = XIL_COMPONENT_IS_READY; return XST_SUCCESS; }
/** * * This function clears pending interrupt(s) with the provided mask. This * function should be called after the software has serviced the interrupts * that are pending. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Bank is the bank number of the GPIO to operate on. * Valid values are 0 to XGPIOPS_MAX_BANKS - 1. * @param Mask is the 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. * * @note None. * *****************************************************************************/ void XGpioPs_IntrClear(XGpioPs *InstancePtr, u8 Bank, u32 Mask) { Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS); /* * Clear the currently pending interrupts. */ XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTSTS_OFFSET, Mask); }
/** * * This function disables the interrupts for the specified pin. * * @param InstancePtr is a pointer to the XGpioPs instance. * @param Pin is the pin number for which the interrupt is to be disabled. * Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1. * * @return None. * * @note None. * *****************************************************************************/ void XGpioPs_IntrDisablePin(XGpioPs *InstancePtr, int Pin) { u8 Bank; u8 PinNumber; u32 IntrReg = 0; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM); /* * Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin(Pin, &Bank, &PinNumber); IntrReg = 1 << PinNumber; XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTDIS_OFFSET, IntrReg); }
/** * * 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 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1. * @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, int Pin, int Data) { u32 RegOffset; u32 Value; u8 Bank; u8 PinNumber; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM); /* * Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin(Pin, &Bank, &PinNumber); if (PinNumber > 15) { /* * There are only 16 data bits in bit maskable register. */ PinNumber -= 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. */ Data &= 0x01; Value = ~(1 << (PinNumber + 16)) & ((Data << PinNumber) | 0xFFFF0000); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_DATA_MASK_OFFSET) + RegOffset, Value); }
/** * * This function is used for setting the IRQ Type of a single GPIO pin. * * @param InstancePtr is a pointer to an XGpioPs instance. * @param Pin is the pin number whose IRQ type is to be set. * Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1. * @param IrqType is the IRQ type for GPIO Pin. Use XGPIOPS_IRQ_TYPE_* * defined in xgpiops.h to specify the IRQ type. * * @return None. * * @note None. * *****************************************************************************/ void XGpioPs_SetIntrTypePin(XGpioPs *InstancePtr, int Pin, u8 IrqType) { u32 IntrTypeReg; u32 IntrPolReg; u32 IntrOnAnyReg; u8 Bank; u8 PinNumber; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM); Xil_AssertVoid(IrqType <= XGPIOPS_IRQ_TYPE_LEVEL_LOW); /* * Get the Bank number and Pin number within the bank. */ XGpioPs_GetBankPin(Pin, &Bank, &PinNumber); IntrTypeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET); IntrPolReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTPOL_OFFSET); IntrOnAnyReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTANY_OFFSET); switch (IrqType) { case XGPIOPS_IRQ_TYPE_EDGE_RISING: IntrTypeReg |= (1 << PinNumber); IntrPolReg |= (1 << PinNumber); IntrOnAnyReg &= ~(1 << PinNumber); break; case XGPIOPS_IRQ_TYPE_EDGE_FALLING: IntrTypeReg |= (1 << PinNumber); IntrPolReg &= ~(1 << PinNumber); IntrOnAnyReg &= ~(1 << PinNumber); break; case XGPIOPS_IRQ_TYPE_EDGE_BOTH: IntrTypeReg |= (1 << PinNumber); IntrOnAnyReg |= (1 << PinNumber); break; case XGPIOPS_IRQ_TYPE_LEVEL_HIGH: IntrTypeReg &= ~(1 << PinNumber); IntrPolReg |= (1 << PinNumber); break; case XGPIOPS_IRQ_TYPE_LEVEL_LOW: IntrTypeReg &= ~(1 << PinNumber); IntrPolReg &= ~(1 << PinNumber); break; } XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET, IntrTypeReg); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTPOL_OFFSET, IntrPolReg); XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr, ((Bank) * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTANY_OFFSET, IntrOnAnyReg); }
/* * * This function resets the GPIO module by writing reset values to * all registers * * @param Base address of GPIO module * * @return None * * @note None. * ******************************************************************************/ void XGpioPs_ResetHw(u32 BaseAddress) { u32 BankCount; /* * Write reset values to all mask data registers */ for(BankCount = 2U; BankCount < (u32)XGPIOPS_MAX_BANKS; BankCount++) { XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_DATA_MASK_OFFSET) + XGPIOPS_DATA_LSW_OFFSET), 0x0U); XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_DATA_MASK_OFFSET) + XGPIOPS_DATA_MSW_OFFSET), 0x0U); } /* * Write reset values to all output data registers */ for(BankCount = 2U; BankCount < (u32)XGPIOPS_MAX_BANKS; BankCount++) { XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_DATA_BANK_OFFSET) + XGPIOPS_DATA_OFFSET), 0x0U); } /* * Reset all registers of all 4 banks */ for(BankCount = 0U; BankCount < (u32)XGPIOPS_MAX_BANKS; BankCount++) { XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_DIRM_OFFSET), 0x0U); XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_OUTEN_OFFSET), 0x0U); XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTMASK_OFFSET), 0x0U); XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTEN_OFFSET), 0x0U); XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTDIS_OFFSET), 0x0U); XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTSTS_OFFSET), 0x0U); XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTPOL_OFFSET), 0x0U); XGpioPs_WriteReg(BaseAddress, ((BankCount * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTANY_OFFSET), 0x0U); } /* * Bank 0 Int type */ XGpioPs_WriteReg(BaseAddress, XGPIOPS_INTTYPE_OFFSET, XGPIOPS_INTTYPE_BANK0_RESET); /* * Bank 1 Int type */ XGpioPs_WriteReg(BaseAddress, ((u32)XGPIOPS_REG_MASK_OFFSET + (u32)XGPIOPS_INTTYPE_OFFSET), XGPIOPS_INTTYPE_BANK1_RESET); /* * Bank 2 Int type */ XGpioPs_WriteReg(BaseAddress, (((u32)2 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET), XGPIOPS_INTTYPE_BANK2_RESET); /* * Bank 3 Int type */ XGpioPs_WriteReg(BaseAddress, (((u32)3 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET), XGPIOPS_INTTYPE_BANK3_RESET); }