1*1b2596b5SMatthias Ringwald /**
2*1b2596b5SMatthias Ringwald * \file
3*1b2596b5SMatthias Ringwald *
4*1b2596b5SMatthias Ringwald * \brief SAM Timer Counter (TC) driver.
5*1b2596b5SMatthias Ringwald *
6*1b2596b5SMatthias Ringwald * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
7*1b2596b5SMatthias Ringwald *
8*1b2596b5SMatthias Ringwald * \asf_license_start
9*1b2596b5SMatthias Ringwald *
10*1b2596b5SMatthias Ringwald * \page License
11*1b2596b5SMatthias Ringwald *
12*1b2596b5SMatthias Ringwald * Redistribution and use in source and binary forms, with or without
13*1b2596b5SMatthias Ringwald * modification, are permitted provided that the following conditions are met:
14*1b2596b5SMatthias Ringwald *
15*1b2596b5SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright notice,
16*1b2596b5SMatthias Ringwald * this list of conditions and the following disclaimer.
17*1b2596b5SMatthias Ringwald *
18*1b2596b5SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright notice,
19*1b2596b5SMatthias Ringwald * this list of conditions and the following disclaimer in the documentation
20*1b2596b5SMatthias Ringwald * and/or other materials provided with the distribution.
21*1b2596b5SMatthias Ringwald *
22*1b2596b5SMatthias Ringwald * 3. The name of Atmel may not be used to endorse or promote products derived
23*1b2596b5SMatthias Ringwald * from this software without specific prior written permission.
24*1b2596b5SMatthias Ringwald *
25*1b2596b5SMatthias Ringwald * 4. This software may only be redistributed and used in connection with an
26*1b2596b5SMatthias Ringwald * Atmel microcontroller product.
27*1b2596b5SMatthias Ringwald *
28*1b2596b5SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29*1b2596b5SMatthias Ringwald * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30*1b2596b5SMatthias Ringwald * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31*1b2596b5SMatthias Ringwald * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32*1b2596b5SMatthias Ringwald * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33*1b2596b5SMatthias Ringwald * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34*1b2596b5SMatthias Ringwald * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35*1b2596b5SMatthias Ringwald * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36*1b2596b5SMatthias Ringwald * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37*1b2596b5SMatthias Ringwald * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38*1b2596b5SMatthias Ringwald * POSSIBILITY OF SUCH DAMAGE.
39*1b2596b5SMatthias Ringwald *
40*1b2596b5SMatthias Ringwald * \asf_license_stop
41*1b2596b5SMatthias Ringwald *
42*1b2596b5SMatthias Ringwald */
43*1b2596b5SMatthias Ringwald /*
44*1b2596b5SMatthias Ringwald * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45*1b2596b5SMatthias Ringwald */
46*1b2596b5SMatthias Ringwald
47*1b2596b5SMatthias Ringwald #include <assert.h>
48*1b2596b5SMatthias Ringwald #include "tc.h"
49*1b2596b5SMatthias Ringwald
50*1b2596b5SMatthias Ringwald /// @cond
51*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
52*1b2596b5SMatthias Ringwald #ifdef __cplusplus
53*1b2596b5SMatthias Ringwald extern "C" {
54*1b2596b5SMatthias Ringwald #endif
55*1b2596b5SMatthias Ringwald /**INDENT-ON**/
56*1b2596b5SMatthias Ringwald /// @endcond
57*1b2596b5SMatthias Ringwald
58*1b2596b5SMatthias Ringwald #ifndef TC_WPMR_WPKEY_PASSWD
59*1b2596b5SMatthias Ringwald #define TC_WPMR_WPKEY_PASSWD TC_WPMR_WPKEY((uint32_t)0x54494D)
60*1b2596b5SMatthias Ringwald #endif
61*1b2596b5SMatthias Ringwald
62*1b2596b5SMatthias Ringwald /**
63*1b2596b5SMatthias Ringwald * \brief Configure TC for timer, waveform generation, or capture.
64*1b2596b5SMatthias Ringwald *
65*1b2596b5SMatthias Ringwald * \param[in,out] p_tc Module hardware register base address pointer
66*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to configure
67*1b2596b5SMatthias Ringwald * \param[in] ul_mode Control mode register bitmask value to set
68*1b2596b5SMatthias Ringwald *
69*1b2596b5SMatthias Ringwald * \note For more information regarding <i>ul_mode</i> configuration refer to
70*1b2596b5SMatthias Ringwald * the section entitled "Channel Mode Register: Capture Mode" and/or section
71*1b2596b5SMatthias Ringwald * "Waveform Operating Mode" in the device-specific datasheet.
72*1b2596b5SMatthias Ringwald *
73*1b2596b5SMatthias Ringwald * \note If the TC is configured for waveform generation then the external event
74*1b2596b5SMatthias Ringwald * selection (EEVT) should only be set to TC_CMR_EEVT_TIOB, or the
75*1b2596b5SMatthias Ringwald * equivalent value of 0, if it really is the intention to use TIOB as an
76*1b2596b5SMatthias Ringwald * external event trigger. This is because this setting forces TIOB to be
77*1b2596b5SMatthias Ringwald * an input, even if the external event trigger has not been enabled with
78*1b2596b5SMatthias Ringwald * TC_CMR_ENETRG, and thus prevents normal operation of TIOB.
79*1b2596b5SMatthias Ringwald */
tc_init(Tc * p_tc,uint32_t ul_channel,uint32_t ul_mode)80*1b2596b5SMatthias Ringwald void tc_init(
81*1b2596b5SMatthias Ringwald Tc *p_tc,
82*1b2596b5SMatthias Ringwald uint32_t ul_channel,
83*1b2596b5SMatthias Ringwald uint32_t ul_mode)
84*1b2596b5SMatthias Ringwald {
85*1b2596b5SMatthias Ringwald TcChannel *tc_channel;
86*1b2596b5SMatthias Ringwald
87*1b2596b5SMatthias Ringwald /* Validate inputs. */
88*1b2596b5SMatthias Ringwald Assert(p_tc);
89*1b2596b5SMatthias Ringwald Assert(ul_channel <
90*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
91*1b2596b5SMatthias Ringwald tc_channel = p_tc->TC_CHANNEL + ul_channel;
92*1b2596b5SMatthias Ringwald
93*1b2596b5SMatthias Ringwald /* Disable TC clock. */
94*1b2596b5SMatthias Ringwald tc_channel->TC_CCR = TC_CCR_CLKDIS;
95*1b2596b5SMatthias Ringwald
96*1b2596b5SMatthias Ringwald /* Disable interrupts. */
97*1b2596b5SMatthias Ringwald tc_channel->TC_IDR = 0xFFFFFFFF;
98*1b2596b5SMatthias Ringwald
99*1b2596b5SMatthias Ringwald /* Clear status register. */
100*1b2596b5SMatthias Ringwald tc_channel->TC_SR;
101*1b2596b5SMatthias Ringwald
102*1b2596b5SMatthias Ringwald /* Set mode. */
103*1b2596b5SMatthias Ringwald tc_channel->TC_CMR = ul_mode;
104*1b2596b5SMatthias Ringwald }
105*1b2596b5SMatthias Ringwald
106*1b2596b5SMatthias Ringwald /**
107*1b2596b5SMatthias Ringwald * \brief Asserts a SYNC signal to generate a software trigger on
108*1b2596b5SMatthias Ringwald * all channels.
109*1b2596b5SMatthias Ringwald *
110*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
111*1b2596b5SMatthias Ringwald *
112*1b2596b5SMatthias Ringwald */
tc_sync_trigger(Tc * p_tc)113*1b2596b5SMatthias Ringwald void tc_sync_trigger(
114*1b2596b5SMatthias Ringwald Tc *p_tc)
115*1b2596b5SMatthias Ringwald {
116*1b2596b5SMatthias Ringwald /* Validate inputs. */
117*1b2596b5SMatthias Ringwald Assert(p_tc);
118*1b2596b5SMatthias Ringwald
119*1b2596b5SMatthias Ringwald p_tc->TC_BCR = TC_BCR_SYNC;
120*1b2596b5SMatthias Ringwald }
121*1b2596b5SMatthias Ringwald
122*1b2596b5SMatthias Ringwald /**
123*1b2596b5SMatthias Ringwald * \brief Configure the TC Block mode.
124*1b2596b5SMatthias Ringwald *
125*1b2596b5SMatthias Ringwald * \note The function tc_init() must be called prior to this one.
126*1b2596b5SMatthias Ringwald *
127*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
128*1b2596b5SMatthias Ringwald * \param[in] ul_blockmode Block mode register value to set
129*1b2596b5SMatthias Ringwald *
130*1b2596b5SMatthias Ringwald * \note For more information regarding <i>ul_blockmode</i> configuration refer to
131*1b2596b5SMatthias Ringwald * the section entitled "TC Block Mode Register" in the device-specific datasheet.
132*1b2596b5SMatthias Ringwald */
tc_set_block_mode(Tc * p_tc,uint32_t ul_blockmode)133*1b2596b5SMatthias Ringwald void tc_set_block_mode(
134*1b2596b5SMatthias Ringwald Tc *p_tc,
135*1b2596b5SMatthias Ringwald uint32_t ul_blockmode)
136*1b2596b5SMatthias Ringwald {
137*1b2596b5SMatthias Ringwald /* Validate inputs. */
138*1b2596b5SMatthias Ringwald Assert(p_tc);
139*1b2596b5SMatthias Ringwald
140*1b2596b5SMatthias Ringwald p_tc->TC_BMR = ul_blockmode;
141*1b2596b5SMatthias Ringwald }
142*1b2596b5SMatthias Ringwald
143*1b2596b5SMatthias Ringwald #if (!SAM3U) || defined(__DOXYGEN__)
144*1b2596b5SMatthias Ringwald
145*1b2596b5SMatthias Ringwald /**
146*1b2596b5SMatthias Ringwald * \brief Configure TC for 2-bit Gray Counter for Stepper Motor.
147*1b2596b5SMatthias Ringwald * \note The function tc_init() must be called prior to this one.
148*1b2596b5SMatthias Ringwald *
149*1b2596b5SMatthias Ringwald * \note This function is not available on SAM3U devices.
150*1b2596b5SMatthias Ringwald *
151*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
152*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to configure
153*1b2596b5SMatthias Ringwald * \param[in] ul_steppermode Stepper motor mode register value to set
154*1b2596b5SMatthias Ringwald *
155*1b2596b5SMatthias Ringwald * \return 0 for OK.
156*1b2596b5SMatthias Ringwald */
tc_init_2bit_gray(Tc * p_tc,uint32_t ul_channel,uint32_t ul_steppermode)157*1b2596b5SMatthias Ringwald uint32_t tc_init_2bit_gray(
158*1b2596b5SMatthias Ringwald Tc *p_tc,
159*1b2596b5SMatthias Ringwald uint32_t ul_channel,
160*1b2596b5SMatthias Ringwald uint32_t ul_steppermode)
161*1b2596b5SMatthias Ringwald {
162*1b2596b5SMatthias Ringwald /* Validate inputs. */
163*1b2596b5SMatthias Ringwald Assert(p_tc);
164*1b2596b5SMatthias Ringwald Assert(ul_channel <
165*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
166*1b2596b5SMatthias Ringwald
167*1b2596b5SMatthias Ringwald p_tc->TC_CHANNEL[ul_channel].TC_SMMR = ul_steppermode;
168*1b2596b5SMatthias Ringwald return 0;
169*1b2596b5SMatthias Ringwald }
170*1b2596b5SMatthias Ringwald
171*1b2596b5SMatthias Ringwald #endif /* (!SAM3U) || defined(__DOXYGEN__) */
172*1b2596b5SMatthias Ringwald
173*1b2596b5SMatthias Ringwald /**
174*1b2596b5SMatthias Ringwald * \brief Start the TC clock on the specified channel.
175*1b2596b5SMatthias Ringwald *
176*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
177*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to configure
178*1b2596b5SMatthias Ringwald */
tc_start(Tc * p_tc,uint32_t ul_channel)179*1b2596b5SMatthias Ringwald void tc_start(
180*1b2596b5SMatthias Ringwald Tc *p_tc,
181*1b2596b5SMatthias Ringwald uint32_t ul_channel)
182*1b2596b5SMatthias Ringwald {
183*1b2596b5SMatthias Ringwald /* Validate inputs. */
184*1b2596b5SMatthias Ringwald Assert(p_tc);
185*1b2596b5SMatthias Ringwald Assert(ul_channel <
186*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
187*1b2596b5SMatthias Ringwald
188*1b2596b5SMatthias Ringwald p_tc->TC_CHANNEL[ul_channel].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
189*1b2596b5SMatthias Ringwald }
190*1b2596b5SMatthias Ringwald
191*1b2596b5SMatthias Ringwald /**
192*1b2596b5SMatthias Ringwald * \brief Stop the TC clock on the specified channel.
193*1b2596b5SMatthias Ringwald *
194*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
195*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to configure
196*1b2596b5SMatthias Ringwald */
tc_stop(Tc * p_tc,uint32_t ul_channel)197*1b2596b5SMatthias Ringwald void tc_stop(
198*1b2596b5SMatthias Ringwald Tc *p_tc,
199*1b2596b5SMatthias Ringwald uint32_t ul_channel)
200*1b2596b5SMatthias Ringwald {
201*1b2596b5SMatthias Ringwald /* Validate inputs. */
202*1b2596b5SMatthias Ringwald Assert(p_tc);
203*1b2596b5SMatthias Ringwald Assert(ul_channel <
204*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
205*1b2596b5SMatthias Ringwald
206*1b2596b5SMatthias Ringwald p_tc->TC_CHANNEL[ul_channel].TC_CCR = TC_CCR_CLKDIS;
207*1b2596b5SMatthias Ringwald }
208*1b2596b5SMatthias Ringwald
209*1b2596b5SMatthias Ringwald /**
210*1b2596b5SMatthias Ringwald * \brief Read the counter value on the specified channel.
211*1b2596b5SMatthias Ringwald *
212*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
213*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to read
214*1b2596b5SMatthias Ringwald *
215*1b2596b5SMatthias Ringwald * \return The counter value.
216*1b2596b5SMatthias Ringwald */
tc_read_cv(Tc * p_tc,uint32_t ul_channel)217*1b2596b5SMatthias Ringwald uint32_t tc_read_cv(
218*1b2596b5SMatthias Ringwald Tc *p_tc,
219*1b2596b5SMatthias Ringwald uint32_t ul_channel)
220*1b2596b5SMatthias Ringwald {
221*1b2596b5SMatthias Ringwald /* Validate inputs. */
222*1b2596b5SMatthias Ringwald Assert(p_tc);
223*1b2596b5SMatthias Ringwald Assert(ul_channel <
224*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
225*1b2596b5SMatthias Ringwald
226*1b2596b5SMatthias Ringwald return p_tc->TC_CHANNEL[ul_channel].TC_CV;
227*1b2596b5SMatthias Ringwald }
228*1b2596b5SMatthias Ringwald
229*1b2596b5SMatthias Ringwald /**
230*1b2596b5SMatthias Ringwald * \brief Read TC Register A (RA) on the specified channel.
231*1b2596b5SMatthias Ringwald *
232*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
233*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to read
234*1b2596b5SMatthias Ringwald *
235*1b2596b5SMatthias Ringwald * \return The TC Register A (RA) value.
236*1b2596b5SMatthias Ringwald */
tc_read_ra(Tc * p_tc,uint32_t ul_channel)237*1b2596b5SMatthias Ringwald uint32_t tc_read_ra(
238*1b2596b5SMatthias Ringwald Tc *p_tc,
239*1b2596b5SMatthias Ringwald uint32_t ul_channel)
240*1b2596b5SMatthias Ringwald {
241*1b2596b5SMatthias Ringwald /* Validate inputs. */
242*1b2596b5SMatthias Ringwald Assert(p_tc);
243*1b2596b5SMatthias Ringwald Assert(ul_channel <
244*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
245*1b2596b5SMatthias Ringwald
246*1b2596b5SMatthias Ringwald return p_tc->TC_CHANNEL[ul_channel].TC_RA;
247*1b2596b5SMatthias Ringwald }
248*1b2596b5SMatthias Ringwald
249*1b2596b5SMatthias Ringwald /**
250*1b2596b5SMatthias Ringwald * \brief Read TC Register B (RB) on the specified channel.
251*1b2596b5SMatthias Ringwald *
252*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
253*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to read
254*1b2596b5SMatthias Ringwald *
255*1b2596b5SMatthias Ringwald * \return The TC Register B (RB) value.
256*1b2596b5SMatthias Ringwald */
tc_read_rb(Tc * p_tc,uint32_t ul_channel)257*1b2596b5SMatthias Ringwald uint32_t tc_read_rb(
258*1b2596b5SMatthias Ringwald Tc *p_tc,
259*1b2596b5SMatthias Ringwald uint32_t ul_channel)
260*1b2596b5SMatthias Ringwald {
261*1b2596b5SMatthias Ringwald /* Validate inputs. */
262*1b2596b5SMatthias Ringwald Assert(p_tc);
263*1b2596b5SMatthias Ringwald Assert(ul_channel <
264*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
265*1b2596b5SMatthias Ringwald
266*1b2596b5SMatthias Ringwald return p_tc->TC_CHANNEL[ul_channel].TC_RB;
267*1b2596b5SMatthias Ringwald }
268*1b2596b5SMatthias Ringwald
269*1b2596b5SMatthias Ringwald /**
270*1b2596b5SMatthias Ringwald * \brief Read TC Register C (RC) on the specified channel.
271*1b2596b5SMatthias Ringwald *
272*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
273*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to read
274*1b2596b5SMatthias Ringwald *
275*1b2596b5SMatthias Ringwald * \return The Register C (RC) value.
276*1b2596b5SMatthias Ringwald */
tc_read_rc(Tc * p_tc,uint32_t ul_channel)277*1b2596b5SMatthias Ringwald uint32_t tc_read_rc(
278*1b2596b5SMatthias Ringwald Tc *p_tc,
279*1b2596b5SMatthias Ringwald uint32_t ul_channel)
280*1b2596b5SMatthias Ringwald {
281*1b2596b5SMatthias Ringwald /* Validate inputs. */
282*1b2596b5SMatthias Ringwald Assert(p_tc);
283*1b2596b5SMatthias Ringwald Assert(ul_channel <
284*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
285*1b2596b5SMatthias Ringwald
286*1b2596b5SMatthias Ringwald return p_tc->TC_CHANNEL[ul_channel].TC_RC;
287*1b2596b5SMatthias Ringwald }
288*1b2596b5SMatthias Ringwald
289*1b2596b5SMatthias Ringwald /**
290*1b2596b5SMatthias Ringwald * \brief Write to TC Register A (RA) on the specified channel.
291*1b2596b5SMatthias Ringwald *
292*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
293*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to write
294*1b2596b5SMatthias Ringwald * \param[in] ul_value Value to write
295*1b2596b5SMatthias Ringwald */
tc_write_ra(Tc * p_tc,uint32_t ul_channel,uint32_t ul_value)296*1b2596b5SMatthias Ringwald void tc_write_ra(
297*1b2596b5SMatthias Ringwald Tc *p_tc,
298*1b2596b5SMatthias Ringwald uint32_t ul_channel,
299*1b2596b5SMatthias Ringwald uint32_t ul_value)
300*1b2596b5SMatthias Ringwald {
301*1b2596b5SMatthias Ringwald /* Validate inputs. */
302*1b2596b5SMatthias Ringwald Assert(p_tc);
303*1b2596b5SMatthias Ringwald Assert(ul_channel <
304*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
305*1b2596b5SMatthias Ringwald
306*1b2596b5SMatthias Ringwald p_tc->TC_CHANNEL[ul_channel].TC_RA = ul_value;
307*1b2596b5SMatthias Ringwald }
308*1b2596b5SMatthias Ringwald
309*1b2596b5SMatthias Ringwald /**
310*1b2596b5SMatthias Ringwald * \brief Write to TC Register B (RB) on the specified channel.
311*1b2596b5SMatthias Ringwald *
312*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
313*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to write
314*1b2596b5SMatthias Ringwald * \param[in] ul_value Value to write
315*1b2596b5SMatthias Ringwald */
tc_write_rb(Tc * p_tc,uint32_t ul_channel,uint32_t ul_value)316*1b2596b5SMatthias Ringwald void tc_write_rb(
317*1b2596b5SMatthias Ringwald Tc *p_tc,
318*1b2596b5SMatthias Ringwald uint32_t ul_channel,
319*1b2596b5SMatthias Ringwald uint32_t ul_value)
320*1b2596b5SMatthias Ringwald {
321*1b2596b5SMatthias Ringwald /* Validate inputs. */
322*1b2596b5SMatthias Ringwald Assert(p_tc);
323*1b2596b5SMatthias Ringwald Assert(ul_channel <
324*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
325*1b2596b5SMatthias Ringwald
326*1b2596b5SMatthias Ringwald p_tc->TC_CHANNEL[ul_channel].TC_RB = ul_value;
327*1b2596b5SMatthias Ringwald }
328*1b2596b5SMatthias Ringwald
329*1b2596b5SMatthias Ringwald /**
330*1b2596b5SMatthias Ringwald * \brief Write to TC Register C (RC) on the selected channel.
331*1b2596b5SMatthias Ringwald *
332*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
333*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to write
334*1b2596b5SMatthias Ringwald * \param[in] ul_value Value to write
335*1b2596b5SMatthias Ringwald */
tc_write_rc(Tc * p_tc,uint32_t ul_channel,uint32_t ul_value)336*1b2596b5SMatthias Ringwald void tc_write_rc(
337*1b2596b5SMatthias Ringwald Tc *p_tc,
338*1b2596b5SMatthias Ringwald uint32_t ul_channel,
339*1b2596b5SMatthias Ringwald uint32_t ul_value)
340*1b2596b5SMatthias Ringwald {
341*1b2596b5SMatthias Ringwald /* Validate inputs. */
342*1b2596b5SMatthias Ringwald Assert(p_tc);
343*1b2596b5SMatthias Ringwald Assert(ul_channel <
344*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
345*1b2596b5SMatthias Ringwald
346*1b2596b5SMatthias Ringwald p_tc->TC_CHANNEL[ul_channel].TC_RC = ul_value;
347*1b2596b5SMatthias Ringwald }
348*1b2596b5SMatthias Ringwald
349*1b2596b5SMatthias Ringwald /**
350*1b2596b5SMatthias Ringwald * \brief Enable the TC interrupts on the specified channel.
351*1b2596b5SMatthias Ringwald *
352*1b2596b5SMatthias Ringwald * \param[in,out] p_tc Module hardware register base address pointer
353*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to configure
354*1b2596b5SMatthias Ringwald * \param[in] ul_sources Bitmask of interrupt sources
355*1b2596b5SMatthias Ringwald *
356*1b2596b5SMatthias Ringwald * Where the input parameter <i>ul_sources</i> can be one or more of the following:
357*1b2596b5SMatthias Ringwald * <table>
358*1b2596b5SMatthias Ringwald * <tr>
359*1b2596b5SMatthias Ringwald * <th>Parameter Value</th>
360*1b2596b5SMatthias Ringwald * <th>Description</th>
361*1b2596b5SMatthias Ringwald * </tr>
362*1b2596b5SMatthias Ringwald * <tr><td>TC_IER_COVFS</td><td>Enables the Counter Overflow Interrupt</td></tr>
363*1b2596b5SMatthias Ringwald * <tr><td>TC_IER_LOVRS</td><td>Enables the Load Overrun Interrupt</td></tr>
364*1b2596b5SMatthias Ringwald * <tr><td>TC_IER_CPAS</td><td>Enables the RA Compare Interrupt</td></tr>
365*1b2596b5SMatthias Ringwald * <tr><td>TC_IER_CPBS</td><td>Enables the RB Compare Interrupt</td></tr>
366*1b2596b5SMatthias Ringwald * <tr><td>TC_IER_CPCS</td><td>Enables the RC Compare Interrupt</td></tr>
367*1b2596b5SMatthias Ringwald * <tr><td>TC_IER_LDRAS</td><td>Enables the RA Load Interrupt</td></tr>
368*1b2596b5SMatthias Ringwald * <tr><td>TC_IER_LDRBS</td><td>Enables the RB Load Interrupt</td></tr>
369*1b2596b5SMatthias Ringwald * <tr><td>TC_IER_ETRGS</td><td>Enables the External Trigger Interrupt</td></tr>
370*1b2596b5SMatthias Ringwald * </table>
371*1b2596b5SMatthias Ringwald */
tc_enable_interrupt(Tc * p_tc,uint32_t ul_channel,uint32_t ul_sources)372*1b2596b5SMatthias Ringwald void tc_enable_interrupt(
373*1b2596b5SMatthias Ringwald Tc *p_tc,
374*1b2596b5SMatthias Ringwald uint32_t ul_channel,
375*1b2596b5SMatthias Ringwald uint32_t ul_sources)
376*1b2596b5SMatthias Ringwald {
377*1b2596b5SMatthias Ringwald TcChannel *tc_channel;
378*1b2596b5SMatthias Ringwald
379*1b2596b5SMatthias Ringwald /* Validate inputs. */
380*1b2596b5SMatthias Ringwald Assert(p_tc);
381*1b2596b5SMatthias Ringwald Assert(ul_channel <
382*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
383*1b2596b5SMatthias Ringwald tc_channel = p_tc->TC_CHANNEL + ul_channel;
384*1b2596b5SMatthias Ringwald tc_channel->TC_IER = ul_sources;
385*1b2596b5SMatthias Ringwald }
386*1b2596b5SMatthias Ringwald
387*1b2596b5SMatthias Ringwald /**
388*1b2596b5SMatthias Ringwald * \brief Disable TC interrupts on the specified channel.
389*1b2596b5SMatthias Ringwald *
390*1b2596b5SMatthias Ringwald * \param[in,out] p_tc Module hardware register base address pointer
391*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to configure
392*1b2596b5SMatthias Ringwald * \param[in] ul_sources A bitmask of Interrupt sources
393*1b2596b5SMatthias Ringwald *
394*1b2596b5SMatthias Ringwald * Where the input parameter <i>ul_sources</i> can be one or more of the following:
395*1b2596b5SMatthias Ringwald * <table>
396*1b2596b5SMatthias Ringwald * <tr>
397*1b2596b5SMatthias Ringwald * <th>Parameter Value</th>
398*1b2596b5SMatthias Ringwald * <th>Description</th>
399*1b2596b5SMatthias Ringwald * </tr>
400*1b2596b5SMatthias Ringwald * <tr><td>TC_IDR_COVFS</td><td>Disables the Counter Overflow Interrupt</td></tr>
401*1b2596b5SMatthias Ringwald * <tr><td>TC_IDR_LOVRS</td><td>Disables the Load Overrun Interrupt</td></tr>
402*1b2596b5SMatthias Ringwald * <tr><td>TC_IDR_CPAS</td><td>Disables the RA Compare Interrupt</td></tr>
403*1b2596b5SMatthias Ringwald * <tr><td>TC_IDR_CPBS</td><td>Disables the RB Compare Interrupt</td></tr>
404*1b2596b5SMatthias Ringwald * <tr><td>TC_IDR_CPCS</td><td>Disables the RC Compare Interrupt</td></tr>
405*1b2596b5SMatthias Ringwald * <tr><td>TC_IDR_LDRAS</td><td>Disables the RA Load Interrupt</td></tr>
406*1b2596b5SMatthias Ringwald * <tr><td>TC_IDR_LDRBS</td><td>Disables the RB Load Interrupt</td></tr>
407*1b2596b5SMatthias Ringwald * <tr><td>TC_IDR_ETRGS</td><td>Disables the External Trigger Interrupt</td></tr>
408*1b2596b5SMatthias Ringwald * </table>
409*1b2596b5SMatthias Ringwald */
tc_disable_interrupt(Tc * p_tc,uint32_t ul_channel,uint32_t ul_sources)410*1b2596b5SMatthias Ringwald void tc_disable_interrupt(
411*1b2596b5SMatthias Ringwald Tc *p_tc,
412*1b2596b5SMatthias Ringwald uint32_t ul_channel,
413*1b2596b5SMatthias Ringwald uint32_t ul_sources)
414*1b2596b5SMatthias Ringwald {
415*1b2596b5SMatthias Ringwald TcChannel *tc_channel;
416*1b2596b5SMatthias Ringwald
417*1b2596b5SMatthias Ringwald /* Validate inputs. */
418*1b2596b5SMatthias Ringwald Assert(p_tc);
419*1b2596b5SMatthias Ringwald Assert(ul_channel <
420*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
421*1b2596b5SMatthias Ringwald tc_channel = p_tc->TC_CHANNEL + ul_channel;
422*1b2596b5SMatthias Ringwald tc_channel->TC_IDR = ul_sources;
423*1b2596b5SMatthias Ringwald }
424*1b2596b5SMatthias Ringwald
425*1b2596b5SMatthias Ringwald /**
426*1b2596b5SMatthias Ringwald * \brief Read the TC interrupt mask for the specified channel.
427*1b2596b5SMatthias Ringwald *
428*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
429*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel to read
430*1b2596b5SMatthias Ringwald *
431*1b2596b5SMatthias Ringwald * \return The TC interrupt mask value.
432*1b2596b5SMatthias Ringwald */
tc_get_interrupt_mask(Tc * p_tc,uint32_t ul_channel)433*1b2596b5SMatthias Ringwald uint32_t tc_get_interrupt_mask(
434*1b2596b5SMatthias Ringwald Tc *p_tc,
435*1b2596b5SMatthias Ringwald uint32_t ul_channel)
436*1b2596b5SMatthias Ringwald {
437*1b2596b5SMatthias Ringwald TcChannel *tc_channel;
438*1b2596b5SMatthias Ringwald
439*1b2596b5SMatthias Ringwald /* Validate inputs. */
440*1b2596b5SMatthias Ringwald Assert(p_tc);
441*1b2596b5SMatthias Ringwald Assert(ul_channel <
442*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
443*1b2596b5SMatthias Ringwald tc_channel = p_tc->TC_CHANNEL + ul_channel;
444*1b2596b5SMatthias Ringwald return tc_channel->TC_IMR;
445*1b2596b5SMatthias Ringwald }
446*1b2596b5SMatthias Ringwald
447*1b2596b5SMatthias Ringwald /**
448*1b2596b5SMatthias Ringwald * \brief Get the current status for the specified TC channel.
449*1b2596b5SMatthias Ringwald *
450*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
451*1b2596b5SMatthias Ringwald * \param[in] ul_channel Channel number
452*1b2596b5SMatthias Ringwald *
453*1b2596b5SMatthias Ringwald * \return The current TC status.
454*1b2596b5SMatthias Ringwald */
tc_get_status(Tc * p_tc,uint32_t ul_channel)455*1b2596b5SMatthias Ringwald uint32_t tc_get_status(
456*1b2596b5SMatthias Ringwald Tc *p_tc,
457*1b2596b5SMatthias Ringwald uint32_t ul_channel)
458*1b2596b5SMatthias Ringwald {
459*1b2596b5SMatthias Ringwald TcChannel *tc_channel;
460*1b2596b5SMatthias Ringwald
461*1b2596b5SMatthias Ringwald /* Validate inputs. */
462*1b2596b5SMatthias Ringwald Assert(p_tc);
463*1b2596b5SMatthias Ringwald Assert(ul_channel <
464*1b2596b5SMatthias Ringwald (sizeof(p_tc->TC_CHANNEL) / sizeof(p_tc->TC_CHANNEL[0])));
465*1b2596b5SMatthias Ringwald
466*1b2596b5SMatthias Ringwald tc_channel = p_tc->TC_CHANNEL + ul_channel;
467*1b2596b5SMatthias Ringwald return tc_channel->TC_SR;
468*1b2596b5SMatthias Ringwald }
469*1b2596b5SMatthias Ringwald
470*1b2596b5SMatthias Ringwald /* TC divisor used to find the lowest acceptable timer frequency */
471*1b2596b5SMatthias Ringwald #define TC_DIV_FACTOR 65536
472*1b2596b5SMatthias Ringwald
473*1b2596b5SMatthias Ringwald #if (!SAM4L) && !defined(__DOXYGEN__)
474*1b2596b5SMatthias Ringwald
475*1b2596b5SMatthias Ringwald #ifndef FREQ_SLOW_CLOCK_EXT
476*1b2596b5SMatthias Ringwald #define FREQ_SLOW_CLOCK_EXT 32768 /* External slow clock frequency (hz) */
477*1b2596b5SMatthias Ringwald #endif
478*1b2596b5SMatthias Ringwald
479*1b2596b5SMatthias Ringwald /**
480*1b2596b5SMatthias Ringwald * \brief Find the best MCK divisor.
481*1b2596b5SMatthias Ringwald *
482*1b2596b5SMatthias Ringwald * Finds the best MCK divisor given the timer frequency and MCK. The result
483*1b2596b5SMatthias Ringwald * is guaranteed to satisfy the following equation:
484*1b2596b5SMatthias Ringwald * \code (MCK / (DIV * 65536)) <= freq <= (MCK / DIV) \endcode
485*1b2596b5SMatthias Ringwald * With DIV being the lowest possible value, to maximize timing adjust resolution.
486*1b2596b5SMatthias Ringwald *
487*1b2596b5SMatthias Ringwald * \param[in] ul_freq Desired timer frequency
488*1b2596b5SMatthias Ringwald * \param[in] ul_mck Master clock frequency
489*1b2596b5SMatthias Ringwald * \param[out] p_uldiv Divisor value
490*1b2596b5SMatthias Ringwald * \param[out] p_ultcclks TCCLKS field value for divisor
491*1b2596b5SMatthias Ringwald * \param[in] ul_boardmck Board clock frequency
492*1b2596b5SMatthias Ringwald *
493*1b2596b5SMatthias Ringwald * \return The divisor found status.
494*1b2596b5SMatthias Ringwald * \retval 0 No suitable divisor was found
495*1b2596b5SMatthias Ringwald * \retval 1 A divisor was found
496*1b2596b5SMatthias Ringwald */
tc_find_mck_divisor(uint32_t ul_freq,uint32_t ul_mck,uint32_t * p_uldiv,uint32_t * p_ultcclks,uint32_t ul_boardmck)497*1b2596b5SMatthias Ringwald uint32_t tc_find_mck_divisor(
498*1b2596b5SMatthias Ringwald uint32_t ul_freq,
499*1b2596b5SMatthias Ringwald uint32_t ul_mck,
500*1b2596b5SMatthias Ringwald uint32_t *p_uldiv,
501*1b2596b5SMatthias Ringwald uint32_t *p_ultcclks,
502*1b2596b5SMatthias Ringwald uint32_t ul_boardmck)
503*1b2596b5SMatthias Ringwald {
504*1b2596b5SMatthias Ringwald const uint32_t divisors[5] = { 2, 8, 32, 128,
505*1b2596b5SMatthias Ringwald ul_boardmck / FREQ_SLOW_CLOCK_EXT };
506*1b2596b5SMatthias Ringwald uint32_t ul_index;
507*1b2596b5SMatthias Ringwald uint32_t ul_high, ul_low;
508*1b2596b5SMatthias Ringwald
509*1b2596b5SMatthias Ringwald /* Satisfy frequency bound. */
510*1b2596b5SMatthias Ringwald for (ul_index = 0;
511*1b2596b5SMatthias Ringwald ul_index < (sizeof(divisors) / sizeof(divisors[0]));
512*1b2596b5SMatthias Ringwald ul_index++) {
513*1b2596b5SMatthias Ringwald ul_high = ul_mck / divisors[ul_index];
514*1b2596b5SMatthias Ringwald ul_low = ul_high / TC_DIV_FACTOR;
515*1b2596b5SMatthias Ringwald if (ul_freq > ul_high) {
516*1b2596b5SMatthias Ringwald return 0;
517*1b2596b5SMatthias Ringwald } else if (ul_freq >= ul_low) {
518*1b2596b5SMatthias Ringwald break;
519*1b2596b5SMatthias Ringwald }
520*1b2596b5SMatthias Ringwald }
521*1b2596b5SMatthias Ringwald if (ul_index >= (sizeof(divisors) / sizeof(divisors[0]))) {
522*1b2596b5SMatthias Ringwald return 0;
523*1b2596b5SMatthias Ringwald }
524*1b2596b5SMatthias Ringwald
525*1b2596b5SMatthias Ringwald /* Store results. */
526*1b2596b5SMatthias Ringwald if (p_uldiv) {
527*1b2596b5SMatthias Ringwald *p_uldiv = divisors[ul_index];
528*1b2596b5SMatthias Ringwald }
529*1b2596b5SMatthias Ringwald
530*1b2596b5SMatthias Ringwald if (p_ultcclks) {
531*1b2596b5SMatthias Ringwald *p_ultcclks = ul_index;
532*1b2596b5SMatthias Ringwald }
533*1b2596b5SMatthias Ringwald
534*1b2596b5SMatthias Ringwald return 1;
535*1b2596b5SMatthias Ringwald }
536*1b2596b5SMatthias Ringwald
537*1b2596b5SMatthias Ringwald #endif /* (!SAM4L) */
538*1b2596b5SMatthias Ringwald
539*1b2596b5SMatthias Ringwald #if (SAM4L) || defined(__DOXYGEN__)
540*1b2596b5SMatthias Ringwald /**
541*1b2596b5SMatthias Ringwald * \brief Find the best PBA/MCK divisor.
542*1b2596b5SMatthias Ringwald *
543*1b2596b5SMatthias Ringwald * <b>For SAM4L devices:</b> Finds the best PBA divisor given the timer
544*1b2596b5SMatthias Ringwald * frequency and PBA clock. The result is guaranteed to satisfy the following equation:
545*1b2596b5SMatthias Ringwald * \code (ul_pbaclk / (2* DIV * 65536)) <= freq <= (ul_pbaclk / (2* DIV)) \endcode
546*1b2596b5SMatthias Ringwald * with DIV being the lowest possible value, to maximize timing adjust resolution.
547*1b2596b5SMatthias Ringwald *
548*1b2596b5SMatthias Ringwald * <b>For non SAM4L devices:</b> Finds the best MCK divisor given the timer frequency
549*1b2596b5SMatthias Ringwald * and MCK. The result is guaranteed to satisfy the following equation:
550*1b2596b5SMatthias Ringwald * \code (MCK / (DIV * 65536)) <= freq <= (MCK / DIV) \endcode
551*1b2596b5SMatthias Ringwald * with DIV being the lowest possible value, to maximize timing adjust resolution.
552*1b2596b5SMatthias Ringwald *
553*1b2596b5SMatthias Ringwald * \param[in] ul_freq Desired timer frequency
554*1b2596b5SMatthias Ringwald * \param[in] ul_mck PBA clock frequency
555*1b2596b5SMatthias Ringwald * \param[out] p_uldiv Divisor value
556*1b2596b5SMatthias Ringwald * \param[out] p_ultcclks TCCLKS field value for divisor
557*1b2596b5SMatthias Ringwald * \param[in] ul_boardmck Board clock frequency (set to 0 for SAM4L devices)
558*1b2596b5SMatthias Ringwald *
559*1b2596b5SMatthias Ringwald * \return The divisor found status.
560*1b2596b5SMatthias Ringwald * \retval 0 No suitable divisor was found
561*1b2596b5SMatthias Ringwald * \retval 1 A divisor was found
562*1b2596b5SMatthias Ringwald */
tc_find_mck_divisor(uint32_t ul_freq,uint32_t ul_mck,uint32_t * p_uldiv,uint32_t * p_ultcclks,uint32_t ul_boardmck)563*1b2596b5SMatthias Ringwald uint32_t tc_find_mck_divisor(
564*1b2596b5SMatthias Ringwald uint32_t ul_freq,
565*1b2596b5SMatthias Ringwald uint32_t ul_mck,
566*1b2596b5SMatthias Ringwald uint32_t *p_uldiv,
567*1b2596b5SMatthias Ringwald uint32_t *p_ultcclks,
568*1b2596b5SMatthias Ringwald uint32_t ul_boardmck)
569*1b2596b5SMatthias Ringwald {
570*1b2596b5SMatthias Ringwald const uint32_t divisors[5] = { 0, 2, 8, 32, 128};
571*1b2596b5SMatthias Ringwald uint32_t ul_index;
572*1b2596b5SMatthias Ringwald uint32_t ul_high, ul_low;
573*1b2596b5SMatthias Ringwald
574*1b2596b5SMatthias Ringwald UNUSED(ul_boardmck);
575*1b2596b5SMatthias Ringwald
576*1b2596b5SMatthias Ringwald /* Satisfy frequency bound. */
577*1b2596b5SMatthias Ringwald for (ul_index = 1;
578*1b2596b5SMatthias Ringwald ul_index < (sizeof(divisors) / sizeof(divisors[0]));
579*1b2596b5SMatthias Ringwald ul_index++) {
580*1b2596b5SMatthias Ringwald ul_high = ul_mck / divisors[ul_index];
581*1b2596b5SMatthias Ringwald ul_low = ul_high / TC_DIV_FACTOR;
582*1b2596b5SMatthias Ringwald if (ul_freq > ul_high) {
583*1b2596b5SMatthias Ringwald return 0;
584*1b2596b5SMatthias Ringwald } else if (ul_freq >= ul_low) {
585*1b2596b5SMatthias Ringwald break;
586*1b2596b5SMatthias Ringwald }
587*1b2596b5SMatthias Ringwald }
588*1b2596b5SMatthias Ringwald if (ul_index >= (sizeof(divisors) / sizeof(divisors[0]))) {
589*1b2596b5SMatthias Ringwald return 0;
590*1b2596b5SMatthias Ringwald }
591*1b2596b5SMatthias Ringwald
592*1b2596b5SMatthias Ringwald /* Store results. */
593*1b2596b5SMatthias Ringwald if (p_uldiv) {
594*1b2596b5SMatthias Ringwald *p_uldiv = divisors[ul_index];
595*1b2596b5SMatthias Ringwald }
596*1b2596b5SMatthias Ringwald
597*1b2596b5SMatthias Ringwald if (p_ultcclks) {
598*1b2596b5SMatthias Ringwald *p_ultcclks = ul_index;
599*1b2596b5SMatthias Ringwald }
600*1b2596b5SMatthias Ringwald
601*1b2596b5SMatthias Ringwald return 1;
602*1b2596b5SMatthias Ringwald }
603*1b2596b5SMatthias Ringwald
604*1b2596b5SMatthias Ringwald #endif /* (SAM4L) || defined(__DOXYGEN__) */
605*1b2596b5SMatthias Ringwald
606*1b2596b5SMatthias Ringwald #if (!SAM4L && !SAMG) || defined(__DOXYGEN__)
607*1b2596b5SMatthias Ringwald
608*1b2596b5SMatthias Ringwald /**
609*1b2596b5SMatthias Ringwald * \brief Enable TC QDEC interrupts.
610*1b2596b5SMatthias Ringwald *
611*1b2596b5SMatthias Ringwald * \note This function is not available on SAM4L or SAMG devices.
612*1b2596b5SMatthias Ringwald *
613*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
614*1b2596b5SMatthias Ringwald * \param[in] ul_sources A bitmask of QDEC interrupts to be enabled
615*1b2596b5SMatthias Ringwald *
616*1b2596b5SMatthias Ringwald * Where the input parameter <i>ul_sources</i> can be one or more of the following:
617*1b2596b5SMatthias Ringwald * <table>
618*1b2596b5SMatthias Ringwald * <tr>
619*1b2596b5SMatthias Ringwald * <th>Parameter Value</th>
620*1b2596b5SMatthias Ringwald * <th>Description</th>
621*1b2596b5SMatthias Ringwald * </tr>
622*1b2596b5SMatthias Ringwald * <tr><td>TC_QIER_IDX</td><td>Enable the rising edge detected on IDX input interrupt</td></tr>
623*1b2596b5SMatthias Ringwald * <tr><td>TC_QIER_DIRCHG</td><td>Enable the change in rotation direction detected interrupt</td></tr>
624*1b2596b5SMatthias Ringwald * <tr><td>TC_QIER_QERR</td><td>Enable the quadrature error detected on PHA/PHB interrupt</td></tr>
625*1b2596b5SMatthias Ringwald * </table>
626*1b2596b5SMatthias Ringwald */
tc_enable_qdec_interrupt(Tc * p_tc,uint32_t ul_sources)627*1b2596b5SMatthias Ringwald void tc_enable_qdec_interrupt(
628*1b2596b5SMatthias Ringwald Tc *p_tc,
629*1b2596b5SMatthias Ringwald uint32_t ul_sources)
630*1b2596b5SMatthias Ringwald {
631*1b2596b5SMatthias Ringwald /* Validate inputs. */
632*1b2596b5SMatthias Ringwald Assert(p_tc);
633*1b2596b5SMatthias Ringwald
634*1b2596b5SMatthias Ringwald p_tc->TC_QIER = ul_sources;
635*1b2596b5SMatthias Ringwald }
636*1b2596b5SMatthias Ringwald
637*1b2596b5SMatthias Ringwald /**
638*1b2596b5SMatthias Ringwald * \brief Disable TC QDEC interrupts.
639*1b2596b5SMatthias Ringwald *
640*1b2596b5SMatthias Ringwald * \note This function is not available on SAM4L or SAMG devices.
641*1b2596b5SMatthias Ringwald *
642*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
643*1b2596b5SMatthias Ringwald * \param[in] ul_sources A bitmask of QDEC interrupts to be disabled
644*1b2596b5SMatthias Ringwald *
645*1b2596b5SMatthias Ringwald * Where the input parameter <i>ul_sources</i> can be one or more of the following:
646*1b2596b5SMatthias Ringwald * <table>
647*1b2596b5SMatthias Ringwald * <tr>
648*1b2596b5SMatthias Ringwald * <th>Parameter Value</th>
649*1b2596b5SMatthias Ringwald * <th>Description</th>
650*1b2596b5SMatthias Ringwald * </tr>
651*1b2596b5SMatthias Ringwald * <tr><td>TC_QIDR_IDX</td><td>Disable the rising edge detected on IDX input interrupt</td></tr>
652*1b2596b5SMatthias Ringwald * <tr><td>TC_QIDR_DIRCHG</td><td>Disable the change in rotation direction detected interrupt</td></tr>
653*1b2596b5SMatthias Ringwald * <tr><td>TC_QIDR_QERR</td><td>Disable the quadrature error detected on PHA/PHB interrupt</td></tr>
654*1b2596b5SMatthias Ringwald * </table>
655*1b2596b5SMatthias Ringwald */
tc_disable_qdec_interrupt(Tc * p_tc,uint32_t ul_sources)656*1b2596b5SMatthias Ringwald void tc_disable_qdec_interrupt(
657*1b2596b5SMatthias Ringwald Tc *p_tc,
658*1b2596b5SMatthias Ringwald uint32_t ul_sources)
659*1b2596b5SMatthias Ringwald {
660*1b2596b5SMatthias Ringwald /* Validate inputs. */
661*1b2596b5SMatthias Ringwald Assert(p_tc);
662*1b2596b5SMatthias Ringwald
663*1b2596b5SMatthias Ringwald p_tc->TC_QIDR = ul_sources;
664*1b2596b5SMatthias Ringwald }
665*1b2596b5SMatthias Ringwald
666*1b2596b5SMatthias Ringwald /**
667*1b2596b5SMatthias Ringwald * \brief Read TC QDEC interrupt mask.
668*1b2596b5SMatthias Ringwald *
669*1b2596b5SMatthias Ringwald * \note This function is not available on SAM4L or SAMG devices.
670*1b2596b5SMatthias Ringwald *
671*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
672*1b2596b5SMatthias Ringwald *
673*1b2596b5SMatthias Ringwald * \return The QDEC interrupt mask value.
674*1b2596b5SMatthias Ringwald */
tc_get_qdec_interrupt_mask(Tc * p_tc)675*1b2596b5SMatthias Ringwald uint32_t tc_get_qdec_interrupt_mask(
676*1b2596b5SMatthias Ringwald Tc *p_tc)
677*1b2596b5SMatthias Ringwald {
678*1b2596b5SMatthias Ringwald /* Validate inputs. */
679*1b2596b5SMatthias Ringwald Assert(p_tc);
680*1b2596b5SMatthias Ringwald
681*1b2596b5SMatthias Ringwald return p_tc->TC_QIMR;
682*1b2596b5SMatthias Ringwald }
683*1b2596b5SMatthias Ringwald
684*1b2596b5SMatthias Ringwald /**
685*1b2596b5SMatthias Ringwald * \brief Get current TC QDEC interrupt status.
686*1b2596b5SMatthias Ringwald *
687*1b2596b5SMatthias Ringwald * \note This function is not available on SAM4L or SAMG devices.
688*1b2596b5SMatthias Ringwald *
689*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
690*1b2596b5SMatthias Ringwald *
691*1b2596b5SMatthias Ringwald * \return The TC QDEC interrupt status.
692*1b2596b5SMatthias Ringwald */
tc_get_qdec_interrupt_status(Tc * p_tc)693*1b2596b5SMatthias Ringwald uint32_t tc_get_qdec_interrupt_status(
694*1b2596b5SMatthias Ringwald Tc *p_tc)
695*1b2596b5SMatthias Ringwald {
696*1b2596b5SMatthias Ringwald /* Validate inputs. */
697*1b2596b5SMatthias Ringwald Assert(p_tc);
698*1b2596b5SMatthias Ringwald
699*1b2596b5SMatthias Ringwald return p_tc->TC_QISR;
700*1b2596b5SMatthias Ringwald }
701*1b2596b5SMatthias Ringwald
702*1b2596b5SMatthias Ringwald #endif /* (!SAM4L && !SAMG) || defined(__DOXYGEN__) */
703*1b2596b5SMatthias Ringwald
704*1b2596b5SMatthias Ringwald #if (!SAM3U) || defined(__DOXYGEN__)
705*1b2596b5SMatthias Ringwald
706*1b2596b5SMatthias Ringwald /**
707*1b2596b5SMatthias Ringwald * \brief Enable or disable write protection of TC registers.
708*1b2596b5SMatthias Ringwald *
709*1b2596b5SMatthias Ringwald * \note This function is not available on SAM3U devices.
710*1b2596b5SMatthias Ringwald *
711*1b2596b5SMatthias Ringwald * \param[out] p_tc Module hardware register base address pointer
712*1b2596b5SMatthias Ringwald * \param[in] ul_enable 1 to enable, 0 to disable
713*1b2596b5SMatthias Ringwald */
tc_set_writeprotect(Tc * p_tc,uint32_t ul_enable)714*1b2596b5SMatthias Ringwald void tc_set_writeprotect(
715*1b2596b5SMatthias Ringwald Tc *p_tc,
716*1b2596b5SMatthias Ringwald uint32_t ul_enable)
717*1b2596b5SMatthias Ringwald {
718*1b2596b5SMatthias Ringwald /* Validate inputs. */
719*1b2596b5SMatthias Ringwald Assert(p_tc);
720*1b2596b5SMatthias Ringwald
721*1b2596b5SMatthias Ringwald if (ul_enable) {
722*1b2596b5SMatthias Ringwald p_tc->TC_WPMR = TC_WPMR_WPKEY_PASSWD | TC_WPMR_WPEN;
723*1b2596b5SMatthias Ringwald } else {
724*1b2596b5SMatthias Ringwald p_tc->TC_WPMR = TC_WPMR_WPKEY_PASSWD;
725*1b2596b5SMatthias Ringwald }
726*1b2596b5SMatthias Ringwald }
727*1b2596b5SMatthias Ringwald
728*1b2596b5SMatthias Ringwald #endif /* (!SAM3U) || defined(__DOXYGEN__) */
729*1b2596b5SMatthias Ringwald
730*1b2596b5SMatthias Ringwald #if SAM4L || defined(__DOXYGEN__)
731*1b2596b5SMatthias Ringwald
732*1b2596b5SMatthias Ringwald /**
733*1b2596b5SMatthias Ringwald * \brief Indicate TC features.
734*1b2596b5SMatthias Ringwald *
735*1b2596b5SMatthias Ringwald * \note This function is only available on SAM4L devices.
736*1b2596b5SMatthias Ringwald *
737*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
738*1b2596b5SMatthias Ringwald *
739*1b2596b5SMatthias Ringwald * \return The TC FEATURES register contents.
740*1b2596b5SMatthias Ringwald */
tc_get_feature(Tc * p_tc)741*1b2596b5SMatthias Ringwald uint32_t tc_get_feature(
742*1b2596b5SMatthias Ringwald Tc *p_tc)
743*1b2596b5SMatthias Ringwald {
744*1b2596b5SMatthias Ringwald /* Validate inputs. */
745*1b2596b5SMatthias Ringwald Assert(p_tc);
746*1b2596b5SMatthias Ringwald
747*1b2596b5SMatthias Ringwald return p_tc->TC_FEATURES;
748*1b2596b5SMatthias Ringwald }
749*1b2596b5SMatthias Ringwald
750*1b2596b5SMatthias Ringwald /**
751*1b2596b5SMatthias Ringwald * \brief Indicate TC version.
752*1b2596b5SMatthias Ringwald *
753*1b2596b5SMatthias Ringwald * \note This function is only available on SAM4L devices.
754*1b2596b5SMatthias Ringwald *
755*1b2596b5SMatthias Ringwald * \param[in] p_tc Module hardware register base address pointer
756*1b2596b5SMatthias Ringwald *
757*1b2596b5SMatthias Ringwald * \return The TC VERSION register contents.
758*1b2596b5SMatthias Ringwald */
tc_get_version(Tc * p_tc)759*1b2596b5SMatthias Ringwald uint32_t tc_get_version(
760*1b2596b5SMatthias Ringwald Tc *p_tc)
761*1b2596b5SMatthias Ringwald {
762*1b2596b5SMatthias Ringwald /* Validate inputs. */
763*1b2596b5SMatthias Ringwald Assert(p_tc);
764*1b2596b5SMatthias Ringwald
765*1b2596b5SMatthias Ringwald return p_tc->TC_VERSION;
766*1b2596b5SMatthias Ringwald }
767*1b2596b5SMatthias Ringwald
768*1b2596b5SMatthias Ringwald #endif /* SAM4L || defined(__DOXYGEN__) */
769*1b2596b5SMatthias Ringwald
770*1b2596b5SMatthias Ringwald /// @cond
771*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
772*1b2596b5SMatthias Ringwald #ifdef __cplusplus
773*1b2596b5SMatthias Ringwald }
774*1b2596b5SMatthias Ringwald #endif
775*1b2596b5SMatthias Ringwald /**INDENT-ON**/
776*1b2596b5SMatthias Ringwald /// @endcond
777