19
19
#include "gpio_stm32.h"
20
20
#include "gpio_utils.h"
21
21
22
- /* F1 series STM32 use AFIO register to configure interrupt generation
23
- * and pinmux.
24
- */
25
- #ifdef CONFIG_SOC_SERIES_STM32F1X
26
- #include "afio_registers.h"
27
- #else
28
- #include "syscfg_registers.h"
29
- #endif
30
-
31
22
/**
32
23
* @brief Common GPIO driver for STM32 MCUs.
33
24
*/
@@ -40,7 +31,7 @@ static void gpio_stm32_isr(int line, void *arg)
40
31
struct device * dev = arg ;
41
32
struct gpio_stm32_data * data = dev -> driver_data ;
42
33
43
- if (BIT (line ) & data -> cb_pins ) {
34
+ if (( BIT (line ) & data -> cb_pins ) != 0 ) {
44
35
_gpio_fire_callbacks (& data -> cb , dev , BIT (line ));
45
36
}
46
37
}
@@ -75,109 +66,141 @@ const int gpio_stm32_flags_to_conf(int flags, int *pincfg)
75
66
return 0 ;
76
67
}
77
68
69
+ /**
70
+ * @brief Translate pin to pinval that the LL library needs
71
+ */
72
+ static inline u32_t stm32_pinval_get (int pin )
73
+ {
74
+ u32_t pinval ;
75
+
76
+ #ifdef CONFIG_SOC_SERIES_STM32F1X
77
+ pinval = (1 << pin ) << GPIO_PIN_MASK_POS ;
78
+ if (pin < 8 ) {
79
+ pinval |= 1 << pin ;
80
+ } else {
81
+ pinval |= (1 << pin ) | 0x04000000 ;
82
+ }
83
+ #else
84
+ pinval = 1 << pin ;
85
+ #endif
86
+ return pinval ;
87
+ }
88
+
78
89
/**
79
90
* @brief Configure the hardware.
80
91
*/
81
92
int gpio_stm32_configure (u32_t * base_addr , int pin , int conf , int altf )
82
93
{
83
- volatile struct stm32_gpio * gpio =
84
- (struct stm32_gpio * )(base_addr );
94
+ GPIO_TypeDef * gpio = (GPIO_TypeDef * )base_addr ;
95
+
96
+ int pin_ll = stm32_pinval_get (pin );
85
97
#ifdef CONFIG_SOC_SERIES_STM32F1X
86
- int cnf , mode , mode_io ;
87
- int crpin = pin ;
98
+ ARG_UNUSED (altf );
88
99
89
- /* pins are configured in CRL (0-7) and CRH (8-15)
90
- * registers
91
- */
92
- volatile u32_t * reg = & gpio -> crl ;
100
+ u32_t temp = conf & (STM32_MODE_INOUT_MASK << STM32_MODE_INOUT_SHIFT );
93
101
94
- ARG_UNUSED (altf );
102
+ if (temp == STM32_MODE_INPUT ) {
103
+ temp = conf & (STM32_CNF_IN_MASK << STM32_CNF_IN_SHIFT );
95
104
96
- if (crpin > 7 ) {
97
- reg = & gpio -> crh ;
98
- crpin -= 8 ;
99
- }
105
+ if (temp == STM32_CNF_IN_ANALOG ) {
106
+ LL_GPIO_SetPinMode (gpio , pin_ll , LL_GPIO_MODE_ANALOG );
107
+ } else if (temp == STM32_CNF_IN_FLOAT ) {
108
+ LL_GPIO_SetPinMode (gpio , pin_ll , LL_GPIO_MODE_FLOATING );
109
+ } else {
110
+ LL_GPIO_SetPinMode (gpio , pin_ll , LL_GPIO_MODE_INPUT );
100
111
101
- /* each port is configured by 2 registers:
102
- * CNFy[1:0]: Port x configuration bits
103
- * MODEy[1:0]: Port x mode bits
104
- *
105
- * memory layout is repeated for every port:
106
- * | CNF | MODE |
107
- * | [0:1] | [0:1] |
108
- */
112
+ temp = conf & (STM32_PUPD_MASK << STM32_PUPD_SHIFT );
109
113
110
- mode_io = (conf >> STM32_MODE_INOUT_SHIFT ) & STM32_MODE_INOUT_MASK ;
111
-
112
- if (mode_io == STM32_MODE_INPUT ) {
113
- int in_pudpd = conf & (STM32_PUPD_MASK << STM32_PUPD_SHIFT );
114
-
115
- /* Pin configured in input mode */
116
- /* Mode: 00 */
117
- mode = mode_io ;
118
- /* Configuration values: */
119
- /* 00: Analog mode */
120
- /* 01: Floating input */
121
- /* 10: Pull-up/Pull-Down */
122
- cnf = (conf >> STM32_CNF_IN_SHIFT ) & STM32_CNF_IN_MASK ;
123
-
124
- if (in_pudpd == STM32_PUPD_PULL_UP ) {
125
- /* enable pull up */
126
- gpio -> odr |= 1 << pin ;
127
- } else if (in_pudpd == STM32_PUPD_PULL_DOWN ) {
128
- /* or pull down */
129
- gpio -> odr &= ~(1 << pin );
114
+ if (temp == STM32_PUPD_PULL_UP ) {
115
+ LL_GPIO_SetPinPull (gpio , pin_ll , LL_GPIO_PULL_UP );
116
+ } else {
117
+ LL_GPIO_SetPinPull (gpio , pin_ll , LL_GPIO_PULL_DOWN );
118
+ }
130
119
}
120
+
131
121
} else {
132
- /* Pin configured in output mode */
133
- int mode_speed = ((conf >> STM32_MODE_OSPEED_SHIFT ) &
134
- STM32_MODE_OSPEED_MASK );
135
- /* Mode output possible values */
136
- /* 01: Max speed 10MHz (default value) */
137
- /* 10: Max speed 2MHz */
138
- /* 11: Max speed 50MHz */
139
- mode = mode_speed + mode_io ;
140
- /* Configuration possible values */
141
- /* x0: Push-pull */
142
- /* x1: Open-drain */
143
- /* 0x: General Purpose Output */
144
- /* 1x: Alternate Function Output */
145
- cnf = ((conf >> STM32_CNF_OUT_0_SHIFT ) & STM32_CNF_OUT_0_MASK ) |
146
- (((conf >> STM32_CNF_OUT_1_SHIFT ) & STM32_CNF_OUT_1_MASK )
147
- << 1 );
148
- }
122
+ temp = conf & (STM32_CNF_OUT_1_MASK << STM32_CNF_OUT_1_SHIFT );
149
123
150
- /* clear bits */
151
- * reg &= ~(0xf << (crpin * 4 ));
152
- /* set bits */
153
- * reg |= (cnf << (crpin * 4 + 2 ) | mode << (crpin * 4 ));
154
- #else
155
- unsigned int mode , otype , ospeed , pupd ;
156
- unsigned int pin_shift = pin << 1 ;
157
- unsigned int afr_bank = pin / 8 ;
158
- unsigned int afr_shift = (pin % 8 ) << 2 ;
159
- u32_t scratch ;
124
+ if (temp == STM32_CNF_GP_OUTPUT ) {
125
+ LL_GPIO_SetPinMode (gpio , pin_ll , LL_GPIO_MODE_OUTPUT );
126
+ } else {
127
+ LL_GPIO_SetPinMode (gpio , pin_ll , LL_GPIO_MODE_ALTERNATE );
128
+ }
129
+
130
+ temp = conf & (STM32_CNF_OUT_0_MASK << STM32_CNF_OUT_0_SHIFT );
131
+
132
+ if (temp == STM32_CNF_PUSH_PULL ) {
133
+ LL_GPIO_SetPinOutputType (gpio , pin_ll , LL_GPIO_OUTPUT_PUSHPULL );
134
+ } else {
135
+ LL_GPIO_SetPinOutputType (gpio , pin_ll , LL_GPIO_OUTPUT_OPENDRAIN );
136
+ }
160
137
161
- mode = (conf >> STM32_MODER_SHIFT ) & STM32_MODER_MASK ;
162
- otype = (conf >> STM32_OTYPER_SHIFT ) & STM32_OTYPER_MASK ;
163
- ospeed = (conf >> STM32_OSPEEDR_SHIFT ) & STM32_OSPEEDR_MASK ;
164
- pupd = (conf >> STM32_PUPDR_SHIFT ) & STM32_PUPDR_MASK ;
138
+ temp = conf & (STM32_MODE_OSPEED_MASK << STM32_MODE_OSPEED_SHIFT );
165
139
166
- scratch = gpio -> moder & ~(STM32_MODER_MASK << pin_shift );
167
- gpio -> moder = scratch | (mode << pin_shift );
140
+ if (temp == STM32_MODE_OUTPUT_MAX_2 ) {
141
+ LL_GPIO_SetPinSpeed (gpio , pin_ll , LL_GPIO_SPEED_FREQ_LOW );
142
+ } else if (temp == STM32_MODE_OUTPUT_MAX_10 ) {
143
+ LL_GPIO_SetPinSpeed (gpio , pin_ll , LL_GPIO_SPEED_FREQ_MEDIUM );
144
+ } else {
145
+ LL_GPIO_SetPinSpeed (gpio , pin_ll , LL_GPIO_SPEED_FREQ_HIGH );
146
+ }
147
+ }
148
+ #else
149
+ u32_t temp = conf & (STM32_MODER_MASK << STM32_MODER_SHIFT );
168
150
169
- scratch = gpio -> ospeedr & ~( STM32_OSPEEDR_MASK << pin_shift );
170
- gpio -> ospeedr = scratch | ( ospeed << pin_shift );
151
+ if ( temp == STM32_MODER_OUTPUT_MODE ) {
152
+ LL_GPIO_SetPinMode ( gpio , pin_ll , LL_GPIO_MODE_OUTPUT );
171
153
172
- scratch = gpio -> otyper & ~(STM32_OTYPER_MASK << pin );
173
- gpio -> otyper = scratch | (otype << pin );
154
+ temp = conf & (STM32_OTYPER_MASK << STM32_OTYPER_SHIFT );
174
155
175
- scratch = gpio -> pupdr & ~(STM32_PUPDR_MASK << pin_shift );
176
- gpio -> pupdr = scratch | (pupd << pin_shift );
156
+ if (temp == STM32_OTYPER_PUSH_PULL ) {
157
+ LL_GPIO_SetPinOutputType (gpio , pin_ll , LL_GPIO_OUTPUT_PUSHPULL );
158
+ } else {
159
+ LL_GPIO_SetPinOutputType (gpio , pin_ll , LL_GPIO_OUTPUT_OPENDRAIN );
160
+ }
161
+
162
+ temp = conf & (STM32_OSPEEDR_MASK << STM32_OSPEEDR_SHIFT );
177
163
178
- scratch = gpio -> afr [afr_bank ] & ~(STM32_AFR_MASK << afr_shift );
179
- gpio -> afr [afr_bank ] = scratch | (altf << afr_shift );
164
+ if (temp == STM32_OSPEEDR_LOW_SPEED ) {
165
+ LL_GPIO_SetPinSpeed (gpio , pin_ll , LL_GPIO_SPEED_FREQ_LOW );
166
+ } else if (temp == STM32_OSPEEDR_MEDIUM_SPEED ) {
167
+ LL_GPIO_SetPinSpeed (gpio , pin_ll , LL_GPIO_SPEED_FREQ_MEDIUM );
168
+ } else if (temp == STM32_OSPEEDR_HIGH_SPEED ) {
169
+ LL_GPIO_SetPinSpeed (gpio , pin_ll , LL_GPIO_SPEED_FREQ_HIGH );
170
+ #if defined(CONFIG_SOC_SERIES_STM32F2X ) || defined(CONFIG_SOC_SERIES_STM32F4X ) || \
171
+ defined(CONFIG_SOC_SERIES_STM32F7X ) || defined(CONFIG_SOC_SERIES_STM32L0X ) || \
172
+ defined(CONFIG_SOC_SERIES_STM32L4X )
173
+ } else if (temp == STM32_OSPEEDR_VERY_HIGH_SPEED ) {
174
+ LL_GPIO_SetPinSpeed (gpio , pin_ll , LL_GPIO_SPEED_FREQ_VERY_HIGH );
180
175
#endif
176
+ } else {
177
+ return - EINVAL ;
178
+ }
179
+ } else if (temp == STM32_MODER_INPUT_MODE ) {
180
+ LL_GPIO_SetPinMode (gpio , pin_ll , LL_GPIO_MODE_INPUT );
181
+
182
+ temp = conf & (STM32_PUPDR_MASK << STM32_PUPDR_SHIFT );
183
+
184
+ if (temp == STM32_PUPDR_PULL_UP ) {
185
+ LL_GPIO_SetPinPull (gpio , pin_ll , LL_GPIO_PULL_UP );
186
+ } else if (temp == STM32_PUPDR_PULL_DOWN ) {
187
+ LL_GPIO_SetPinPull (gpio , pin_ll , LL_GPIO_PULL_DOWN );
188
+ } else {
189
+ LL_GPIO_SetPinPull (gpio , pin_ll , LL_GPIO_PULL_NO );
190
+ }
191
+ } else if (temp == STM32_MODER_ANALOG_MODE ) {
192
+ LL_GPIO_SetPinMode (gpio , pin_ll , LL_GPIO_MODE_ANALOG );
193
+ } else {
194
+ LL_GPIO_SetPinMode (gpio , pin_ll , LL_GPIO_MODE_ALTERNATE );
195
+
196
+ if (pin < 8 ) {
197
+ LL_GPIO_SetAFPin_0_7 (gpio , pin_ll , altf );
198
+ } else {
199
+ LL_GPIO_SetAFPin_8_15 (gpio , pin_ll , altf );
200
+ }
201
+ }
202
+ #endif /* CONFIG_SOC_SERIES_STM32F1X */
203
+
181
204
return 0 ;
182
205
}
183
206
@@ -186,15 +209,6 @@ int gpio_stm32_configure(u32_t *base_addr, int pin, int conf, int altf)
186
209
*/
187
210
const int gpio_stm32_enable_int (int port , int pin )
188
211
{
189
- #ifdef CONFIG_SOC_SERIES_STM32F1X
190
- volatile struct stm32_afio * syscfg =
191
- (struct stm32_afio * )AFIO_BASE ;
192
- #else
193
- volatile struct stm32_syscfg * syscfg =
194
- (struct stm32_syscfg * )SYSCFG_BASE ;
195
- #endif
196
- volatile union syscfg_exticr * exticr ;
197
-
198
212
#if defined(CONFIG_SOC_SERIES_STM32F2X ) || \
199
213
defined(CONFIG_SOC_SERIES_STM32F3X ) || \
200
214
defined(CONFIG_SOC_SERIES_STM32F4X ) || \
@@ -208,20 +222,20 @@ const int gpio_stm32_enable_int(int port, int pin)
208
222
/* Enable SYSCFG clock */
209
223
clock_control_on (clk , (clock_control_subsys_t * ) & pclken );
210
224
#endif
211
- int shift = 0 ;
212
-
213
- if (pin <= 3 ) {
214
- exticr = & syscfg -> exticr1 ;
215
- } else if (pin <= 7 ) {
216
- exticr = & syscfg -> exticr2 ;
217
- } else if (pin <= 11 ) {
218
- exticr = & syscfg -> exticr3 ;
219
- } else if (pin <= 15 ) {
220
- exticr = & syscfg -> exticr4 ;
221
- } else {
225
+
226
+ uint32_t line ;
227
+
228
+ if (pin > 15 ) {
222
229
return - EINVAL ;
223
230
}
224
231
232
+ #if defined(CONFIG_SOC_SERIES_STM32L0X ) || \
233
+ defined(CONFIG_SOC_SERIES_STM32F0X )
234
+ line = ((pin % 4 * 4 ) << 16 ) | (pin / 4 );
235
+ #else
236
+ line = (0xF << ((pin % 4 * 4 ) + 16 )) | (pin / 4 );
237
+ #endif
238
+
225
239
#ifdef CONFIG_SOC_SERIES_STM32L0X
226
240
/*
227
241
* Ports F and G are not present on some STM32L0 parts, so
@@ -233,10 +247,11 @@ const int gpio_stm32_enable_int(int port, int pin)
233
247
}
234
248
#endif
235
249
236
- shift = 4 * (pin % 4 );
237
-
238
- exticr -> val &= ~(0xf << shift );
239
- exticr -> val |= port << shift ;
250
+ #ifdef CONFIG_SOC_SERIES_STM32F1X
251
+ LL_GPIO_AF_SetEXTISource (port , line );
252
+ #else
253
+ LL_SYSCFG_SetEXTISource (port , line );
254
+ #endif
240
255
241
256
return 0 ;
242
257
}
@@ -259,30 +274,30 @@ static int gpio_stm32_config(struct device *dev, int access_op,
259
274
* configuration
260
275
*/
261
276
map_res = gpio_stm32_flags_to_conf (flags , & pincfg );
262
- if (map_res ) {
277
+ if (map_res != 0 ) {
263
278
return map_res ;
264
279
}
265
280
266
- if (gpio_stm32_configure (cfg -> base , pin , pincfg , 0 )) {
281
+ if (gpio_stm32_configure (cfg -> base , pin , pincfg , 0 ) != 0 ) {
267
282
return - EIO ;
268
283
}
269
284
270
- if (flags & GPIO_INT ) {
285
+ if (( flags & GPIO_INT ) != 0 ) {
271
286
272
287
if (stm32_exti_set_callback (pin , cfg -> port ,
273
- gpio_stm32_isr , dev )) {
288
+ gpio_stm32_isr , dev ) != 0 ) {
274
289
return - EBUSY ;
275
290
}
276
291
277
292
gpio_stm32_enable_int (cfg -> port , pin );
278
293
279
- if (flags & GPIO_INT_EDGE ) {
294
+ if (( flags & GPIO_INT_EDGE ) != 0 ) {
280
295
int edge = 0 ;
281
296
282
- if (flags & GPIO_INT_DOUBLE_EDGE ) {
297
+ if (( flags & GPIO_INT_DOUBLE_EDGE ) != 0 ) {
283
298
edge = STM32_EXTI_TRIG_RISING |
284
299
STM32_EXTI_TRIG_FALLING ;
285
- } else if (flags & GPIO_INT_ACTIVE_HIGH ) {
300
+ } else if (( flags & GPIO_INT_ACTIVE_HIGH ) != 0 ) {
286
301
edge = STM32_EXTI_TRIG_RISING ;
287
302
} else {
288
303
edge = STM32_EXTI_TRIG_FALLING ;
@@ -304,17 +319,17 @@ static int gpio_stm32_write(struct device *dev, int access_op,
304
319
u32_t pin , u32_t value )
305
320
{
306
321
const struct gpio_stm32_config * cfg = dev -> config -> config_info ;
307
- struct stm32_gpio * gpio = (struct stm32_gpio * )cfg -> base ;
308
- int pval = 1 << (pin & 0xf );
322
+ GPIO_TypeDef * gpio = (GPIO_TypeDef * )cfg -> base ;
309
323
310
324
if (access_op != GPIO_ACCESS_BY_PIN ) {
311
325
return - ENOTSUP ;
312
326
}
313
327
328
+ pin = stm32_pinval_get (pin );
314
329
if (value != 0 ) {
315
- gpio -> odr |= pval ;
330
+ LL_GPIO_SetOutputPin ( gpio , pin ) ;
316
331
} else {
317
- gpio -> odr &= ~ pval ;
332
+ LL_GPIO_ResetOutputPin ( gpio , pin ) ;
318
333
}
319
334
320
335
return 0 ;
@@ -327,13 +342,13 @@ static int gpio_stm32_read(struct device *dev, int access_op,
327
342
u32_t pin , u32_t * value )
328
343
{
329
344
const struct gpio_stm32_config * cfg = dev -> config -> config_info ;
330
- struct stm32_gpio * gpio = (struct stm32_gpio * )cfg -> base ;
345
+ GPIO_TypeDef * gpio = (GPIO_TypeDef * )cfg -> base ;
331
346
332
347
if (access_op != GPIO_ACCESS_BY_PIN ) {
333
348
return - ENOTSUP ;
334
349
}
335
350
336
- * value = (gpio -> idr >> pin ) & 0x1 ;
351
+ * value = (LL_GPIO_ReadInputPort ( gpio ) >> pin ) & 0x1 ;
337
352
338
353
return 0 ;
339
354
}
0 commit comments