/** * @file hal_gpio.c * * @copyright Nehemis SARL reserves all rights even in the event of industrial * property rights. We reserve all rights of disposal such as * copying and passing on to third parties. * * @brief HAL layer for the GPIO module. * */ /****************************************************************************** * Include Header Files ******************************************************************************/ #include "map_hal.h" #include "hal_gpio.h" /* CubeMX */ #include "gpio.h" /****************************************************************************** * Macro constant declarations ******************************************************************************/ #define HAL_GET_GPIO_OUTPUT_TYPE(port, pin) \ ((((port)->OTYPER & (OUTPUT_TYPE << (pin))) == 0) ? GPIO_MODE_OUTPUT_PP : GPIO_MODE_OUTPUT_OD) #define HAL_GPIO_GET_INTERRUPT_INPUT_MODE(port, pin) \ (((((port)->MODER >> ((pin) * 2)) & 0x3) == GPIO_MODE_IT_RISING) || \ ((((port)->MODER >> ((pin) * 2)) & 0x3) == GPIO_MODE_IT_FALLING) || \ ((((port)->MODER >> ((pin) * 2)) & 0x3) == GPIO_MODE_IT_RISING_FALLING)) #define HAL_GPIO_MODE_MASK (0x3u) /****************************************************************************** * Type declarations ******************************************************************************/ /****************************************************************************** * Module Global Variable Declarations ******************************************************************************/ static uint32 (*halGpioCallbacks[MAP_HAL_GPIO_NUMBER])(HalGpioEdgeType_en); /****************************************************************************** * Static Function Declarations ******************************************************************************/ /****************************************************************************** * Extern Function Definition ******************************************************************************/ uint32 HalGpioInit(void) { return NMS_ERR_NONE; } uint32 HalGpioRead( MapHalGpioPin_en pin_en, HalGpioState_en * state_pen ) { uint32 error_u32 = NMS_ERR_DEFAULT; uint16 targetPin_u16; GPIO_TypeDef* targetPort_pst = NULL; error_u32 = MapHalGpio(pin_en, &targetPin_u16, &targetPort_pst); if(error_u32 == NMS_ERR_NONE) { *state_pen = (HAL_GPIO_ReadPin(targetPort_pst, targetPin_u16) == GPIO_PIN_SET) ? HAL_GPIO_STATE_HIGH : HAL_GPIO_STATE_LOW; } else { *state_pen = HAL_GPIO_STATE_UNKNOWN; error_u32 = NMS_ERR_UNEXPECTED; } return error_u32; } uint32 HalGpioWrite( MapHalGpioPin_en pin_en, HalGpioState_en state_en ) { uint32 error_u32 = NMS_ERR_DEFAULT; uint16 targetPin_u16; GPIO_TypeDef* targetPort_pst = NULL; error_u32 = MapHalGpio(pin_en, &targetPin_u16, &targetPort_pst); if(error_u32 == NMS_ERR_NONE) { uint32 outpuType_u32 = HAL_GET_GPIO_OUTPUT_TYPE(targetPort_pst, pin_en); if(outpuType_u32 == GPIO_MODE_OUTPUT_PP || outpuType_u32 == GPIO_MODE_OUTPUT_OD) { switch (state_en) { case HAL_GPIO_STATE_HIGH: HAL_GPIO_WritePin(targetPort_pst, targetPin_u16, GPIO_PIN_SET); break; case HAL_GPIO_STATE_LOW: HAL_GPIO_WritePin(targetPort_pst, targetPin_u16, GPIO_PIN_RESET); break; default: error_u32 = NMS_ERR_UNKNOWN; break; } } HalGpioState_en activeState_en = (HAL_GPIO_ReadPin(targetPort_pst, targetPin_u16) == GPIO_PIN_SET) ? HAL_GPIO_STATE_HIGH : HAL_GPIO_STATE_LOW; if(activeState_en != state_en) { error_u32 = NMS_ERR_INVALID_CONFIG; } } else { error_u32 = NMS_ERR_UNEXPECTED; } return error_u32; } uint32 HalGpioToggle( MapHalGpioPin_en pin_en ) { uint32 error_u32 = NMS_ERR_DEFAULT; uint16 targetPin_u16; GPIO_TypeDef* targetPort_pst = NULL; error_u32 = MapHalGpio(pin_en, &targetPin_u16, &targetPort_pst); if(error_u32 == NMS_ERR_NONE) { uint32 outpuType_u32 = HAL_GET_GPIO_OUTPUT_TYPE(targetPort_pst, targetPin_u16); if(outpuType_u32 == GPIO_MODE_OUTPUT_PP || outpuType_u32 == GPIO_MODE_OUTPUT_OD) { HAL_GPIO_TogglePin(targetPort_pst, targetPin_u16); } } else { error_u32 = NMS_ERR_UNEXPECTED; } return error_u32; } uint32 HalGpioReConfigure( MapHalGpioPin_en pin_en, HalGpioType_en type_en ) { uint32 error_u32 = NMS_ERR_DEFAULT; uint16 targetPin_u16; GPIO_TypeDef* targetPort_pst = NULL; GPIO_InitTypeDef gpioInit_st = {0}; error_u32 = MapHalGpio(pin_en, &targetPin_u16, &targetPort_pst); if(error_u32 == NMS_ERR_NONE) { gpioInit_st.Pin = targetPin_u16; switch(type_en) { case HAL_GPIO_INPUT: gpioInit_st.Mode = GPIO_MODE_INPUT; gpioInit_st.Pull = GPIO_NOPULL; error_u32 = NMS_ERR_NONE; break; case HAL_GPIO_OUTPUT_PUSH_PULL_UP: gpioInit_st.Mode = GPIO_MODE_OUTPUT_PP; gpioInit_st.Pull = GPIO_PULLUP; error_u32 = NMS_ERR_NONE; break; case HAL_GPIO_OUTPUT_PUSH_PULL_DOWN: gpioInit_st.Mode = GPIO_MODE_OUTPUT_PP; gpioInit_st.Pull = GPIO_PULLDOWN; error_u32 = NMS_ERR_NONE; break; case HAL_GPIO_OUTPUT_PUSH_PULL_FREE: gpioInit_st.Mode = GPIO_MODE_OUTPUT_PP; gpioInit_st.Pull = GPIO_NOPULL; error_u32 = NMS_ERR_NONE; break; case HAL_GPIO_OUTPUT_OPEN_DRAIN_UP: gpioInit_st.Mode = GPIO_MODE_OUTPUT_OD; gpioInit_st.Pull = GPIO_PULLUP; error_u32 = NMS_ERR_NONE; break; case HAL_GPIO_OUTPUT_OPEN_DRAIN_FREE: gpioInit_st.Mode = GPIO_MODE_OUTPUT_OD; gpioInit_st.Pull = GPIO_NOPULL; error_u32 = NMS_ERR_NONE; break; case HAL_GPIO_ISR_RISING: gpioInit_st.Mode = GPIO_MODE_IT_RISING; gpioInit_st.Pull = GPIO_NOPULL; error_u32 = NMS_ERR_NONE; break; case HAL_GPIO_ISR_FALLING: gpioInit_st.Mode = GPIO_MODE_IT_FALLING; gpioInit_st.Pull = GPIO_NOPULL; error_u32 = NMS_ERR_NONE; break; default: /* HAL_GPIO_ALTERNATE or unknown state. */ error_u32 = NMS_ERR_INVALID_ARGUMENT; break; } } else { error_u32 = NMS_ERR_UNEXPECTED; } /* Deploy hardware modification. */ if(error_u32 == NMS_ERR_NONE) { HAL_GPIO_DeInit(targetPort_pst, targetPin_u16); HAL_GPIO_Init(targetPort_pst, &gpioInit_st); } return error_u32; } uint32 HalGpioSetCallback( MapHalGpioPin_en pin_en, uint32 (*callback_pfn)(HalGpioEdgeType_en edge_en)) { uint32 error_u32 = NMS_ERR_NONE; /* Ideal values of edge are 0 or 1 for now */ if ((pin_en < MAP_HAL_GPIO_NUMBER) && (callback_pfn != NULL)) { #ifdef DEBUG_ISSUE_EXTI_GPIO /* The check is always false. The configuration of interruption is not set in the GPIO settings, but in EXTI setttings. * This part of code need to be update to correct this feature (check the pin wanted is in interruption mode). * mbarth */ GPIO_TypeDef* targetPort_pst = NULL; uint32 moder_u32 = HAL_GPIO_GET_INTERRUPT_INPUT_MODE(targetPort_pst, pin_en); if ((moder_u32 == GPIO_MODE_IT_RISING) || (moder_u32 == GPIO_MODE_IT_FALLING) || (moder_u32 == GPIO_MODE_IT_RISING_FALLING)) #endif { halGpioCallbacks[pin_en] = callback_pfn; } } else { error_u32 = NMS_ERR_UNEXPECTED; } return error_u32; } /****************************************************************************** * Static Function Definitions ******************************************************************************/ /****************************************************************************** * Callback Function Definitions ******************************************************************************/ /** * @brief CubeMX GPIO callback * * @param[in] GPIO_Pin The GPIO pin on which the interrupt occurs * */ void HAL_GPIO_EXTI_Rising_Callback( uint16 GPIO_Pin ) { uint32 error_u32 = NMS_ERR_NONE; MapHalGpioPin_en mappedPin_en; error_u32 = MapHalGpioCallback(GPIO_Pin, &mappedPin_en); if ((error_u32 == NMS_ERR_NONE) && (halGpioCallbacks[mappedPin_en] != NULL)) { halGpioCallbacks[mappedPin_en](HAL_GPIO_EDGE_RISING); } } /** * @brief CubeMX GPIO falling callback * * @param[in] GPIO_Pin The GPIO pin on which the interrupt occurs * */ void HAL_GPIO_EXTI_Falling_Callback( uint16 GPIO_Pin ) { uint32 error_u32 = NMS_ERR_DEFAULT; MapHalGpioPin_en mappedPin_en; error_u32 = MapHalGpioCallback(GPIO_Pin, &mappedPin_en); if ((error_u32 == NMS_ERR_NONE) && (halGpioCallbacks[mappedPin_en] != NULL)) { halGpioCallbacks[mappedPin_en](HAL_GPIO_EDGE_FALLING); } } /** * @brief CubeMX GPIO callback * * @param[in] GPIO_Pin The GPIO pin on which the interrupt occurs * */ void HAL_GPIO_EXTI_Callback( uint16 GPIO_Pin ) { uint32 error_u32 = NMS_ERR_DEFAULT; MapHalGpioPin_en mappedPin_en; error_u32 = MapHalGpioCallback(GPIO_Pin, &mappedPin_en); if ((error_u32 == NMS_ERR_NONE) && (halGpioCallbacks[mappedPin_en] != NULL)) { halGpioCallbacks[mappedPin_en](HAL_GPIO_EDGE_NONE); /* Default value set for now*/ } }