1/*
2 * File: SMO_arctan_PLL.c
3 *
4 * Code generated for Simulink model 'SMO_arctan_PLL'.
5 *
6 * Model version : 1.812
7 * Simulink Coder version : 9.4 (R2020b) 29-Jul-2020
8 * C/C++ source code generated on : Tue Apr 11 20:18:35 2023
9 *
10 * Target selection: ert.tlc
11 * Embedded hardware selection: ARM Compatible->ARM Cortex-M
12 * Code generation objectives:
13 * 1. Execution efficiency
14 * 2. RAM efficiency
15 * Validation result: Not run
16 */
17
18#include "SMO_arctan_PLL.h"
19#define NumBitsPerChar 8U
20
21extern real_T rt_remd_snf(real_T u0, real_T u1);
22static real_T rtGetNaN(void);
23static real32_T rtGetNaNF(void);
24extern real_T rtInf;
25extern real_T rtMinusInf;
26extern real_T rtNaN;
27extern real32_T rtInfF;
28extern real32_T rtMinusInfF;
29extern real32_T rtNaNF;
30static void rt_InitInfAndNaN(size_t realSize);
31static boolean_T rtIsInf(real_T value);
32static boolean_T rtIsInfF(real32_T value);
33static boolean_T rtIsNaN(real_T value);
34static boolean_T rtIsNaNF(real32_T value);
35typedef struct {
36 struct {
37 uint32_T wordH;
38 uint32_T wordL;
39 } words;
40} BigEndianIEEEDouble;
41
42typedef struct {
43 struct {
44 uint32_T wordL;
45 uint32_T wordH;
46 } words;
47} LittleEndianIEEEDouble;
48
49typedef struct {
50 union {
51 real32_T wordLreal;
52 uint32_T wordLuint;
53 } wordL;
54} IEEESingle;
55
56real_T rtInf;
57real_T rtMinusInf;
58real_T rtNaN;
59real32_T rtInfF;
60real32_T rtMinusInfF;
61real32_T rtNaNF;
62static real_T rtGetInf(void);
63static real32_T rtGetInfF(void);
64static real_T rtGetMinusInf(void);
65static real32_T rtGetMinusInfF(void);
66
67/*===========*
68 * Constants *
69 *===========*/
70#define RT_PI 3.14159265358979323846
71#define RT_PIF 3.1415927F
72#define RT_LN_10 2.30258509299404568402
73#define RT_LN_10F 2.3025851F
74#define RT_LOG10E 0.43429448190325182765
75#define RT_LOG10EF 0.43429449F
76#define RT_E 2.7182818284590452354
77#define RT_EF 2.7182817F
78
79/*
80 * UNUSED_PARAMETER(x)
81 * Used to specify that a function parameter (argument) is required but not
82 * accessed by the function body.
83 */
84#ifndef UNUSED_PARAMETER
85#if defined(__LCC__)
86#define UNUSED_PARAMETER(x) /* do nothing */
87#else
88
89/*
90 * This is the semi-ANSI standard way of indicating that an
91 * unused function parameter is required.
92 */
93#define UNUSED_PARAMETER(x) (void) (x)
94#endif
95#endif
96
97/*
98 * Initialize rtNaN needed by the generated code.
99 * NaN is initialized as non-signaling. Assumes IEEE.
100 */
101static real_T rtGetNaN(void)
102{
103 size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar);
104 real_T nan = 0.0;
105 if (bitsPerReal == 32U) {
106 nan = rtGetNaNF();
107 } else {
108 union {
109 LittleEndianIEEEDouble bitVal;
110 real_T fltVal;
111 } tmpVal;
112
113 tmpVal.bitVal.words.wordH = 0xFFF80000U;
114 tmpVal.bitVal.words.wordL = 0x00000000U;
115 nan = tmpVal.fltVal;
116 }
117
118 return nan;
119}
120
121/*
122 * Initialize rtNaNF needed by the generated code.
123 * NaN is initialized as non-signaling. Assumes IEEE.
124 */
125static real32_T rtGetNaNF(void)
126{
127 IEEESingle nanF = { { 0 } };
128
129 nanF.wordL.wordLuint = 0xFFC00000U;
130 return nanF.wordL.wordLreal;
131}
132
133/*
134 * Initialize the rtInf, rtMinusInf, and rtNaN needed by the
135 * generated code. NaN is initialized as non-signaling. Assumes IEEE.
136 */
137static void rt_InitInfAndNaN(size_t realSize)
138{
139 (void) (realSize);
140 rtNaN = rtGetNaN();
141 rtNaNF = rtGetNaNF();
142 rtInf = rtGetInf();
143 rtInfF = rtGetInfF();
144 rtMinusInf = rtGetMinusInf();
145 rtMinusInfF = rtGetMinusInfF();
146}
147
148/* Test if value is infinite */
149static boolean_T rtIsInf(real_T value)
150{
151 return (boolean_T)((value==rtInf || value==rtMinusInf) ? 1U : 0U);
152}
153
154/* Test if single-precision value is infinite */
155static boolean_T rtIsInfF(real32_T value)
156{
157 return (boolean_T)(((value)==rtInfF || (value)==rtMinusInfF) ? 1U : 0U);
158}
159
160/* Test if value is not a number */
161static boolean_T rtIsNaN(real_T value)
162{
163 boolean_T result = (boolean_T) 0;
164 size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar);
165 if (bitsPerReal == 32U) {
166 result = rtIsNaNF((real32_T)value);
167 } else {
168 union {
169 LittleEndianIEEEDouble bitVal;
170 real_T fltVal;
171 } tmpVal;
172
173 tmpVal.fltVal = value;
174 result = (boolean_T)((tmpVal.bitVal.words.wordH & 0x7FF00000) == 0x7FF00000 &&
175 ( (tmpVal.bitVal.words.wordH & 0x000FFFFF) != 0 ||
176 (tmpVal.bitVal.words.wordL != 0) ));
177 }
178
179 return result;
180}
181
182/* Test if single-precision value is not a number */
183static boolean_T rtIsNaNF(real32_T value)
184{
185 IEEESingle tmp;
186 tmp.wordL.wordLreal = value;
187 return (boolean_T)( (tmp.wordL.wordLuint & 0x7F800000) == 0x7F800000 &&
188 (tmp.wordL.wordLuint & 0x007FFFFF) != 0 );
189}
190
191/*
192 * Initialize rtInf needed by the generated code.
193 * Inf is initialized as non-signaling. Assumes IEEE.
194 */
195static real_T rtGetInf(void)
196{
197 size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar);
198 real_T inf = 0.0;
199 if (bitsPerReal == 32U) {
200 inf = rtGetInfF();
201 } else {
202 union {
203 LittleEndianIEEEDouble bitVal;
204 real_T fltVal;
205 } tmpVal;
206
207 tmpVal.bitVal.words.wordH = 0x7FF00000U;
208 tmpVal.bitVal.words.wordL = 0x00000000U;
209 inf = tmpVal.fltVal;
210 }
211
212 return inf;
213}
214
215/*
216 * Initialize rtInfF needed by the generated code.
217 * Inf is initialized as non-signaling. Assumes IEEE.
218 */
219static real32_T rtGetInfF(void)
220{
221 IEEESingle infF;
222 infF.wordL.wordLuint = 0x7F800000U;
223 return infF.wordL.wordLreal;
224}
225
226/*
227 * Initialize rtMinusInf needed by the generated code.
228 * Inf is initialized as non-signaling. Assumes IEEE.
229 */
230static real_T rtGetMinusInf(void)
231{
232 size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar);
233 real_T minf = 0.0;
234 if (bitsPerReal == 32U) {
235 minf = rtGetMinusInfF();
236 } else {
237 union {
238 LittleEndianIEEEDouble bitVal;
239 real_T fltVal;
240 } tmpVal;
241
242 tmpVal.bitVal.words.wordH = 0xFFF00000U;
243 tmpVal.bitVal.words.wordL = 0x00000000U;
244 minf = tmpVal.fltVal;
245 }
246
247 return minf;
248}
249
250/*
251 * Initialize rtMinusInfF needed by the generated code.
252 * Inf is initialized as non-signaling. Assumes IEEE.
253 */
254static real32_T rtGetMinusInfF(void)
255{
256 IEEESingle minfF;
257 minfF.wordL.wordLuint = 0xFF800000U;
258 return minfF.wordL.wordLreal;
259}
260
261real_T rt_remd_snf(real_T u0, real_T u1)
262{
263 real_T q;
264 real_T y;
265 if (rtIsNaN(u0) || rtIsNaN(u1) || rtIsInf(u0)) {
266 y = (rtNaN);
267 } else if (rtIsInf(u1)) {
268 y = u0;
269 } else if ((u1 != 0.0) && (u1 != trunc(u1))) {
270 q = fabs(u0 / u1);
271 if (!(fabs(q - floor(q + 0.5)) > DBL_EPSILON * q)) {
272 y = 0.0 * u0;
273 } else {
274 y = fmod(u0, u1);
275 }
276 } else {
277 y = fmod(u0, u1);
278 }
279
280 return y;
281}
282
283/* Model step function */
284void SMO_arctan_PLL_step(RT_MODEL *const rtM, real_T rtU_Ialfabeta[2], real_T
285 rtU_Ualfabeta[2], real_T *rtY_theta, real_T *rtY_we)
286{
287 DW *rtDW = rtM->dwork;
288 real_T rtb_Add1;
289 real_T rtb_Add1_h;
290 real_T rtb_Product4;
291 real_T rtb_Sum;
292 real_T rtb_Sum2;
293 real_T rtb_Sum5;
294 real_T rtb_Switch_e;
295
296 /* Sum: '<S7>/Sum2' incorporates:
297 * DiscreteIntegrator: '<S7>/Discrete-Time Integrator'
298 * Inport: '<Root>/Ialfa,beta'
299 */
300 rtb_Sum2 = rtDW->DiscreteTimeIntegrator_DSTATE_e - rtU_Ialfabeta[0];
301
302 /* Switch: '<S58>/Switch' incorporates:
303 * Abs: '<S58>/Abs'
304 * Constant: '<S7>/Constant1'
305 * Constant: '<S7>/Constant3'
306 * Product: '<S58>/Divide'
307 * Product: '<S58>/Divide1'
308 * Product: '<S58>/Divide2'
309 * Sum: '<S58>/Add'
310 */
311 if (fabs(rtb_Sum2) - 120.0 > 0.0) {
312 /* Signum: '<S58>/Sign' */
313 if (rtb_Sum2 < 0.0) {
314 rtb_Sum2 = -1.0;
315 } else if (rtb_Sum2 > 0.0) {
316 rtb_Sum2 = 1.0;
317 } else if (rtb_Sum2 == 0.0) {
318 rtb_Sum2 = 0.0;
319 } else {
320 rtb_Sum2 = (rtNaN);
321 }
322
323 /* End of Signum: '<S58>/Sign' */
324 rtb_Sum2 *= 100.0;
325 } else {
326 rtb_Sum2 = rtb_Sum2 / 120.0 * 100.0;
327 }
328
329 /* End of Switch: '<S58>/Switch' */
330
331 /* Sum: '<S7>/Sum5' incorporates:
332 * DiscreteIntegrator: '<S7>/Discrete-Time Integrator1'
333 * Inport: '<Root>/Ialfa,beta'
334 */
335 rtb_Sum5 = rtDW->DiscreteTimeIntegrator1_DSTATE - rtU_Ialfabeta[1];
336
337 /* Switch: '<S57>/Switch' incorporates:
338 * Abs: '<S57>/Abs'
339 * Constant: '<S7>/Constant4'
340 * Constant: '<S7>/Constant5'
341 * Product: '<S57>/Divide'
342 * Product: '<S57>/Divide1'
343 * Product: '<S57>/Divide2'
344 * Sum: '<S57>/Add'
345 */
346 if (fabs(rtb_Sum5) - 120.0 > 0.0) {
347 /* Signum: '<S57>/Sign' */
348 if (rtb_Sum5 < 0.0) {
349 rtb_Sum5 = -1.0;
350 } else if (rtb_Sum5 > 0.0) {
351 rtb_Sum5 = 1.0;
352 } else if (rtb_Sum5 == 0.0) {
353 rtb_Sum5 = 0.0;
354 } else {
355 rtb_Sum5 = (rtNaN);
356 }
357
358 /* End of Signum: '<S57>/Sign' */
359 rtb_Switch_e = rtb_Sum5 * 100.0;
360 } else {
361 rtb_Switch_e = rtb_Sum5 / 120.0 * 100.0;
362 }
363
364 /* End of Switch: '<S57>/Switch' */
365
366 /* Sqrt: '<S6>/Sqrt' incorporates:
367 * Constant: '<S6>/Constant'
368 * Math: '<S6>/Math Function'
369 * Math: '<S6>/Math Function1'
370 * Sum: '<S6>/Add'
371 */
372 rtb_Sum5 = sqrt((rtb_Sum2 * rtb_Sum2 + rtb_Switch_e * rtb_Switch_e) + 1.0E-6);
373
374 /* Sum: '<S6>/Sum' incorporates:
375 * DiscreteIntegrator: '<S6>/Discrete-Time Integrator'
376 * Gain: '<S6>/Gain'
377 * Product: '<S6>/Divide'
378 * Product: '<S6>/Divide2'
379 * Product: '<S6>/Product'
380 * Product: '<S6>/Product1'
381 * Trigonometry: '<S6>/Trigonometric Function'
382 * Trigonometry: '<S6>/Trigonometric Function1'
383 */
384 rtb_Sum5 = -(rtb_Sum2 / rtb_Sum5) * cos(rtDW->DiscreteTimeIntegrator_DSTATE) -
385 rtb_Switch_e / rtb_Sum5 * sin(rtDW->DiscreteTimeIntegrator_DSTATE);
386
387 /* Sum: '<S49>/Sum' incorporates:
388 * DiscreteIntegrator: '<S40>/Integrator'
389 * Gain: '<S45>/Proportional Gain'
390 */
391 rtb_Sum = 12566.370614359172 * rtb_Sum5 + rtDW->Integrator_DSTATE;
392
393 /* Sum: '<S5>/Add1' incorporates:
394 * Constant: '<S5>/Filter_Constant'
395 * Constant: '<S5>/One'
396 * Product: '<S5>/Product'
397 * Product: '<S5>/Product1'
398 * UnitDelay: '<S5>/Unit Delay'
399 */
400 rtb_Add1 = rtb_Sum * 0.01885 + 0.98115 * rtDW->UnitDelay_DSTATE;
401
402 /* Sum: '<S4>/Add1' incorporates:
403 * Constant: '<S4>/Filter_Constant'
404 * Constant: '<S4>/One'
405 * Product: '<S4>/Product'
406 * Product: '<S4>/Product1'
407 * UnitDelay: '<S4>/Unit Delay'
408 */
409 rtb_Add1_h = rtb_Add1 * 0.1 + 0.9 * rtDW->UnitDelay_DSTATE_h;
410
411 /* Outport: '<Root>/we' incorporates:
412 * Constant: '<S1>/P'
413 * Gain: '<S1>/Gain3'
414 * Product: '<S1>/Divide1'
415 */
416 *rtY_we = 9.5492965855137211 * rtb_Add1_h / 4.0;
417
418 /* Product: '<S7>/Product4' incorporates:
419 * Constant: '<S7>/Constant2'
420 */
421 rtb_Product4 = rtb_Add1 * 0.000178;
422
423 /* Sum: '<S7>/ ' incorporates:
424 * DiscreteIntegrator: '<S7>/Discrete-Time Integrator'
425 * DiscreteIntegrator: '<S7>/Discrete-Time Integrator1'
426 * Gain: '<S7>/ 1//L'
427 * Gain: '<S7>/ 1//L '
428 * Gain: '<S7>/Gain5'
429 * Gain: '<S7>/R//L '
430 * Inport: '<Root>/Ualfa,beta'
431 * Product: '<S7>/Product3'
432 */
433 rtb_Switch_e = ((5617.9775280898875 * rtU_Ualfabeta[1] - 61.797752808988761 *
434 rtDW->DiscreteTimeIntegrator1_DSTATE) - 5617.9775280898875 *
435 rtb_Switch_e) + 5617.9775280898875 * rtb_Product4 *
436 rtDW->DiscreteTimeIntegrator_DSTATE_e;
437
438 /* Outport: '<Root>/theta' incorporates:
439 * Constant: '<S2>/Constant1'
440 * DiscreteIntegrator: '<S6>/Discrete-Time Integrator'
441 * Math: '<S2>/Rem1'
442 * Sum: '<S2>/Add1'
443 */
444 *rtY_theta = rt_remd_snf(rtDW->DiscreteTimeIntegrator_DSTATE +
445 6.2831853071795862, 6.2831853071795862);
446
447 /* Update for DiscreteIntegrator: '<S6>/Discrete-Time Integrator' */
448 rtDW->DiscreteTimeIntegrator_DSTATE += 6.0E-5 * rtb_Sum;
449
450 /* Update for DiscreteIntegrator: '<S7>/Discrete-Time Integrator' incorporates:
451 * DiscreteIntegrator: '<S7>/Discrete-Time Integrator1'
452 * Gain: '<S7>/1//L'
453 * Gain: '<S7>/1//L '
454 * Gain: '<S7>/Gain4'
455 * Gain: '<S7>/R//L'
456 * Inport: '<Root>/Ualfa,beta'
457 * Product: '<S7>/Product2'
458 * Sum: '<S7>/ '
459 */
460 rtDW->DiscreteTimeIntegrator_DSTATE_e += (((5617.9775280898875 *
461 rtU_Ualfabeta[0] - 61.797752808988761 *
462 rtDW->DiscreteTimeIntegrator_DSTATE_e) - 5617.9775280898875 * rtb_Sum2) -
463 5617.9775280898875 * rtb_Product4 * rtDW->DiscreteTimeIntegrator1_DSTATE) *
464 6.0E-5;
465
466 /* Update for DiscreteIntegrator: '<S7>/Discrete-Time Integrator1' */
467 rtDW->DiscreteTimeIntegrator1_DSTATE += 6.0E-5 * rtb_Switch_e;
468
469 /* Update for DiscreteIntegrator: '<S40>/Integrator' incorporates:
470 * Gain: '<S37>/Integral Gain'
471 */
472 rtDW->Integrator_DSTATE += 3.9478417604357429E+7 * rtb_Sum5 * 6.0E-5;
473
474 /* Update for UnitDelay: '<S5>/Unit Delay' */
475 rtDW->UnitDelay_DSTATE = rtb_Add1;
476
477 /* Update for UnitDelay: '<S4>/Unit Delay' */
478 rtDW->UnitDelay_DSTATE_h = rtb_Add1_h;
479}
480
481/* Model initialize function */
482void SMO_arctan_PLL_initialize(RT_MODEL *const rtM)
483{
484 /* Registration code */
485
486 /* initialize non-finites */
487 rt_InitInfAndNaN(sizeof(real_T));
488 UNUSED_PARAMETER(rtM);
489}
490
491/*
492 * File trailer for generated code.
493 *
494 * [EOF]
495 */
496