PWM_sf.c 25 KB

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