📄 ddk_gpio.c
字号:
GPIO_INT_TYPE intType;
UINT32 mask;
UINT32 pin;
UINT32 intMask;
UINT32 puen;
UINT32 icr;
if (!pGpioCfg)
return FALSE;
intMask = pGpioCfg->IntrConfig.PinMap;
intType = pGpioCfg->IntrConfig.IntType;
if (intMask == 0 || intType >= GPIO_INT_TYPE_MAX) {
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("GpioConfigIntrFunc: invalid pins! input %x type %d\r\n"),
intMask, intType));
return FALSE;
}
DDK_GPIO_LOCK();
// Input, interrupt disabled.
port = pGpioCfg->IntrConfig.Port;
g_pGPIO->PORT[port].IMR &= ~intMask;
g_pGPIO->PORT[port].GIUS |= intMask;
g_pGPIO->PORT[port].DDIR &= ~intMask;
if ((intMask & 0x0000FFFF) != 0) {
icr = g_pGPIO->PORT[port].ICR1;
for (pin = 0, mask = 1; pin < 16; pin++, mask <<= 1) {
if (mask & intMask) {
icr &= ~(3 << (pin * 2));
if (bEnable == TRUE)
icr |= (intType << (pin * 2));
}
}
g_pGPIO->PORT[port].ICR1 = icr;
}
if ((intMask & 0xFFFF0000) != 0) {
icr = g_pGPIO->PORT[port].ICR2;
for (pin = 0, mask = (1 << 16); pin < 16; pin++, mask <<= 1) {
if (mask & intMask) {
icr &= ~(3 << (pin * 2));
if (bEnable == TRUE)
icr |= (intType << (pin * 2));
}
}
g_pGPIO->PORT[port].ICR2 = icr;
}
// Pullup enabled if interrupt is negative level/edge triggered
// and pullup disabled otherwise.
puen = g_pGPIO->PORT[port].PUEN;
if (bEnable && (intType == GPIO_INT_TYPE_POSEDGE || intType == GPIO_INT_TYPE_POSLEVEL))
puen &= ~intMask;
else
puen |= intMask;
g_pGPIO->PORT[port].PUEN = puen;
// Clear any pedign interrupt status
g_pGPIO->PORT[port].ISR |= intMask;
DDK_GPIO_UNLOCK();
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: DDKGpioEnable
//
// This function provides a mechanism for configuring a GPIO pin mapping for
// a particular peripheral.
//
// Parameters:
// pGpioCfg
// [in] Pointer to configuration.
//
// Returns:
// TRUE if request was successful, otherwise returns false.
//
//------------------------------------------------------------------------------
BOOL DDKGpioEnable(DDK_GPIO_CFG *pGpioCfg)
{
BOOL rc = FALSE;
// Call function itself
switch(pGpioCfg->ConfigType) {
case GPIO_CFG_PRI:
rc = GpioConfigPriFunc(pGpioCfg, TRUE);
break;
case GPIO_CFG_ALT:
rc = GpioConfigAltFunc(pGpioCfg, TRUE);
break;
case GPIO_CFG_MODULEIO:
rc = GpioConfigModuleIOFunc(pGpioCfg, TRUE);
break;
case GPIO_CFG_INT:
rc = GpioConfigIntrFunc(pGpioCfg, TRUE);
break;
case GPIO_CFG_IO:
rc = GpioConfigIOFunc(pGpioCfg, TRUE);
break;
default:
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("DDKEnableGpio: invalid config type!\r\n")));
break;
}
return rc;
}
//------------------------------------------------------------------------------
//
// Function: DDKGpioDisable
//
// This function provides a mechanism for resetting a GPIO pin mapping for
// a particular peripheral.
//
// Parameters:
// pGpioCfg
// [in] Pointer to configuration.
//
// Returns:
// TRUE if request was successful, otherwise returns false.
//
//------------------------------------------------------------------------------
BOOL DDKGpioDisable(DDK_GPIO_CFG *pGpioCfg)
{
BOOL rc = FALSE;
// Call function itself
switch (pGpioCfg->ConfigType) {
case GPIO_CFG_PRI:
rc = GpioConfigPriFunc(pGpioCfg, FALSE);
break;
case GPIO_CFG_ALT:
rc = GpioConfigAltFunc(pGpioCfg, FALSE);
break;
case GPIO_CFG_MODULEIO:
rc = GpioConfigModuleIOFunc(pGpioCfg, FALSE);
break;
case GPIO_CFG_INT:
rc = GpioConfigIntrFunc(pGpioCfg, FALSE);
break;
case GPIO_CFG_IO:
rc = GpioConfigIOFunc(pGpioCfg, FALSE);
break;
default:
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("OALIoCtlHalDisableGpio: invalid config type!\r\n")));
break;
}
return rc;
}
//-----------------------------------------------------------------------------
//
// Function: DDKGpioWriteData
//
// Writes the GPIO port data to the specified pins.
//
// Parameters:
// port
// [in] GPIO port.
// portMask
// [in] Bit mask for data port pins to be written.
// data
// [in] Data to be written.
//
// Returns:
// Returns TRUE.
//
//-----------------------------------------------------------------------------
BOOL DDKGpioWriteData(GPIO_PORT port, UINT32 portMask, UINT32 data)
{
UINT32 oldReg, newReg;
// Make sure data bits fall within mask
data &= portMask;
// Safely update GPIO data register
do {
oldReg = g_pGPIO->PORT[port].DR;
newReg = (oldReg & (~portMask)) | data;
} while (InterlockedTestExchange((LPLONG)&g_pGPIO->PORT[port].DR,
oldReg, newReg) != oldReg);
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: DDKGpioWriteDataPin
//
// Writes the GPIO port data to the specified pin.
//
// Parameters:
// port
// [in] GPIO port.
// pin
// [in] GPIO pin [0-31].
// data
// [in] Data to be written [0 or 1].
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL DDKGpioWriteDataPin(GPIO_PORT port, UINT32 pin, UINT32 data)
{
if (pin >= GPIO_PINS_PER_PORT) {
DBGCHK((_T("CSPDDK")), FALSE);
return FALSE;
}
if ((data != 0) && (data != 1)) {
DBGCHK((_T("CSPDDK")), FALSE);
return FALSE;
}
return DDKGpioWriteData(port, GPIO_PIN_MASK(pin), (data << pin));
}
//-----------------------------------------------------------------------------
//
// Function: DDKGpioReadData
//
// Reads the GPIO port data for the specified pins.
//
// Parameters:
// port
// [in] GPIO port.
// portMask
// [in] Bit mask for data port pins to be read.
// pData
// [out] Points to buffer for data read.
//
// Returns:
// Returns TRUE.
//
//-----------------------------------------------------------------------------
BOOL DDKGpioReadData(GPIO_PORT port, UINT32 portMask, UINT32 *pData)
{
*pData = portMask & g_pGPIO->PORT[port].SSR;
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: DDKGpioReadDataPin
//
// Reads the GPIO port data from the specified pin.
//
// Parameters:
// port
// [in] GPIO port.
// pin
// [in] GPIO pin [0-31].
// pData
// [out] Points to buffer for data read. Data will be shifted to LSB.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL DDKGpioReadDataPin(GPIO_PORT port, UINT32 pin, UINT32 *pData)
{
if (pin >= GPIO_PINS_PER_PORT) {
DBGCHK((_T("CSPDDK")), FALSE);
return FALSE;
}
DDKGpioReadData(port, GPIO_PIN_MASK(pin), pData);
*pData >>= pin;
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: DDKGpioReadIntr
//
// Reads the GPIO port interrupt status for the specified pins.
//
// Parameters:
// port
// [in] GPIO port.
// portMask
// [in] Bit mask for data port pins to be read.
// pStatus
// [out] Points to buffer for interrupt status.
//
// Returns:
// Returns TRUE.
//
//-----------------------------------------------------------------------------
BOOL DDKGpioReadIntr(GPIO_PORT port, UINT32 portMask, UINT32 *pStatus)
{
*pStatus = portMask & g_pGPIO->PORT[port].ISR;
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: DDKGpioReadIntrPin
//
// Reads the GPIO port interrupt status from the specified pin.
//
// Parameters:
// port
// [in] GPIO port.
// pin
// [in] GPIO pin [0-31].
// pStatus
// [out] Points to buffer for interrupt status. Status will be
// shifted to LSB.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL DDKGpioReadIntrPin(GPIO_PORT port, UINT32 pin, UINT32 *pStatus)
{
if (pin >= GPIO_PINS_PER_PORT) {
DBGCHK((_T("CSPDDK")), FALSE);
return FALSE;
}
DDKGpioReadIntr(port, GPIO_PIN_MASK(pin), pStatus);
*pStatus >>= pin;
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: DDKGpioClearIntrPin
//
// Clears the GPIO interrupt status for the specified pin.
//
// Parameters:
// port
// [in] GPIO port.
// pin
// [in] GPIO pin [0-31].
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL DDKGpioClearIntrPin(GPIO_PORT port, UINT32 pin)
{
if (pin >= GPIO_PINS_PER_PORT) {
DBGCHK((_T("CSPDDK")), FALSE);
return FALSE;
}
// GPIO ISR is write-1-clear
g_pGPIO->PORT[port].ISR = GPIO_PIN_MASK(pin);
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: DDKSetGpioInterruptState
//
// Unmasks/Masks the interrupt for the specified pin.
//
// Parameters:
// port
// [in] GPIO port.
// pin
// [in] GPIO pin [0-31].
// bEnable
// [in] TURE for Unmask, FALSE for Mask.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL DDKGpioSetIntrPin(GPIO_PORT port, UINT32 pin, BOOL bEnable)
{
if (pin >= GPIO_PINS_PER_PORT) {
DBGCHK((_T("CSPDDK")), FALSE);
return FALSE;
}
DDK_GPIO_LOCK();
if (bEnable)
g_pGPIO->PORT[port].IMR |= GPIO_PIN_MASK(pin);
else
g_pGPIO->PORT[port].IMR &= ~GPIO_PIN_MASK(pin);
// GPIO ISR is write-1-clear
g_pGPIO->PORT[port].ISR = GPIO_PIN_MASK(pin);
DDK_GPIO_UNLOCK();
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: DDKGpioSetIntrType
//
// Sets the current type setting reading for pin specified by signal. The pin
// should have already been initialised as an interrupt pin during GPIO
// initialisation.
//
// Parameters:
// port
// [in] GPIO port.
// pin
// [in] GPIO pin [0-31].
// type
// [in] Interrupt type setting.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL DDKGpioSetIntrType(GPIO_PORT port, UINT32 pin,
GPIO_INT_TYPE type)
{
REG32 *pICR;
UINT32 imr;
if (pin >= GPIO_PINS_PER_PORT) {
DBGCHK((_T("CSPDDK")), FALSE);
return FALSE;
}
DDK_GPIO_LOCK();
imr = g_pGPIO->PORT[port].IMR;
g_pGPIO->PORT[port].IMR &= ~GPIO_PIN_MASK(pin);
g_pGPIO->PORT[port].ISR |= GPIO_PIN_MASK(pin);
if (pin < 16) {
pICR = &g_pGPIO->PORT[port].ICR1;
} else if(pin > 15 && pin < 32) {
pin -= 16;
pICR = &g_pGPIO->PORT[port].ICR2;
}
*pICR &= ~(3 << (pin * 2));
switch (type) {
case GPIO_INT_TYPE_POSEDGE:
*pICR |= GPIO_INT_TYPE_POSEDGE << (pin * 2);
break;
case GPIO_INT_TYPE_NEGEDGE:
*pICR |= GPIO_INT_TYPE_NEGEDGE << (pin * 2);
break;
case GPIO_INT_TYPE_POSLEVEL:
*pICR |= GPIO_INT_TYPE_POSLEVEL << (pin * 2);
break;
case GPIO_INT_TYPE_NEGLEVEL:
*pICR |= GPIO_INT_TYPE_NEGLEVEL << (pin * 2);
break;
}
g_pGPIO->PORT[port].IMR = imr;
DDK_GPIO_UNLOCK();
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -