User avatar
schorsch76
Posts: 47
Joined: Sun Apr 28, 2013 8:01 am

[SOLVED] Trying to understand the MCP2515

Mon Aug 15, 2022 11:15 am

I got this HAT PiCAN3 [1]. It works. When i disable the overlay and try to use the spidev with spitest [2] i get no answer from the MCP2515.

As far as i understand the manual of the chip [3] i should send 0xA0 0x00 0x00 to read the status.

Code: Select all

georg@raspberrypi:~/spidev-test $ ./spidev_test -D /dev/spidev0.0 -v -s 10000000 -i test.bin 
spi mode: 0x4
bits per word: 8
max speed: 10000000 Hz (10000 KHz)
TX | A0 00 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | �..
RX | 00 00 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | ...
I also tried other SPI modes but the RX is always 0. With the overlay enabled i can create the can0 interface. Thus i think the spi and the chip is working. I got the resent 64 bit Raspi OS.

If i read through the overlay source [4] i can see that it does:
- Enable spi0 hardware
- Disable spidev 0.0 (fragment 1)
- set interrupt pin to BCM25
- Create a can0_osc
- Create a can0_pins
- create the mcp2515@0 node.

So: What do i miss that the spidev cant read the status?

Just to clearify: I just want to understand what is happening there because in theory, i think i should be able to read the status.....


[1] https://www.elektor.com/pican-3-can-bus ... a-smps-rtc
[2] https://github.com/rm-hull/spidev-test.git
[3] https://ww1.microchip.com/downloads/en/ ... 01801J.pdf
[4] https://github.com/raspberrypi/linux/bl ... verlay.dts

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4655
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: Trying to understand the MCP2515

Mon Aug 15, 2022 12:49 pm

I don't understand where you get "A0 00 00" from - enlighten me.

These two functions from the driver may help:

Code: Select all

        struct mcp251x_priv *priv = spi_get_drvdata(spi);
        u8 value;
        int ret;

        /* Wait for oscillator startup timer after power up */
        mdelay(MCP251X_OST_DELAY_MS);

        priv->spi_tx_buf[0] = INSTRUCTION_RESET;
        ret = mcp251x_spi_write(spi, 1);
        if (ret)
                return ret;

        /* Wait for oscillator startup timer after reset */
        mdelay(MCP251X_OST_DELAY_MS);

        /* Wait for reset to finish */
        ret = mcp251x_read_stat_poll_timeout(spi, value, value == CANCTRL_REQOP_CONF,
                                             MCP251X_OST_DELAY_MS * 1000,
                                             USEC_PER_SEC);
        if (ret)
                dev_err(&spi->dev, "MCP251x didn't enter in conf mode after reset\n");
        return ret;
}

static int mcp251x_hw_probe(struct spi_device *spi)
{
        u8 ctrl;
        int ret;

        ret = mcp251x_hw_reset(spi);
        if (ret)
                return ret;

        ctrl = mcp251x_read_reg(spi, CANCTRL);

        dev_dbg(&spi->dev, "CANCTRL 0x%02x\n", ctrl);

        /* Check for power up default value */
        if ((ctrl & 0x17) != 0x07)
                return -ENODEV;

        return 0;
}
The reset function first waits 5ms (which might be necessary if power has only just be provided to the 2515, but probably not in your case), and sends INSTRUCTION_RESET (the byte 0xc0). It then reads the status register CANSTAT (0x0e) - by sending 0x03 0x0e 0x00 - until the third byte received is CONF (0x80).

User avatar
schorsch76
Posts: 47
Joined: Sun Apr 28, 2013 8:01 am

Re: Trying to understand the MCP2515

Mon Aug 15, 2022 1:43 pm

@PhilE: Thanks! Thats now working! I just missed the reset then read. :mrgreen:

Return to “Device Tree”