1#include "ch32_gpio.hpp"
5uint32_t LibXR::CH32GetGPIOPeriph(GPIO_TypeDef* port)
11 else if (port == GPIOA)
12 return RCC_APB2Periph_GPIOA;
15 else if (port == GPIOB)
16 return RCC_APB2Periph_GPIOB;
19 else if (port == GPIOC)
20 return RCC_APB2Periph_GPIOC;
23 else if (port == GPIOD)
24 return RCC_APB2Periph_GPIOD;
27 else if (port == GPIOE)
28 return RCC_APB2Periph_GPIOE;
33extern "C" void EXTI0_IRQHandler(
void) __attribute__((interrupt));
34extern "C" void EXTI0_IRQHandler(
void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line0); }
36extern "C" void EXTI1_IRQHandler(
void) __attribute__((interrupt));
37extern "C" void EXTI1_IRQHandler(
void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line1); }
39extern "C" void EXTI2_IRQHandler(
void) __attribute__((interrupt));
40extern "C" void EXTI2_IRQHandler(
void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line2); }
42extern "C" void EXTI3_IRQHandler(
void) __attribute__((interrupt));
43extern "C" void EXTI3_IRQHandler(
void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line3); }
45extern "C" void EXTI4_IRQHandler(
void) __attribute__((interrupt));
46extern "C" void EXTI4_IRQHandler(
void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line4); }
48extern "C" void EXTI9_5_IRQHandler(
void) __attribute__((interrupt));
49extern "C" void EXTI9_5_IRQHandler(
void)
51 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line5);
52 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line6);
53 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line7);
54 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line8);
55 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line9);
58extern "C" void EXTI15_10_IRQHandler(
void) __attribute__((interrupt));
59extern "C" void EXTI15_10_IRQHandler(
void)
61 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line10);
62 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line11);
63 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line12);
64 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line13);
65 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line14);
66 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line15);
69CH32GPIO::CH32GPIO(GPIO_TypeDef* port, uint16_t pin,
GPIO::Direction direction,
71 : port_(port), pin_(pin), irq_(irq)
73 if (irq_ != NonMaskableInt_IRQn)
76 map[GetEXTIID(pin)] =
this;
79 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(port_), ENABLE);
81 GPIO_InitTypeDef gpio_init = {};
82 gpio_init.GPIO_Pin = pin_;
83 gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
87 case Direction::RISING_INTERRUPT:
88 case Direction::FALL_INTERRUPT:
89 case Direction::FALL_RISING_INTERRUPT:
90 case Direction::INPUT:
91 gpio_init.GPIO_Mode = (pull == Pull::UP) ? GPIO_Mode_IPU
92 : (pull == Pull::DOWN) ? GPIO_Mode_IPD
93 : GPIO_Mode_IN_FLOATING;
95 case Direction::OUTPUT_PUSH_PULL:
96 gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
98 case Direction::OUTPUT_OPEN_DRAIN:
99 gpio_init.GPIO_Mode = GPIO_Mode_Out_OD;
103 GPIO_Init(port_, &gpio_init);
107 case Direction::RISING_INTERRUPT:
108 ConfigureEXTI(EXTI_Trigger_Rising);
110 case Direction::FALL_INTERRUPT:
111 ConfigureEXTI(EXTI_Trigger_Falling);
113 case Direction::FALL_RISING_INTERRUPT:
114 ConfigureEXTI(EXTI_Trigger_Rising_Falling);
126 GPIO_SetBits(port_, pin_);
128 GPIO_ResetBits(port_, pin_);
129 return ErrorCode::OK;
134 EXTI->INTENR |= (1 << GetEXTIID(pin_));
135 return ErrorCode::OK;
140 EXTI->INTENR &= ~(1 << GetEXTIID(pin_));
141 return ErrorCode::OK;
146 GPIO_InitTypeDef gpio_init = {};
147 gpio_init.GPIO_Pin = pin_;
148 gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
153 gpio_init.GPIO_Mode = (config.
pull ==
Pull::UP) ? GPIO_Mode_IPU
155 : GPIO_Mode_IN_FLOATING;
158 gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
161 gpio_init.GPIO_Mode = GPIO_Mode_Out_OD;
166 gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
170 GPIO_Init(port_, &gpio_init);
175 ConfigureEXTI(EXTI_Trigger_Rising);
178 ConfigureEXTI(EXTI_Trigger_Falling);
181 ConfigureEXTI(EXTI_Trigger_Rising_Falling);
187 return ErrorCode::OK;
190void CH32GPIO::OnInterrupt()
198void CH32GPIO::CheckInterrupt(uint32_t line)
200 if (EXTI_GetITStatus(line) != RESET)
202 EXTI_ClearITPendingBit(line);
203 map[GetEXTIID(line)]->OnInterrupt();
207void CH32GPIO::ConfigureEXTI(EXTITrigger_TypeDef trigger)
209 EXTI_InitTypeDef exti = {};
210 uint8_t pin_source = __builtin_ctz(pin_);
211 uint8_t port_source = 0xFF;
214 if (port_ == GPIOA) port_source = GPIO_PortSourceGPIOA;
217 else if (port_ == GPIOB)
219 port_source = GPIO_PortSourceGPIOB;
223 else if (port_ == GPIOC)
225 port_source = GPIO_PortSourceGPIOC;
229 else if (port_ == GPIOD)
231 port_source = GPIO_PortSourceGPIOD;
235 else if (port_ == GPIOE)
237 port_source = GPIO_PortSourceGPIOE;
241 else if (port_ == GPIOF)
243 port_source = GPIO_PortSourceGPIOF;
247 else if (port_ == GPIOG)
249 port_source = GPIO_PortSourceGPIOG;
253 else if (port_ == GPIOH)
255 port_source = GPIO_PortSourceGPIOH;
259 else if (port_ == GPIOI)
261 port_source = GPIO_PortSourceGPIOI;
265 ASSERT(port_source != 0xFF);
267 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
268 GPIO_EXTILineConfig(port_source, pin_source);
270 exti.EXTI_Line = 1 << pin_source;
271 exti.EXTI_Mode = EXTI_Mode_Interrupt;
272 exti.EXTI_Trigger = trigger;
273 exti.EXTI_LineCmd = ENABLE;
276 NVIC_EnableIRQ(irq_);
279uint8_t CH32GPIO::GetEXTIID(uint16_t pin) {
return __builtin_ctz(pin); }
ErrorCode SetConfig(Configuration config) override
配置 GPIO 引脚参数。Configures the GPIO pin settings.
ErrorCode DisableInterrupt() override
禁用 GPIO 引脚中断。Disables the GPIO pin interrupt.
bool Read() override
读取 GPIO 引脚状态。Reads the GPIO pin state.
ErrorCode Write(bool value) override
写入 GPIO 引脚状态。Writes the GPIO pin state.
ErrorCode EnableInterrupt() override
使能 GPIO 引脚中断。Enables the GPIO pin interrupt.
void Run(bool in_isr, PassArgs &&...args) const
执行回调函数,并传递参数。 Executes the callback function, passing the arguments.
bool Empty() const
检查回调是否为空。 Checks if the callback is empty.
Callback callback_
GPIO 事件的回调函数。Callback function for GPIO events.
Direction
定义 GPIO 引脚的方向类型。Defines the direction types for GPIO pins.
@ OUTPUT_PUSH_PULL
推挽输出模式。Push-pull output mode.
@ RISING_INTERRUPT
上升沿中断模式。Rising edge interrupt mode.
@ FALL_RISING_INTERRUPT
双沿触发中断模式。Both edge interrupt mode.
@ OUTPUT_OPEN_DRAIN
开漏输出模式。Open-drain output mode.
@ FALL_INTERRUPT
下降沿中断模式。Falling edge interrupt mode.
Pull
定义 GPIO 引脚的上拉/下拉模式。Defines the pull-up/pull-down configurations for GPIO pins.
@ DOWN
下拉模式。Pull-down mode.
存储 GPIO 配置参数的结构体。Structure storing GPIO configuration parameters.
Pull pull
GPIO 上拉/下拉配置。GPIO pull-up/pull-down configuration.
Direction direction
GPIO 引脚方向。GPIO pin direction.