1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

tests/conn_can: Add can tranceiver

- Add tja1042 pin configuration to tests/can_trx
- Add ncv7356 pin configuration to tests/can_trx
- Add can transceivers to tests/conn_can
- Add tja1042 pin configuration to tests/conn_can
- Add ncv7356 pin configuration to tests/conn_can
- rename print functions
- Add to CFLAGS
This commit is contained in:
Jannes 2019-10-29 13:22:19 +01:00
parent 63a4d126e4
commit f0e994532a
5 changed files with 187 additions and 153 deletions

View File

@ -7,14 +7,25 @@ USEMODULE += ps
USEMODULE += can_trx
TRX_TO_BUILD ?= tja1042 ncv7356
TRX_TO_BUILD ?= tja1042
ifneq (,$(filter tja1042,$(TRX_TO_BUILD)))
USEMODULE += tja1042
TJA1042_STB_PIN ?= GPIO_PIN\(0,0\)
CFLAGS += -DTJA1042_STB_PIN=$(TJA1042_STB_PIN)
endif
ifneq (,$(filter ncv7356,$(TRX_TO_BUILD)))
USEMODULE += ncv7356
NCV7356_MODE0_PIN ?= GPIO_PIN\(0,0\)
NCV7356_MODE1_PIN ?= GPIO_PIN\(0,1\)
CFLAGS += -DNCV7356_MODE0_PIN=$(NCV7356_MODE0_PIN)
CFLAGS += -DNCV7356_MODE1_PIN=$(NCV7356_MODE1_PIN)
endif
# Some boards throw a missing-field-initializers error
CFLAGS += -Wno-missing-field-initializers
include $(RIOTBASE)/Makefile.include

View File

