]> rtime.felk.cvut.cz Git - socketcan-simulink.git/blob - blocks/sfunction_cantransmit.c
sfunction_cansetup: correct debug message for rx/tx sockets open.
[socketcan-simulink.git] / blocks / sfunction_cantransmit.c
1 /* Copyright (C) 2013-2014 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Michal Horn <hornmich@fel.cvut.cz>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * File : sfunction_cantransmit.c
35  * Abstract:
36  *     C-MEX S-function block for RPP CAN bus transmit message.
37  *
38  * References:
39  *     header.c
40  *     trailer.c
41  *
42  * Compile with:
43  *     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'])
44  */
45
46 /*
47 %YAML 1.2
48 ---
49 Name: CAN Transmit
50 Category: CAN
51 Header: rpp/can.h
52 Mnemonic: CANT
53
54 Inputs:
55   - { name: "Msg", type: "dynamically" }
56
57 Outputs:
58
59 Parameters:
60   - { name: "Module",                   type: "Choice", range: "CAN1, CAN2, CAN3"   }
61   - { name: "Message ID type",          type: "Choice", range: "Standard, Extended" }
62   - { name: "Message ID",               type: "uint16"                              }
63   - { name: "Automatic mailbox number", type: "bool"                                }
64   - { name: "Mailbox number",           type: "int8"                              }
65
66 # Description is in Markdown mark-up
67 Description: |
68
69   This block allows to send a message to the CAN bus. It can be
70   configured for any of the CAN ports (modules) CAN1, CAN2 or CAN3.
71
72   The message data are read from `Msg` input port. The data type is
73   decided automatically from the input, but it is restricted to uint8,
74   uint16, uint32 and CAN\_MESSAGE. The CAN\_MESSAGE object can be
75   created by the `CAN Pack` block.
76
77   The message sent by the block will have an ID assigned according to
78   the number in the *Message ID* parameter. The block supports both
79   types of message IDs: Standard (11b) and Extended (29b). If
80   CAN\_MESSAGE is used as input type, the message ID stored in
81   CAN\_MESSAGE object is ignored and the ID from the parameter of this
82   block is used instead.
83
84   The mailbox number can be assigned automatically or manually. Automatic mailbox
85   numbers are generated in ascending order from 0 to 31. Every mailbox must have a unique
86   number. It is possible to mix blocks with automatically and manually
87   assigned mailboxes. If the manually assigned mailbox number would
88   collide with the automatic one then the automatically generated
89   block will get assigned a next higher non-colliding ID.
90   The mailbox numbers are shared between CAN Transmit and CAN Receive
91   blocks with the same CAN port (module) parameter.
92
93   In order to use this block, there must be a `CAN Configure` block in the model.
94
95 Status:
96   Tested:
97     - Transmission of the message with configured ID
98     - Automatic generation of mailboxes numbers in combination with
99       manual specification in other blocks. Colliding mailbox numbers
100       are correctly handled.
101     - Input message data type recognition
102     - When unsupported data type is connected to the Msg input port, Simulink generates a reasonable error message
103   Untested:
104     - Handling of error states on CAN bus
105   Not working:
106     - External mode - throwing syntax error during compilation
107
108 RPP API functions used:
109     - rpp_can_write()
110
111 Relevant demos:
112     - cantransmit
113     - can_demo
114 ...
115 */
116
117
118 #define S_FUNCTION_NAME sfunction_cantransmit
119 #include "header.c"
120 #include <stdio.h>
121 #include "sfun_can_util.h"
122
123 #define MSG_TYPE_STANDART_MAX   2048
124 #define MSG_TYPE_EXTENDED_MAX   536870912
125 #define MAILBOX_ID_MIN                  1
126 #define MAILBOX_MAX_CNT                 64
127
128 #define PARAM_NAME_MODULE_ID    "module_id"
129 #define PARAM_NAME_MAILBOX_ID   "mailbox_id"
130 #define PARAM_NAME_MESSAGE_TYPE "message_type"
131 #define PARAM_NAME_MESSAGE_ID   "message_id"
132 #define PARAM_NAME_MAILBOX_AUTO "mailbox_auto"
133
134 /** Identifier of the input */
135 enum input {
136         IN_MSG,
137         IN_COUNT
138 };
139
140 /** Identifiers of the block parameters */
141 enum params{
142         PARAM_MODULE_ID,
143         PARAM_MAILBOX_ID,
144         PARAM_MSG_TYPE,
145         PARAM_MSG_ID,
146         PARAM_MAILBOX_AUTO,
147         PARAM_COUNT
148 };
149
150 enum message_id_type {
151         MSG_ID_STANDART,
152         MSG_ID_EXTENDED,
153         MSG_ID_MIXED
154 };
155
156
157 static void mdlInitializeSizes(SimStruct *S)
158 {
159
160         CAN_Common_MdlInitSizes(S);
161
162         if (!rppSetNumParams(S, PARAM_COUNT)) {
163                 return;
164         }
165
166         /*
167          * Configure input ports: 1
168          *      - Message to be sent
169          */
170         if (!ssSetNumInputPorts(S, IN_COUNT)) {
171                 return;
172         }
173
174         rppAddInputPort(S, IN_MSG, DYNAMICALLY_TYPED);
175
176         /* No output ports */
177         if (!ssSetNumOutputPorts(S, 0)) {
178                 return;
179         }
180
181         /* Set standard options for this block */
182         rppSetStandardOptions(S);
183 }
184
185 #if defined(MATLAB_MEX_FILE)
186 #define MDL_SET_INPUT_PORT_DATA_TYPE
187 void mdlSetInputPortDataType(SimStruct *S, int_T port, DTypeId type)
188 {
189         if (port == IN_MSG) {
190                 if (type == SS_UINT8 ||
191                     type == SS_UINT16 ||
192                     type == SS_UINT32 ||
193                     /* CAN pack seems to use this data type, but it is
194                      * not registered in sfun_can_util.c. Strange. */
195                     type == ssGetDataTypeId(S, "CAN_MESSAGE") ||
196                     type == ssGetDataTypeId(S, SL_CAN_STANDARD_FRAME_DTYPE_NAME) ||
197                     type == ssGetDataTypeId(S, SL_CAN_EXTENDED_FRAME_DTYPE_NAME))
198                         ssSetInputPortDataType(S, port, type);
199                 else {
200                         char msg[300];
201                         snprintf(msg, sizeof(msg), "Unsupported data type '%s' on Msg input port.",
202                                  ssGetDataTypeName(S, type));
203                         ssSetErrorStatus(S, msg);
204                 }
205         }
206 }
207 #endif
208
209 #ifdef MATLAB_MEX_FILE
210 #define MDL_CHECK_PARAMETERS
211
212 static void mdlCheckParameters(SimStruct *S){
213         /* Check the parameter mailbox id */
214         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_MAILBOX_AUTO))[0] == 0) {
215                 if (!rppValidParamRange(S, PARAM_MAILBOX_ID, MAILBOX_ID_MIN, MAILBOX_ID_MIN + MAILBOX_MAX_CNT)) {
216                         return;
217                 }
218         }
219
220         int min = 0;
221         int max = 0;
222         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_MSG_TYPE))[0] == MSG_ID_STANDART) {
223                 max = MSG_TYPE_STANDART_MAX;
224         }
225         else {
226                 max = MSG_TYPE_EXTENDED_MAX;
227         }
228
229         /* Check the parameter message id */
230         if (!rppValidParamRange(S, PARAM_MSG_ID, min, max)) {
231                 return;
232         }
233 }
234 #endif
235
236
237 #ifdef MATLAB_MEX_FILE
238 #define MDL_SET_WORK_WIDTHS
239 static void mdlSetWorkWidths(SimStruct *S){
240
241         if (!ssSetNumRunTimeParams(S, PARAM_COUNT)) {
242                 return;
243         }
244
245         ssRegDlgParamAsRunTimeParam(S, PARAM_MODULE_ID,  PARAM_MODULE_ID, PARAM_NAME_MODULE_ID, SS_UINT8);
246         ssRegDlgParamAsRunTimeParam(S, PARAM_MAILBOX_ID,  PARAM_MAILBOX_ID, PARAM_NAME_MAILBOX_ID, SS_INT8);
247         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_TYPE,  PARAM_MSG_TYPE, PARAM_NAME_MESSAGE_TYPE, SS_UINT16);   
248         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_ID,  PARAM_MSG_ID, PARAM_NAME_MESSAGE_ID, SS_UINT32); 
249         ssRegDlgParamAsRunTimeParam(S, PARAM_MAILBOX_AUTO,  PARAM_MAILBOX_AUTO, PARAM_NAME_MAILBOX_AUTO, SS_BOOLEAN);     
250 }
251 #endif
252
253 #define COMMON_MDLINITIALIZESAMPLETIMES_INHERIT
254 #define UNUSED_MDLOUTPUTS
255 #define UNUSED_MDLTERMINATE
256 #include "trailer.c"