blob: f4e59068d4bcfa97be0c86f51b95d7e8836f4b46 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2012 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <debug.h>
24#include <assert.h>
25#include <dev/gpio.h>
26#include <platform/stm32.h>
27#include <platform/gpio.h>
28#include <stm32f2xx_gpio.h>
29#include <stm32f2xx_rcc.h>
30
31static GPIO_TypeDef *port_to_pointer(unsigned int port)
32{
33 switch (port) {
34 default:
35 case GPIO_PORT_A:
36 return GPIOA;
37 case GPIO_PORT_B:
38 return GPIOB;
39 case GPIO_PORT_C:
40 return GPIOC;
41 case GPIO_PORT_D:
42 return GPIOD;
43 case GPIO_PORT_E:
44 return GPIOE;
45 case GPIO_PORT_F:
46 return GPIOF;
47 case GPIO_PORT_G:
48 return GPIOG;
49 case GPIO_PORT_H:
50 return GPIOH;
51 case GPIO_PORT_I:
52 return GPIOI;
53 }
54}
55
56static void enable_port(unsigned int port)
57{
58 DEBUG_ASSERT(port <= GPIO_PORT_I);
59
60 /* happens to be the RCC ids are sequential bits, so we can start from A and shift */
61 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA << port, ENABLE);
62}
63
64void stm32_gpio_early_init(void)
65{
66}
67
68int gpio_config(unsigned nr, unsigned flags)
69{
70
71 uint port = GPIO_PORT(nr);
72 uint pin = GPIO_PIN(nr);
73
74 enable_port(port);
75
76 GPIO_InitTypeDef init;
77 init.GPIO_Speed = GPIO_Speed_50MHz;
78 init.GPIO_Pin = (1 << pin);
79 init.GPIO_PuPd = GPIO_PuPd_NOPULL;
80
81 if (flags & GPIO_INPUT) {
82 init.GPIO_Mode = GPIO_Mode_IN;
83 } else if (flags & GPIO_OUTPUT) {
84 init.GPIO_Mode = GPIO_Mode_OUT;
85 } else if (flags & GPIO_STM32_AF) {
86 init.GPIO_Mode = GPIO_Mode_AF;
87 GPIO_PinAFConfig(port_to_pointer(port), pin, GPIO_AFNUM(flags));
88 }
89
90 if (flags & GPIO_PULLUP) {
91 init.GPIO_PuPd = GPIO_PuPd_UP;
92 } else if (flags & GPIO_PULLDOWN) {
93 init.GPIO_PuPd = GPIO_PuPd_DOWN;
94 }
95
96 if (flags & GPIO_STM32_OD) {
97 init.GPIO_OType = GPIO_OType_OD;
98 } else {
99 init.GPIO_OType = GPIO_OType_PP;
100 }
101
102 GPIO_Init(port_to_pointer(port), &init);
103
104 return 0;
105}
106
107void gpio_set(unsigned nr, unsigned on)
108{
109 GPIO_WriteBit(port_to_pointer(GPIO_PORT(nr)), 1 << GPIO_PIN(nr), on);
110}
111
112int gpio_get(unsigned nr)
113{
114 return GPIO_ReadInputDataBit(port_to_pointer(GPIO_PORT(nr)), 1 << GPIO_PIN(nr));
115}
116