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 <stm32f10x_gpio.h>
14 #include <stm32f10x_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 }
34 }
35
enable_port(unsigned int port)36 static void enable_port(unsigned int port) {
37 DEBUG_ASSERT(port <= GPIO_PORT_G);
38
39 /* happens to be the RCC ids are sequential bits, so we can start from A and shift */
40 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA << port, ENABLE);
41 }
42
stm32_gpio_early_init(void)43 void stm32_gpio_early_init(void) {
44 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
45 }
46
gpio_config(unsigned nr,unsigned flags)47 int gpio_config(unsigned nr, unsigned flags) {
48 uint port = GPIO_PORT(nr);
49 uint pin = GPIO_PIN(nr);
50
51 enable_port(port);
52
53 GPIO_InitTypeDef init;
54 init.GPIO_Speed = GPIO_Speed_50MHz;
55
56 init.GPIO_Pin = (1 << pin);
57
58 if (flags & GPIO_STM32_AF) {
59 if (flags & GPIO_STM32_OD)
60 init.GPIO_Mode = GPIO_Mode_Out_OD;
61 else
62 init.GPIO_Mode = GPIO_Mode_AF_PP;
63 } else if (flags & GPIO_OUTPUT) {
64 if (flags & GPIO_STM32_OD)
65 init.GPIO_Mode = GPIO_Mode_Out_OD;
66 else
67 init.GPIO_Mode = GPIO_Mode_Out_PP;
68 } else { // GPIO_INPUT
69 if (flags & GPIO_PULLUP) {
70 init.GPIO_Mode = GPIO_Mode_IPU;
71 } else if (flags & GPIO_PULLDOWN) {
72 init.GPIO_Mode = GPIO_Mode_IPD;
73 } else {
74 init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
75 }
76 }
77
78 GPIO_Init(port_to_pointer(port), &init);
79
80 return 0;
81 }
82
gpio_set(unsigned nr,unsigned on)83 void gpio_set(unsigned nr, unsigned on) {
84 GPIO_WriteBit(port_to_pointer(GPIO_PORT(nr)), 1 << GPIO_PIN(nr), on);
85 }
86
gpio_get(unsigned nr)87 int gpio_get(unsigned nr) {
88 return GPIO_ReadInputDataBit(port_to_pointer(GPIO_PORT(nr)), 1 << GPIO_PIN(nr));
89 }
90
91