Skip to content

Commit 2fb616e

Browse files
cybertalegalak
authored andcommitted
soc: arm: st_stm32: Using LL library to implement gpio functions
The original implementation of gpio functions access registers directly. Using LL library can add a set of unifying access functions for all series of stm32 for avoiding accessing low level code, and improve readability. Signed-off-by: Song Qiang <[email protected]>
1 parent 9612f9d commit 2fb616e

27 files changed

+176
-567
lines changed

drivers/gpio/gpio_stm32.c

Lines changed: 144 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,6 @@
1919
#include "gpio_stm32.h"
2020
#include "gpio_utils.h"
2121

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-
3122
/**
3223
* @brief Common GPIO driver for STM32 MCUs.
3324
*/
@@ -40,7 +31,7 @@ static void gpio_stm32_isr(int line, void *arg)
4031
struct device *dev = arg;
4132
struct gpio_stm32_data *data = dev->driver_data;
4233

43-
if (BIT(line) & data->cb_pins) {
34+
if ((BIT(line) & data->cb_pins) != 0) {
4435
_gpio_fire_callbacks(&data->cb, dev, BIT(line));
4536
}
4637
}
@@ -75,109 +66,141 @@ const int gpio_stm32_flags_to_conf(int flags, int *pincfg)
7566
return 0;
7667
}
7768

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+
7889
/**
7990
* @brief Configure the hardware.
8091
*/
8192
int gpio_stm32_configure(u32_t *base_addr, int pin, int conf, int altf)
8293
{
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);
8597
#ifdef CONFIG_SOC_SERIES_STM32F1X
86-
int cnf, mode, mode_io;
87-
int crpin = pin;
98+
ARG_UNUSED(altf);
8899

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);
93101

94-
ARG_UNUSED(altf);
102+
if (temp == STM32_MODE_INPUT) {
103+
temp = conf & (STM32_CNF_IN_MASK << STM32_CNF_IN_SHIFT);
95104

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);
100111

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);
109113

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+
}
130119
}
120+
131121
} 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);
149123

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+
}
160137

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);
165139

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);
168150

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);
171153

172-
scratch = gpio->otyper & ~(STM32_OTYPER_MASK << pin);
173-
gpio->otyper = scratch | (otype << pin);
154+
temp = conf & (STM32_OTYPER_MASK << STM32_OTYPER_SHIFT);
174155

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);
177163

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);
180175
#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+
181204
return 0;
182205
}
183206

@@ -186,15 +209,6 @@ int gpio_stm32_configure(u32_t *base_addr, int pin, int conf, int altf)
186209
*/
187210
const int gpio_stm32_enable_int(int port, int pin)
188211
{
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-
198212
#if defined(CONFIG_SOC_SERIES_STM32F2X) || \
199213
defined(CONFIG_SOC_SERIES_STM32F3X) || \
200214
defined(CONFIG_SOC_SERIES_STM32F4X) || \
@@ -208,20 +222,20 @@ const int gpio_stm32_enable_int(int port, int pin)
208222
/* Enable SYSCFG clock */
209223
clock_control_on(clk, (clock_control_subsys_t *) &pclken);
210224
#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) {
222229
return -EINVAL;
223230
}
224231

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+
225239
#ifdef CONFIG_SOC_SERIES_STM32L0X
226240
/*
227241
* 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)
233247
}
234248
#endif
235249

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
240255

241256
return 0;
242257
}
@@ -259,30 +274,30 @@ static int gpio_stm32_config(struct device *dev, int access_op,
259274
* configuration
260275
*/
261276
map_res = gpio_stm32_flags_to_conf(flags, &pincfg);
262-
if (map_res) {
277+
if (map_res != 0) {
263278
return map_res;
264279
}
265280

266-
if (gpio_stm32_configure(cfg->base, pin, pincfg, 0)) {
281+
if (gpio_stm32_configure(cfg->base, pin, pincfg, 0) != 0) {
267282
return -EIO;
268283
}
269284

270-
if (flags & GPIO_INT) {
285+
if ((flags & GPIO_INT) != 0) {
271286

272287
if (stm32_exti_set_callback(pin, cfg->port,
273-
gpio_stm32_isr, dev)) {
288+
gpio_stm32_isr, dev) != 0) {
274289
return -EBUSY;
275290
}
276291

277292
gpio_stm32_enable_int(cfg->port, pin);
278293

279-
if (flags & GPIO_INT_EDGE) {
294+
if ((flags & GPIO_INT_EDGE) != 0) {
280295
int edge = 0;
281296

282-
if (flags & GPIO_INT_DOUBLE_EDGE) {
297+
if ((flags & GPIO_INT_DOUBLE_EDGE) != 0) {
283298
edge = STM32_EXTI_TRIG_RISING |
284299
STM32_EXTI_TRIG_FALLING;
285-
} else if (flags & GPIO_INT_ACTIVE_HIGH) {
300+
} else if ((flags & GPIO_INT_ACTIVE_HIGH) != 0) {
286301
edge = STM32_EXTI_TRIG_RISING;
287302
} else {
288303
edge = STM32_EXTI_TRIG_FALLING;
@@ -304,17 +319,17 @@ static int gpio_stm32_write(struct device *dev, int access_op,
304319
u32_t pin, u32_t value)
305320
{
306321
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;
309323

310324
if (access_op != GPIO_ACCESS_BY_PIN) {
311325
return -ENOTSUP;
312326
}
313327

328+
pin = stm32_pinval_get(pin);
314329
if (value != 0) {
315-
gpio->odr |= pval;
330+
LL_GPIO_SetOutputPin(gpio, pin);
316331
} else {
317-
gpio->odr &= ~pval;
332+
LL_GPIO_ResetOutputPin(gpio, pin);
318333
}
319334

320335
return 0;
@@ -327,13 +342,13 @@ static int gpio_stm32_read(struct device *dev, int access_op,
327342
u32_t pin, u32_t *value)
328343
{
329344
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;
331346

332347
if (access_op != GPIO_ACCESS_BY_PIN) {
333348
return -ENOTSUP;
334349
}
335350

336-
*value = (gpio->idr >> pin) & 0x1;
351+
*value = (LL_GPIO_ReadInputPort(gpio) >> pin) & 0x1;
337352

338353
return 0;
339354
}

0 commit comments

Comments
 (0)