]> rtime.felk.cvut.cz Git - pes-rpp/rpp-simulink.git/blob - rpp/blocks/sfunction_canreceive.c
doc: Update documentation of external mode and related stuff
[pes-rpp/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 1 to 64. 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 number.
96   The mailbox numbers are shared between CAN Transmit and CAN Receive
97   blocks with the same CAN port (module) parameter.
98
99   On message reception, the mailboxes and their acceptance filters are
100   consulted in the order of increasing mailbox number. If a message
101   can be accepted by more than one block you may want to assign the
102   mailbox number manually to have better control over which block
103   receives the message.
104
105   The output of this block is a message data in selected format: uint8, uint16, uint32
106   or CAN\_MESSAGE. The CAN\_MESSAGE object can be unpacked by `CAN Unpack` block.
107
108   Every time a message is received, the function call on `f()` output
109   signal is triggered and the received message data is appears on the
110   `Msg` output port. See `cantransmit.slx` demo for examples of
111   different configurations and the usage of the CAN blocks.
112
113   In order to use this block, there must be a `CAN Configure` block in the model.
114
115 Status: Stable
116
117 RPP API functions used:
118     - rpp_can_read()
119
120 Relevant demos:
121     - cantransmit
122     - can_demo
123 ...
124 */
125
126
127 #define S_FUNCTION_NAME sfunction_canreceive
128
129 #include "header.c"
130 #include <stdio.h>
131 #include "sfun_can_util.h"
132 #include "simstruc.h"
133
134 #define MSG_TYPE_STANDART_MAX   2048
135 #define MSG_TYPE_EXTENDED_MAX   536870912
136 #define MAILBOX_ID_MIN                  1
137 #define MAILBOX_MAX_CNT                 64
138
139 #define PARAM_NAME_MODULE_ID    "module_id"
140 #define PARAM_NAME_MAILBOX_ID   "mailbox_id"
141 #define PARAM_NAME_MSG_TYPE             "message_type"
142 #define PARAM_NAME_MSG_ID               "message_id"
143 #define PARAM_NAME_DATA_TYPE    "data_type"
144 #define PARAM_NAME_MSG_FILTER   "message_filter" 
145 #define PARAM_NAME_MSG_MASK             "message_mask"  
146 #define PARAM_NAME_MAILBOX_AUTO "mailbox_auto"
147
148 /** Identifiers of the block parameters */
149 enum params{
150         PARAM_MODULE_ID,
151         PARAM_MAILBOX_ID,
152         PARAM_MSG_TYPE,
153         PARAM_MSG_ID,
154         PARAM_DATA_TYPE,
155         PARAM_MSG_FILTER,
156         PARAM_MSG_MASK,
157         PARAM_MAILBOX_AUTO,
158         PARAM_COUNT
159 };
160
161 enum message_data_type {
162         DATA_TYPE_UINT8 = 1,
163         DATA_TYPE_UINT16 = 2,
164         DATA_TYPE_UINT32 = 3,
165         DATA_TYPE_CAN_MESSAGE = 4
166 };
167
168 enum message_id_type {
169         MSG_ID_STANDART = 1,
170         MSG_ID_EXTENDED,
171         MSG_ID_MIXED
172 };
173
174 enum outputs {
175         OUT_FNC_CALL,
176         OUT_MSG,
177         OUT_COUNT
178 };
179
180 static bool msg_received;
181
182 static void mdlInitializeSizes(SimStruct *S){
183
184         CAN_Common_MdlInitSizes(S);
185
186         /*DTypeId type;*/
187
188         if(!rppSetNumParams(S, PARAM_COUNT)) {
189                 return;
190         }
191
192         /* No input ports */
193         if(!ssSetNumInputPorts(S, 0)) {
194                 return;
195         }
196      
197         /*
198          * Configure output ports: 1
199          *      - Received Message
200          *      - Message is received
201          */
202         if(!ssSetNumOutputPorts(S, OUT_COUNT)) {
203                 return;
204         }
205         rppAddOutputPort(S, OUT_FNC_CALL, SS_FCN_CALL);
206
207         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_DATA_TYPE))[0] == DATA_TYPE_UINT8) {
208                 rppAddOutputPort(S, OUT_MSG, SS_UINT8);
209         }
210         else if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_DATA_TYPE))[0] == DATA_TYPE_UINT16) {
211                 rppAddOutputPort(S, OUT_MSG, SS_UINT16);
212         }
213         else if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_DATA_TYPE))[0] == DATA_TYPE_UINT32) {
214                 rppAddOutputPort(S, OUT_MSG, SS_UINT32);
215         }
216         else {
217                 rppAddOutputPort(S, OUT_MSG, ssGetDataTypeId(S, "CAN_MESSAGE"));
218         }
219
220         /* Set standard options for this block */
221         rppSetStandardOptions(S);
222 }
223
224
225 #ifdef MATLAB_MEX_FILE
226 #define MDL_CHECK_PARAMETERS
227
228 static void mdlCheckParameters(SimStruct *S){
229         int min = 0;
230         int max = 0;
231     /* Check the parameter mailbox number */
232         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_MAILBOX_AUTO))[0] == 0) {
233                 if (!rppValidParamRange(S, PARAM_MAILBOX_ID, MAILBOX_ID_MIN, MAILBOX_ID_MIN + MAILBOX_MAX_CNT)) {
234                         return;
235                 }
236         }
237
238         if ((int_T)mxGetPr(ssGetSFcnParam(S, PARAM_MSG_TYPE))[0] == MSG_ID_STANDART) {
239                 max = MSG_TYPE_STANDART_MAX;
240         }
241         else {
242                 max = MSG_TYPE_EXTENDED_MAX;
243         }
244
245     /* Check the parameter message identifier */
246     if (!rppValidParamRange(S, PARAM_MSG_ID, min, max)) {
247         return;
248     }
249 }
250 #endif
251
252 static void mdlInitializeSampleTimes(SimStruct *S)
253 {
254         ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
255         ssSetOffsetTime(S, 0, 0);
256
257     ssSetCallSystemOutput(S,0);  /* call on first element */
258 }
259
260
261 #ifdef MATLAB_MEX_FILE
262 #define MDL_SET_WORK_WIDTHS
263 static void mdlSetWorkWidths(SimStruct *S){
264
265         if(!ssSetNumRunTimeParams(S, PARAM_COUNT)) {
266         return;
267         }
268
269         ssRegDlgParamAsRunTimeParam(S, PARAM_MODULE_ID,  PARAM_MODULE_ID, PARAM_NAME_MODULE_ID, SS_UINT8);
270         ssRegDlgParamAsRunTimeParam(S, PARAM_MAILBOX_ID,  PARAM_MAILBOX_ID, PARAM_NAME_MAILBOX_ID, SS_INT8);
271         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_TYPE,  PARAM_MSG_TYPE, PARAM_NAME_MSG_TYPE, SS_UINT16);   
272         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_ID,  PARAM_MSG_ID, PARAM_NAME_MSG_ID, SS_UINT32); 
273         ssRegDlgParamAsRunTimeParam(S, PARAM_DATA_TYPE,  PARAM_DATA_TYPE, PARAM_NAME_DATA_TYPE, SS_UINT8);   
274         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_FILTER,  PARAM_MSG_FILTER, PARAM_NAME_MSG_FILTER, SS_UINT8);   
275         ssRegDlgParamAsRunTimeParam(S, PARAM_MSG_MASK,  PARAM_MSG_MASK, PARAM_NAME_MSG_MASK, SS_UINT32);   
276         ssRegDlgParamAsRunTimeParam(S, PARAM_MAILBOX_AUTO,  PARAM_MAILBOX_AUTO, PARAM_NAME_MAILBOX_AUTO, SS_BOOLEAN);   
277 }
278 #endif
279
280 #define UNUSED_MDLOUTPUTS
281 #define UNUSED_MDLTERMINATE
282 #include "trailer.c"