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:
parent
63a4d126e4
commit
f0e994532a
@ -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
|
||||
|
@ -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 },
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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},
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user