iLLD_TC27xD  1.0
IfxGtm_Atom_Timer.c
Go to the documentation of this file.
1 /**
2  * \file IfxGtm_Atom_Timer.c
3  * \brief GTM TIMER details
4  *
5  * \version iLLD_1_0_0_11_0
6  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
7  *
8  *
9  * IMPORTANT NOTICE
10  *
11  *
12  * Infineon Technologies AG (Infineon) is supplying this file for use
13  * exclusively with Infineon's microcontroller products. This file can be freely
14  * distributed within development tools that are supporting such microcontroller
15  * products.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
21  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  */
24 
25 /******************************************************************************/
26 /*----------------------------------Includes----------------------------------*/
27 /******************************************************************************/
28 
29 #include "IfxGtm_Atom_Timer.h"
30 #include "_Utilities/Ifx_Assert.h"
31 #include "IfxGtm_bf.h"
32 #include "stddef.h"
33 
34 /******************************************************************************/
35 /*-------------------------Function Implementations---------------------------*/
36 /******************************************************************************/
37 
39 {
40  boolean event;
41  event = IfxGtm_Atom_Ch_isZeroNotification(driver->atom, driver->timerChannel);
42 
43  if (event)
44  {
46  }
47  else
48  {}
49 
50  return event;
51 }
52 
53 
55 {
56  boolean event;
57  event = IfxGtm_Atom_Ch_isOneNotification(driver->atom, driver->triggerChannel);
58 
59  if (event)
60  {
62  }
63  else
64  {}
65 
66  return event;
67 }
68 
69 
71 {
72  driver->channelsMask |= mask;
73 }
74 
75 
77 {
79 }
80 
81 
83 {
85 }
86 
87 
89 {
90  return 1.0 / IfxStdIf_Timer_tickToS(driver->base.clockFreq, driver->base.period);
91 }
92 
93 
95 {
96  return driver->base.clockFreq;
97 }
98 
99 
101 {
102  return driver->offset;
103 }
104 
105 
107 {
108  return driver->base.period;
109 }
110 
111 
113 {
114  return IfxGtm_Atom_Ch_getTimerPointer(driver->atom, driver->timerChannel);
115 }
116 
117 
119 {
120  return 1.0 / driver->base.clockFreq;
121 }
122 
123 
125 {
126  return IfxGtm_Atom_Ch_getCompareOne(driver->atom, driver->triggerChannel) - 1;
127 }
128 
129 
131 {
133 }
134 
135 
137 {
138  /* FIXME Add the case when no trigger is defiend config->triggerOut = NULL
139  * FIXME Check if pwm is configured (IfxGtm_Atom_Ch_configurePwmMode) if if (triggerChannel == driver->timerChannel)
140  * Check similar issue on TOM */
141  boolean result = TRUE;
142  IfxGtm_Atom_Timer_Base *base = &driver->base;
143 
144  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->base.countDir == IfxStdIf_Timer_CountDir_up); /* only this mode is supported */
145 
146  driver->gtm = config->gtm;
147  driver->atomIndex = config->atom;
148  driver->atom = &config->gtm->ATOM[config->atom];
149  driver->timerChannel = config->timerChannel;
150 
151  base->triggerEnabled = config->base.trigger.enabled;
152 
153  if (base->triggerEnabled)
154  {
155  driver->triggerChannel = config->triggerOut->channel;
156  }
157  else
158  {
159  driver->triggerChannel = driver->timerChannel; // Set to timer channel to disable its use
160  }
161 
162  driver->agc = (Ifx_GTM_ATOM_AGC *)&driver->atom->AGC.GLB_CTRL;
163 
164  /* Initialize the timer part */
165  IfxGtm_Atom_Ch_configurePwmMode(driver->atom, driver->timerChannel, config->clock,
168 
170 
171  if ((config->base.minResolution > 0) && ((1.0 / base->clockFreq) > config->base.minResolution))
172  {
173  result = FALSE;
175  }
176 
177  result &= IfxGtm_Atom_Timer_setFrequency(driver, config->base.frequency);
178  driver->offset = IfxStdIf_Timer_sToTick(driver->base.clockFreq, 1.0 / config->base.frequency * config->base.startOffset);
179 
180  /* check that driver->offset is not more than 24 bits */
181  if (driver->offset <= 0xFFFFFF)
182  {
183  IfxGtm_Atom_Ch_setCounterValue(driver->atom, driver->timerChannel, driver->offset);
184  }
185  else
186  {
187  result = FALSE;
189  }
190 
191  /* Initialize the trigger part */
192  driver->channelsMask = 1 << driver->timerChannel;
193 
194  if (base->triggerEnabled)
195  {
196  IfxGtm_Atom_Ch triggerChannel = driver->triggerChannel;
197  uint16 triggerChannelMask = 1 << triggerChannel;
198 
200 
201  IfxGtm_Atom_Ch_setCounterValue(driver->atom, triggerChannel, driver->offset);
202 
203  if (triggerChannel != driver->timerChannel)
204  {
205  IfxGtm_Atom_Ch_configurePwmMode(driver->atom, triggerChannel, config->clock,
208  IfxGtm_Atom_Agc_enableChannels(driver->agc, triggerChannelMask, 0, FALSE);
209  driver->channelsMask |= triggerChannelMask;
210  }
211 
212  /* Signal must go out of the GTM even if the port outpout is not enabled */
213  IfxGtm_Atom_Agc_enableChannelsOutput(driver->agc, triggerChannelMask, 0, FALSE);
214 
215  if (config->base.trigger.outputEnabled)
216  {
217  /* Initialize the port */
219  }
220 
221  result &= IfxGtm_Atom_Timer_setTrigger(driver, config->base.trigger.triggerPoint);
222  }
223 
224  /* Interrupt configuration */
225  {
226  volatile Ifx_SRC_SRCR *src;
227  boolean timerHasIrq = config->base.isrPriority > 0;
228  boolean triggerHasIrq = (config->base.trigger.isrPriority > 0) && base->triggerEnabled;
229 
230  if (driver->triggerChannel == driver->timerChannel)
231  {
232  IfxGtm_Atom_Ch_setNotification(driver->atom, driver->timerChannel, timerHasIrq ? config->irqModeTimer : config->irqModeTrigger, timerHasIrq, triggerHasIrq);
233  src = IfxGtm_Atom_Ch_getSrcPointer(driver->gtm, config->atom, driver->timerChannel);
234  IfxSrc_init(src, timerHasIrq ? config->base.isrProvider : config->base.trigger.isrProvider, timerHasIrq ? config->base.isrPriority : config->base.trigger.isrPriority);
235  /* FIXME ADD warning on interrupt setting in case timer and trigger uses the same channels or different channels, and in case only timer or trigger or both generates interrupts */
236  IfxSrc_enable(src);
237  }
238  else
239  {
241 
242  if (timerHasIrq)
243  {
244  IfxGtm_Atom_Ch_setNotification(driver->atom, driver->timerChannel, irqMode, TRUE, FALSE);
245  src = IfxGtm_Atom_Ch_getSrcPointer(driver->gtm, config->atom, driver->timerChannel);
246  IfxSrc_init(src, config->base.isrProvider, config->base.isrPriority);
247  IfxSrc_enable(src);
248  }
249 
250  if (triggerHasIrq)
251  {
252  IfxGtm_Atom_Ch_setNotification(driver->atom, driver->triggerChannel, irqMode, FALSE, TRUE);
253  src = IfxGtm_Atom_Ch_getSrcPointer(driver->gtm, config->atom, driver->triggerChannel);
254  IfxSrc_init(src, config->base.trigger.isrProvider, config->base.trigger.isrPriority);
255  IfxSrc_enable(src);
256  }
257  }
258  }
259 
260  /* Transfer the shadow registers */
261  IfxGtm_Atom_Agc_setChannelsForceUpdate(driver->agc, driver->channelsMask, 0, 0, 0);
262  IfxGtm_Atom_Agc_trigger(driver->agc);
263  IfxGtm_Atom_Agc_setChannelsForceUpdate(driver->agc, 0, driver->channelsMask, 0, 0);
264 
265  return result;
266 }
267 
268 
270 {
272  config->gtm = gtm;
273  config->atom = IfxGtm_Atom_0;
274  config->timerChannel = IfxGtm_Atom_Ch_0;
275  config->triggerOut = NULL_PTR;
276  config->clock = IfxGtm_Cmu_Clk_0;
280 }
281 
282 
284 {
285  IfxGtm_Atom_Agc_enableChannels(driver->agc, driver->channelsMask, 0, TRUE);
286 }
287 
288 
290 {
291  Ifx_TimerValue period = IfxStdIf_Timer_sToTick(driver->base.clockFreq, 1.0 / frequency);
292 
293  return IfxGtm_Atom_Timer_setPeriod(driver, period);
294 }
295 
296 
298 {
299  boolean result = TRUE;
300  driver->base.period = period;
301 
302  /* check that period is not more that 24 bits */
303  if (period <= 0xFFFFFF)
304  {
305  IfxGtm_Atom_Ch_setCompareZeroShadow(driver->atom, driver->timerChannel, period);
306 
307  if (driver->triggerChannel != driver->timerChannel)
308  {
309  IfxGtm_Atom_Ch_setCompareZeroShadow(driver->atom, driver->triggerChannel, period);
310  }
311  }
312  else
313  {
314  result = FALSE;
316  }
317 
318  return result;
319 }
320 
321 
323 {
324  IfxGtm_Atom_Ch_setOneShotMode(driver->atom, driver->timerChannel, enabled);
325 }
326 
327 
329 {
330  boolean result = TRUE;
331 
332  /* check that trigger point is not more that 24 bits */
333  if (triggerPoint <= (0xFFFFFF - 1))
334  {
335  IfxGtm_Atom_Ch_setCompareOneShadow(driver->atom, driver->triggerChannel, triggerPoint + 1);
336  }
337  else
338  {
339  result = FALSE;
341  }
342 
343  return result;
344 }
345 
346 
348 {
349  /* *INDENT-OFF* Note: this file was indented manually by the author. */
350  /* Set the API link */
351  stdif->driver = driver;
368  /* *INDENT-ON* */
369 
370  return TRUE;
371 }
372 
373 
375 {
376  IfxGtm_Atom_Agc_enableChannels(driver->agc, 0, driver->channelsMask, TRUE);
377 }
378 
379 
381 {
382  driver->base.clockFreq = IfxGtm_Atom_Ch_getClockFrequency(driver->gtm, driver->atom, driver->timerChannel);
383 }