%% Copyright (C) 2014 Czech Technical University in Prague %% %% Authors: %% Michal Horn %% Michal Sojka %% Pavel Pisa - author of SocketCAN port %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions are %% met: %% %% 1. Redistributions of source code must retain the above copyright %% notice, this list of conditions and the following disclaimer. %% %% 2. Redistributions in binary form must reproduce the above copyright %% notice, this list of conditions and the following disclaimer in the %% documentation and/or other materials provided with the %% distribution. %% %% 3. Neither the name of the copyright holder nor the names of its %% contributors may be used to endorse or promote products derived %% from this software without specific prior written permission. %% %% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS %% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT %% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR %% A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT %% HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, %% SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT %% LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, %% DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY %% THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT %% (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE %% OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %% %% File : sfunction_cansetup.tlc %% Abstract: %% TLC file for configuring the CAN modules on the TI TMS570LS3137 MCU %% %% References: %% BlockTypeSetup() : refs/rtw_tlc.pdf p. 277 %% Outputs() : refs/rtw_tlc.pdf p. 281 %implements sfunction_cansetup "C" %include "common.tlc" %include "rpp_can_common.tlc" %% Function: BlockTypeSetup ==================================================== %function BlockTypeSetup(block, system) void %% Ensure required header files are included % %% %")> %assign ::rpp_can_config_present = 1 % %endfunction %function BlockInstanceSetup(block, system) void %if EXISTS("rpp_canc_in_model") == 0 %assign ::rpp_canc_in_model = 1 %else % %endif %endfunction %% Function: Start ============================================================= %function Start(block, system) Output %openfile buffer enum ert_can_msg_types { ERT_CAN_STANDARD, ERT_CAN_EXTENDED, ERT_CAN_MIXED, }; struct ert_can_channel_config { unsigned int baudrate; const char *net_dev_name; }; struct ert_can_tx_config { int channel; int id_type; canid_t id; int msg_obj; }; struct ert_can_rx_config { int channel; int id_type; canid_t id; canid_t mask; int msg_obj; }; struct ert_can_config { int num_tx_obj; int num_rx_obj; struct ert_can_tx_config *tx_config; struct ert_can_rx_config *rx_config; struct ert_can_channel_config *channel_config; const char **channel_ifname; }; #define CAN_TX_COUNT % #define CAN_RX_COUNT % struct ert_can_channel_config can_channel_config[3] = { { .baudrate = % }, { .baudrate = % }, { .baudrate = % } }; struct ert_can_tx_config tx_config[CAN_TX_COUNT] = { %foreach id = Rpp.Can.Tx.NumBlocks %with Rpp.Can.Tx.Block[id] // % { %if % == 1 .id_type = ERT_CAN_STANDARD, %elseif % == 2 .id_type = ERT_CAN_EXTENDED, %else .id_type = ERT_CAN_MIXED, %endif .id = %, .channel = %, .msg_obj = %, }, %endwith %endforeach }; struct ert_can_rx_config rx_config[CAN_RX_COUNT] = { %foreach id = Rpp.Can.Rx.NumBlocks %with Rpp.Can.Rx.Block[id] // % { %if %==1 .id_type = ERT_CAN_STANDARD, %elseif %==2 .id_type = ERT_CAN_EXTENDED, %else .id_type = ERT_CAN_MIXED, %endif .id = %, .mask = %, .channel = %, .msg_obj = %, }, %endwith %endforeach }; const char *ert_can_channel_ifname[] = { "can0", /*FIXME - for now skip this */ "can0", "can1", "can2", "can3" }; const struct ert_can_config can_config = { .num_tx_obj = CAN_TX_COUNT, .num_rx_obj = CAN_RX_COUNT, .tx_config = tx_config, .rx_config = rx_config, .channel_config = can_channel_config, .channel_ifname = ert_can_channel_ifname }; int can_tx_handles[CAN_TX_COUNT]; int can_rx_handles[CAN_RX_COUNT]; %closefile buffer % { int idx; for (idx = 0; idx < CAN_TX_COUNT; idx++) { struct ert_can_tx_config *cfg = &can_config.tx_config[idx]; const char *ifname = can_config.channel_ifname[cfg->channel]; int fd; struct sockaddr_can addr; struct ifreq ifr; fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (fd == -1) { printf("CAN socket create error.\n"); exit(1); } if(fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { printf("CAN socket set O_NONBLOCK error.\n"); exit(1); } memset(&addr, 0, sizeof(addr)); addr.can_family = AF_CAN; strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { printf("CAN socket ioctl SIOCGIFINDEX error.\n"); exit(1); } addr.can_ifindex = ifr.ifr_ifindex; /* disable default receive filter on this RAW socket */ setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); if (bind(fd, (struct sockaddr *)(void*)&addr, sizeof(addr)) < 0) { printf("CAN socket bind error.\n"); exit(1); } printf("tx opening %s\n", ifname); can_tx_handles[idx] = fd; } for (idx = 0; idx < CAN_RX_COUNT; idx++) { struct ert_can_rx_config *cfg = &can_config.rx_config[idx]; const char *ifname = can_config.channel_ifname[cfg->channel]; int fd; struct sockaddr_can addr; struct ifreq ifr; struct can_filter sc_filter; fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (fd == -1) { printf("CAN socket create error.\n"); exit(1); } if(fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { printf("CAN socket set O_NONBLOCK error.\n"); exit(1); } memset(&addr, 0, sizeof(addr)); addr.can_family = AF_CAN; strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { printf("CAN socket ioctl SIOCGIFINDEX error.\n"); exit(1); } addr.can_ifindex = ifr.ifr_ifindex; /* disable default receive filter on this RAW socket */ setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); if (bind(fd, (struct sockaddr *)(void*)&addr, sizeof(addr)) < 0) { printf("CAN socket bind error.\n"); exit(1); } memset(&sc_filter, 0, sizeof(sc_filter)); sc_filter.can_id = cfg->id; sc_filter.can_mask = CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; if (cfg->id_type == ERT_CAN_EXTENDED) sc_filter.can_id |= CAN_EFF_FLAG; else if(cfg->id_type == ERT_CAN_MIXED) sc_filter.can_mask &= ~CAN_EFF_FLAG; if (setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, &sc_filter, sizeof(sc_filter)) < 0) { printf("CAN socket setsockopt CAN_RAW_FILTER error.\n"); exit(1); } printf("rx opening %s\n", ifname); can_rx_handles[idx] = fd; } } %%else { %% printf("CAN communication initialized.\n"); %%} %endfunction %% [EOF]