iLLD_TC27xD  1.0
IfxPsi5_Psi5.c
Go to the documentation of this file.
1 /**
2  * \file IfxPsi5_Psi5.c
3  * \brief PSI5 PSI5 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 "IfxPsi5_Psi5.h"
30 
31 /** \addtogroup IfxLld_Psi5_Psi5_Module
32  * \{ */
33 
34 /******************************************************************************/
35 /*-----------------------Private Function Prototypes--------------------------*/
36 /******************************************************************************/
37 
38 /** \brief Enable PSI5 kernel
39  * \param psi5 pointer to the base of PSI5 registers
40  * \return None
41  */
42 static void IfxPsi5_Psi5_enableModule(Ifx_PSI5 *psi5);
43 
44 /** \brief Reset PSI5 kernel
45  * \param psi5 pointer to the base of PSI5 registers
46  * \return None
47  */
48 static void IfxPsi5_Psi5_resetModule(Ifx_PSI5 *psi5);
49 
50 /** \} */
51 
52 /** \addtogroup IfxLld_Psi5_Psi5_Clock
53  * \{ */
54 
55 /******************************************************************************/
56 /*-----------------------Private Function Prototypes--------------------------*/
57 /******************************************************************************/
58 
59 /** \brief Returns the configured fracDiv psi5 clock frequency in Hz.
60  * \param psi5 Pointer to the base of PSI5 registers
61  * \return Returns the configured fracDiv psi5 clock frequency in Hz.
62  */
63 static uint32 IfxPsi5_Psi5_getFracDivClock(Ifx_PSI5 *psi5);
64 
65 /** \brief Configure the fracDiv clock.
66  * \param psi5 Pointer to the base of PSI5 registers
67  * \param clock Specifies the required clock frequency in Hz.
68  * \return Returns the configured clock frequency in Hz.
69  */
70 static uint32 IfxPsi5_Psi5_initializeClock(Ifx_PSI5 *psi5, const IfxPsi5_Psi5_Clock *clock);
71 
72 /** \} */
73 
74 /******************************************************************************/
75 /*-------------------------Function Implementations---------------------------*/
76 /******************************************************************************/
77 
79 {
80  Ifx_PSI5 *psi5SFR = psi5->psi5;
81 
82  IfxPsi5_Psi5_resetModule(psi5SFR);
83 }
84 
85 
86 static void IfxPsi5_Psi5_enableModule(Ifx_PSI5 *psi5)
87 {
88  psi5->CLC.U = 0x00000000;
89 }
90 
91 
92 static uint32 IfxPsi5_Psi5_getFracDivClock(Ifx_PSI5 *psi5)
93 {
94  uint32 result;
96 
97  switch (psi5->FDR.B.DM)
98  {
100  result = fPsi5;
101  break;
103  result = fPsi5 / (IFXPSI5_STEP_RANGE - psi5->FDR.B.STEP);
104  break;
106  result = (fPsi5 * IFXPSI5_STEP_RANGE) / psi5->FDR.B.STEP;
107  break;
109  result = 0;
110  break;
111  default:
112  result = 0;
113  }
114 
115  return result;
116 }
117 
118 
120 {
121  uint32 wdtIdx;
122  boolean status = TRUE;
123 
125 
127 
128  Ifx_PSI5 *psi5 = config->module->psi5;
129  Ifx_PSI5_CH *psi5Ch = &psi5->CH[config->channelId];
130  channel->channel = psi5Ch;
131  channel->module = (IfxPsi5_Psi5 *)config->module;
132  channel->channelId = config->channelId;
133 
134  Ifx_PSI5_CH_PGC tempPGC;
135  tempPGC.B.PLEN = config->pulseGeneration.pulseLength;
136  tempPGC.B.DEL = config->pulseGeneration.delayLength;
137  tempPGC.B.TBS = config->pulseGeneration.timeBaseSelect;
138  tempPGC.B.ETB = config->pulseGeneration.externalTimeBaseSelect;
139  tempPGC.B.ETS = config->pulseGeneration.externalTriggerSelect;
140  tempPGC.B.BOT = config->pulseGeneration.blankoutTime;
141 
143  {
145  tempPGC.B.PTE = TRUE;
146  tempPGC.B.ETE = FALSE;
147  tempPGC.B.BYP = FALSE;
148  break;
149 
151  tempPGC.B.PTE = FALSE;
152  tempPGC.B.ETE = TRUE;
153  tempPGC.B.BYP = FALSE;
154  break;
155 
157  tempPGC.B.PTE = FALSE;
158  tempPGC.B.ETE = FALSE;
159  tempPGC.B.BYP = TRUE;
160  break;
161  }
162 
163  psi5Ch->PGC.U = tempPGC.U;
164 
165  Ifx_PSI5_CH_CTV tempCTV;
166  tempCTV.B.CTV = config->channelTrigger.channelTriggerValue;
167  tempCTV.B.CTC = config->channelTrigger.channelTriggerCounter;
168  psi5Ch->CTV.U = tempCTV.U;
169 
170  for (wdtIdx = 0; wdtIdx < IFXPSI5_NUM_WDTS; wdtIdx++)
171  {
172  psi5Ch->WDT[wdtIdx].U = config->watchdogTimerLimit[wdtIdx];
173  }
174 
175  Ifx_PSI5_CH_RCRA tempRCRA;
176  tempRCRA.B.PDL0 = config->receiveControl.payloadLength[0];
177  tempRCRA.B.PDL1 = config->receiveControl.payloadLength[1];
178  tempRCRA.B.PDL2 = config->receiveControl.payloadLength[2];
179  tempRCRA.B.PDL3 = config->receiveControl.payloadLength[3];
180  tempRCRA.B.PDL4 = config->receiveControl.payloadLength[4];
181  tempRCRA.B.PDL5 = config->receiveControl.payloadLength[5];
182  tempRCRA.B.ASYN = config->receiveControl.asynchronousModeSelected;
183  tempRCRA.B.AVBS = config->receiveControl.verboseForAsynchronousMode;
184  psi5Ch->RCRA.U = tempRCRA.U;
185 
186  Ifx_PSI5_CH_RCRB tempRCRB;
187  tempRCRB.B.MSG0 = config->receiveControl.messagingBitsPresence[0];
188  tempRCRB.B.MSG1 = config->receiveControl.messagingBitsPresence[1];
189  tempRCRB.B.MSG2 = config->receiveControl.messagingBitsPresence[2];
190  tempRCRB.B.MSG3 = config->receiveControl.messagingBitsPresence[3];
191  tempRCRB.B.MSG4 = config->receiveControl.messagingBitsPresence[4];
192  tempRCRB.B.MSG5 = config->receiveControl.messagingBitsPresence[5];
193  tempRCRB.B.CRC0 = config->receiveControl.crcOrParity[0];
194  tempRCRB.B.CRC1 = config->receiveControl.crcOrParity[1];
195  tempRCRB.B.CRC2 = config->receiveControl.crcOrParity[2];
196  tempRCRB.B.CRC3 = config->receiveControl.crcOrParity[3];
197  tempRCRB.B.CRC4 = config->receiveControl.crcOrParity[4];
198  tempRCRB.B.CRC5 = config->receiveControl.crcOrParity[5];
199  tempRCRB.B.FEC0 = config->receiveControl.frameExpectation[0];
200  tempRCRB.B.FEC1 = config->receiveControl.frameExpectation[1];
201  tempRCRB.B.FEC2 = config->receiveControl.frameExpectation[2];
202  tempRCRB.B.FEC3 = config->receiveControl.frameExpectation[3];
203  tempRCRB.B.FEC4 = config->receiveControl.frameExpectation[4];
204  tempRCRB.B.FEC5 = config->receiveControl.frameExpectation[5];
205  tempRCRB.B.VBS0 = config->receiveControl.verbose[0];
206  tempRCRB.B.VBS1 = config->receiveControl.verbose[1];
207  tempRCRB.B.VBS2 = config->receiveControl.verbose[2];
208  tempRCRB.B.VBS3 = config->receiveControl.verbose[3];
209  tempRCRB.B.VBS4 = config->receiveControl.verbose[4];
210  tempRCRB.B.VBS5 = config->receiveControl.verbose[5];
211  psi5Ch->RCRB.U = tempRCRB.U;
212 
213  Ifx_PSI5_CH_RCRC tempRCRC;
214  tempRCRC.B.BRS = config->receiveControl.baudrateSelect;
215  tempRCRC.B.TSP = config->receiveControl.pulseTimestampSelect;
216  tempRCRC.B.TSF = config->receiveControl.frameTimestampSelect;
217  tempRCRC.B.TSR = config->receiveControl.receiveDataRegisterTimestamp;
218  psi5Ch->RCRC.U = tempRCRC.U;
219 
220  Ifx_PSI5_RFC tempRFC;
221  tempRFC.B.FWL = config->receiveControl.fifoWarningLevel;
222  psi5->RFC[config->channelId].U = tempRFC.U;
223 
224  Ifx_PSI5_CH_SCR tempSCR;
225  tempSCR.B.PLL = config->sendControl.payloadLength;
226  tempSCR.B.EPS = config->sendControl.enhancedProtocolSelected;
227  tempSCR.B.BSC = config->sendControl.bitStuffingEnabled;
228  tempSCR.B.SSL = config->sendControl.ssrPayloadLength;
229  tempSCR.B.SOL = config->sendControl.sorPayloadLength;
230  tempSCR.B.CRC = config->sendControl.crcGenerationEnabled;
231  tempSCR.B.STA = config->sendControl.startSequenceGenerationEnabled;
232  tempSCR.B.INH = config->sendControl.inhibitingAutomaticTransferEnabled;
233  psi5Ch->SCR.U = tempSCR.U;
234 
235  Ifx_PSI5_CH_IOCR tempIOCR;
236  tempIOCR.B.DEPTH = config->inputOutputControl.digitalInputFilterDepth;
237  tempIOCR.B.OIE = config->inputOutputControl.outputInverterEnabled;
238  tempIOCR.B.IIE = config->inputOutputControl.inputInverterEnabled;
239  psi5Ch->IOCR.U = tempIOCR.U;
240 
241  psi5->GCR.U |=
243 
244  IfxScuWdt_setCpuEndinit(passwd);
245 
246  const IfxPsi5_Psi5_PinsConfig *pins = config->pinsConfig;
247 
248  if (pins != NULL_PTR)
249  {
250  const IfxPsi5_Rx_In *rx = pins->in;
251 
252  if (rx != NULL_PTR)
253  {
254  IfxPsi5_initRxPin(rx, pins->inMode);
255  }
256 
257  const IfxPsi5_Tx_Out *tx = pins->out;
258 
259  if (tx != NULL_PTR)
260  {
261  IfxPsi5_initTxPin(tx, pins->outMode, pins->pinDriver);
262  }
263  }
264 
265  return status;
266 }
267 
268 
270 {
271  IfxPsi5_Psi5_ChannelConfig IfxPsi5_Psi5_defaultChannelConfig = {
273  .module = NULL_PTR,
274  .pulseGeneration = {
275  .pulseLength = 5,
276  .delayLength = 1,
277  .timeBaseSelect = IfxPsi5_TimeBase_internal,
278  .externalTimeBaseSelect = IfxPsi5_Trigger_0,
279  .periodicOrExternalOrBypass = IfxPsi5_TriggerType_periodic,
280  .externalTriggerSelect = IfxPsi5_Trigger_0,
281  .blankoutTime = 5
282  },
283  .channelTrigger = {
284  .channelTriggerValue = 0x150,
285  .channelTriggerCounter = 0x130
286  },
287  .watchdogTimerLimit[0] = 0x0,
288  .watchdogTimerLimit[1] = 0x0,
289  .watchdogTimerLimit[2] = 0x0,
290  .watchdogTimerLimit[3] = 0x0,
291  .watchdogTimerLimit[4] = 0x0,
292  .watchdogTimerLimit[5] = 0x0,
293  .watchdogTimerLimit[6] = 0x0,
294  .receiveControl = {
295  .payloadLength[0] = 8,
296  .payloadLength[1] = 8,
297  .payloadLength[2] = 8,
298  .payloadLength[3] = 8,
299  .payloadLength[4] = 8,
300  .payloadLength[5] = 8,
301  .asynchronousModeSelected = FALSE,
302  .verboseForAsynchronousMode = IfxPsi5_Verbose_off,
303  .messagingBitsPresence[0] = IfxPsi5_MessagingBits_absent,
304  .messagingBitsPresence[1] = IfxPsi5_MessagingBits_absent,
305  .messagingBitsPresence[2] = IfxPsi5_MessagingBits_absent,
306  .messagingBitsPresence[3] = IfxPsi5_MessagingBits_absent,
307  .messagingBitsPresence[4] = IfxPsi5_MessagingBits_absent,
308  .messagingBitsPresence[5] = IfxPsi5_MessagingBits_absent,
309  .crcOrParity[0] = IfxPsi5_CRCorParity_parity,
310  .crcOrParity[1] = IfxPsi5_CRCorParity_parity,
311  .crcOrParity[2] = IfxPsi5_CRCorParity_parity,
312  .crcOrParity[3] = IfxPsi5_CRCorParity_parity,
313  .crcOrParity[4] = IfxPsi5_CRCorParity_parity,
314  .crcOrParity[5] = IfxPsi5_CRCorParity_parity,
315  .frameExpectation[0] = IfxPsi5_FrameExpectation_notExpected,
316  .frameExpectation[1] = IfxPsi5_FrameExpectation_notExpected,
317  .frameExpectation[2] = IfxPsi5_FrameExpectation_notExpected,
318  .frameExpectation[3] = IfxPsi5_FrameExpectation_notExpected,
319  .frameExpectation[4] = IfxPsi5_FrameExpectation_notExpected,
320  .frameExpectation[5] = IfxPsi5_FrameExpectation_notExpected,
321  .verbose[0] = IfxPsi5_Verbose_off,
322  .verbose[1] = IfxPsi5_Verbose_off,
323  .verbose[2] = IfxPsi5_Verbose_off,
324  .verbose[3] = IfxPsi5_Verbose_off,
325  .verbose[4] = IfxPsi5_Verbose_off,
326  .verbose[5] = IfxPsi5_Verbose_off,
327  .baudrateSelect = IfxPsi5_BaudRate_125,
328  .pulseTimestampSelect = IfxPsi5_TimestampRegister_a,
329  .frameTimestampSelect = IfxPsi5_TimestampRegister_a,
330  .receiveDataRegisterTimestamp = IfxPsi5_ReceiveDataRegisterTimestamp_pulse,
331  .fifoWarningLevel = 16
332  },
333  .sendControl = {
334  .payloadLength = 32,
335  .enhancedProtocolSelected = FALSE,
336  .bitStuffingEnabled = FALSE,
337  .ssrPayloadLength = 32,
338  .sorPayloadLength = 32,
339  .crcGenerationEnabled = FALSE,
340  .startSequenceGenerationEnabled = FALSE,
341  .inhibitingAutomaticTransferEnabled = FALSE
342  },
343  .inputOutputControl = {
344  .digitalInputFilterDepth = IfxPsi5_DigitalInputFilterDepth_0,
345  .outputInverterEnabled = FALSE,
346  .inputInverterEnabled = FALSE
347  }
348  };
349  *config = IfxPsi5_Psi5_defaultChannelConfig;
350  config->module = psi5;
351 }
352 
353 
355 {
356  boolean status = TRUE;
357  Ifx_PSI5 *psi5SFR = config->psi5;
358 
359  psi5->psi5 = psi5SFR;
360 
363  IfxPsi5_Psi5_enableModule(psi5SFR);
364 
365  if (IfxPsi5_Psi5_initializeClock(psi5SFR, &config->fracDiv) == 0)
366  {
367  status = FALSE;
368 
369  return status;
370  }
371  else
372  {}
373 
374  if (IfxPsi5_Psi5_initializeClock(psi5SFR, &config->slowClock) == 0)
375  {
376  status = FALSE;
377 
378  return status;
379  }
380  else
381  {}
382 
383  if (IfxPsi5_Psi5_initializeClock(psi5SFR, &config->fastClock) == 0)
384  {
385  status = FALSE;
386 
387  return status;
388  }
389  else
390  {}
391 
392  if (IfxPsi5_Psi5_initializeClock(psi5SFR, &config->timestampClock) == 0)
393  {
394  status = FALSE;
395 
396  return status;
397  }
398  else
399  {}
400 
401  IfxScuWdt_setCpuEndinit(passwd);
402 
403  return status;
404 }
405 
406 
408 {
409  uint32 spbFrequency = IfxScuCcu_getSpbFrequency();
410 
411  config->psi5 = psi5;
412  config->fracDiv.frequency = spbFrequency;
430 }
431 
432 
433 static uint32 IfxPsi5_Psi5_initializeClock(Ifx_PSI5 *psi5, const IfxPsi5_Psi5_Clock *clock)
434 {
435  uint64 step = 0;
436  uint32 result = 0;
437  IfxPsi5_DividerMode divMode = clock->mode;
438  IfxPsi5_ClockType clockType = clock->type;
439  uint32 clockFrequency = clock->frequency;
440  uint32 fInput;
441  Ifx_PSI5_FDR tempFDR, tempFDRL, tempFDRH, tempFDRT;
442 
443  if (clockType == IfxPsi5_ClockType_fracDiv)
444  {
445  fInput = IfxScuCcu_getSpbFrequency();
446  }
447  else
448  {
449  fInput = IfxPsi5_Psi5_getFracDivClock(psi5);
450 
451  if (fInput == 0)
452  {
453  result = 0;
454 
455  return result;
456  }
457  else
458  {}
459  }
460 
461  switch (divMode)
462  {
464  step = IFXPSI5_STEP_RANGE - (fInput / clockFrequency);
465 
466  if (step > (IFXPSI5_STEP_RANGE - 1))
467  {
468  step = IFXPSI5_STEP_RANGE - 1;
469  }
470  else
471  {
472  /* do nothing */
473  }
474 
475  result = (uint32)(fInput / (IFXPSI5_STEP_RANGE - step));
476  break;
477 
479  step = (uint64)((uint64)clockFrequency * IFXPSI5_STEP_RANGE) / fInput;
480 
481  if (step > (IFXPSI5_STEP_RANGE - 1))
482  {
483  step = IFXPSI5_STEP_RANGE - 1;
484  }
485  else
486  {
487  /* do nothing */
488  }
489 
490  result = (uint32)((uint64)((uint64)fInput * step)) / IFXPSI5_STEP_RANGE;
491  break;
492 
494  default:
495  step = 0;
496  result = 0;
497  break;
498  }
499 
500  if (result != 0)
501  {
502  switch (clockType)
503  {
505  tempFDR.U = 0;
506  tempFDR.B.DM = divMode;
507  tempFDR.B.STEP = (uint32)step;
508  psi5->FDR.U = tempFDR.U;
509  break;
510 
512  tempFDRL.U = 0;
513  tempFDRL.B.DM = divMode;
514  tempFDRL.B.STEP = (uint32)step;
515  psi5->FDRL.U = tempFDRL.U;
516  break;
517 
519  tempFDRH.U = 0;
520  tempFDRH.B.DM = divMode;
521  tempFDRH.B.STEP = (uint32)step;
522  psi5->FDRH.U = tempFDRH.U;
523  break;
524 
526  tempFDRT.U = 0;
527  tempFDRT.B.DM = divMode;
528  tempFDRT.B.STEP = (uint32)step;
529  psi5->FDRT.U = tempFDRT.U;
530  break;
531  }
532  }
533 
534  return result;
535 }
536 
537 
539 {
540  if (channel->module->psi5->INTSTATA[channel->channelId].B.RDI == TRUE)
541  {
542  frame->rdm.lowWord = channel->channel->RDRL.U;
543  frame->rdm.highWord = channel->channel->RDRH.U;
544 
545  channel->module->psi5->INTCLRA[channel->channelId].U |= (IFX_PSI5_INTCLRA_RDI_MSK << IFX_PSI5_INTCLRA_RDI_OFF) | (IFX_PSI5_INTCLRA_RSI_MSK << IFX_PSI5_INTCLRA_RSI_OFF);
546 
547  return TRUE;
548  }
549  else
550  {
551  return FALSE;
552  }
553 }
554 
555 
557 {
558  message->rds.value = channel->channel->SDS[slot].U;
559 
560  return TRUE;
561 }
562 
563 
564 static void IfxPsi5_Psi5_resetModule(Ifx_PSI5 *psi5)
565 {
567 
569  psi5->KRST1.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
570  psi5->KRST0.B.RST = 1;
571 
572  while (psi5->KRST0.B.RSTSTAT == 0)
573  {
574  /* Wait until reset is executed */
575  }
576 
577  psi5->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
579 }
580 
581 
583 {
584  channel->channel->SDRL.U = data & 0xFFFFFFFF;
585  channel->channel->SDRH.U = (data >> 32) & 0xFFFFFFFF;
586 
587  if (channel->module->psi5->INTSTATA[channel->channelId].B.TPOI)
588  {
589  return FALSE;
590  }
591  else
592  {
593  return TRUE;
594  }
595 }