cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5 SPI Slave Not Working Zephyr

rulmer
Associate II

Hi all,

I'm struggling to get SPI working on my STM32U5G9J. I have an nordic master device outputting 6 bytes of data every 500 ms over SPI and plugged into the proper pins, double checked and confirmed on analyzer.

stm32u5g9j_dk2.overlay

/ {
    aliases {
        spi-slave = &spi1;
    };
};

&spi1 {
    status = "okay";
    pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pb5 &spi1_nss_pb0>;
    pinctrl-names = "default";
    /delete-property/ cs-gpios;
    fifo-enable;
};

main.c

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/util.h>

LOG_MODULE_REGISTER(main);

#define SPIOP (SPI_OP_MODE_SLAVE | SPI_WORD_SET(8) | SPI_LINES_SINGLE | SPI_TRANSFER_MSB)

static const struct device *spi_in_dev = DEVICE_DT_GET(DT_ALIAS(spi_slave));
static const struct spi_config spi_in_cfg = {
    .frequency = MHZ(1),
    .operation = SPIOP,
    .slave = 0,
};

int main(void)
{
    if (!device_is_ready(spi_in_dev))
    {
        LOG_ERR("SPI not ready");
        return 1;
    }

    LOG_INF("program started");

    static uint8_t rx_buf[1];
    static const size_t rx_size = sizeof(rx_buf);
    static struct spi_buf rx_spi_buf = {.buf = rx_buf, .len = rx_size};
    static struct spi_buf_set rx_spi_buf_set = {.buffers = &rx_spi_buf, .count = 1};

    while (1)
    {
        memset(rx_buf, 0, rx_size);

        int ret = spi_read(spi_in_dev, &spi_in_cfg, &rx_spi_buf_set);
        if (ret < 0)
        {
            LOG_ERR("SPI read error: %d", ret);
            continue;
        }

        LOG_HEXDUMP_INF(rx_buf, rx_size, "read bytes:");
    }

    return 0;
}

prj.conf

CONFIG_SPI=y
CONFIG_GPIO=y
CONFIG_PINCTRL=y

CONFIG_SPI_SLAVE=y
CONFIG_SPI_STM32_INTERRUPT=y

CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y


It's logging every 500 ms (exactly when master outputs data):

<err> spi_stm32: spi_stm32_get_err: err=32
<err> main: SPI read error: -5


err 32 (hex 0x20) is generic HAL_SPI_ERROR_FLAG. If I disconnect the MOSI pin the error persists; Disconnecting any other pins stops prints. 

The error seems to be here, called during spi interrupt:

static int spi_stm32_get_err(SPI_TypeDef *spi)
{
	uint32_t sr = stm32_reg_read(&spi->SR);

	if ((sr & SPI_STM32_ERR_MSK) != 0U) {
		LOG_ERR("%s: err=%d", __func__, sr & (uint32_t)SPI_STM32_ERR_MSK);

		/* OVR error must be explicitly cleared */
		if (LL_SPI_IsActiveFlag_OVR(spi)) {
			LL_SPI_ClearFlag_OVR(spi);
		}

		return -EIO;
	}

	return 0;
}

I'm not really sure where to go from here in debugging. Any suggestions?
Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
rulmer
Associate II

You need to call `spi_transceive` instead of `spi_read` and pass a dummy TX buffer in (which has to be same length as rx_buf).

View solution in original post

1 REPLY 1
rulmer
Associate II

You need to call `spi_transceive` instead of `spi_read` and pass a dummy TX buffer in (which has to be same length as rx_buf).