#include #include "global_types.h" #include "cgpio_HW.h" #include "cgpio.h" #include "intc_list.h" #include "intc.h" #include "diag_API.h" #include "platform.h" #include "utilities.h" #include "bsp.h" #include "quec_cust_feature.h" /* MFPR Fragments */ #define GPIO_MFPR_BASE1 0xD401E0DC #define GPIO_MFPR_BASE2 0xD401E1A0 #define GPIO_MFPR_BASE3 0xD401E304 #define GPIO_MFPR_BASE4 0xD401E1B8 #define GPIO_MFPR_BASE5 0xD401E1E0 #define GPIO_MFPR_BASE6 0xD401E0C8 #define GPIO_MFPR_BASE7 0xD401E2EC #define GPIO_MFPR_BASE8 0xD401E2E4 #define GPIO_MFPR_BASE9 0xD401E2BC #define GPIO_MFPR_BASE10 0xD401E32C #define GPIO_MFPR_BASE11 0xD401E094 #define GPIO_MFPR_BASE12 0xD401E2F0 #define GPIO_MFPR_BASE13 0xD401E0B4 #define GPIO_MFPR_BASE14 0xD401E2DC #define GPIO_MFPR_BASE15 0xD401E19C #define GPIO_MFPR_BASE16 0xD401E260 #define GPIO_MFPR_BASE17 0xD401E320 #define GPIO_MFPR_BASE18 0xD401E2C4 #define GPIO_MFPR_BASE19 0xD401E0CC #define GPIO_MFPR_BASE20 0xD401E054 #define GPIO_MFPR_BASE21 0xD401E1CC #define GPIO_MFPR_BASE22 0xD401E2B8 #define GPIO_MFPR_BASE23 0xD401E1BC #define GPIO_MFPR_BASE24 0xD401E0AC #define INVALID_GPIO_MFPR_ADDR 0xFFFFFFFF UINT32 GPIO_MFPR_ADDR(UINT32 n) { if(CHIP_IS_CRANEL){ return ( n <= 36 ? GPIO_MFPR_BASE1 + (n << 2): \ ((n ==37)) ? GPIO_MFPR_BASE21: \ ((n <= 47) &&(n >=45)) ? GPIO_MFPR_BASE16 + ((n-45) << 2): \ ((n <= 54) &&(n >=49)) ? GPIO_MFPR_BASE2 + ((n-49) << 2): \ ((n == 55))? 0xD401E0C8: \ ((n == 56))? 0xD401E32C: \ ((n == 57))? 0xD401E0D0: \ ((n <= 66)&&(n >=60) ) ? GPIO_MFPR_BASE3 + ((n-60) << 2): \ ((n <= 70)&&(n >=68) ) ? GPIO_MFPR_BASE22 + ((n-68) << 2): \ ((n <= 74)&&(n>=71)) ? GPIO_MFPR_BASE23 + ((n-71)<<2): \ ((n <= 80)&&(n>=78)) ? 0xD401E2E0 + ((n-78)<<2): \ ((n <= 94)&&(n>=81)) ? 0xD401E254 + ((n-81)<<2): \ ((n == 85))? 0xD401E0D4: \ ((n <=120)&&(n >= 117))? 0xD401E0B4+((n-117)<<2): \ ((n == 121))? GPIO_MFPR_BASE10: \ ((n <= 126)&&(n >= 122))? GPIO_MFPR_BASE6+((n-122) << 2) : \ ((n == 122))? GPIO_MFPR_BASE6: \ ((n == 124))? 0xD401E0D0: \ ((n == 126))? 0xD401E0D8: \ ((n == 77))? 0xD401E2DC: \ INVALID_GPIO_MFPR_ADDR); } else if(CHIP_IS_CRANELS){ return ( n <= 36 ? GPIO_MFPR_BASE1 + (n << 2): \ ((n ==37)) ? GPIO_MFPR_BASE21: \ ((n <= 47) &&(n >=45)) ? GPIO_MFPR_BASE16 + ((n-45) << 2): \ ((n <= 54) &&(n >=49)) ? GPIO_MFPR_BASE2 + ((n-49) << 2): \ ((n == 55))? 0xD491E0B4: \ ((n == 56))? 0xD401E0B8: \ ((n == 57))? 0xD401E0bc: \ ((n == 58))? 0xD401E0C0: \ ((n == 59))? 0xD401E0CC: \ ((n <= 66)&&(n >=60) ) ? GPIO_MFPR_BASE3 + ((n-60) << 2): \ ((n <= 70)&&(n >=68) ) ? 0xD401E2B8 + ((n-68) << 2): \ ((n <= 76)&&(n>=71)) ? 0xD401E1BC + ((n-71)<<2): \ ((n == 77))? 0xD401E0D8: \ ((n == 78))? 0xD401E0D4: \ ((n <= 80)&&(n>=78)) ? 0xD401E2E0 + ((n-78)<<2): \ ((n <= 88)&&(n>=81)) ? 0xD401E054 + ((n-81)<<2): \ ((n <= 94)&&(n>=89)) ? 0xD401E074 + ((n-89)<<2): \ ((n <=120)&&(n >= 117))? 0xD401E0B4+((n-117)<<2): \ ((n == 121))? 0xD401E32C: \ ((n <= 126)&&(n >= 122))? GPIO_MFPR_BASE6+((n-122) << 2) : \ ((n == 122))? GPIO_MFPR_BASE6: \ ((n == 124))? 0xD401E0D0: \ ((n == 126))? 0xD401E0D8: \ INVALID_GPIO_MFPR_ADDR); } else if(CHIP_IS_CRANELR || CHIP_IS_CRANELRH){ return ( n <= 15 ? GPIO_MFPR_BASE1 + (n << 2): \ ((n <= 36)&&(n >= 33)) ? 0xD401E160 + ((n-33) << 2): \ ((n == 37)) ? 0xD401E1CC: \ ((n <= 54)&&(n >= 49)) ? GPIO_MFPR_BASE2 + ((n-49) << 2): \ ((n == 55)) ? 0xD401E0C8: \ ((n == 56)) ? 0xD401E32C: \ ((n == 57)) ? 0xD401E0D0: \ ((n <= 66)&&(n >= 60)) ? GPIO_MFPR_BASE3 + ((n-60) << 2): \ ((n == 67)) ? 0xD401E12C: \ ((n <= 70)&&(n >= 68)) ? 0xD401E2B8 + ((n-68) << 2): \ ((n <= 74)&&(n >= 71)) ? 0xD401E1BC + ((n-71)<<2): \ ((n <= 80)&&(n >= 79)) ? 0xD401E2E4 + ((n-79)<<2): \ ((n == 84)) ? 0xD401E0CC: \ ((n <= 86)&&(n >= 85)) ? 0xD401E0D4 + ((n-85)<<2): \ ((n <= 90)&&(n >= 87)) ? 0xD401E0B4 + ((n-87)<<2): \ INVALID_GPIO_MFPR_ADDR); } else if(CHIP_IS_CRANELG){ return ( ((n <= 9)&&(n >= 4)) ? GPIO_MFPR_BASE1 + (n << 2): \ ((n <= 36)&&(n >= 33)) ? 0xD401E160 + ((n-33) << 2): \ ((n == 37)) ? GPIO_MFPR_BASE21: \ ((n <= 52)&&(n >= 49)) ? GPIO_MFPR_BASE2 + ((n-49) << 2): \ ((n == 55)) ? GPIO_MFPR_BASE6: \ ((n == 56)) ? GPIO_MFPR_BASE10: \ ((n == 57)) ? 0xD401E0D0: \ ((n <= 66)&&(n >= 61)) ? GPIO_MFPR_BASE3 + ((n-60) << 2): \ ((n <= 70)&&(n >= 69)) ? GPIO_MFPR_BASE22 + ((n-68) << 2): \ ((n <= 74)&&(n >= 71)) ? GPIO_MFPR_BASE23 + ((n-71)<<2): \ ((n <= 80)&&(n >= 79)) ? GPIO_MFPR_BASE8 + ((n-79)<<2): \ ((n == 85)) ? 0xD401E0D4: \ ((n == 87)) ? 0xD401E0B4: \ ((n <= 90)&&(n >= 89)) ? 0xD401E0BC + ((n-89)<<2): \ INVALID_GPIO_MFPR_ADDR); } else{ return ((CHIP_IS_CRANEM)? \ ( n <= 36 ? GPIO_MFPR_BASE1 + (n << 2): \ ((n <= 47) &&(n >=45)) ? GPIO_MFPR_BASE16 + ((n-45) << 2): \ ((n <= 54) &&(n >=49)) ? GPIO_MFPR_BASE2 + ((n-49) << 2): \ ((n <= 66)&&(n >=60) ) ? GPIO_MFPR_BASE3 + ((n-60) << 2): \ ((n <= 76)&&(n>=71)) ? GPIO_MFPR_BASE18 + ((n-71)<<2): \ (n == 85) ? 0xD401E0C4: \ ((n <= 126)&&(n >= 122))? GPIO_MFPR_BASE6+((n-122) << 2) : \ ((n <= 120)&&(n >=117) ) ? GPIO_MFPR_BASE13 + ((n-117) << 2): \ (n == 121 )? GPIO_MFPR_BASE10 : \ ((n <= 80)&&(n >=79)) ? GPIO_MFPR_BASE8 + ((n-79)<<2) : \ ((n <= 70)&&(n >=69)) ? GPIO_MFPR_BASE9 + ((n-69)<<2) : \ ((n <= 78)&&(n>=77)) ? GPIO_MFPR_BASE14 + ((n-77)<<2): \ INVALID_GPIO_MFPR_ADDR): \ ( n <= 36 ? GPIO_MFPR_BASE1 + (n << 2): \ ((n <= 43) &&(n >=37)) ? GPIO_MFPR_BASE11 + ((n-37) << 2): \ ((n <= 47) &&(n >=45)) ? GPIO_MFPR_BASE16 + ((n-45) << 2): \ ((n <= 54) &&(n >=49)) ? GPIO_MFPR_BASE2 + ((n-49) << 2): \ ((n <= 66)&&(n >=60) ) ? GPIO_MFPR_BASE3 + ((n-60) << 2): \ ((n <= 78)&&(n>=71)) ? GPIO_MFPR_BASE4 + ((n-71)<<2): \ ((n <= 86)&&(n>=81) ) ? GPIO_MFPR_BASE5 + ((n-81) << 2): \ ((n <= 126)&&(n >= 122))? GPIO_MFPR_BASE6+((n-122) << 2) : \ (n == 48 )? GPIO_MFPR_BASE7 : \ ((n <= 59)&&(n >=55) ) ? GPIO_MFPR_BASE12 + ((n-55) << 2): \ ((n <= 120)&&(n >=117) ) ? GPIO_MFPR_BASE13 + ((n-117) << 2): \ (n == 121 )? GPIO_MFPR_BASE10 : \ ((n <= 80)&&(n >=79)) ? GPIO_MFPR_BASE8 + ((n-79)<<2) : \ ((n <= 70)&&(n >=69)) ? GPIO_MFPR_BASE9 + ((n-69)<<2) : \ INVALID_GPIO_MFPR_ADDR)); } } typedef struct { BOOL IntcEnabled; BOOL WuEnabled; GPIOCallback ISR; GPIOCallback WU; }GPIO_Port_Handler; #define GPIO_CHECK_VALID_CALLBACK(p) if(p == NULL) \ return GPIORC_NULL_POINTER #define GPIO_CHECK_VALID_HANDLE(p) if(p>=GPIO_MAX_PORT_HANDLERS ) \ return GPIORC_INVALID_PIN_NUM #define GPIO_CHECK_VALID_VALUE(p) if((p!=0) && (p!=1)) \ return GPIORC_INCORRECT_INIT_VALUE #define GPIO_CHECK_VALID_DIRECTION(p) if((p!=GPIO_IN_PIN) && (p!=GPIO_OUT_PIN)) \ return GPIORC_INCORRECT_DIRECTION #define GPIO_CHECK_VALID_TRANSITION(p) if((p!=GPIO_RISE_EDGE) && (p !=GPIO_FALL_EDGE) && (p!=GPIO_TWO_EDGE)) \ return GPIORC_INCORRECT_TRANSITION_TYPE #define GPIO_CHECK_VALID_PULL(p) if((p!=GPIO_PULL_DISABLE ) && (p!=GPIO_PULLUP_ENABLE) && (p!=GPIO_PULLDN_ENABLE)) \ return GPIORC_INCORRECT_PULL static UINT32 GPIORegisterBase[GPIO_REGISTER_GROUPS] = { GPIO_GROUP_BASE1, GPIO_GROUP_BASE2, GPIO_GROUP_BASE3, GPIO_GROUP_BASE4}; static GPIO_Port_Handler GPIOPortHandler[GPIO_MAX_PORT_HANDLERS]; static UINT32 *GetBaseAddr(UINT32 portHandle) { UINT32 base_addr; if(portHandle < VSPI_GPIO_32) base_addr = GPIO_REGISTER_BASE + GPIORegisterBase[0]; else if(portHandle < VSPI_GPIO_64) base_addr = GPIO_REGISTER_BASE + GPIORegisterBase[1]; else if(portHandle < VSPI_GPIO_96) base_addr = GPIO_REGISTER_BASE + GPIORegisterBase[2]; else if(portHandle <= VSPI_GPIO_MAX) base_addr = GPIO_REGISTER_BASE + GPIORegisterBase[3]; else base_addr = 0; return (UINT32 *)base_addr; } /*********************************************************************** * Function: GpioSetLevel * ************************************************************************ * Description: Writes a value to a port * * * * Parameters: portHandle - the port handle * * value - the value to be written * * * * Return value: GPIORC_OK * * GPIORC_INVALID_PORT_HANDLE * GPIORC_INCORRECT_INIT_VALUE * GPIORC_WRITE_TO_INPUT * * * * Notes: * ***********************************************************************/ GPIOReturnCode GpioSetLevel(UINT32 portHandle, UINT32 value) { GPIORegisters *GPIOReg; GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_VALUE(value); if(GpioGetDirection(portHandle) != GPIO_OUT_PIN) return GPIORC_WRITE_TO_INPUT; GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); switch (value) { case 1: GPIOReg->PSR.REG = GPIO_SHIFT(portHandle); break; case 0: GPIOReg->PCR.REG = GPIO_SHIFT(portHandle); break; } return GPIORC_OK; } /*********************************************************************** * Function: GpioGetLevel * ************************************************************************ * Description: Get current level of a port * * * * Parameters: portHandle - the port handle * * * * * * Return value: GPIORC_LOW GPIORC_HIGH * * GPIORC_INVALID_PORT_HANDLE * * * * Notes: * ***********************************************************************/ GPIOReturnCode GpioGetLevel(UINT32 portHandle) { GPIORegisters *GPIOReg; UINT32 bit; GPIO_CHECK_VALID_HANDLE(portHandle); GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); bit = GPIOReg->PLR.REG & GPIO_SHIFT(portHandle); return bit ? GPIORC_HIGH : GPIORC_LOW; } /*********************************************************************** * Function: GpioEnableEdgeDetection * ************************************************************************ * Description: Enable edge detection function of a port * * * * Parameters: portHandle - the port handle * * edge - the edge detection type * * * * Return value: GPIORC_OK GPIORC_INVALID_PORT_HANDLE GPIORC_INCORRECT_TRANSITION_TYPE * * GPIORC_PIN_NOT_FREE * * * * Notes: * ***********************************************************************/ GPIOReturnCode GpioEnableEdgeDetection(UINT32 portHandle, GPIOTransitionType edge) { GPIORegisters *GPIOReg; GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_TRANSITION(edge); GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); ASSERT(GPIOReg != 0); if(GpioGetDirection(portHandle) != GPIO_IN_PIN) return GPIORC_PIN_NOT_FREE; if(edge == GPIO_RISE_EDGE || edge == GPIO_TWO_EDGE) { GPIOReg->RER.REG |= GPIO_SHIFT(portHandle); GPIOPortHandler[portHandle].IntcEnabled = TRUE; } if(edge == GPIO_FALL_EDGE || edge == GPIO_TWO_EDGE) { GPIOReg->FER.REG |= GPIO_SHIFT(portHandle); GPIOPortHandler[portHandle].IntcEnabled = TRUE; } GPIOReg->CP_MASK.REG |= GPIO_SHIFT(portHandle); return GPIORC_OK; } GPIOReturnCode GpioEnableEdgeDetectionBit(UINT32 portHandle, GPIOTransitionType edge) { GPIORegisters *GPIOReg; UINT32 base_addr=0; UINT32 val; GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_TRANSITION(edge); GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); ASSERT(GPIOReg != 0); if(GpioGetDirection(portHandle) != GPIO_IN_PIN) return GPIORC_PIN_NOT_FREE; base_addr=(UINT32)GetBaseAddr(portHandle); if(edge == GPIO_RISE_EDGE || edge == GPIO_TWO_EDGE) { val=*(volatile UINT32*)(base_addr+0x30); val|=GPIO_SHIFT(portHandle); *(volatile UINT32*)(base_addr+0x30)=val; GPIOPortHandler[portHandle].IntcEnabled = TRUE; } if(edge == GPIO_FALL_EDGE || edge == GPIO_TWO_EDGE) { val=*(volatile UINT32*)(base_addr+0x3C); val|=GPIO_SHIFT(portHandle); *(volatile UINT32*)(base_addr+0x3C)=val; GPIOPortHandler[portHandle].IntcEnabled = TRUE; } return GPIORC_OK; } GPIOReturnCode GpioDisableEdgeDetectionBit(UINT32 portHandle, GPIOTransitionType edge) { GPIORegisters *GPIOReg; UINT32 base_addr=0; UINT32 val; UINT32 v2; GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_TRANSITION(edge); GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); ASSERT(GPIOReg != 0); if(GpioGetDirection(portHandle) != GPIO_IN_PIN) return GPIORC_PIN_NOT_FREE; base_addr=(UINT32)GetBaseAddr(portHandle); if(edge == GPIO_RISE_EDGE || edge == GPIO_TWO_EDGE) { val=*(volatile UINT32*)(base_addr+0x30); v2=GPIO_SHIFT(portHandle); val&=~v2; *(volatile UINT32*)(base_addr+0x30)=val; } if(edge == GPIO_FALL_EDGE || edge == GPIO_TWO_EDGE) { val=*(volatile UINT32*)(base_addr+0x3C); v2=GPIO_SHIFT(portHandle); val&=~v2; *(volatile UINT32*)(base_addr+0x3C)=val; } return GPIORC_OK; } GPIOReturnCode GpioEnableEdgeDetection_wakeup(UINT32 portHandle, GPIOTransitionType edge) { UINT32 regval,mfpr_mask = 0; volatile UINT32 *mfpr_addr; GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_TRANSITION(edge); mfpr_addr = (volatile UINT32 *)GPIO_MFPR_ADDR(portHandle); if((UINT32)mfpr_addr == INVALID_GPIO_MFPR_ADDR) { RTI_LOG("INVALID_GPIO_MFPR_ADDR: %d in func: %s",portHandle, __func__); return GPIORC_INVALID_PORT_HANDLE; } if(GpioGetDirection(portHandle) != GPIO_IN_PIN) return GPIORC_PIN_NOT_FREE; GpioClearEdgeDetection(portHandle); if(edge == GPIO_RISE_EDGE || edge == GPIO_TWO_EDGE) { mfpr_mask |= (GPIO_BIT_ENABLE_RED); GPIOPortHandler[portHandle].WuEnabled= TRUE; } if(edge == GPIO_FALL_EDGE || edge == GPIO_TWO_EDGE) { mfpr_mask |= (GPIO_BIT_ENABLE_FED); GPIOPortHandler[portHandle].WuEnabled= TRUE; } regval = *(mfpr_addr); *(mfpr_addr) = (regval | mfpr_mask) & ~(GPIO_BIT_CLEAR_ED); return GPIORC_OK; } /*********************************************************************** * Function: GpioDisableEdgeDetection * ************************************************************************ * Description: Disable edge detection function of a port * * * * Parameters: portHandle - the port handle * * edge - the edge detection type * * * * Return value: GPIORC_OK GPIORC_INVALID_PORT_HANDLE GPIORC_INCORRECT_TRANSITION_TYPE * * * * * * Notes: * ***********************************************************************/ GPIOReturnCode GpioDisableEdgeDetection(UINT32 portHandle, GPIOTransitionType edge) { GPIORegisters *GPIOReg; volatile UINT32 regVal; GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_TRANSITION(edge); GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); ASSERT(GPIOReg != 0); if(edge == GPIO_RISE_EDGE || edge == GPIO_TWO_EDGE) { GPIOReg->RER.REG &= ~(GPIO_SHIFT(portHandle)); } if(edge == GPIO_FALL_EDGE || edge == GPIO_TWO_EDGE) { GPIOReg->FER.REG &= ~(GPIO_SHIFT(portHandle)); } if(((GPIOReg->RER.REG & GPIO_SHIFT(portHandle))==0) && ((GPIOReg->FER.REG & GPIO_SHIFT(portHandle))==0)) { regVal = GPIOReg->CP_MASK.REG; regVal &= ~(GPIO_SHIFT(portHandle)); GPIOReg->CP_MASK.REG = regVal; GPIOPortHandler[portHandle].IntcEnabled= FALSE; } return GPIORC_OK; } GPIOReturnCode GpioDisableEdgeDetection_wakeup(UINT32 portHandle, GPIOTransitionType edge) { UINT32 regval,mfpr_mask = 0xffffffff; volatile UINT32 *mfpr_addr; GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_TRANSITION(edge); mfpr_addr = (volatile UINT32 *)GPIO_MFPR_ADDR(portHandle); if((UINT32)mfpr_addr == INVALID_GPIO_MFPR_ADDR) { RTI_LOG("INVALID_GPIO_MFPR_ADDR: %d in func: %s",portHandle, __func__); return GPIORC_INVALID_PORT_HANDLE; } GpioClearEdgeDetection(portHandle); if(edge == GPIO_RISE_EDGE || edge == GPIO_TWO_EDGE) { mfpr_mask &= ~(GPIO_BIT_ENABLE_RED); } if(edge == GPIO_FALL_EDGE || edge == GPIO_TWO_EDGE) { mfpr_mask &= ~(GPIO_BIT_ENABLE_FED); } regval = *(mfpr_addr); *(mfpr_addr) = regval & mfpr_mask; regval = *(mfpr_addr); if((regval & (GPIO_BIT_ENABLE_RED|GPIO_BIT_ENABLE_FED)) == 0) { GPIOPortHandler[portHandle].WuEnabled= FALSE; } return GPIORC_OK; } /*********************************************************************** * Function: GpioIsEdgeDetected * ************************************************************************ * Description: check the pending bit of edge detection ofr a port * * * * Parameters: portHandle - the port handle * * * * Return value: GPIORC_OK GPIORC_INVALID_PORT_HANDLE * * * * Notes: * ***********************************************************************/ GPIOReturnCode GpioIsEdgeDetected(UINT32 portHandle) { UINT32 bit; GPIORegisters *GPIOReg; GPIO_CHECK_VALID_HANDLE(portHandle); GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); bit = GPIOReg->EDR.REG & GPIO_SHIFT(portHandle); return bit? GPIORC_TRUE : GPIORC_FALSE; } GPIOReturnCode GpioIsEdgeDetected_wakeup(UINT32 portHandle) { volatile UINT32*gpio_edge_reg; UINT32 bit; GPIO_CHECK_VALID_HANDLE(portHandle); gpio_edge_reg = (volatile UINT32 *)MFPR_EDGE_ADDR(portHandle); bit = *(gpio_edge_reg) & GPIO_SHIFT(portHandle); return bit? GPIORC_TRUE : GPIORC_FALSE; } /*********************************************************************** * Function: GpioClearEdgeDetection * ************************************************************************ * Description: clear the pending bit of edge detection ofr a port * * * * Parameters: portHandle - the port handle * * * * Return value: GPIORC_OK GPIORC_INVALID_PORT_HANDLE * * * * Notes: * ***********************************************************************/ GPIOReturnCode GpioClearEdgeDetection(UINT32 portHandle) { GPIORegisters *GPIOReg; GPIO_CHECK_VALID_HANDLE(portHandle); GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); GPIOReg->EDR.REG = GPIO_SHIFT(portHandle); return GPIORC_OK; } GPIOReturnCode GpioClearEdgeDetection_wakeup(UINT32 portHandle) { volatile UINT32 *mfpr_addr; GPIO_CHECK_VALID_HANDLE(portHandle); mfpr_addr = (volatile UINT32 *)GPIO_MFPR_ADDR(portHandle); if((UINT32)mfpr_addr == INVALID_GPIO_MFPR_ADDR) { RTI_LOG("INVALID_GPIO_MFPR_ADDR: %d in func: %s",portHandle, __func__); return GPIORC_INVALID_PORT_HANDLE; } *(mfpr_addr) |= GPIO_BIT_CLEAR_ED; *(mfpr_addr) &= ~(GPIO_BIT_CLEAR_ED); return GPIORC_OK; } /*********************************************************************** * Function: GpioSetDirection * ************************************************************************ * Description: Controls the direction of a given port * * * * Parameters: portHandle - the port handle * * dir - the required direction * * * * Return value: GPIORC_OK * * GPIORC_INVALID_PORT_HANDLE * * GPIORC_INCORRECT_DIRECTION GPIORC_PIN_USED_IN_PORT * * * * Notes: * * * * * * * * If the port is with interrupt, it can not be changed to output with * * this API * *************************************************************************/ GPIOReturnCode GpioSetDirection(UINT32 portHandle, GPIOPinDirection dir) { GPIORegisters *GPIOReg; volatile UINT32 *mfpr_addr; UINT32 regval; GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_DIRECTION(dir); mfpr_addr = (volatile UINT32 *)GPIO_MFPR_ADDR(portHandle); if((UINT32)mfpr_addr == INVALID_GPIO_MFPR_ADDR) { RTI_LOG("INVALID_GPIO_MFPR_ADDR: %d in func: %s",portHandle, __func__); return GPIORC_INVALID_PORT_HANDLE; } #if 0 //remove this restriction, since this senario does exist. if (dir == GPIO_OUT_PIN && GPIOPortHandler[portHandle].IntcEnabled == TRUE) { return GPIORC_PIN_USED_IN_PORT; } #endif GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); ASSERT(GPIOReg != 0); switch (dir) { case GPIO_OUT_PIN: GPIOReg->SDR.REG = GPIO_SHIFT(portHandle); if (CHIP_IS_CRANE) *(mfpr_addr) &= ~(GPIO_BIT_SLEEP_DIR); break; case GPIO_IN_PIN: GPIOReg->CDR.REG = GPIO_SHIFT(portHandle); if (CHIP_IS_CRANE) *(mfpr_addr) |= GPIO_BIT_SLEEP_DIR; break; } if(CHIP_IS_CRANELR || CHIP_IS_CRANELRH) { //low drive strength, set bit12/11 to 0 *(mfpr_addr) &= 0xE7FF; } else { //medium drive slew rate *(mfpr_addr) |= GPIO_BIT_DRIVE_1; } return GPIORC_OK; } /*********************************************************************** * Function: GpioGetDirection * ************************************************************************ * Description: Get the direction of a given port * * * * Parameters: portHandle - the port handle * * * * Return value: GPIO_IN_PIN GPIO_OUT_PIN * * GPIORC_INVALID_PORT_HANDLE * * * * * Notes: * * * **************************************************************************/ GPIOPinDirection GpioGetDirection(UINT32 portHandle) { GPIORegisters *GPIOReg; UINT32 bit; // GPIO_CHECK_VALID_HANDLE(portHandle); GPIOReg = (GPIORegisters *)GetBaseAddr(portHandle); bit = GPIOReg->PDR.REG & GPIO_SHIFT(portHandle); return bit? GPIO_OUT_PIN : GPIO_IN_PIN; } /*********************************************************************** * Function: GpioSetPullControl * ************************************************************************ * Description: Controls the pull up and pull down state of port * * * * Parameters: portHandle - the port handle * * pull - pull up/pull down/not pull * * * * Return value: GPIORC_OK * * GPIORC_INVALID_PORT_HANDLE * * GPIORC_INCORRECT_PULL * * Notes: * * * * * * * * If the port is with interrupt, it can not be changed to output with * * this API * *************************************************************************/ GPIOReturnCode GpioSetPullControl(UINT32 portHandle, GPIOPullUpDown pull) { volatile UINT32 *mfpr_addr; UINT32 regval; GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_PULL(pull); mfpr_addr = (volatile UINT32 *)GPIO_MFPR_ADDR(portHandle); if((UINT32)mfpr_addr == INVALID_GPIO_MFPR_ADDR) { RTI_LOG("INVALID_GPIO_MFPR_ADDR: %d in func: %s",portHandle, __func__); return GPIORC_INVALID_PIN_NUM; } if(pull == GPIO_PULL_DISABLE) { regval = *(mfpr_addr); *(mfpr_addr) = (regval | (GPIO_BIT_PULL_SEL)) & ~(GPIO_BIT_PULLUP) &~(GPIO_BIT_PULLDN); } else if(pull == GPIO_PULLUP_ENABLE) { regval = *(mfpr_addr); *(mfpr_addr) = (regval | (GPIO_BIT_PULL_SEL)| (GPIO_BIT_PULLUP)) & ~(GPIO_BIT_PULLDN); } else if(pull == GPIO_PULLDN_ENABLE) { regval = *(mfpr_addr); *(mfpr_addr) = (regval | (GPIO_BIT_PULL_SEL) | (GPIO_BIT_PULLDN)) & ~(GPIO_BIT_PULLUP); } else { /*mischecked by coverity*/ /*coverity[dead_error_line]*/ return GPIORC_INCORRECT_PULL; } return GPIORC_OK; } #ifdef QUECTEL_OPEN_CPU /*********************************************************************** * Function: GpioGetPullControl * ************************************************************************ * Description: Get the pull up and pull down state of port * * * * Parameters: portHandle - the port handle * * * * Return value: GPIO_PULL_DISABLE * * GPIO_PULLUP_ENABLE * * GPIO_PULLDN_ENABLE * * Notes: * * * * * * * * If the port is with interrupt, it can not be changed to output with * * this API * *************************************************************************/ GPIOReturnCode GpioGetPullControl(UINT32 portHandle) { volatile UINT32 *mfpr_addr; UINT32 regval; GPIO_CHECK_VALID_HANDLE(portHandle); mfpr_addr = (volatile UINT32 *)GPIO_MFPR_ADDR(portHandle); if((UINT32)mfpr_addr == INVALID_GPIO_MFPR_ADDR) return GPIORC_INVALID_PIN_NUM; regval = *(mfpr_addr); if ((regval & GPIO_BIT_PULL_SEL) && (regval & GPIO_BIT_PULLUP)) { return GPIO_PULLUP_ENABLE; } else if ((regval & GPIO_BIT_PULL_SEL) && (regval & GPIO_BIT_PULLDN)) { return GPIO_PULLDN_ENABLE; } else { return GPIO_PULL_DISABLE; } } #endif /* QUECTEL_GPIO_ENABLE */ /*********************************************************************** * Function: GpioBindWakeupCallback * ************************************************************************ * Description: Bind a callback function to a GPIO's wakeup event * * * * Parameters: portHandle - the port handle * * * * Return value: GPIORC_OK GPIO_NULL_POINTER * * GPIORC_INVALID_PORT_HANDLE * * Notes: * * * **************************************************************************/ GPIOReturnCode GpioBindWakeupCallback(UINT32 portHandle, GPIOCallback func) { GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_CALLBACK(func); GPIOPortHandler[portHandle].WU = func; return GPIORC_OK; } /*********************************************************************** * Function: GpioBindInterruptCallback * ************************************************************************ * Description: Bind a callback function to a GPIO's interrupt * * * * Parameters: portHandle - the port handle * * * * Return value: GPIORC_OK GPIO_NULL_POINTER * * GPIORC_INVALID_PORT_HANDLE * * Notes: * * * **************************************************************************/ GPIOReturnCode GpioBindInterruptCallback(UINT32 portHandle, GPIOCallback func) { GPIO_CHECK_VALID_HANDLE(portHandle); GPIO_CHECK_VALID_CALLBACK(func); GPIOPortHandler[portHandle].ISR = func; return GPIORC_OK; } /*********************************************************************** * Function: GpioInitConfiguration * ************************************************************************ * Description: Init GPIO functions with a configuration set * * * * Parameters: portHandle - the port handle * config - the configuration set * * * Return value: GPIORC_OK Any error code during configuration * * * Notes: Please note that pinmux configured globally will be over-written * * * **************************************************************************/ GPIOReturnCode GpioInitConfiguration(UINT32 portHandle, GPIOConfiguration config) { GPIOReturnCode ret; volatile UINT32 *mfpr_addr; GPIO_CHECK_VALID_HANDLE(portHandle); if(config.pinDir == GPIO_IN_PIN) { //config pull up and pull down resistors ret = GpioSetPullControl(portHandle, config.pinPull); if(ret != GPIORC_OK) return ret; } //init direction ret = GpioSetDirection(portHandle, config.pinDir); if(ret != GPIORC_OK) return ret; //set up an initial pin level if(GpioGetDirection(portHandle) == GPIO_OUT_PIN) { ret = GpioSetLevel(portHandle, config.initLv); if(ret != GPIORC_OK) return ret; } //open edge detection function if(config.pinEd != GPIO_NO_EDGE) { ret = GpioEnableEdgeDetection(portHandle, config.pinEd); if(ret != GPIORC_OK) return ret; #if 0 //temp disable ret = GpioEnableEdgeDetection_wakeup(portHandle, config.pinEd); if(ret != GPIORC_OK) return ret; #endif } //bind interrupt and wakeup callback if(config.wu) { ret = GpioBindWakeupCallback(portHandle, config.wu); if(ret != GPIORC_OK) return ret; GPIOPortHandler[portHandle].WuEnabled= TRUE; } if(config.isr) { ret = GpioBindInterruptCallback(portHandle, config.isr); if(ret != GPIORC_OK) return ret; GPIOPortHandler[portHandle].IntcEnabled = TRUE; DIAG_FILTER(MAT, MATHandleIndication, GpioInitConfiguration_1, DIAG_INFORMATION) diagPrintf("enable interrupt %d", portHandle); } return GPIORC_OK; } /*********************************************************************** * Function: GpioCommonWakeupCallback * ************************************************************************ * Description: Common entrance of GPIO wakeup * * * * Parameters: * * * * Return value: * * * Notes: * * * **************************************************************************/ void GpioCommonWakeupCallback(void) { UINT32 i; GPIOCallback wu; for(i = 0 ; i < GPIO_MAX_PORT_HANDLERS; i++) { if(GpioIsEdgeDetected_wakeup(i)) { GpioClearEdgeDetection_wakeup(i); /**20240529 miles.ma û��ע��quec_sfp_eint_register����ʹ��quec_uart_wakeup_mode_enable����£����Ѻ󣬽��������ڵĻ����жϣ� ��ֹ���ʹ�����ʱ��Ƶ�����������жϣ�����dump**/ #if QUECTEL_OPEN_CPU #ifndef MIN_SYS if(!IsMiniSystem()) { extern void* quec_get_gpio_wu_hisr(int gpio_num); extern char quec_uart_get_wakeup_mode_flag(UART_Port port); if(!quec_get_gpio_wu_hisr(51) && (i==51)&&(quec_uart_get_wakeup_mode_flag(UART_PORT_STUART))) { GpioDisableEdgeDetection_wakeup(i,GPIO_TWO_EDGE); //��ֹ������Ƶ�������жϵ���dump } } #endif #endif if(GPIOPortHandler[i].WuEnabled) { #if QUECTEL_OPEN_CPU GpioDisableEdgeDetection_wakeup(i,GPIO_TWO_EDGE); extern void quec_active_gpio_wu_hisr(unsigned int gpio_num); #ifndef MIN_SYS if(!IsMiniSystem()) { quec_active_gpio_wu_hisr(i);//����hisr,ִ�пͻ�ע��Ļص� } #endif #else GPIOPortHandler[i].WuEnabled = FALSE; wu = GPIOPortHandler[i].WU; if(wu) wu(); GPIOPortHandler[i].WuEnabled = TRUE; #endif } } } } /*********************************************************************** * Function: GpioCommonInterruptCallback * ************************************************************************ * Description: Common entrance of GPIO interrupts * * * * Parameters: * * * * Return value: * * * Notes: * * * **************************************************************************/ void GpioCommonInterruptCallback(UINT32 ulValue) { UINT32 i; GPIOCallback isr; for(i = 0 ; i < GPIO_MAX_PORT_HANDLERS; i++) { if(GpioIsEdgeDetected(i)) { rti_record_line("GPO", i); } //filter in software if(GPIOPortHandler[i].IntcEnabled) { //check hardware pending bit if(GpioIsEdgeDetected(i)) { GpioClearEdgeDetection(i); #if QUECTEL_OPEN_CPU GPIOPortHandler[i].IntcEnabled = FALSE; isr = GPIOPortHandler[i].ISR; if(isr) { (isr)(); } else { GpioDisableEdgeDetection(i,GPIO_TWO_EDGE); extern void quec_active_gpio_hisr(unsigned int gpio_num); #ifndef MIN_SYS if(!IsMiniSystem()) { quec_active_gpio_hisr(i);//����hisr,ִ�пͻ�ע��Ļص� } #endif } GPIOPortHandler[i].IntcEnabled = TRUE; #else GPIOPortHandler[i].IntcEnabled = FALSE; isr = GPIOPortHandler[i].ISR; if(isr) (isr)(); GPIOPortHandler[i].IntcEnabled = TRUE; #endif } } } } /*********************************************************************** * Function: GpioPhase1Init * ************************************************************************ * Description: Init GPIO interrupts and wakeup source * * * * Parameters: * * * * Return value: * * * Notes: * * * **************************************************************************/ GPIOReturnCode GpioPhase1Init(void) { //fill GPIOPortHandler with zero memset( GPIOPortHandler, 0 , sizeof(GPIOPortHandler)); //BU_REG_WRITE(APBC_GPIO_CLC_RST, 0x3); return GPIORC_OK; } GPIOReturnCode GpioPhase2Init(void) { //Enable GPIO edge detection interrupt INTC_ReturnCode intcStatus; UINT8 index; GPIORegisters *GPIOReg; for(index=0;indexRER.REG= 0; GPIOReg->FER.REG= 0; GPIOReg->EDR.REG= ~0; } //enable GPIO interrupt(Pad Level Change) intcStatus = INTCConfigure ( INTC_SRC_GPIO_COMBINED_CP, INTC_IRQ, INTC_RISING_EDGE); intcStatus = INTCBind(INTC_SRC_GPIO_COMBINED_CP , GpioCommonInterruptCallback); INTCEnable(INTC_SRC_GPIO_COMBINED_CP); return GPIORC_OK; } static UINT32 gpio_isr_count=0; static UINT8 gpio_test_num=0; void gpio_isr(void) { gpio_isr_count++; } //ICAT EXPORTED FUNCTION - VALI_IF,GPIO,GPIO_INTERRUPT_TEST void GPIO_INTERRUPT_TEST(UINT8 *gpioNum) { GPIOConfiguration config={0}; GPIOReturnCode ret; gpio_test_num = *gpioNum; DIAG_FILTER(MAT, MATHandleIndication, GPIO_INTERRUPT_TEST_0, DIAG_INFORMATION) diagPrintf("gpio : %d,dir=%d, LVL=%d", *gpioNum,GpioGetDirection(gpio_test_num),GpioGetLevel(gpio_test_num)); config.pinDir = GPIO_IN_PIN; //config.pinDir = GPIO_OUT_PIN; config.pinEd = GPIO_RISE_EDGE; config.pinPull = GPIO_PULLDN_ENABLE; config.isr = gpio_isr; //config.initLv=1; ret = GpioInitConfiguration(gpio_test_num,config); DIAG_FILTER(MAT, MATHandleIndication, GPIO_INTERRUPT_TEST_1, DIAG_INFORMATION) diagPrintf("ret=%d, LVL=%d", ret,GpioGetLevel(gpio_test_num)); } //ICAT EXPORTED FUNCTION - VALI_IF,GPIO,setGpioLvl void setGpioLvl(UINT8 *lvl) { UINT32 i; GPIOReturnCode ret; ret = GpioSetLevel(gpio_test_num,*lvl); DIAG_FILTER(MAT, MATHandleIndication, setGpioLvl_0, DIAG_INFORMATION) diagPrintf("ret=%d, LVL=%d", ret,*lvl); } //ICAT EXPORTED FUNCTION - VALI_IF,GPIO,getGpioLvl void getGpioLvl(void) { DIAG_FILTER(MAT, MATHandleIndication, getGpioLvl_0, DIAG_INFORMATION) diagPrintf("dir=%d, LVL=%d", GpioGetDirection(gpio_test_num),GpioGetLevel(gpio_test_num)); } extern UINT32 current_icu_interrupt_num; extern UINT32 icu_interrupt_count; //ICAT EXPORTED FUNCTION - VALI_IF,GPIO,dump_isr_count void dump_isr_count(void) { DIAG_FILTER(MAT, MATHandleIndication, dump_isr_count_0, DIAG_INFORMATION) diagPrintf("gpio_isr_count=%d",gpio_isr_count); } //ICAT EXPORTED FUNCTION - VALI_IF,GPIO,getGPIOPinmuxAddress UINT32 getGPIOPinmuxAddress(UINT32 GPIONum) { UINT32 GPIOPinmuxAddr = 0; if(GPIONum <= 36) GPIOPinmuxAddr = 0xd401e0dc + GPIONum*4; else if(GPIONum >= 49 && GPIONum <= 54) GPIOPinmuxAddr = 0xd401e1a0 + (GPIONum - 49)*4; #if defined(CRANELG_SUPPORT) else if(GPIONum == 55) GPIOPinmuxAddr = 0xd401e0c8; #endif else if(GPIONum >= 60 && GPIONum <= 66) GPIOPinmuxAddr = 0xd401e304 + (GPIONum - 60)*4; #if ((defined(CRANEL_4MRAM) || defined(CRANEL_8MRAM)) || defined(CRANELR_SUPPORT) || defined(CRANELRH_SUPPORT)) else if(GPIONum == 37) GPIOPinmuxAddr = 0xd401e1cc; else if(GPIONum >= 68 && GPIONum <= 70) GPIOPinmuxAddr = 0xd401e2b8 + (GPIONum - 69)*4; else if(GPIONum >= 71 && GPIONum <= 74) GPIOPinmuxAddr = 0xd401e1bc + (GPIONum - 71)*4; else if(GPIONum >= 78 && GPIONum <= 80) GPIOPinmuxAddr = 0xd401e2e0 + (GPIONum - 78)*4; #else else if(GPIONum >= 71 && GPIONum <= 86) GPIOPinmuxAddr = 0xd401e1b8 + (GPIONum - 71)*4; #endif else ASSERT(0); return GPIOPinmuxAddr; }