Skip to content

Commit

Permalink
Merge pull request #19 from paulcox/master
Browse files Browse the repository at this point in the history
Simulink models: dual motor control (PWM+encoder)
  • Loading branch information
jpiat committed Mar 9, 2015
2 parents 682234e + af9bf6f commit 2927694
Show file tree
Hide file tree
Showing 16 changed files with 1,259 additions and 0 deletions.
23 changes: 23 additions & 0 deletions logi-motor-control/sw/simulink/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
MATLAB r2014b Simulink Models using BeagleBoneBlack support package for Embedded Coder

Uses motor control bitstream in hw directory.

Tested with PmodHB5 modules plugged into top row of PMOD1 and PMOD2 ports, and
two Digilent geared DC motors (1:53 reduction)

Included S-Functions built for MS Windows 64-bits

Runs on standard logibone image referenced in logibone quick start guide, but
you must first disable password authentication for ubuntu user in
sudoers file. Run sudo visudo and add the following on last line:

ubuntu ALL = NOPASSWD: ALL

TODO:
-Models currently limited to 10Hz max
-Combine multiple logibone reads and write into a single one for performance?
-Use logibone library?
-Load bitstream in block initialization?
-Bitstream load conditional on checksum register perhaps?
-Pass certain data as block parameters instead of input signals?
-Build for win32?
Binary file not shown.
Binary file not shown.
Binary file not shown.
241 changes: 241 additions & 0 deletions logi-motor-control/sw/simulink/logi_readall.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
/*
* File: logi_readall.c
*
*
* --- THIS FILE GENERATED BY S-FUNCTION BUILDER: 3.0 ---
*
* This file is an S-function produced by the S-Function
* Builder which only recognizes certain fields. Changes made
* outside these fields will be lost the next time the block is
* used to load, edit, and resave this file. This file will be overwritten
* by the S-function Builder block. If you want to edit this file by hand,
* you must change it only in the area defined as:
*
* %%%-SFUNWIZ_defines_Changes_BEGIN
* #define NAME 'replacement text'
* %%% SFUNWIZ_defines_Changes_END
*
* DO NOT change NAME--Change the 'replacement text' only.
*
* For better compatibility with the Simulink Coder, the
* "wrapper" S-function technique is used. This is discussed
* in the Simulink Coder's Manual in the Chapter titled,
* "Wrapper S-functions".
*
* -------------------------------------------------------------------------
* | See matlabroot/simulink/src/sfuntmpl_doc.c for a more detailed template |
* -------------------------------------------------------------------------
* Created: Mon Mar 9 17:55:47 2015
*/
#define S_FUNCTION_LEVEL 2
#define S_FUNCTION_NAME logi_readall
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* %%%-SFUNWIZ_defines_Changes_BEGIN --- EDIT HERE TO _END */
#define NUM_INPUTS 1
/* Input Port 0 */
#define IN_PORT_0_NAME address
#define INPUT_0_WIDTH 1
#define INPUT_DIMS_0_COL 1
#define INPUT_0_DTYPE uint16_T
#define INPUT_0_COMPLEX COMPLEX_NO
#define IN_0_FRAME_BASED FRAME_NO
#define IN_0_BUS_BASED 0
#define IN_0_BUS_NAME
#define IN_0_DIMS 1-D
#define INPUT_0_FEEDTHROUGH 1
#define IN_0_ISSIGNED 0
#define IN_0_WORDLENGTH 8
#define IN_0_FIXPOINTSCALING 1
#define IN_0_FRACTIONLENGTH 9
#define IN_0_BIAS 0
#define IN_0_SLOPE 0.125

#define NUM_OUTPUTS 1
/* Output Port 0 */
#define OUT_PORT_0_NAME data
#define OUTPUT_0_WIDTH 1
#define OUTPUT_DIMS_0_COL 1
#define OUTPUT_0_DTYPE uint16_T
#define OUTPUT_0_COMPLEX COMPLEX_NO
#define OUT_0_FRAME_BASED FRAME_NO
#define OUT_0_BUS_BASED 0
#define OUT_0_BUS_NAME
#define OUT_0_DIMS 1-D
#define OUT_0_ISSIGNED 1
#define OUT_0_WORDLENGTH 8
#define OUT_0_FIXPOINTSCALING 1
#define OUT_0_FRACTIONLENGTH 3
#define OUT_0_BIAS 0
#define OUT_0_SLOPE 0.125

#define NPARAMS 0

