]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_M4_ATSAM4S_Atmel_Studio/src/asf/sam/drivers/pio/pio_handler.c
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / CORTEX_M4_ATSAM4S_Atmel_Studio / src / asf / sam / drivers / pio / pio_handler.c
1 /**\r
2  * \file\r
3  *\r
4  * \brief Parallel Input/Output (PIO) interrupt handler for SAM.\r
5  *\r
6  * Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.\r
7  *\r
8  * \asf_license_start\r
9  *\r
10  * Redistribution and use in source and binary forms, with or without\r
11  * modification, are permitted provided that the following conditions are met:\r
12  *\r
13  * 1. Redistributions of source code must retain the above copyright notice,\r
14  *    this list of conditions and the following disclaimer.\r
15  *\r
16  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
17  *    this list of conditions and the following disclaimer in the documentation\r
18  *    and/or other materials provided with the distribution.\r
19  *\r
20  * 3. The name of Atmel may not be used to endorse or promote products derived\r
21  *    from this software without specific prior written permission.\r
22  *\r
23  * 4. This software may only be redistributed and used in connection with an\r
24  *    Atmel microcontroller product.\r
25  *\r
26  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED\r
27  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
29  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR\r
30  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
34  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
36  * POSSIBILITY OF SUCH DAMAGE.\r
37  *\r
38  * \asf_license_stop\r
39  *\r
40  */\r
41 \r
42 #include "exceptions.h"\r
43 #include "pio.h"\r
44 #include "pio_handler.h"\r
45 \r
46 /** \r
47  * Maximum number of interrupt sources that can be defined. This\r
48  * constant can be increased, but the current value is the smallest possible one\r
49  * that will be compatible with all existing projects.\r
50  */\r
51 #define MAX_INTERRUPT_SOURCES       7\r
52 \r
53 /**\r
54  * Describes a PIO interrupt source, including the PIO instance triggering the\r
55  * interrupt and the associated interrupt handler.\r
56  */\r
57 struct s_interrupt_source {\r
58         uint32_t id;\r
59         uint32_t mask;\r
60         uint32_t attr;\r
61 \r
62         /* Interrupt handler. */\r
63         void (*handler) (const uint32_t, const uint32_t);\r
64 };\r
65 \r
66 \r
67 /* List of interrupt sources. */\r
68 static struct s_interrupt_source gs_interrupt_sources[MAX_INTERRUPT_SOURCES];\r
69 \r
70 /* Number of currently defined interrupt sources. */\r
71 static uint32_t gs_ul_nb_sources = 0;\r
72 \r
73 /**\r
74  * \brief Process an interrupt request on the given PIO controller.\r
75  *\r
76  * \param p_pio PIO controller base address.\r
77  * \param ul_id PIO controller ID.\r
78  */\r
79 void pio_handler_process(Pio *p_pio, uint32_t ul_id)\r
80 {\r
81         uint32_t status;\r
82         uint32_t i;\r
83 \r
84         /* Read PIO controller status */\r
85         status = pio_get_interrupt_status(p_pio);\r
86         status &= pio_get_interrupt_mask(p_pio);\r
87 \r
88         /* Check pending events */\r
89         if (status != 0) {\r
90                 /* Find triggering source */\r
91                 i = 0;\r
92                 while (status != 0) {\r
93                         /* Source is configured on the same controller */\r
94                         if (gs_interrupt_sources[i].id == ul_id) {\r
95                                 /* Source has PIOs whose statuses have changed */\r
96                                 if ((status & gs_interrupt_sources[i].mask) != 0) {\r
97                                         gs_interrupt_sources[i].handler(gs_interrupt_sources[i].id,\r
98                                                         gs_interrupt_sources[i].mask);\r
99                                         status &= ~(gs_interrupt_sources[i].mask);\r
100                                 }\r
101                         }\r
102                         i++;\r
103                 }\r
104         }\r
105 }\r
106 \r
107 /**\r
108  * \brief Set an interrupt handler for the provided pins.\r
109  * The provided handler will be called with the triggering pin as its parameter \r
110  * as soon as an interrupt is detected. \r
111  *\r
112  * \param p_pio PIO controller base address.\r
113  * \param ul_id PIO ID.\r
114  * \param ul_mask Pins (bit mask) to configure.\r
115  * \param ul_attr Pins attribute to configure.\r
116  * \param p_handler Interrupt handler function pointer.\r
117  *\r
118  * \return 0 if successful, 1 if the maximum number of sources has been defined.\r
119  */\r
120 uint32_t pio_handler_set(Pio *p_pio, uint32_t ul_id, uint32_t ul_mask,\r
121                 uint32_t ul_attr, void (*p_handler) (uint32_t, uint32_t))\r
122 {\r
123         struct s_interrupt_source *pSource;\r
124 \r
125         if (gs_ul_nb_sources >= MAX_INTERRUPT_SOURCES)\r
126                 return 1;\r
127 \r
128         /* Define new source */\r
129         pSource = &(gs_interrupt_sources[gs_ul_nb_sources]);\r
130         pSource->id = ul_id;\r
131         pSource->mask = ul_mask;\r
132         pSource->attr = ul_attr;\r
133         pSource->handler = p_handler;\r
134         gs_ul_nb_sources++;\r
135 \r
136         /* Configure interrupt mode */\r
137         pio_configure_interrupt(p_pio, ul_mask, ul_attr);\r
138         \r
139         return 0;\r
140 }\r
141 \r
142 /**\r
143  * \brief Parallel IO Controller A interrupt handler.\r
144  * Redefined PIOA interrupt handler for NVIC interrupt table.\r
145  */\r
146 void PIOA_Handler(void)\r
147 {\r
148         pio_handler_process(PIOA, ID_PIOA);\r
149 }\r
150 \r
151 /**\r
152  * \brief Parallel IO Controller B interrupt handler\r
153  * Redefined PIOB interrupt handler for NVIC interrupt table.\r
154  */\r
155 void PIOB_Handler(void)\r
156 {\r
157     pio_handler_process(PIOB, ID_PIOB);\r
158 }\r
159 \r
160 /**\r
161  * \brief Parallel IO Controller C interrupt handler.\r
162  * Redefined PIOC interrupt handler for NVIC interrupt table.\r
163  */\r
164 void PIOC_Handler(void)\r
165 {\r
166         pio_handler_process(PIOC, ID_PIOC);\r
167 }\r
168 \r
169 #if SAM3XA\r
170 /**\r
171  * \brief Parallel IO Controller D interrupt handler.\r
172  * Redefined PIOD interrupt handler for NVIC interrupt table.\r
173  */\r
174 void PIOD_Handler(void)\r
175 {\r
176         pio_handler_process(PIOD, ID_PIOD);\r
177 }\r
178 \r
179 /**\r
180  * \brief Parallel IO Controller E interrupt handler.\r
181  * Redefined PIOE interrupt handler for NVIC interrupt table.\r
182  */\r
183 void PIOE_Handler(void)\r
184 {\r
185         pio_handler_process(PIOE, ID_PIOE);\r
186 }\r
187 \r
188 /**\r
189  * \brief Parallel IO Controller F interrupt handler.\r
190  * Redefined PIOF interrupt handler for NVIC interrupt table.\r
191  */\r
192 void PIOF_Handler(void)\r
193 {\r
194         pio_handler_process(PIOF, ID_PIOF);\r
195 }\r
196 #endif\r
197 \r
198 /**\r
199  * \brief Initialize PIO interrupt management logic.\r
200  *\r
201  * \note The desired priority of PIO must be provided.\r
202  * Calling this function multiple times result in the reset of currently\r
203  * configured interrupt on the provided PIO.\r
204  *\r
205  * \param p_pio PIO controller base address.\r
206  * \param ul_irqn NVIC line number.\r
207  * \param ul_priority PIO controller interrupts priority.\r
208  */\r
209 void pio_handler_set_priority(Pio *p_pio, IRQn_Type ul_irqn, uint32_t ul_priority)\r
210 {\r
211         /* Configure PIO interrupt sources */\r
212         pio_get_interrupt_status(p_pio);\r
213         pio_disable_interrupt(p_pio, 0xFFFFFFFF);\r
214         NVIC_DisableIRQ(ul_irqn);\r
215         NVIC_ClearPendingIRQ(ul_irqn);\r
216         NVIC_SetPriority(ul_irqn, ul_priority);\r
217         NVIC_EnableIRQ(ul_irqn);\r
218 }\r
219 \r
220 /// @cond 0\r
221 /**INDENT-OFF**/\r
222 #ifdef __cplusplus\r
223 }\r
224 #endif\r
225 /**INDENT-ON**/\r
226 /// @endcond\r