This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320F28379D: How to implement time delay for a signal?

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Hello,

I am working with TMS320F28379D. Basically, I implemented an algorithm in MATLAB/Simulink where I used transport delay block in my simulation model. And I am trying to implement the same algorithm where I can give a time delay to a signal instead of transport delay block. So, I just want to know if I can implement the same algorithm in Code Composer Studio where it works the same as the transport delay block.

Please let me know.

Best Regards

Rachana

  • Hi Rachana,

    Can you give us an idea on what was the time delay (constant/variable) introduced by TDB in matlab?

    Regards,
    Gautam
  • Hi Rachana,

    Your answer to Gautam's question would help us better understand the delay functionality you're seeking for.

    I've provided below the functions already developed in C2000Ware for F2837xD that delay a specified number of microseconds or cycle counts in case it's helpful.

    For bit-field code (fixed microsecond delay): the macro DELAY_US(A) defined in F2837xD_Examples.h (found in C:\ti\c2000\C2000Ware_1_00_03_00\device_support\f2837xd\common\include)

    For Driverlib code (fixed cycle count delay): SysCtl_delay(uint32_t count) defined in sysctl.h (found in C:\ti\c2000\C2000Ware_1_00_03_00\driverlib\f2837xd\driverlib)

    Regards,
    Elizabeth
  • Hi Gautam,

    Thanks for taking time to reply me back.

    I am using multiple TDB blocks in my Simulink model and I am giving a time delays of (1/240; 1/720; 1/1200; 1/1680; 1/2160; 1/2640 for those TDBs blocks.

    It would really help me a lot if you can give an idea on how to do the same in Code Composer Studio.

    Best Regards

    Rachana

  • Rachana Dasari said:
    I am using multiple TDB blocks in my Simulink model and I am giving a time delays of (1/240; 1/720; 1/1200; 1/1680; 1/2160; 1/2640 for those TDBs blocks.

    For  simple delays you can refer to what Lizzie has mentioned above. Are you looking for something similar to mentioned in the link?

    Regards,

    Gautam

  • Hi Rachana,

    Was either Gautam's or my suggestions helpful in answering your question? If so, can you please mark the helpful replies with the "This resolved my issue" button? If not, can you provide an update on your development regarding the delays? Thanks.

    Regards,
    Elizabeth
  • Hi Elizabeth,

    I am trying to find out an example of how to implement TDB block in code composer studio according to your reply 

    (F2837xD_Examples.h (found in C:\ti\c2000\C2000Ware_1_00_03_00\device_support\f2837xd\common\include)

    But I was not able to figure out on how to implement the transport delay in code composer studio. Could you please give me a little more idea on how to implement it.

    Best Regards

    Rachana

  • Hi Rachana,

    You can call the DELAY_US macro with specified number of microseconds to delay.
    For example:
    DELAY_US (100); // delay of 100 microseconds

    Regards,
    Elizabeth
  • Hi Elizabeth,

    I was not able to figure out the problem. I thought it would be better if I can take a screenshot of my Simulink Model and ask you for the example code. I have attached my Simulink file and the input signal is considered as, y = 170*cos(u)-10*sin(u)-14*cos(3*u)-40*sin(3*u)+1.8*cos(5*u); And for the transport delay blocks, I am giving a delay of 1/120; 1/360; 1/600 with an initial buffer size of 1024.

    Could you please help me to figure out on how to implement the same in Code Composer Studio. Could you provide me an example if possible? Please have a look at the attached file and let me know if you need any info!

    Thanks and Regards

    Rachana

  • Hi Rachana,

    Other than the method of using the DELAY_US macro, I'm unfortunately not aware of other example code for this. One suggestion would be to look at the code generated for this model by MathWorks and see if you can port it to a CCS project.

    Regards,
    Elizabeth
  • Hi Rachana,

    Elizabeth has a good point - MathWorks Embedded Coder will generate the needed C code for your Simulink model including the transport delays,and you can take that C code and import it into your CCS project. 

    We also have some special C2000 specific support -> you can learn about that here: https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/484814

    Cheers,

    -Brian

  • Hi Brian and Elizabeth,

    Thanks for your patience to reply me back.

    As you said I tried to generate the code from Simulink and imported the code into Code Composer Studio. But it is popping up some errors and I believe that the code generated from Simulink is not that appropriate.

    I am attaching the code that is generated from the Simulink. Please have a look at it and let me know if this is the appropriate code for my algorithm.

    /*
    2 * simple.c
    3 *
    4 * Academic License - for use in teaching, academic research, and meeting
    5 * course requirements at degree granting institutions only. Not for
    6 * government, commercial, or other organizational use.
    7 *
    8 * Code generation for model "simple".
    9 *
    10 * Model version : 1.1
    11 * Simulink Coder version : 8.12 (R2017a) 16-Feb-2017
    12 * C source code generated on : Mon Apr 02 13:25:52 2018
    13 *
    14 * Target selection: grt.tlc
    15 * Note: GRT includes extra infrastructure and instrumentation for prototyping
    16 * Embedded hardware selection: Intel->x86-64 (Windows64)
    17 * Code generation objectives: Unspecified
    18 * Validation result: Not run
    19 */
    20
    21 #include "simple.h"
    22 #include "simple_private.h"
    23
    24 /* Block signals (auto storage) */
    25 B_simple_T simple_B;
    26
    27 /* Block states (auto storage) */
    28 DW_simple_T simple_DW;
    29
    30 /* External outputs (root outports fed by signals with auto storage) */
    31 ExtY_simple_T simple_Y;
    32
    33 /* Real-time model */
    34 RT_MODEL_simple_T simple_M_;
    35 RT_MODEL_simple_T *const simple_M = &simple_M_;
    36
    37 /*
    38 * Time delay interpolation routine
    39 *
    40 * The linear interpolation is performed using the formula:
    41 *
    42 * (t2 - tMinusDelay) (tMinusDelay - t1)
    43 * u(t) = ----------------- * u1 + ------------------- * u2
    44 * (t2 - t1) (t2 - t1)
    45 */
    46 real_T rt_TDelayInterpolate(
    47 real_T tMinusDelay, /* tMinusDelay = currentSimTime - delay */
    48 real_T tStart,
    49 real_T *tBuf,
    50 real_T *uBuf,
    51 int_T bufSz,
    52 int_T *lastIdx,
    53 int_T oldestIdx,
    54 int_T newIdx,
    55 real_T initOutput,
    56 boolean_T discrete,
    57 boolean_T minorStepAndTAtLastMajorOutput)
    58 {
    59 int_T i;
    60 real_T yout, t1, t2, u1, u2;
    61
    62 /*
    63 * If there is only one data point in the buffer, this data point must be
    64 * the t= 0 and tMinusDelay > t0, it ask for something unknown. The best
    65 * guess if initial output as well
    66 */
    67 if ((newIdx == 0) && (oldestIdx ==0 ) && (tMinusDelay > tStart))
    68 return initOutput;
    69
    70 /*
    71 * If tMinusDelay is less than zero, should output initial value
    72 */
    73 if (tMinusDelay <= tStart)
    74 return initOutput;
    75
    76 /* For fixed buffer extrapolation:
    77 * if tMinusDelay is small than the time at oldestIdx, if discrete, output
    78 * tailptr value, else use tailptr and tailptr+1 value to extrapolate
    79 * It is also for fixed buffer. Note: The same condition can happen for transport delay block where
    80 * use tStart and and t[tail] other than using t[tail] and t[tail+1].
    81 * See below
    82 */
    83 if ((tMinusDelay <= tBuf[oldestIdx] ) ) {
    84 if (discrete) {
    85 return(uBuf[oldestIdx]);
    86 } else {
    87 int_T tempIdx= oldestIdx + 1;
    88 if (oldestIdx == bufSz-1)
    89 tempIdx = 0;
    90 t1= tBuf[oldestIdx];
    91 t2= tBuf[tempIdx];
    92 u1= uBuf[oldestIdx];
    93 u2= uBuf[tempIdx];
    94 if (t2 == t1) {
    95 if (tMinusDelay >= t2) {
    96 yout = u2;
    97 } else {
    98 yout = u1;
    99 }
    100 } else {
    101 real_T f1 = (t2-tMinusDelay) / (t2-t1);
    102 real_T f2 = 1.0 - f1;
    103
    104 /*
    105 * Use Lagrange's interpolation formula. Exact outputs at t1, t2.
    106 */
    107 yout = f1*u1 + f2*u2;
    108 }
    109
    110 return yout;
    111 }
    112 }
    113
    114 /*
    115 * When block does not have direct feedthrough, we use the table of
    116 * values to extrapolate off the end of the table for delays that are less
    117 * than 0 (less then step size). This is not completely accurate. The
    118 * chain of events is as follows for a given time t. Major output - look
    119 * in table. Update - add entry to table. Now, if we call the output at
    120 * time t again, there is a new entry in the table. For very small delays,
    121 * this means that we will have a different answer from the previous call
    122 * to the output fcn at the same time t. The following code prevents this
    123 * from happening.
    124 */
    125 if (minorStepAndTAtLastMajorOutput) {
    126 /* pretend that the new entry has not been added to table */
    127 if (newIdx != 0) {
    128 if (*lastIdx == newIdx) {
    129 (*lastIdx)--;
    130 }
    131
    132 newIdx--;
    133 } else {
    134 if (*lastIdx == newIdx) {
    135 *lastIdx = bufSz-1;
    136 }
    137
    138 newIdx = bufSz - 1;
    139 }
    140 }
    141
    142 i = *lastIdx;
    143 if (tBuf[i] < tMinusDelay) {
    144 /* Look forward starting at last index */
    145 while (tBuf[i] < tMinusDelay) {
    146 /* May occur if the delay is less than step-size - extrapolate */
    147 if (i == newIdx)
    148 break;
    149 i = ( i < (bufSz-1) ) ? (i+1) : 0;/* move through buffer */
    150 }
    151 } else {
    152 /*
    153 * Look backwards starting at last index which can happen when the
    154 * delay time increases.
    155 */
    156 while (tBuf[i] >= tMinusDelay) {
    157 /*
    158 * Due to the entry condition at top of function, we
    159 * should never hit the end.
    160 */
    161 i = (i > 0) ? i-1 : (bufSz-1); /* move through buffer */
    162 }
    163
    164 i = ( i < (bufSz-1) ) ? (i+1) : 0;
    165 }
    166
    167 *lastIdx = i;
    168 if (discrete) {
    169 /*
    170 * tempEps = 128 * eps;
    171 * localEps = max(tempEps, tempEps*fabs(tBuf[i]))/2;
    172 */
    173 double tempEps = (DBL_EPSILON) * 128.0;
    174 double localEps = tempEps * fabs(tBuf[i]);
    175 if (tempEps > localEps) {
    176 localEps = tempEps;
    177 }
    178
    179 localEps = localEps / 2.0;
    180 if (tMinusDelay >= (tBuf[i] - localEps)) {
    181 yout = uBuf[i];
    182 } else {
    183 if (i == 0) {
    184 yout = uBuf[bufSz-1];
    185 } else {
    186 yout = uBuf[i-1];
    187 }
    188 }
    189 } else {
    190 if (i == 0) {
    191 t1 = tBuf[bufSz-1];
    192 u1 = uBuf[bufSz-1];
    193 } else {
    194 t1 = tBuf[i-1];
    195 u1 = uBuf[i-1];
    196 }
    197
    198 t2 = tBuf[i];
    199 u2 = uBuf[i];
    200 if (t2 == t1) {
    201 if (tMinusDelay >= t2) {
    202 yout = u2;
    203 } else {
    204 yout = u1;
    205 }
    206 } else {
    207 real_T f1 = (t2-tMinusDelay) / (t2-t1);
    208 real_T f2 = 1.0 - f1;
    209
    210 /*
    211 * Use Lagrange's interpolation formula. Exact outputs at t1, t2.
    212 */
    213 yout = f1*u1 + f2*u2;
    214 }
    215 }
    216
    217 return(yout);
    218 }
    219
    220 /* Model step function */
    221 void simple_step(void)
    222 {
    223 /* local block i/o variables */
    224 real_T rtb_Sum1;
    225 real_T rtb_Sum2;
    226 real_T rtb_TransportDelay2;
    227 real_T rtb_TransportDelay1;
    228 real_T rtb_TransportDelay;
    229 real_T rtb_Gain9;
    230
    231 /* TransportDelay: '<Root>/Transport Delay2' */
    232 {
    233 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay2_PWORK.TUbufferPtrs[0];
    234 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay2_PWORK.TUbufferPtrs[1];
    235 real_T simTime = simple_M->Timing.t[0];
    236 real_T tMinusDelay = simTime - (simple_P.TransportDelay2_Delay);
    237 rtb_TransportDelay2 = rt_TDelayInterpolate(
    238 tMinusDelay,
    239 0.0,
    240 *tBuffer,
    241 *uBuffer,
    242 simple_DW.TransportDelay2_IWORK.CircularBufSize,
    243 &simple_DW.TransportDelay2_IWORK.Last,
    244 simple_DW.TransportDelay2_IWORK.Tail,
    245 simple_DW.TransportDelay2_IWORK.Head,
    246 simple_P.TransportDelay2_InitOutput,
    247 0,
    248 0);
    249 }
    250
    251 /* TransportDelay: '<Root>/Transport Delay1' */
    252 {
    253 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay1_PWORK.TUbufferPtrs[0];
    254 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay1_PWORK.TUbufferPtrs[1];
    255 real_T simTime = simple_M->Timing.t[0];
    256 real_T tMinusDelay = simTime - (simple_P.TransportDelay1_Delay);
    257 rtb_TransportDelay1 = rt_TDelayInterpolate(
    258 tMinusDelay,
    259 0.0,
    260 *tBuffer,
    261 *uBuffer,
    262 simple_DW.TransportDelay1_IWORK.CircularBufSize,
    263 &simple_DW.TransportDelay1_IWORK.Last,
    264 simple_DW.TransportDelay1_IWORK.Tail,
    265 simple_DW.TransportDelay1_IWORK.Head,
    266 simple_P.TransportDelay1_InitOutput,
    267 0,
    268 0);
    269 }
    270
    271 /* TransportDelay: '<Root>/Transport Delay' */
    272 {
    273 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay_PWORK.TUbufferPtrs[0];
    274 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay_PWORK.TUbufferPtrs[1];
    275 real_T simTime = simple_M->Timing.t[0];
    276 real_T tMinusDelay = simTime - (simple_P.TransportDelay_Delay);
    277 rtb_TransportDelay = rt_TDelayInterpolate(
    278 tMinusDelay,
    279 0.0,
    280 *tBuffer,
    281 *uBuffer,
    282 simple_DW.TransportDelay_IWORK.CircularBufSize,
    283 &simple_DW.TransportDelay_IWORK.Last,
    284 simple_DW.TransportDelay_IWORK.Tail,
    285 simple_DW.TransportDelay_IWORK.Head,
    286 simple_P.TransportDelay_InitOutput,
    287 0,
    288 0);
    289 }
    290
    291 /* Gain: '<Root>/Gain9' incorporates:
    292 * Clock: '<Root>/Clock'
    293 */
    294 rtb_Gain9 = simple_P.Gain9_Gain * simple_M->Timing.t[0];
    295
    296 /* MATLAB Function: '<Root>/MATLAB Function' */
    297 /* MATLAB Function 'MATLAB Function': '<S1>:1' */
    298 /* '<S1>:1:4' */
    299 simple_B.y = (((170.0 * cos(rtb_Gain9) - 10.0 * sin(rtb_Gain9)) - cos(3.0 *
    300 rtb_Gain9) * 14.0) - sin(3.0 * rtb_Gain9) * 40.0) + cos(5.0 * rtb_Gain9) *
    301 1.8;
    302
    303 /* Sum: '<Root>/Sum1' */
    304 rtb_Sum1 = simple_B.y - rtb_TransportDelay;
    305
    306 /* Sum: '<Root>/Sum2' */
    307 rtb_Sum2 = rtb_TransportDelay1 + rtb_Sum1;
    308
    309 /* Outport: '<Root>/Out1' incorporates:
    310 * Sum: '<Root>/Sum5'
    311 */
    312 simple_Y.Out1 = rtb_TransportDelay2 + rtb_Sum2;
    313
    314 /* Matfile logging */
    315 rt_UpdateTXYLogVars(simple_M->rtwLogInfo, (simple_M->Timing.t));
    316
    317 /* Update for TransportDelay: '<Root>/Transport Delay2' */
    318 {
    319 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay2_PWORK.TUbufferPtrs[0];
    320 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay2_PWORK.TUbufferPtrs[1];
    321 real_T simTime = simple_M->Timing.t[0];
    322 simple_DW.TransportDelay2_IWORK.Head =
    323 ((simple_DW.TransportDelay2_IWORK.Head <
    324 (simple_DW.TransportDelay2_IWORK.CircularBufSize-1)) ?
    325 (simple_DW.TransportDelay2_IWORK.Head+1) : 0);
    326 if (simple_DW.TransportDelay2_IWORK.Head ==
    327 simple_DW.TransportDelay2_IWORK.Tail) {
    328 simple_DW.TransportDelay2_IWORK.Tail =
    329 ((simple_DW.TransportDelay2_IWORK.Tail <
    330 (simple_DW.TransportDelay2_IWORK.CircularBufSize-1)) ?
    331 (simple_DW.TransportDelay2_IWORK.Tail+1) : 0);
    332 }
    333
    334 (*tBuffer)[simple_DW.TransportDelay2_IWORK.Head] = simTime;
    335 (*uBuffer)[simple_DW.TransportDelay2_IWORK.Head] = rtb_Sum2;
    336 }
    337
    338 /* Update for TransportDelay: '<Root>/Transport Delay1' */
    339 {
    340 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay1_PWORK.TUbufferPtrs[0];
    341 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay1_PWORK.TUbufferPtrs[1];
    342 real_T simTime = simple_M->Timing.t[0];
    343 simple_DW.TransportDelay1_IWORK.Head =
    344 ((simple_DW.TransportDelay1_IWORK.Head <
    345 (simple_DW.TransportDelay1_IWORK.CircularBufSize-1)) ?
    346 (simple_DW.TransportDelay1_IWORK.Head+1) : 0);
    347 if (simple_DW.TransportDelay1_IWORK.Head ==
    348 simple_DW.TransportDelay1_IWORK.Tail) {
    349 simple_DW.TransportDelay1_IWORK.Tail =
    350 ((simple_DW.TransportDelay1_IWORK.Tail <
    351 (simple_DW.TransportDelay1_IWORK.CircularBufSize-1)) ?
    352 (simple_DW.TransportDelay1_IWORK.Tail+1) : 0);
    353 }
    354
    355 (*tBuffer)[simple_DW.TransportDelay1_IWORK.Head] = simTime;
    356 (*uBuffer)[simple_DW.TransportDelay1_IWORK.Head] = rtb_Sum1;
    357 }
    358
    359 /* Update for TransportDelay: '<Root>/Transport Delay' */
    360 {
    361 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay_PWORK.TUbufferPtrs[0];
    362 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay_PWORK.TUbufferPtrs[1];
    363 real_T simTime = simple_M->Timing.t[0];
    364 simple_DW.TransportDelay_IWORK.Head = ((simple_DW.TransportDelay_IWORK.Head <
    365 (simple_DW.TransportDelay_IWORK.CircularBufSize-1)) ?
    366 (simple_DW.TransportDelay_IWORK.Head+1) : 0);
    367 if (simple_DW.TransportDelay_IWORK.Head ==
    368 simple_DW.TransportDelay_IWORK.Tail) {
    369 simple_DW.TransportDelay_IWORK.Tail =
    370 ((simple_DW.TransportDelay_IWORK.Tail <
    371 (simple_DW.TransportDelay_IWORK.CircularBufSize-1)) ?
    372 (simple_DW.TransportDelay_IWORK.Tail+1) : 0);
    373 }
    374
    375 (*tBuffer)[simple_DW.TransportDelay_IWORK.Head] = simTime;
    376 (*uBuffer)[simple_DW.TransportDelay_IWORK.Head] = simple_B.y;
    377 }
    378
    379 /* signal main to stop simulation */
    380 { /* Sample time: [0.0s, 0.0s] */
    381 if ((rtmGetTFinal(simple_M)!=-1) &&
    382 !((rtmGetTFinal(simple_M)-simple_M->Timing.t[0]) > simple_M->Timing.t[0]
    383 * (DBL_EPSILON))) {
    384 rtmSetErrorStatus(simple_M, "Simulation finished");
    385 }
    386 }
    387
    388 /* Update absolute time for base rate */
    389 /* The "clockTick0" counts the number of times the code of this task has
    390 * been executed. The absolute time is the multiplication of "clockTick0"
    391 * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
    392 * overflow during the application lifespan selected.
    393 * Timer of this task consists of two 32 bit unsigned integers.
    394 * The two integers represent the low bits Timing.clockTick0 and the high bits
    395 * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
    396 */
    397 if (!(++simple_M->Timing.clockTick0)) {
    398 ++simple_M->Timing.clockTickH0;
    399 }
    400
    401 simple_M->Timing.t[0] = simple_M->Timing.clockTick0 *
    402 simple_M->Timing.stepSize0 + simple_M->Timing.clockTickH0 *
    403 simple_M->Timing.stepSize0 * 4294967296.0;
    404 }
    405
    406 /* Model initialize function */
    407 void simple_initialize(void)
    408 {
    409 /* Registration code */
    410
    411 /* initialize non-finites */
    412 rt_InitInfAndNaN(sizeof(real_T));
    413
    414 /* initialize real-time model */
    415 (void) memset((void *)simple_M, 0,
    416 sizeof(RT_MODEL_simple_T));
    417
    418 {
    419 /* Setup solver object */
    420 rtsiSetSimTimeStepPtr(&simple_M->solverInfo, &simple_M->Timing.simTimeStep);
    421 rtsiSetTPtr(&simple_M->solverInfo, &rtmGetTPtr(simple_M));
    422 rtsiSetStepSizePtr(&simple_M->solverInfo, &simple_M->Timing.stepSize0);
    423 rtsiSetErrorStatusPtr(&simple_M->solverInfo, (&rtmGetErrorStatus(simple_M)));
    424 rtsiSetRTModelPtr(&simple_M->solverInfo, simple_M);
    425 }
    426
    427 rtsiSetSimTimeStep(&simple_M->solverInfo, MAJOR_TIME_STEP);
    428 rtsiSetSolverName(&simple_M->solverInfo,"FixedStepDiscrete");
    429 rtmSetTPtr(simple_M, &simple_M->Timing.tArray[0]);
    430 rtmSetTFinal(simple_M, 10.0);
    431 simple_M->Timing.stepSize0 = 0.2;
    432
    433 /* Setup for data logging */
    434 {
    435 static RTWLogInfo rt_DataLoggingInfo;
    436 rt_DataLoggingInfo.loggingInterval = NULL;
    437 simple_M->rtwLogInfo = &rt_DataLoggingInfo;
    438 }
    439
    440 /* Setup for data logging */
    441 {
    442 rtliSetLogXSignalInfo(simple_M->rtwLogInfo, (NULL));
    443 rtliSetLogXSignalPtrs(simple_M->rtwLogInfo, (NULL));
    444 rtliSetLogT(simple_M->rtwLogInfo, "tout");
    445 rtliSetLogX(simple_M->rtwLogInfo, "");
    446 rtliSetLogXFinal(simple_M->rtwLogInfo, "");
    447 rtliSetLogVarNameModifier(simple_M->rtwLogInfo, "rt_");
    448 rtliSetLogFormat(simple_M->rtwLogInfo, 4);
    449 rtliSetLogMaxRows(simple_M->rtwLogInfo, 0);
    450 rtliSetLogDecimation(simple_M->rtwLogInfo, 1);
    451 rtliSetLogY(simple_M->rtwLogInfo, "");
    452 rtliSetLogYSignalInfo(simple_M->rtwLogInfo, (NULL));
    453 rtliSetLogYSignalPtrs(simple_M->rtwLogInfo, (NULL));
    454 }
    455
    456 /* block I/O */
    457 (void) memset(((void *) &simple_B), 0,
    458 sizeof(B_simple_T));
    459
    460 /* states (dwork) */
    461 (void) memset((void *)&simple_DW, 0,
    462 sizeof(DW_simple_T));
    463
    464 /* external outputs */
    465 simple_Y.Out1 = 0.0;
    466
    467 /* Matfile logging */
    468 rt_StartDataLoggingWithStartTime(simple_M->rtwLogInfo, 0.0, rtmGetTFinal
    469 (simple_M), simple_M->Timing.stepSize0, (&rtmGetErrorStatus(simple_M)));
    470
    471 /* Start for TransportDelay: '<Root>/Transport Delay2' */
    472 {
    473 real_T *pBuffer = &simple_DW.TransportDelay2_RWORK.TUbufferArea[0];
    474 simple_DW.TransportDelay2_IWORK.Tail = 0;
    475 simple_DW.TransportDelay2_IWORK.Head = 0;
    476 simple_DW.TransportDelay2_IWORK.Last = 0;
    477 simple_DW.TransportDelay2_IWORK.CircularBufSize = 1024;
    478 pBuffer[0] = simple_P.TransportDelay2_InitOutput;
    479 pBuffer[1024] = simple_M->Timing.t[0];
    480 simple_DW.TransportDelay2_PWORK.TUbufferPtrs[0] = (void *) &pBuffer[0];
    481 simple_DW.TransportDelay2_PWORK.TUbufferPtrs[1] = (void *) &pBuffer[1024];
    482 }
    483
    484 /* Start for TransportDelay: '<Root>/Transport Delay1' */
    485 {
    486 real_T *pBuffer = &simple_DW.TransportDelay1_RWORK.TUbufferArea[0];
    487 simple_DW.TransportDelay1_IWORK.Tail = 0;
    488 simple_DW.TransportDelay1_IWORK.Head = 0;
    489 simple_DW.TransportDelay1_IWORK.Last = 0;
    490 simple_DW.TransportDelay1_IWORK.CircularBufSize = 1024;
    491 pBuffer[0] = simple_P.TransportDelay1_InitOutput;
    492 pBuffer[1024] = simple_M->Timing.t[0];
    493 simple_DW.TransportDelay1_PWORK.TUbufferPtrs[0] = (void *) &pBuffer[0];
    494 simple_DW.TransportDelay1_PWORK.TUbufferPtrs[1] = (void *) &pBuffer[1024];
    495 }
    496
    497 /* Start for TransportDelay: '<Root>/Transport Delay' */
    498 {
    499 real_T *pBuffer = &simple_DW.TransportDelay_RWORK.TUbufferArea[0];
    500 simple_DW.TransportDelay_IWORK.Tail = 0;
    501 simple_DW.TransportDelay_IWORK.Head = 0;
    502 simple_DW.TransportDelay_IWORK.Last = 0;
    503 simple_DW.TransportDelay_IWORK.CircularBufSize = 1024;
    504 pBuffer[0] = simple_P.TransportDelay_InitOutput;
    505 pBuffer[1024] = simple_M->Timing.t[0];
    506 simple_DW.TransportDelay_PWORK.TUbufferPtrs[0] = (void *) &pBuffer[0];
    507 simple_DW.TransportDelay_PWORK.TUbufferPtrs[1] = (void *) &pBuffer[1024];
    508 }
    509 }
    510
    511 /* Model terminate function */
    512 void simple_terminate(void)
    513 {
    514 /* (no terminate code required) */
    515 }

  • Hi Brain and Elizabeth,

    Thanks for your patience in replying me back.
    As per your advice, I tried to generate the code form Simulink and imported the code to Code Composer Studio but it popped up some errors. I am attaching the generated code from Simulink.

    Please have a look at it and let me know if this code is appropriate for my algorithm.



    21 #include "simple.h"
    22 #include "simple_private.h"
    23
    24 /* Block signals (auto storage) */
    25 B_simple_T simple_B;
    26
    27 /* Block states (auto storage) */
    28 DW_simple_T simple_DW;
    29
    30 /* External outputs (root outports fed by signals with auto storage) */
    31 ExtY_simple_T simple_Y;
    32
    33 /* Real-time model */
    34 RT_MODEL_simple_T simple_M_;
    35 RT_MODEL_simple_T *const simple_M = &simple_M_;
    36
    37 /*
    38 * Time delay interpolation routine
    39 *
    40 * The linear interpolation is performed using the formula:
    41 *
    42 * (t2 - tMinusDelay) (tMinusDelay - t1)
    43 * u(t) = ----------------- * u1 + ------------------- * u2
    44 * (t2 - t1) (t2 - t1)
    45 */
    46 real_T rt_TDelayInterpolate(
    47 real_T tMinusDelay, /* tMinusDelay = currentSimTime - delay */
    48 real_T tStart,
    49 real_T *tBuf,
    50 real_T *uBuf,
    51 int_T bufSz,
    52 int_T *lastIdx,
    53 int_T oldestIdx,
    54 int_T newIdx,
    55 real_T initOutput,
    56 boolean_T discrete,
    57 boolean_T minorStepAndTAtLastMajorOutput)
    58 {
    59 int_T i;
    60 real_T yout, t1, t2, u1, u2;
    61
    62 /*
    63 * If there is only one data point in the buffer, this data point must be
    64 * the t= 0 and tMinusDelay > t0, it ask for something unknown. The best
    65 * guess if initial output as well
    66 */
    67 if ((newIdx == 0) && (oldestIdx ==0 ) && (tMinusDelay > tStart))
    68 return initOutput;
    69
    70 /*
    71 * If tMinusDelay is less than zero, should output initial value
    72 */
    73 if (tMinusDelay <= tStart)
    74 return initOutput;
    75
    76 /* For fixed buffer extrapolation:
    77 * if tMinusDelay is small than the time at oldestIdx, if discrete, output
    78 * tailptr value, else use tailptr and tailptr+1 value to extrapolate
    79 * It is also for fixed buffer. Note: The same condition can happen for transport delay block where
    80 * use tStart and and t[tail] other than using t[tail] and t[tail+1].
    81 * See below
    82 */
    83 if ((tMinusDelay <= tBuf[oldestIdx] ) ) {
    84 if (discrete) {
    85 return(uBuf[oldestIdx]);
    86 } else {
    87 int_T tempIdx= oldestIdx + 1;
    88 if (oldestIdx == bufSz-1)
    89 tempIdx = 0;
    90 t1= tBuf[oldestIdx];
    91 t2= tBuf[tempIdx];
    92 u1= uBuf[oldestIdx];
    93 u2= uBuf[tempIdx];
    94 if (t2 == t1) {
    95 if (tMinusDelay >= t2) {
    96 yout = u2;
    97 } else {
    98 yout = u1;
    99 }
    100 } else {
    101 real_T f1 = (t2-tMinusDelay) / (t2-t1);
    102 real_T f2 = 1.0 - f1;
    103
    104 /*
    105 * Use Lagrange's interpolation formula. Exact outputs at t1, t2.
    106 */
    107 yout = f1*u1 + f2*u2;
    108 }
    109
    110 return yout;
    111 }
    112 }
    113
    114 /*
    115 * When block does not have direct feedthrough, we use the table of
    116 * values to extrapolate off the end of the table for delays that are less
    117 * than 0 (less then step size). This is not completely accurate. The
    118 * chain of events is as follows for a given time t. Major output - look
    119 * in table. Update - add entry to table. Now, if we call the output at
    120 * time t again, there is a new entry in the table. For very small delays,
    121 * this means that we will have a different answer from the previous call
    122 * to the output fcn at the same time t. The following code prevents this
    123 * from happening.
    124 */
    125 if (minorStepAndTAtLastMajorOutput) {
    126 /* pretend that the new entry has not been added to table */
    127 if (newIdx != 0) {
    128 if (*lastIdx == newIdx) {
    129 (*lastIdx)--;
    130 }
    131
    132 newIdx--;
    133 } else {
    134 if (*lastIdx == newIdx) {
    135 *lastIdx = bufSz-1;
    136 }
    137
    138 newIdx = bufSz - 1;
    139 }
    140 }
    141
    142 i = *lastIdx;
    143 if (tBuf[i] < tMinusDelay) {
    144 /* Look forward starting at last index */
    145 while (tBuf[i] < tMinusDelay) {
    146 /* May occur if the delay is less than step-size - extrapolate */
    147 if (i == newIdx)
    148 break;
    149 i = ( i < (bufSz-1) ) ? (i+1) : 0;/* move through buffer */
    150 }
    151 } else {
    152 /*
    153 * Look backwards starting at last index which can happen when the
    154 * delay time increases.
    155 */
    156 while (tBuf[i] >= tMinusDelay) {
    157 /*
    158 * Due to the entry condition at top of function, we
    159 * should never hit the end.
    160 */
    161 i = (i > 0) ? i-1 : (bufSz-1); /* move through buffer */
    162 }
    163
    164 i = ( i < (bufSz-1) ) ? (i+1) : 0;
    165 }
    166
    167 *lastIdx = i;
    168 if (discrete) {
    169 /*
    170 * tempEps = 128 * eps;
    171 * localEps = max(tempEps, tempEps*fabs(tBuf[i]))/2;
    172 */
    173 double tempEps = (DBL_EPSILON) * 128.0;
    174 double localEps = tempEps * fabs(tBuf[i]);
    175 if (tempEps > localEps) {
    176 localEps = tempEps;
    177 }
    178
    179 localEps = localEps / 2.0;
    180 if (tMinusDelay >= (tBuf[i] - localEps)) {
    181 yout = uBuf[i];
    182 } else {
    183 if (i == 0) {
    184 yout = uBuf[bufSz-1];
    185 } else {
    186 yout = uBuf[i-1];
    187 }
    188 }
    189 } else {
    190 if (i == 0) {
    191 t1 = tBuf[bufSz-1];
    192 u1 = uBuf[bufSz-1];
    193 } else {
    194 t1 = tBuf[i-1];
    195 u1 = uBuf[i-1];
    196 }
    197
    198 t2 = tBuf[i];
    199 u2 = uBuf[i];
    200 if (t2 == t1) {
    201 if (tMinusDelay >= t2) {
    202 yout = u2;
    203 } else {
    204 yout = u1;
    205 }
    206 } else {
    207 real_T f1 = (t2-tMinusDelay) / (t2-t1);
    208 real_T f2 = 1.0 - f1;
    209
    210 /*
    211 * Use Lagrange's interpolation formula. Exact outputs at t1, t2.
    212 */
    213 yout = f1*u1 + f2*u2;
    214 }
    215 }
    216
    217 return(yout);
    218 }
    219
    220 /* Model step function */
    221 void simple_step(void)
    222 {
    223 /* local block i/o variables */
    224 real_T rtb_Sum1;
    225 real_T rtb_Sum2;
    226 real_T rtb_TransportDelay2;
    227 real_T rtb_TransportDelay1;
    228 real_T rtb_TransportDelay;
    229 real_T rtb_Gain9;
    230
    231 /* TransportDelay: '<Root>/Transport Delay2' */
    232 {
    233 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay2_PWORK.TUbufferPtrs[0];
    234 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay2_PWORK.TUbufferPtrs[1];
    235 real_T simTime = simple_M->Timing.t[0];
    236 real_T tMinusDelay = simTime - (simple_P.TransportDelay2_Delay);
    237 rtb_TransportDelay2 = rt_TDelayInterpolate(
    238 tMinusDelay,
    239 0.0,
    240 *tBuffer,
    241 *uBuffer,
    242 simple_DW.TransportDelay2_IWORK.CircularBufSize,
    243 &simple_DW.TransportDelay2_IWORK.Last,
    244 simple_DW.TransportDelay2_IWORK.Tail,
    245 simple_DW.TransportDelay2_IWORK.Head,
    246 simple_P.TransportDelay2_InitOutput,
    247 0,
    248 0);
    249 }
    250
    251 /* TransportDelay: '<Root>/Transport Delay1' */
    252 {
    253 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay1_PWORK.TUbufferPtrs[0];
    254 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay1_PWORK.TUbufferPtrs[1];
    255 real_T simTime = simple_M->Timing.t[0];
    256 real_T tMinusDelay = simTime - (simple_P.TransportDelay1_Delay);
    257 rtb_TransportDelay1 = rt_TDelayInterpolate(
    258 tMinusDelay,
    259 0.0,
    260 *tBuffer,
    261 *uBuffer,
    262 simple_DW.TransportDelay1_IWORK.CircularBufSize,
    263 &simple_DW.TransportDelay1_IWORK.Last,
    264 simple_DW.TransportDelay1_IWORK.Tail,
    265 simple_DW.TransportDelay1_IWORK.Head,
    266 simple_P.TransportDelay1_InitOutput,
    267 0,
    268 0);
    269 }
    270
    271 /* TransportDelay: '<Root>/Transport Delay' */
    272 {
    273 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay_PWORK.TUbufferPtrs[0];
    274 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay_PWORK.TUbufferPtrs[1];
    275 real_T simTime = simple_M->Timing.t[0];
    276 real_T tMinusDelay = simTime - (simple_P.TransportDelay_Delay);
    277 rtb_TransportDelay = rt_TDelayInterpolate(
    278 tMinusDelay,
    279 0.0,
    280 *tBuffer,
    281 *uBuffer,
    282 simple_DW.TransportDelay_IWORK.CircularBufSize,
    283 &simple_DW.TransportDelay_IWORK.Last,
    284 simple_DW.TransportDelay_IWORK.Tail,
    285 simple_DW.TransportDelay_IWORK.Head,
    286 simple_P.TransportDelay_InitOutput,
    287 0,
    288 0);
    289 }
    290
    291 /* Gain: '<Root>/Gain9' incorporates:
    292 * Clock: '<Root>/Clock'
    293 */
    294 rtb_Gain9 = simple_P.Gain9_Gain * simple_M->Timing.t[0];
    295
    296 /* MATLAB Function: '<Root>/MATLAB Function' */
    297 /* MATLAB Function 'MATLAB Function': '<S1>:1' */
    298 /* '<S1>:1:4' */
    299 simple_B.y = (((170.0 * cos(rtb_Gain9) - 10.0 * sin(rtb_Gain9)) - cos(3.0 *
    300 rtb_Gain9) * 14.0) - sin(3.0 * rtb_Gain9) * 40.0) + cos(5.0 * rtb_Gain9) *
    301 1.8;
    302
    303 /* Sum: '<Root>/Sum1' */
    304 rtb_Sum1 = simple_B.y - rtb_TransportDelay;
    305
    306 /* Sum: '<Root>/Sum2' */
    307 rtb_Sum2 = rtb_TransportDelay1 + rtb_Sum1;
    308
    309 /* Outport: '<Root>/Out1' incorporates:
    310 * Sum: '<Root>/Sum5'
    311 */
    312 simple_Y.Out1 = rtb_TransportDelay2 + rtb_Sum2;
    313
    314 /* Matfile logging */
    315 rt_UpdateTXYLogVars(simple_M->rtwLogInfo, (simple_M->Timing.t));
    316
    317 /* Update for TransportDelay: '<Root>/Transport Delay2' */
    318 {
    319 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay2_PWORK.TUbufferPtrs[0];
    320 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay2_PWORK.TUbufferPtrs[1];
    321 real_T simTime = simple_M->Timing.t[0];
    322 simple_DW.TransportDelay2_IWORK.Head =
    323 ((simple_DW.TransportDelay2_IWORK.Head <
    324 (simple_DW.TransportDelay2_IWORK.CircularBufSize-1)) ?
    325 (simple_DW.TransportDelay2_IWORK.Head+1) : 0);
    326 if (simple_DW.TransportDelay2_IWORK.Head ==
    327 simple_DW.TransportDelay2_IWORK.Tail) {
    328 simple_DW.TransportDelay2_IWORK.Tail =
    329 ((simple_DW.TransportDelay2_IWORK.Tail <
    330 (simple_DW.TransportDelay2_IWORK.CircularBufSize-1)) ?
    331 (simple_DW.TransportDelay2_IWORK.Tail+1) : 0);
    332 }
    333
    334 (*tBuffer)[simple_DW.TransportDelay2_IWORK.Head] = simTime;
    335 (*uBuffer)[simple_DW.TransportDelay2_IWORK.Head] = rtb_Sum2;
    336 }
    337
    338 /* Update for TransportDelay: '<Root>/Transport Delay1' */
    339 {
    340 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay1_PWORK.TUbufferPtrs[0];
    341 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay1_PWORK.TUbufferPtrs[1];
    342 real_T simTime = simple_M->Timing.t[0];
    343 simple_DW.TransportDelay1_IWORK.Head =
    344 ((simple_DW.TransportDelay1_IWORK.Head <
    345 (simple_DW.TransportDelay1_IWORK.CircularBufSize-1)) ?
    346 (simple_DW.TransportDelay1_IWORK.Head+1) : 0);
    347 if (simple_DW.TransportDelay1_IWORK.Head ==
    348 simple_DW.TransportDelay1_IWORK.Tail) {
    349 simple_DW.TransportDelay1_IWORK.Tail =
    350 ((simple_DW.TransportDelay1_IWORK.Tail <
    351 (simple_DW.TransportDelay1_IWORK.CircularBufSize-1)) ?
    352 (simple_DW.TransportDelay1_IWORK.Tail+1) : 0);
    353 }
    354
    355 (*tBuffer)[simple_DW.TransportDelay1_IWORK.Head] = simTime;
    356 (*uBuffer)[simple_DW.TransportDelay1_IWORK.Head] = rtb_Sum1;
    357 }
    358
    359 /* Update for TransportDelay: '<Root>/Transport Delay' */
    360 {
    361 real_T **uBuffer = (real_T**)&simple_DW.TransportDelay_PWORK.TUbufferPtrs[0];
    362 real_T **tBuffer = (real_T**)&simple_DW.TransportDelay_PWORK.TUbufferPtrs[1];
    363 real_T simTime = simple_M->Timing.t[0];
    364 simple_DW.TransportDelay_IWORK.Head = ((simple_DW.TransportDelay_IWORK.Head <
    365 (simple_DW.TransportDelay_IWORK.CircularBufSize-1)) ?
    366 (simple_DW.TransportDelay_IWORK.Head+1) : 0);
    367 if (simple_DW.TransportDelay_IWORK.Head ==
    368 simple_DW.TransportDelay_IWORK.Tail) {
    369 simple_DW.TransportDelay_IWORK.Tail =
    370 ((simple_DW.TransportDelay_IWORK.Tail <
    371 (simple_DW.TransportDelay_IWORK.CircularBufSize-1)) ?
    372 (simple_DW.TransportDelay_IWORK.Tail+1) : 0);
    373 }
    374
    375 (*tBuffer)[simple_DW.TransportDelay_IWORK.Head] = simTime;
    376 (*uBuffer)[simple_DW.TransportDelay_IWORK.Head] = simple_B.y;
    377 }
    378
    379 /* signal main to stop simulation */
    380 { /* Sample time: [0.0s, 0.0s] */
    381 if ((rtmGetTFinal(simple_M)!=-1) &&
    382 !((rtmGetTFinal(simple_M)-simple_M->Timing.t[0]) > simple_M->Timing.t[0]
    383 * (DBL_EPSILON))) {
    384 rtmSetErrorStatus(simple_M, "Simulation finished");
    385 }
    386 }
    387
    388 /* Update absolute time for base rate */
    389 /* The "clockTick0" counts the number of times the code of this task has
    390 * been executed. The absolute time is the multiplication of "clockTick0"
    391 * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
    392 * overflow during the application lifespan selected.
    393 * Timer of this task consists of two 32 bit unsigned integers.
    394 * The two integers represent the low bits Timing.clockTick0 and the high bits
    395 * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
    396 */
    397 if (!(++simple_M->Timing.clockTick0)) {
    398 ++simple_M->Timing.clockTickH0;
    399 }
    400
    401 simple_M->Timing.t[0] = simple_M->Timing.clockTick0 *
    402 simple_M->Timing.stepSize0 + simple_M->Timing.clockTickH0 *
    403 simple_M->Timing.stepSize0 * 4294967296.0;
    404 }
    405
    406 /* Model initialize function */
    407 void simple_initialize(void)
    408 {
    409 /* Registration code */
    410
    411 /* initialize non-finites */
    412 rt_InitInfAndNaN(sizeof(real_T));
    413
    414 /* initialize real-time model */
    415 (void) memset((void *)simple_M, 0,
    416 sizeof(RT_MODEL_simple_T));
    417
    418 {
    419 /* Setup solver object */
    420 rtsiSetSimTimeStepPtr(&simple_M->solverInfo, &simple_M->Timing.simTimeStep);
    421 rtsiSetTPtr(&simple_M->solverInfo, &rtmGetTPtr(simple_M));
    422 rtsiSetStepSizePtr(&simple_M->solverInfo, &simple_M->Timing.stepSize0);
    423 rtsiSetErrorStatusPtr(&simple_M->solverInfo, (&rtmGetErrorStatus(simple_M)));
    424 rtsiSetRTModelPtr(&simple_M->solverInfo, simple_M);
    425 }
    426
    427 rtsiSetSimTimeStep(&simple_M->solverInfo, MAJOR_TIME_STEP);
    428 rtsiSetSolverName(&simple_M->solverInfo,"FixedStepDiscrete");
    429 rtmSetTPtr(simple_M, &simple_M->Timing.tArray[0]);
    430 rtmSetTFinal(simple_M, 10.0);
    431 simple_M->Timing.stepSize0 = 0.2;
    432
    433 /* Setup for data logging */
    434 {
    435 static RTWLogInfo rt_DataLoggingInfo;
    436 rt_DataLoggingInfo.loggingInterval = NULL;
    437 simple_M->rtwLogInfo = &rt_DataLoggingInfo;
    438 }
    439
    440 /* Setup for data logging */
    441 {
    442 rtliSetLogXSignalInfo(simple_M->rtwLogInfo, (NULL));
    443 rtliSetLogXSignalPtrs(simple_M->rtwLogInfo, (NULL));
    444 rtliSetLogT(simple_M->rtwLogInfo, "tout");
    445 rtliSetLogX(simple_M->rtwLogInfo, "");
    446 rtliSetLogXFinal(simple_M->rtwLogInfo, "");
    447 rtliSetLogVarNameModifier(simple_M->rtwLogInfo, "rt_");
    448 rtliSetLogFormat(simple_M->rtwLogInfo, 4);
    449 rtliSetLogMaxRows(simple_M->rtwLogInfo, 0);
    450 rtliSetLogDecimation(simple_M->rtwLogInfo, 1);
    451 rtliSetLogY(simple_M->rtwLogInfo, "");
    452 rtliSetLogYSignalInfo(simple_M->rtwLogInfo, (NULL));
    453 rtliSetLogYSignalPtrs(simple_M->rtwLogInfo, (NULL));
    454 }
    455
    456 /* block I/O */
    457 (void) memset(((void *) &simple_B), 0,
    458 sizeof(B_simple_T));
    459
    460 /* states (dwork) */
    461 (void) memset((void *)&simple_DW, 0,
    462 sizeof(DW_simple_T));
    463
    464 /* external outputs */
    465 simple_Y.Out1 = 0.0;
    466
    467 /* Matfile logging */
    468 rt_StartDataLoggingWithStartTime(simple_M->rtwLogInfo, 0.0, rtmGetTFinal
    469 (simple_M), simple_M->Timing.stepSize0, (&rtmGetErrorStatus(simple_M)));
    470
    471 /* Start for TransportDelay: '<Root>/Transport Delay2' */
    472 {
    473 real_T *pBuffer = &simple_DW.TransportDelay2_RWORK.TUbufferArea[0];
    474 simple_DW.TransportDelay2_IWORK.Tail = 0;
    475 simple_DW.TransportDelay2_IWORK.Head = 0;
    476 simple_DW.TransportDelay2_IWORK.Last = 0;
    477 simple_DW.TransportDelay2_IWORK.CircularBufSize = 1024;
    478 pBuffer[0] = simple_P.TransportDelay2_InitOutput;
    479 pBuffer[1024] = simple_M->Timing.t[0];
    480 simple_DW.TransportDelay2_PWORK.TUbufferPtrs[0] = (void *) &pBuffer[0];
    481 simple_DW.TransportDelay2_PWORK.TUbufferPtrs[1] = (void *) &pBuffer[1024];
    482 }
    483
    484 /* Start for TransportDelay: '<Root>/Transport Delay1' */
    485 {
    486 real_T *pBuffer = &simple_DW.TransportDelay1_RWORK.TUbufferArea[0];
    487 simple_DW.TransportDelay1_IWORK.Tail = 0;
    488 simple_DW.TransportDelay1_IWORK.Head = 0;
    489 simple_DW.TransportDelay1_IWORK.Last = 0;
    490 simple_DW.TransportDelay1_IWORK.CircularBufSize = 1024;
    491 pBuffer[0] = simple_P.TransportDelay1_InitOutput;
    492 pBuffer[1024] = simple_M->Timing.t[0];
    493 simple_DW.TransportDelay1_PWORK.TUbufferPtrs[0] = (void *) &pBuffer[0];
    494 simple_DW.TransportDelay1_PWORK.TUbufferPtrs[1] = (void *) &pBuffer[1024];
    495 }
    496
    497 /* Start for TransportDelay: '<Root>/Transport Delay' */
    498 {
    499 real_T *pBuffer = &simple_DW.TransportDelay_RWORK.TUbufferArea[0];
    500 simple_DW.TransportDelay_IWORK.Tail = 0;
    501 simple_DW.TransportDelay_IWORK.Head = 0;
    502 simple_DW.TransportDelay_IWORK.Last = 0;
    503 simple_DW.TransportDelay_IWORK.CircularBufSize = 1024;
    504 pBuffer[0] = simple_P.TransportDelay_InitOutput;
    505 pBuffer[1024] = simple_M->Timing.t[0];
    506 simple_DW.TransportDelay_PWORK.TUbufferPtrs[0] = (void *) &pBuffer[0];
    507 simple_DW.TransportDelay_PWORK.TUbufferPtrs[1] = (void *) &pBuffer[1024];
    508 }
    509 }
    510
    511 /* Model terminate function */
    512 void simple_terminate(void)
    513 {
    514 /* (no terminate code required) */
    515 }
  • Rachana,

    I'm not in Tech Support, so I cant go through your code. You can contact MathWorks Technical Support for more detailed assistance if that is what is needed.

    Question: Are you using the MathWorks C2000 Support Package, or just normal C code from Embedded Coder?

    ---

    If you are using our C2000 Support Package , it creates a CCS project file you can use to debug the code inside of CCS.

    https://www.mathworks.com/help/supportpkg/texasinstrumentsc2000/ug/overview-of-creating-models-for-c2000-processors.html

    My location for the project folder is here: ...model-name_ert_rtw\CCS_Project. Here is an example from an F28377S model I ran a couple weeks ago:

    ---

    Cheers,

    -Brian

  • Hi Brian,

    
    

    I was able to solve my issue by using C2000 support package. 

    But I wasn't sure if that's the appropriate code for my algorithm. I am attaching the generated code file and my Simulink model. Please let me know if you think this is the exact code for what I am looking for. 
    And also, if this is the appropriate code my Simulink model, how do I check my output? I tried to import the generated code into the Code Composer Studio and wasn't able to find how do I check my output. For which variable to I put a watchdog and check for the output?  
    Please let me know if you have any idea about this issue and I am not even sure if I should ask this question to Mathworks. I would be really happy if could help me with this issue. Let me know even if I should contact Mathworks

    /*
    * Academic License - for use in teaching, academic research, and meeting
    * course requirements at degree granting institutions only. Not for
    * government, commercial, or other organizational use.
    *
    * File: ert_main.c
    *
    * Code generated for Simulink model 'pllex'.
    *
    * Model version : 1.41
    * Simulink Coder version : 8.14 (R2018a) 06-Feb-2018
    * C/C++ source code generated on : Tue Apr 10 16:33:12 2018
    *
    * Target selection: ert.tlc
    * Embedded hardware selection: Texas Instruments->C2000
    * Code generation objectives:
    * 1. Execution efficiency
    * 2. RAM efficiency
    * Validation result: Not run
    */

    #include "pllex.h"
    #include "rtwtypes.h"

    volatile int IsrOverrun = 0;
    boolean_T isRateRunning[2] = { 0, 0 };

    boolean_T need2runFlags[2] = { 0, 0 };

    void rt_OneStep(void)
    {
    boolean_T eventFlags[2];

    /* Check base rate for overrun */
    if (isRateRunning[0]++) {
    IsrOverrun = 1;
    isRateRunning[0]--; /* allow future iterations to succeed*/
    return;
    }

    /*
    * For a bare-board target (i.e., no operating system), the rates
    * that execute this base step are buffered locally to allow for
    * overlapping preemption. The generated code includes function
    * writeCodeInfoFcn() which sets the rates
    * that need to run this time step. The return values are 1 and 0
    * for true and false, respectively.
    */
    pllex_SetEventsForThisBaseStep(eventFlags);
    enableTimer0Interrupt();
    pllex_step0();

    /* Get model outputs here */
    disableTimer0Interrupt();
    isRateRunning[0]--;
    if (eventFlags[1]) {
    if (need2runFlags[1]++) {
    IsrOverrun = 1;
    need2runFlags[1]--; /* allow future iterations to succeed*/
    return;
    }
    }

    if (need2runFlags[1]) {
    if (isRateRunning[1]) {
    /* Yield to higher priority*/
    return;
    }

    isRateRunning[1]++;
    enableTimer0Interrupt();

    /* Step the model for subrate "1" */
    switch (1)
    {
    case 1 :
    pllex_step1();

    /* Get model outputs here */
    break;

    default :
    break;
    }

    disableTimer0Interrupt();
    need2runFlags[1]--;
    isRateRunning[1]--;
    }
    }

    volatile boolean_T stopRequested = false;
    int main(void)
    {
    volatile boolean_T runModel = true;
    float modelBaseRate = 1.0E-6;
    float systemClock = 200;
    c2000_flash_init();
    init_board();

    #ifdef MW_EXEC_PROFILER_ON

    config_profilerTimer();

    #endif

    ;
    rtmSetErrorStatus(rtM, 0);
    pllex_initialize();
    configureTimer0(modelBaseRate, systemClock);
    runModel =
    rtmGetErrorStatus(rtM) == (NULL);
    enableTimer0Interrupt();
    globalInterruptEnable();
    while (runModel) {
    stopRequested = !(
    rtmGetErrorStatus(rtM) == (NULL));
    runModel = !(stopRequested);
    }

    /* Disable rt_OneStep() here */
    globalInterruptDisable();
    return 0;
    }

    /*
    * File trailer for generated code.
    *
    * [EOF]
    */

    Thanks in advance!!
    Best Regards
  • Hi Rachana,

    I cant really review your code (I'm not in Tech Support). Generally the code you need will be in <modelname>.c and <modelname>.h.  Most customers have an existing CCS project which contains their algorithm/control code (e.e. <algorthm>.c). You would cut and paste the core of <modelname>.c into <algorithm>.c.  I cant tell you how to do this exactly, as it depends on your software architecture and <algorithm>.c.  We provide a basic project you can import and use as per the doc link I gave you previously.

    If you are still stuck, please contact MathWorks Technical Support for assistance.

    Cheers,

    -Brian

  • Hi Brian,

    I am attaching the main code( <modelname>.c). Please have a look at it and let me know on where do I put the watchdog variable and check for the output.

    *
    * Academic License - for use in teaching, academic research, and meeting
    * course requirements at degree granting institutions only. Not for
    * government, commercial, or other organizational use.
    *
    * File: pllex.c
    *
    * Code generated for Simulink model 'pllex'.
    *
    * Model version : 1.43
    * Simulink Coder version : 8.14 (R2018a) 06-Feb-2018
    * C/C++ source code generated on : Wed Apr 11 12:04:34 2018
    *
    * Target selection: ert.tlc
    * Embedded hardware selection: Texas Instruments->C2000
    * Code generation objectives:
    * 1. Execution efficiency
    * 2. RAM efficiency
    * Validation result: Not run
    */

    #include "pllex.h"
    #ifndef UCHAR_MAX
    #include <limits.h>
    #endif

    #if ( UCHAR_MAX != (0xFFFFU) ) || ( SCHAR_MAX != (0x7FFF) )
    #error Code was generated for compiler with different sized uchar/char. \
    Consider adjusting Test hardware word size settings on the \
    Hardware Implementation pane to match your compiler word sizes as \
    defined in limits.h of the compiler. Alternatively, you can \
    select the Test hardware is the same as production hardware option and \
    select the Enable portable word sizes option on the Code Generation > \
    Verification pane for ERT based targets, which will disable the \
    preprocessor word size checks.
    #endif

    #if ( USHRT_MAX != (0xFFFFU) ) || ( SHRT_MAX != (0x7FFF) )
    #error Code was generated for compiler with different sized ushort/short. \
    Consider adjusting Test hardware word size settings on the \
    Hardware Implementation pane to match your compiler word sizes as \
    defined in limits.h of the compiler. Alternatively, you can \
    select the Test hardware is the same as production hardware option and \
    select the Enable portable word sizes option on the Code Generation > \
    Verification pane for ERT based targets, which will disable the \
    preprocessor word size checks.
    #endif

    #if ( UINT_MAX != (0xFFFFU) ) || ( INT_MAX != (0x7FFF) )
    #error Code was generated for compiler with different sized uint/int. \
    Consider adjusting Test hardware word size settings on the \
    Hardware Implementation pane to match your compiler word sizes as \
    defined in limits.h of the compiler. Alternatively, you can \
    select the Test hardware is the same as production hardware option and \
    select the Enable portable word sizes option on the Code Generation > \
    Verification pane for ERT based targets, which will disable the \
    preprocessor word size checks.
    #endif

    #if ( ULONG_MAX != (0xFFFFFFFFUL) ) || ( LONG_MAX != (0x7FFFFFFFL) )
    #error Code was generated for compiler with different sized ulong/long. \
    Consider adjusting Test hardware word size settings on the \
    Hardware Implementation pane to match your compiler word sizes as \
    defined in limits.h of the compiler. Alternatively, you can \
    select the Test hardware is the same as production hardware option and \
    select the Enable portable word sizes option on the Code Generation > \
    Verification pane for ERT based targets, which will disable the \
    preprocessor word size checks.
    #endif

    /* Skipping ulong_long/long_long check: insufficient preprocessor integer range. */
    void InitAdcA (void);
    void config_ADCA_SOC0 (void);

    /* Block signals and states (default storage) */
    DW rtDW;

    /* Real-time model */
    RT_MODEL rtM_;
    RT_MODEL *const rtM = &rtM_;
    static void rate_monotonic_scheduler(void);
    static uint16_T adcAInitFlag = 0;

    /*
    * Set which subrates need to run this base step (base rate always runs).
    * This function must be called prior to calling the model step function
    * in order to "remember" which rates need to run this base step. The
    * buffering of events allows for overlapping preemption.
    */
    void pllex_SetEventsForThisBaseStep(boolean_T *eventFlags)
    {
    /* Task runs when its counter is zero, computed via rtmStepTask macro */
    eventFlags[1] = ((boolean_T)rtmStepTask(rtM, 1));
    }

    /*
    * This function updates active task flag for each subrate
    * and rate transition flags for tasks that exchange data.
    * The function assumes rate-monotonic multitasking scheduler.
    * The function must be called at model base rate so that
    * the generated code self-manages all its subrates and rate
    * transition flags.
    */
    static void rate_monotonic_scheduler(void)
    {
    /* Compute which subrates run during the next base time step. Subrates
    * are an integer multiple of the base rate counter. Therefore, the subtask
    * counter is reset when it reaches its limit (zero means run).
    */
    (rtM->Timing.TaskCounters.TID[1])++;
    if ((rtM->Timing.TaskCounters.TID[1]) > 82) {/* Sample time: [8.3E-5s, 0.0s] */
    rtM->Timing.TaskCounters.TID[1] = 0;
    }
    }

    /* Model step function for TID0 */
    void pllex_step0(void) /* Sample time: [1.0E-6s, 0.0s] */
    {
    { /* Sample time: [1.0E-6s, 0.0s] */
    rate_monotonic_scheduler();
    }
    }

    /* Model step function for TID1 */
    void pllex_step1(void) /* Sample time: [8.3E-5s, 0.0s] */
    {
    /* S-Function (c2802xadc): '<Root>/ADC' */
    {
    /* Internal Reference Voltage : Fixed scale 0 to 3.3 V range. */
    /* External Reference Voltage : Allowable ranges of VREFHI(ADCINA0) = 3.3 and VREFLO(tied to ground) = 0 */
    AdcaRegs.ADCSOCFRC1.bit.SOC0 = 1;

    /* Wait for the period of Sampling window and EOC result to be latched after trigger */
    asm(" RPT #75 || NOP");
    rtDW.ADC = (AdcaResultRegs.ADCRESULT0);
    }
    }

    /* Model initialize function */
    void pllex_initialize(void)
    {
    /* Registration code */

    /* initialize real-time model */
    (void) memset((void *)rtM, 0,
    sizeof(RT_MODEL));

    /* states (dwork) */
    (void) memset((void *) &rtDW, 0,
    sizeof(DW));

    /* Start for S-Function (c2802xadc): '<Root>/ADC' */
    if (adcAInitFlag == 0) {
    InitAdcA();
    adcAInitFlag = 1;
    }

    config_ADCA_SOC0 ();
    }

    /*
    * File trailer for generated code.
    *
    * [EOF]
    */

    Thanks in advance!!

    Best Regards

    Rachana Dasari

  • I cannot review your code. Please contact MathWorks Technical Support for direct assistance.

    -b

  • Brian,

    Thank you. I will contact Mathworks.