diff --git a/logi-motor-control/sw/simulink/README.txt b/logi-motor-control/sw/simulink/README.txt new file mode 100644 index 00000000..f2bf5a37 --- /dev/null +++ b/logi-motor-control/sw/simulink/README.txt @@ -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? \ No newline at end of file diff --git a/logi-motor-control/sw/simulink/SFB__logi_readall__SFB.mat b/logi-motor-control/sw/simulink/SFB__logi_readall__SFB.mat new file mode 100644 index 00000000..6557d786 Binary files /dev/null and b/logi-motor-control/sw/simulink/SFB__logi_readall__SFB.mat differ diff --git a/logi-motor-control/sw/simulink/SFB__logibone_motor_block__SFB.mat b/logi-motor-control/sw/simulink/SFB__logibone_motor_block__SFB.mat new file mode 100644 index 00000000..af5b2363 Binary files /dev/null and b/logi-motor-control/sw/simulink/SFB__logibone_motor_block__SFB.mat differ diff --git a/logi-motor-control/sw/simulink/beaglebone_logi.slx b/logi-motor-control/sw/simulink/beaglebone_logi.slx new file mode 100644 index 00000000..2141db00 Binary files /dev/null and b/logi-motor-control/sw/simulink/beaglebone_logi.slx differ diff --git a/logi-motor-control/sw/simulink/logi_readall.c b/logi-motor-control/sw/simulink/logi_readall.c new file mode 100644 index 00000000..84e3c2cf --- /dev/null +++ b/logi-motor-control/sw/simulink/logi_readall.c @@ -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 + + diff --git a/logi-motor-control/sw/simulink/logi_readall.mexw64 b/logi-motor-control/sw/simulink/logi_readall.mexw64 new file mode 100644 index 00000000..0389d53f Binary files /dev/null and b/logi-motor-control/sw/simulink/logi_readall.mexw64 differ diff --git a/logi-motor-control/sw/simulink/logi_readall.tlc b/logi-motor-control/sw/simulink/logi_readall.tlc new file mode 100644 index 00000000..823056e6 --- /dev/null +++ b/logi-motor-control/sw/simulink/logi_readall.tlc @@ -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 + % + %% +%endfunction + +%% InitializeConditions ========================================================= + %% + %function InitializeConditions(block, system) Output + /* % Block: % */ + { + + real_T initVector[1] = {0}; + %assign rollVars = ["/DSTATE"] + %assign rollRegions = [0:%] + %roll sigIdx = rollRegions, lcv = 1, block, "Roller", rollVars + %if % == 1 + % = initVector[0]; + %else + % = initVector[%]; + %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(%, %, %); + + %% +%endfunction + +%% Function: Update ========================================================== +%% Abstract: +%% Update +%% +%% +%function Update(block, system) Output + /* S-Function "logi_readall_wrapper" Block: % */ + + %assign pu0 = LibBlockInputSignalAddr(0, "", "", 0) + %assign py0 = LibBlockOutputSignalAddr(0, "", "", 0) + %assign pxd = LibBlockDWorkAddr(DSTATE, "", "", 0) + + + + logi_readall_Update_wrapper(%, %, %); + + + %% +%endfunction +%% [EOF] logi_readall.tlc + + + + + diff --git a/logi-motor-control/sw/simulink/logi_readall_wrapper.c b/logi-motor-control/sw/simulink/logi_readall_wrapper.c new file mode 100644 index 00000000..88b99789 --- /dev/null +++ b/logi-motor-control/sw/simulink/logi_readall_wrapper.c @@ -0,0 +1,88 @@ + + +/* + * Include Files + * + */ +#if defined(MATLAB_MEX_FILE) +#include "tmwtypes.h" +#include "simstruc_types.h" +#else +#include "rtwtypes.h" +#endif + +/* %%%-SFUNWIZ_wrapper_includes_Changes_BEGIN --- EDIT HERE TO _END */ +#ifndef MATLAB_MEX_FILE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif +/* %%%-SFUNWIZ_wrapper_includes_Changes_END --- EDIT HERE TO _BEGIN */ +#define u_width 1 +#define y_width 1 +/* + * Create external references here. + * + */ +/* %%%-SFUNWIZ_wrapper_externs_Changes_BEGIN --- EDIT HERE TO _END */ +#ifndef MATLAB_MEX_FILE +int fd; +unsigned short readVal; +#endif +/* %%%-SFUNWIZ_wrapper_externs_Changes_END --- EDIT HERE TO _BEGIN */ + +/* + * Output functions + * + */ +void logi_readall_Outputs_wrapper(const uint16_T *address, + uint16_T *data, + const real_T *xD) +{ +/* %%%-SFUNWIZ_wrapper_Outputs_Changes_BEGIN --- EDIT HERE TO _END */ +if (xD[0] == 1){ +#ifndef MATLAB_MEX_FILE + pread(fd, &readVal, 2, address[0]); + data[0] = readVal; +#endif +} +/* This sample sets the output equal to the input + y0[0] = u0[0]; + For complex signals use: y0[0].re = u0[0].re; + y0[0].im = u0[0].im; + y1[0].re = u1[0].re; + y1[0].im = u1[0].im; +*/ +/* %%%-SFUNWIZ_wrapper_Outputs_Changes_END --- EDIT HERE TO _BEGIN */ +} + +/* + * Updates function + * + */ +void logi_readall_Update_wrapper(const uint16_T *address, + const uint16_T *data, + real_T *xD) +{ + /* %%%-SFUNWIZ_wrapper_Update_Changes_BEGIN --- EDIT HERE TO _END */ +if (xD[0] == 0){ + xD[0] = 1; + #ifndef MATLAB_MEX_FILE + fd = open("/dev/logibone_mem", O_RDWR | O_SYNC); + #endif +} + + +/* + * Code example + * xD[0] = u0[0]; +*/ +/* %%%-SFUNWIZ_wrapper_Update_Changes_END --- EDIT HERE TO _BEGIN */ +} diff --git a/logi-motor-control/sw/simulink/logibone_motor_block.c b/logi-motor-control/sw/simulink/logibone_motor_block.c new file mode 100644 index 00000000..97ffcad9 --- /dev/null +++ b/logi-motor-control/sw/simulink/logibone_motor_block.c @@ -0,0 +1,485 @@ +/* + * File: logibone_motor_block.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:56:15 2015 +*/ +#define S_FUNCTION_LEVEL 2 +#define S_FUNCTION_NAME logibone_motor_block +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ +/* %%%-SFUNWIZ_defines_Changes_BEGIN --- EDIT HERE TO _END */ +#define NUM_INPUTS 7 +/* Input Port 0 */ +#define IN_PORT_0_NAME duty1 +#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 +/* Input Port 1 */ +#define IN_PORT_1_NAME duty2 +#define INPUT_1_WIDTH 1 +#define INPUT_DIMS_1_COL 1 +#define INPUT_1_DTYPE uint16_T +#define INPUT_1_COMPLEX COMPLEX_NO +#define IN_1_FRAME_BASED FRAME_NO +#define IN_1_BUS_BASED 0 +#define IN_1_BUS_NAME +#define IN_1_DIMS 1-D +#define INPUT_1_FEEDTHROUGH 1 +#define IN_1_ISSIGNED 0 +#define IN_1_WORDLENGTH 8 +#define IN_1_FIXPOINTSCALING 1 +#define IN_1_FRACTIONLENGTH 9 +#define IN_1_BIAS 0 +#define IN_1_SLOPE 0.125 +/* Input Port 2 */ +#define IN_PORT_2_NAME period +#define INPUT_2_WIDTH 1 +#define INPUT_DIMS_2_COL 1 +#define INPUT_2_DTYPE uint16_T +#define INPUT_2_COMPLEX COMPLEX_NO +#define IN_2_FRAME_BASED FRAME_NO +#define IN_2_BUS_BASED 0 +#define IN_2_BUS_NAME +#define IN_2_DIMS 1-D +#define INPUT_2_FEEDTHROUGH 1 +#define IN_2_ISSIGNED 0 +#define IN_2_WORDLENGTH 8 +#define IN_2_FIXPOINTSCALING 1 +#define IN_2_FRACTIONLENGTH 9 +#define IN_2_BIAS 0 +#define IN_2_SLOPE 0.125 +/* Input Port 3 */ +#define IN_PORT_3_NAME reset_cnt1 +#define INPUT_3_WIDTH 1 +#define INPUT_DIMS_3_COL 1 +#define INPUT_3_DTYPE boolean_T +#define INPUT_3_COMPLEX COMPLEX_NO +#define IN_3_FRAME_BASED FRAME_NO +#define IN_3_BUS_BASED 0 +#define IN_3_BUS_NAME +#define IN_3_DIMS 1-D +#define INPUT_3_FEEDTHROUGH 1 +#define IN_3_ISSIGNED 0 +#define IN_3_WORDLENGTH 8 +#define IN_3_FIXPOINTSCALING 1 +#define IN_3_FRACTIONLENGTH 9 +#define IN_3_BIAS 0 +#define IN_3_SLOPE 0.125 +/* Input Port 4 */ +#define IN_PORT_4_NAME reset_cnt2 +#define INPUT_4_WIDTH 1 +#define INPUT_DIMS_4_COL 1 +#define INPUT_4_DTYPE boolean_T +#define INPUT_4_COMPLEX COMPLEX_NO +#define IN_4_FRAME_BASED FRAME_NO +#define IN_4_BUS_BASED 0 +#define IN_4_BUS_NAME +#define IN_4_DIMS 1-D +#define INPUT_4_FEEDTHROUGH 1 +#define IN_4_ISSIGNED 0 +#define IN_4_WORDLENGTH 8 +#define IN_4_FIXPOINTSCALING 1 +#define IN_4_FRACTIONLENGTH 9 +#define IN_4_BIAS 0 +#define IN_4_SLOPE 0.125 +/* Input Port 5 */ +#define IN_PORT_5_NAME dir1 +#define INPUT_5_WIDTH 1 +#define INPUT_DIMS_5_COL 1 +#define INPUT_5_DTYPE boolean_T +#define INPUT_5_COMPLEX COMPLEX_NO +#define IN_5_FRAME_BASED FRAME_NO +#define IN_5_BUS_BASED 0 +#define IN_5_BUS_NAME +#define IN_5_DIMS 1-D +#define INPUT_5_FEEDTHROUGH 1 +#define IN_5_ISSIGNED 0 +#define IN_5_WORDLENGTH 8 +#define IN_5_FIXPOINTSCALING 1 +#define IN_5_FRACTIONLENGTH 9 +#define IN_5_BIAS 0 +#define IN_5_SLOPE 0.125 +/* Input Port 6 */ +#define IN_PORT_6_NAME dir2 +#define INPUT_6_WIDTH 1 +#define INPUT_DIMS_6_COL 1 +#define INPUT_6_DTYPE boolean_T +#define INPUT_6_COMPLEX COMPLEX_NO +#define IN_6_FRAME_BASED FRAME_NO +#define IN_6_BUS_BASED 0 +#define IN_6_BUS_NAME +#define IN_6_DIMS 1-D +#define INPUT_6_FEEDTHROUGH 1 +#define IN_6_ISSIGNED 0 +#define IN_6_WORDLENGTH 8 +#define IN_6_FIXPOINTSCALING 1 +#define IN_6_FRACTIONLENGTH 9 +#define IN_6_BIAS 0 +#define IN_6_SLOPE 0.125 + +#define NUM_OUTPUTS 4 +/* Output Port 0 */ +#define OUT_PORT_0_NAME cnt1 +#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 +/* Output Port 1 */ +#define OUT_PORT_1_NAME cnt2 +#define OUTPUT_1_WIDTH 1 +#define OUTPUT_DIMS_1_COL 1 +#define OUTPUT_1_DTYPE uint16_T +#define OUTPUT_1_COMPLEX COMPLEX_NO +#define OUT_1_FRAME_BASED FRAME_NO +#define OUT_1_BUS_BASED 0 +#define OUT_1_BUS_NAME +#define OUT_1_DIMS 1-D +#define OUT_1_ISSIGNED 1 +#define OUT_1_WORDLENGTH 8 +#define OUT_1_FIXPOINTSCALING 1 +#define OUT_1_FRACTIONLENGTH 3 +#define OUT_1_BIAS 0 +#define OUT_1_SLOPE 0.125 +/* Output Port 2 */ +#define OUT_PORT_2_NAME spd1 +#define OUTPUT_2_WIDTH 1 +#define OUTPUT_DIMS_2_COL 1 +#define OUTPUT_2_DTYPE uint16_T +#define OUTPUT_2_COMPLEX COMPLEX_NO +#define OUT_2_FRAME_BASED FRAME_NO +#define OUT_2_BUS_BASED 0 +#define OUT_2_BUS_NAME +#define OUT_2_DIMS 1-D +#define OUT_2_ISSIGNED 1 +#define OUT_2_WORDLENGTH 8 +#define OUT_2_FIXPOINTSCALING 1 +#define OUT_2_FRACTIONLENGTH 3 +#define OUT_2_BIAS 0 +#define OUT_2_SLOPE 0.125 +/* Output Port 3 */ +#define OUT_PORT_3_NAME spd2 +#define OUTPUT_3_WIDTH 1 +#define OUTPUT_DIMS_3_COL 1 +#define OUTPUT_3_DTYPE uint16_T +#define OUTPUT_3_COMPLEX COMPLEX_NO +#define OUT_3_FRAME_BASED FRAME_NO +#define OUT_3_BUS_BASED 0 +#define OUT_3_BUS_NAME +#define OUT_3_DIMS 1-D +#define OUT_3_ISSIGNED 1 +#define OUT_3_WORDLENGTH 8 +#define OUT_3_FIXPOINTSCALING 1 +#define OUT_3_FRACTIONLENGTH 3 +#define OUT_3_BIAS 0 +#define OUT_3_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 logibone_motor_block_Outputs_wrapper(const uint16_T *duty1, + const uint16_T *duty2, + const uint16_T *period, + const boolean_T *reset_cnt1, + const boolean_T *reset_cnt2, + const boolean_T *dir1, + const boolean_T *dir2, + uint16_T *cnt1, + uint16_T *cnt2, + uint16_T *spd1, + uint16_T *spd2, + const real_T *xD); +extern void logibone_motor_block_Update_wrapper(const uint16_T *duty1, + const uint16_T *duty2, + const uint16_T *period, + const boolean_T *reset_cnt1, + const boolean_T *reset_cnt2, + const boolean_T *dir1, + const boolean_T *dir2, + const uint16_T *cnt1, + const uint16_T *cnt2, + const uint16_T *spd1, + const uint16_T *spd2, + 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; + /*Input Port 0 */ + 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*/ + + /*Input Port 1 */ + ssSetInputPortWidth(S, 1, INPUT_1_WIDTH); /* */ + ssSetInputPortDataType(S, 1, SS_UINT16); + ssSetInputPortComplexSignal(S, 1, INPUT_1_COMPLEX); + ssSetInputPortDirectFeedThrough(S, 1, INPUT_1_FEEDTHROUGH); + ssSetInputPortRequiredContiguous(S, 1, 1); /*direct input signal access*/ + + /*Input Port 2 */ + ssSetInputPortWidth(S, 2, INPUT_2_WIDTH); /* */ + ssSetInputPortDataType(S, 2, SS_UINT16); + ssSetInputPortComplexSignal(S, 2, INPUT_2_COMPLEX); + ssSetInputPortDirectFeedThrough(S, 2, INPUT_2_FEEDTHROUGH); + ssSetInputPortRequiredContiguous(S, 2, 1); /*direct input signal access*/ + + /*Input Port 3 */ + ssSetInputPortWidth(S, 3, INPUT_3_WIDTH); /* */ + ssSetInputPortDataType(S, 3, SS_BOOLEAN); + ssSetInputPortComplexSignal(S, 3, INPUT_3_COMPLEX); + ssSetInputPortDirectFeedThrough(S, 3, INPUT_3_FEEDTHROUGH); + ssSetInputPortRequiredContiguous(S, 3, 1); /*direct input signal access*/ + + /*Input Port 4 */ + ssSetInputPortWidth(S, 4, INPUT_4_WIDTH); /* */ + ssSetInputPortDataType(S, 4, SS_BOOLEAN); + ssSetInputPortComplexSignal(S, 4, INPUT_4_COMPLEX); + ssSetInputPortDirectFeedThrough(S, 4, INPUT_4_FEEDTHROUGH); + ssSetInputPortRequiredContiguous(S, 4, 1); /*direct input signal access*/ + + /*Input Port 5 */ + ssSetInputPortWidth(S, 5, INPUT_5_WIDTH); /* */ + ssSetInputPortDataType(S, 5, SS_BOOLEAN); + ssSetInputPortComplexSignal(S, 5, INPUT_5_COMPLEX); + ssSetInputPortDirectFeedThrough(S, 5, INPUT_5_FEEDTHROUGH); + ssSetInputPortRequiredContiguous(S, 5, 1); /*direct input signal access*/ + + /*Input Port 6 */ + ssSetInputPortWidth(S, 6, INPUT_6_WIDTH); /* */ + ssSetInputPortDataType(S, 6, SS_BOOLEAN); + ssSetInputPortComplexSignal(S, 6, INPUT_6_COMPLEX); + ssSetInputPortDirectFeedThrough(S, 6, INPUT_6_FEEDTHROUGH); + ssSetInputPortRequiredContiguous(S, 6, 1); /*direct input signal access*/ + + + if (!ssSetNumOutputPorts(S, NUM_OUTPUTS)) return; + /* Output Port 0 */ + ssSetOutputPortWidth(S, 0, OUTPUT_0_WIDTH); + ssSetOutputPortDataType(S, 0, SS_UINT16); + ssSetOutputPortComplexSignal(S, 0, OUTPUT_0_COMPLEX); + /* Output Port 1 */ + ssSetOutputPortWidth(S, 1, OUTPUT_1_WIDTH); + ssSetOutputPortDataType(S, 1, SS_UINT16); + ssSetOutputPortComplexSignal(S, 1, OUTPUT_1_COMPLEX); + /* Output Port 2 */ + ssSetOutputPortWidth(S, 2, OUTPUT_2_WIDTH); + ssSetOutputPortDataType(S, 2, SS_UINT16); + ssSetOutputPortComplexSignal(S, 2, OUTPUT_2_COMPLEX); + /* Output Port 3 */ + ssSetOutputPortWidth(S, 3, OUTPUT_3_WIDTH); + ssSetOutputPortDataType(S, 3, SS_UINT16); + ssSetOutputPortComplexSignal(S, 3, OUTPUT_3_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 *duty1 = (const uint16_T*) ssGetInputPortSignal(S,0); + const uint16_T *duty2 = (const uint16_T*) ssGetInputPortSignal(S,1); + const uint16_T *period = (const uint16_T*) ssGetInputPortSignal(S,2); + const boolean_T *reset_cnt1 = (const boolean_T*) ssGetInputPortSignal(S,3); + const boolean_T *reset_cnt2 = (const boolean_T*) ssGetInputPortSignal(S,4); + const boolean_T *dir1 = (const boolean_T*) ssGetInputPortSignal(S,5); + const boolean_T *dir2 = (const boolean_T*) ssGetInputPortSignal(S,6); + uint16_T *cnt1 = (uint16_T *)ssGetOutputPortRealSignal(S,0); + uint16_T *cnt2 = (uint16_T *)ssGetOutputPortRealSignal(S,1); + uint16_T *spd1 = (uint16_T *)ssGetOutputPortRealSignal(S,2); + uint16_T *spd2 = (uint16_T *)ssGetOutputPortRealSignal(S,3); + const real_T *xD = ssGetDiscStates(S); + + + logibone_motor_block_Outputs_wrapper(duty1, duty2, period, reset_cnt1, reset_cnt2, dir1, dir2, cnt1, cnt2, spd1, spd2, 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 *duty1 = (const uint16_T*) ssGetInputPortSignal(S,0); + const uint16_T *duty2 = (const uint16_T*) ssGetInputPortSignal(S,1); + const uint16_T *period = (const uint16_T*) ssGetInputPortSignal(S,2); + const boolean_T *reset_cnt1 = (const boolean_T*) ssGetInputPortSignal(S,3); + const boolean_T *reset_cnt2 = (const boolean_T*) ssGetInputPortSignal(S,4); + const boolean_T *dir1 = (const boolean_T*) ssGetInputPortSignal(S,5); + const boolean_T *dir2 = (const boolean_T*) ssGetInputPortSignal(S,6); + uint16_T *cnt1 = (uint16_T *)ssGetOutputPortRealSignal(S,0); + uint16_T *cnt2 = (uint16_T *)ssGetOutputPortRealSignal(S,1); + uint16_T *spd1 = (uint16_T *)ssGetOutputPortRealSignal(S,2); + uint16_T *spd2 = (uint16_T *)ssGetOutputPortRealSignal(S,3); + + logibone_motor_block_Update_wrapper(duty1, duty2, period, reset_cnt1, reset_cnt2, dir1, dir2, cnt1, cnt2, spd1, spd2, 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 + + diff --git a/logi-motor-control/sw/simulink/logibone_motor_block.mexw64 b/logi-motor-control/sw/simulink/logibone_motor_block.mexw64 new file mode 100644 index 00000000..cbc87cba Binary files /dev/null and b/logi-motor-control/sw/simulink/logibone_motor_block.mexw64 differ diff --git a/logi-motor-control/sw/simulink/logibone_motor_block.tlc b/logi-motor-control/sw/simulink/logibone_motor_block.tlc new file mode 100644 index 00000000..68365223 --- /dev/null +++ b/logi-motor-control/sw/simulink/logibone_motor_block.tlc @@ -0,0 +1,134 @@ +%% File : logibone_motor_block.tlc +%% Created: Mon Mar 9 17:56:15 2015 +%% +%% Description: +%% Simulink Coder wrapper functions interface generated for +%% S-function "logibone_motor_block.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 logibone_motor_block "C" +%% Function: BlockTypeSetup =================================================== +%% +%% Purpose: +%% Set up external references for wrapper functions in the +%% generated code. +%% +%function BlockTypeSetup(block, system) Output + %openfile externs + + extern void logibone_motor_block_Outputs_wrapper(const uint16_T *duty1, + const uint16_T *duty2, + const uint16_T *period, + const boolean_T *reset_cnt1, + const boolean_T *reset_cnt2, + const boolean_T *dir1, + const boolean_T *dir2, + uint16_T *cnt1, + uint16_T *cnt2, + uint16_T *spd1, + uint16_T *spd2, + const real_T *xD); + extern void logibone_motor_block_Update_wrapper(const uint16_T *duty1, + const uint16_T *duty2, + const uint16_T *period, + const boolean_T *reset_cnt1, + const boolean_T *reset_cnt2, + const boolean_T *dir1, + const boolean_T *dir2, + const uint16_T *cnt1, + const uint16_T *cnt2, + const uint16_T *spd1, + const uint16_T *spd2, + real_T *xD); + %closefile externs + % + %% +%endfunction + +%% InitializeConditions ========================================================= + %% + %function InitializeConditions(block, system) Output + /* % Block: % */ + { + + real_T initVector[1] = {0}; + %assign rollVars = ["/DSTATE"] + %assign rollRegions = [0:%] + %roll sigIdx = rollRegions, lcv = 1, block, "Roller", rollVars + %if % == 1 + % = initVector[0]; + %else + % = initVector[%]; + %endif + %endroll + } + + %endfunction +%% Function: Outputs ========================================================== +%% +%% Purpose: +%% Code generation rules for mdlOutputs function. +%% +%function Outputs(block, system) Output + %% + %assign pu0 = LibBlockInputSignalAddr(0, "", "", 0) + %assign pu1 = LibBlockInputSignalAddr(1, "", "", 0) + %assign pu2 = LibBlockInputSignalAddr(2, "", "", 0) + %assign pu3 = LibBlockInputSignalAddr(3, "", "", 0) + %assign pu4 = LibBlockInputSignalAddr(4, "", "", 0) + %assign pu5 = LibBlockInputSignalAddr(5, "", "", 0) + %assign pu6 = LibBlockInputSignalAddr(6, "", "", 0) + %assign py0 = LibBlockOutputSignalAddr(0, "", "", 0) + %assign py1 = LibBlockOutputSignalAddr(1, "", "", 0) + %assign py2 = LibBlockOutputSignalAddr(2, "", "", 0) + %assign py3 = LibBlockOutputSignalAddr(3, "", "", 0) + %assign pxd = LibBlockDWorkAddr(DSTATE, "", "", 0) + %assign py_width = LibBlockOutputSignalWidth(0) + %assign pu_width = LibBlockInputSignalWidth(0) + logibone_motor_block_Outputs_wrapper(%, %, %, %, %, %, %, %, %, %, %, %); + + %% +%endfunction + +%% Function: Update ========================================================== +%% Abstract: +%% Update +%% +%% +%function Update(block, system) Output + /* S-Function "logibone_motor_block_wrapper" Block: % */ + + %assign pu0 = LibBlockInputSignalAddr(0, "", "", 0) + %assign pu1 = LibBlockInputSignalAddr(1, "", "", 0) + %assign pu2 = LibBlockInputSignalAddr(2, "", "", 0) + %assign pu3 = LibBlockInputSignalAddr(3, "", "", 0) + %assign pu4 = LibBlockInputSignalAddr(4, "", "", 0) + %assign pu5 = LibBlockInputSignalAddr(5, "", "", 0) + %assign pu6 = LibBlockInputSignalAddr(6, "", "", 0) + %assign py0 = LibBlockOutputSignalAddr(0, "", "", 0) + %assign py1 = LibBlockOutputSignalAddr(1, "", "", 0) + %assign py2 = LibBlockOutputSignalAddr(2, "", "", 0) + %assign py3 = LibBlockOutputSignalAddr(3, "", "", 0) + %assign pxd = LibBlockDWorkAddr(DSTATE, "", "", 0) + + + + logibone_motor_block_Update_wrapper(%, %, %, %, %, %, %, %, %, %, %, %); + + + %% +%endfunction +%% [EOF] logibone_motor_block.tlc + + + + + diff --git a/logi-motor-control/sw/simulink/logibone_motor_block_wrapper.c b/logi-motor-control/sw/simulink/logibone_motor_block_wrapper.c new file mode 100644 index 00000000..70dabd23 --- /dev/null +++ b/logi-motor-control/sw/simulink/logibone_motor_block_wrapper.c @@ -0,0 +1,125 @@ + + +/* + * Include Files + * + */ +#if defined(MATLAB_MEX_FILE) +#include "tmwtypes.h" +#include "simstruc_types.h" +#else +#include "rtwtypes.h" +#endif + +/* %%%-SFUNWIZ_wrapper_includes_Changes_BEGIN --- EDIT HERE TO _END */ +#ifndef MATLAB_MEX_FILE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif +/* %%%-SFUNWIZ_wrapper_includes_Changes_END --- EDIT HERE TO _BEGIN */ +#define u_width 1 +#define y_width 1 +/* + * Create external references here. + * + */ +/* %%%-SFUNWIZ_wrapper_externs_Changes_BEGIN --- EDIT HERE TO _END */ +#ifndef MATLAB_MEX_FILE +int fd; +unsigned short readVal; +unsigned short writeVal; +#endif +/* %%%-SFUNWIZ_wrapper_externs_Changes_END --- EDIT HERE TO _BEGIN */ + +/* + * Output functions + * + */ +void logibone_motor_block_Outputs_wrapper(const uint16_T *duty1, + const uint16_T *duty2, + const uint16_T *period, + const boolean_T *reset_cnt1, + const boolean_T *reset_cnt2, + const boolean_T *dir1, + const boolean_T *dir2, + uint16_T *cnt1, + uint16_T *cnt2, + uint16_T *spd1, + uint16_T *spd2, + const real_T *xD) +{ +/* %%%-SFUNWIZ_wrapper_Outputs_Changes_BEGIN --- EDIT HERE TO _END */ +if (xD[0] == 1){ +#ifndef MATLAB_MEX_FILE + //write pwm values + pwrite(fd, period, 2, 0x0005); + pwrite(fd, duty1, 2, 0x0006); + pwrite(fd, duty2, 2, 0x0007); + //write direction - don't bother preserving previous value + writeVal = 0; + if(dir1[0]) writeVal = 0x1; + if(dir2[0]) writeVal |= 0x0100; + pwrite(fd, &writeVal, 2, 0x0001); + + //read encoder counts + pread(fd, &readVal, 2, 0x0000); + cnt1[0] = readVal; + pread(fd, &readVal, 2, 0x0001); + cnt2[0] = readVal; + //read encoder speeds - not yet implemented in bitstream + //pread(fd, &readVal, 2, 0x0000); + spd1[0] = 0; + //pread(fd, &readVal, 2, 0x0001); + spd2[0] = 0; +#endif +} +/* This sample sets the output equal to the input + y0[0] = u0[0]; + For complex signals use: y0[0].re = u0[0].re; + y0[0].im = u0[0].im; + y1[0].re = u1[0].re; + y1[0].im = u1[0].im; +*/ +/* %%%-SFUNWIZ_wrapper_Outputs_Changes_END --- EDIT HERE TO _BEGIN */ +} + +/* + * Updates function + * + */ +void logibone_motor_block_Update_wrapper(const uint16_T *duty1, + const uint16_T *duty2, + const uint16_T *period, + const boolean_T *reset_cnt1, + const boolean_T *reset_cnt2, + const boolean_T *dir1, + const boolean_T *dir2, + const uint16_T *cnt1, + const uint16_T *cnt2, + const uint16_T *spd1, + const uint16_T *spd2, + real_T *xD) +{ + /* %%%-SFUNWIZ_wrapper_Update_Changes_BEGIN --- EDIT HERE TO _END */ +if (xD[0] == 0){ + xD[0] = 1; + #ifndef MATLAB_MEX_FILE + fd = open("/dev/logibone_mem", O_RDWR | O_SYNC); + #endif +} + + +/* + * Code example + * xD[0] = u0[0]; +*/ +/* %%%-SFUNWIZ_wrapper_Update_Changes_END --- EDIT HERE TO _BEGIN */ +} diff --git a/logi-motor-control/sw/simulink/logibone_motorcontrol1.slx b/logi-motor-control/sw/simulink/logibone_motorcontrol1.slx new file mode 100644 index 00000000..6b3a64b5 Binary files /dev/null and b/logi-motor-control/sw/simulink/logibone_motorcontrol1.slx differ diff --git a/logi-motor-control/sw/simulink/logibone_motorcontrol2.slx b/logi-motor-control/sw/simulink/logibone_motorcontrol2.slx new file mode 100644 index 00000000..cdc434b7 Binary files /dev/null and b/logi-motor-control/sw/simulink/logibone_motorcontrol2.slx differ diff --git a/logi-motor-control/sw/simulink/logibone_motorcontrol_openloop.mp4 b/logi-motor-control/sw/simulink/logibone_motorcontrol_openloop.mp4 new file mode 100644 index 00000000..eadef954 Binary files /dev/null and b/logi-motor-control/sw/simulink/logibone_motorcontrol_openloop.mp4 differ diff --git a/logi-motor-control/sw/simulink/rtwmakecfg.m b/logi-motor-control/sw/simulink/rtwmakecfg.m new file mode 100644 index 00000000..fb0ea4c9 --- /dev/null +++ b/logi-motor-control/sw/simulink/rtwmakecfg.m @@ -0,0 +1,65 @@ +function makeInfo=rtwmakecfg() +%RTWMAKECFG.m adds include and source directories to rtw make files. +% makeInfo=RTWMAKECFG returns a structured array containing +% following field: +% makeInfo.includePath - cell array containing additional include +% directories. Those directories will be +% expanded into include instructions of Simulink +% Coder generated make files. +% +% makeInfo.sourcePath - cell array containing additional source +% directories. Those directories will be +% expanded into rules of Simulink Coder generated +% make files. +makeInfo.includePath = {}; +makeInfo.sourcePath = {}; +makeInfo.linkLibsObjs = {}; + +% + +sfBuilderBlocksByMaskType = find_system(bdroot,'FollowLinks','on','LookUnderMasks','on','MaskType','S-Function Builder'); +sfBuilderBlocksByCallback = find_system(bdroot,'OpenFcn','sfunctionwizard(gcbh)'); +sfBuilderBlocksDeployed = find_system(bdroot,'BlockType','S-Function','SFunctionDeploymentMode','on'); +sfBuilderBlocks = {sfBuilderBlocksByMaskType{:} sfBuilderBlocksByCallback{:} sfBuilderBlocksDeployed{:}}; +sfBuilderBlocks = unique(sfBuilderBlocks); +if isempty(sfBuilderBlocks) + return; +end +for idx = 1:length(sfBuilderBlocks) + sfBuilderBlockNameMATFile{idx} = get_param(sfBuilderBlocks{idx},'FunctionName'); + sfBuilderBlockNameMATFile{idx} = ['.' filesep 'SFB__' char(sfBuilderBlockNameMATFile{idx}) '__SFB.mat']; +end +sfBuilderBlockNameMATFile = unique(sfBuilderBlockNameMATFile); +for idx = 1:length(sfBuilderBlockNameMATFile) + if exist(sfBuilderBlockNameMATFile{idx}) + loadedData = load(sfBuilderBlockNameMATFile{idx}); + if isfield(loadedData,'SFBInfoStruct') + makeInfo = UpdateMakeInfo(makeInfo,loadedData.SFBInfoStruct); + clear loadedData; + end + end +end + +function updatedMakeInfo = UpdateMakeInfo(makeInfo,SFBInfoStruct) +updatedMakeInfo = {}; +if isfield(makeInfo,'includePath') + if isfield(SFBInfoStruct,'includePath') + updatedMakeInfo.includePath = {makeInfo.includePath{:} SFBInfoStruct.includePath{:}}; + else + updatedMakeInfo.includePath = {makeInfo.includePath{:}}; + end +end +if isfield(makeInfo,'sourcePath') + if isfield(SFBInfoStruct,'sourcePath') + updatedMakeInfo.sourcePath = {makeInfo.sourcePath{:} SFBInfoStruct.sourcePath{:}}; + else + updatedMakeInfo.sourcePath = {makeInfo.sourcePath{:}}; + end +end +if isfield(makeInfo,'linkLibsObjs') + if isfield(SFBInfoStruct,'additionalLibraries') + updatedMakeInfo.linkLibsObjs = {makeInfo.linkLibsObjs{:} SFBInfoStruct.additionalLibraries{:}}; + else + updatedMakeInfo.linkLibsObjs = {makeInfo.linkLibsObjs{:}}; + end +end