1 %% Copyright (C) 2014 Czech Technical University in Prague
4 %% Michal Horn <hornmich@fel.cvut.cz>
5 %% Michal Sojka <sojkam1@fel.cvut.cz>
6 %% Pavel Pisa <pisa@cmp.felk.cvut.cz> - author of SocketCAN port
8 %% Redistribution and use in source and binary forms, with or without
9 %% modification, are permitted provided that the following conditions are
12 %% 1. Redistributions of source code must retain the above copyright
13 %% notice, this list of conditions and the following disclaimer.
15 %% 2. Redistributions in binary form must reproduce the above copyright
16 %% notice, this list of conditions and the following disclaimer in the
17 %% documentation and/or other materials provided with the
20 %% 3. Neither the name of the copyright holder nor the names of its
21 %% contributors may be used to endorse or promote products derived
22 %% from this software without specific prior written permission.
24 %% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 %% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 %% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 %% A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 %% HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 %% SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 %% LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 %% DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 %% THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 %% (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 %% OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 %% File : sfunction_cansetup.tlc
38 %% TLC file for configuring the CAN modules on the TI TMS570LS3137 MCU
41 %% BlockTypeSetup() : refs/rtw_tlc.pdf p. 277
42 %% Outputs() : refs/rtw_tlc.pdf p. 281
45 %implements sfunction_cansetup "C"
48 %include "rpp_can_common.tlc"
50 %% Function: BlockTypeSetup ====================================================
51 %function BlockTypeSetup(block, system) void
53 %% Ensure required header files are included
54 %<RppCommonBlockTypeSetup(block, system)>
55 %% %<LibAddToCommonIncludes("<sys/ti_drv_dmm.h>")>
57 %assign ::rpp_can_config_present = 1
59 %<RppCANCommonBlockTypeSetup()>
62 %function BlockInstanceSetup(block, system) void
63 %if EXISTS("rpp_canc_in_model") == 0
64 %assign ::rpp_canc_in_model = 1
66 %<LibBlockReportError(block, "Only one CAN Setup block is allowed in the model.")>
71 %% Function: Start =============================================================
72 %function Start(block, system) Output
75 enum ert_can_msg_types {
81 struct ert_can_channel_config {
82 unsigned int baudrate;
83 const char *net_dev_name;
86 struct ert_can_tx_config {
93 struct ert_can_rx_config {
101 struct ert_can_config {
104 struct ert_can_tx_config *tx_config;
105 struct ert_can_rx_config *rx_config;
106 struct ert_can_channel_config *channel_config;
107 const char **channel_ifname;
110 #define CAN_TX_COUNT %<Rpp.Can.Tx.NumBlocks>
111 #define CAN_RX_COUNT %<Rpp.Can.Rx.NumBlocks>
113 struct ert_can_channel_config can_channel_config[3] = {
115 .baudrate = %<LibBlockParameterValue(baudrate_can1, 0)>
118 .baudrate = %<LibBlockParameterValue(baudrate_can2, 0)>
121 .baudrate = %<LibBlockParameterValue(baudrate_can3, 0)>
125 struct ert_can_tx_config tx_config[CAN_TX_COUNT] = {
126 %foreach id = Rpp.Can.Tx.NumBlocks
127 %with Rpp.Can.Tx.Block[id]
131 .id_type = ERT_CAN_STANDARD,
133 .id_type = ERT_CAN_EXTENDED,
135 .id_type = ERT_CAN_MIXED,
138 .channel = %<Controller>,
139 .msg_obj = %<MsgObj>,
145 struct ert_can_rx_config rx_config[CAN_RX_COUNT] = {
146 %foreach id = Rpp.Can.Rx.NumBlocks
147 %with Rpp.Can.Rx.Block[id]
151 .id_type = ERT_CAN_STANDARD,
153 .id_type = ERT_CAN_EXTENDED,
155 .id_type = ERT_CAN_MIXED,
158 .mask = %<SPRINTF("%#x", Mask)>,
159 .channel = %<Controller>,
160 .msg_obj = %<MsgObj>,
166 const char *ert_can_channel_ifname[] = {
167 "can0", /*FIXME - for now skip this */
174 const struct ert_can_config can_config = {
175 .num_tx_obj = CAN_TX_COUNT,
176 .num_rx_obj = CAN_RX_COUNT,
177 .tx_config = tx_config,
178 .rx_config = rx_config,
179 .channel_config = can_channel_config,
180 .channel_ifname = ert_can_channel_ifname
183 int can_tx_handles[CAN_TX_COUNT];
185 int can_rx_handles[CAN_RX_COUNT];
188 %<LibSetSourceFileSection(LibGetModelDotCFile(), "Declarations", buffer)>
192 for (idx = 0; idx < CAN_TX_COUNT; idx++) {
193 struct ert_can_tx_config *cfg = &can_config.tx_config[idx];
194 const char *ifname = can_config.channel_ifname[cfg->channel];
196 struct sockaddr_can addr;
199 fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
201 printf("CAN socket create error.\n");
204 if(fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
205 printf("CAN socket set O_NONBLOCK error.\n");
208 memset(&addr, 0, sizeof(addr));
209 addr.can_family = AF_CAN;
210 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
211 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
212 printf("CAN socket ioctl SIOCGIFINDEX error.\n");
215 addr.can_ifindex = ifr.ifr_ifindex;
217 /* disable default receive filter on this RAW socket */
218 setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
220 if (bind(fd, (struct sockaddr *)(void*)&addr, sizeof(addr)) < 0) {
221 printf("CAN socket bind error.\n");
224 printf("rx opening %s\n", ifname);
225 can_tx_handles[idx] = fd;
228 for (idx = 0; idx < CAN_RX_COUNT; idx++) {
229 struct ert_can_rx_config *cfg = &can_config.rx_config[idx];
230 const char *ifname = can_config.channel_ifname[cfg->channel];
232 struct sockaddr_can addr;
234 struct can_filter sc_filter;
236 fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
238 printf("CAN socket create error.\n");
241 if(fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
242 printf("CAN socket set O_NONBLOCK error.\n");
245 memset(&addr, 0, sizeof(addr));
246 addr.can_family = AF_CAN;
247 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
248 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
249 printf("CAN socket ioctl SIOCGIFINDEX error.\n");
252 addr.can_ifindex = ifr.ifr_ifindex;
254 /* disable default receive filter on this RAW socket */
255 setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
257 if (bind(fd, (struct sockaddr *)(void*)&addr, sizeof(addr)) < 0) {
258 printf("CAN socket bind error.\n");
262 memset(&sc_filter, 0, sizeof(sc_filter));
263 sc_filter.can_id = cfg->id;
264 sc_filter.can_mask = CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG;
265 if (cfg->id_type == ERT_CAN_EXTENDED)
266 sc_filter.can_id |= CAN_EFF_FLAG;
267 else if(cfg->id_type == ERT_CAN_MIXED)
268 sc_filter.can_mask &= ~CAN_EFF_FLAG;
270 if (setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, &sc_filter, sizeof(sc_filter)) < 0) {
271 printf("CAN socket setsockopt CAN_RAW_FILTER error.\n");
275 printf("tx opening %s\n", ifname);
276 can_rx_handles[idx] = fd;
280 %% printf("CAN communication initialized.\n");