1 /* Copyright (C) 2014 Czech Technical University in Prague
4 * - Michal Horn <hornmich@fel.cvut.cz>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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
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.
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.
34 * File : sfunction_canrecive.c
36 * C-MEX S-function block for RPP CAN bus receive message.
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'])
57 - { name: "f()", type: "Function call" }
58 - { name: "Msg", type: "uint8, uint16, uint32 or CAN MESSAGE" }
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" }
70 # Description is in Markdown mark-up
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.
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.
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.
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.
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.
105 In order to use this block, there must be a `CAN Configure` block in the model.
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
117 - Handling of error states on CAN bus
119 - Receiving at baudrate higher than 700kb
120 - External mode - throwing syntax error during compilation
122 RPP API functions used:
132 #define S_FUNCTION_NAME sfunction_canreceive
136 #include "sfun_can_util.h"
137 #include "simstruc.h"
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
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"
153 /** Identifiers of the block parameters */
166 enum message_data_type {
168 DATA_TYPE_UINT16 = 2,
169 DATA_TYPE_UINT32 = 3,
170 DATA_TYPE_CAN_MESSAGE = 4
173 enum message_id_type {
185 static bool msg_received;
187 static void mdlInitializeSizes(SimStruct *S){
189 CAN_Common_MdlInitSizes(S);
193 if(!rppSetNumParams(S, PARAM_COUNT)) {
198 if(!ssSetNumInputPorts(S, 0)) {
203 * Configure output ports: 1
205 * - Message is received
207 if(!ssSetNumOutputPorts(S, OUT_COUNT)) {
210 rppAddOutputPort(S, OUT_FNC_CALL, SS_FCN_CALL);
212 if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_DATA_TYPE))[0] == DATA_TYPE_UINT8) {
213 rppAddOutputPort(S, OUT_MSG, SS_UINT8);
215 else if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_DATA_TYPE))[0] == DATA_TYPE_UINT16) {
216 rppAddOutputPort(S, OUT_MSG, SS_UINT16);
218 else if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_DATA_TYPE))[0] == DATA_TYPE_UINT32) {
219 rppAddOutputPort(S, OUT_MSG, SS_UINT32);
222 rppAddOutputPort(S, OUT_MSG, ssGetDataTypeId(S, "CAN_MESSAGE"));
225 /* Set standard options for this block */
226 rppSetStandardOptions(S);
230 #ifdef MATLAB_MEX_FILE
231 #define MDL_CHECK_PARAMETERS
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)) {
243 if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_MSG_TYPE))[0] == MSG_ID_STANDART) {
244 max = MSG_TYPE_STANDART_MAX;
247 max = MSG_TYPE_EXTENDED_MAX;
250 /* Check the parameter message identifier */
251 if (!rppValidParamRange(S, PARAM_MSG_ID, min, max)) {
257 static void mdlInitializeSampleTimes(SimStruct *S)
259 ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
260 ssSetOffsetTime(S, 0, 0);
262 ssSetCallSystemOutput(S,0); /* call on first element */
266 #ifdef MATLAB_MEX_FILE
267 #define MDL_SET_WORK_WIDTHS
268 static void mdlSetWorkWidths(SimStruct *S){
270 if(!ssSetNumRunTimeParams(S, PARAM_COUNT)) {
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);
285 #define UNUSED_MDLOUTPUTS
286 #define UNUSED_MDLTERMINATE