@ -27,102 +27,83 @@
#ifdef MODULE_TJA1042
#include "tja1042.h"
static can_trx_t tja1042 = {
.driver = &tja1042_driver,
tja1042_trx_t tja1042 = { .trx.driver = &tja1042_driver,
.stb_pin = TJA1042_STB_PIN
};
#endif
#ifdef MODULE_NCV7356
#include "ncv7356.h"
static can_trx_t ncv7356 = {
.driver = &ncv7356_driver,
ncv7356_trx_t ncv7356 ={ .trx.driver = &ncv7356_driver,
.mode0_pin = NCV7356_MODE0_PIN,
.mode1_pin = NCV7356_MODE1_PIN
};
#endif
static can_trx_t *devs[] = {
#ifdef MODULE_TJA1042
&tja1042,
(can_trx_t *)&tja1042,
#endif
#ifdef MODULE_NCV7356
&ncv7356,
(can_trx_t *)&ncv7356,
#endif
NULL,
};
static int help(int argc, char **argv)
{
(void)argc;
(void)argv;
puts("Help:");
puts("\tinit [trx_id] - initialize a trx");
puts("\tset_mode [trx_id] [mode] - set a mode on the trx");
printf("trx_id: 0..%u\n", (unsigned)ARRAY_SIZE(devs));
puts("modes:");
puts("\t0: normal mode");
puts("\t1: silent mode");
puts("\t2: standby mode");
puts("\t3: high-speed mode (SW CAN only)");
puts("\t4: high-voltage wakeup mode (SW CAN only)");
return 0;
}
static int init(int argc, char **argv) {
if (argc < 2) {
puts("trx_id needed");
help(0, NULL);
puts("usage: init [trx_id]");
return 1;
}
unsigned trx = atoi(argv[1]);
if (trx < ARRAY_SIZE(devs)) {
int res = can_trx_init(devs[trx]);
if (res >= 0) {
puts("Trx successfully initialized");
return 0;
}
else {
printf("Error when initializing trx: %d\n", res);
}
}
else {
if (trx >= ARRAY_SIZE(devs)) {
puts("Invalid trx_id");
return 1;
}
return 1;
int res = can_trx_init(devs[trx]);
if (res < 0) {
printf("Error when initializing trx: %d\n", res);
return 1;
}
puts("Trx successfully initialized");
return 0;
}
static int set_mode(int argc, char **argv) {
if (argc < 3) {
puts("trx_id and mode needed");
help(0, NULL);
puts("usage: set_mode [trx_id] [mode]");
puts("modes:");
puts("\t0: normal mode");
puts("\t1: silent mode");
puts("\t2: standby mode");
puts("\t3: high-speed mode (SW CAN only)");
puts("\t4: high-voltage wakeup mode (SW CAN only)");
return 1;
}
unsigned trx = atoi(argv[1]);
unsigned mode = atoi(argv[2]);
if ((trx < ARRAY_SIZE(devs)) &&
(mode <= TRX_HIGH_VOLTAGE_WAKE_UP_MODE)) {
int res = can_trx_set_mode(devs[trx], mode);
if (res >= 0) {
puts("Mode successfully set");
return 0;
}
else {
printf("Error when setting mode: %d\n", res);
}
}
else {
if ((trx >= ARRAY_SIZE(devs)) ||
(mode > TRX_HIGH_VOLTAGE_WAKE_UP_MODE)) {
puts("Invalid trx_id or mode");
return 1;
}
return 1;
int res = can_trx_set_mode(devs[trx], mode);
if (res < 0) {
printf("Error when setting mode: %d\n", res);
return 1;
}
puts("Mode successfully set");
return 0;
}
static const shell_command_t cmds[] = {
{ "help", "help", help },
{ "init", "initialize a can trx", init },
{ "set_mode", "set a can trx mode", set_mode },
{ NULL, NULL, NULL },

View File

@ -13,8 +13,32 @@ USEMODULE += can_pm
USEMODULE += can_trx
USEMODULE += auto_init_can
FEATURES_REQUIRED += periph_can
FEATURES_REQUIRED += periph_gpio_irq
TRX_TO_BUILD ?= tja1042
ifneq (,$(filter tja1042,$(TRX_TO_BUILD)))
USEMODULE += tja1042
TJA1042_STB_PIN ?= GPIO_PIN\(0,0\)
CFLAGS += -DTJA1042_STB_PIN=$(TJA1042_STB_PIN)
endif
ifneq (,$(filter ncv7356,$(TRX_TO_BUILD)))
USEMODULE += ncv7356
NCV7356_MODE0_PIN ?= GPIO_PIN\(0,0\)
NCV7356_MODE1_PIN ?= GPIO_PIN\(0,1\)
CFLAGS += -DNCV7356_MODE0_PIN=$(NCV7356_MODE0_PIN)
CFLAGS += -DNCV7356_MODE1_PIN=$(NCV7356_MODE1_PIN)
endif
CFLAGS += -DGNRC_PKTBUF_SIZE=4096
CFLAGS += -DCAN_PKT_BUF_SIZE=64
CFLAGS += -DCAN_ROUTER_MAX_FILTER=32
# Some boards throw a missing-field-initializers error
CFLAGS += -Wno-missing-field-initializers
include $(RIOTBASE)/Makefile.include

View File

@ -3,62 +3,11 @@ tests/conn_can
Demo application for the CAN stack with conn_can interface.
Native prerequisites
============
For using the can stack on top of socketCAN, available for linux, you need:
- socketCAN (part of kernel starting from 2.6.25)
- install the 32bit version of libsocketcan:
if you're on a 64bit system:
```
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libsocketcan-dev:i386
```
On 32 bit you can just do the following:
```
sudo apt-get install libsocketcan-dev
```
Alternatively, you can compile from source:
```
wget http://www.pengutronix.de/software/libsocketcan/download/libsocketcan-0.0.10.tar.bz2
$ sudo tar xvjf libsocketcan-0.0.10.tar.bz2
$ sudo rm -rf libsocketcan-0.0.10.tar.bz2
$ sudo cd libsocketcan-0.0.10
$ sudo ./configure
compile in 32bits
./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAG
$ sudo make
$ sudo make install
sudo ldconfig
/usr/local/lib
```
The default native configuration defines two virtual can ifaces to be used.
Before running this test on native, you should create those:
```
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link add dev vcan1 type vcan
sudo ip link set vcan0 up
sudo ip link set vcan1 up
```
Usage
=====
Adapt pin configuration in Makefile to match the used CAN transceiver (e.g. TJA1042_STB_PIN)
Build, flash and start the application:
```
export BOARD=your_board
@ -67,6 +16,16 @@ make flash
make term
```
To initialize a CAN transceiver device (trx_id = 0)
```
init 0
```
To set a CAN transceiver device's (trx_id = 0) mode to TRX_NORMAL_MODE
```
set_mode 0 0
```
The CAN interfaces are registered at startup to the dll. The list of registered
interfaces and their RIOT names can be retrieved with:
```
@ -125,36 +84,3 @@ sampling point 87.5%:
```
test_can set_bitrate 250000 875
```
Linux CAN basic commands
========================
Once the interfaces are set up, can-utils commands provide a way to send and receive
raw CAN frames and ISO-TP datagrams.
For ISO-TP, an experimental module for linux can be found [here](https://github.com/hartkopp/can-isotp).
It needs to be loaded before trying to use ISO-TP protocol.
Here are some basics examples.
Send a raw CAN frame, id 0x100, data 00 11 22:
```
cansend vcan0 100#001122
```
Dump the traffic on a CAN interface:
```
candump vcan0
```
Send an ISO-TP datagram, source id 700, dest id 708, data 00 11 22 33 aa bb cc dd:
```
echo 00 11 22 33 aa bb cc dd | isotpsend -s 700 -d 708 vcan0
```
Receive ISO-TP datagram:
```
isotprecv -s 708 -d 700 vcan0
```
Please read commands help for more details on usage.

View File

@ -32,6 +32,33 @@
#include "can/conn/isotp.h"
#include "can/device.h"
#include "can/can_trx.h"
#ifdef MODULE_TJA1042
#include "tja1042.h"
tja1042_trx_t tja1042 = { .trx.driver = &tja1042_driver,
.stb_pin = TJA1042_STB_PIN
};
#endif
#ifdef MODULE_NCV7356
#include "ncv7356.h"
ncv7356_trx_t ncv7356 = { .trx.driver = &ncv7356_driver,
.mode0_pin = NCV7356_MODE0_PIN,
.mode1_pin = NCV7356_MODE1_PIN
};
#endif
static can_trx_t *devs[] = {
#ifdef MODULE_TJA1042
(can_trx_t *)&tja1042,
#endif
#ifdef MODULE_NCV7356
(can_trx_t *)&ncv7356,
#endif
NULL,
};
#define THREAD_STACKSIZE (THREAD_STACKSIZE_MAIN)
#define RECEIVE_THREAD_MSG_QUEUE_SIZE (8)
@ -67,8 +94,9 @@ static void print_usage(void)
{
puts("test_can list");
puts("test_can send ifnum can_id [B1 [B2 [B3 [B4 [B5 [B6 [B7 [B8]]]]]]]]");
puts("test_can sendrtr ifnum can_id lenght(0..8)");
printf("test_can recv ifnum user_id timeout can_id1 [can_id2..can_id%d]\n", MAX_FILTER);
puts("test_can sendrtr ifnum can_id length(0..8)");
printf("test_can recv ifnum user_id timeout can_id1 [can_id2..can_id%d]\n",
MAX_FILTER);
puts("test_can close user_id");
#ifdef MODULE_CAN_ISOTP
puts("test_can bind_isotp ifnum user_id source_id dest_id");
@ -237,7 +265,8 @@ static int _bind_isotp(int argc, char **argv)
isotp_opt.rx_id = strtoul(argv[5], NULL, 16);
#ifdef MODULE_CONN_CAN_ISOTP_MULTI
conn_can_isotp_init_slave(&conn_isotp[thread_nb], (conn_can_isotp_slave_t *)&conn_isotp[thread_nb]);
conn_can_isotp_init_slave(&conn_isotp[thread_nb], (conn_can_isotp_slave_t *)
&conn_isotp[thread_nb]);
#endif
ret = conn_can_isotp_create(&conn_isotp[thread_nb], &isotp_opt, ifnum);
if (ret == 0) {
@ -578,11 +607,14 @@ static void *_receive_thread(void *args)
case CAN_MSG_RECV:
{
int ret;
while ((ret = conn_can_raw_recv(&conn[thread_nb], &frame, msg.content.value))
while ((ret = conn_can_raw_recv(&conn[thread_nb], &frame,
msg.content.value))
== sizeof(struct can_frame)) {
printf("%d: %-8s %" PRIx32 " [%x] ",
thread_nb, raw_can_get_name_by_ifnum(conn[thread_nb].ifnum),
frame.can_id, frame.can_dlc);
thread_nb,
raw_can_get_name_by_ifnum(conn[thread_nb].ifnum),
frame.can_id,
frame.can_dlc);
for (int i = 0; i < frame.can_dlc; i++) {
printf(" %02X", frame.data[i]);
}
@ -597,11 +629,14 @@ static void *_receive_thread(void *args)
case CAN_MSG_RECV_ISOTP:
{
int ret;
while ((ret = conn_can_isotp_recv(&conn_isotp[thread_nb], isotp_buf[thread_nb],
ISOTP_BUF_SIZE, msg.content.value))
while ((ret = conn_can_isotp_recv(&conn_isotp[thread_nb],
isotp_buf[thread_nb],
ISOTP_BUF_SIZE, msg.content.value))
<= ISOTP_BUF_SIZE && ret >= 0) {
printf("%d: %-8s ISOTP [%d] ",
thread_nb, raw_can_get_name_by_ifnum(conn_isotp[thread_nb].ifnum), ret);
thread_nb,
raw_can_get_name_by_ifnum(conn_isotp[thread_nb].ifnum),
ret);
for (int i = 0; i < ret; i++) {
printf(" %02X", isotp_buf[thread_nb][i]);
}
@ -614,7 +649,8 @@ static void *_receive_thread(void *args)
{
msg_t reply;
can_opt_t *opt = msg.content.ptr;
int ret = conn_can_isotp_send(&conn_isotp[thread_nb], opt->data, opt->data_len, 0);
int ret = conn_can_isotp_send(&conn_isotp[thread_nb], opt->data,
opt->data_len, 0);
reply.type = msg.type;
reply.content.value = ret;
msg_reply(&msg, &reply);
@ -622,7 +658,8 @@ static void *_receive_thread(void *args)
}
#endif /* MODULE_CAN_ISOTP */
default:
printf("%d: _receive_thread: received unknown message\n", thread_nb);
printf("%d: _receive_thread: received unknown message\n",
thread_nb);
break;
}
}
@ -630,8 +667,63 @@ static void *_receive_thread(void *args)
return NULL;
}
static int init(int argc, char **argv) {
if (argc < 2) {
puts("usage: init [trx_id]");
return 1;
}
unsigned trx = atoi(argv[1]);
if (trx >= ARRAY_SIZE(devs)) {
puts("Invalid trx_id");
return 1;
}
int res = can_trx_init(devs[trx]);
if (res < 0) {
printf("Error when initializing trx: %d\n", res);
return 1;
}
puts("Trx successfully initialized");
return 0;
}
static int set_mode(int argc, char **argv) {
if (argc < 3) {
puts("usage: set_mode [trx_id] [mode]");
puts("modes:");
puts("\t0: normal mode");
puts("\t1: silent mode");
puts("\t2: standby mode");
puts("\t3: high-speed mode (SW CAN only)");
puts("\t4: high-voltage wakeup mode (SW CAN only)");
return 1;
}
unsigned trx = atoi(argv[1]);
unsigned mode = atoi(argv[2]);
if ((trx >= ARRAY_SIZE(devs)) ||
(mode > TRX_HIGH_VOLTAGE_WAKE_UP_MODE)) {
puts("Invalid trx_id or mode");
return 1;
}
int res = can_trx_set_mode(devs[trx], mode);
if (res < 0) {
printf("Error when setting mode: %d\n", res);
return 1;
}
puts("Mode successfully set");
return 0;
}
static const shell_command_t _commands[] = {
{"test_can", "Test CAN functions", _can_handler},
{ "init", "initialize a can trx", init },
{ "set_mode", "set a can trx mode", set_mode },
{ NULL, NULL, NULL},
};