1 /*
2 * Copyright (c) 2020 Gerson Fernando Budke <nandojve@gmail.com>
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 /** @file
7 * @brief Atmel SAM MCU family General-Purpose Input/Output Controller (GPIO)
8 * module HAL driver.
9 */
10
11 #include <zephyr/sys/__assert.h>
12 #include "soc_gpio.h"
13
configure_common_attr(volatile Gpio * gpio,uint32_t mask,uint32_t flags)14 static void configure_common_attr(volatile Gpio *gpio,
15 uint32_t mask, uint32_t flags)
16 {
17 flags &= SOC_GPIO_FLAGS_MASK;
18
19 /* Disable interrupts on the pin(s) */
20 gpio->IERC = mask;
21
22 /* Configure pull-up(s) */
23 if (flags & SOC_GPIO_PULLUP) {
24 gpio->PUERS = mask;
25 } else {
26 gpio->PUERC = mask;
27 }
28
29 /* Configure pull-down(s) */
30 if (flags & SOC_GPIO_PULLDOWN) {
31 gpio->PDERS = mask;
32 } else {
33 gpio->PDERC = mask;
34 }
35
36 /* Configure open drain (multi-drive) */
37 if (flags & SOC_GPIO_OPENDRAIN) {
38 gpio->ODMERS = mask;
39 } else {
40 gpio->ODMERC = mask;
41 }
42 }
43
configure_input_attr(volatile Gpio * gpio,uint32_t mask,uint32_t flags)44 static void configure_input_attr(volatile Gpio *gpio,
45 uint32_t mask, uint32_t flags)
46 {
47 /* Configure input filter */
48 if ((flags & SOC_GPIO_IN_FILTER_MASK) != 0U) {
49 if ((flags & SOC_GPIO_IN_FILTER_MASK) ==
50 SOC_GPIO_IN_FILTER_DEBOUNCE) {
51 /* Enable de-bounce, disable de-glitch */
52 gpio->GFERC = mask;
53 } else {
54 /* Disable de-bounce, enable de-glitch */
55 gpio->GFERS = mask;
56 }
57 } else {
58 gpio->GFERC = mask;
59 }
60
61 /* Configure interrupt */
62 if (flags & SOC_GPIO_INT_ENABLE) {
63 if ((flags & SOC_GPIO_INT_TRIG_MASK) ==
64 SOC_GPIO_INT_TRIG_DOUBLE_EDGE) {
65 gpio->IMR0C = mask;
66 gpio->IMR1C = mask;
67 } else {
68 if (flags & SOC_GPIO_INT_ACTIVE_HIGH) {
69 /* Rising Edge*/
70 gpio->IMR0S = mask;
71 gpio->IMR1C = mask;
72 } else {
73 /* Falling Edge */
74 gpio->IMR0C = mask;
75 gpio->IMR1S = mask;
76 }
77 }
78 /* Enable interrupts on the pin(s) */
79 gpio->IERS = mask;
80 } else {
81 gpio->IERC = mask;
82 }
83 }
84
soc_gpio_configure(const struct soc_gpio_pin * pin)85 void soc_gpio_configure(const struct soc_gpio_pin *pin)
86 {
87 uint32_t mask = pin->mask;
88 volatile Gpio *gpio = pin->regs;
89 uint8_t periph_id = pin->periph_id;
90 uint32_t flags = pin->flags;
91 uint32_t type = pin->flags & SOC_GPIO_FUNC_MASK;
92
93 /* Configure pin attributes common to all functions */
94 configure_common_attr(gpio, mask, flags);
95
96 switch (type) {
97 case SOC_GPIO_FUNC_A:
98 gpio->PMR0C = mask;
99 gpio->PMR1C = mask;
100 gpio->PMR2C = mask;
101 gpio->GPERC = mask;
102 break;
103
104 case SOC_GPIO_FUNC_B:
105 gpio->PMR0S = mask;
106 gpio->PMR1C = mask;
107 gpio->PMR2C = mask;
108 gpio->GPERC = mask;
109 break;
110
111 case SOC_GPIO_FUNC_C:
112 gpio->PMR0C = mask;
113 gpio->PMR1S = mask;
114 gpio->PMR2C = mask;
115 gpio->GPERC = mask;
116 break;
117
118 case SOC_GPIO_FUNC_D:
119 gpio->PMR0S = mask;
120 gpio->PMR1S = mask;
121 gpio->PMR2C = mask;
122 gpio->GPERC = mask;
123 break;
124
125 case SOC_GPIO_FUNC_E:
126 gpio->PMR0C = mask;
127 gpio->PMR1C = mask;
128 gpio->PMR2S = mask;
129 gpio->GPERC = mask;
130 break;
131
132 case SOC_GPIO_FUNC_F:
133 gpio->PMR0S = mask;
134 gpio->PMR1C = mask;
135 gpio->PMR2S = mask;
136 gpio->GPERC = mask;
137 break;
138
139 case SOC_GPIO_FUNC_G:
140 gpio->PMR0C = mask;
141 gpio->PMR1S = mask;
142 gpio->PMR2S = mask;
143 gpio->GPERC = mask;
144 break;
145
146 case SOC_GPIO_FUNC_H:
147 gpio->PMR0S = mask;
148 gpio->PMR1S = mask;
149 gpio->PMR2S = mask;
150 gpio->GPERC = mask;
151 break;
152
153 case SOC_GPIO_FUNC_IN:
154 soc_pmc_peripheral_enable(periph_id);
155 configure_input_attr(gpio, mask, flags);
156
157 gpio->ODERC = mask;
158 gpio->STERS = mask;
159 gpio->GPERS = mask;
160 break;
161
162 case SOC_GPIO_FUNC_OUT_1:
163 case SOC_GPIO_FUNC_OUT_0:
164 if (type == SOC_GPIO_FUNC_OUT_1) {
165 gpio->OVRS = mask;
166 } else {
167 gpio->OVRC = mask;
168 }
169
170 gpio->ODCR0S = mask;
171 gpio->ODCR1S = mask;
172 gpio->ODERS = mask;
173 gpio->STERC = mask;
174 gpio->GPERS = mask;
175 break;
176
177 default:
178 __ASSERT(0, "Unsupported pin function, check pin.flags value");
179 return;
180 }
181 }
182
soc_gpio_list_configure(const struct soc_gpio_pin pins[],unsigned int size)183 void soc_gpio_list_configure(const struct soc_gpio_pin pins[],
184 unsigned int size)
185 {
186 for (int i = 0; i < size; i++) {
187 soc_gpio_configure(&pins[i]);
188 }
189 }
190