1/*
2 * Academic License - for use in teaching, academic research, and meeting
3 * course requirements at degree granting institutions only. Not for
4 * government, commercial, or other organizational use.
5 *
6 * File: m3_core.c
7 *
8 * Code generated for Simulink model 'm3_core'.
9 *
10 * Model version : 1.91
11 * Simulink Coder version : 8.11 (R2016b) 25-Aug-2016
12 * C/C++ source code generated on : Thu Sep 27 00:27:58 2018
13 *
14 * Target selection: ert.tlc
15 * Embedded hardware selection: ARM Compatible->ARM Cortex
16 * Code generation objectives: Unspecified
17 * Validation result: Not run
18 */
19
20#include "m3_core.h"
21#include "m3_core_private.h"
22#include "m3_core_dt.h"
23#define m3_core_BlockingMode (false)
24#define m3_core_LocalIPPort_ (25555.0)
25#define m3_core_LocalIPPort__p (-1.0)
26#define m3_core_RemoteIPPort_ (25000.0)
27
28/* Block signals (auto storage) */
29B_m3_core_T m3_core_B;
30
31/* Block states (auto storage) */
32DW_m3_core_T m3_core_DW;
33
34/* Real-time model */
35RT_MODEL_m3_core_T m3_core_M_;
36RT_MODEL_m3_core_T *const m3_core_M = &m3_core_M_;
37static void rate_monotonic_scheduler(void);
38
39/*
40 * Set which subrates need to run this base step (base rate always runs).
41 * This function must be called prior to calling the model step function
42 * in order to "remember" which rates need to run this base step. The
43 * buffering of events allows for overlapping preemption.
44 */
45void m3_core_SetEventsForThisBaseStep(boolean_T *eventFlags)
46{
47 /* Task runs when its counter is zero, computed via rtmStepTask macro */
48 eventFlags[1] = ((boolean_T)rtmStepTask(m3_core_M, 1));
49 eventFlags[2] = ((boolean_T)rtmStepTask(m3_core_M, 2));
50}
51
52/*
53 * This function updates active task flag for each subrate
54 * and rate transition flags for tasks that exchange data.
55 * The function assumes rate-monotonic multitasking scheduler.
56 * The function must be called at model base rate so that
57 * the generated code self-manages all its subrates and rate
58 * transition flags.
59 */
60static void rate_monotonic_scheduler(void)
61{
62 /* Compute which subrates run during the next base time step. Subrates
63 * are an integer multiple of the base rate counter. Therefore, the subtask
64 * counter is reset when it reaches its limit (zero means run).
65 */
66 (m3_core_M->Timing.TaskCounters.TID[1])++;
67 if ((m3_core_M->Timing.TaskCounters.TID[1]) > 1) {/* Sample time: [0.1s, 0.0s] */
68 m3_core_M->Timing.TaskCounters.TID[1] = 0;
69 }
70
71 (m3_core_M->Timing.TaskCounters.TID[2])++;
72 if ((m3_core_M->Timing.TaskCounters.TID[2]) > 4) {/* Sample time: [0.25s, 0.0s] */
73 m3_core_M->Timing.TaskCounters.TID[2] = 0;
74 }
75}
76
77/* Model step function for TID0 */
78void m3_core_step0(void) /* Sample time: [0.05s, 0.0s] */
79{
80 { /* Sample time: [0.05s, 0.0s] */
81 rate_monotonic_scheduler();
82 }
83
84 /* External mode */
85 rtExtModeUploadCheckTrigger(3);
86 rtExtModeUpload(0, m3_core_M->Timing.taskTime0);
87
88 /* signal main to stop simulation */
89 { /* Sample time: [0.05s, 0.0s] */
90 if ((rtmGetTFinal(m3_core_M)!=-1) &&
91 !((rtmGetTFinal(m3_core_M)-m3_core_M->Timing.taskTime0) >
92 m3_core_M->Timing.taskTime0 * (DBL_EPSILON))) {
93 rtmSetErrorStatus(m3_core_M, "Simulation finished");
94 }
95
96 if (rtmGetStopRequested(m3_core_M)) {
97 rtmSetErrorStatus(m3_core_M, "Simulation finished");
98 }
99 }
100
101 /* Update absolute time */
102 /* The "clockTick0" counts the number of times the code of this task has
103 * been executed. The absolute time is the multiplication of "clockTick0"
104 * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
105 * overflow during the application lifespan selected.
106 */
107 m3_core_M->Timing.taskTime0 =
108 (++m3_core_M->Timing.clockTick0) * m3_core_M->Timing.stepSize0;
109}
110
111/* Model step function for TID1 */
112void m3_core_step1(void) /* Sample time: [0.1s, 0.0s] */
113{
114 uint16_T varargout_1[8];
115 int32_T i;
116
117 /* Start for MATLABSystem: '<Root>/UDP Send1' incorporates:
118 * Constant: '<Root>/Constant'
119 * MATLABSystem: '<Root>/UDP Send1'
120 */
121 ARM_TransmitUdpPacket((uint32_T)m3_core_BlockingMode, (uint32_T)
122 m3_core_RemoteIPPort_, m3_core_P.Constant_Value, 16U);
123
124 /* MATLABSystem: '<Root>/UDP Receive' incorporates:
125 * Start for MATLABSystem: '<Root>/UDP Receive'
126 */
127 m3_core_B.UDPReceive_o2 = ARM_ReceiveUdpPacket((uint32_T)m3_core_BlockingMode,
128 (uint32_T)m3_core_LocalIPPort_, varargout_1, 16U);
129 for (i = 0; i < 8; i++) {
130 m3_core_B.UDPReceive_o1[i] = varargout_1[i];
131 }
132
133 /* End of MATLABSystem: '<Root>/UDP Receive' */
134 rtExtModeUpload(1, ((m3_core_M->Timing.clockTick1) * 0.1));
135
136 /* Update absolute time */
137 /* The "clockTick1" counts the number of times the code of this task has
138 * been executed. The resolution of this integer timer is 0.1, which is the step size
139 * of the task. Size of "clockTick1" ensures timer will not overflow during the
140 * application lifespan selected.
141 */
142 m3_core_M->Timing.clockTick1++;
143}
144
145/* Model step function for TID2 */
146void m3_core_step2(void) /* Sample time: [0.25s, 0.0s] */
147{
148 real_T rtb_PulseGenerator;
149
150 /* DiscretePulseGenerator: '<S1>/Pulse Generator' */
151 rtb_PulseGenerator = (m3_core_DW.clockTickCounter <
152 m3_core_P.PulseGenerator_Duty) &&
153 (m3_core_DW.clockTickCounter >= 0) ? m3_core_P.PulseGenerator_Amp : 0.0;
154 if (m3_core_DW.clockTickCounter >= m3_core_P.PulseGenerator_Period - 1.0) {
155 m3_core_DW.clockTickCounter = 0;
156 } else {
157 m3_core_DW.clockTickCounter++;
158 }
159
160 /* End of DiscretePulseGenerator: '<S1>/Pulse Generator' */
161
162 /* S-Function (concerto_do_write): '<S1>/Digital Output2' incorporates:
163 * DataTypeConversion: '<S1>/Data Type Conversion2'
164 */
165 MW_GPIOPinWrite(2U, 128U, (uint8_T)(rtb_PulseGenerator != 0.0), 7U);
166 rtExtModeUpload(2, ((m3_core_M->Timing.clockTick2) * 0.25));
167
168 /* Update absolute time */
169 /* The "clockTick2" counts the number of times the code of this task has
170 * been executed. The resolution of this integer timer is 0.25, which is the step size
171 * of the task. Size of "clockTick2" ensures timer will not overflow during the
172 * application lifespan selected.
173 */
174 m3_core_M->Timing.clockTick2++;
175}
176
177/* Model initialize function */
178void m3_core_initialize(void)
179{
180 /* Registration code */
181
182 /* initialize real-time model */
183 (void) memset((void *)m3_core_M, 0,
184 sizeof(RT_MODEL_m3_core_T));
185 rtmSetTFinal(m3_core_M, -1);
186 m3_core_M->Timing.stepSize0 = 0.05;
187
188 /* External mode info */
189 m3_core_M->Sizes.checksums[0] = (1468656801U);
190 m3_core_M->Sizes.checksums[1] = (3008255270U);
191 m3_core_M->Sizes.checksums[2] = (1200553158U);
192 m3_core_M->Sizes.checksums[3] = (704796611U);
193
194 {
195 static const sysRanDType rtAlwaysEnabled = SUBSYS_RAN_BC_ENABLE;
196 static RTWExtModeInfo rt_ExtModeInfo;
197 static const sysRanDType *systemRan[3];
198 m3_core_M->extModeInfo = (&rt_ExtModeInfo);
199 rteiSetSubSystemActiveVectorAddresses(&rt_ExtModeInfo, systemRan);
200 systemRan[0] = &rtAlwaysEnabled;
201 systemRan[1] = &rtAlwaysEnabled;
202 systemRan[2] = &rtAlwaysEnabled;
203 rteiSetModelMappingInfoPtr(m3_core_M->extModeInfo,
204 &m3_core_M->SpecialInfo.mappingInfo);
205 rteiSetChecksumsPtr(m3_core_M->extModeInfo, m3_core_M->Sizes.checksums);
206 rteiSetTPtr(m3_core_M->extModeInfo, rtmGetTPtr(m3_core_M));
207 }
208
209 /* block I/O */
210 (void) memset(((void *) &m3_core_B), 0,
211 sizeof(B_m3_core_T));
212
213 /* states (dwork) */
214 (void) memset((void *)&m3_core_DW, 0,
215 sizeof(DW_m3_core_T));
216
217 /* data type transition information */
218 {
219 static DataTypeTransInfo dtInfo;
220 (void) memset((char_T *) &dtInfo, 0,
221 sizeof(dtInfo));
222 m3_core_M->SpecialInfo.mappingInfo = (&dtInfo);
223 dtInfo.numDataTypes = 16;
224 dtInfo.dataTypeSizes = &rtDataTypeSizes[0];
225 dtInfo.dataTypeNames = &rtDataTypeNames[0];
226
227 /* Block I/O transition table */
228 dtInfo.BTransTable = &rtBTransTable;
229
230 /* Parameters transition table */
231 dtInfo.PTransTable = &rtPTransTable;
232 }
233
234 {
235 static const char_T tmp[8] = { '0', '.', '0', '.', '0', '.', '0', '\x00' };
236
237 static const char_T tmp_0[16] = { '2', '5', '5', '.', '2', '5', '5', '.',
238 '2', '5', '5', '.', '2', '5', '5', '\x00' };
239
240 char_T tmp_1[8];
241 char_T tmp_2[16];
242 int32_T i;
243
244 /* Start for MATLABSystem: '<Root>/UDP Send1' */
245 m3_core_DW.obj_c.isInitialized = 0;
246 m3_core_DW.obj_c.isInitialized = 1;
247 for (i = 0; i < 16; i++) {
248 tmp_2[i] = tmp_0[i];
249 }
250
251 ARM_UDP_Initialize((int32_T)m3_core_LocalIPPort__p, tmp_2, (uint32_T)
252 m3_core_RemoteIPPort_);
253
254 /* End of Start for MATLABSystem: '<Root>/UDP Send1' */
255
256 /* Start for MATLABSystem: '<Root>/UDP Receive' */
257 m3_core_DW.obj.isInitialized = 0;
258 m3_core_DW.obj.isInitialized = 1;
259 for (i = 0; i < 8; i++) {
260 tmp_1[i] = tmp[i];
261 }
262
263 ARM_UDP_Initialize((int32_T)m3_core_LocalIPPort_, tmp_1, 0);
264
265 /* End of Start for MATLABSystem: '<Root>/UDP Receive' */
266
267 /* Start for DiscretePulseGenerator: '<S1>/Pulse Generator' */
268 m3_core_DW.clockTickCounter = 0;
269
270 /* Start for S-Function (concerto_do_write): '<S1>/Digital Output2' */
271 MW_GPIOPinConfigureCoreSelect(2U, 128U, 0U);
272 MW_GPIO_Init(2U, 128U, 1U);
273 MW_GPIOPinWrite(2U, 128U, 1U, 7U);
274 }
275}
276
277/* Model terminate function */
278void m3_core_terminate(void)
279{
280 /* Start for MATLABSystem: '<Root>/UDP Send1' incorporates:
281 * Terminate for MATLABSystem: '<Root>/UDP Send1'
282 */
283 if (m3_core_DW.obj_c.isInitialized == 1) {
284 m3_core_DW.obj_c.isInitialized = 2;
285 }
286
287 /* End of Start for MATLABSystem: '<Root>/UDP Send1' */
288
289 /* Start for MATLABSystem: '<Root>/UDP Receive' incorporates:
290 * Terminate for MATLABSystem: '<Root>/UDP Receive'
291 */
292 if (m3_core_DW.obj.isInitialized == 1) {
293 m3_core_DW.obj.isInitialized = 2;
294 }
295
296 /* End of Start for MATLABSystem: '<Root>/UDP Receive' */
297}
298
299/*
300 * File trailer for generated code.
301 *
302 * [EOF]
303 */
304