]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/AVR32_UC3/DRIVERS/TC/tc.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / AVR32_UC3 / DRIVERS / TC / tc.c
1 /*This file is prepared for Doxygen automatic documentation generation.*/\r
2 /*! \file *********************************************************************\r
3  *\r
4  * \brief TC driver for AVR32 UC3.\r
5  *\r
6  * AVR32 Timer/Counter driver module.\r
7  *\r
8  * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32\r
9  * - Supported devices:  All AVR32 devices with a TC module can be used.\r
10  * - AppNote:\r
11  *\r
12  * \author               Atmel Corporation: http://www.atmel.com \n\r
13  *                       Support and FAQ: http://support.atmel.no/\r
14  *\r
15  ******************************************************************************/\r
16 \r
17 /* Copyright (c) 2007, Atmel Corporation All rights reserved.\r
18  *\r
19  * Redistribution and use in source and binary forms, with or without\r
20  * modification, are permitted provided that the following conditions are met:\r
21  *\r
22  * 1. Redistributions of source code must retain the above copyright notice,\r
23  * this list of conditions and the following disclaimer.\r
24  *\r
25  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
26  * this list of conditions and the following disclaimer in the documentation\r
27  * and/or other materials provided with the distribution.\r
28  *\r
29  * 3. The name of ATMEL may not be used to endorse or promote products derived\r
30  * from this software without specific prior written permission.\r
31  *\r
32  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
33  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
34  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND\r
35  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,\r
36  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
37  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
38  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
39  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
41  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
42  */\r
43 \r
44 \r
45 #include <avr32/io.h>\r
46 #include "compiler.h"\r
47 #include "tc.h"\r
48 \r
49 \r
50 int tc_get_interrupt_settings(volatile avr32_tc_t *tc, unsigned int channel)\r
51 {\r
52   // Check for valid input.\r
53   if (channel >= TC_NUMBER_OF_CHANNELS)\r
54     return TC_INVALID_ARGUMENT;\r
55 \r
56   return tc->channel[channel].imr;\r
57 }\r
58 \r
59 \r
60 int tc_configure_interrupts(volatile avr32_tc_t *tc, unsigned int channel, const tc_interrupt_t *bitfield)\r
61 {\r
62   // Check for valid input.\r
63   if (channel >= TC_NUMBER_OF_CHANNELS)\r
64     return TC_INVALID_ARGUMENT;\r
65 \r
66   // Enable the appropriate interrupts.\r
67   tc->channel[channel].ier = bitfield->etrgs << AVR32_TC_ETRGS_OFFSET |\r
68                              bitfield->ldrbs << AVR32_TC_LDRBS_OFFSET |\r
69                              bitfield->ldras << AVR32_TC_LDRAS_OFFSET |\r
70                              bitfield->cpcs << AVR32_TC_CPCS_OFFSET |\r
71                              bitfield->cpbs << AVR32_TC_CPBS_OFFSET |\r
72                              bitfield->cpas << AVR32_TC_CPAS_OFFSET |\r
73                              bitfield->lovrs << AVR32_TC_LOVRS_OFFSET |\r
74                              bitfield->covfs << AVR32_TC_COVFS_OFFSET;\r
75 \r
76   // Disable the appropriate interrupts.\r
77   tc->channel[channel].idr = (~bitfield->etrgs & 1) << AVR32_TC_ETRGS_OFFSET |\r
78                              (~bitfield->ldrbs & 1) << AVR32_TC_LDRBS_OFFSET |\r
79                              (~bitfield->ldras & 1) << AVR32_TC_LDRAS_OFFSET |\r
80                              (~bitfield->cpcs & 1) << AVR32_TC_CPCS_OFFSET |\r
81                              (~bitfield->cpbs & 1) << AVR32_TC_CPBS_OFFSET |\r
82                              (~bitfield->cpas & 1) << AVR32_TC_CPAS_OFFSET |\r
83                              (~bitfield->lovrs & 1) << AVR32_TC_LOVRS_OFFSET |\r
84                              (~bitfield->covfs & 1) << AVR32_TC_COVFS_OFFSET;\r
85 \r
86   return 0;\r
87 }\r
88 \r
89 \r
90 int tc_select_external_clock(volatile avr32_tc_t *tc, unsigned int channel, unsigned int ext_clk_sig_src)\r
91 {\r
92   // Check for valid input.\r
93   if (channel >= TC_NUMBER_OF_CHANNELS || ext_clk_sig_src >= 1 << AVR32_TC_BMR_TC0XC0S_SIZE)\r
94     return TC_INVALID_ARGUMENT;\r
95 \r
96   // Clear bit-field and set the correct behavior.\r
97   tc->bmr = (tc->bmr & ~(AVR32_TC_BMR_TC0XC0S_MASK << (channel * AVR32_TC_BMR_TC0XC0S_SIZE))) |\r
98             (ext_clk_sig_src << (channel * AVR32_TC_BMR_TC0XC0S_SIZE));\r
99 \r
100   return 0;\r
101 }\r
102 \r
103 \r
104 int tc_init_capture(volatile avr32_tc_t *tc, const tc_capture_opt_t *opt)\r
105 {\r
106   // Check for valid input.\r
107   if (opt->channel >= TC_NUMBER_OF_CHANNELS)\r
108     return TC_INVALID_ARGUMENT;\r
109 \r
110   // MEASURE SIGNALS: Capture operating mode.\r
111   tc->channel[opt->channel].cmr = opt->ldrb << AVR32_TC_LDRB_OFFSET |\r
112                                   opt->ldra << AVR32_TC_LDRA_OFFSET |\r
113                                   0 << AVR32_TC_WAVE_OFFSET |\r
114                                   opt->cpctrg << AVR32_TC_CPCTRG_OFFSET |\r
115                                   opt->abetrg << AVR32_TC_ABETRG_OFFSET |\r
116                                   opt->etrgedg << AVR32_TC_ETRGEDG_OFFSET|\r
117                                   opt->ldbdis << AVR32_TC_LDBDIS_OFFSET |\r
118                                   opt->ldbstop << AVR32_TC_LDBSTOP_OFFSET |\r
119                                   opt->burst << AVR32_TC_BURST_OFFSET |\r
120                                   opt->clki << AVR32_TC_CLKI_OFFSET |\r
121                                   opt->tcclks << AVR32_TC_TCCLKS_OFFSET;\r
122 \r
123   return 0;\r
124 }\r
125 \r
126 \r
127 int tc_init_waveform(volatile avr32_tc_t *tc, const tc_waveform_opt_t *opt)\r
128 {\r
129   // Check for valid input.\r
130   if (opt->channel >= TC_NUMBER_OF_CHANNELS)\r
131     return TC_INVALID_ARGUMENT;\r
132 \r
133   // GENERATE SIGNALS: Waveform operating mode.\r
134   tc->channel[opt->channel].cmr = opt->bswtrg << AVR32_TC_BSWTRG_OFFSET |\r
135                                   opt->beevt << AVR32_TC_BEEVT_OFFSET |\r
136                                   opt->bcpc << AVR32_TC_BCPC_OFFSET |\r
137                                   opt->bcpb << AVR32_TC_BCPB_OFFSET |\r
138                                   opt->aswtrg << AVR32_TC_ASWTRG_OFFSET |\r
139                                   opt->aeevt << AVR32_TC_AEEVT_OFFSET |\r
140                                   opt->acpc << AVR32_TC_ACPC_OFFSET |\r
141                                   opt->acpa << AVR32_TC_ACPA_OFFSET |\r
142                                   1 << AVR32_TC_WAVE_OFFSET |\r
143                                   opt->wavsel << AVR32_TC_WAVSEL_OFFSET |\r
144                                   opt->enetrg << AVR32_TC_ENETRG_OFFSET |\r
145                                   opt->eevt << AVR32_TC_EEVT_OFFSET |\r
146                                   opt->eevtedg << AVR32_TC_EEVTEDG_OFFSET |\r
147                                   opt->cpcdis << AVR32_TC_CPCDIS_OFFSET |\r
148                                   opt->cpcstop << AVR32_TC_CPCSTOP_OFFSET |\r
149                                   opt->burst << AVR32_TC_BURST_OFFSET |\r
150                                   opt->clki << AVR32_TC_CLKI_OFFSET |\r
151                                   opt->tcclks << AVR32_TC_TCCLKS_OFFSET;\r
152 \r
153   return 0;\r
154 }\r
155 \r
156 \r
157 int tc_start(volatile avr32_tc_t *tc, unsigned int channel)\r
158 {\r
159   // Check for valid input.\r
160   if (channel >= TC_NUMBER_OF_CHANNELS)\r
161     return TC_INVALID_ARGUMENT;\r
162 \r
163   // Enable, reset and start the selected timer/counter channel.\r
164   tc->channel[channel].ccr = AVR32_TC_SWTRG_MASK | AVR32_TC_CLKEN_MASK;\r
165 \r
166   return 0;\r
167 }\r
168 \r
169 \r
170 int tc_stop(volatile avr32_tc_t *tc, unsigned int channel)\r
171 {\r
172   // Check for valid input.\r
173   if (channel >= TC_NUMBER_OF_CHANNELS)\r
174     return TC_INVALID_ARGUMENT;\r
175 \r
176   // Disable the selected timer/counter channel.\r
177   tc->channel[channel].ccr = AVR32_TC_CLKDIS_MASK;\r
178 \r
179   return 0;\r
180 }\r
181 \r
182 \r
183 int tc_software_trigger(volatile avr32_tc_t *tc, unsigned int channel)\r
184 {\r
185   // Check for valid input.\r
186   if (channel >= TC_NUMBER_OF_CHANNELS)\r
187     return TC_INVALID_ARGUMENT;\r
188 \r
189   // Reset the selected timer/counter channel.\r
190   tc->channel[channel].ccr = AVR32_TC_SWTRG_MASK;\r
191 \r
192   return 0;\r
193 }\r
194 \r
195 \r
196 void tc_sync_trigger(volatile avr32_tc_t *tc)\r
197 {\r
198   // Reset all channels of the selected timer/counter.\r
199   tc->bcr = AVR32_TC_BCR_SYNC_MASK;\r
200 }\r
201 \r
202 \r
203 int tc_read_sr(volatile avr32_tc_t *tc, unsigned int channel)\r
204 {\r
205   // Check for valid input.\r
206   if (channel >= TC_NUMBER_OF_CHANNELS)\r
207     return TC_INVALID_ARGUMENT;\r
208 \r
209   return tc->channel[channel].sr;\r
210 }\r
211 \r
212 \r
213 int tc_read_tc(volatile avr32_tc_t *tc, unsigned int channel)\r
214 {\r
215   // Check for valid input.\r
216   if (channel >= TC_NUMBER_OF_CHANNELS)\r
217     return TC_INVALID_ARGUMENT;\r
218 \r
219   return Rd_bitfield(tc->channel[channel].cv, AVR32_TC_CV_MASK);\r
220 }\r
221 \r
222 \r
223 int tc_read_ra(volatile avr32_tc_t *tc, unsigned int channel)\r
224 {\r
225   // Check for valid input.\r
226   if (channel >= TC_NUMBER_OF_CHANNELS)\r
227     return TC_INVALID_ARGUMENT;\r
228 \r
229   return Rd_bitfield(tc->channel[channel].ra, AVR32_TC_RA_MASK);\r
230 }\r
231 \r
232 \r
233 int tc_read_rb(volatile avr32_tc_t *tc, unsigned int channel)\r
234 {\r
235   // Check for valid input.\r
236   if (channel >= TC_NUMBER_OF_CHANNELS)\r
237     return TC_INVALID_ARGUMENT;\r
238 \r
239   return Rd_bitfield(tc->channel[channel].rb, AVR32_TC_RB_MASK);\r
240 }\r
241 \r
242 \r
243 int tc_read_rc(volatile avr32_tc_t *tc, unsigned int channel)\r
244 {\r
245   // Check for valid input.\r
246   if (channel >= TC_NUMBER_OF_CHANNELS)\r
247     return TC_INVALID_ARGUMENT;\r
248 \r
249   return Rd_bitfield(tc->channel[channel].rc, AVR32_TC_RC_MASK);\r
250 }\r
251 \r
252 \r
253 int tc_write_ra(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value)\r
254 {\r
255   // Check for valid input.\r
256   if (channel >= TC_NUMBER_OF_CHANNELS)\r
257     return TC_INVALID_ARGUMENT;\r
258 \r
259   // This function is only available in WAVEFORM mode.\r
260   if (Tst_bits(tc->channel[channel].cmr, AVR32_TC_WAVE_MASK))\r
261     Wr_bitfield(tc->channel[channel].ra, AVR32_TC_RA_MASK, value);\r
262 \r
263   return value;\r
264 }\r
265 \r
266 \r
267 int tc_write_rb(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value)\r
268 {\r
269   // Check for valid input.\r
270   if (channel >= TC_NUMBER_OF_CHANNELS)\r
271     return TC_INVALID_ARGUMENT;\r
272 \r
273   // This function is only available in WAVEFORM mode.\r
274   if (Tst_bits(tc->channel[channel].cmr, AVR32_TC_WAVE_MASK))\r
275     Wr_bitfield(tc->channel[channel].rb, AVR32_TC_RB_MASK, value);\r
276 \r
277   return value;\r
278 }\r
279 \r
280 \r
281 int tc_write_rc(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value)\r
282 {\r
283   // Check for valid input.\r
284   if (channel >= TC_NUMBER_OF_CHANNELS)\r
285     return TC_INVALID_ARGUMENT;\r
286 \r
287   // This function is only available in WAVEFORM mode.\r
288   if (Tst_bits(tc->channel[channel].cmr, AVR32_TC_WAVE_MASK))\r
289     Wr_bitfield(tc->channel[channel].rc, AVR32_TC_RC_MASK, value);\r
290 \r
291   return value;\r
292 }\r