#define SAMPLE_TIME_0 INHERITED_SAMPLE_TIME
#define NUM_DISC_STATES 1
#define DISC_STATES_IC [0]
#define NUM_CONT_STATES 0
#define CONT_STATES_IC [0]

#define SFUNWIZ_GENERATE_TLC 1
#define SOURCEFILES "__SFB__"
#define PANELINDEX 6
#define USE_SIMSTRUCT 0
#define SHOW_COMPILE_STEPS 0
#define CREATE_DEBUG_MEXFILE 0
#define SAVE_CODE_ONLY 0
#define SFUNWIZ_REVISION 3.0
/* %%%-SFUNWIZ_defines_Changes_END --- EDIT HERE TO _BEGIN */
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
#include "simstruc.h"

extern void logi_readall_Outputs_wrapper(const uint16_T *address,
uint16_T *data,
const real_T *xD);
extern void logi_readall_Update_wrapper(const uint16_T *address,
const uint16_T *data,
real_T *xD);

/*====================*
* S-function methods *
*====================*/
/* Function: mdlInitializeSizes ===============================================
* Abstract:
* Setup sizes of the various vectors.
*/
static void mdlInitializeSizes(SimStruct *S)
{

DECL_AND_INIT_DIMSINFO(inputDimsInfo);
DECL_AND_INIT_DIMSINFO(outputDimsInfo);
ssSetNumSFcnParams(S, NPARAMS);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return; /* Parameter mismatch will be reported by Simulink */
}

ssSetNumContStates(S, NUM_CONT_STATES);
ssSetNumDiscStates(S, NUM_DISC_STATES);

if (!ssSetNumInputPorts(S, NUM_INPUTS)) return;
ssSetInputPortWidth(S, 0, INPUT_0_WIDTH);
ssSetInputPortDataType(S, 0, SS_UINT16);
ssSetInputPortComplexSignal(S, 0, INPUT_0_COMPLEX);
ssSetInputPortDirectFeedThrough(S, 0, INPUT_0_FEEDTHROUGH);
ssSetInputPortRequiredContiguous(S, 0, 1); /*direct input signal access*/

if (!ssSetNumOutputPorts(S, NUM_OUTPUTS)) return;
ssSetOutputPortWidth(S, 0, OUTPUT_0_WIDTH);
ssSetOutputPortDataType(S, 0, SS_UINT16);
ssSetOutputPortComplexSignal(S, 0, OUTPUT_0_COMPLEX);
ssSetNumSampleTimes(S, 1);
ssSetNumRWork(S, 0);
ssSetNumIWork(S, 0);
ssSetNumPWork(S, 0);
ssSetNumModes(S, 0);
ssSetNumNonsampledZCs(S, 0);

ssSetSimulinkVersionGeneratedIn(S, "8.4");

/* Take care when specifying exception free code - see sfuntmpl_doc.c */
ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE |
SS_OPTION_USE_TLC_WITH_ACCELERATOR |
SS_OPTION_WORKS_WITH_CODE_REUSE));
}

# define MDL_SET_INPUT_PORT_FRAME_DATA
static void mdlSetInputPortFrameData(SimStruct *S,
int_T port,
Frame_T frameData)
{
ssSetInputPortFrameData(S, port, frameData);
}
/* Function: mdlInitializeSampleTimes =========================================
* Abstract:
* Specifiy the sample time.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, SAMPLE_TIME_0);
ssSetOffsetTime(S, 0, 0.0);
}
#define MDL_INITIALIZE_CONDITIONS
/* Function: mdlInitializeConditions ========================================
* Abstract:
* Initialize the states
*/
static void mdlInitializeConditions(SimStruct *S)
{
real_T *xD = ssGetRealDiscStates(S);


xD[0] = 0;

}
#define MDL_SET_INPUT_PORT_DATA_TYPE
static void mdlSetInputPortDataType(SimStruct *S, int port, DTypeId dType)
{
ssSetInputPortDataType( S, 0, dType);
}
#define MDL_SET_OUTPUT_PORT_DATA_TYPE
static void mdlSetOutputPortDataType(SimStruct *S, int port, DTypeId dType)
{
ssSetOutputPortDataType(S, 0, dType);
}

