iLLD_TC27xC  1.0
IfxAsclin_Asc.c
Go to the documentation of this file.
1 /**
2  * \file IfxAsclin_Asc.c
3  * \brief ASCLIN ASC details
4  *
5  * \version iLLD_0_1_0_10
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 "IfxAsclin_Asc.h"
30 #include "Scu/Std/IfxScuWdt.h"
31 #include "SysSe/Bsp/Bsp.h"
32 
33 /******************************************************************************/
34 /*-------------------------Function Implementations---------------------------*/
35 /******************************************************************************/
36 
38 {
39  Ifx_SizeT count = 1;
40  uint8 data;
41 
42  while (IfxAsclin_Asc_read(asclin, &data, &count, TIME_INFINITE) != TRUE)
43  {}
44 
45  return data;
46 }
47 
48 
50 {
51  Ifx_SizeT count = 1;
52 
53  return IfxAsclin_Asc_write(asclin, &data, &count, TIME_INFINITE);
54 }
55 
56 
58 {
59  return Ifx_Fifo_canReadCount(asclin->rx, count, timeout);
60 }
61 
62 
64 {
65  return Ifx_Fifo_canWriteCount(asclin->tx, count, timeout);
66 }
67 
68 
70 {
72  Ifx_Fifo_clear(asclin->rx);
73 }
74 
75 
77 {
78  Ifx_Fifo_clear(asclin->tx);
80 }
81 
82 
84 {
85  Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler*/
87  IfxScuWdt_clearCpuEndinit(psw); /* clearing the endinit protection */
88  IfxAsclin_setDisableModuleRequest(asclinSFR); /* disabling the module */
89  IfxScuWdt_setCpuEndinit(psw); /* setting the endinit protection back on */
90 }
91 
92 
94 {
95  Ifx_TickTime deadline = getDeadLine(timeout);
96  boolean result;
97 
98  /* Flush the software FIFO */
99  result = Ifx_Fifo_flush(asclin->tx, timeout);
100 
101  if (result)
102  {
103  /* Flush the hardware FIFO (wait until all bytes have been transmitted) */
104  do
105  {
106  result = IfxAsclin_getTxFifoFillLevel(asclin->asclin) == 0;
107  } while (!result && !isDeadLine(deadline));
108  }
109 
110  return result;
111 }
112 
113 
115 {
116  return Ifx_Fifo_readCount(asclin->rx);
117 }
118 
119 
121 {
122  return &asclin->rx->eventWriter;
123 }
124 
125 
127 {
128  return asclin->sendCount;
129 }
130 
131 
133 {
134  return asclin->txTimestamp;
135 }
136 
137 
139 {
140  return Ifx_Fifo_writeCount(asclin->tx);
141 }
142 
143 
145 {
146  return &asclin->tx->eventWriter;
147 }
148 
149 
151 {
152  Ifx_ASCLIN *asclinSFR = config->asclin; /* pointer to ASCLIN registers*/
154 
155  asclin->asclin = asclinSFR; /* adding register pointer to module handler*/
156 
157  IfxAsclin_enableModule(asclinSFR); /* enabling the module*/
158  IfxAsclin_setClockSource(asclinSFR, IfxAsclin_ClockSource_noClock); /* disabling the clock*/
159  IfxAsclin_setFrameMode(asclinSFR, IfxAsclin_FrameMode_initialise); /* setting the module in Initialise mode*/
160  IfxAsclin_setPrescaler(asclinSFR, config->baudrate.prescaler); /* sets the prescaler */
161  IfxAsclin_setClockSource(asclinSFR, config->clockSource); /* temporary set the clock source for baudrate configuration*/
162  status = (IfxAsclin_Status)IfxAsclin_setBitTiming(asclinSFR, /* setting the baudrate bit fields to generate the required baudrate*/
163  config->baudrate.baudrate,
164  config->baudrate.oversampling,
166  config->bitTiming.medianFilter);
167  IfxAsclin_setClockSource(asclinSFR, IfxAsclin_ClockSource_noClock); /* disabling the clock again*/
168 
169  IfxAsclin_enableLoopBackMode(asclinSFR, config->loopBack); /* selecting the loopback mode */
170  IfxAsclin_enableParity(asclinSFR, config->frame.parityBit); /* setting parity enable */
171  IfxAsclin_setParityType(asclinSFR, config->frame.parityType); /* setting parity type (odd/even)*/
172  IfxAsclin_setStopBit(asclinSFR, config->frame.stopBit); /* setting the stop bit */
173  IfxAsclin_setShiftDirection(asclinSFR, config->frame.shiftDir); /* setting the shift direction */
174  IfxAsclin_setDataLength(asclinSFR, config->frame.dataLength); /* setting the data length */
175  IfxAsclin_setTxFifoInletWidth(asclinSFR, config->fifo.inWidth); /* setting Tx FIFO inlet width */
176  IfxAsclin_setRxFifoOutletWidth(asclinSFR, config->fifo.outWidth); /* setting Rx FIFO outlet width */
177  IfxAsclin_setIdleDelay(asclinSFR, config->frame.idleDelay); /* setting idle delay */
178  IfxAsclin_setTxFifoInterruptLevel(asclinSFR, config->fifo.txFifoInterruptLevel); /* setting Tx FIFO level at which a Tx interrupt will be triggered*/
179  IfxAsclin_setRxFifoInterruptLevel(asclinSFR, config->fifo.rxFifoInterruptLevel); /* setting Rx FIFO interrupt level at which a Rx interrupt will be triggered*/
180  IfxAsclin_setFrameMode(asclinSFR, config->frame.frameMode); /* selecting the frame mode*/
181 
182  /* Pin mapping */
183  const IfxAsclin_Asc_Pins *pins = config->pins;
184 
185  if (pins != NULL_PTR)
186  {
187  IfxAsclin_Cts_In *cts = pins->cts;
188 
189  if (cts != NULL_PTR)
190  {
191  IfxAsclin_initCtsPin(cts, pins->ctsMode);
192  }
193 
194  IfxAsclin_Rx_In *rx = pins->rx;
195 
196  if (rx != NULL_PTR)
197  {
198  IfxAsclin_initRxPin(rx, pins->rxMode);
199  }
200 
201  IfxAsclin_Rts_Out *rts = pins->rts;
202 
203  if (rts != NULL_PTR)
204  {
205  IfxAsclin_initRtsPin(rts, pins->rtsMode, pins->pinDriver);
206  }
207 
208  IfxAsclin_Tx_Out *tx = pins->tx;
209 
210  if (tx != NULL_PTR)
211  {
212  IfxAsclin_initTxPin(tx, pins->txMode, pins->pinDriver);
213  }
214  }
215 
216  IfxAsclin_setClockSource(asclinSFR, config->clockSource); /* select the clock source*/
217 
218  IfxAsclin_disableAllFlags(asclinSFR); /* disable all flags */
219  IfxAsclin_clearAllFlags(asclinSFR); /* clear all flags */
220 
221  /* HW error flags */
222  asclin->errorFlags.ALL = 0;
223 
224  if (config->errorFlags.flags.parityError)
225  {
227  }
228 
229  if (config->errorFlags.flags.frameError)
230  {
232  }
233 
234  if (config->errorFlags.flags.rxFifoOverflow)
235  {
237  }
238 
239  if (config->errorFlags.flags.rxFifoUnderflow)
240  {
242  }
243 
244  if (config->errorFlags.flags.txFifoOverflow)
245  {
247  }
248 
249  /* transmission flags */
250  asclin->rxSwFifoOverflow = FALSE;
251  asclin->txInProgress = FALSE;
252 
253  /* Buffer mode */
254  Ifx_SizeT elementSize;
255  asclin->dataBufferMode = config->dataBufferMode;
256  asclin->txTimestamp = 0;
257  asclin->sendCount = 0;
258 
259  switch (asclin->dataBufferMode)
260  {
262  elementSize = 1;
263  break;
265  elementSize = sizeof(Ifx_DataBufferMode_TimeStampSingle);
266  break;
267  default:
268  elementSize = 0;
270  break;
271  }
272 
273  /* SW Fifos */
274  if (config->txBuffer != NULL_PTR)
275  {
276  asclin->tx = Ifx_Fifo_init(config->txBuffer, config->txBufferSize, elementSize);
277  }
278  else
279  {
280  asclin->tx = Ifx_Fifo_create(config->txBufferSize, elementSize);
281  }
282 
283  if (config->rxBuffer != NULL_PTR)
284  {
285  asclin->rx = Ifx_Fifo_init(config->rxBuffer, config->rxBufferSize, elementSize);
286  }
287  else
288  {
289  asclin->rx = Ifx_Fifo_create(config->rxBufferSize, elementSize);
290  }
291 
292  /* initialising the interrupts */
293  if (config->interrupt.rxPriority > 0)
294  {
295  volatile Ifx_SRC_SRCR *src;
296  src = IfxAsclin_getSrcPointerRx(asclinSFR);
297  IfxSrc_init(src, config->interrupt.typeOfService, config->interrupt.rxPriority);
299  IfxSrc_enable(src);
300  }
301 
302  if (config->interrupt.txPriority > 0)
303  {
304  volatile Ifx_SRC_SRCR *src;
305  src = IfxAsclin_getSrcPointerTx(asclinSFR);
306  IfxSrc_init(src, config->interrupt.typeOfService, config->interrupt.txPriority);
308  IfxSrc_enable(src);
309  }
310 
311  if (config->interrupt.erPriority > 0)
312  {
313  volatile Ifx_SRC_SRCR *src;
314  src = IfxAsclin_getSrcPointerEr(asclinSFR);
315  IfxSrc_init(src, config->interrupt.typeOfService, config->interrupt.erPriority);
317  IfxSrc_enable(src);
318  }
319 
320  /* enable transfers */
321  IfxAsclin_enableRxFifoInlet(asclinSFR, TRUE); // enabling Rx FIFO for recieving
322  IfxAsclin_enableTxFifoOutlet(asclinSFR, TRUE); // enabling Tx FIFO for transmitting
323 
324  IfxAsclin_flushRxFifo(asclinSFR); // flushing Rx FIFO
325  IfxAsclin_flushTxFifo(asclinSFR); // flushing Tx FIFO
326 
327  return status;
328 }
329 
330 
331 void IfxAsclin_Asc_initModuleConfig(IfxAsclin_Asc_Config *config, Ifx_ASCLIN *asclin)
332 {
333  config->asclin = asclin;
334 
335  /* loop back disabled */
336  config->loopBack = FALSE; /* no loop back*/
337 
338  /* Default values for baudrate */
339  config->clockSource = IfxAsclin_ClockSource_kernelClock; /* kernel clock, fclc*/
340  config->baudrate.prescaler = 1; /* default prescaler*/
341  config->baudrate.baudrate = 115200; /* default baudrate (the fractional dividier setup will be calculated in initModule*/
342  config->baudrate.oversampling = IfxAsclin_OversamplingFactor_4; /* default oversampling factor*/
343 
344  /* Default Values for Bit Timings */
345  config->bitTiming.medianFilter = IfxAsclin_SamplesPerBit_one; /* one sample per bit*/
346  config->bitTiming.samplePointPosition = IfxAsclin_SamplePointPosition_3; /* sample point position at 3*/
347  /* Default Values for Frame Control */
348  config->frame.idleDelay = IfxAsclin_IdleDelay_0; /* no idle delay*/
349  config->frame.stopBit = IfxAsclin_StopBit_1; /* one stop bit*/
350  config->frame.frameMode = IfxAsclin_FrameMode_asc; /* ASC mode*/
351  config->frame.shiftDir = IfxAsclin_ShiftDirection_lsbFirst; /* shift diection LSB first*/
352  config->frame.parityBit = FALSE; /* disable parity*/
353  config->frame.parityType = IfxAsclin_ParityType_even; /* even parity (if parity enabled)*/
354  config->frame.dataLength = IfxAsclin_DataLength_8; /* number of bits per transfer 8*/
355 
356  /* Default Values for Fifo Control */
357  config->fifo.inWidth = IfxAsclin_TxFifoInletWidth_1; /* 8-bit wide write*/
358  config->fifo.outWidth = IfxAsclin_RxFifoOutletWidth_1; /* 8-bit wide read*/
361  config->fifo.buffMode = IfxAsclin_ReceiveBufferMode_rxFifo; /* RxFIFO*/
362 
363  /* Default Values for Interrupt Config */
364  config->interrupt.rxPriority = 0; /* receive interrupt priority 0*/
365  config->interrupt.txPriority = 0; /* transmit interrupt priority 0*/
366  config->interrupt.erPriority = 0; /* error interrupt priority 0*/
367  config->interrupt.typeOfService = IfxSrc_Tos_cpu0; /* type of service CPU0*/
368 
369  /* Enable error flags */
370  config->errorFlags.ALL = ~0; /* all error flags enabled*/
371 
372  /* init pointers */
373  config->pins = NULL_PTR; /* pins to null pointer*/
374  config->rxBuffer = NULL_PTR; /* Rx Fifo buffer*/
375  config->txBuffer = NULL_PTR; /* Tx Fifo buffer*/
376 
377  config->txBufferSize = 0; /* Rx Fifo buffer size*/
378  config->rxBufferSize = 0; /* Rx Fifo buffer size*/
379 
381 }
382 
383 
385 {
386  if (asclin->txInProgress == FALSE) /* Send first byte: send init */
387  {
388  if (Ifx_Fifo_isEmpty(asclin->tx) == FALSE)
389  {
390  uint8 data;
391  asclin->txInProgress = TRUE;
392 
393  switch (asclin->dataBufferMode)
394  {
396  {
397  Ifx_Fifo_read(asclin->tx, &data, 1, TIME_NULL);
398  /* FIXME optimize usage of HW fifo */
399  /* FIXME add support for data size != 8 bit */
400  }
401  break;
403  {
405  Ifx_Fifo_read(asclin->tx, &packedData, sizeof(packedData), TIME_NULL);
406  data = packedData.data;
407  }
408  break;
409  }
410 
411  IfxAsclin_write8(asclin->asclin, &data, 1);
412  }
413  }
414 }
415 
416 
418 {
419  Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler*/
420 
421  /* store all the flags in the variable */
422  if (IfxAsclin_getParityErrorFlagStatus(asclinSFR))
423  {
425  asclin->errorFlags.flags.parityError = 1;
426  }
427 
428  if (IfxAsclin_getFrameErrorFlagStatus(asclinSFR))
429  {
431  asclin->errorFlags.flags.frameError = 1;
432  }
433 
435  {
437  asclin->errorFlags.flags.rxFifoOverflow = 1;
438  }
439 
441  {
443  asclin->errorFlags.flags.rxFifoUnderflow = 1;
444  }
445 
447  {
449  asclin->errorFlags.flags.txFifoOverflow = 1;
450  }
451 }
452 
453 
455 {
456  uint8 ascData;
457 
458  switch (asclin->dataBufferMode)
459  {
461  {
462  /* FIXME optimize usage of HW fifo */
463  /* FIXME add support for data size != 8 bit */
464  IfxAsclin_read8(asclin->asclin, &ascData, 1);
465 
466  if (Ifx_Fifo_write(asclin->rx, &ascData, 1, TIME_NULL) != 0)
467  {
468  /* Receive buffer is full, data is discard */
469  asclin->rxSwFifoOverflow = TRUE;
470  }
471 
472  break;
473  }
475  {
477 
478  packedData.timestamp = now();
479  IfxAsclin_read8(asclin->asclin, &ascData, 1);
480  packedData.data = ascData;
481 
482  if (Ifx_Fifo_write(asclin->rx, &packedData, sizeof(packedData), TIME_NULL) != 0)
483  {
484  /* Receive buffer is full, data is discard */
485  asclin->rxSwFifoOverflow = TRUE;
486  }
487  }
488  break;
489  }
490 }
491 
492 
494 {
495  asclin->txTimestamp = now();
496  asclin->sendCount++;
497 
498  switch (asclin->dataBufferMode)
499  {
501  {
502  uint8 ascData;
503 
504  if (Ifx_Fifo_read(asclin->tx, &ascData, 1, TIME_NULL) != 0)
505  {
506  /* Transmit buffer is empty */
507  asclin->txInProgress = FALSE;
508  }
509  else
510  {
511  /* FIXME optimize usage of HW fifo */
512  /* FIXME add support for data size != 8 bit */
513  IfxAsclin_write8(asclin->asclin, &ascData, 1);
514  }
515 
516  break;
517  }
519  {
521  uint8 ascData;
522 
523  if (Ifx_Fifo_read(asclin->tx, &packedData, sizeof(packedData), TIME_NULL) != 0)
524  { /* Transmit buffer is empty */
525  asclin->txInProgress = FALSE;
526  }
527  else
528  {
529  ascData = packedData.data;
530  IfxAsclin_write8(asclin->asclin, &ascData, 1);
531  }
532  }
533  break;
534  }
535 }
536 
537 
538 boolean IfxAsclin_Asc_read(IfxAsclin_Asc *asclin, void *data, Ifx_SizeT *count, Ifx_TickTime timeout)
539 {
540  Ifx_SizeT left = Ifx_Fifo_read(asclin->rx, data, *count, timeout);
541 
542  *count -= left;
543 
544  return left == 0;
545 }
546 
547 
549 {
550  asclin->sendCount = 0;
551 }
552 
553 
555 {
556  /* Set the API link */
557  stdif->driver = asclin;
575  stdif->txDisabled = FALSE;
576  return TRUE;
577 }
578 
579 
580 boolean IfxAsclin_Asc_write(IfxAsclin_Asc *asclin, void *data, Ifx_SizeT *count, Ifx_TickTime timeout)
581 {
582  Ifx_SizeT left;
583  boolean result = TRUE;
584 
585  if (*count != 0)
586  {
587  left = Ifx_Fifo_write(asclin->tx, data, *count, timeout);
589 
590  *count -= left;
591  result = left == 0;
592  }
593 
594  return result;
595 }