4
\$\begingroup\$

I have a board with a working SPI interface. I can read one slave via the SPI interface successfully.

When I try to read data or get a status on a secondary slave, the MCP2515 IC, I'm not getting any response. I have verified the connections by using a voltmeter continuity test, I have verified the ground and voltage connections to the IC. I understand that the MCP2515 is unique in how it initializes at start-up per the datasheet. I have tried numerous initialization sequences with no success. I am beginning to think I have a bad IC, but I would like to be able to test it and prove that theory.

The only other issue I can think of is a possible clocking issue. I have a 16 MHz crystal on the MCU and a 16 MHz crystal on the MCP2515 per the datasheet. Both have 22 pF capacitors. If the clocking is off, I think I would at least get garbage. Can someone look at the code and validate it looks good and that I do in fact have a clocking or hardware issue?

bool mcp2515_init(void)
{
    char str[80];
    unsigned int test_value;

    SET(MCP2515_CS);
    SET_OUTPUT(MCP2515_CS);

    SET(USB_CS);
    //SET_OUTPUT(USB_CS);

    SET(SD_CS);
    //SET_OUTPUT(SD_CS);

    RESET(P_SCK);
    RESET(P_MOSI);
    RESET(P_MISO);

    SET_OUTPUT(P_SCK);
    SET_OUTPUT(P_MOSI);
    SET_INPUT(P_MISO);

    SET_INPUT(MCP2515_INT);
    SET(MCP2515_INT);

    // Active SPI master interface
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
    SPSR = 0;

    // Reset MCP2515 by software reset.
    // After this it is in configuration mode.
    RESET(MCP2515_CS);
    spi_putc(SPI_RESET);
    SET(MCP2515_CS);

    // Wait a little bit until the MCP2515 has restarted
    _delay_us(15);

    // Load CNF1..3 Register
    RESET(MCP2515_CS);

    spi_putc(SPI_WRITE);
    spi_putc(CNF3);

    spi_putc((1<<PHSEG21));  // Bitrate 125 kbps at 16 MHz
    spi_putc((1<<BTLMODE)|(1<<PHSEG11));
    spi_putc((1<<BRP2)|(1<<BRP1)|(1<<BRP0));



    // Activate interrupts
    spi_putc((1<<RX1IE)|(1<<RX0IE));
    SET(MCP2515_CS);


    test_value = mcp2515_read_register(CANCTRL);
    sprintf(str, "test value is [%d]\n\n",test_value);
    UART1_TxString(str);

    // Test if we could read back the value => is the chip accessible?
    if (mcp2515_read_register(CNF1) != ((1<<BRP2)|(1<<BRP1)|(1<<BRP0))) {

        return false;
    }

    // Deactivate the RXnBF pins (high impedance state)
    mcp2515_write_register(BFPCTRL, 0);

    // Set TXnRTS as inputs
    mcp2515_write_register(TXRTSCTRL, 0);

    // Turn off filters => receive any message
    mcp2515_write_register(RXB0CTRL, (1<<RXM1)|(1<<RXM0));
    mcp2515_write_register(RXB1CTRL, (1<<RXM1)|(1<<RXM0));

    // Reset device to normal mode
    mcp2515_write_register(CANCTRL, 0);

    return true;
}
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Do you have a scope to monitor the lines? \$\endgroup\$
    – Eugene Sh.
    Jan 17 '17 at 15:16
  • \$\begingroup\$ Unfortunately, no. I have a JTAG interface for debugging and I have AtmelICE debugger \$\endgroup\$
    – Eddie
    Jan 17 '17 at 16:37
  • \$\begingroup\$ Clocks being a tad off won't matter for SPI. SPI master sends SPI clock and slave bases all communication timing off of that (actually in the hardware). \$\endgroup\$ Mar 5 '17 at 19:55
3
\$\begingroup\$

After many hours of debugging and testing the circuit, I finally found the issue being tied to the RESET PIN on the MCP2515. I misunderstood the datasheet thinking that the RESET PIN could be floating and that I could use software RESET in its place. That is NOT the case. The RESET PIN must be terminated with a pull up resistor OR tied to the RESET circuit of your MCU. I chose the PULL-UP resistor option. This prevents the MCP2515 from being stuck/hung in the RESET mode. After adding the pull-up to the circuit, I am now able to communicate with the MCP2515. It would be nice if the datasheet had a section of "Minimum Required PINS" like some datasheets have. Hope this helps someone else by making sure all the required PINS are terminated before coding :)

\$\endgroup\$
1
  • \$\begingroup\$ Yup, this exact same issue wasted many hours of mine as well. It is mentioned in the datasheet but on page 57, after everything else and you won't get that the pin needs to be held high unless you read the whole explanation. I'm all for reading documentation, but I agree this is definitely obscure. \$\endgroup\$
    – bgp
    Mar 29 '17 at 5:09
2
\$\begingroup\$

MCP2515 is a complete CAN controller. SPI is only the way to communicate with it.

Before you worry about the SPI, you must check, if the chip has power and ground; then if its reset pin is released (it is a good idea to control its reset pin, so you can reliably reset the chip anytime); you must make sure its CS Chip Select pin is selected.

Even after the chip is selected and reset, the documentation warns you that the controller needs some time to do its internal initialization. For example, I use 2msec delay after resetting it before attempting to communicate with the chip.

Once that all is okay, you have one more extremely important thing to do: make sure your processor SPI setting is correct! You mention, your SPI is already working with another chip. That is not enough, unless the other chip uses the exact same SPI setting, which I am giving you a 25% chance: you must select SPI clock polarity (set data on the CPU and the data will be clocked into MCP2515 on the rising edge of SCK), '0' value is with line at Low level.

You absolutely must study the chip documentation, part 12.0 SPI INTERFACE.

One more thing, there is a low budget way to monitor the line if you do not have oscilloscope, use a Voltmeter, or better LED attached to pin monitored (use 3 LEDs: one each for clock, SI and SO).

Next bring your CPU software to debug mode, and bit-bang the SPI communication to verify the bus works. (bit-bang means manually set the port pins to high and low, while you are stepping through the code).

While that is possible, it is not the best practice, because it will take you time, but it is done in many situations even by professionals. If you do not want to buy an oscilloscope, consider buying one of those low USB logic analyzer boxes - many come with SPI analyzer software included!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.