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