1 /*
2 * Copyright (c) 2012 Travis Geiselbrecht
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8 #include <lk/debug.h>
9 #include <assert.h>
10 #include <dev/gpio.h>
11 #include <platform/stm32.h>
12 #include <platform/gpio.h>
13 #include <stm32f4xx_gpio.h>
14 #include <stm32f4xx_rcc.h>
15
port_to_pointer(unsigned int port)16 static GPIO_TypeDef *port_to_pointer(unsigned int port) {
17 switch (port) {
18 default:
19 case GPIO_PORT_A:
20 return GPIOA;
21 case GPIO_PORT_B:
22 return GPIOB;
23 case GPIO_PORT_C:
24 return GPIOC;
25 case GPIO_PORT_D:
26 return GPIOD;
27 case GPIO_PORT_E:
28 return GPIOE;
29 case GPIO_PORT_F:
30 return GPIOF;
31 case GPIO_PORT_G:
32 return GPIOG;
33 case GPIO_PORT_H:
34 return GPIOH;
35 case GPIO_PORT_I:
36 return GPIOI;
37 }
38 }
39
enable_port(unsigned int port)40 static void enable_port(unsigned int port) {
41 DEBUG_ASSERT(port <= GPIO_PORT_I);
42
43 /* happens to be the RCC ids are sequential bits, so we can start from A and shift */
44 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA << port, ENABLE);
45 }
46
stm32_gpio_early_init(void)47 void stm32_gpio_early_init(void) {
48 }
49
gpio_config(unsigned nr,unsigned flags)50 int gpio_config(unsigned nr, unsigned flags) {
51
52 uint port = GPIO_PORT(nr);
53 uint pin = GPIO_PIN(nr);
54
55 enable_port(port);
56
57 GPIO_InitTypeDef init;
58 init.GPIO_Speed = GPIO_Speed_50MHz;
59 init.GPIO_Pin = (1 << pin);
60 init.GPIO_PuPd = GPIO_PuPd_NOPULL;
61
62 if (flags & GPIO_INPUT) {
63 init.GPIO_Mode = GPIO_Mode_IN;
64 } else if (flags & GPIO_OUTPUT) {
65 init.GPIO_Mode = GPIO_Mode_OUT;
66 } else if (flags & GPIO_STM32_AF) {
67 init.GPIO_Mode = GPIO_Mode_AF;
68 GPIO_PinAFConfig(port_to_pointer(port), pin, GPIO_AFNUM(flags));
69 }
70
71 if (flags & GPIO_PULLUP) {
72 init.GPIO_PuPd = GPIO_PuPd_UP;
73 } else if (flags & GPIO_PULLDOWN) {
74 init.GPIO_PuPd = GPIO_PuPd_DOWN;
75 }
76
77 if (flags & GPIO_STM32_OD) {
78 init.GPIO_OType = GPIO_OType_OD;
79 } else {
80 init.GPIO_OType = GPIO_OType_PP;
81 }
82
83 GPIO_Init(port_to_pointer(port), &init);
84
85 return 0;
86 }
87
gpio_set(unsigned nr,unsigned on)88 void gpio_set(unsigned nr, unsigned on) {
89 GPIO_WriteBit(port_to_pointer(GPIO_PORT(nr)), 1 << GPIO_PIN(nr), on);
90 }
91
gpio_get(unsigned nr)92 int gpio_get(unsigned nr) {
93 return GPIO_ReadInputDataBit(port_to_pointer(GPIO_PORT(nr)), 1 << GPIO_PIN(nr));
94 }
95
96