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