1 /* *****************************************************************************
2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Except as contained in this notice, the name of Maxim Integrated
23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
24 * Products, Inc. Branding Policy.
25 *
26 * The mere transfer of this software does not imply any licenses
27 * of trade secrets, proprietary technology, copyrights, patents,
28 * trademarks, maskwork rights, or any other form of intellectual
29 * property whatsoever. Maxim Integrated Products, Inc. retains all
30 * ownership rights.
31 *
32 * $Date: 2018-12-18 15:37:22 -0600 (Tue, 18 Dec 2018) $
33 * $Revision: 40072 $
34 *
35 **************************************************************************** */
36
37 /* **** Includes **** */
38 #include "mxc_config.h"
39 #include "mxc_assert.h"
40 #include "gpio.h"
41 #include <stddef.h>
42
43 /* **** Definitions **** */
44
45 /* **** Globals **** */
46
47 static void (*callback[MXC_CFG_GPIO_INSTANCES][MXC_CFG_GPIO_PINS_PORT])(void *);
48 static void *cbparam[MXC_CFG_GPIO_INSTANCES][MXC_CFG_GPIO_PINS_PORT];
49
50 /* **** Functions **** */
51
GPIO_Init(void)52 int GPIO_Init(void)
53 {
54 int i;
55 int j;
56
57 // Initialize call back arrays
58 for(i = 0; i < MXC_CFG_GPIO_INSTANCES; i++) {
59 for(j = 0; j < MXC_CFG_GPIO_PINS_PORT; j++) {
60 callback[i][j] = NULL;
61 }
62 }
63 return E_NO_ERROR;
64 }
65
66 /* ************************************************************************** */
67 /*
68 * GPIO_EN2 | GPIO_EN1 | GPIO_EN | Function
69 * --------------|---------------------|---------------------|----------------------
70 * 0 | 0 | 0 | Alternative 1
71 * 0 | 1 | 0 | Alternative 2
72 * 1 | 0 | 0 | Alternative 3
73 * 1 | 1 | 0 | Alternative 4
74 * 0 | 0 | 1 | GPIO (default)
75 */
76
GPIO_Config(const gpio_cfg_t * cfg)77 int GPIO_Config(const gpio_cfg_t *cfg)
78 {
79 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
80
81 // Set the GPIO type
82 switch (cfg->func) {
83 case GPIO_FUNC_IN:
84 gpio->out_en_clr = cfg->mask;
85 gpio->en_set = cfg->mask;
86 gpio->en1_clr = cfg->mask;
87 gpio->en2_clr = cfg->mask;
88 break;
89 case GPIO_FUNC_OUT:
90 gpio->out_en_set = cfg->mask;
91 gpio->en_set = cfg->mask;
92 gpio->en1_clr = cfg->mask;
93 gpio->en2_clr = cfg->mask;
94 break;
95 case GPIO_FUNC_ALT1:
96 gpio->en_clr = cfg->mask;
97 gpio->en1_clr = cfg->mask;
98 gpio->en2_clr = cfg->mask;
99 break;
100 case GPIO_FUNC_ALT2:
101 gpio->en_clr = cfg->mask;
102 gpio->en1_set = cfg->mask;
103 gpio->en2_clr = cfg->mask;
104 break;
105 case GPIO_FUNC_ALT3:
106 #if TARGET==32660
107 gpio->en_set = cfg->mask;
108 gpio->en1_set = cfg->mask;
109 #else
110 gpio->en_clr = cfg->mask;
111 gpio->en1_clr = cfg->mask;
112 gpio->en2_set = cfg->mask;
113 #endif
114 break;
115 case GPIO_FUNC_ALT4:
116 gpio->en_clr = cfg->mask;
117 gpio->en1_set = cfg->mask;
118 gpio->en2_set = cfg->mask;
119 break;
120 default:
121 return E_BAD_PARAM;
122 }
123
124 // Configure the pad
125 switch (cfg->pad) {
126 case GPIO_PAD_NONE:
127 gpio->pad_cfg1 &= ~cfg->mask;
128 gpio->pad_cfg2 &= ~cfg->mask;
129 #if TARGET==32660
130 gpio->ps &= ~cfg->mask;
131 #endif
132 break;
133 case GPIO_PAD_PULL_UP:
134 gpio->pad_cfg1 |= cfg->mask;
135 gpio->pad_cfg2 &= ~cfg->mask;
136 #if TARGET==32660
137 gpio->ps |= cfg->mask;
138 #endif
139 break;
140 case GPIO_PAD_PULL_DOWN:
141 gpio->pad_cfg1 &= ~cfg->mask;
142 gpio->pad_cfg2 |= cfg->mask;
143 #if TARGET==32660
144 gpio->ps &= ~cfg->mask;
145 #endif
146 break;
147 default:
148 return E_BAD_PARAM;
149 }
150
151 return E_NO_ERROR;
152 }
153
154 /* ************************************************************************** */
GPIO_InGet(const gpio_cfg_t * cfg)155 uint32_t GPIO_InGet(const gpio_cfg_t *cfg)
156 {
157 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
158
159 return (gpio->in & cfg->mask);
160 }
161
162 /* ************************************************************************** */
GPIO_OutSet(const gpio_cfg_t * cfg)163 void GPIO_OutSet(const gpio_cfg_t *cfg)
164 {
165 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
166
167 gpio->out_set = cfg->mask;
168 }
169
170 /* ************************************************************************** */
GPIO_OutClr(const gpio_cfg_t * cfg)171 void GPIO_OutClr(const gpio_cfg_t *cfg)
172 {
173 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
174
175 gpio->out_clr = cfg->mask;
176 }
177
178 /* ************************************************************************** */
GPIO_OutGet(const gpio_cfg_t * cfg)179 uint32_t GPIO_OutGet(const gpio_cfg_t *cfg)
180 {
181 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
182
183 return (gpio->out & cfg->mask);
184 }
185
186 /* ************************************************************************** */
GPIO_OutPut(const gpio_cfg_t * cfg,uint32_t val)187 void GPIO_OutPut(const gpio_cfg_t *cfg, uint32_t val)
188 {
189 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
190
191 gpio->out = (gpio->out & ~cfg->mask) | (val & cfg->mask);
192 }
193
194 /* ************************************************************************** */
GPIO_OutToggle(const gpio_cfg_t * cfg)195 void GPIO_OutToggle(const gpio_cfg_t *cfg)
196 {
197 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
198
199 gpio->out ^= cfg->mask;
200 }
201
202 /* ************************************************************************** */
GPIO_IntConfig(const gpio_cfg_t * cfg,gpio_int_mode_t mode,gpio_int_pol_t pol)203 int GPIO_IntConfig(const gpio_cfg_t *cfg, gpio_int_mode_t mode, gpio_int_pol_t pol)
204 {
205 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
206
207 switch (mode) {
208 case GPIO_INT_LEVEL:
209 gpio->int_mod &= ~cfg->mask;
210 break;
211 case GPIO_INT_EDGE:
212 gpio->int_mod |= cfg->mask;
213 break;
214 default:
215 return E_BAD_PARAM;
216 }
217
218 switch (pol) {
219 case GPIO_INT_FALLING: /* GPIO_INT_HIGH */
220 gpio->int_pol &= ~cfg->mask;
221 gpio->int_dual_edge &= ~cfg->mask;
222 break;
223 case GPIO_INT_RISING: /* GPIO_INT_LOW */
224 gpio->int_pol |= cfg->mask;
225 gpio->int_dual_edge &= ~cfg->mask;
226 break;
227 case GPIO_INT_BOTH:
228 gpio->int_dual_edge |= cfg->mask;
229 break;
230 default:
231 return E_BAD_PARAM;
232 }
233
234 return E_NO_ERROR;
235 }
236
237 /* ************************************************************************** */
GPIO_IntEnable(const gpio_cfg_t * cfg)238 void GPIO_IntEnable(const gpio_cfg_t *cfg)
239 {
240 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
241
242 gpio->int_en_set = cfg->mask;
243 }
244
245 /* ************************************************************************** */
GPIO_IntDisable(const gpio_cfg_t * cfg)246 void GPIO_IntDisable(const gpio_cfg_t *cfg)
247 {
248 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
249
250 gpio->int_en_clr = cfg->mask;
251 }
252
253 /* ************************************************************************** */
GPIO_IntStatus(const gpio_cfg_t * cfg)254 uint32_t GPIO_IntStatus(const gpio_cfg_t *cfg)
255 {
256 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
257
258 return (gpio->int_stat & cfg->mask);
259 }
260
261 /* ************************************************************************** */
GPIO_IntClr(const gpio_cfg_t * cfg)262 void GPIO_IntClr(const gpio_cfg_t *cfg)
263 {
264 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(cfg->port);
265
266 gpio->int_clr = cfg->mask;
267 }
268
269 /* ************************************************************************** */
GPIO_RegisterCallback(const gpio_cfg_t * cfg,gpio_callback_fn func,void * cbdata)270 void GPIO_RegisterCallback(const gpio_cfg_t *cfg, gpio_callback_fn func, void *cbdata)
271 {
272 uint32_t mask;
273 unsigned int pin;
274
275 mask = cfg->mask;
276 pin = 0;
277
278 while (mask) {
279 if (mask & 1) {
280 callback[cfg->port][pin] = func;
281 cbparam[cfg->port][pin] = cbdata;
282 }
283 pin++;
284 mask >>= 1;
285 }
286 }
287
288 /* ************************************************************************** */
GPIO_Handler(unsigned int port)289 void GPIO_Handler(unsigned int port)
290 {
291 uint32_t stat;
292 unsigned int pin;
293
294 MXC_ASSERT(port < MXC_CFG_GPIO_INSTANCES);
295
296 mxc_gpio_regs_t *gpio = MXC_GPIO_GET_GPIO(port);
297
298 stat = gpio->int_stat;
299 gpio->int_clr = stat;
300
301 pin = 0;
302
303 while (stat) {
304 if (stat & 1) {
305 if(callback[port][pin]) {
306 callback[port][pin](cbparam[port][pin]);
307 }
308 }
309 pin++;
310 stat >>= 1;
311 }
312 }
313