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#if defined(GPIOF)
31 else if (port == GPIOF)
32 return RCC_APB2Periph_GPIOF;
33#endif
34#if defined(GPIOG)
35 else if (port == GPIOG)
36 return RCC_APB2Periph_GPIOG;
37#endif
38#if defined(GPIOH)
39 else if (port == GPIOH)
40 return RCC_APB2Periph_GPIOH;
41#endif
42#if defined(GPIOI)
43 else if (port == GPIOI)
44 return RCC_APB2Periph_GPIOI;
45#endif
46 return 0;
47}
48
49extern "C" void EXTI0_IRQHandler(void) __attribute__((interrupt));
50extern "C" void EXTI0_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line0); }
51
52extern "C" void EXTI1_IRQHandler(void) __attribute__((interrupt));
53extern "C" void EXTI1_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line1); }
54
55extern "C" void EXTI2_IRQHandler(void) __attribute__((interrupt));
56extern "C" void EXTI2_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line2); }
57
58extern "C" void EXTI3_IRQHandler(void) __attribute__((interrupt));
59extern "C" void EXTI3_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line3); }
60
61extern "C" void EXTI4_IRQHandler(void) __attribute__((interrupt));
62extern "C" void EXTI4_IRQHandler(void) { LibXR::CH32GPIO::CheckInterrupt(EXTI_Line4); }
63
64extern "C" void EXTI9_5_IRQHandler(void) __attribute__((interrupt));
65extern "C" void EXTI9_5_IRQHandler(void)
66{
67 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line5);
68 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line6);
69 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line7);
70 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line8);
71 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line9);
72}
73
74extern "C" void EXTI15_10_IRQHandler(void) __attribute__((interrupt));
75extern "C" void EXTI15_10_IRQHandler(void)
76{
77 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line10);
78 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line11);
79 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line12);
80 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line13);
81 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line14);
82 LibXR::CH32GPIO::CheckInterrupt(EXTI_Line15);
83}
84
85CH32GPIO::CH32GPIO(GPIO_TypeDef* port, uint16_t pin, GPIO::Direction direction,
86 GPIO::Pull pull, IRQn_Type irq)
87 : port_(port), pin_(pin), irq_(irq)
88{
89 if (irq_ != NonMaskableInt_IRQn)
90 {
91 NVIC_EnableIRQ(irq_);
92 map[GetEXTIID(pin)] = this;
93 }
94
95 RCC_APB2PeriphClockCmd(CH32GetGPIOPeriph(port_), ENABLE);
96
97 GPIO_InitTypeDef gpio_init = {};
98 gpio_init.GPIO_Pin = pin_;
99 gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
100
101 switch (direction)
102 {
103 case Direction::RISING_INTERRUPT:
104 case Direction::FALL_INTERRUPT:
105 case Direction::FALL_RISING_INTERRUPT:
106 case Direction::INPUT:
107 gpio_init.GPIO_Mode = (pull == Pull::UP) ? GPIO_Mode_IPU
108 : (pull == Pull::DOWN) ? GPIO_Mode_IPD
109 : GPIO_Mode_IN_FLOATING;
110 break;
111 case Direction::OUTPUT_PUSH_PULL:
112 gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
113 break;
114 case Direction::OUTPUT_OPEN_DRAIN:
115 gpio_init.GPIO_Mode = GPIO_Mode_Out_OD;
116 break;
117 }
118
119 GPIO_Init(port_, &gpio_init);
120
121 switch (direction)
122 {
123 case Direction::RISING_INTERRUPT:
124 ConfigureEXTI(EXTI_Trigger_Rising);
125 break;
126 case Direction::FALL_INTERRUPT:
127 ConfigureEXTI(EXTI_Trigger_Falling);
128 break;
129 case Direction::FALL_RISING_INTERRUPT:
130 ConfigureEXTI(EXTI_Trigger_Rising_Falling);
131 break;
132 default:
133 break;
134 }
135}
136
137bool CH32GPIO::Read() { return GPIO_ReadInputDataBit(port_, pin_) == Bit_SET; }
138
139ErrorCode CH32GPIO::Write(bool value)
140{
141 if (value)
142 GPIO_SetBits(port_, pin_);
143 else
144 GPIO_ResetBits(port_, pin_);
145 return ErrorCode::OK;
146}
147
149{
150 EXTI->INTENR |= (1 << GetEXTIID(pin_));
151 return ErrorCode::OK;
152}
153
155{
156 EXTI->INTENR &= ~(1 << GetEXTIID(pin_));
157 return ErrorCode::OK;
158}
159
161{
162 GPIO_InitTypeDef gpio_init = {};
163 gpio_init.GPIO_Pin = pin_;
164 gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
165
166 switch (config.direction)
167 {
168 case Direction::INPUT:
169 gpio_init.GPIO_Mode = (config.pull == Pull::UP) ? GPIO_Mode_IPU
170 : (config.pull == Pull::DOWN) ? GPIO_Mode_IPD
171 : GPIO_Mode_IN_FLOATING;
172 break;
174 gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
175 break;
177 gpio_init.GPIO_Mode = GPIO_Mode_Out_OD;
178 break;
182 gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
183 break;
184 }
185
186 GPIO_Init(port_, &gpio_init);
187
188 switch (config.direction)
189 {
191 ConfigureEXTI(EXTI_Trigger_Rising);
192 break;
194 ConfigureEXTI(EXTI_Trigger_Falling);
195 break;
197 ConfigureEXTI(EXTI_Trigger_Rising_Falling);
198 break;
199 default:
200 break;
201 }
202
203 return ErrorCode::OK;
204}
205
206void CH32GPIO::OnInterrupt()
207{
208 if (!callback_.Empty())
209 {
210 callback_.Run(true);
211 }
212}
213
214void CH32GPIO::CheckInterrupt(uint32_t line)
215{
216 if (EXTI_GetITStatus(line) != RESET)
217 {
218 EXTI_ClearITPendingBit(line);
219 map[GetEXTIID(line)]->OnInterrupt();
220 }
221}
222
223void CH32GPIO::ConfigureEXTI(EXTITrigger_TypeDef trigger)
224{
225 EXTI_InitTypeDef exti = {};
226 uint8_t pin_source = __builtin_ctz(pin_);
227 uint8_t port_source = 0xFF;
228
229#if defined(GPIOA)
230 if (port_ == GPIOA) port_source = GPIO_PortSourceGPIOA;
231#endif
232#if defined(GPIOB)
233 else if (port_ == GPIOB)
234 {
235 port_source = GPIO_PortSourceGPIOB;
236 }
237#endif
238#if defined(GPIOC)
239 else if (port_ == GPIOC)
240 {
241 port_source = GPIO_PortSourceGPIOC;
242 }
243#endif
244#if defined(GPIOD)
245 else if (port_ == GPIOD)
246 {
247 port_source = GPIO_PortSourceGPIOD;
248 }
249#endif
250#if defined(GPIOE)
251 else if (port_ == GPIOE)
252 {
253 port_source = GPIO_PortSourceGPIOE;
254 }
255#endif
256#if defined(GPIOF)
257 else if (port_ == GPIOF)
258 {
259 port_source = GPIO_PortSourceGPIOF;
260 }
261#endif
262#if defined(GPIOG)
263 else if (port_ == GPIOG)
264 {
265 port_source = GPIO_PortSourceGPIOG;
266 }
267#endif
268#if defined(GPIOH)
269 else if (port_ == GPIOH)
270 {
271 port_source = GPIO_PortSourceGPIOH;
272 }
273#endif
274#if defined(GPIOI)
275 else if (port_ == GPIOI)
276 {
277 port_source = GPIO_PortSourceGPIOI;
278 }
279#endif
280
281 ASSERT(port_source != 0xFF);
282
283 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
284 GPIO_EXTILineConfig(port_source, pin_source);
285
286 exti.EXTI_Line = 1 << pin_source;
287 exti.EXTI_Mode = EXTI_Mode_Interrupt;
288 exti.EXTI_Trigger = trigger;
289 exti.EXTI_LineCmd = ENABLE;
290 EXTI_Init(&exti);
291
292 NVIC_EnableIRQ(irq_);
293}
294
295uint8_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