0

I have SamC21 XPRO board as a SPI slave with program written using ASF and Arduino Uno as a dummy SPI master. I expect 3 bytes long values.

The master sets SS to LOW then sends three bytes and then sets SS back to HIGH then waits a while and repeats it forever. I also had to add small delays between setting signals otherwise the slave had problems with receiving.

The code of slave checks if a value is received in a loop. It uses spi_read_buffer_wait funtion for checking. But the problem is that it receives any three bytes long value, not just the one between edges SS LOW and SS HIGH. So when the slave misses a byte then it starts receiving nonsence. Is it possible to receive a multi-byte value defined by SS signal and discard buffer content when the value is not complete (or receive shorter value)? Otherwise it is like random number generator.

I also noticed when I change code to receive only two bytes then it works faster and delays are not necessary. Could it be related?

I am new to microcontrollers so the code is made from Example project. Code of slave is:

#include <asf.h>

/* SPI MUX define */

#define SPI_BUF_LENGTH 3
struct spi_module spi_slave_instance;

static uint8_t buffer_rx[SPI_BUF_LENGTH] = {0x00, 0x00, 0x00};

void configure_spi_slave(void)
{
    struct spi_config config_spi_slave;
    /* Configure, initialize and enable SERCOM SPI module */
    spi_get_config_defaults(&config_spi_slave);
    config_spi_slave.mode = SPI_MODE_SLAVE;
    config_spi_slave.mode_specific.slave.preload_enable = true;
    config_spi_slave.mode_specific.slave.frame_format = SPI_FRAME_FORMAT_SPI_FRAME;
    config_spi_slave.mux_setting = CONF_SLAVE_MUX_SETTING;

    config_spi_slave.pinmux_pad0 = CONF_SLAVE_PINMUX_PAD0;
    config_spi_slave.pinmux_pad1 = CONF_SLAVE_PINMUX_PAD1;
    config_spi_slave.pinmux_pad2 = CONF_SLAVE_PINMUX_PAD2;
    config_spi_slave.pinmux_pad3 = CONF_SLAVE_PINMUX_PAD3;

    spi_init(&spi_slave_instance, CONF_SLAVE_SPI_MODULE, &config_spi_slave);

    spi_enable(&spi_slave_instance);
}

static bool spi_read_data(uint8_t *buffer_rx) {
    return spi_read_buffer_wait(&spi_slave_instance, buffer_rx, SPI_BUF_LENGTH, 0x00) == STATUS_OK;
}

int main (void)
{
    system_init();
    configure_spi_slave();

    for (i = 0; i < SPI_BUF_LENGTH; ++i) {
        buffer_rx[i] = 0x00;
    }

    while (1) {
        if (spi_read_data(buffer_rx)) {
            /* Data Output here and clear buffer_rx again*/
        }
    }
}
Jirka Picek
  • 111
  • 5
  • 1
    Is it possible? Yes. The slave must obviously check the SS pin to determine which group of three bytes belong to the same packet. Yes, the other problem could be related. – Justme Mar 02 '21 at 09:23
  • @Justme Thank you. I had problems with interrupts handling when using ASF. Finally I solved it, so now I don't use polling, but I use callbacks (ASF drivers handles interrupts). And the problem with receiving fast only 2 bytes long message is most probably problem of inefficient ASF driver. – Jirka Picek Mar 12 '21 at 13:46

0 Answers0