]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/blob - rpp/blocks/sfunction_cantransmit.c
0d89063b5dafaa71a6b254f6ac8c845818e78971
[jenkicar/rpp-simulink.git] / rpp / blocks / sfunction_cantransmit.c
1 /* Copyright (C) 2013-2015 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Michal Horn <hornmich@fel.cvut.cz>
5  *
6  * This document contains proprietary information belonging to Czech
7  * Technical University in Prague. Passing on and copying of this
8  * document, and communication of its contents is not permitted
9  * without prior written authorization.
10  *
11  * File : sfunction_cantransmit.c
12  * Abstract:
13  *     C-MEX S-function block for RPP CAN bus transmit message.
14  *
15  * References:
16  *     header.c
17  *     trailer.c
18  *
19  * Compile with:
20  *     mex(['-I' matlabroot '/toolbox/shared/can/src/scanutil'], ['-I' matlabroot '/toolbox/rtw/targets/common/can/datatypes'],  'sfunction_cantransmit.c', [matlabroot '/toolbox/rtw/targets/common/can/datatypes/sfun_can_util.c'], [matlabroot '/toolbox/rtw/targets/common/can/datatypes/can_msg.c'])
21  */
22
23 /*
24 %YAML 1.2
25 ---
26 Name: CAN Transmit
27 Category: CAN
28 Header: rpp/can.h
29 Mnemonic: CANT
30
31 Inputs:
32   - { name: "Msg", type: "dynamically" }
33
34 Outputs:
35
36 Parameters:
37   - { name: "Module",                   type: "Choice", range: "CAN1, CAN2, CAN3"   }
38   - { name: "Frame type",               type: "Choice", range: "Standard, Extended" }
39   - { name: "Message ID",               type: "uint16"                              }
40   - { name: "Automatic mailbox number", type: "bool"                                }
41   - { name: "Mailbox number",           type: "int8",   range: "[1–64]"             }
42
43 # Description and Help is in Markdown mark-up
44 Description: |
45
46   Transmit a CAN message.
47
48   Expects a uint8, uint16, uint32 or CAN\_MESSAGE object as an input. Use
49   CAN Pack to create the CAN\_MESSAGE object.
50
51   Matlab expression can be used as Message ID and Mailbox number.
52
53   Uncheck *Automatic mailbox number*, if user defined mailbox number is
54   needed.
55
56 Help: |
57
58   This block allows to send a message to the CAN bus. It can be
59   configured for any of the CAN ports (modules) CAN1, CAN2 or CAN3.
60
61   The message data are read from `Msg` input port. The data type is
62   decided automatically from the input, but it is restricted to uint8,
63   uint16, uint32 and CAN\_MESSAGE. The CAN\_MESSAGE object can be
64   created by the `CAN Pack` block.
65
66   The message sent by the block will have an ID assigned according to
67   the number in the *Message ID* parameter. The block supports both
68   types of message IDs: Standard (11b) and Extended (29b). If
69   CAN\_MESSAGE is used as input type, the message ID stored in
70   CAN\_MESSAGE object is ignored and the ID from the parameter of this
71   block is used instead.
72
73   The mailbox number can be assigned automatically or manually. Automatic mailbox
74   numbers are generated in ascending order from 1 to 64. Every mailbox must have a unique
75   number. It is possible to mix blocks with automatically and manually
76   assigned mailboxes. If the manually assigned mailbox number would
77   collide with the automatic one then the automatically generated
78   block will get assigned a next higher non-colliding number.
79   The mailbox numbers are shared between CAN Transmit and CAN Receive
80   blocks with the same CAN port (module) parameter.
81
82   If there is multiple messages waiting for transmission, the order in
83   which they are transmitted depends on their mailbox numbers and not
84   on the message IDs. The lower the mailbox number is, the sooner the
85   message will be transmitted. If you want to have this under control,
86   you should specify the numbers of the mailboxes manually.
87
88   In order to use this block, there must be a `CAN Configure` block in the model.
89
90 Status: Stable
91
92 RPP API functions used:
93     - rpp_can_write()
94
95 Relevant demos:
96     - cantransmit
97     - can_demo
98 ...
99 */
100
101
102 #define S_FUNCTION_NAME sfunction_cantransmit
103 #include "header.c"
104 #include <stdio.h>
105 #include "sfun_can_util.h"
106
107 #define MSG_TYPE_STANDART_MAX   2048
108 #define MSG_TYPE_EXTENDED_MAX   536870912
109 #define MAILBOX_ID_MIN                  1
110 #define MAILBOX_MAX_CNT                 64
111
112 #define PARAM_NAME_MODULE_ID    "module_id"
113 #define PARAM_NAME_MAILBOX_ID   "mailbox_id"
114 #define PARAM_NAME_MESSAGE_TYPE "message_type"
115 #define PARAM_NAME_MESSAGE_ID   "message_id"
116 #define PARAM_NAME_MAILBOX_AUTO "mailbox_auto"
117
118 /** Identifier of the input */
119 enum input {
120         IN_MSG,
121         IN_COUNT
122 };
123
124 /** Identifiers of the block parameters */
125 enum params{
126         PARAM_MODULE_ID,
127         PARAM_MAILBOX_ID,
128         PARAM_MSG_TYPE,
129         PARAM_MSG_ID,
130         PARAM_MAILBOX_AUTO,
131         PARAM_COUNT
132 };
133
134 enum message_id_type {
135         MSG_ID_STANDART = 1,
136         MSG_ID_EXTENDED,
137         MSG_ID_MIXED
138 };
139
140
141 static void mdlInitializeSizes(SimStruct *S)
142 {
143
144         CAN_Common_MdlInitSizes(S);
145
146         if (!rppSetNumParams(S, PARAM_COUNT)) {
147                 return;
148         }
149
150         /*
151          * Configure input ports: 1
152          *      - Message to be sent
153          */
154         if (!ssSetNumInputPorts(S, IN_COUNT)) {
155                 return;
156         }
157
158         rppAddInputPort(S, IN_MSG, DYNAMICALLY_TYPED);
159
160         /* No output ports */
161         if (!ssSetNumOutputPorts(S, 0)) {
162                 return;
163         }
164
165         /* Set standard options for this block */
166         rppSetStandardOptions(S);
167 }
168
169 #if defined(MATLAB_MEX_FILE)
170 #define MDL_SET_INPUT_PORT_DATA_TYPE
171 void mdlSetInputPortDataType(SimStruct *S, int_T port, DTypeId type)
172 {
173         if (port == IN_MSG) {
174                 if (type == SS_UINT8 ||
175                     type == SS_UINT16 ||
176                     type == SS_UINT32 ||
177                     /* CAN pack seems to use this data type, but it is
178                      * not registered in sfun_can_util.c. Strange. */
179                     type == ssGetDataTypeId(S, "CAN_MESSAGE") ||
180                     type == ssGetDataTypeId(S, SL_CAN_STANDARD_FRAME_DTYPE_NAME) ||
181                     type == ssGetDataTypeId(S, SL_CAN_EXTENDED_FRAME_DTYPE_NAME))
182                         ssSetInputPortDataType(S, port, type);
183                 else {
184                         char msg[300];
185                         sprintf(msg, "Unsupported data type '%s' on Msg input port.",
186                                  ssGetDataTypeName(S, type));
187                         ssSetErrorStatus(S, msg);
188                 }
189         }
190 }
191 #endif
192
193 #ifdef MATLAB_MEX_FILE
194 #define MDL_CHECK_PARAMETERS
195
196 static void mdlCheckParameters(SimStruct *S){
197         int min = 0;
198         int max = 0;
199         /* Check the parameter mailbox id */
200         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_MAILBOX_AUTO))[0] == 0) {
201                 if (!rppValidParamRange(S, PARAM_MAILBOX_ID, MAILBOX_ID_MIN, MAILBOX_ID_MIN + MAILBOX_MAX_CNT)) {
202                         return;
203                 }
204         }
205
206         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_MSG_TYPE))[0] == MSG_ID_STANDART) {
207                 max = MSG_TYPE_STANDART_MAX;
208         }
209         else {
210                 max = MSG_TYPE_EXTENDED_MAX;
211         }
212
213         /* Check the parameter message id */
214         if (!rppValidParamRange(S, PARAM_MSG_ID, min, max)) {
215                 return;
216         }
217 }
218 #endif
219
220
221 #ifdef MATLAB_MEX_FILE
222 #define MDL_SET_WORK_WIDTHS
223 static void mdlSetWorkWidths(SimStruct *S){
224
225         if (!ssSetNumRunTimeParams(S, PARAM_COUNT)) {
226                 return;
227         }
228
229         ssRegDlgParamAsRunTimeParam(S, PARAM_MODULE_ID,  PARAM_MODULE_ID, PARAM_NAME_MODULE_ID, SS_UINT8);
230         ssRegDlgParamAsRunTimeParam(S, PARAM_MAILBOX_ID,  PARAM_MAILBOX_ID, PARAM_NAME_MAILBOX_ID, SS_INT8);
231         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_TYPE,  PARAM_MSG_TYPE, PARAM_NAME_MESSAGE_TYPE, SS_UINT16);   
232         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_ID,  PARAM_MSG_ID, PARAM_NAME_MESSAGE_ID, SS_UINT32); 
233         ssRegDlgParamAsRunTimeParam(S, PARAM_MAILBOX_AUTO,  PARAM_MAILBOX_AUTO, PARAM_NAME_MAILBOX_AUTO, SS_BOOLEAN);     
234 }
235 #endif
236
237 #define COMMON_MDLINITIALIZESAMPLETIMES_INHERIT
238 #define UNUSED_MDLOUTPUTS
239 #define UNUSED_MDLTERMINATE
240 #include "trailer.c"