]> git.sur5r.net Git - freertos/blob - Demo/AVR32_UC3A_GCC/Atmel_SW_Framework/DRIVERS/GPIO/gpio.c
42f4c49d5a20660fe4a72cc535c58789aef19f0d
[freertos] / Demo / AVR32_UC3A_GCC / Atmel_SW_Framework / DRIVERS / GPIO / gpio.c
1 /* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */\r
2
3 /*This file has been prepared for Doxygen automatic documentation generation.*/\r
4 /*! \file *********************************************************************\r
5  *\r
6  * \brief GPIO driver for AVR32 UC3.\r
7  *\r
8  * This file defines a useful set of functions for the GPIO.\r
9  *\r
10  * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32\r
11  * - Supported devices:  All AVR32 devices with a GPIO module can be used.\r
12  * - AppNote:\r
13  *\r
14  * \author               Atmel Corporation: http://www.atmel.com \n\r
15  *                       Support and FAQ: http://support.atmel.no/\r
16  *\r
17  *****************************************************************************/\r
18 \r
19 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.\r
20  *\r
21  * Redistribution and use in source and binary forms, with or without\r
22  * modification, are permitted provided that the following conditions are met:\r
23  *\r
24  * 1. Redistributions of source code must retain the above copyright notice, this\r
25  * list of conditions and the following disclaimer.\r
26  *\r
27  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
28  * this list of conditions and the following disclaimer in the documentation\r
29  * and/or other materials provided with the distribution.\r
30  *\r
31  * 3. The name of Atmel may not be used to endorse or promote products derived\r
32  * from this software without specific prior written permission.\r
33  *\r
34  * 4. This software may only be redistributed and used in connection with an Atmel\r
35  * AVR product.\r
36  *\r
37  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED\r
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
39  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
40  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR\r
41  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
42  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
45  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
46  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\r
47  *\r
48  */\r
49 \r
50 #include "gpio.h"\r
51 \r
52 //! GPIO module instance.\r
53 #define GPIO  AVR32_GPIO\r
54 \r
55 \r
56 /*! \name Peripheral Bus Interface\r
57  */\r
58 //! @{\r
59 \r
60 \r
61 int gpio_enable_module(const gpio_map_t gpiomap, unsigned int size)\r
62 {\r
63   int status = GPIO_SUCCESS;\r
64   unsigned int i;\r
65 \r
66   for (i = 0; i < size; i++)\r
67   {\r
68     status |= gpio_enable_module_pin(gpiomap->pin, gpiomap->function);\r
69     gpiomap++;\r
70   }\r
71 \r
72   return status;\r
73 }\r
74 \r
75 \r
76 int gpio_enable_module_pin(unsigned int pin, unsigned int function)\r
77 {\r
78   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
79 \r
80   // Enable the correct function.\r
81   switch (function)\r
82   {\r
83   case 0: // A function.\r
84     gpio_port->pmr0c = 1 << (pin & 0x1F);\r
85     gpio_port->pmr1c = 1 << (pin & 0x1F);\r
86 #if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)\r
87     gpio_port->pmr2c = 1 << (pin & 0x1F);\r
88 #endif\r
89     break;\r
90 \r
91   case 1: // B function.\r
92     gpio_port->pmr0s = 1 << (pin & 0x1F);\r
93     gpio_port->pmr1c = 1 << (pin & 0x1F);\r
94 #if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)\r
95     gpio_port->pmr2c = 1 << (pin & 0x1F);\r
96 #endif\r
97     break;\r
98 \r
99   case 2: // C function.\r
100     gpio_port->pmr0c = 1 << (pin & 0x1F);\r
101     gpio_port->pmr1s = 1 << (pin & 0x1F);\r
102 #if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)\r
103     gpio_port->pmr2c = 1 << (pin & 0x1F);\r
104 #endif\r
105     break;\r
106 \r
107   case 3: // D function.\r
108     gpio_port->pmr0s = 1 << (pin & 0x1F);\r
109     gpio_port->pmr1s = 1 << (pin & 0x1F);\r
110 #if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)\r
111     gpio_port->pmr2c = 1 << (pin & 0x1F);\r
112 #endif\r
113     break;\r
114 \r
115 #if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)\r
116   case 4: // E function.\r
117     gpio_port->pmr0c = 1 << (pin & 0x1F);\r
118     gpio_port->pmr1c = 1 << (pin & 0x1F);\r
119     gpio_port->pmr2s = 1 << (pin & 0x1F);\r
120     break;\r
121     \r
122   case 5: // F function.\r
123     gpio_port->pmr0s = 1 << (pin & 0x1F);\r
124     gpio_port->pmr1c = 1 << (pin & 0x1F);\r
125     gpio_port->pmr2s = 1 << (pin & 0x1F);\r
126     break;\r
127     \r
128   case 6: // G function.\r
129     gpio_port->pmr0c = 1 << (pin & 0x1F);\r
130     gpio_port->pmr1s = 1 << (pin & 0x1F);\r
131     gpio_port->pmr2s = 1 << (pin & 0x1F);\r
132     break;\r
133     \r
134   case 7: // H function.\r
135     gpio_port->pmr0s = 1 << (pin & 0x1F);\r
136     gpio_port->pmr1s = 1 << (pin & 0x1F);\r
137     gpio_port->pmr2s = 1 << (pin & 0x1F);\r
138     break;\r
139 #endif\r
140 \r
141   default:\r
142     return GPIO_INVALID_ARGUMENT;\r
143   }\r
144 \r
145   // Disable GPIO control.\r
146   gpio_port->gperc = 1 << (pin & 0x1F);\r
147 \r
148   return GPIO_SUCCESS;\r
149 }\r
150 \r
151 \r
152 void gpio_enable_gpio(const gpio_map_t gpiomap, unsigned int size)\r
153 {\r
154   unsigned int i;\r
155 \r
156   for (i = 0; i < size; i++)\r
157   {\r
158     gpio_enable_gpio_pin(gpiomap->pin);\r
159     gpiomap++;\r
160   }\r
161 }\r
162 \r
163 \r
164 void gpio_enable_gpio_pin(unsigned int pin)\r
165 {\r
166   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
167   gpio_port->oderc = 1 << (pin & 0x1F);\r
168   gpio_port->gpers = 1 << (pin & 0x1F);\r
169 }\r
170 \r
171 \r
172 // The open-drain mode is not synthesized on the current AVR32 products.\r
173 // If one day some AVR32 products have this feature, the corresponding part\r
174 // numbers should be listed in the #if below.\r
175 // Note that other functions are available in this driver to use pins with open\r
176 // drain in GPIO mode. The advantage of the open-drain mode functions over these\r
177 // other functions is that they can be used not only in GPIO mode but also in\r
178 // module mode.\r
179 #if 0\r
180 \r
181 \r
182 void gpio_enable_pin_open_drain(unsigned int pin)\r
183 {\r
184   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
185   gpio_port->odmers = 1 << (pin & 0x1F);\r
186 }\r
187 \r
188 \r
189 void gpio_disable_pin_open_drain(unsigned int pin)\r
190 {\r
191   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
192   gpio_port->odmerc = 1 << (pin & 0x1F);\r
193 }\r
194 \r
195 \r
196 #endif\r
197 \r
198 \r
199 void gpio_enable_pin_pull_up(unsigned int pin)\r
200 {\r
201   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
202   gpio_port->puers = 1 << (pin & 0x1F);\r
203 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)\r
204   gpio_port->pderc = 1 << (pin & 0x1F);\r
205 #endif\r
206 }\r
207 \r
208 \r
209 void gpio_disable_pin_pull_up(unsigned int pin)\r
210 {\r
211   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
212   gpio_port->puerc = 1 << (pin & 0x1F);\r
213 }\r
214 \r
215 #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED)\r
216 // Added support of Pull-up Resistor, Pull-down Resistor and Buskeeper Control.\r
217 \r
218 /*! \brief Enables the pull-down resistor of a pin.\r
219  *\r
220  * \param pin The pin number.\r
221  */\r
222 void gpio_enable_pin_pull_down(unsigned int pin)\r
223 {\r
224   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
225   gpio_port->puerc = 1 << (pin & 0x1F);\r
226   gpio_port->pders = 1 << (pin & 0x1F);\r
227 }\r
228 \r
229 /*! \brief Disables the pull-down resistor of a pin.\r
230  *\r
231  * \param pin The pin number.\r
232  */\r
233 void gpio_disable_pin_pull_down(unsigned int pin)\r
234 {\r
235   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
236   gpio_port->pderc = 1 << (pin & 0x1F);\r
237 }\r
238 \r
239 /*! \brief Enables the buskeeper functionality on a pin.\r
240  *\r
241  * \param pin The pin number.\r
242  */\r
243 void gpio_enable_pin_buskeeper(unsigned int pin)\r
244 {\r
245   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
246   gpio_port->puers = 1 << (pin & 0x1F);\r
247   gpio_port->pders = 1 << (pin & 0x1F);\r
248 }\r
249 \r
250 /*! \brief Disables the buskeeper functionality on a pin.\r
251  *\r
252  * \param pin The pin number.\r
253  */\r
254 void gpio_disable_pin_buskeeper(unsigned int pin)\r
255 {\r
256   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
257   gpio_port->puerc = 1 << (pin & 0x1F);\r
258   gpio_port->pderc = 1 << (pin & 0x1F);\r
259 }\r
260 \r
261 #endif\r
262 \r
263 int gpio_get_pin_value(unsigned int pin)\r
264 {\r
265   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
266   return (gpio_port->pvr >> (pin & 0x1F)) & 1;\r
267 }\r
268 \r
269 \r
270 int gpio_get_gpio_pin_output_value(unsigned int pin)\r
271 {\r
272   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
273   return (gpio_port->ovr >> (pin & 0x1F)) & 1;\r
274 }\r
275 \r
276 \r
277 int gpio_get_gpio_open_drain_pin_output_value(unsigned int pin)\r
278 {\r
279   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
280   return ((gpio_port->oder >> (pin & 0x1F)) & 1) ^ 1;\r
281 }\r
282 \r
283 \r
284 void gpio_set_gpio_pin(unsigned int pin)\r
285 {\r
286   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
287 \r
288   gpio_port->ovrs  = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 1.\r
289   gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin.\r
290   gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.\r
291 }\r
292 \r
293 \r
294 void gpio_clr_gpio_pin(unsigned int pin)\r
295 {\r
296   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
297 \r
298   gpio_port->ovrc  = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 0.\r
299   gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin.\r
300   gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.\r
301 }\r
302 \r
303 \r
304 void gpio_tgl_gpio_pin(unsigned int pin)\r
305 {\r
306   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
307 \r
308   gpio_port->ovrt  = 1 << (pin & 0x1F); // Toggle the I/O line.\r
309   gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin.\r
310   gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.\r
311 }\r
312 \r
313 \r
314 void gpio_set_gpio_open_drain_pin(unsigned int pin)\r
315 {\r
316   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
317 \r
318   gpio_port->oderc = 1 << (pin & 0x1F); // The GPIO output driver is disabled for that pin.\r
319   gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.\r
320 }\r
321 \r
322 \r
323 void gpio_clr_gpio_open_drain_pin(unsigned int pin)\r
324 {\r
325   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
326 \r
327   gpio_port->ovrc  = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 0.\r
328   gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin.\r
329   gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.\r
330 }\r
331 \r
332 \r
333 void gpio_tgl_gpio_open_drain_pin(unsigned int pin)\r
334 {\r
335   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
336 \r
337   gpio_port->ovrc  = 1 << (pin & 0x1F); // Value to be driven on the I/O line if the GPIO output driver is enabled: 0.\r
338   gpio_port->odert = 1 << (pin & 0x1F); // The GPIO output driver is toggled for that pin.\r
339   gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.\r
340 }\r
341 \r
342 \r
343 void gpio_enable_pin_glitch_filter(unsigned int pin)\r
344 {\r
345   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
346   gpio_port->gfers = 1 << (pin & 0x1F);\r
347 }\r
348 \r
349 \r
350 void gpio_disable_pin_glitch_filter(unsigned int pin)\r
351 {\r
352   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
353   gpio_port->gferc = 1 << (pin & 0x1F);\r
354 }\r
355 \r
356 /*! \brief Configure the edge detector of an input pin\r
357  *\r
358  * \param pin The pin number.\r
359  * \param mode The edge detection mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE\r
360  *             or \ref GPIO_FALLING_EDGE).\r
361  *\r
362  * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.\r
363  */\r
364 static int gpio_configure_edge_detector(unsigned int pin, unsigned int mode)\r
365 {\r
366   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
367   \r
368   // Configure the edge detector.\r
369   switch (mode)\r
370   {\r
371   case GPIO_PIN_CHANGE:\r
372     gpio_port->imr0c = 1 << (pin & 0x1F);\r
373     gpio_port->imr1c = 1 << (pin & 0x1F);\r
374     break;\r
375 \r
376   case GPIO_RISING_EDGE:\r
377     gpio_port->imr0s = 1 << (pin & 0x1F);\r
378     gpio_port->imr1c = 1 << (pin & 0x1F);\r
379     break;\r
380 \r
381   case GPIO_FALLING_EDGE:\r
382     gpio_port->imr0c = 1 << (pin & 0x1F);\r
383     gpio_port->imr1s = 1 << (pin & 0x1F);\r
384     break;\r
385 \r
386   default:\r
387     return GPIO_INVALID_ARGUMENT;\r
388   }\r
389 \r
390   return GPIO_SUCCESS;\r
391 }\r
392 \r
393 \r
394 int gpio_enable_pin_interrupt(unsigned int pin, unsigned int mode)\r
395 {\r
396   volatile avr32_gpio_port_t  *gpio_port = &GPIO.port[pin >> 5];\r
397 \r
398   // Enable the glitch filter.\r
399   gpio_port->gfers = 1 << (pin & 0x1F);\r
400 \r
401   // Configure the edge detector.\r
402   if(GPIO_INVALID_ARGUMENT == gpio_configure_edge_detector(pin, mode))\r
403     return(GPIO_INVALID_ARGUMENT);\r
404 \r
405   // Enable interrupt.\r
406   gpio_port->iers = 1 << (pin & 0x1F);\r
407 \r
408   return GPIO_SUCCESS;\r
409 }\r
410 \r
411 \r
412 void gpio_disable_pin_interrupt(unsigned int pin)\r
413 {\r
414   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
415   gpio_port->ierc = 1 << (pin & 0x1F);\r
416 }\r
417 \r
418 \r
419 int gpio_get_pin_interrupt_flag(unsigned int pin)\r
420 {\r
421   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
422   return (gpio_port->ifr >> (pin & 0x1F)) & 1;\r
423 }\r
424 \r
425 \r
426 void gpio_clear_pin_interrupt_flag(unsigned int pin)\r
427 {\r
428   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
429   gpio_port->ifrc = 1 << (pin & 0x1F);\r
430 }\r
431 \r
432 \r
433 //#\r
434 //# Peripheral Event System Support.\r
435 //#\r
436 #if UC3L\r
437 int gpio_configure_pin_periph_event_mode(unsigned int pin, unsigned int mode, unsigned int use_igf)\r
438 {\r
439   volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];\r
440 \r
441   if(TRUE == use_igf)\r
442   {\r
443     // Enable the glitch filter.\r
444     gpio_port->gfers = 1 << (pin & 0x1F);\r
445   }\r
446   else\r
447   {\r
448     // Disable the glitch filter.\r
449     gpio_port->gferc = 1 << (pin & 0x1F);\r
450   }\r
451 \r
452   // Configure the edge detector.\r
453   return(gpio_configure_edge_detector(pin, mode));\r
454 }\r
455 \r
456 #endif\r
457 \r
458 //! @}\r