]> rtime.felk.cvut.cz Git - socketcan-simulink.git/blob - blocks/tlc_c/sfunction_canreceive.tlc
Import of CAN support from TMS570 Rapid Prototyping Platform project.
[socketcan-simulink.git] / blocks / tlc_c / sfunction_canreceive.tlc
1 %% Copyright (C) 2014 Czech Technical University in Prague
2 %%
3 %% Authors:
4 %%     Michal Horn  <hornmich@fel.cvut.cz>
5 %%     Michal Sojka <sojkam1@fel.cvut.cz>
6 %%
7 %% Redistribution and use in source and binary forms, with or without
8 %% modification, are permitted provided that the following conditions are
9 %% met:
10 %%
11 %% 1. Redistributions of source code must retain the above copyright
12 %%    notice, this list of conditions and the following disclaimer.
13 %%
14 %% 2. Redistributions in binary form must reproduce the above copyright
15 %%    notice, this list of conditions and the following disclaimer in the
16 %%    documentation and/or other materials provided with the
17 %%    distribution.
18 %%
19 %% 3. Neither the name of the copyright holder nor the names of its
20 %%    contributors may be used to endorse or promote products derived
21 %%    from this software without specific prior written permission.
22 %%
23 %% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 %% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 %% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 %% A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 %% HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 %% SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 %% LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 %% DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 %% THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 %% (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 %% OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 %%
35 %% File : sfunction_canreceive.tlc
36 %% Abstract:
37 %%     TLC file for configuring the CAN RX buffer on the TI TMS570LS3137 MCU
38 %%
39 %% References:
40 %%     BlockTypeSetup() : refs/rtw_tlc.pdf p. 277
41 %%     Outputs()        : refs/rtw_tlc.pdf p. 281
42
43
44 %implements sfunction_canreceive "C"
45
46 %include "common.tlc"
47 %include "rpp_can_common.tlc"
48
49 %% Function: BlockTypeSetup ====================================================
50 %function BlockTypeSetup(block, system) void
51     %<RppCommonBlockTypeSetup(block, system)>
52         %<RppCANCommonBlockTypeSetup()>
53 %endfunction
54
55 %% Function: BlockInstanceSetup ================================================
56 %function BlockInstanceSetup(block, system) void
57
58         %assign module_id_par = LibBlockParameterValue(module_id, 0)
59         %assign mailbox_num_par = LibBlockParameterValue(mailbox_id, 0)
60         %assign message_type_par = LibBlockParameterValue(message_type, 0)
61         %assign message_id_par = LibBlockParameterValue(message_id, 0)
62         %assign data_type_par = LibBlockParameterValue(data_type, 0)
63         %assign message_filter_par = LibBlockParameterValue(message_filter, 0)
64         %assign message_mask_par = LibBlockParameterValue(message_mask, 0)
65         %assign mailbox_auto_par = LibBlockParameterValue(mailbox_auto, 0)
66
67     %if message_filter_par == 1
68             %assign mask = 8388607 %% 0x7FFFFF
69     %else
70             %assign mask = message_mask_par
71     %endif
72
73         %% This seems to be the only way to add a record to an array. The
74         %% other way - creating the record with %createrecord and adding
75         %% it later with %addtorecord doesn't work.
76         %addtorecord Rpp.Can.Rx Block { ...
77           HwObj Rpp.Can.Rx.NumBlocks; ...
78           Controller module_id_par; ...
79           MsgObj 0; /% Invalid MsgObj - proper value will be assigned later %/ ...
80           Type message_type_par; ...
81           Id message_id_par; ...
82           Mask mask; ...
83           Name "%<LibGetBlockName(block)>" ...
84         }
85         %assign blockInfo = Rpp.Can.Rx.Block[Rpp.Can.Rx.NumBlocks] /% create alias to the record %/
86         %if %<mailbox_auto_par>==1
87           %<RppPlaceAutomaticMailboxNumber(blockInfo)>
88         %else
89           %<RppPlaceManualMailboxNumber(blockInfo, mailbox_num_par)>
90         %endif
91
92         /% Remember which blockInfo record is associated wit this block %/
93          %addtorecord block RppRxInfo blockInfo
94         %assign Rpp.Can.Rx.NumBlocks = Rpp.Can.Rx.NumBlocks + 1
95 %endfunction
96
97 %% Function: Start =============================================================
98 %function Start(block, system) Output
99
100     %if !SLibCodeGenForSim()
101
102           %if EXISTS(::rpp_can_config_present) == 0
103                 %<LibBlockReportError(block, "CAN buc configuration block not present!")>
104           %endif
105     %endif
106
107
108 %endfunction
109
110 %% Function: Outputs ===========================================================
111 %function Outputs(block, system) Output
112
113   %if !SLibCodeGenForSim()
114         %assign data_type_par = LibBlockParameterValue(data_type, 0)
115         %assign message = LibBlockOutputSignal(1, "", "", 1)
116
117         {
118           struct rpp_can_pdu pdu;
119           int ret;
120
121           ret = rpp_can_read(%<RppRxInfo.HwObj>, &pdu);
122           switch (ret) {
123             case -RPP_EINVAL:
124                 rpp_sci_printf("Receiving CAN message failed (%s).\n", "%<RppRxInfo.Name>");
125                 break;
126             case -RPP_ENODATA:
127                 break;
128             case SUCCESS: {
129                 %if %<data_type_par>==4
130                   // CAN_MESSAGE
131                   %<message>.Length = pdu.dlc;
132                   %<message>.ID = pdu.id;
133                   int i;
134                   for (i = 0; i < pdu.dlc; i++ ) {
135                         %<message>.Data[i] = pdu.data[i];
136                         %%rpp_sci_printf("%X ", pdu.data[i]);
137                   }
138                 %elseif %<data_type_par>==3
139                   // uint32
140                   int msg =     (pdu.data[0]) |
141                   (pdu.data[1]<<8) |
142                   (pdu.data[2]<<16) |
143                   (pdu.data[3]<<24);
144                   %<message> = msg;
145                   %%rpp_sci_printf("32b: %X ", msg);
146                 %elseif %<data_type_par>==2
147                   // uint16
148                   int msg =     (pdu.data[0]) |
149                   (pdu.data[1]<<8);
150                   %<message> = msg;
151                   %%rpp_sci_printf("16b: %X ", msg);
152                 %else
153                   // uint8
154                   int msg = pdu.data[0];
155                   %<message> = msg;
156                   %%rpp_sci_printf("8b: %X ", msg);
157                 %endif
158                 %%rpp_sci_printf("\n");
159
160                 %% Call a function to process the received message via function-call subsystem
161                 %foreach callIdx = NumSFcnSysOutputCalls
162                   %if LibIsEqual(SFcnSystemOutputCall[callIdx].BlockToCall,"unconnected")
163                         %continue
164                   %endif
165                   %% call the downstream system
166                   %<LibBlockExecuteFcnCall(block, callIdx)>\
167                 %endforeach
168                 break;
169             }
170           }
171         }
172   %endif
173 %endfunction
174
175 %% [EOF]