iLLD_TC29x  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_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.h"
30 
31 /******************************************************************************/
32 /*-------------------------Function Implementations---------------------------*/
33 /******************************************************************************/
34 
35 void IfxAsclin_enableAscErrorFlags(Ifx_ASCLIN *asclin, boolean parEnable, boolean rfoEnable)
36 {
37  IfxAsclin_enableParityErrorFlag(asclin, parEnable); /* enables parity error*/
38  IfxAsclin_enableRxFifoOverflowFlag(asclin, rfoEnable); /* enables Rx fifo Overflow error*/
39 }
40 
41 
42 void IfxAsclin_enableModule(Ifx_ASCLIN *asclin)
43 {
45  IfxScuWdt_clearCpuEndinit(psw); /* clears the endinit protection*/
46  IfxAsclin_setEnableModuleRequest(asclin); /* enables the module*/
47  IfxScuWdt_setCpuEndinit(psw); /* sets the endinit protection back on*/
48 }
49 
50 
51 float32 IfxAsclin_getFaFrequency(Ifx_ASCLIN *asclin)
52 {
53  float32 frequency;
54  IfxAsclin_ClockSource clockSource = IfxAsclin_getClockSource(asclin); /* gets the current clock source*/
55 
56  switch (clockSource)
57  {
58  case IfxAsclin_ClockSource_noClock: /* gets the respective frequency*/
59  frequency = 0.0;
60  break;
62  frequency = IfxScuCcu_getSpbFrequency();
63  break;
65  frequency = IfxScuCcu_getOsc0Frequency();
66  break;
68  frequency = IfxScuCcu_getPllErayFrequency();
69  break;
71  frequency = IfxScuCcu_getBaud2Frequency();
72  break;
74  frequency = IfxScuCcu_getBaud1Frequency();
75  break;
76  default:
77  frequency = 0.0;
78  break;
79  }
80 
81  return frequency;
82 }
83 
84 
85 sint32 IfxAsclin_getIndex(Ifx_ASCLIN *asclin)
86 {
87  uint32 base = (uint32)&MODULE_ASCLIN0;
88  uint32 singleDistance = ((uint32)&MODULE_ASCLIN1) - base;
89  uint32 distance = ((uint32)asclin) - base;
90  uint32 index = distance / singleDistance;
91  return index;
92 }
93 
94 
96 {
97  return (IfxAsclin_getPdFrequency(asclin) * asclin->BRG.B.NUMERATOR) / asclin->BRG.B.DENOMINATOR;
98 }
99 
100 
102 {
103  return IfxAsclin_getFaFrequency(asclin) / (asclin->BITCON.B.PRESCALER + 1);
104 }
105 
106 
108 {
109  return IfxAsclin_getOvsFrequency(asclin) / asclin->BITCON.B.OVERSAMPLING;
110 }
111 
112 
113 volatile Ifx_SRC_SRCR *IfxAsclin_getSrcPointerEr(Ifx_ASCLIN *asclin)
114 {
115  return &MODULE_SRC.ASCLIN.ASCLIN[IfxAsclin_getIndex(asclin)].ERR;
116 }
117 
118 
119 volatile Ifx_SRC_SRCR *IfxAsclin_getSrcPointerRx(Ifx_ASCLIN *asclin)
120 {
121  return &MODULE_SRC.ASCLIN.ASCLIN[IfxAsclin_getIndex(asclin)].RX;
122 }
123 
124 
125 volatile Ifx_SRC_SRCR *IfxAsclin_getSrcPointerTx(Ifx_ASCLIN *asclin)
126 {
127  return &MODULE_SRC.ASCLIN.ASCLIN[IfxAsclin_getIndex(asclin)].TX;
128 }
129 
130 
131 uint32 IfxAsclin_read16(Ifx_ASCLIN *asclin, uint16 *data, uint32 count)
132 {
133  volatile Ifx_ASCLIN_RXDATA *rxData = (volatile Ifx_ASCLIN_RXDATA *)&asclin->RXDATA.U;
134 
135  while (count > 0)
136  {
137  *data++ = (uint16)rxData->U;
138  count--;
139  }
140 
141  return count;
142 }
143 
144 
145 uint32 IfxAsclin_read32(Ifx_ASCLIN *asclin, uint32 *data, uint32 count)
146 {
147  volatile Ifx_ASCLIN_RXDATA *rxData = (volatile Ifx_ASCLIN_RXDATA *)&asclin->RXDATA.U;
148 
149  while (count > 0)
150  {
151  *data++ = rxData->U;
152  count--;
153  }
154 
155  return count;
156 }
157 
158 
159 uint32 IfxAsclin_read8(Ifx_ASCLIN *asclin, uint8 *data, uint32 count)
160 {
161  volatile Ifx_ASCLIN_RXDATA *rxData = (volatile Ifx_ASCLIN_RXDATA *)&asclin->RXDATA.U;
162 
163  while (count > 0)
164  {
165  *data++ = (uint8)rxData->U;
166  count--;
167  }
168 
169  return count;
170 }
171 
172 
173 void IfxAsclin_setBaudrateBitFields(Ifx_ASCLIN *asclin, uint16 prescaler, uint16 numerator, uint16 denominator, IfxAsclin_OversamplingFactor oversampling)
174 {
175  IfxAsclin_ClockSource clockSource = IfxAsclin_getClockSource(asclin); /* gets the current clock source */
176  IfxAsclin_setClockSource(asclin, IfxAsclin_ClockSource_noClock); /* turns off the clock for settings */
177  IfxAsclin_setPrescaler(asclin, prescaler); /* sets the prescaler*/
178  IfxAsclin_setNumerator(asclin, numerator); /* sets the numerator*/
179  IfxAsclin_setDenominator(asclin, denominator); /* sets the denominator*/
180  IfxAsclin_setOversampling(asclin, oversampling); /* sets the oversampling*/
181  IfxAsclin_setClockSource(asclin, clockSource); /* sets the clock source back on*/
182 }
183 
184 
185 boolean IfxAsclin_setBitTiming(Ifx_ASCLIN *asclin, float32 baudrate, IfxAsclin_OversamplingFactor oversampling, IfxAsclin_SamplePointPosition samplepoint, IfxAsclin_SamplesPerBit medianFilter)
186 {
188  float32 fOvs;
189  uint32 d, n, dBest = 1, nBest = 1;
190  float32 f;
191 
192  /* Set the PD frequency */
193  float32 fpd = IfxAsclin_getPdFrequency(asclin);
194  oversampling = __maxu(oversampling, 4);
195  samplepoint = __maxu(samplepoint, 1);
196  fOvs = baudrate * oversampling;
197  float32 relError = fOvs;
198  float32 limit = 0.001 * fOvs; // save the error limit
199 
200  boolean terminated = FALSE;
201  float32 newRelError; //modified by Hassan
202  uint32 adder_facL, adder_facH, adder_facL_min, count; //modified by Hassan
203 
204  d = (uint32)(fpd / fOvs);
205  n = 1;
206 
207  dBest = d;
208  nBest = n;
209  adder_facL_min = 0;
210  f = (fpd * n) / d;
211  relError = __absf(fOvs - f);
212 
213  if (relError <= limit)
214  {
215  terminated = TRUE;
216  }
217 
218  for (n = 2; ((!terminated) && ((n * d) <= 0xFFF)); n++)
219  {
220  if (n == 2)
221  {
222  adder_facL = 1;
223  adder_facH = 1;
224  }
225  else
226  {
227  adder_facL = (adder_facL_min * n) / nBest;
228  adder_facH = adder_facL + 1;
229  }
230 
231  for (count = adder_facL; count <= adder_facH; count++)
232  {
233  f = (fpd * n) / (n * d + count);
234  newRelError = __absf(fOvs - f);
235 
236  if (relError > (newRelError))
237  {
238  relError = newRelError;
239  nBest = n;
240  dBest = (n * d + count);
241  adder_facL_min = count;
242  }
243  }
244 
245  if (relError <= limit)
246  {
247  break;
248  }
249  }
250 
252  asclin->BRG.B.DENOMINATOR = dBest;
253  asclin->BRG.B.NUMERATOR = nBest;
254 
255  /* Set the SHIFT frequency */
256  asclin->BITCON.B.OVERSAMPLING = oversampling - 1;
257 
258  /* Set the sampling point */
259  asclin->BITCON.B.SAMPLEPOINT = samplepoint;
260 
261  /* Set the median filter */
262  asclin->BITCON.B.SM = medianFilter ? 1 : 0;
263 
264  IfxAsclin_setClockSource(asclin, source);
265 
266  return TRUE;
267 }
268 
269 
270 void IfxAsclin_setClockSource(Ifx_ASCLIN *asclin, IfxAsclin_ClockSource clockSource)
271 {
272  asclin->CSR.B.CLKSEL = clockSource; /* selects the given clock source*/
273 
274  /* Waits TW or polls for CSR.CON to change */
275  if (clockSource == IfxAsclin_ClockSource_noClock)
276  {
277  while (IfxAsclin_getClockStatus(asclin) != 0U)
278  {}
279  }
280  else
281  {
282  while (IfxAsclin_getClockStatus(asclin) != 1U)
283  {}
284  }
285 }
286 
287 
288 uint32 IfxAsclin_write16(Ifx_ASCLIN *asclin, uint16 *data, uint32 count)
289 {
290  volatile Ifx_ASCLIN_TXDATA *txData = (volatile Ifx_ASCLIN_TXDATA *)&asclin->TXDATA.U;
291 
292  while ((count > 0))
293  {
294  txData->U = *data++;
295  count--;
296  }
297 
298  return count;
299 }
300 
301 
302 uint32 IfxAsclin_write32(Ifx_ASCLIN *asclin, uint32 *data, uint32 count)
303 {
304  volatile Ifx_ASCLIN_TXDATA *txData = (volatile Ifx_ASCLIN_TXDATA *)&asclin->TXDATA.U;
305 
306  while ((count > 0))
307  {
308  txData->U = *data++;
309  count--;
310  }
311 
312  return count;
313 }
314 
315 
316 uint32 IfxAsclin_write8(Ifx_ASCLIN *asclin, uint8 *data, uint32 count)
317 {
318  volatile Ifx_ASCLIN_TXDATA *txData = (volatile Ifx_ASCLIN_TXDATA *)&asclin->TXDATA.U;
319 
320  while ((count > 0))
321  {
322  txData->U = *data++;
323  count--;
324  }
325 
326  return count;
327 }
328 
329 
330 void IfxAsclin_resetModule(Ifx_ASCLIN *asclin)
331 {
334 
335  asclin->KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
336  asclin->KRST1.B.RST = 1;
337  IfxScuWdt_setCpuEndinit(passwd);
338 
339  while (0 == asclin->KRST0.B.RSTSTAT) /* Wait until reset is executed */
340  {}
341 
343  asclin->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
344 
345  IfxScuWdt_setCpuEndinit(passwd);
346 }