Canbus Hat support

Andrew PeaseAndrew Pease Posts: 4New Member
I'm glad there's a lot of effort by the Up team to make Raspberry Pi Hats compatible, but I'm not clear on what is involved. I'm interested in the Up for a relatively low-volume product, but the only thing missing is canbus support. We can make a simple canbus hat that uses an MCP2515 via SPI that the Raspberry Pi supports, but I don't know if that would require driver work by the Up team. Does Linux on the Up use the arm device tree driver infrastructure, or does each hat have to be ported individually?

Comments

  • Dan O'DonovanDan O'Donovan Posts: 218Emutex mod
    Thanks for asking this question!
    The x86-64 kernel for UP doesn't use the ARM Device Tree to register SPI and I2C devices so, to use kernel drivers to manage an I2C or SPI HAT, a little bit of (trivial) extra work is needed to create a small kernel module which registers the SPI device. The code would look something like this:
    ...
    static struct mcp251x_platform_data mcp251x_info = {    .oscillator_frequency = 8000000, };
    static struct spi_board_info canbus_hat_spi_info = {
            .modalias = "mcp2515",
            .platform_data = &mcp251x_info,
            .irq = gpio_to_irq(?),
            .max_speed_hz = 2*1000*1000,
            .bus_num = 2,
            .chip_select = 0,
    };
    ...
    static struct spi_device *dev;
    static int __init canbus_hat_init(void)
    {
    	dev = spi_new_device(spi_busnum_to_master(2), &canbus_hat_spi_info);
    	return dev ? -ENODEV : 0;
    }
    static void __exit canbus_hat_exit(void)
    {
    	if (dev)
    		spi_unregister_device(dev);
    }
    module_init(canbus_hat_init);
    module_exit(canbus_hat_exit);
    MODULE_LICENSE("GPL");
    
    Code taken from this example: https://github.com/MinnowBoard/minnow-max-extras/blob/master/modules/calamari/calamari.c

    We are planning to implement a better solution for this. We want to adopt the approach that MinnowBoard folks are working towards, which is to use ACPI SSDT overlays to register SPI and I2C devices before the OS boots (quite similar to how the Raspberry Pi bootloader uses Device Tree overlays). I'll keep you posted as we make progress on this.
  • Dan O'DonovanDan O'Donovan Posts: 218Emutex mod
    Actually, there have been some recent developments on this (which I haven't had a chance to examine yet) but it is an indication of where this is headed:
    https://lkml.org/lkml/2016/3/31/333
  • Andrew PeaseAndrew Pease Posts: 4New Member
    Thanks for the reply! I look forward to trying one of your boards out, the small kernel module looks reasonably straightforward for my purposes.
  • FedericoFederico Posts: 2New Member
    Androvsky how did you can bus hat implementation ended? I am also looking into it
  • Andrew PeaseAndrew Pease Posts: 4New Member
    I never ended up using the Up board in that project, sorry. I've since moved on to other projects, but I'm still keeping an eye on the Up board for them.
  • MaryemAyadiMaryemAyadi Posts: 4New Member

    @Dan O'Donovan Are there any updates ?? If not yet, can you please explain more ? I just wrote the following Kernel Module and charged it on UP2 but still not wotking :

            #include <linux/module.h>
            #include <linux/init.h>
            #include <linux/kernel.h> 
            #include <linux/can/platform/mcp251x.h> 
            #include <linux/gpio.h> 
            #include <linux/spi/spi.h> 
            #include <config/x86/reroute/for/broken/boot/irqs.h>
            #include <linux/interrupt.h> 
    
    
            MODULE_AUTHOR("Maryem");
            MODULE_DESCRIPTION("exemple de module");
            MODULE_LICENSE("GPL");
    
            static struct mcp251x_platform_data mcp251x_info = {    .oscillator_frequency = 10000000, };
    
            static struct spi_board_info canbus_hat_spi_info = {
                    .modalias = "mcp2515",
                    .platform_data = &mcp251x_info,
                    .irq = gpio_to_irq(430),
                    .max_speed_hz = 10*1000*1000,
                    .bus_num = 0,
                    .chip_select = 0,
            };
    
            static struct spi_device *dev;
    
            static int __init canbus_hat_init(void)
            {   dev = spi_new_device(spi_busnum_to_master(2), &canbus_hat_spi_info);
                return dev ? -ENODEV : 0;
            }
    
    
            static void __exit canbus_hat_exit(void)
            {   if (dev)
                    spi_unregister_device(dev);
            }
    
    
            module_init(canbus_hat_init);
            module_exit(canbus_hat_exit);
    

    Any Ideas ?? :neutral: Thank you !

  • npurtschertnpurtschert Posts: 6New Member
    edited October 23

    @Dan O'Donovan I would like to know about the status of supporting a CAN bus through a SPI or I2C Interface in UP boards. I hope there is a solution for this so far? I would like to make some tests with the UP board and CAN bus like this one: https://copperhilltech.com/pican2-duo-can-bus-board-for-raspberry-pi-2-3/

    I would be glad to hear from you soon.

  • totolitototolito Posts: 1New Member
    edited November 8

    @MaryemAyadi

    Maybe this misstake is your problem:

    canbus_hat_spi_info .bus_num = 0
    but
    spi_busnum_to_master(2) in spi_new_device(...)

    Have a look at spi_board_info definition and identify on which bus you connect your MCP25...

Sign In or Register to comment.