Hardfault in SPI?

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've got some code which uses the ASF SERCOM SPI driver on a SAMD21J18A, and it's been working well enough for the most part.  However, while trying to implement something new, I started getting hardfaults - the code isn't exactly right yet, so I'm not shocked, but in trying to track down what exactly is causing the faults, I still don't understand.

 

I enabled the MTB, and it seems to be indicating that the last code running before it hit my fault handler was line 1323 of sam0/drivers/sercom/spi/spi.h:

 

        *rx_data = (uint8_t)spi_module->DATA.reg;

 

... am I missing some way for this line to be causing a hardfault?  rx_data should be pointing at a static variable in my code at this point (I double-checked, it's pretty simple), so I'm not sure what's going on.  Any thoughts?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hard faults get hit on memory accesses (this is also peripherals, as they're mapped as memory). You C statement has a write and a read. Which one is it? Normally you'd descend down to the assembler code so you can see exactly what instruction caused the problem, put a breakpoint on it and try again. You then look at the register involved and see what address it has in it. Is it rx_data that is wrong or spi_module->... ? divide and conquer.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just following up; the problem turned out to be passing an odd address to spi_transceive_wait() for the receive buffer.  Here's the signatures of spi_transceive_wait() vs spi_transceive_buffer_wait():

 

enum status_code spi_transceive_wait(
        struct spi_module *const module,
        uint16_t tx_data,
        uint16_t *rx_data);

enum status_code spi_transceive_buffer_wait(
        struct spi_module *const module,
        uint8_t *tx_data,
        uint8_t *rx_data,
        uint16_t length);

 

... if you cast rx_data for spi_transceive_wait() to (uint8_t *),  you'll run into trouble if it's at an odd address. As I did.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That’s an interesting one!