iLLD_TC27xD  1.0
IfxGpt12_IncrEnc.c
Go to the documentation of this file.
1 /**
2  * \file IfxGpt12_IncrEnc.c
3  * \brief GPT12 INCRENC 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 "IfxGpt12_IncrEnc.h"
30 
31 /******************************************************************************/
32 /*-----------------------Private Function Prototypes--------------------------*/
33 /******************************************************************************/
34 
35 /** \brief Update internal data when incremental mode is using T2.\n
36  * This function shall be periodically called
37  * \param driver driver handle
38  * \return None
39  */
40 static void IfxGpt12_IncrEnc_updateFromT2(IfxGpt12_IncrEnc *driver);
41 
42 /** \brief Update internal data when incremental mode is using T3.\n
43  * This function shall be periodically called
44  * \param driver driver handle
45  * \return None
46  */
47 static void IfxGpt12_IncrEnc_updateFromT3(IfxGpt12_IncrEnc *driver);
48 
49 /** \brief Updates the speed
50  * \param driver driver handle
51  * \param newPosition new position
52  * \return None
53  */
54 static void IfxGpt12_IncrEnc_updateSpeedFromT2(IfxGpt12_IncrEnc *driver, sint32 newPosition);
55 
56 /** \brief Updates the speed
57  * \param driver driver handle
58  * \param newPosition new position
59  * \return None
60  */
61 static void IfxGpt12_IncrEnc_updateSpeedFromT3(IfxGpt12_IncrEnc *driver, sint32 newPosition);
62 
63 /******************************************************************************/
64 /*-------------------------Function Implementations---------------------------*/
65 /******************************************************************************/
66 
68 {
69  return ((float32)driver->turn + (float32)driver->rawPosition / (float32)driver->resolution) * 2.0 * IFX_PI;
70 }
71 
72 
74 {
75  return driver->direction;
76 }
77 
78 
80 {
81  return driver->status;
82 }
83 
84 
86 {
87  return driver->offset;
88 }
89 
90 
92 {
93  return 1; /* Period per rotation is 1*/
94 }
95 
96 
98 {
99  return (float32)driver->rawPosition * driver->positionConst;
100 }
101 
102 
104 {
105  return driver->rawPosition;
106 }
107 
108 
110 {
111  return driver->updatePeriod;
112 }
113 
114 
116 {
117  return driver->resolution;
118 }
119 
120 
122 {
124 }
125 
126 
128 {
129  return driver->speed;
130 }
131 
132 
134 {
135  return driver->turn;
136 }
137 
138 
140 {
141  boolean status = TRUE;
142  Ifx_GPT12 *gpt12 = config->module;
143 
144  driver->module = gpt12;
145 
146  driver->offset = config->base.offset;
147  driver->resolution = config->base.resolution * config->base.resolutionFactor;
148  driver->positionConst = 1.0 / (float32)driver->resolution * 2.0 * IFX_PI;
149  driver->speedModeThreshold = config->base.speedModeThreshold;
151 
152  driver->status.status = 0;
153  driver->status.B.notSynchronised = 1;
154  driver->minSpeed = config->base.minSpeed;
155  driver->maxSpeed = config->base.maxSpeed;
156 
157  driver->rawPosition = 0;
158  driver->speed = 0;
160  driver->turn = 0;
161 
162  if (config->pinA->timer == 3)
163  {
164  /* T3 Configuration */
166 
167  switch (config->base.resolutionFactor)
168  {
171  break;
174  break;
175  default:
176  status = FALSE;
177  break;
178  }
179 
184 
185  if (config->pinZ != NULL_PTR)
186  { /* Only configure T4 if zero signal is available. Zero has to be on T4IN */
187  /* T4 Configuration */
192  IfxGpt12_T4_setInterruptEnable(gpt12, config->zeroIsrPriority != 0);
195 
196  if (config->zeroIsrPriority)
197  {
198  /* setup interrupt */
199  volatile Ifx_SRC_SRCR *src = IfxGpt12_T4_getSrc(gpt12);
200  IfxSrc_init(src, config->zeroIsrProvider, config->zeroIsrPriority);
201  IfxSrc_enable(src);
202  }
203  }
204 
205  /* T5 Configuration */
216 
217  driver->update = (IfxGpt12_IncrEnc_Update) & IfxGpt12_IncrEnc_updateFromT3;
218  }
219  else if (config->pinA->timer == 2)
220  {
221  /* T2 Configuration */
223 
224  switch (config->base.resolutionFactor)
225  {
228  break;
231  break;
232  default:
233  status = FALSE;
234  break;
235  }
236 
240 
241  if (config->pinZ != NULL_PTR)
242  { /* Only configure T4 if zero signal is available. Zero has to be on T4EUD */
243  /* T4 Configuration */
251  }
252 
253  driver->update = (IfxGpt12_IncrEnc_Update) & IfxGpt12_IncrEnc_updateFromT2;
254  }
255 
256  IfxGpt12_initTxInPin(config->pinA, config->pinMode);
257  IfxGpt12_initTxEudInPin(config->pinB, config->pinMode);
258 
259  if (config->pinZ != NULL_PTR)
260  {
261  IfxGpt12_initTxInPin(config->pinZ, config->pinMode);
262  }
263 
264  driver->speedConstTimeDiff =
265  (2.0 * IFX_PI) / (config->base.resolution * 2) * IfxGpt12_T5_getFrequency(gpt12);
266 
267  driver->speedFilterEnabled = config->base.speedFilterEnabled;
268 
269  if (config->base.speedFilterEnabled)
270  {
271  Ifx_LowPassPt1_Config lpfConfig;
272  lpfConfig.gain = 1.0;
273  lpfConfig.cutOffFrequency = config->base.speedFilerCutOffFrequency;
274  lpfConfig.samplingTime = config->base.updatePeriod;
275  Ifx_LowPassPt1_init(&driver->speedLpf, &lpfConfig);
276  }
277 
278  return status;
279 }
280 
281 
283 {
284  IfxStdIf_Pos_initConfig(&config->base);
286  config->base.minSpeed = 1.0 / 60.0 * (2 * IFX_PI); // 1 rpm
287  config->base.maxSpeed = 20000.0 / 60.0 * (2 * IFX_PI); // 20000 rpm
288  config->base.speedFilterEnabled = TRUE;
289  config->base.speedFilerCutOffFrequency = config->base.maxSpeed / 2 * IFX_PI * 10;
290 
291  config->pinA = NULL_PTR;
292  config->pinB = NULL_PTR;
293  config->pinZ = NULL_PTR;
295  config->module = gpt12;
296  config->zeroIsrPriority = 0;
298 }
299 
300 
302 {
303  if (driver->status.B.notSynchronised)
304  {
305  driver->status.B.notSynchronised = 0;
306  }
307 
308  if (driver->direction == IfxStdIf_Pos_Dir_forward)
309  {
310  driver->turn++;
311  }
312  else
313  {
314  driver->turn--;
315  }
316 }
317 
318 
320 {
321  driver->rawPosition = 0;
322  driver->turn = 0;
323  driver->speed = 0;
324  driver->status.status = 0;
325  driver->status.B.notSynchronised = 1;
326 }
327 
328 
330 {
331  IfxStdIf_Pos_Status status;
332  status.status = 0;
333  status.B.notSynchronised = driver->status.B.notSynchronised;
334  driver->status.status = status.status;
335 }
336 
337 
339 {
340  driver->offset = offset;
341 }
342 
343 
345 {
346  driver->updatePeriod = updatePeriod;
347  driver->speedConstPulseCount = (2.0 * IFX_PI) / driver->resolution / updatePeriod;
348  driver->speedModeThresholdTick = driver->speedModeThreshold * driver->resolution * updatePeriod / (2.0 * IFX_PI);
349 }
350 
351 
353 {
354  /* Ensure the stdif is reset to zeros */
355  memset(stdif, 0, sizeof(IfxStdIf_Pos));
356 
357  /* Set the driver */
358  stdif->driver = driver;
359 
360  /* *INDENT-OFF* Note: this file was indented manually by the author. */
361  /* Set the API link */
380  /* *INDENT-ON* */
381 
382  return TRUE;
383 }
384 
385 
387 {
388  driver->update(driver);
389 }
390 
391 
392 static void IfxGpt12_IncrEnc_updateFromT2(IfxGpt12_IncrEnc *driver)
393 {
394  Ifx_GPT12 *gpt12 = driver->module;
395  sint32 newPosition;
396  driver->direction = gpt12->T2CON.B.T2RDIR ? IfxStdIf_Pos_Dir_backward : IfxStdIf_Pos_Dir_forward;
397 
398  newPosition = gpt12->T2.U;
399  newPosition = (newPosition + driver->offset) & (driver->resolution - 1);
400  IfxGpt12_IncrEnc_updateSpeedFromT2(driver, newPosition);
401  driver->rawPosition = newPosition;
402 }
403 
404 
405 static void IfxGpt12_IncrEnc_updateFromT3(IfxGpt12_IncrEnc *driver)
406 {
407  Ifx_GPT12 *gpt12 = driver->module;
408  sint32 newPosition;
409  driver->direction = gpt12->T3CON.B.T3RDIR ? IfxStdIf_Pos_Dir_backward : IfxStdIf_Pos_Dir_forward;
410 
411  newPosition = gpt12->T3.U;
412 
413  newPosition = (newPosition + driver->offset) & (driver->resolution - 1);
414  IfxGpt12_IncrEnc_updateSpeedFromT3(driver, newPosition);
415  driver->rawPosition = newPosition;
416 }
417 
418 
419 static void IfxGpt12_IncrEnc_updateSpeedFromT2(IfxGpt12_IncrEnc *driver, sint32 newPosition)
420 {
421  float32 speed;
422  uint32 diff;
423 
424  if (driver->direction == IfxStdIf_Pos_Dir_forward)
425  {
426  diff = newPosition - driver->rawPosition;
427  }
428  else
429  {
430  diff = driver->rawPosition - newPosition;
431  }
432 
433  diff &= driver->resolution - 1;
434 
435  speed = diff * driver->speedConstPulseCount;
436 
437  speed = driver->direction == IfxStdIf_Pos_Dir_forward ? speed : -speed;
438 
439  if (driver->speedFilterEnabled)
440  {
441  driver->speed = Ifx_LowPassPt1_do(&driver->speedLpf, speed);
442  }
443  else
444  {
445  driver->speed = speed;
446  }
447 }
448 
449 
450 static void IfxGpt12_IncrEnc_updateSpeedFromT3(IfxGpt12_IncrEnc *driver, sint32 newPosition)
451 {
452  float32 speed;
453  uint32 diff;
454 
455  if (driver->direction == IfxStdIf_Pos_Dir_forward)
456  {
457  diff = newPosition - driver->rawPosition;
458  }
459  else
460  {
461  diff = driver->rawPosition - newPosition;
462  }
463 
464  diff &= driver->resolution - 1;
465 
466  if (diff > driver->speedModeThresholdTick)
467  { /* Use pulse count mode ( Fast speed ) */
468  speed = diff * driver->speedConstPulseCount;
469  }
470  else
471  { /* Use time diff mode (slow speed), only if T3 is used as core */
472  Ifx_GPT12 *gpt12 = driver->module;
473  volatile Ifx_SRC_SRCR *srcT5 = IfxGpt12_T5_getSrc(gpt12);
474 
475  if (srcT5->B.SRR != 1)
476  { // NO overflow of T5
477  volatile Ifx_SRC_SRCR *srcCap = IfxGpt12_getCaptureSrc(gpt12);
478 
479  // Check if a new value is captured
480  if (srcCap->B.SRR != 0)
481  {
482  // Delete Capture Request Bit
483  srcCap->B.CLRR = 1;
484  speed = driver->speedConstTimeDiff / gpt12->CAPREL.B.CAPREL;
485  }
486  else
487  { /* FIXME T5 should be set so that overflow is detected for min speed configuration so that this case is never entered */
488  speed = driver->speed;
489  }
490  }
491  else
492  { // T5 overflow detected
493  // Delete Overflow Request bit
494  srcT5->B.CLRR = 1;
495  speed = 0.0;
496  }
497  }
498 
499  speed = driver->direction == IfxStdIf_Pos_Dir_forward ? speed : -speed;
500 
501  if (driver->speedFilterEnabled)
502  {
503  driver->speed = Ifx_LowPassPt1_do(&driver->speedLpf, speed);
504  }
505  else
506  {
507  driver->speed = speed;
508  }
509 }