rt-thread-official/bsp/nuvoton/libraries/n9h30/Driver/Source/nu_gpio.c

501 lines
13 KiB
C

/**************************************************************************//**
* @file gpio.c
* @version V1.00
* @brief N9H30 GPIO driver source file
*
* SPDX-License-Identifier: Apache-2.0
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "N9H30.h"
#include "nu_sys.h"
#include "nu_gpio.h"
/** @addtogroup N9H30_Device_Driver N9H30 Device Driver
@{
*/
/** @addtogroup N9H30_GPIO_Driver GPIO Driver
@{
*/
/** @addtogroup N9H30_GPIO_EXPORTED_FUNCTIONS GPIO Exported Functions
@{
*/
/**
* @brief Set GPIO Port
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bitMap GPIO port. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
*
* @retval <0 Fail
* @retval 0 Success
*
* @details This function is used to set GPIO port output data.
*/
INT32 GPIO_Set(GPIO_PORT port, UINT32 bitMap)
{
INT32 offset;
INT32 reg;
offset = (INT32)port;
reg = inpw(REG_GPIOA_DATAOUT + offset);
reg = reg | bitMap;
outpw(REG_GPIOA_DATAOUT + offset, reg);
return SUCCESSFUL;
}
/**
* @brief Clear GPIO port OUT Data
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bitMap GPIO port data. It could be 0x00 ~ 0xFF.
*
* @retval <0 Fail
* @retval 0 Success
*
* @details Clear GPIO port output data to 0.
*/
INT32 GPIO_Clr(GPIO_PORT port, UINT32 bitMap)
{
INT32 offset;
INT32 reg;
offset = (INT32)port;
reg = inpw(REG_GPIOA_DATAOUT + offset);
reg = reg & (~bitMap);
outpw(REG_GPIOA_DATAOUT + offset, reg);
return SUCCESSFUL;
}
/**
* @brief Open GPIO bit
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bit GPIO pin. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
* @param[in] direction GPIO direction. It could be \ref DIR_INPUT or \ref DIR_OUTPUT
* @param[in] pull GPIO pull-up. It could be \ref NO_PULL_UP or \ref PULL_UP
*
* @retval <0 Fail
* @retval 0 Success
*
* @details This function is used to open gpio pin.
*/
INT32 GPIO_OpenBit(GPIO_PORT port, UINT32 bit, GPIO_DIR direction, GPIO_PULL pull)
{
UINT32 reg;
UINT32 mask;
INT32 offset;
offset = (INT32)port;
mask = (UINT32)bit;
reg = inpw(REG_GPIOA_DIR + offset);
reg = reg & (~mask);
if (direction == DIR_OUTPUT)
{
reg = reg | mask;
}
outpw(REG_GPIOA_DIR + offset, reg);
reg = inpw(REG_GPIOA_PUEN + offset);
reg = reg & (~mask);
if (pull == PULL_UP)
{
reg = reg | mask;
outpw(REG_GPIOA_PUEN + offset, reg);
}
else if (pull == PULL_DOWN)
{
reg = reg | mask;
outpw(REG_GPIOA_PDEN + offset, reg);
}
else
{
outpw(REG_GPIOA_PUEN + offset, reg);
outpw(REG_GPIOA_PDEN + offset, reg);
}
return SUCCESSFUL;
}
/**
* @brief Set GPIO pin OUT Data
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bit GPIO pin. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
*
* @retval <0 Fail
* @retval 0 Success
*
* @details Set the Data into specified GPIO pin.
*/
INT32 GPIO_CloseBit(GPIO_PORT port, UINT32 bit)
{
UINT32 reg;
UINT32 mask;
INT32 offset;
offset = (INT32)port;
mask = (UINT32)bit;
reg = inpw(REG_GPIOA_DIR + offset);
reg = reg & (~mask);
outpw(REG_GPIOA_DIR + offset, reg);
reg = inpw(REG_GPIOA_PUEN + offset);
reg = reg & (~mask);
outpw(REG_GPIOA_PUEN + offset, reg);
return SUCCESSFUL;
}
/**
* @brief Set GPIO pin OUT Data
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bit GPIO pin. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
*
* @retval <0 Fail
* @retval 0 Success
*
* @details Set the Data into specified GPIO pin.
*/
INT32 GPIO_SetBit(GPIO_PORT port, UINT32 bit)
{
UINT32 bitMap;
INT32 offset;
INT32 reg;
offset = (INT32)port;
bitMap = (UINT32)bit;
reg = inpw(REG_GPIOA_DATAOUT + offset);
reg = reg | bitMap;
outpw(REG_GPIOA_DATAOUT + offset, reg);
return SUCCESSFUL;
}
/**
* @brief Clear GPIO port Interrupt Flag
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bitMap GPIO port data. It could be 0x00 ~ 0xFF.
*
* @retval <0 Fail
* @retval 0 Success
*
* @details Clear the interrupt status of specified GPIO port.
*/
INT32 GPIO_ClrISR(GPIO_PORT port, UINT32 bitMap)
{
INT32 offset;
offset = (INT32)port;
outpw(REG_GPIOA_ISR + offset, bitMap);
return SUCCESSFUL;
}
/**
* @brief Clear GPIO Pin Interrupt Flag
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bit GPIO pin. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
*
* @retval <0 Fail
* @retval 0 Success
*
* @details Clear the interrupt status of specified GPIO pin.
*/
INT32 GPIO_ClrISRBit(GPIO_PORT port, UINT32 bit)
{
UINT32 bitMap;
INT32 offset;
offset = (INT32)port;
bitMap = (UINT32)bit;
outpw(REG_GPIOA_ISR + offset, bitMap);
return SUCCESSFUL;
}
/**
* @brief Clear GPIO pin OUT Data
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bit GPIO pin. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
*
* @retval <0 Fail
* @retval 0 Success
*
* @details Set the Data into specified GPIO pin.
*/
INT32 GPIO_ClrBit(GPIO_PORT port, UINT32 bit)
{
UINT32 bitMap;
INT32 offset;
INT32 reg;
offset = (INT32)port;
bitMap = (UINT32)bit;
reg = inpw(REG_GPIOA_DATAOUT + offset);
reg = reg & (~bitMap);
outpw(REG_GPIOA_DATAOUT + offset, reg);
return SUCCESSFUL;
}
/**
* @brief Read GPIO pin In Data
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bit GPIO pin. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
*
* @retval 1/0 GPIO pin input data.
*
* @details Read the In Data from GPIO pin.
*/
INT32 GPIO_ReadBit(GPIO_PORT port, UINT32 bit)
{
UINT32 reg;
UINT32 bitMap;
INT32 offset;
offset = (INT32)port;
bitMap = (UINT32)bit;
reg = inpw(REG_GPIOA_DATAIN + offset);
return ((reg & bitMap) ? 1 : 0);
}
/**
* @brief Set GPIO pin direction
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bit GPIO pin. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
* @param[in] direction GPIO direction. It could be \ref DIR_INPUT, \ref DIR_OUTPUT.
*
* @retval <0 Fail
* @retval 0 Success
*
* @details Set the GPIO direction into specified GPIO pin.
*/
INT32 GPIO_SetBitDir(GPIO_PORT port, UINT32 bit, GPIO_DIR direction)
{
UINT32 reg;
UINT32 bitMap;
INT32 offset;
offset = (INT32)port;
bitMap = (UINT32)bit;
reg = inpw(REG_GPIOA_DIR + offset);
reg = reg & (~bitMap);
if (direction == DIR_OUTPUT)
{
reg = reg | bitMap;
}
outpw(REG_GPIOA_DIR + offset, reg);
return SUCCESSFUL;
}
/**
* @brief Enable GPIO trigger type.
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bitMap GPIO port. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
* @param[in] triggerType The triggerType of specified GPIO pin. It could be \n
* \ref RISING, \ref FALLING, \ref BOTH_EDGE, \ref HIGH, \ref LOW.
*
* @retval <0 Fail
* @retval 0 Success
*
* @details This function is used to enable trigger type.
*/
INT32 GPIO_EnableTriggerType(GPIO_PORT port, UINT32 bitMap, GPIO_TRIGGER_TYPE triggerType)
{
UINT32 reg;
INT32 offset;
offset = (INT32)port;
switch (triggerType)
{
case LOW:
reg = inpw(REG_GPIOA_IMD + offset);
outpw(REG_GPIOA_IMD + offset, reg | bitMap);
reg = inpw(REG_GPIOA_IREN + offset);
outpw(REG_GPIOA_IREN + offset, reg & ~bitMap);
reg = inpw(REG_GPIOA_IFEN + offset);
outpw(REG_GPIOA_IFEN + offset, reg | bitMap);
break;
case HIGH:
reg = inpw(REG_GPIOA_IMD + offset);
outpw(REG_GPIOA_IMD + offset, reg | bitMap);
reg = inpw(REG_GPIOA_IREN + offset);
outpw(REG_GPIOA_IREN + offset, reg | bitMap);
reg = inpw(REG_GPIOA_IFEN + offset);
outpw(REG_GPIOA_IFEN + offset, reg & ~bitMap);
break;
case FALLING:
reg = inpw(REG_GPIOA_IMD + offset);
outpw(REG_GPIOA_IMD + offset, reg & ~bitMap);
reg = inpw(REG_GPIOA_IREN + offset);
outpw(REG_GPIOA_IREN + offset, reg & ~bitMap);
reg = inpw(REG_GPIOA_IFEN + offset);
outpw(REG_GPIOA_IFEN + offset, reg | bitMap);
break;
case RISING:
reg = inpw(REG_GPIOA_IMD + offset);
outpw(REG_GPIOA_IMD + offset, reg & ~bitMap);
reg = inpw(REG_GPIOA_IREN + offset);
outpw(REG_GPIOA_IREN + offset, reg | bitMap);
reg = inpw(REG_GPIOA_IFEN + offset);
outpw(REG_GPIOA_IFEN + offset, reg & ~bitMap);
break;
case BOTH_EDGE:
reg = inpw(REG_GPIOA_IMD + offset);
outpw(REG_GPIOA_IMD + offset, reg & ~bitMap);
reg = inpw(REG_GPIOA_IREN + offset);
outpw(REG_GPIOA_IREN + offset, reg | bitMap);
reg = inpw(REG_GPIOA_IFEN + offset);
outpw(REG_GPIOA_IFEN + offset, reg | bitMap);
break;
}
return SUCCESSFUL;
}
/**
* @brief Disable GPIO trigger type.
*
* @param[in] port GPIO port. It could be \ref GPIOA, \ref GPIOB, ... or \ref GPIOJ
* @param[in] bitMap GPIO port. It could be \ref BIT0 \ref BIT1, ... or \ref BIT31
*
* @retval <0 Fail
* @retval 0 Success
*
* @details This function is used to disable trigger type.
*/
INT32 GPIO_DisableTriggerType(GPIO_PORT port, UINT32 bitMap)
{
UINT32 reg;
INT32 offset;
offset = (INT32)port;
reg = inpw(REG_GPIOA_IMD + offset);
outpw(REG_GPIOA_IMD + offset, reg & ~bitMap);
reg = inpw(REG_GPIOA_IREN + offset);
outpw(REG_GPIOA_IREN + offset, reg & ~bitMap);
reg = inpw(REG_GPIOA_IFEN + offset);
outpw(REG_GPIOA_IFEN + offset, reg & ~bitMap);
return SUCCESSFUL;
}
/**
* @brief Enable GPIO De-bounce Function
*
* @param[in] debounceClkSel The de-bounce sampling cycle selection. It could be 0~0xF. \n
* 0 = Sample interrupt input once per 1 clocks. \n
* 1 = Sample interrupt input once per 2 clocks. \n
* 2 = Sample interrupt input once per 4 clocks. \n
* 3 = Sample interrupt input once per 8 clocks. \n
* 4 = Sample interrupt input once per 16 clocks. \n
* 5 = Sample interrupt input once per 32 clocks. \n
* 6 = Sample interrupt input once per 64 clocks. \n
* 7 = Sample interrupt input once per 128 clocks. \n
* 8 = Sample interrupt input once per 256 clocks. \n
* 9 = Sample interrupt input once per 2*256 clocks. \n
* 10 = Sample interrupt input once per 4*256 clocks. \n
* 11 = Sample interrupt input once per 8*256 clocks. \n
* 12 = Sample interrupt input once per 16*256 clocks. \n
* 13 = Sample interrupt input once per 32*256 clocks. \n
* 14 = Sample interrupt input once per 64*256 clocks. \n
* 15 = Sample interrupt input once per 128*256 clocks
*
* @retval <0 Fail
* @retval 0 Success
*
* @details Enable the interrupt de-bounce function of specified GPIO.
*/
INT32 GPIO_EnableDebounce(INT32 debounceClkSel)
{
UINT32 reg;
reg = inpw(REG_GPIO_DBNCECON);
/* Setting the debounce timing */
reg = ((reg & ~0xf) | debounceClkSel);
/* Enable the debounce function */
reg = reg | 0x20;
outpw(REG_GPIO_DBNCECON, reg);
return SUCCESSFUL;
}
/**
* @brief Disable GPIO De-bounce Function.
*
* @retval <0 Fail
* @retval 0 Success
*
* @details Disable the interrupt de-bounce function of specified GPIO.
*/
INT32 GPIO_DisableDebounce(void)
{
UINT32 reg;
reg = inpw(REG_GPIO_DBNCECON);
/* Setting the debounce timing */
reg = ((reg & ~0xf));
/* Enable the debounce function */
reg = reg | 0x20;
outpw(REG_GPIO_DBNCECON, reg);
return SUCCESSFUL;
}
/*@}*/ /* end of group N9H30_GPIO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group N9H30_GPIO_Driver */
/*@}*/ /* end of group N9H30_Device_Driver */