1 %% Copyright (C) 2014 Czech Technical University in Prague
4 %% Michal Horn <hornmich@fel.cvut.cz>
5 %% Michal Sojka <sojkam1@fel.cvut.cz>
7 %% Redistribution and use in source and binary forms, with or without
8 %% modification, are permitted provided that the following conditions are
11 %% 1. Redistributions of source code must retain the above copyright
12 %% notice, this list of conditions and the following disclaimer.
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
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.
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.
35 %% File : sfunction_cansetup.tlc
37 %% TLC file for configuring the CAN modules on the TI TMS570LS3137 MCU
40 %% BlockTypeSetup() : refs/rtw_tlc.pdf p. 277
41 %% Outputs() : refs/rtw_tlc.pdf p. 281
44 %implements sfunction_cansetup "C"
47 %include "rpp_can_common.tlc"
49 %% Function: BlockTypeSetup ====================================================
50 %function BlockTypeSetup(block, system) void
52 %% Ensure required header files are included
53 %<RppCommonBlockTypeSetup(block, system)>
54 %% %<LibAddToCommonIncludes("<sys/ti_drv_dmm.h>")>
56 %assign ::rpp_can_config_present = 1
58 %<RppCANCommonBlockTypeSetup()>
61 %function BlockInstanceSetup(block, system) void
62 %if EXISTS("rpp_canc_in_model") == 0
63 %assign ::rpp_canc_in_model = 1
65 %<LibBlockReportError(block, "Only one CAN Setup block is allowed in the model.")>
70 %% Function: Start =============================================================
71 %function Start(block, system) Output
74 enum ert_can_msg_types {
80 struct ert_can_channel_config {
81 unsigned int baudrate;
82 const char *net_dev_name;
85 struct ert_can_tx_config {
92 struct ert_can_rx_config {
100 struct ert_can_config {
103 struct ert_can_tx_config *tx_config;
104 struct ert_can_rx_config *rx_config;
105 struct ert_can_channel_config *channel_config;
106 const char **channel_ifname;
109 #define CAN_TX_COUNT %<Rpp.Can.Tx.NumBlocks>
110 #define CAN_RX_COUNT %<Rpp.Can.Rx.NumBlocks>
112 struct ert_can_channel_config can_channel_config[3] = {
114 .baudrate = %<LibBlockParameterValue(baudrate_can1, 0)>
117 .baudrate = %<LibBlockParameterValue(baudrate_can2, 0)>
120 .baudrate = %<LibBlockParameterValue(baudrate_can3, 0)>
124 struct ert_can_tx_config tx_config[CAN_TX_COUNT] = {
125 %foreach id = Rpp.Can.Tx.NumBlocks
126 %with Rpp.Can.Tx.Block[id]
130 .id_type = ERT_CAN_STANDARD,
132 .id_type = ERT_CAN_EXTENDED,
134 .id_type = ERT_CAN_MIXED,
137 .channel = %<Controller>,
138 .msg_obj = %<MsgObj>,
144 struct ert_can_rx_config rx_config[CAN_RX_COUNT] = {
145 %foreach id = Rpp.Can.Rx.NumBlocks
146 %with Rpp.Can.Rx.Block[id]
150 .id_type = ERT_CAN_STANDARD,
152 .id_type = ERT_CAN_EXTENDED,
154 .id_type = ERT_CAN_MIXED,
157 .mask = %<SPRINTF("%#x", Mask)>,
158 .channel = %<Controller>,
159 .msg_obj = %<MsgObj>,
165 const char *ert_can_channel_ifname[] = {
166 "can0", /*FIXME - for now skip this */
173 const struct ert_can_config can_config = {
174 .num_tx_obj = CAN_TX_COUNT,
175 .num_rx_obj = CAN_RX_COUNT,
176 .tx_config = tx_config,
177 .rx_config = rx_config,
178 .channel_config = can_channel_config,
179 .channel_ifname = ert_can_channel_ifname
182 int can_tx_handles[CAN_TX_COUNT];
184 int can_rx_handles[CAN_RX_COUNT];
187 %<LibSetSourceFileSection(LibGetModelDotCFile(), "Declarations", buffer)>
191 for (idx = 0; idx < CAN_TX_COUNT; idx++) {
192 struct ert_can_tx_config *cfg = &can_config.tx_config[idx];
193 const char *ifname = can_config.channel_ifname[cfg->channel];
195 struct sockaddr_can addr;
198 fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
200 printf("CAN socket create error.\n");
203 if(fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
204 printf("CAN socket set O_NONBLOCK error.\n");
207 memset(&addr, 0, sizeof(addr));
208 addr.can_family = AF_CAN;
209 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
210 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
211 printf("CAN socket ioctl SIOCGIFINDEX error.\n");
214 addr.can_ifindex = ifr.ifr_ifindex;
216 /* disable default receive filter on this RAW socket */
217 setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
219 if (bind(fd, (struct sockaddr *)(void*)&addr, sizeof(addr)) < 0) {
220 printf("CAN socket bind error.\n");
223 printf("rx opening %s\n", ifname);
224 can_tx_handles[idx] = fd;
227 for (idx = 0; idx < CAN_RX_COUNT; idx++) {
228 struct ert_can_rx_config *cfg = &can_config.rx_config[idx];
229 const char *ifname = can_config.channel_ifname[cfg->channel];
231 struct sockaddr_can addr;
233 struct can_filter sc_filter;
235 fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
237 printf("CAN socket create error.\n");
240 if(fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
241 printf("CAN socket set O_NONBLOCK error.\n");
244 memset(&addr, 0, sizeof(addr));
245 addr.can_family = AF_CAN;
246 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
247 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
248 printf("CAN socket ioctl SIOCGIFINDEX error.\n");
251 addr.can_ifindex = ifr.ifr_ifindex;
253 /* disable default receive filter on this RAW socket */
254 setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
256 if (bind(fd, (struct sockaddr *)(void*)&addr, sizeof(addr)) < 0) {
257 printf("CAN socket bind error.\n");
261 memset(&sc_filter, 0, sizeof(sc_filter));
262 sc_filter.can_id = cfg->id;
263 sc_filter.can_mask = CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG;
264 if (cfg->id_type == ERT_CAN_EXTENDED)
265 sc_filter.can_id |= CAN_EFF_FLAG;
266 else if(cfg->id_type == ERT_CAN_MIXED)
267 sc_filter.can_mask &= ~CAN_EFF_FLAG;
269 if (setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, &sc_filter, sizeof(sc_filter)) < 0) {
270 printf("CAN socket setsockopt CAN_RAW_FILTER error.\n");
274 printf("tx opening %s\n", ifname);
275 can_rx_handles[idx] = fd;
279 %% printf("CAN communication initialized.\n");