iLLD_TC27xC  1.0
IfxAsclin.c
Go to the documentation of this file.
1 /**
2  * \file IfxAsclin.c
3  * \brief ASCLIN basic functionality
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.h"
30 #include "Scu/Std/IfxScuCcu.h"
31 #include "Scu/Std/IfxScuWdt.h"
32 
33 /******************************************************************************/
34 /*-------------------------Function Implementations---------------------------*/
35 /******************************************************************************/
36 
37 void IfxAsclin_enableAscErrorFlags(Ifx_ASCLIN *asclin, boolean parEnable, boolean rfoEnable)
38 {
39  IfxAsclin_enableParityErrorFlag(asclin, parEnable); /* enables parity error*/
40  IfxAsclin_enableRxFifoOverflowFlag(asclin, rfoEnable); /* enables Rx fifo Overflow error*/
41 }
42 
43 
44 void IfxAsclin_enableModule(Ifx_ASCLIN *asclin)
45 {
47  IfxScuWdt_clearCpuEndinit(psw); /* clears the endinit protection*/
48  IfxAsclin_setEnableModuleRequest(asclin); /* enables the module*/
49  IfxScuWdt_setCpuEndinit(psw); /* sets the endinit protection back on*/
50 }
51 
52 
53 float32 IfxAsclin_getFaFrequency(Ifx_ASCLIN *asclin)
54 {
55  float32 frequency;
56  IfxAsclin_ClockSource clockSource = IfxAsclin_getClockSource(asclin); /* gets the current clock source*/
57 
58  switch (clockSource)
59  {
60  case IfxAsclin_ClockSource_noClock: /* gets the respective frequency*/
61  frequency = 0.0;
62  break;
64  frequency = IfxScuCcu_getSpbFrequency();
65  break;
67  frequency = IfxScuCcu_getOsc0Frequency();
68  break;
70  frequency = IfxScuCcu_getPllErayFrequency();
71  break;
73  frequency = IfxScuCcu_getBaud2Frequency();
74  break;
76  frequency = IfxScuCcu_getBaud1Frequency();
77  break;
78  default:
79  frequency = 0.0;
80  break;
81  }
82 
83  return frequency;
84 }
85 
86 
87 sint32 IfxAsclin_getIndex(Ifx_ASCLIN *asclin)
88 {
89  uint32 base = (uint32)&MODULE_ASCLIN0;
90  uint32 singleDistance = ((uint32)&MODULE_ASCLIN1) - base;
91  uint32 distance = ((uint32)asclin) - base;
92  uint32 index = distance / singleDistance;
93  return index;
94 }
95 
96 
98 {
99  return (IfxAsclin_getPdFrequency(asclin) * asclin->BRG.B.NUMERATOR) / asclin->BRG.B.DENOMINATOR;
100 }
101 
102 
104 {
105  return IfxAsclin_getFaFrequency(asclin) / (asclin->BITCON.B.PRESCALER + 1);
106 }
107 
108 
110 {
111  return IfxAsclin_getOvsFrequency(asclin) / asclin->BITCON.B.OVERSAMPLING;
112 }
113 
114 
115 volatile Ifx_SRC_SRCR *IfxAsclin_getSrcPointerEr(Ifx_ASCLIN *asclin)
116 {
117  return &MODULE_SRC.ASCLIN.ASCLIN[IfxAsclin_getIndex(asclin)].ERR;
118 }
119 
120 
121 volatile Ifx_SRC_SRCR *IfxAsclin_getSrcPointerRx(Ifx_ASCLIN *asclin)
122 {
123  return &MODULE_SRC.ASCLIN.ASCLIN[IfxAsclin_getIndex(asclin)].RX;
124 }
125 
126 
127 volatile Ifx_SRC_SRCR *IfxAsclin_getSrcPointerTx(Ifx_ASCLIN *asclin)
128 {
129  return &MODULE_SRC.ASCLIN.ASCLIN[IfxAsclin_getIndex(asclin)].TX;
130 }
131 
132 
133 uint32 IfxAsclin_read16(Ifx_ASCLIN *asclin, uint16 *data, uint32 count)
134 {
135  volatile Ifx_ASCLIN_RXDATA *rxData = (volatile Ifx_ASCLIN_RXDATA *)&asclin->RXDATA.U;
136 
137  while (count > 0)
138  {
139  *data++ = (uint16)rxData->U;
140  count--;
141  }
142 
143  return count;
144 }
145 
146 
147 uint32 IfxAsclin_read32(Ifx_ASCLIN *asclin, uint32 *data, uint32 count)
148 {
149  volatile Ifx_ASCLIN_RXDATA *rxData = (volatile Ifx_ASCLIN_RXDATA *)&asclin->RXDATA.U;
150 
151  while (count > 0)
152  {
153  *data++ = rxData->U;
154  count--;
155  }
156 
157  return count;
158 }
159 
160 
161 uint32 IfxAsclin_read8(Ifx_ASCLIN *asclin, uint8 *data, uint32 count)
162 {
163  volatile Ifx_ASCLIN_RXDATA *rxData = (volatile Ifx_ASCLIN_RXDATA *)&asclin->RXDATA.U;
164 
165  while (count > 0)
166  {
167  *data++ = (uint8)rxData->U;
168  count--;
169  }
170 
171  return count;
172 }
173 
174 
175 void IfxAsclin_setBaudrateBitFields(Ifx_ASCLIN *asclin, uint16 prescaler, uint16 numerator, uint16 denominator, IfxAsclin_OversamplingFactor oversampling)
176 {
177  IfxAsclin_ClockSource clockSource = IfxAsclin_getClockSource(asclin); /* gets the current clock source */
178  IfxAsclin_setClockSource(asclin, IfxAsclin_ClockSource_noClock); /* turns off the clock for settings */
179  IfxAsclin_setPrescaler(asclin, prescaler); /* sets the prescaler*/
180  IfxAsclin_setNumerator(asclin, numerator); /* sets the numerator*/
181  IfxAsclin_setDenominator(asclin, denominator); /* sets the denominator*/
182  IfxAsclin_setOversampling(asclin, oversampling); /* sets the oversampling*/
183  IfxAsclin_setClockSource(asclin, clockSource); /* sets the clock source back on*/
184 }
185 
186 
187 boolean IfxAsclin_setBitTiming(Ifx_ASCLIN *asclin, float32 baudrate, IfxAsclin_OversamplingFactor oversampling, IfxAsclin_SamplePointPosition samplepoint, IfxAsclin_SamplesPerBit medianFilter)
188 {
190  float32 fOvs;
191  uint32 d, n, dBest = 1, nBest = 1;
192  float32 f;
193 
194  /* Set the PD frequency */
195  float32 fpd = IfxAsclin_getPdFrequency(asclin);
196 
197  oversampling = __maxu(oversampling + 1, 4);
198  samplepoint = __maxu(samplepoint, 1);
199  fOvs = baudrate * oversampling;
200  float32 relError = fOvs;
201  float32 limit = 0.001 * fOvs; /* save the error limit*/
202  boolean terminated = FALSE;
203 
204  d = (uint32)(fpd / fOvs);
205  float32 factor = fOvs / fpd; /* move division out of the loop */
206 
207  for ( ; !terminated && d <= 0xFFF; d++)
208  {
209  n = (uint32)(factor * d);
210  /* As n is rounded to the next smaller value, f = (fpd * n) / d <= fOvs
211  * rounding up would have f >=fOvs
212  * Only 2 values for n needs to be tested: n and n+1, therefore lastN*/
213  uint32 lastN = __minX(n + 1, d); /* Limit next loop to 2, highest value is d */
214 
215  for ( ; n <= lastN; n++)
216  {
217  f = (fpd * n) / d;
218 
219  float32 newRelError = __absf(fOvs - f); /* save the value, no need to know the sign of the error */
220 
221  if (relError > (newRelError))
222  {
223  relError = newRelError;
224  nBest = n;
225  dBest = d;
226 
227  if (relError <= limit)
228  {
229  terminated = TRUE;
230  break;
231  }
232  }
233  }
234  }
235 
237  asclin->BRG.B.DENOMINATOR = dBest;
238  asclin->BRG.B.NUMERATOR = nBest;
239 
240  /* Set the SHIFT frequency */
241  asclin->BITCON.B.OVERSAMPLING = oversampling - 1;
242 
243  /* Set the sampling point */
244  asclin->BITCON.B.SAMPLEPOINT = samplepoint;
245 
246  /* Set the median filter */
247  asclin->BITCON.B.SM = medianFilter ? 1 : 0;
248 
249  IfxAsclin_setClockSource(asclin, source);
250 
251  return TRUE;
252 }
253 
254 
255 void IfxAsclin_setClockSource(Ifx_ASCLIN *asclin, IfxAsclin_ClockSource clockSource)
256 {
257  asclin->CSR.B.CLKSEL = clockSource; /* selects the given clock source*/
258 
259  /* Waits TW or polls for CSR.CON to change */
260  if (clockSource == IfxAsclin_ClockSource_noClock)
261  {
262  while (IfxAsclin_getClockStatus(asclin) != 0U)
263  {}
264  }
265  else
266  {
267  while (IfxAsclin_getClockStatus(asclin) != 1U)
268  {}
269  }
270 }
271 
272 
273 uint32 IfxAsclin_write16(Ifx_ASCLIN *asclin, uint16 *data, uint32 count)
274 {
275  volatile Ifx_ASCLIN_TXDATA *txData = (volatile Ifx_ASCLIN_TXDATA *)&asclin->TXDATA.U;
276 
277  while ((count > 0))
278  {
279  txData->U = *data++;
280  count--;
281  }
282 
283  return count;
284 }
285 
286 
287 uint32 IfxAsclin_write32(Ifx_ASCLIN *asclin, uint32 *data, uint32 count)
288 {
289  volatile Ifx_ASCLIN_TXDATA *txData = (volatile Ifx_ASCLIN_TXDATA *)&asclin->TXDATA.U;
290 
291  while ((count > 0))
292  {
293  txData->U = *data++;
294  count--;
295  }
296 
297  return count;
298 }
299 
300 
301 uint32 IfxAsclin_write8(Ifx_ASCLIN *asclin, uint8 *data, uint32 count)
302 {
303  volatile Ifx_ASCLIN_TXDATA *txData = (volatile Ifx_ASCLIN_TXDATA *)&asclin->TXDATA.U;
304 
305  while ((count > 0))
306  {
307  txData->U = *data++;
308  count--;
309  }
310 
311  return count;
312 }