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