]> rtime.felk.cvut.cz Git - socketcan-simulink.git/blob - blocks/sfunction_canreceive.c
Include actual and requested position visualization in robotic arm model.
[socketcan-simulink.git] / blocks / sfunction_canreceive.c
1 /* Copyright (C) 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_canrecive.c
35  * Abstract:
36  *     C-MEX S-function block for RPP CAN bus receive 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_canreceive.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 Receive
50 Category: CAN
51 Header: rpp/can.h
52 Mnemonic: CANR
53
54 Inputs:
55
56 Outputs:
57   - { name: "f()", type: "Function call"                        }
58   - { name: "Msg", type: "uint8, uint16, uint32 or CAN MESSAGE" }
59
60 Parameters:
61   - { name: "Module",                   type: "Choice", range: "CAN1, CAN2, CAN3"                        }
62   - { name: "Message ID type",          type: "Choice", range: "Standard, Extended, Mixed"               }
63   - { name: "Message ID filter",        type: "Choice", range: "Single ID, ID and mask"                  }
64   - { name: "Message ID",               type: "uint32"                                                   }
65   - { name: "Message ID mask",          type: "uint8"                                                    }
66   - { name: "Data type",                type: "Choice", range: "uint8, uint16, uint32, CAN MESSAGE TYPE" }
67   - { name: "Automatic mailbox number", type: "bool"                                                     }
68   - { name: "Mailbox number (0-31)",    type: "int8"                                                    }
69
70 # Description is in Markdown mark-up
71 Description: |
72
73   This block allows receiving messages from the CAN bus. It can be
74   configured for any of the CAN ports (modules) CAN1, CAN2 or CAN3.
75
76   The acceptance rules for message reception can be specified by a
77   *Message ID* parameter and optionally by a *Message ID mask*.
78   Specifying the mask allows to receive messages with multiple IDs.
79   The block supports both, the Standard (11b ID) and the Extended (29b
80   ID) frame formats. Note that if Mixed message ID type is selected,
81   the blocks will receive both frame types, but the Standard Message
82   ID and optionally the Message ID mask has to be shifted by 18 bits
83   to the left to correspond with the extended IDs and masks. For
84   example, if Message ID parameter is set to 0x80000 and mask
85   to 0x1ffbfff, the block will receive SFF messages with IDs 0x002 and
86   0x003 and EFF IDs 0x00080000 and 0x000c0000.
87
88   The mailbox number can be assigned automatically or manually. Automatic mailbox
89   numbers are generated in ascending order from 0 to 31. Every mailbox must have a unique
90   number. It is possible to mix blocks with automatically and manually
91   assigned mailboxes. If the manually assigned mailbox number would
92   collide with the automatic one then the automatically generated
93   block will get assigned a next higher non-colliding ID.
94   The mailbox numbers are shared between CAN Transmit and CAN Receive
95   blocks with the same CAN port (module) parameter.
96
97   The output of this block is a message data in selected format: uint8, uint16, uint32
98   or CAN\_MESSAGE. The CAN\_MESSAGE object can be unpacked by `CAN Unpack` block.
99
100   Every time a message is received, the function call on `f()` output
101   signal is triggered and the received message data is appears on the
102   `Msg` output port. See `cantransmit.slx` demo for examples of
103   different configurations and the usage of the CAN blocks.
104
105   In order to use this block, there must be a `CAN Configure` block in the model.
106
107 Status:
108   Tested:
109     - Reception of messages with a configured ID.
110     - Rejection of messages with other ID then the configured one. FIXME
111     - Reception of messages with a set of IDs specified by a ID and mask.
112     - Reception of messages with Standard ID type, rejection of the messages with Extended ID type and vice versa.
113     - Reception of messages with both messages ID types.
114     - Automatic generation of mailboxes numbers with combination with manual specification, duplicate mailbox numbers detection.
115     - Function call triggering when new message is accepted
116   Untested:
117     - Handling of error states on CAN bus
118   Not working:
119     - Receiving at baudrate higher than 700kb
120     - External mode - throwing syntax error during compilation
121
122 RPP API functions used:
123     - rpp_can_read()
124
125 Relevant demos:
126     - cantransmit
127     - can_demo
128 ...
129 */
130
131
132 #define S_FUNCTION_NAME sfunction_canreceive
133
134 #include "header.c"
135 #include <stdio.h>
136 #include "sfun_can_util.h"
137 #include "simstruc.h"
138
139 #define MSG_TYPE_STANDART_MAX   2048
140 #define MSG_TYPE_EXTENDED_MAX   536870912
141 #define MAILBOX_ID_MIN                  1
142 #define MAILBOX_MAX_CNT                 64
143
144 #define PARAM_NAME_MODULE_ID    "module_id"
145 #define PARAM_NAME_MAILBOX_ID   "mailbox_id"
146 #define PARAM_NAME_MSG_TYPE             "message_type"
147 #define PARAM_NAME_MSG_ID               "message_id"
148 #define PARAM_NAME_DATA_TYPE    "data_type"
149 #define PARAM_NAME_MSG_FILTER   "message_filter" 
150 #define PARAM_NAME_MSG_MASK             "message_mask"  
151 #define PARAM_NAME_MAILBOX_AUTO "mailbox_auto"
152
153 /** Identifiers of the block parameters */
154 enum params{
155         PARAM_MODULE_ID,
156         PARAM_MAILBOX_ID,
157         PARAM_MSG_TYPE,
158         PARAM_MSG_ID,
159         PARAM_DATA_TYPE,
160         PARAM_MSG_FILTER,
161         PARAM_MSG_MASK,
162         PARAM_MAILBOX_AUTO,
163         PARAM_COUNT
164 };
165
166 enum message_data_type {
167         DATA_TYPE_UINT8 = 1,
168         DATA_TYPE_UINT16 = 2,
169         DATA_TYPE_UINT32 = 3,
170         DATA_TYPE_CAN_MESSAGE = 4
171 };
172
173 enum message_id_type {
174         MSG_ID_STANDART,
175         MSG_ID_EXTENDED,
176         MSG_ID_MIXED
177 };
178
179 enum outputs {
180         OUT_FNC_CALL,
181         OUT_MSG,
182         OUT_COUNT
183 };
184
185 static bool msg_received;
186
187 static void mdlInitializeSizes(SimStruct *S){
188
189         CAN_Common_MdlInitSizes(S);
190
191         /*DTypeId type;*/
192
193         if(!rppSetNumParams(S, PARAM_COUNT)) {
194                 return;
195         }
196
197         /* No input ports */
198         if(!ssSetNumInputPorts(S, 0)) {
199                 return;
200         }
201      
202         /*
203          * Configure output ports: 1
204          *      - Received Message
205          *      - Message is received
206          */
207         if(!ssSetNumOutputPorts(S, OUT_COUNT)) {
208                 return;
209         }
210         rppAddOutputPort(S, OUT_FNC_CALL, SS_FCN_CALL);
211
212         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_DATA_TYPE))[0] == DATA_TYPE_UINT8) {
213                 rppAddOutputPort(S, OUT_MSG, SS_UINT8);
214         }
215         else if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_DATA_TYPE))[0] == DATA_TYPE_UINT16) {
216                 rppAddOutputPort(S, OUT_MSG, SS_UINT16);
217         }
218         else if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_DATA_TYPE))[0] == DATA_TYPE_UINT32) {
219                 rppAddOutputPort(S, OUT_MSG, SS_UINT32);
220         }
221         else {
222                 rppAddOutputPort(S, OUT_MSG, ssGetDataTypeId(S, "CAN_MESSAGE"));
223         }
224
225         /* Set standard options for this block */
226         rppSetStandardOptions(S);
227 }
228
229
230 #ifdef MATLAB_MEX_FILE
231 #define MDL_CHECK_PARAMETERS
232
233 static void mdlCheckParameters(SimStruct *S){
234     /* Check the parameter mailbox number */
235         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_MAILBOX_AUTO))[0] == 0) {
236                 if (!rppValidParamRange(S, PARAM_MAILBOX_ID, MAILBOX_ID_MIN, MAILBOX_ID_MIN + MAILBOX_MAX_CNT)) {
237                         return;
238                 }
239         }
240
241         int min = 0;
242         int max = 0;
243         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_MSG_TYPE))[0] == MSG_ID_STANDART) {
244                 max = MSG_TYPE_STANDART_MAX;
245         }
246         else {
247                 max = MSG_TYPE_EXTENDED_MAX;
248         }
249
250     /* Check the parameter message identifier */
251     if (!rppValidParamRange(S, PARAM_MSG_ID, min, max)) {
252         return;
253     }
254 }
255 #endif
256
257 static void mdlInitializeSampleTimes(SimStruct *S)
258 {
259         ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
260         ssSetOffsetTime(S, 0, 0);
261
262     ssSetCallSystemOutput(S,0);  /* call on first element */
263 }
264
265
266 #ifdef MATLAB_MEX_FILE
267 #define MDL_SET_WORK_WIDTHS
268 static void mdlSetWorkWidths(SimStruct *S){
269
270         if(!ssSetNumRunTimeParams(S, PARAM_COUNT)) {
271         return;
272         }
273
274         ssRegDlgParamAsRunTimeParam(S, PARAM_MODULE_ID,  PARAM_MODULE_ID, PARAM_NAME_MODULE_ID, SS_UINT8);
275         ssRegDlgParamAsRunTimeParam(S, PARAM_MAILBOX_ID,  PARAM_MAILBOX_ID, PARAM_NAME_MAILBOX_ID, SS_INT8);
276         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_TYPE,  PARAM_MSG_TYPE, PARAM_NAME_MSG_TYPE, SS_UINT16);   
277         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_ID,  PARAM_MSG_ID, PARAM_NAME_MSG_ID, SS_UINT32); 
278         ssRegDlgParamAsRunTimeParam(S, PARAM_DATA_TYPE,  PARAM_DATA_TYPE, PARAM_NAME_DATA_TYPE, SS_UINT8);   
279         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_FILTER,  PARAM_MSG_FILTER, PARAM_NAME_MSG_FILTER, SS_UINT8);   
280         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_MASK,  PARAM_MSG_MASK, PARAM_NAME_MSG_MASK, SS_UINT32);   
281         ssRegDlgParamAsRunTimeParam(S, PARAM_MAILBOX_AUTO,  PARAM_MAILBOX_AUTO, PARAM_NAME_MAILBOX_AUTO, SS_BOOLEAN);   
282 }
283 #endif
284
285 #define UNUSED_MDLOUTPUTS
286 #define UNUSED_MDLTERMINATE
287 #include "trailer.c"