| 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 | |
| 21 | extern real_T rt_remd_snf(real_T u0, real_T u1); |
| 22 | static real_T rtGetNaN(void); |
| 23 | static real32_T rtGetNaNF(void); |
| 24 | extern real_T rtInf; |
| 25 | extern real_T rtMinusInf; |
| 26 | extern real_T rtNaN; |
| 27 | extern real32_T rtInfF; |
| 28 | extern real32_T rtMinusInfF; |
| 29 | extern real32_T rtNaNF; |
| 30 | static void rt_InitInfAndNaN(size_t realSize); |
| 31 | static boolean_T rtIsInf(real_T value); |
| 32 | static boolean_T rtIsInfF(real32_T value); |
| 33 | static boolean_T rtIsNaN(real_T value); |
| 34 | static boolean_T rtIsNaNF(real32_T value); |
| 35 | typedef struct { |
| 36 | struct { |
| 37 | uint32_T wordH; |
| 38 | uint32_T wordL; |
| 39 | } words; |
| 40 | } BigEndianIEEEDouble; |
| 41 | |
| 42 | typedef struct { |
| 43 | struct { |
| 44 | uint32_T wordL; |
| 45 | uint32_T wordH; |
| 46 | } words; |
| 47 | } LittleEndianIEEEDouble; |
| 48 | |
| 49 | typedef struct { |
| 50 | union { |
| 51 | real32_T wordLreal; |
| 52 | uint32_T wordLuint; |
| 53 | } wordL; |
| 54 | } IEEESingle; |
| 55 | |
| 56 | real_T rtInf; |
| 57 | real_T rtMinusInf; |
| 58 | real_T rtNaN; |
| 59 | real32_T rtInfF; |
| 60 | real32_T rtMinusInfF; |
| 61 | real32_T rtNaNF; |
| 62 | static real_T rtGetInf(void); |
| 63 | static real32_T rtGetInfF(void); |
| 64 | static real_T rtGetMinusInf(void); |
| 65 | static 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 | */ |
| 101 | static 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 | */ |
| 125 | static 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 | */ |
| 137 | static 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 */ |
| 149 | static 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 */ |
| 155 | static 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 */ |
| 161 | static 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 */ |
| 183 | static 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 | */ |
| 195 | static 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 | */ |
| 219 | static 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 | */ |
| 230 | static 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 | */ |
| 254 | static real32_T rtGetMinusInfF(void) |
| 255 | { |
| 256 | IEEESingle minfF; |
| 257 | minfF.wordL.wordLuint = 0xFF800000U; |
| 258 | return minfF.wordL.wordLreal; |
| 259 | } |
| 260 | |
| 261 | real_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 */ |
| 284 | void 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 */ |
| 482 | void 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 | |