]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_AT91SAM3U256_IAR/AT91Lib/peripherals/pio/pio.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / CORTEX_AT91SAM3U256_IAR / AT91Lib / peripherals / pio / pio.c
1 /* ----------------------------------------------------------------------------\r
2  *         ATMEL Microcontroller Software Support \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2008, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 //------------------------------------------------------------------------------\r
31 //         Headers\r
32 //------------------------------------------------------------------------------\r
33 \r
34 #include "pio.h"\r
35 #include <board.h>\r
36 \r
37 //------------------------------------------------------------------------------\r
38 //         Local Functions\r
39 //------------------------------------------------------------------------------\r
40 \r
41 //------------------------------------------------------------------------------\r
42 /// Configures one or more pin(s) of a PIO controller as being controlled by\r
43 /// peripheral A. Optionally, the corresponding internal pull-up(s) can be\r
44 /// enabled.\r
45 /// \param pio  Pointer to a PIO controller.\r
46 /// \param mask  Bitmask of one or more pin(s) to configure.\r
47 /// \param enablePullUp  Indicates if the pin(s) internal pull-up shall be\r
48 ///                      configured.\r
49 //------------------------------------------------------------------------------\r
50 static void PIO_SetPeripheralA(\r
51     AT91S_PIO *pio,\r
52     unsigned int mask,\r
53     unsigned char enablePullUp)\r
54 {\r
55 #if !defined(AT91C_PIOA_ASR)\r
56     unsigned int abmr;\r
57 #endif\r
58 \r
59     // Disable interrupts on the pin(s)\r
60     pio->PIO_IDR = mask;\r
61 \r
62     // Enable the pull-up(s) if necessary\r
63     if (enablePullUp) {\r
64 \r
65         pio->PIO_PPUER = mask;\r
66     }\r
67     else {\r
68 \r
69         pio->PIO_PPUDR = mask;\r
70     }\r
71 \r
72     // Configure pin\r
73 #if defined(AT91C_PIOA_ASR)\r
74     pio->PIO_ASR = mask;\r
75 #else\r
76     abmr = pio->PIO_ABSR;\r
77     pio->PIO_ABSR &= (~mask & abmr);\r
78 #endif\r
79     pio->PIO_PDR = mask;\r
80 }\r
81 \r
82 //------------------------------------------------------------------------------\r
83 /// Configures one or more pin(s) of a PIO controller as being controlled by\r
84 /// peripheral B. Optionally, the corresponding internal pull-up(s) can be\r
85 /// enabled.\r
86 /// \param pio  Pointer to a PIO controller.\r
87 /// \param mask  Bitmask of one or more pin(s) to configure.\r
88 /// \param enablePullUp  Indicates if the pin(s) internal pull-up shall be\r
89 ///                      configured.\r
90 //------------------------------------------------------------------------------\r
91 static void PIO_SetPeripheralB(\r
92     AT91S_PIO *pio,\r
93     unsigned int mask,\r
94     unsigned char enablePullUp)\r
95 {\r
96 #if !defined(AT91C_PIOA_BSR)\r
97     unsigned int abmr;\r
98 #endif\r
99 \r
100     // Disable interrupts on the pin(s)\r
101     pio->PIO_IDR = mask;\r
102 \r
103     // Enable the pull-up(s) if necessary\r
104     if (enablePullUp) {\r
105 \r
106         pio->PIO_PPUER = mask;\r
107     }\r
108     else {\r
109 \r
110         pio->PIO_PPUDR = mask;\r
111     }\r
112 \r
113     // Configure pin\r
114 #if defined(AT91C_PIOA_BSR)\r
115     pio->PIO_BSR = mask;\r
116 #else\r
117     abmr = pio->PIO_ABSR;\r
118     pio->PIO_ABSR = mask | abmr;\r
119 #endif\r
120     pio->PIO_PDR = mask;\r
121 }\r
122 \r
123 #if defined(AT91C_PIOA_IFDGSR) //Glitch or Debouncing filter selection supported\r
124 //------------------------------------------------------------------------------\r
125 /// Configures Glitch or Debouncing filter for input\r
126 /// \param pio      Pointer to a PIO controller.\r
127 /// \param mask   Bitmask for filter selection.\r
128 ///                     each of 32 bit field, 0 is Glitch, 1 is Debouncing\r
129 /// \param clkDiv  Clock divider if Debouncing select, using the lowest 14 bits\r
130 ///                     common for all PIO line of selecting deboucing filter\r
131 //------------------------------------------------------------------------------\r
132 static void PIO_SetFilter(\r
133     AT91S_PIO *pio,\r
134     unsigned int filterSel,\r
135     unsigned int clkDiv)\r
136 {\r
137     pio->PIO_DIFSR = filterSel;//set Debouncing, 0 bit field no effect\r
138     pio->PIO_SCIFSR = ~filterSel;//set Glitch, 0 bit field no effect\r
139 \r
140     pio->PIO_SCDR = clkDiv & 0x3FFF;//the lowest 14 bits work\r
141 }\r
142 #endif\r
143 \r
144 //------------------------------------------------------------------------------\r
145 /// Configures one or more pin(s) or a PIO controller as inputs. Optionally,\r
146 /// the corresponding internal pull-up(s) and glitch filter(s) can be\r
147 /// enabled.\r
148 /// \param pio  Pointer to a PIO controller.\r
149 /// \param mask  Bitmask indicating which pin(s) to configure as input(s).\r
150 /// \param enablePullUp  Indicates if the internal pull-up(s) must be enabled.\r
151 /// \param enableFilter  Indicates if the glitch filter(s) must be enabled.\r
152 //------------------------------------------------------------------------------\r
153 static void PIO_SetInput(\r
154     AT91S_PIO *pio,\r
155     unsigned int mask,\r
156     unsigned char enablePullUp,\r
157     unsigned char enableFilter)\r
158 {\r
159     // Disable interrupts\r
160     pio->PIO_IDR = mask;\r
161 \r
162     // Enable pull-up(s) if necessary\r
163     if (enablePullUp) {\r
164     \r
165         pio->PIO_PPUER = mask;\r
166     }\r
167     else {\r
168     \r
169         pio->PIO_PPUDR = mask;\r
170     }\r
171 \r
172     // Enable filter(s) if necessary\r
173     if (enableFilter) {\r
174     \r
175         pio->PIO_IFER = mask;\r
176     }\r
177     else {\r
178     \r
179         pio->PIO_IFDR = mask;\r
180     }\r
181 \r
182     // Configure pin as input\r
183     pio->PIO_ODR = mask;\r
184     pio->PIO_PER = mask;\r
185 }\r
186 \r
187 //------------------------------------------------------------------------------\r
188 /// Configures one or more pin(s) of a PIO controller as outputs, with the\r
189 /// given default value. Optionally, the multi-drive feature can be enabled\r
190 /// on the pin(s).\r
191 /// \param pio  Pointer to a PIO controller.\r
192 /// \param mask  Bitmask indicating which pin(s) to configure.\r
193 /// \param defaultValue  Default level on the pin(s).\r
194 /// \param enableMultiDrive  Indicates if the pin(s) shall be configured as\r
195 ///                          open-drain.\r
196 /// \param enablePullUp  Indicates if the pin shall have its pull-up activated.\r
197 //------------------------------------------------------------------------------\r
198 static void PIO_SetOutput(\r
199     AT91S_PIO *pio,\r
200     unsigned int mask,\r
201     unsigned char defaultValue,\r
202     unsigned char enableMultiDrive,\r
203     unsigned char enablePullUp)\r
204 {\r
205     // Disable interrupts\r
206     pio->PIO_IDR = mask;\r
207 \r
208     // Enable pull-up(s) if necessary\r
209     if (enablePullUp) {\r
210     \r
211         pio->PIO_PPUER = mask;\r
212     }\r
213     else {\r
214     \r
215         pio->PIO_PPUDR = mask;\r
216     }\r
217 \r
218     // Enable multi-drive if necessary\r
219     if (enableMultiDrive) {\r
220     \r
221         pio->PIO_MDER = mask;\r
222     }\r
223     else {\r
224     \r
225         pio->PIO_MDDR = mask;\r
226     }\r
227 \r
228     // Set default value\r
229     if (defaultValue) {\r
230 \r
231         pio->PIO_SODR = mask;\r
232     }\r
233     else {\r
234 \r
235         pio->PIO_CODR = mask;\r
236     }\r
237 \r
238     // Configure pin(s) as output(s)\r
239     pio->PIO_OER = mask;\r
240     pio->PIO_PER = mask;\r
241 }\r
242 \r
243 //------------------------------------------------------------------------------\r
244 //         Global Functions\r
245 //------------------------------------------------------------------------------\r
246 \r
247 //------------------------------------------------------------------------------\r
248 /// Configures a list of Pin instances, each of which can either hold a single\r
249 /// pin or a group of pins, depending on the mask value; all pins are configured\r
250 /// by this function. The size of the array must also be provided and is easily\r
251 /// computed using PIO_LISTSIZE whenever its length is not known in advance.\r
252 /// \param list  Pointer to a list of Pin instances.\r
253 /// \param size  Size of the Pin list (calculated using PIO_LISTSIZE).\r
254 /// \return 1 if the pins have been configured properly; otherwise 0.\r
255 //------------------------------------------------------------------------------\r
256 unsigned char PIO_Configure(const Pin *list, unsigned int size)\r
257 {\r
258     // Configure pins\r
259     while (size > 0) {\r
260     \r
261         switch (list->type) {\r
262     \r
263             case PIO_PERIPH_A:\r
264                 PIO_SetPeripheralA(list->pio,\r
265                                    list->mask,\r
266                                    (list->attribute & PIO_PULLUP) ? 1 : 0);\r
267                 break;\r
268     \r
269             case PIO_PERIPH_B:\r
270                 PIO_SetPeripheralB(list->pio,\r
271                                    list->mask,\r
272                                    (list->attribute & PIO_PULLUP) ? 1 : 0);\r
273                 break;\r
274     \r
275             case PIO_INPUT:\r
276                 AT91C_BASE_PMC->PMC_PCER = 1 << list->id;\r
277                 PIO_SetInput(list->pio,\r
278                              list->mask,\r
279                              (list->attribute & PIO_PULLUP) ? 1 : 0,\r
280                              (list->attribute & PIO_DEGLITCH)? 1 : 0);\r
281 \r
282                 #if defined(AT91C_PIOA_IFDGSR) //PIO3 with Glitch or Debouncing selection\r
283                 //if glitch input filter enabled, set it\r
284                 if(list->attribute & PIO_DEGLITCH)//Glitch input filter enabled\r
285                     PIO_SetFilter(list->pio,\r
286                         list->inFilter.filterSel,\r
287                         list->inFilter.clkDivider);\r
288                 #endif\r
289                 break;\r
290     \r
291             case PIO_OUTPUT_0:\r
292             case PIO_OUTPUT_1:\r
293                 PIO_SetOutput(list->pio,\r
294                               list->mask,\r
295                               (list->type == PIO_OUTPUT_1),\r
296                               (list->attribute & PIO_OPENDRAIN) ? 1 : 0,\r
297                               (list->attribute & PIO_PULLUP) ? 1 : 0);\r
298                 break;\r
299     \r
300             default: return 0;\r
301         }\r
302 \r
303         list++;\r
304         size--;\r
305     }\r
306 \r
307     return 1;\r
308 }\r
309 \r
310 //------------------------------------------------------------------------------\r
311 /// Sets a high output level on all the PIOs defined in the given Pin instance.\r
312 /// This has no immediate effects on PIOs that are not output, but the PIO\r
313 /// controller will memorize the value they are changed to outputs.\r
314 /// \param pin  Pointer to a Pin instance describing one or more pins.\r
315 //------------------------------------------------------------------------------\r
316 void PIO_Set(const Pin *pin)\r
317 {\r
318     pin->pio->PIO_SODR = pin->mask;\r
319 }\r
320 \r
321 //------------------------------------------------------------------------------\r
322 /// Sets a low output level on all the PIOs defined in the given Pin instance.\r
323 /// This has no immediate effects on PIOs that are not output, but the PIO\r
324 /// controller will memorize the value they are changed to outputs.\r
325 /// \param pin  Pointer to a Pin instance describing one or more pins.\r
326 //------------------------------------------------------------------------------\r
327 void PIO_Clear(const Pin *pin)\r
328 {\r
329     pin->pio->PIO_CODR = pin->mask;\r
330 }\r
331 \r
332 //------------------------------------------------------------------------------\r
333 /// Returns 1 if one or more PIO of the given Pin instance currently have a high\r
334 /// level; otherwise returns 0. This method returns the actual value that is\r
335 /// being read on the pin. To return the supposed output value of a pin, use\r
336 /// PIO_GetOutputDataStatus() instead.\r
337 /// \param pin  Pointer to a Pin instance describing one or more pins.\r
338 /// \return 1 if the Pin instance contains at least one PIO that currently has\r
339 /// a high level; otherwise 0.\r
340 //------------------------------------------------------------------------------\r
341 unsigned char PIO_Get(const Pin *pin)\r
342 {\r
343     unsigned int reg;\r
344     if ((pin->type == PIO_OUTPUT_0) || (pin->type == PIO_OUTPUT_1)) {\r
345 \r
346         reg = pin->pio->PIO_ODSR;\r
347     }\r
348     else {\r
349 \r
350         reg = pin->pio->PIO_PDSR;\r
351     }\r
352 \r
353     if ((reg & pin->mask) == 0) {\r
354 \r
355         return 0;\r
356     }\r
357     else {\r
358 \r
359         return 1;\r
360     }\r
361 }\r
362 \r
363 \r
364 //------------------------------------------------------------------------------\r
365 /// Returns 1 if one or more PIO of the given Pin are configured to output a\r
366 /// high level (even if they are not output).\r
367 /// To get the actual value of the pin, use PIO_Get() instead.\r
368 /// \param pin  Pointer to a Pin instance describing one or more pins.\r
369 /// \return 1 if the Pin instance contains at least one PIO that is configured\r
370 /// to output a high level; otherwise 0.\r
371 //------------------------------------------------------------------------------\r
372 unsigned char PIO_GetOutputDataStatus(const Pin *pin)\r
373 {\r
374     if ((pin->pio->PIO_ODSR & pin->mask) == 0) {\r
375 \r
376         return 0;\r
377     }\r
378     else {\r
379 \r
380         return 1;\r
381     }\r
382 }\r