Files
banban/ql-kernel/threadx/quec_minsys/cgpio.c
T

1276 lines
43 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#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;index<GPIO_REGISTER_GROUPS;index++)
{
GPIOReg = (GPIORegisters *)(GPIO_REGISTER_BASE + GPIORegisterBase[index]);
GPIOReg->RER.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;
}