You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
489 lines
12 KiB
489 lines
12 KiB
|
|
#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);
|