]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4_ATSAM4L_Atmel_Studio/src/asf/sam/drivers/eic/eic.c
SAM4L tickless implementation: Bug fix and update the demo project to exercise the...
[freertos] / FreeRTOS / Demo / CORTEX_M4_ATSAM4L_Atmel_Studio / src / asf / sam / drivers / eic / eic.c
1 /**\r
2  * \file\r
3  *\r
4  * \brief EIC driver for SAM\r
5  *\r
6  * Copyright (c) 2012 Atmel Corporation. All rights reserved.\r
7  *\r
8  * \asf_license_start\r
9  *\r
10  * \page License\r
11  *\r
12  * Redistribution and use in source and binary forms, with or without\r
13  * modification, are permitted provided that the following conditions are met:\r
14  *\r
15  * 1. Redistributions of source code must retain the above copyright notice,\r
16  *    this list of conditions and the following disclaimer.\r
17  *\r
18  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
19  *    this list of conditions and the following disclaimer in the documentation\r
20  *    and/or other materials provided with the distribution.\r
21  *\r
22  * 3. The name of Atmel may not be used to endorse or promote products derived\r
23  *    from this software without specific prior written permission.\r
24  *\r
25  * 4. This software may only be redistributed and used in connection with an\r
26  *    Atmel microcontroller product.\r
27  *\r
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED\r
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR\r
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
38  * POSSIBILITY OF SUCH DAMAGE.\r
39  *\r
40  * \asf_license_stop\r
41  *\r
42  */\r
43 \r
44 #include "eic.h"\r
45 #include "sysclk.h"\r
46 #include "sleepmgr.h"\r
47 \r
48 /// @cond 0\r
49 /**INDENT-OFF**/\r
50 #ifdef __cplusplus\r
51 extern "C" {\r
52 #endif\r
53 /**INDENT-ON**/\r
54 /// @endcond\r
55 \r
56 /**\r
57  * \defgroup sam_drivers_eic_group External Interrupt Controller(EIC)\r
58  *\r
59  * See \ref sam_eic_quickstart.\r
60  *\r
61  * EIC allows pins to be configured as external interrupts.\r
62  *\r
63  * @{\r
64  */\r
65 \r
66 \r
67 /**\r
68  * \internal\r
69  * \brief EIC callback function pointer array\r
70  */\r
71 eic_callback_t eic_callback_pointer[EIC_NUMBER_OF_LINES];\r
72 \r
73 /**\r
74  * \brief Write the EIC hardware with specified configuration value.\r
75  *\r
76  * \param eic Base address of the EIC module\r
77  * \param eic_line_conf Configuration parameters of the EIC module\r
78  * (see \ref eic_line_config)\r
79  * \param line_number Number of line to config\r
80  */\r
81 void eic_line_set_config(Eic *eic, uint8_t line_number,\r
82         struct eic_line_config *eic_line_conf)\r
83 {\r
84                 /* Set up mode level */\r
85                 eic->EIC_MODE = (eic_line_conf->eic_mode == EIC_MODE_LEVEL_TRIGGERED)\r
86                                 ? (eic->EIC_MODE | (1 << line_number))\r
87                                 : (eic->EIC_MODE & ~(1 << line_number));\r
88                 /* Set up edge type */\r
89                 eic->EIC_EDGE = (eic_line_conf->eic_edge == EIC_EDGE_RISING_EDGE)\r
90                                 ? (eic->EIC_EDGE | (1 << line_number))\r
91                                 : (eic->EIC_EDGE & ~(1 << line_number));\r
92                 /* Set up level */\r
93                 eic->EIC_LEVEL = (eic_line_conf->eic_level == EIC_LEVEL_HIGH_LEVEL)\r
94                                 ? (eic->EIC_LEVEL | (1 << line_number))\r
95                                 : (eic->EIC_LEVEL & ~(1 << line_number));\r
96                 /* Set up if filter is used */\r
97                 eic->EIC_FILTER = (eic_line_conf->eic_filter == EIC_FILTER_ENABLED)\r
98                                 ? (eic->EIC_FILTER | (1 << line_number))\r
99                                 : (eic->EIC_FILTER & ~(1 << line_number));\r
100                 /* Set up which mode is used : asynchronous mode/ synchronous mode */\r
101                 eic->EIC_ASYNC = (eic_line_conf->eic_async == EIC_ASYNCH_MODE)\r
102                                 ? (eic->EIC_ASYNC | (1 << line_number))\r
103                                 : (eic->EIC_ASYNC & ~(1 << line_number));\r
104 \r
105 }\r
106 \r
107 /**\r
108  * \brief Disable the EIC module\r
109  *\r
110  * \param eic Base address of the EIC module\r
111  */\r
112 void eic_disable(Eic *eic)\r
113 {\r
114         sysclk_disable_peripheral_clock(eic);\r
115         sleepmgr_unlock_mode(SLEEPMGR_BACKUP);\r
116 }\r
117 \r
118 /**\r
119  * \brief Enable the EIC module\r
120  *\r
121  * \param eic Base address of the EIC module\r
122  */\r
123 void eic_enable(Eic *eic)\r
124 {\r
125         sysclk_enable_peripheral_clock(eic);\r
126         sleepmgr_lock_mode(SLEEPMGR_BACKUP);\r
127 }\r
128 \r
129 /**\r
130  * \brief Set callback for given EIC line\r
131  *\r
132  * \param eic Base address of the EIC module\r
133  * \param line_number Number of line.\r
134  * \param callback callback function pointer.\r
135  * \param irq_line  interrupt line.\r
136  * \param irq_level interrupt level.\r
137  */\r
138 void eic_line_set_callback(Eic *eic, uint8_t line_number,\r
139         eic_callback_t callback, uint8_t irq_line, uint8_t irq_level)\r
140 {\r
141         eic_callback_pointer[line_number] = callback;\r
142         irq_register_handler((IRQn_Type)irq_line, irq_level);\r
143         eic_line_enable_interrupt(eic, line_number);\r
144 }\r
145 \r
146 /**\r
147  * \internal\r
148  * \brief Common EIC line interrupt handler\r
149  *\r
150  * The optional callback used by the interrupt handler is set by the\r
151  * eic_line_set_callback() function.\r
152  *\r
153  * \param line_number EIC linel number to handle interrupt for\r
154  */\r
155 static void eic_line_interrupt(uint8_t line_number)\r
156 {\r
157         if (eic_callback_pointer[line_number]) {\r
158                 eic_callback_pointer[line_number]();\r
159         } else {\r
160                 Assert(false); /* Catch unexpected interrupt */\r
161         }\r
162 }\r
163 \r
164 /**\r
165  * \brief Interrupt handler for EIC NMI.\r
166  */\r
167 void NMI_Handler(void)\r
168 {\r
169         eic_line_interrupt(0);\r
170 }\r
171 \r
172 /**\r
173  * \brief Interrupt handler for EIC line 1.\r
174  */\r
175 void EIC_1_Handler(void)\r
176 {\r
177         eic_line_interrupt(1);\r
178 }\r
179 \r
180 /**\r
181  * \brief Interrupt handler for EIC line 2.\r
182  */\r
183 void EIC_2_Handler(void)\r
184 {\r
185         eic_line_interrupt(2);\r
186 }\r
187 \r
188 /**\r
189  * \brief Interrupt handler for EIC line 3.\r
190  */\r
191 void EIC_3_Handler(void)\r
192 {\r
193         eic_line_interrupt(3);\r
194 }\r
195 \r
196 /**\r
197  * \brief Interrupt handler for EIC line 4.\r
198  */\r
199 void EIC_4_Handler(void)\r
200 {\r
201         eic_line_interrupt(4);\r
202 }\r
203 \r
204 /**\r
205  * \brief Interrupt handler for EIC line 5.\r
206  */\r
207 void EIC_5_Handler(void)\r
208 {\r
209         eic_line_interrupt(5);\r
210 }\r
211 \r
212 /**\r
213  * \brief Interrupt handler for EIC line 6.\r
214  */\r
215 void EIC_6_Handler(void)\r
216 {\r
217         eic_line_interrupt(6);\r
218 }\r
219 \r
220 /**\r
221  * \brief Interrupt handler for EIC line 7.\r
222  */\r
223 void EIC_7_Handler(void)\r
224 {\r
225         eic_line_interrupt(7);\r
226 }\r
227 \r
228 /**\r
229  * \brief Interrupt handler for EIC line 8.\r
230  */\r
231 void EIC_8_Handler(void)\r
232 {\r
233         eic_line_interrupt(8);\r
234 }\r
235 \r
236 //@}\r
237 \r
238 /// @cond 0\r
239 /**INDENT-OFF**/\r
240 #ifdef __cplusplus\r
241 }\r
242 #endif\r
243 /**INDENT-ON**/\r
244 /// @endcond\r