|
|
#include "zgpio.hpp"
#define TAG "GPIO"
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 = chip_get_gpio(pin); m_pinoff = chip_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 = chip_get_gpio(pin); m_pinoff = chip_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) ZEARLY_LOGI(TAG, "%s%s set %d", chip_gpio_group_get_name(m_gpio), chip_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: ZEARLY_ASSERT(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
|