Up Board MCP2515 CAN BUS Ubuntu 18.04 Intel CPU
Hello,
I have the Waveshare 2-CH CAN Hat (https://www.waveshare.com/wiki/2-CH_CAN_HAT) that I am trying to get working correctly with the Up board.
I have gotten the HAT to work on the Up Squared thanks to the instructions in the posts https://forum.up-community.org/discussion/3811/solved-mcp2515-can-bus-ubuntu-18-04-intel-cpu#latest and https://forum.up-community.org/discussion/96/canbus-hat-support. I also used the kernel module code from @nukular, but tweaked a couple of things:
- oscillator_frequency was set to 16000000
- max_speed_hz is 10 * 1000 * 1000
The settings I passed to the kernel module which worked on the Up Squared are:
- gpio_int pin Linux 471 (or GPIO pin 23).
- busnum was 1
- chip_select 0
On the Up board, I've discovered that the busnum has to be 2 and the chip select has to be 1. Otherwise, I get errors in the dmesg logs.
My setup:
I have one Up Squared with the CAN hat and kernel module installed. I've verified it can talk over the CAN hat to another Up Squared with the same CAN hat and kernel module running.
I have one Up board with the CAN hat and kernel module installed.
The Up board and Up Squared board have wires connecting each other on the CAN0 interface, CAN0_H on the Up Squared is connected to CAN0_H on the UP board and CAN0_L on the Up Squared is connected to CAN0_L on the Up board.
The test I've been doing is to run candump can0
on the Up Squared and cansend can0 000#11.22.33.44
on the Up board.
Things I've tried:
I've tried using the following gpio pin options when loading the kernel module:
- 471
- 22
- 23
After using insmod
to load the kernel module with one of the above options and setting up the can0 interface, I tried using cansend
to send a message to the Up Squared. The Up Squared never receives the message.
Has anyone else been able to get the waveshare 2-CH CAN Hat working with the Up board?
Here is the output of dmesg logs:
[ 941.544179] mcp2515_init: init [ 941.544206] mcp2515_init: irq for pin 471 is 157 [ 941.559150] mcp2515_init: device created! [ 941.573040] CAN device driver interface [ 941.617122] mcp251x spi2.1 can0: MCP2515 successfully initialized. [ 969.439637] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready [ 1644.014597] can: controller area network core (rev 20170425 abi 9) [ 1644.014735] NET: Registered protocol family 29 [ 1644.026087] can: raw protocol (rev 20170425) [ 1964.268386] mcp2515_init: exit [ 2067.185173] mcp2515_init: init [ 2067.185269] mcp2515_init: irq for pin 23 is 158 [ 2067.236835] mcp251x spi2.1 can0: MCP2515 successfully initialized. [ 2067.236927] mcp2515_init: device created! [ 2114.461978] up_irq_chip_set_type_parent: type:2, gc->label:up-pinctrl, offset:23 [ 2114.461984] up_irq_chip_set_type_parent: pin->irq:158, pin->soc_gpio.irq:138 [ 2114.461986] up_irq_chip_set_type_parent: no NULL [ 2114.479256] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready [ 2200.669503] x86/PAT: alsa-sink-HdmiL:2800 map pfn RAM range req uncached-minus for [mem 0x3c500000-0x3c556fff], got write-combining [ 2234.067601] x86/PAT: alsa-sink-HdmiL:2800 map pfn RAM range req uncached-minus for [mem 0x3c500000-0x3c556fff], got write-combining [ 2241.640608] mcp2515_init: exit [ 2347.534458] mcp2515_init: init [ 2347.534561] mcp2515_init: irq for pin 22 is 159 [ 2347.582054] mcp251x spi2.1 can0: MCP2515 successfully initialized. [ 2347.582183] mcp2515_init: device created! [ 2367.080299] up_irq_chip_set_type_parent: type:2, gc->label:up-pinctrl, offset:22 [ 2367.080305] up_irq_chip_set_type_parent: pin->irq:159, pin->soc_gpio.irq:137 [ 2367.080307] up_irq_chip_set_type_parent: no NULL [ 2367.103268] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready [ 2843.670977] mcp2515_init: exit
For reference, here is the kernel module code:
#include <linux/init.h> #include <linux/module.h> #include <linux/spi/spi.h> #include <linux/can/platform/mcp251x.h> #include <linux/gpio.h> #include <linux/interrupt.h> int busnum = 2; int chip_select = 1; int gpio_int = 471; module_param(busnum, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); MODULE_PARM_DESC(busnum, "busnum of spi bus to use"); module_param(gpio_int, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); MODULE_PARM_DESC(gpio_int, "linux gpio number of INT gpio"); module_param(chip_select, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); MODULE_PARM_DESC(chip_select, "spi chip select"); int gpio_requested = 0; struct spi_device *dev1; static struct mcp251x_platform_data mcp251x_info = { .oscillator_frequency = 16000000, }; static struct spi_board_info spi_device_info = { .modalias = "mcp2515", .platform_data = &mcp251x_info, .irq = -1, .max_speed_hz = 10 * 1000 * 1000, }; static int __init mcp2515_init(void) { int ret; struct spi_master *master; printk("mcp2515_init: init\n"); ret = gpio_request(gpio_int, "sysfs"); if(ret) { printk("mcp2515_init: could not request gpio %d\n", gpio_int); goto error_postgpio; } gpio_requested = 1; gpio_direction_input(gpio_int); ret = gpio_to_irq(gpio_int); printk("mcp2515_init: irq for pin %d is %d\n", gpio_int, ret); spi_device_info.irq = ret; spi_device_info.bus_num = busnum; spi_device_info.chip_select = chip_select; master = spi_busnum_to_master( spi_device_info.bus_num ); if( !master ) { printk("mcp2515_init: MASTER not found.\n"); ret = -ENODEV; goto error_postgpio; } // create a new slave device, given the master and device info dev1 = spi_new_device( master, &spi_device_info ); if( !dev1) { printk("mcp2515_init: FAILED to create slave.\n"); ret = -ENODEV; goto error_postgpio; } printk("mcp2515_init: device created!\n"); return 0; error_postgpio: gpio_free(gpio_int); return ret; } static void __exit mcp2515_exit(void) { printk("mcp2515_init: exit\n"); if( dev1 ) { spi_unregister_device(dev1); } if(gpio_requested) { gpio_free(gpio_int); } } module_init(mcp2515_init); module_exit(mcp2515_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jeff"); MODULE_DESCRIPTION("MCP2515 init");