libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
ch32_gpio.cpp
1#include "ch32_gpio.hpp"
2
3using namespace LibXR;
4
5uint32_t LibXR::CH32GetGPIOPeriph(GPIO_TypeDef* port)
6{
7 if (false)
8 {
9 }
10#if defined(GPIOA)
11 else if (port == GPIOA)
12 return RCC_APB2Periph_GPIOA;
13#endif
14#if defined(GPIOB)
15 else if (port == GPIOB)
16 return RCC_APB2Periph_GPIOB;
17#endif
18#if defined(GPIOC)
19 else if (port == GPIOC)
20 return RCC_APB2Periph_GPIOC;
21#endif
22#if defined(GPIOD)
23 else if (port == GPIOD)
24 return RCC_APB2Periph_GPIOD;
25#endif
26#if defined(GPIOE)
27 else if (port == GPIOE)
28 return RCC_APB2Periph_GPIOE;
29#endif
30 return 0;
31}
32
33extern "C" void EXTI0_IRQHandler(void) __attribute__((interrupt));
34extern "C" void EXTI0_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line0); }
35
36extern "C" void EXTI1_IRQHandler(void) __attribute__((interrupt));
37extern "C" void EXTI1_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line1); }
38
39extern "C" void EXTI2_IRQHandler(void) __attribute__((interrupt));
40extern "C" void EXTI2_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line2); }
41
42extern "C" void EXTI3_IRQHandler(void) __attribute__((interrupt));
43extern "C" void EXTI3_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line3); }
44
45extern "C" void EXTI4_IRQHandler(void) __attribute__((interrupt));
46extern "C" void EXTI4_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line4); }
47
48extern "C" void EXTI9_5_IRQHandler(void) __attribute__((interrupt));
49extern "C" void EXTI9_5_IRQHandler(void)
50{
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);
56}
57
58extern "C" void EXTI15_10_IRQHandler(void) __attribute__((interrupt));
59extern "C" void EXTI15_10_IRQHandler(void)
60{
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);
67}
68
69CH32GPIO::CH32GPIO(GPIO_TypeDef* port, uint16_t pin, GPIO::Direction direction,
70 GPIO::Pull pull, IRQn_Type irq)
71 : port_(port), pin_(pin), irq_(irq)
72{
73 if (irq_ != NonMaskableInt_IRQn)
74 {
75 NVIC_EnableIRQ(irq_);
76 map[GetEXTIID(pin)] = this;
77 }
78
79 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(port_), ENABLE);
80
81 GPIO_InitTypeDef gpio_init = {};
82 gpio_init.GPIO_Pin = pin_;
83 gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
84
85 switch (direction)
86 {
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;
94 break;
95 case Direction::OUTPUT_PUSH_PULL:
96 gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
97 break;
98 case Direction::OUTPUT_OPEN_DRAIN:
99 gpio_init.GPIO_Mode = GPIO_Mode_Out_OD;
100 break;
101 }
102
103 GPIO_Init(port_, &gpio_init);
104
105 switch (direction)
106 {
107 case Direction::RISING_INTERRUPT:
108 ConfigureEXTI(EXTI_Trigger_Rising);
109 break;
110 case Direction::FALL_INTERRUPT:
111 ConfigureEXTI(EXTI_Trigger_Falling);
112 break;
113 case Direction::FALL_RISING_INTERRUPT:
114 ConfigureEXTI(EXTI_Trigger_Rising_Falling);
115 break;
116 default:
117 break;
118 }
119}
120
121bool CH32GPIO::Read() { return GPIO_ReadInputDataBit(port_, pin_) == Bit_SET; }
122
123ErrorCode CH32GPIO::Write(bool value)
124{
125 if (value)
126 GPIO_SetBits(port_, pin_);
127 else
128 GPIO_ResetBits(port_, pin_);
129 return ErrorCode::OK;
130}
131
133{
134 EXTI->INTENR |= (1 << GetEXTIID(pin_));
135 return ErrorCode::OK;
136}
137
139{
140 EXTI->INTENR &= ~(1 << GetEXTIID(pin_));
141 return ErrorCode::OK;
142}
143
145{
146 GPIO_InitTypeDef gpio_init = {};
147 gpio_init.GPIO_Pin = pin_;
148 gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
149
150 switch (config.direction)
151 {
152 case Direction::INPUT:
153 gpio_init.GPIO_Mode = (config.pull == Pull::UP) ? GPIO_Mode_IPU
154 : (config.pull == Pull::DOWN) ? GPIO_Mode_IPD
155 : GPIO_Mode_IN_FLOATING;
156 break;
158 gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
159 break;
161 gpio_init.GPIO_Mode = GPIO_Mode_Out_OD;
162 break;
166 gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
167 break;
168 }
169
170 GPIO_Init(port_, &gpio_init);
171
172 switch (config.direction)
173 {
175 ConfigureEXTI(EXTI_Trigger_Rising);
176 break;
178 ConfigureEXTI(EXTI_Trigger_Falling);
179 break;
181 ConfigureEXTI(EXTI_Trigger_Rising_Falling);
182 break;
183 default:
184 break;
185 }
186
187 return ErrorCode::OK;
188}
189
190void CH32GPIO::OnInterrupt()
191{
192 if (!callback_.Empty())
193 {
194 callback_.Run(true);
195 }
196}
197
198void CH32GPIO::CheckInterrupt(uint32_t line)
199{
200 if (EXTI_GetITStatus(line) != RESET)
201 {
202 EXTI_ClearITPendingBit(line);
203 map[GetEXTIID(line)]->OnInterrupt();
204 }
205}
206
207void CH32GPIO::ConfigureEXTI(EXTITrigger_TypeDef trigger)
208{
209 EXTI_InitTypeDef exti = {};
210 uint8_t pin_source = __builtin_ctz(pin_);
211 uint8_t port_source = 0xFF;
212
213#if defined(GPIOA)
214 if (port_ == GPIOA) port_source = GPIO_PortSourceGPIOA;
215#endif
216#if defined(GPIOB)
217 else if (port_ == GPIOB)
218 {
219 port_source = GPIO_PortSourceGPIOB;
220 }
221#endif
222#if defined(GPIOC)
223 else if (port_ == GPIOC)
224 {
225 port_source = GPIO_PortSourceGPIOC;
226 }
227#endif
228#if defined(GPIOD)
229 else if (port_ == GPIOD)
230 {
231 port_source = GPIO_PortSourceGPIOD;
232 }
233#endif
234#if defined(GPIOE)
235 else if (port_ == GPIOE)
236 {
237 port_source = GPIO_PortSourceGPIOE;
238 }
239#endif
240#if defined(GPIOF)
241 else if (port_ == GPIOF)
242 {
243 port_source = GPIO_PortSourceGPIOF;
244 }
245#endif
246#if defined(GPIOG)
247 else if (port_ == GPIOG)
248 {
249 port_source = GPIO_PortSourceGPIOG;
250 }
251#endif
252#if defined(GPIOH)
253 else if (port_ == GPIOH)
254 {
255 port_source = GPIO_PortSourceGPIOH;
256 }
257#endif
258#if defined(GPIOI)
259 else if (port_ == GPIOI)
260 {
261 port_source = GPIO_PortSourceGPIOI;
262 }
263#endif
264
265 ASSERT(port_source != 0xFF);
266
267 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
268 GPIO_EXTILineConfig(port_source, pin_source);
269
270 exti.EXTI_Line = 1 << pin_source;
271 exti.EXTI_Mode = EXTI_Mode_Interrupt;
272 exti.EXTI_Trigger = trigger;
273 exti.EXTI_LineCmd = ENABLE;
274 EXTI_Init(&exti);
275
276 NVIC_EnableIRQ(irq_);
277}
278
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.
Definition libxr_cb.hpp:207
bool Empty() const
检查回调是否为空。 Checks if the callback is empty.
Definition libxr_cb.hpp:222
Callback callback_
GPIO 事件的回调函数。Callback function for GPIO events.
Definition gpio.hpp:56
Direction
定义 GPIO 引脚的方向类型。Defines the direction types for GPIO pins.
Definition gpio.hpp:20
@ 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.
@ INPUT
输入模式。Input mode.
@ FALL_INTERRUPT
下降沿中断模式。Falling edge interrupt mode.
Pull
定义 GPIO 引脚的上拉/下拉模式。Defines the pull-up/pull-down configurations for GPIO pins.
Definition gpio.hpp:35
@ DOWN
下拉模式。Pull-down mode.
@ UP
上拉模式。Pull-up mode.
LibXR 命名空间
Definition ch32_gpio.hpp:9
存储 GPIO 配置参数的结构体。Structure storing GPIO configuration parameters.
Definition gpio.hpp:46
Pull pull
GPIO 上拉/下拉配置。GPIO pull-up/pull-down configuration.
Definition gpio.hpp:48
Direction direction
GPIO 引脚方向。GPIO pin direction.
Definition gpio.hpp:47