#include "zgpio.hpp" extern "C" { #include "logger.h" } #define TAG "GPIO" #define PC_IRQ_PREEMPTPRIORITY_DEFAULT 5 namespace iflytop { /******************************************************************************* * LISTENER * *******************************************************************************/ static ZGPIO *s_irqGPIO[20]; int s_irqGPIO_num = 0; extern "C" { /** * @brief This function handles EXTI line3 interrupt. */ void EXTI0_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); } void EXTI1_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1); } void EXTI2_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2); } void EXTI3_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); } void EXTI4_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); } void EXTI9_5_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9); } void EXTI15_10_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15); } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { for (int i = 0; i < s_irqGPIO_num; i++) { s_irqGPIO[i]->tryTriggerIRQ(GPIO_Pin); } } } void ZGPIO::regListener(onirq_t listener) { m_onirq = listener; } /******************************************************************************* * GPIOIMPL * *******************************************************************************/ /******************************************************************************* * BASE_FUNC * *******************************************************************************/ bool ZGPIO::enableClock() { #ifdef GPIOA if (m_gpio == GPIOA) { __HAL_RCC_GPIOA_CLK_ENABLE(); return true; } #endif #ifdef GPIOB if (m_gpio == GPIOB) { __HAL_RCC_GPIOB_CLK_ENABLE(); return true; } #endif #ifdef GPIOC if (m_gpio == GPIOC) { __HAL_RCC_GPIOC_CLK_ENABLE(); return true; } #endif #ifdef GPIOD if (m_gpio == GPIOD) { __HAL_RCC_GPIOD_CLK_ENABLE(); return true; } #endif #ifdef GPIOE if (m_gpio == GPIOE) { __HAL_RCC_GPIOE_CLK_ENABLE(); return true; } #endif #ifdef GPIOF if (m_gpio == GPIOF) { __HAL_RCC_GPIOF_CLK_ENABLE(); return true; } #endif #ifdef GPIOG if (m_gpio == GPIOG) { __HAL_RCC_GPIOG_CLK_ENABLE(); return true; } #endif #ifdef GPIOH if (m_gpio == GPIOH) { __HAL_RCC_GPIOH_CLK_ENABLE(); return true; } #endif #ifdef GPIOI if (m_gpio == GPIOI) { __HAL_RCC_GPIOI_CLK_ENABLE(); return true; } #endif #ifdef GPIOJ if (m_gpio == GPIOJ) { __HAL_RCC_GPIOJ_CLK_ENABLE(); return true; } #endif #ifdef GPIOK if (m_gpio == GPIOK) { __HAL_RCC_GPIOK_CLK_ENABLE(); return true; } #endif return false; } void regIRQGPIO(ZGPIO *gpio) { for (int i = 0; i < s_irqGPIO_num; i++) { if (s_irqGPIO[i] == gpio) { return; } } EARLY_ASSERT((s_irqGPIO_num + 1) < (int)ZARRAY_SIZE(s_irqGPIO)); s_irqGPIO[s_irqGPIO_num] = gpio; s_irqGPIO_num++; } bool ZGPIO::isMirror() { return m_mirror; } void ZGPIO::initAsInput(Pin_t pin, GPIOMode_t mode, GPIOIrqType_t irqtype, bool mirror) { if (pin == PinNull) return; m_mirror = mirror; m_mode = mode; m_irqtype = irqtype; m_gpiotype = kType_Input; m_pin = pin; m_gpio = stm32_get_gpio_group(pin); m_pinoff = stm32_get_pinoff(pin); uint32_t pulluptype = 0; if (mode == kMode_nopull) { pulluptype = GPIO_NOPULL; } else if (mode == kMode_pullup) { pulluptype = GPIO_PULLUP; } else if (mode == kMode_pulldown) { pulluptype = GPIO_PULLDOWN; } enableClock(); GPIO_InitTypeDef m_GPIO_InitStruct = {0}; if (m_irqtype == kIRQ_noIrq) { m_GPIO_InitStruct.Pin = m_pinoff; m_GPIO_InitStruct.Mode = GPIO_MODE_INPUT; m_GPIO_InitStruct.Pull = pulluptype; m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; } else if (m_irqtype == kIRQ_risingIrq) { m_GPIO_InitStruct.Pin = m_pinoff; m_GPIO_InitStruct.Mode = m_mirror ? GPIO_MODE_IT_FALLING : GPIO_MODE_IT_RISING; m_GPIO_InitStruct.Pull = pulluptype; m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; } else if (m_irqtype == kIRQ_fallingIrq) { m_GPIO_InitStruct.Pin = m_pinoff; m_GPIO_InitStruct.Mode = !m_mirror ? GPIO_MODE_IT_FALLING : GPIO_MODE_IT_RISING; m_GPIO_InitStruct.Pull = pulluptype; m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; } else if (m_irqtype == kIRQ_risingAndFallingIrq) { m_GPIO_InitStruct.Pin = m_pinoff; m_GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; m_GPIO_InitStruct.Pull = pulluptype; m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; } HAL_GPIO_Init(m_gpio, &m_GPIO_InitStruct); if (m_irqtype != kIRQ_noIrq) { regIRQGPIO(this); lastLevel = getState(); HAL_NVIC_SetPriority(getEXTIIRQn(), PC_IRQ_PREEMPTPRIORITY_DEFAULT, 0); HAL_NVIC_EnableIRQ(getEXTIIRQn()); } m_initflag = true; return; } void ZGPIO::initAsOutput(Pin_t pin, GPIOMode_t mode, bool mirror, bool initLevel) { if (pin == PinNull) return; m_mirror = mirror; m_mode = mode; m_irqtype = kIRQ_noIrq; m_gpiotype = kType_Output; m_pin = pin; m_gpio = stm32_get_gpio_group(pin); m_pinoff = stm32_get_pinoff(pin); enableClock(); GPIO_InitTypeDef m_GPIO_InitStruct = {0}; initLevel = m_mirror ? !initLevel : initLevel; GPIO_PinState pinState = initLevel ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(m_gpio, m_pinoff, pinState); if (m_mode == kMode_nopull) { m_GPIO_InitStruct.Pin = m_pinoff; m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; m_GPIO_InitStruct.Pull = GPIO_NOPULL; m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; } else if (m_mode == kMode_pullup) { m_GPIO_InitStruct.Pin = m_pinoff; m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; m_GPIO_InitStruct.Pull = GPIO_PULLUP; m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; } else if (m_mode == kMode_pulldown) { m_GPIO_InitStruct.Pin = m_pinoff; m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; m_GPIO_InitStruct.Pull = GPIO_PULLDOWN; m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; } else if (m_mode == kMode_od) { m_GPIO_InitStruct.Pin = m_pinoff; m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; m_GPIO_InitStruct.Pull = 0; m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; } HAL_GPIO_Init(m_gpio, &m_GPIO_InitStruct); m_initflag = true; return; } bool ZGPIO::isItRisingEXITGPIO() { return m_irqtype == kIRQ_risingIrq; } bool ZGPIO::isItFallingEXITGPIO() { return m_irqtype == kIRQ_fallingIrq; } bool ZGPIO::isItRisingAndItFallingEXITGPIO() { return m_irqtype == kIRQ_risingAndFallingIrq; } /******************************************************************************* * EXT FUNC * *******************************************************************************/ /** * @brief 判断当前是否是这个引脚产生的中断 * * @param checkloop * @param GPIO_Pin * @return true * @return false * * 由于STM32的GPIO中断线是共用的,所以需要根据GPIO的即时状态判断是否是这个引脚产生的中?? * * 判断逻辑??: * 先判断所有中断模式是 GPIO_MODE_IT_RISING ?? GPIO_MODE_IT_FALLING 的引脚,采样当前电平判断是否是这个引脚产生的中断 * 再判断中断模式是 GPIO_MODE_IT_RISING_FALLING 的引脚,直接返回true */ bool ZGPIO::tryTriggerIRQ(uint16_t GPIO_Pin) { bool ret = false; bool nostate = false; if (GPIO_Pin != m_pinoff) return false; if (!(isItRisingEXITGPIO() || isItFallingEXITGPIO() || isItRisingAndItFallingEXITGPIO())) { return false; } nostate = getState(); if (isItRisingEXITGPIO()) { if (nostate) { ret = true; if (m_onirq) { m_onirq(this, kRisingIrqEvent); } } } else if (isItFallingEXITGPIO()) { if (!nostate) { ret = true; if (m_onirq) { m_onirq(this, kFallingIrqEvent); } } } else { if (lastLevel != nostate) { ret = true; if (m_onirq) { if (lastLevel) m_onirq(this, kRisingIrqEvent); else m_onirq(this, kFallingIrqEvent); } } } lastLevel = nostate; return ret; } void ZGPIO::toggleState() { HAL_GPIO_TogglePin(m_gpio, m_pinoff); } uint32_t ZGPIO::getStateUint32() { if (getState()) return 1; else return 0; } bool ZGPIO::getState() { if (m_pin == PinNull) return false; bool ret = false; if (HAL_GPIO_ReadPin(m_gpio, m_pinoff) == GPIO_PIN_SET) { ret = true; } else { ret = false; } if (m_mirror) ret = !ret; return ret; } bool ZGPIO::setState(bool state) { if (m_pin == PinNull) return true; if (m_mirror) state = !state; if (m_log_when_setstate) { ZLOGI(TAG, "%s%s set %d", stm32_gpio_group_get_name(m_gpio), stm32_pinoff_get_name(m_pinoff), state); } if (state) { HAL_GPIO_WritePin(m_gpio, m_pinoff, GPIO_PIN_SET); } else { HAL_GPIO_WritePin(m_gpio, m_pinoff, GPIO_PIN_RESET); } return true; } IRQn_Type ZGPIO::getEXTIIRQn() { switch (m_pinoff) { case GPIO_PIN_0: return EXTI0_IRQn; case GPIO_PIN_1: return EXTI1_IRQn; case GPIO_PIN_2: return EXTI2_IRQn; case GPIO_PIN_3: return EXTI3_IRQn; case GPIO_PIN_4: return EXTI4_IRQn; case GPIO_PIN_5: case GPIO_PIN_6: case GPIO_PIN_7: case GPIO_PIN_8: case GPIO_PIN_9: return EXTI9_5_IRQn; case GPIO_PIN_10: case GPIO_PIN_11: case GPIO_PIN_12: case GPIO_PIN_13: case GPIO_PIN_14: case GPIO_PIN_15: return EXTI15_10_IRQn; default: ZASSERT(0); } return EXTI0_IRQn; } /** * @brief 初始化GPIO为中断模?? * * @param pull GPIO_NOPULL, GPIO_PULLUP, GPIO_PULLDOWN * @param mode GPIO_MODE_IT_RISING, GPIO_MODE_IT_FALLING, GPIO_MODE_IT_RISING_FALLING * @return true * @return false */ } // namespace iflytop using namespace iflytop; ZGPIO IO_PA0(PA0); ZGPIO IO_PA1(PA1); ZGPIO IO_PA2(PA2); ZGPIO IO_PA3(PA3); ZGPIO IO_PA4(PA4); ZGPIO IO_PA5(PA5); ZGPIO IO_PA6(PA6); ZGPIO IO_PA7(PA7); ZGPIO IO_PA8(PA8); ZGPIO IO_PA9(PA9); ZGPIO IO_PA10(PA10); ZGPIO IO_PA11(PA11); ZGPIO IO_PA12(PA12); ZGPIO IO_PA13(PA13); ZGPIO IO_PA14(PA14); ZGPIO IO_PA15(PA15); ZGPIO IO_PB0(PB0); ZGPIO IO_PB1(PB1); ZGPIO IO_PB2(PB2); ZGPIO IO_PB3(PB3); ZGPIO IO_PB4(PB4); ZGPIO IO_PB5(PB5); ZGPIO IO_PB6(PB6); ZGPIO IO_PB7(PB7); ZGPIO IO_PB8(PB8); ZGPIO IO_PB9(PB9); ZGPIO IO_PB10(PB10); ZGPIO IO_PB11(PB11); ZGPIO IO_PB12(PB12); ZGPIO IO_PB13(PB13); ZGPIO IO_PB14(PB14); ZGPIO IO_PB15(PB15); ZGPIO IO_PC0(PC0); ZGPIO IO_PC1(PC1); ZGPIO IO_PC2(PC2); ZGPIO IO_PC3(PC3); ZGPIO IO_PC4(PC4); ZGPIO IO_PC5(PC5); ZGPIO IO_PC6(PC6); ZGPIO IO_PC7(PC7); ZGPIO IO_PC8(PC8); ZGPIO IO_PC9(PC9); ZGPIO IO_PC10(PC10); ZGPIO IO_PC11(PC11); ZGPIO IO_PC12(PC12); ZGPIO IO_PC13(PC13); ZGPIO IO_PC14(PC14); ZGPIO IO_PC15(PC15); ZGPIO IO_PD0(PD0); ZGPIO IO_PD1(PD1); ZGPIO IO_PD2(PD2); ZGPIO IO_PD3(PD3); ZGPIO IO_PD4(PD4); ZGPIO IO_PD5(PD5); ZGPIO IO_PD6(PD6); ZGPIO IO_PD7(PD7); ZGPIO IO_PD8(PD8); ZGPIO IO_PD9(PD9); ZGPIO IO_PD10(PD10); ZGPIO IO_PD11(PD11); ZGPIO IO_PD12(PD12); ZGPIO IO_PD13(PD13); ZGPIO IO_PD14(PD14); ZGPIO IO_PD15(PD15); ZGPIO IO_PE0(PE0); ZGPIO IO_PE1(PE1); ZGPIO IO_PE2(PE2); ZGPIO IO_PE3(PE3); ZGPIO IO_PE4(PE4); ZGPIO IO_PE5(PE5); ZGPIO IO_PE6(PE6); ZGPIO IO_PE7(PE7); ZGPIO IO_PE8(PE8); ZGPIO IO_PE9(PE9); ZGPIO IO_PE10(PE10); ZGPIO IO_PE11(PE11); ZGPIO IO_PE12(PE12); ZGPIO IO_PE13(PE13); ZGPIO IO_PE14(PE14); ZGPIO IO_PE15(PE15); ZGPIO IO_PF0(PF0); ZGPIO IO_PF1(PF1); ZGPIO IO_PF2(PF2); ZGPIO IO_PF3(PF3); ZGPIO IO_PF4(PF4); ZGPIO IO_PF5(PF5); ZGPIO IO_PF6(PF6); ZGPIO IO_PF7(PF7); ZGPIO IO_PF8(PF8); ZGPIO IO_PF9(PF9); ZGPIO IO_PF10(PF10); ZGPIO IO_PF11(PF11); ZGPIO IO_PF12(PF12); ZGPIO IO_PF13(PF13); ZGPIO IO_PF14(PF14); ZGPIO IO_PF15(PF15); ZGPIO IO_PG0(PG0); ZGPIO IO_PG1(PG1); ZGPIO IO_PG2(PG2); ZGPIO IO_PG3(PG3); ZGPIO IO_PG4(PG4); ZGPIO IO_PG5(PG5); ZGPIO IO_PG6(PG6); ZGPIO IO_PG7(PG7); ZGPIO IO_PG8(PG8); ZGPIO IO_PG9(PG9); ZGPIO IO_PG10(PG10); ZGPIO IO_PG11(PG11); ZGPIO IO_PG12(PG12); ZGPIO IO_PG13(PG13); ZGPIO IO_PG14(PG14); ZGPIO IO_PG15(PG15);