1/*
2 * PWM_sf.c
3 *
4 * Code generation for model "PWM_sf".
5 *
6 * Model version : 1.825
7 * Simulink Coder version : 9.4 (R2020b) 29-Jul-2020
8 * C source code generated on : Fri Apr 14 12:53:29 2023
9 *
10 * Target selection: rtwsfcn.tlc
11 * Note: GRT includes extra infrastructure and instrumentation for prototyping
12 * Embedded hardware selection: ARM Compatible->ARM Cortex-M
13 * Emulation hardware selection:
14 * Differs from embedded hardware (MATLAB Host)
15 * Code generation objectives:
16 * 1. Execution efficiency
17 * 2. RAM efficiency
18 * Validation result: Not run
19 */
20
21#include <math.h>
22#include "PWM_sf.h"
23#include "PWM_sf_private.h"
24#include "simstruc.h"
25#include "fixedpoint.h"
26#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)
27
28extern void *PWM_malloc(SimStruct *S);
29
30#endif
31
32#ifndef __RTW_UTFREE__
33#if defined (MATLAB_MEX_FILE)
34
35extern void * utMalloc(size_t);
36extern void utFree(void *);
37
38#endif
39#endif /* #ifndef __RTW_UTFREE__ */
40
41/* Forward declaration for local functions */
42static real_T PWM_rt_remd_snf(real_T u0, real_T u1);
43
44#if defined(MATLAB_MEX_FILE)
45#include "rt_nonfinite.c"
46#endif
47
48static const char_T *RT_MEMORY_ALLOCATION_ERROR =
49 "memory allocation error in generated S-Function";
50
51/*
52 * Time delay interpolation routine
53 *
54 * The linear interpolation is performed using the formula:
55 *
56 * (t2 - tMinusDelay) (tMinusDelay - t1)
57 * u(t) = ----------------- * u1 + ------------------- * u2
58 * (t2 - t1) (t2 - t1)
59 */
60real_T PWM_sf_rt_TDelayInterpolate(
61 real_T tMinusDelay, /* tMinusDelay = currentSimTime - delay */
62 real_T tStart,
63 real_T *tBuf,
64 real_T *uBuf,
65 int_T bufSz,
66 int_T *lastIdx,
67 int_T oldestIdx,
68 int_T newIdx,
69 real_T initOutput,
70 boolean_T discrete,
71 boolean_T minorStepAndTAtLastMajorOutput)
72{
73 int_T i;
74 real_T yout, t1, t2, u1, u2;
75
76 /*
77 * If there is only one data point in the buffer, this data point must be
78 * the t= 0 and tMinusDelay > t0, it ask for something unknown. The best
79 * guess if initial output as well
80 */
81 if ((newIdx == 0) && (oldestIdx ==0 ) && (tMinusDelay > tStart))
82 return initOutput;
83
84 /*
85 * If tMinusDelay is less than zero, should output initial value
86 */
87 if (tMinusDelay <= tStart)
88 return initOutput;
89
90 /* For fixed buffer extrapolation:
91 * if tMinusDelay is small than the time at oldestIdx, if discrete, output
92 * tailptr value, else use tailptr and tailptr+1 value to extrapolate
93 * It is also for fixed buffer. Note: The same condition can happen for transport delay block where
94 * use tStart and and t[tail] other than using t[tail] and t[tail+1].
95 * See below
96 */
97 if ((tMinusDelay <= tBuf[oldestIdx] ) ) {
98 if (discrete) {
99 return(uBuf[oldestIdx]);
100 } else {
101 int_T tempIdx= oldestIdx + 1;
102 if (oldestIdx == bufSz-1)
103 tempIdx = 0;
104 t1= tBuf[oldestIdx];
105 t2= tBuf[tempIdx];
106 u1= uBuf[oldestIdx];
107 u2= uBuf[tempIdx];
108 if (t2 == t1) {
109 if (tMinusDelay >= t2) {
110 yout = u2;
111 } else {
112 yout = u1;
113 }
114 } else {
115 real_T f1 = (t2-tMinusDelay) / (t2-t1);
116 real_T f2 = 1.0 - f1;
117
118 /*
119 * Use Lagrange's interpolation formula. Exact outputs at t1, t2.
120 */
121 yout = f1*u1 + f2*u2;
122 }
123
124 return yout;
125 }
126 }
127
128 /*
129 * When block does not have direct feedthrough, we use the table of
130 * values to extrapolate off the end of the table for delays that are less
131 * than 0 (less then step size). This is not completely accurate. The
132 * chain of events is as follows for a given time t. Major output - look
133 * in table. Update - add entry to table. Now, if we call the output at
134 * time t again, there is a new entry in the table. For very small delays,
135 * this means that we will have a different answer from the previous call
136 * to the output fcn at the same time t. The following code prevents this
137 * from happening.
138 */
139 if (minorStepAndTAtLastMajorOutput) {
140 /* pretend that the new entry has not been added to table */
141 if (newIdx != 0) {
142 if (*lastIdx == newIdx) {
143 (*lastIdx)--;
144 }
145
146 newIdx--;
147 } else {
148 if (*lastIdx == newIdx) {
149 *lastIdx = bufSz-1;
150 }
151
152 newIdx = bufSz - 1;
153 }
154 }
155
156 i = *lastIdx;
157 if (tBuf[i] < tMinusDelay) {
158 /* Look forward starting at last index */
159 while (tBuf[i] < tMinusDelay) {
160 /* May occur if the delay is less than step-size - extrapolate */
161 if (i == newIdx)
162 break;
163 i = ( i < (bufSz-1) ) ? (i+1) : 0;/* move through buffer */
164 }
165 } else {
166 /*
167 * Look backwards starting at last index which can happen when the
168 * delay time increases.
169 */
170 while (tBuf[i] >= tMinusDelay) {
171 /*
172 * Due to the entry condition at top of function, we
173 * should never hit the end.
174 */
175 i = (i > 0) ? i-1 : (bufSz-1); /* move through buffer */
176 }
177
178 i = ( i < (bufSz-1) ) ? (i+1) : 0;
179 }
180
181 *lastIdx = i;
182 if (discrete) {
183 /*
184 * tempEps = 128 * eps;
185 * localEps = max(tempEps, tempEps*fabs(tBuf[i]))/2;
186 */
187 double tempEps = (DBL_EPSILON) * 128.0;
188 double localEps = tempEps * fabs(tBuf[i]);
189 if (tempEps > localEps) {
190 localEps = tempEps;
191 }
192
193 localEps = localEps / 2.0;
194 if (tMinusDelay >= (tBuf[i] - localEps)) {
195 yout = uBuf[i];
196 } else {
197 if (i == 0) {
198 yout = uBuf[bufSz-1];
199 } else {
200 yout = uBuf[i-1];
201 }
202 }
203 } else {
204 if (i == 0) {
205 t1 = tBuf[bufSz-1];
206 u1 = uBuf[bufSz-1];
207 } else {
208 t1 = tBuf[i-1];
209 u1 = uBuf[i-1];
210 }
211
212 t2 = tBuf[i];
213 u2 = uBuf[i];
214 if (t2 == t1) {
215 if (tMinusDelay >= t2) {
216 yout = u2;
217 } else {
218 yout = u1;
219 }
220 } else {
221 real_T f1 = (t2-tMinusDelay) / (t2-t1);
222 real_T f2 = 1.0 - f1;
223
224 /*
225 * Use Lagrange's interpolation formula. Exact outputs at t1, t2.
226 */
227 yout = f1*u1 + f2*u2;
228 }
229 }
230
231 return(yout);
232}
233
234real_T PWM_look1_binlx(real_T u0, const real_T bp0[], const real_T table[],
235 uint32_T maxIndex)
236{
237 real_T frac;
238 real_T yL_0d0;
239 uint32_T bpIdx;
240 uint32_T iLeft;
241 uint32_T iRght;
242
243 /* Column-major Lookup 1-D
244 Search method: 'binary'
245 Use previous index: 'off'
246 Interpolation method: 'Linear point-slope'
247 Extrapolation method: 'Linear'
248 Use last breakpoint for index at or above upper limit: 'off'
249 Remove protection against out-of-range input in generated code: 'off'
250 */
251 /* Prelookup - Index and Fraction
252 Index Search method: 'binary'
253 Extrapolation method: 'Linear'
254 Use previous index: 'off'
255 Use last breakpoint for index at or above upper limit: 'off'
256 Remove protection against out-of-range input in generated code: 'off'
257 */
258 if (u0 <= bp0[0U]) {
259 iLeft = 0U;
260 frac = (u0 - bp0[0U]) / (bp0[1U] - bp0[0U]);
261 } else if (u0 < bp0[maxIndex]) {
262 /* Binary Search */
263 bpIdx = maxIndex >> 1U;
264 iLeft = 0U;
265 iRght = maxIndex;
266 while (iRght - iLeft > 1U) {
267 if (u0 < bp0[bpIdx]) {
268 iRght = bpIdx;
269 } else {
270 iLeft = bpIdx;
271 }
272
273 bpIdx = (iRght + iLeft) >> 1U;
274 }
275
276 frac = (u0 - bp0[iLeft]) / (bp0[iLeft + 1U] - bp0[iLeft]);
277 } else {
278 iLeft = maxIndex - 1U;
279 frac = (u0 - bp0[maxIndex - 1U]) / (bp0[maxIndex] - bp0[maxIndex - 1U]);
280 }
281
282 /* Column-major Interpolation 1-D
283 Interpolation method: 'Linear point-slope'
284 Use last breakpoint for index at or above upper limit: 'off'
285 Overflow mode: 'wrapping'
286 */
287 yL_0d0 = table[iLeft];
288 return (table[iLeft + 1U] - yL_0d0) * frac + yL_0d0;
289}
290
291static real_T PWM_rt_remd_snf(real_T u0, real_T u1)
292{
293 real_T q;
294 real_T y;
295 if (rtIsNaN(u0) || rtIsNaN(u1) || rtIsInf(u0)) {
296 y = (rtNaN);
297 } else if (rtIsInf(u1)) {
298 y = u0;
299 } else if ((u1 != 0.0) && (u1 != trunc(u1))) {
300 q = fabs(u0 / u1);
301 if (!(fabs(q - floor(q + 0.5)) > DBL_EPSILON * q)) {
302 y = 0.0 * u0;
303 } else {
304 y = fmod(u0, u1);
305 }
306 } else {
307 y = fmod(u0, u1);
308 }
309
310 return y;
311}
312
313/* Start for root system: '<Root>' */
314#define MDL_START
315
316static void mdlStart(SimStruct *S)
317{
318 /* instance underlying S-Function data */
319#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)
320#if defined(MATLAB_MEX_FILE)
321
322 /* non-finites */
323 rt_InitInfAndNaN(sizeof(real_T));
324
325 /* Check for invalid switching between solver types */
326 if (ssIsVariableStepSolver(S)) {
327 ssSetErrorStatus(S, "This Simulink Coder generated "
328 "S-Function cannot be used in a simulation with "
329 "a solver type of variable-step "
330 "because this S-Function was created from a model with "
331 "solver type of fixed-step and it has continuous time blocks. "
332 "See the Solver page of the simulation parameters dialog.");
333 return;
334 }
335
336 if (fabs(ssGetFixedStepSize(S) - 5.0E-7) > mxGetEps()*100*5.0E-7) {
337 ssSetErrorStatus(S, "This Simulink Coder generated "
338 "S-Function cannot be used in a simulation with "
339 "the current fixed step size "
340 "because this S-Function was created from a model with "
341 "a fixed step size of 5.0E-7 and had both "
342 "continuous blocks and discrete blocks running at this rate. "
343 "See the Solver page of the simulation parameters dialog.");
344 return;
345 }
346
347#endif
348
349 PWM_malloc(S);
350 if (ssGetErrorStatus(S) != (NULL) ) {
351 return;
352 }
353
354#endif
355
356 {
357 B_PWM_T *_rtB;
358 _rtB = ((B_PWM_T *) ssGetLocalBlockIO(S));
359
360 /* Start for TransportDelay: '<S2>/Transport Delay' */
361 {
362 real_T *pBuffer = &((real_T*) ssGetDWork(S, 0))[1];
363 ((int_T*) ssGetDWork(S, 6))[0] = 0;
364 ((int_T*) ssGetDWork(S, 6))[1] = 0;
365 ((int_T*) ssGetDWork(S, 6))[2] = 0;
366 ((int_T*) ssGetDWork(S, 6))[3] = 1024;
367 pBuffer[0] = 0.0;
368 pBuffer[1024] = ssGetT(S);
369 ((void**) ssGetDWork(S, 3))[0] = (void *) &pBuffer[0];
370 ((void**) ssGetDWork(S, 3))[1] = (void *) &pBuffer[1024];
371 }
372
373 /* Start for TransportDelay: '<S2>/Transport Delay1' */
374 {
375 real_T *pBuffer = &((real_T*) ssGetDWork(S, 1))[1];
376 ((int_T*) ssGetDWork(S, 7))[0] = 0;
377 ((int_T*) ssGetDWork(S, 7))[1] = 0;
378 ((int_T*) ssGetDWork(S, 7))[2] = 0;
379 ((int_T*) ssGetDWork(S, 7))[3] = 1024;
380 pBuffer[0] = 0.0;
381 pBuffer[1024] = ssGetT(S);
382 ((void**) ssGetDWork(S, 4))[0] = (void *) &pBuffer[0];
383 ((void**) ssGetDWork(S, 4))[1] = (void *) &pBuffer[1024];
384 }
385
386 /* Start for TransportDelay: '<S2>/Transport Delay2' */
387 {
388 real_T *pBuffer = &((real_T*) ssGetDWork(S, 2))[1];
389 ((int_T*) ssGetDWork(S, 8))[0] = 0;
390 ((int_T*) ssGetDWork(S, 8))[1] = 0;
391 ((int_T*) ssGetDWork(S, 8))[2] = 0;
392 ((int_T*) ssGetDWork(S, 8))[3] = 1024;
393 pBuffer[0] = 0.0;
394 pBuffer[1024] = ssGetT(S);
395 ((void**) ssGetDWork(S, 5))[0] = (void *) &pBuffer[0];
396 ((void**) ssGetDWork(S, 5))[1] = (void *) &pBuffer[1024];
397 }
398 }
399}
400
401/* Outputs for root system: '<Root>' */
402static void mdlOutputs(SimStruct *S, int_T tid)
403{
404 /* local block i/o variables */
405 real_T rtb_TransportDelay1;
406 real_T rtb_TransportDelay2;
407 real_T rtb_TransportDelay;
408 B_PWM_T *_rtB;
409 real_T expr_2_0_0;
410 real_T rtb_Abs;
411 real_T rtb_Abs2;
412 boolean_T rtb_RelationalOperator;
413 boolean_T rtb_RelationalOperator1;
414 boolean_T rtb_RelationalOperator2;
415 _rtB = ((B_PWM_T *) ssGetLocalBlockIO(S));
416 if (ssIsContinuousTask(S, tid)) {
417 /* S-Function (sfun_tstart): '<S3>/startTime' */
418 /* S-Function Block (sfun_tstart): <S3>/startTime */
419 expr_2_0_0 = ssGetTStart(S);
420
421 /* Lookup_n-D: '<S3>/Look-Up Table1' incorporates:
422 * Clock: '<S3>/Clock'
423 * Constant: '<S3>/Constant'
424 * Math: '<S3>/Math Function'
425 * Sum: '<S3>/Sum'
426 */
427 expr_2_0_0 = PWM_look1_binlx(PWM_rt_remd_snf(ssGetT(S) - expr_2_0_0, 0.0001),
428 PWM_ConstP.LookUpTable1_bp01Data, PWM_ConstP.LookUpTable1_tableData, 2U);
429
430 /* RelationalOperator: '<S2>/Relational Operator' */
431 rtb_RelationalOperator = (expr_2_0_0 > *((const real_T **)
432 ssGetInputPortSignalPtrs(S, 0))[0]);
433
434 /* TransportDelay: '<S2>/Transport Delay' */
435 {
436 real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 3))[0];
437 real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 3))[1];
438 real_T simTime = ssGetT(S);
439 real_T tMinusDelay = simTime - 2.0E-6;
440 rtb_TransportDelay = PWM_sf_rt_TDelayInterpolate(
441 tMinusDelay,
442 0.0,
443 *tBuffer,
444 *uBuffer,
445 ((int_T*) ssGetDWork(S, 6))[3],
446 &((int_T*) ssGetDWork(S, 6))[2],
447 ((int_T*) ssGetDWork(S, 6))[0],
448 ((int_T*) ssGetDWork(S, 6))[1],
449 0.0,
450 0,
451 (boolean_T) (ssIsMinorTimeStep(S) && (ssGetTimeOfLastOutput(S) == ssGetT
452 (S))));
453 }
454
455 /* DataTypeConversion: '<S2>/Data Type Conversion3' incorporates:
456 * Logic: '<S2>/Logical Operator'
457 */
458 rtb_Abs2 = !rtb_RelationalOperator;
459
460 /* Abs: '<S2>/Abs' incorporates:
461 * DataTypeConversion: '<S2>/Data Type Conversion3'
462 * Sum: '<S2>/Subtract'
463 */
464 rtb_Abs = fabs(rtb_Abs2 - rtb_TransportDelay);
465
466 /* Product: '<S2>/Product' */
467 _rtB->Product = rtb_Abs2 * rtb_Abs;
468
469 /* Product: '<S2>/Product1' */
470 _rtB->Product1 = rtb_Abs * rtb_TransportDelay;
471
472 /* RelationalOperator: '<S2>/Relational Operator1' */
473 rtb_RelationalOperator1 = (expr_2_0_0 > *((const real_T **)
474 ssGetInputPortSignalPtrs(S, 0))[1]);
475
476 /* TransportDelay: '<S2>/Transport Delay1' */
477 {
478 real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 4))[0];
479 real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 4))[1];
480 real_T simTime = ssGetT(S);
481 real_T tMinusDelay = simTime - 2.0E-6;
482 rtb_TransportDelay1 = PWM_sf_rt_TDelayInterpolate(
483 tMinusDelay,
484 0.0,
485 *tBuffer,
486 *uBuffer,
487 ((int_T*) ssGetDWork(S, 7))[3],
488 &((int_T*) ssGetDWork(S, 7))[2],
489 ((int_T*) ssGetDWork(S, 7))[0],
490 ((int_T*) ssGetDWork(S, 7))[1],
491 0.0,
492 0,
493 (boolean_T) (ssIsMinorTimeStep(S) && (ssGetTimeOfLastOutput(S) == ssGetT
494 (S))));
495 }
496
497 /* RelationalOperator: '<S2>/Relational Operator2' */
498 rtb_RelationalOperator2 = (expr_2_0_0 > *((const real_T **)
499 ssGetInputPortSignalPtrs(S, 0))[2]);
500
501 /* TransportDelay: '<S2>/Transport Delay2' */
502 {
503 real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 5))[0];
504 real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 5))[1];
505 real_T simTime = ssGetT(S);
506 real_T tMinusDelay = simTime - 2.0E-6;
507 rtb_TransportDelay2 = PWM_sf_rt_TDelayInterpolate(
508 tMinusDelay,
509 0.0,
510 *tBuffer,
511 *uBuffer,
512 ((int_T*) ssGetDWork(S, 8))[3],
513 &((int_T*) ssGetDWork(S, 8))[2],
514 ((int_T*) ssGetDWork(S, 8))[0],
515 ((int_T*) ssGetDWork(S, 8))[1],
516 0.0,
517 0,
518 (boolean_T) (ssIsMinorTimeStep(S) && (ssGetTimeOfLastOutput(S) == ssGetT
519 (S))));
520 }
521
522 /* DataTypeConversion: '<S2>/Data Type Conversion1' incorporates:
523 * Logic: '<S2>/Logical Operator1'
524 * ManualSwitch: '<S1>/Manual Switch'
525 */
526 rtb_Abs2 = !rtb_RelationalOperator1;
527
528 /* Abs: '<S2>/Abs1' incorporates:
529 * DataTypeConversion: '<S2>/Data Type Conversion1'
530 * ManualSwitch: '<S1>/Manual Switch'
531 * Sum: '<S2>/Subtract1'
532 */
533 expr_2_0_0 = fabs(rtb_Abs2 - rtb_TransportDelay1);
534
535 /* Outport: '<Root>/PWMb' incorporates:
536 * ManualSwitch: '<S1>/Manual Switch'
537 * Product: '<S2>/Product2'
538 * Product: '<S2>/Product3'
539 */
540 ((real_T *)ssGetOutputPortSignal(S, 0))[2] = rtb_Abs2 * expr_2_0_0;
541 ((real_T *)ssGetOutputPortSignal(S, 0))[3] = expr_2_0_0 *
542 rtb_TransportDelay1;
543
544 /* DataTypeConversion: '<S2>/Data Type Conversion5' incorporates:
545 * Logic: '<S2>/Logical Operator2'
546 * ManualSwitch: '<S1>/Manual Switch'
547 */
548 expr_2_0_0 = !rtb_RelationalOperator2;
549
550 /* Abs: '<S2>/Abs2' incorporates:
551 * ManualSwitch: '<S1>/Manual Switch'
552 * Sum: '<S2>/Subtract2'
553 */
554 rtb_Abs2 = fabs(expr_2_0_0 - rtb_TransportDelay2);
555
556 /* Outport: '<Root>/PWMb' incorporates:
557 * ManualSwitch: '<S1>/Manual Switch'
558 * Product: '<S2>/Product4'
559 * Product: '<S2>/Product5'
560 */
561 ((real_T *)ssGetOutputPortSignal(S, 0))[0] = _rtB->Product;
562 ((real_T *)ssGetOutputPortSignal(S, 0))[1] = _rtB->Product1;
563 ((real_T *)ssGetOutputPortSignal(S, 0))[4] = expr_2_0_0 * rtb_Abs2;
564 ((real_T *)ssGetOutputPortSignal(S, 0))[5] = rtb_Abs2 * rtb_TransportDelay2;
565
566 /* DataTypeConversion: '<S2>/Data Type Conversion6' */
567 _rtB->DataTypeConversion6 = rtb_RelationalOperator2;
568
569 /* DataTypeConversion: '<S2>/Data Type Conversion2' */
570 _rtB->DataTypeConversion2 = rtb_RelationalOperator1;
571 }
572
573 if (ssIsSampleHit(S, 1, tid)) {
574 }
575
576 if (ssIsContinuousTask(S, tid)) {
577 /* DataTypeConversion: '<S2>/Data Type Conversion4' */
578 _rtB->DataTypeConversion4 = rtb_RelationalOperator;
579 }
580
581 UNUSED_PARAMETER(tid);
582}
583
584/* Update for root system: '<Root>' */
585#define MDL_UPDATE
586
587static void mdlUpdate(SimStruct *S, int_T tid)
588{
589 B_PWM_T *_rtB;
590 _rtB = ((B_PWM_T *) ssGetLocalBlockIO(S));
591 if (ssIsContinuousTask(S, tid)) {
592 /* Update for TransportDelay: '<S2>/Transport Delay' */
593 {
594 real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 3))[0];
595 real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 3))[1];
596 real_T simTime = ssGetT(S);
597 ((int_T*) ssGetDWork(S, 6))[1] = ((((int_T*) ssGetDWork(S, 6))[1] <
598 (((int_T*) ssGetDWork(S, 6))[3]-1)) ? (((int_T*) ssGetDWork(S, 6))[1]+1)
599 : 0);
600 if (((int_T*) ssGetDWork(S, 6))[1] == ((int_T*) ssGetDWork(S, 6))[0]) {
601 ((int_T*) ssGetDWork(S, 6))[0] = ((((int_T*) ssGetDWork(S, 6))[0] <
602 (((int_T*) ssGetDWork(S, 6))[3]-1)) ? (((int_T*) ssGetDWork(S, 6))[0]+
603 1) : 0);
604 }
605
606 (*tBuffer)[((int_T*) ssGetDWork(S, 6))[1]] = simTime;
607 (*uBuffer)[((int_T*) ssGetDWork(S, 6))[1]] = _rtB->DataTypeConversion4;
608 }
609
610 /* Update for TransportDelay: '<S2>/Transport Delay1' */
611 {
612 real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 4))[0];
613 real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 4))[1];
614 real_T simTime = ssGetT(S);
615 ((int_T*) ssGetDWork(S, 7))[1] = ((((int_T*) ssGetDWork(S, 7))[1] <
616 (((int_T*) ssGetDWork(S, 7))[3]-1)) ? (((int_T*) ssGetDWork(S, 7))[1]+1)
617 : 0);
618 if (((int_T*) ssGetDWork(S, 7))[1] == ((int_T*) ssGetDWork(S, 7))[0]) {
619 ((int_T*) ssGetDWork(S, 7))[0] = ((((int_T*) ssGetDWork(S, 7))[0] <
620 (((int_T*) ssGetDWork(S, 7))[3]-1)) ? (((int_T*) ssGetDWork(S, 7))[0]+
621 1) : 0);
622 }
623
624 (*tBuffer)[((int_T*) ssGetDWork(S, 7))[1]] = simTime;
625 (*uBuffer)[((int_T*) ssGetDWork(S, 7))[1]] = _rtB->DataTypeConversion2;
626 }
627
628 /* Update for TransportDelay: '<S2>/Transport Delay2' */
629 {
630 real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 5))[0];
631 real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 5))[1];
632 real_T simTime = ssGetT(S);
633 ((int_T*) ssGetDWork(S, 8))[1] = ((((int_T*) ssGetDWork(S, 8))[1] <
634 (((int_T*) ssGetDWork(S, 8))[3]-1)) ? (((int_T*) ssGetDWork(S, 8))[1]+1)
635 : 0);
636 if (((int_T*) ssGetDWork(S, 8))[1] == ((int_T*) ssGetDWork(S, 8))[0]) {
637 ((int_T*) ssGetDWork(S, 8))[0] = ((((int_T*) ssGetDWork(S, 8))[0] <
638 (((int_T*) ssGetDWork(S, 8))[3]-1)) ? (((int_T*) ssGetDWork(S, 8))[0]+
639 1) : 0);
640 }
641
642 (*tBuffer)[((int_T*) ssGetDWork(S, 8))[1]] = simTime;
643 (*uBuffer)[((int_T*) ssGetDWork(S, 8))[1]] = _rtB->DataTypeConversion6;
644 }
645 }
646
647 UNUSED_PARAMETER(tid);
648}
649
650/* Termination for root system: '<Root>' */
651static void mdlTerminate(SimStruct *S)
652{
653 B_PWM_T *_rtB;
654 _rtB = ((B_PWM_T *) ssGetLocalBlockIO(S));
655
656#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)
657
658 if (ssGetUserData(S) != (NULL) ) {
659 rt_FREE(ssGetLocalBlockIO(S));
660 }
661
662 rt_FREE(ssGetUserData(S));
663
664#endif
665
666}
667
668#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)
669#include "PWM_mid.h"
670#endif
671
672/* Function to initialize sizes. */
673static void mdlInitializeSizes(SimStruct *S)
674{
675 ssSetNumSampleTimes(S, 2); /* Number of sample times */
676 ssSetNumContStates(S, 0); /* Number of continuous states */
677 ssSetNumNonsampledZCs(S, 0); /* Number of nonsampled ZCs */
678
679 /* Number of output ports */
680 if (!ssSetNumOutputPorts(S, 1))
681 return;
682
683 /* outport number: 0 */
684 if (!ssSetOutputPortVectorDimension(S, 0, 6))
685 return;
686 if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) {
687 ssSetOutputPortDataType(S, 0, SS_DOUBLE);
688 }
689
690 ssSetOutputPortSampleTime(S, 0, 0.0);
691 ssSetOutputPortOffsetTime(S, 0, 0.0);
692 ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
693
694 /* Number of input ports */
695 if (!ssSetNumInputPorts(S, 1))
696 return;
697
698 /* inport number: 0 */
699 {
700 if (!ssSetInputPortVectorDimension(S, 0, 3))
701 return;
702 if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) {
703 ssSetInputPortDataType(S, 0, SS_DOUBLE);
704 }
705
706 ssSetInputPortDirectFeedThrough(S, 0, 1);
707 ssSetInputPortSampleTime(S, 0, 5.0E-7);
708 ssSetInputPortOffsetTime(S, 0, 0.0);
709 ssSetInputPortOverWritable(S, 0, 0);
710 ssSetInputPortOptimOpts(S, 0, SS_NOT_REUSABLE_AND_GLOBAL);
711 }
712
713 ssSetRTWGeneratedSFcn(S, 1); /* Generated S-function */
714
715 /* DWork */
716 if (!ssSetNumDWork(S, 9)) {
717 return;
718 }
719
720 /* '<S2>/Transport Delay': RWORK */
721 ssSetDWorkName(S, 0, "DWORK0");
722 ssSetDWorkWidth(S, 0, 2049);
723
724 /* '<S2>/Transport Delay1': RWORK */
725 ssSetDWorkName(S, 1, "DWORK1");
726 ssSetDWorkWidth(S, 1, 2049);
727
728 /* '<S2>/Transport Delay2': RWORK */
729 ssSetDWorkName(S, 2, "DWORK2");
730 ssSetDWorkWidth(S, 2, 2049);
731
732 /* '<S2>/Transport Delay': PWORK */
733 ssSetDWorkName(S, 3, "DWORK3");
734 ssSetDWorkWidth(S, 3, 2);
735 ssSetDWorkDataType(S, 3, SS_POINTER);
736
737 /* '<S2>/Transport Delay1': PWORK */
738 ssSetDWorkName(S, 4, "DWORK4");
739 ssSetDWorkWidth(S, 4, 2);
740 ssSetDWorkDataType(S, 4, SS_POINTER);
741
742 /* '<S2>/Transport Delay2': PWORK */
743 ssSetDWorkName(S, 5, "DWORK5");
744 ssSetDWorkWidth(S, 5, 2);
745 ssSetDWorkDataType(S, 5, SS_POINTER);
746
747 /* '<S2>/Transport Delay': IWORK */
748 ssSetDWorkName(S, 6, "DWORK6");
749 ssSetDWorkWidth(S, 6, 4);
750 ssSetDWorkDataType(S, 6, SS_INTEGER);
751
752 /* '<S2>/Transport Delay1': IWORK */
753 ssSetDWorkName(S, 7, "DWORK7");
754 ssSetDWorkWidth(S, 7, 4);
755 ssSetDWorkDataType(S, 7, SS_INTEGER);
756
757 /* '<S2>/Transport Delay2': IWORK */
758 ssSetDWorkName(S, 8, "DWORK8");
759 ssSetDWorkWidth(S, 8, 4);
760 ssSetDWorkDataType(S, 8, SS_INTEGER);
761
762 /* Tunable Parameters */
763 ssSetNumSFcnParams(S, 0);
764
765 /* Number of expected parameters */
766#if defined(MATLAB_MEX_FILE)
767
768 if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
769
770#if defined(MDL_CHECK_PARAMETERS)
771
772 mdlCheckParameters(S);
773
774#endif /* MDL_CHECK_PARAMETERS */
775
776 if (ssGetErrorStatus(S) != (NULL) ) {
777 return;
778 }
779 } else {
780 return; /* Parameter mismatch will be reported by Simulink */
781 }
782
783#endif /* MATLAB_MEX_FILE */
784
785 /* Options */
786 ssSetOptions(S, (SS_OPTION_RUNTIME_EXCEPTION_FREE_CODE |
787 SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED ));
788
789#if SS_SFCN_FOR_SIM
790
791 {
792 ssSupportsMultipleExecInstances(S, false);
793 ssRegisterMsgForNotSupportingMultiExecInst(S,
794 "<diag_root><diag id=\"Simulink:blocks:BlockDoesNotSupportMultiExecInstances\" pr=\"d\"><arguments><arg type=\"encoded\">UABXAE0ALwBQAFcATQAvAG0AbwBkAHUAbABhAHQAZQBkACAAdwBhAHYAZQAvAHMAdABhAHIAdABUAGkAbQBlAAAA</arg><arg type=\"encoded\">PABfAF8AaQBpAFMAUwBfAF8APgA8AC8AXwBfAGkAaQBTAFMAXwBfAD4AAAA=</arg><arg type=\"encoded\">PABfAF8AaQB0AGUAcgBCAGwAawBfAF8APgA8AC8AXwBfAGkAdABlAHIAQgBsAGsAXwBfAD4AAAA=</arg></arguments><hs><h>AAAACIDlzUD+</h></hs></diag></diag_root>");
795 ssHasStateInsideForEachSS(S, false);
796 }
797
798#endif
799
800}
801
802/* Function to initialize sample times. */
803static void mdlInitializeSampleTimes(SimStruct *S)
804{
805 /* task periods */
806 ssSetSampleTime(S, 0, 0.0);
807 ssSetSampleTime(S, 1, 5.0E-7);
808
809 /* task offsets */
810 ssSetOffsetTime(S, 0, 0.0);
811 ssSetOffsetTime(S, 1, 0.0);
812}
813
814#if defined(MATLAB_MEX_FILE)
815#include "fixedpoint.c"
816#include "simulink.c"
817#else
818#undef S_FUNCTION_NAME
819#define S_FUNCTION_NAME PWM_sf
820#include "cg_sfun.h"
821#endif /* defined(MATLAB_MEX_FILE) */
822