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