Skip to content

Commit af9bf6f

Browse files
committed
Simulink models: dual motor control (PWM+encoder)
r2014b Simulink models using S-Function Builder to access registers of the motor control bitstream for PWM and encoder interface.
1 parent dc14c4e commit af9bf6f

16 files changed

+1259
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
MATLAB r2014b Simulink Models using BeagleBoneBlack support package for Embedded Coder
2+
3+
Uses motor control bitstream in hw directory.
4+
5+
Tested with PmodHB5 modules plugged into top row of PMOD1 and PMOD2 ports, and
6+
two Digilent geared DC motors (1:53 reduction)
7+
8+
Included S-Functions built for MS Windows 64-bits
9+
10+
Runs on standard logibone image referenced in logibone quick start guide, but
11+
you must first disable password authentication for ubuntu user in
12+
sudoers file. Run sudo visudo and add the following on last line:
13+
14+
ubuntu ALL = NOPASSWD: ALL
15+
16+
TODO:
17+
-Models currently limited to 10Hz max
18+
-Combine multiple logibone reads and write into a single one for performance?
19+
-Use logibone library?
20+
-Load bitstream in block initialization?
21+
-Bitstream load conditional on checksum register perhaps?
22+
-Pass certain data as block parameters instead of input signals?
23+
-Build for win32?
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
/*
2+
* File: logi_readall.c
3+
*
4+
*
5+
* --- THIS FILE GENERATED BY S-FUNCTION BUILDER: 3.0 ---
6+
*
7+
* This file is an S-function produced by the S-Function
8+
* Builder which only recognizes certain fields. Changes made
9+
* outside these fields will be lost the next time the block is
10+
* used to load, edit, and resave this file. This file will be overwritten
11+
* by the S-function Builder block. If you want to edit this file by hand,
12+
* you must change it only in the area defined as:
13+
*
14+
* %%%-SFUNWIZ_defines_Changes_BEGIN
15+
* #define NAME 'replacement text'
16+
* %%% SFUNWIZ_defines_Changes_END
17+
*
18+
* DO NOT change NAME--Change the 'replacement text' only.
19+
*
20+
* For better compatibility with the Simulink Coder, the
21+
* "wrapper" S-function technique is used. This is discussed
22+
* in the Simulink Coder's Manual in the Chapter titled,
23+
* "Wrapper S-functions".
24+
*
25+
* -------------------------------------------------------------------------
26+
* | See matlabroot/simulink/src/sfuntmpl_doc.c for a more detailed template |
27+
* -------------------------------------------------------------------------
28+
* Created: Mon Mar 9 17:55:47 2015
29+
*/
30+
#define S_FUNCTION_LEVEL 2
31+
#define S_FUNCTION_NAME logi_readall
32+
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
33+
/* %%%-SFUNWIZ_defines_Changes_BEGIN --- EDIT HERE TO _END */
34+
#define NUM_INPUTS 1
35+
/* Input Port 0 */
36+
#define IN_PORT_0_NAME address
37+
#define INPUT_0_WIDTH 1
38+
#define INPUT_DIMS_0_COL 1
39+
#define INPUT_0_DTYPE uint16_T
40+
#define INPUT_0_COMPLEX COMPLEX_NO
41+
#define IN_0_FRAME_BASED FRAME_NO
42+
#define IN_0_BUS_BASED 0
43+
#define IN_0_BUS_NAME
44+
#define IN_0_DIMS 1-D
45+
#define INPUT_0_FEEDTHROUGH 1
46+
#define IN_0_ISSIGNED 0
47+
#define IN_0_WORDLENGTH 8
48+
#define IN_0_FIXPOINTSCALING 1
49+
#define IN_0_FRACTIONLENGTH 9
50+
#define IN_0_BIAS 0
51+
#define IN_0_SLOPE 0.125
52+
53+
#define NUM_OUTPUTS 1
54+
/* Output Port 0 */
55+
#define OUT_PORT_0_NAME data
56+
#define OUTPUT_0_WIDTH 1
57+
#define OUTPUT_DIMS_0_COL 1
58+
#define OUTPUT_0_DTYPE uint16_T
59+
#define OUTPUT_0_COMPLEX COMPLEX_NO
60+
#define OUT_0_FRAME_BASED FRAME_NO
61+
#define OUT_0_BUS_BASED 0
62+
#define OUT_0_BUS_NAME
63+
#define OUT_0_DIMS 1-D
64+
#define OUT_0_ISSIGNED 1
65+
#define OUT_0_WORDLENGTH 8
66+
#define OUT_0_FIXPOINTSCALING 1
67+
#define OUT_0_FRACTIONLENGTH 3
68+
#define OUT_0_BIAS 0
69+
#define OUT_0_SLOPE 0.125
70+
71+
#define NPARAMS 0
72+
73+
#define SAMPLE_TIME_0 INHERITED_SAMPLE_TIME
74+
#define NUM_DISC_STATES 1
75+
#define DISC_STATES_IC [0]
76+
#define NUM_CONT_STATES 0
77+
#define CONT_STATES_IC [0]
78+
79+
#define SFUNWIZ_GENERATE_TLC 1
80+
#define SOURCEFILES "__SFB__"
81+
#define PANELINDEX 6
82+
#define USE_SIMSTRUCT 0
83+
#define SHOW_COMPILE_STEPS 0
84+
#define CREATE_DEBUG_MEXFILE 0
85+
#define SAVE_CODE_ONLY 0
86+
#define SFUNWIZ_REVISION 3.0
87+
/* %%%-SFUNWIZ_defines_Changes_END --- EDIT HERE TO _BEGIN */
88+
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
89+
#include "simstruc.h"
90+
91+
extern void logi_readall_Outputs_wrapper(const uint16_T *address,
92+
uint16_T *data,
93+
const real_T *xD);
94+
extern void logi_readall_Update_wrapper(const uint16_T *address,
95+
const uint16_T *data,
96+
real_T *xD);
97+
98+
/*====================*
99+
* S-function methods *
100+
*====================*/
101+
/* Function: mdlInitializeSizes ===============================================
102+
* Abstract:
103+
* Setup sizes of the various vectors.
104+
*/
105+
static void mdlInitializeSizes(SimStruct *S)
106+
{
107+
108+
DECL_AND_INIT_DIMSINFO(inputDimsInfo);
109+
DECL_AND_INIT_DIMSINFO(outputDimsInfo);
110+
ssSetNumSFcnParams(S, NPARAMS);
111+
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
112+
return; /* Parameter mismatch will be reported by Simulink */
113+
}
114+
115+
ssSetNumContStates(S, NUM_CONT_STATES);
116+
ssSetNumDiscStates(S, NUM_DISC_STATES);
117+
118+
if (!ssSetNumInputPorts(S, NUM_INPUTS)) return;
119+
ssSetInputPortWidth(S, 0, INPUT_0_WIDTH);
120+
ssSetInputPortDataType(S, 0, SS_UINT16);
121+
ssSetInputPortComplexSignal(S, 0, INPUT_0_COMPLEX);
122+
ssSetInputPortDirectFeedThrough(S, 0, INPUT_0_FEEDTHROUGH);
123+
ssSetInputPortRequiredContiguous(S, 0, 1); /*direct input signal access*/
124+
125+
if (!ssSetNumOutputPorts(S, NUM_OUTPUTS)) return;
126+
ssSetOutputPortWidth(S, 0, OUTPUT_0_WIDTH);
127+
ssSetOutputPortDataType(S, 0, SS_UINT16);
128+
ssSetOutputPortComplexSignal(S, 0, OUTPUT_0_COMPLEX);
129+
ssSetNumSampleTimes(S, 1);
130+
ssSetNumRWork(S, 0);
131+
ssSetNumIWork(S, 0);
132+
ssSetNumPWork(S, 0);
133+
ssSetNumModes(S, 0);
134+
ssSetNumNonsampledZCs(S, 0);
135+
136+
ssSetSimulinkVersionGeneratedIn(S, "8.4");
137+
138+
/* Take care when specifying exception free code - see sfuntmpl_doc.c */
139+
ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE |
140+
SS_OPTION_USE_TLC_WITH_ACCELERATOR |
141+
SS_OPTION_WORKS_WITH_CODE_REUSE));
142+
}
143+
144+
# define MDL_SET_INPUT_PORT_FRAME_DATA
145+
static void mdlSetInputPortFrameData(SimStruct *S,
146+
int_T port,
147+
Frame_T frameData)
148+
{
149+
ssSetInputPortFrameData(S, port, frameData);
150+
}
151+
/* Function: mdlInitializeSampleTimes =========================================
152+
* Abstract:
153+
* Specifiy the sample time.
154+
*/
155+
static void mdlInitializeSampleTimes(SimStruct *S)
156+
{
157+
ssSetSampleTime(S, 0, SAMPLE_TIME_0);
158+
ssSetOffsetTime(S, 0, 0.0);
159+
}
160+
#define MDL_INITIALIZE_CONDITIONS
161+
/* Function: mdlInitializeConditions ========================================
162+
* Abstract:
163+
* Initialize the states
164+
*/
165+
static void mdlInitializeConditions(SimStruct *S)
166+
{
167+
real_T *xD = ssGetRealDiscStates(S);
168+
169+
170+
xD[0] = 0;
171+
172+
}
173+
#define MDL_SET_INPUT_PORT_DATA_TYPE
174+
static void mdlSetInputPortDataType(SimStruct *S, int port, DTypeId dType)
175+
{
176+
ssSetInputPortDataType( S, 0, dType);
177+
}
178+
#define MDL_SET_OUTPUT_PORT_DATA_TYPE
179+
static void mdlSetOutputPortDataType(SimStruct *S, int port, DTypeId dType)
180+
{
181+
ssSetOutputPortDataType(S, 0, dType);
182+
}
183+
184+
#define MDL_SET_DEFAULT_PORT_DATA_TYPES
185+
static void mdlSetDefaultPortDataTypes(SimStruct *S)
186+
{
187+
ssSetInputPortDataType( S, 0, SS_DOUBLE);
188+
ssSetOutputPortDataType(S, 0, SS_DOUBLE);
189+
}
190+
/* Function: mdlOutputs =======================================================
191+
*
192+
*/
193+
static void mdlOutputs(SimStruct *S, int_T tid)
194+
{
195+
const uint16_T *address = (const uint16_T*) ssGetInputPortSignal(S,0);
196+
uint16_T *data = (uint16_T *)ssGetOutputPortRealSignal(S,0);
197+
const real_T *xD = ssGetDiscStates(S);
198+
199+
200+
logi_readall_Outputs_wrapper(address, data, xD);
201+
202+
203+
}
204+
#define MDL_UPDATE /* Change to #undef to remove function */
205+
/* Function: mdlUpdate ======================================================
206+
* Abstract:
207+
* This function is called once for every major integration time step.
208+
* Discrete states are typically updated here, but this function is useful
209+
* for performing any tasks that should only take place once per
210+
* integration step.
211+
*/
212+
static void mdlUpdate(SimStruct *S, int_T tid)
213+
{
214+
real_T *xD = ssGetDiscStates(S);
215+
const uint16_T *address = (const uint16_T*) ssGetInputPortSignal(S,0);
216+
uint16_T *data = (uint16_T *)ssGetOutputPortRealSignal(S,0);
217+
218+
logi_readall_Update_wrapper(address, data, xD);
219+
}
220+
221+
222+
/* Function: mdlTerminate =====================================================
223+
* Abstract:
224+
* In this function, you should perform any actions that are necessary
225+
* at the termination of a simulation. For example, if memory was
226+
* allocated in mdlStart, this is the place to free it.
227+
*/
228+
static void mdlTerminate(SimStruct *S)
229+
{
230+
231+
232+
233+
}
234+
235+
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
236+
#include "simulink.c" /* MEX-file interface mechanism */
237+
#else
238+
#include "cg_sfun.h" /* Code generation registration function */
239+
#endif
240+
241+
Binary file not shown.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
%% File : logi_readall.tlc
2+
%% Created: Mon Mar 9 17:55:47 2015
3+
%%
4+
%% Description:
5+
%% Simulink Coder wrapper functions interface generated for
6+
%% S-function "logi_readall.c".
7+
%%
8+
%% File generated by S-function Builder Block
9+
%%
10+
%% For more information on using the Target Language with the
11+
%% Simulink Coder, see the Target Language Compiler manual
12+
%% (under Simulink Coder) in the "Inlining S-Functions"
13+
%% chapter under the section and subsection:
14+
%% "Writing Block Target Files to Inline S-Functions",
15+
%% "Function-Based or Wrappered Code".
16+
%%
17+
%implements logi_readall "C"
18+
%% Function: BlockTypeSetup ===================================================
19+
%%
20+
%% Purpose:
21+
%% Set up external references for wrapper functions in the
22+
%% generated code.
23+
%%
24+
%function BlockTypeSetup(block, system) Output
25+
%openfile externs
26+
27+
extern void logi_readall_Outputs_wrapper(const uint16_T *address,
28+
uint16_T *data,
29+
const real_T *xD);
30+
extern void logi_readall_Update_wrapper(const uint16_T *address,
31+
const uint16_T *data,
32+
real_T *xD);
33+
%closefile externs
34+
%<LibCacheExtern(externs)>
35+
%%
36+
%endfunction
37+
38+
%% InitializeConditions =========================================================
39+
%%
40+
%function InitializeConditions(block, system) Output
41+
/* %<Type> Block: %<Name> */
42+
{
43+
44+
real_T initVector[1] = {0};
45+
%assign rollVars = ["<dwork>/DSTATE"]
46+
%assign rollRegions = [0:%<LibBlockDWorkWidth(DSTATE)-1>]
47+
%roll sigIdx = rollRegions, lcv = 1, block, "Roller", rollVars
48+
%if %<LibBlockDWorkWidth(DSTATE)> == 1
49+
%<LibBlockDWork(DSTATE, "", lcv, sigIdx)> = initVector[0];
50+
%else
51+
%<LibBlockDWork(DSTATE, "", lcv, sigIdx)> = initVector[%<lcv>];
52+
%endif
53+
%endroll
54+
}
55+
56+
%endfunction
57+
%% Function: Outputs ==========================================================
58+
%%
59+
%% Purpose:
60+
%% Code generation rules for mdlOutputs function.
61+
%%
62+
%function Outputs(block, system) Output
63+
%%
64+
%assign pu0 = LibBlockInputSignalAddr(0, "", "", 0)
65+
%assign py0 = LibBlockOutputSignalAddr(0, "", "", 0)
66+
%assign pxd = LibBlockDWorkAddr(DSTATE, "", "", 0)
67+
%assign py_width = LibBlockOutputSignalWidth(0)
68+
%assign pu_width = LibBlockInputSignalWidth(0)
69+
logi_readall_Outputs_wrapper(%<pu0>, %<py0>, %<pxd>);
70+
71+
%%
72+
%endfunction
73+
74+
%% Function: Update ==========================================================
75+
%% Abstract:
76+
%% Update
77+
%%
78+
%%
79+
%function Update(block, system) Output
80+
/* S-Function "logi_readall_wrapper" Block: %<Name> */
81+
82+
%assign pu0 = LibBlockInputSignalAddr(0, "", "", 0)
83+
%assign py0 = LibBlockOutputSignalAddr(0, "", "", 0)
84+
%assign pxd = LibBlockDWorkAddr(DSTATE, "", "", 0)
85+
86+
87+
88+
logi_readall_Update_wrapper(%<pu0>, %<py0>, %<pxd>);
89+
90+
91+
%%
92+
%endfunction
93+
%% [EOF] logi_readall.tlc
94+
95+
96+
97+
98+

0 commit comments

Comments
 (0)