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