#define MDL_SET_DEFAULT_PORT_DATA_TYPES
static void mdlSetDefaultPortDataTypes(SimStruct *S)
{
ssSetInputPortDataType( S, 0, SS_DOUBLE);
ssSetOutputPortDataType(S, 0, SS_DOUBLE);
}
/* Function: mdlOutputs =======================================================
*
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
const uint16_T *address = (const uint16_T*) ssGetInputPortSignal(S,0);
uint16_T *data = (uint16_T *)ssGetOutputPortRealSignal(S,0);
const real_T *xD = ssGetDiscStates(S);


logi_readall_Outputs_wrapper(address, data, xD);


}
#define MDL_UPDATE /* Change to #undef to remove function */
/* Function: mdlUpdate ======================================================
* Abstract:
* This function is called once for every major integration time step.
* Discrete states are typically updated here, but this function is useful
* for performing any tasks that should only take place once per
* integration step.
*/
static void mdlUpdate(SimStruct *S, int_T tid)
{
real_T *xD = ssGetDiscStates(S);
const uint16_T *address = (const uint16_T*) ssGetInputPortSignal(S,0);
uint16_T *data = (uint16_T *)ssGetOutputPortRealSignal(S,0);

logi_readall_Update_wrapper(address, data, xD);
}


/* Function: mdlTerminate =====================================================
* Abstract:
* In this function, you should perform any actions that are necessary
* at the termination of a simulation. For example, if memory was
* allocated in mdlStart, this is the place to free it.
*/
static void mdlTerminate(SimStruct *S)
{



}

#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif


Binary file not shown.
98 changes: 98 additions & 0 deletions logi-motor-control/sw/simulink/logi_readall.tlc
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
%% File : logi_readall.tlc
%% Created: Mon Mar 9 17:55:47 2015
%%
%% Description:
%% Simulink Coder wrapper functions interface generated for
%% S-function "logi_readall.c".
%%
%% File generated by S-function Builder Block
%%
%% For more information on using the Target Language with the
%% Simulink Coder, see the Target Language Compiler manual
%% (under Simulink Coder) in the "Inlining S-Functions"
%% chapter under the section and subsection:
%% "Writing Block Target Files to Inline S-Functions",
%% "Function-Based or Wrappered Code".
%%
%implements logi_readall "C"
%% Function: BlockTypeSetup ===================================================
%%
%% Purpose:
%% Set up external references for wrapper functions in the
%% generated code.
%%
%function BlockTypeSetup(block, system) Output
%openfile externs

extern void logi_readall_Outputs_wrapper(const uint16_T *address,
uint16_T *data,
const real_T *xD);
extern void logi_readall_Update_wrapper(const uint16_T *address,
const uint16_T *data,
real_T *xD);
%closefile externs
%<LibCacheExtern(externs)>
%%
%endfunction

%% InitializeConditions =========================================================
%%
%function InitializeConditions(block, system) Output
/* %<Type> Block: %<Name> */
{

real_T initVector[1] = {0};
%assign rollVars = ["<dwork>/DSTATE"]
%assign rollRegions = [0:%<LibBlockDWorkWidth(DSTATE)-1>]
%roll sigIdx = rollRegions, lcv = 1, block, "Roller", rollVars
%if %<LibBlockDWorkWidth(DSTATE)> == 1
%<LibBlockDWork(DSTATE, "", lcv, sigIdx)> = initVector[0];
%else
%<LibBlockDWork(DSTATE, "", lcv, sigIdx)> = initVector[%<lcv>];
%endif
%endroll
}

%endfunction
%% Function: Outputs ==========================================================
%%
%% Purpose:
%% Code generation rules for mdlOutputs function.
%%
%function Outputs(block, system) Output
%%
%assign pu0 = LibBlockInputSignalAddr(0, "", "", 0)
%assign py0 = LibBlockOutputSignalAddr(0, "", "", 0)
%assign pxd = LibBlockDWorkAddr(DSTATE, "", "", 0)
%assign py_width = LibBlockOutputSignalWidth(0)
%assign pu_width = LibBlockInputSignalWidth(0)
logi_readall_Outputs_wrapper(%<pu0>, %<py0>, %<pxd>);

%%
%endfunction

%% Function: Update ==========================================================
%% Abstract:
%% Update
%%
%%
%function Update(block, system) Output
/* S-Function "logi_readall_wrapper" Block: %<Name> */

%assign pu0 = LibBlockInputSignalAddr(0, "", "", 0)
%assign py0 = LibBlockOutputSignalAddr(0, "", "", 0)
%assign pxd = LibBlockDWorkAddr(DSTATE, "", "", 0)



logi_readall_Update_wrapper(%<pu0>, %<py0>, %<pxd>);


%%
%endfunction
%% [EOF] logi_readall.tlc





Loading

0 comments on commit 2927694

Please sign in to comment.