blob: ac2a8a3e0bd6e3ddef06b5a2f24f015be8bf5682 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2012-2015 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 <err.h>
25#include <assert.h>
26#include <dev/gpio.h>
27#include <platform/stm32.h>
28#include <platform/gpio.h>
29
30static GPIO_TypeDef *port_to_pointer(unsigned int port)
31{
32 DEBUG_ASSERT(port <= GPIO_PORT_K);
33
34 switch (port) {
35 default:
36 case GPIO_PORT_A:
37 return GPIOA;
38 case GPIO_PORT_B:
39 return GPIOB;
40 case GPIO_PORT_C:
41 return GPIOC;
42 case GPIO_PORT_D:
43 return GPIOD;
44 case GPIO_PORT_E:
45 return GPIOE;
46 case GPIO_PORT_F:
47 return GPIOF;
48 case GPIO_PORT_G:
49 return GPIOG;
50 case GPIO_PORT_H:
51 return GPIOH;
52 case GPIO_PORT_I:
53 return GPIOI;
54 case GPIO_PORT_J:
55 return GPIOJ;
56 case GPIO_PORT_K:
57 return GPIOK;
58 }
59}
60
61static void enable_port(unsigned int port)
62{
63 DEBUG_ASSERT(port <= GPIO_PORT_K);
64
65 switch (port) {
66 case GPIO_PORT_A:
67 __HAL_RCC_GPIOA_CLK_ENABLE();
68 break;
69 case GPIO_PORT_B:
70 __HAL_RCC_GPIOB_CLK_ENABLE();
71 break;
72 case GPIO_PORT_C:
73 __HAL_RCC_GPIOC_CLK_ENABLE();
74 break;
75 case GPIO_PORT_D:
76 __HAL_RCC_GPIOD_CLK_ENABLE();
77 break;
78 case GPIO_PORT_E:
79 __HAL_RCC_GPIOE_CLK_ENABLE();
80 break;
81 case GPIO_PORT_F:
82 __HAL_RCC_GPIOF_CLK_ENABLE();
83 break;
84 case GPIO_PORT_G:
85 __HAL_RCC_GPIOG_CLK_ENABLE();
86 break;
87 case GPIO_PORT_H:
88 __HAL_RCC_GPIOH_CLK_ENABLE();
89 break;
90 case GPIO_PORT_I:
91 __HAL_RCC_GPIOI_CLK_ENABLE();
92 break;
93 case GPIO_PORT_J:
94 __HAL_RCC_GPIOJ_CLK_ENABLE();
95 break;
96 case GPIO_PORT_K:
97 __HAL_RCC_GPIOK_CLK_ENABLE();
98 break;
99 }
100}
101
102void stm32_gpio_early_init(void)
103{
104}
105
106int gpio_config(unsigned nr, unsigned flags)
107{
108 uint port = GPIO_PORT(nr);
109 uint pin = GPIO_PIN(nr);
110
111 enable_port(port);
112
113 GPIO_InitTypeDef init;
114 init.Speed = GPIO_SPEED_HIGH;
115 init.Pin = (1 << pin);
116 init.Alternate = 0;
117
118 if (flags & GPIO_INPUT) {
119 init.Mode = GPIO_MODE_INPUT;
120 } else if (flags & GPIO_OUTPUT) {
121 if (flags & GPIO_STM32_OD) {
122 init.Mode = GPIO_MODE_OUTPUT_OD;
123 } else {
124 init.Mode = GPIO_MODE_OUTPUT_PP;
125 }
126 } else if (flags & GPIO_STM32_AF) {
127 if (flags & GPIO_STM32_OD) {
128 init.Mode = GPIO_MODE_AF_OD;
129 } else {
130 init.Mode = GPIO_MODE_AF_PP;
131 }
132 init.Alternate = GPIO_AFNUM(flags);
133 } else {
134 panic("stm32f7: invalid args to gpio_config\n");
135 return ERR_INVALID_ARGS;
136 }
137
138 if (flags & GPIO_PULLUP) {
139 init.Pull = GPIO_PULLUP;
140 } else if (flags & GPIO_PULLDOWN) {
141 init.Pull = GPIO_PULLDOWN;
142 } else {
143 init.Pull = GPIO_NOPULL;
144 }
145
146 HAL_GPIO_Init(port_to_pointer(port), &init);
147
148 return 0;
149}
150
151void gpio_set(unsigned nr, unsigned on)
152{
153 HAL_GPIO_WritePin(port_to_pointer(GPIO_PORT(nr)), 1 << GPIO_PIN(nr), on);
154}
155
156int gpio_get(unsigned nr)
157{
158 return HAL_GPIO_ReadPin(port_to_pointer(GPIO_PORT(nr)), 1 << GPIO_PIN(nr));
159}
160