This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SPIS data shift on first transfer


I have two micro-controllers communicating over SPI.

The STM32F746 is SPI master.
The nRF52840 is SPI slave. I use SDK v15.3.

I am sending two bytes over SPI from the STM32F746 to the nRF52840 every 5-30 milliseconds.

The MISO data of the first (and only the first) SPI transfer after a reset or a reconfiguration of the SPI is shifted from 1 bit, e.g. 0x88 is shifted to 0x44. All following transfers are correct.

I read but the solutions there did not solve my problem.

I checked with a logic analyser that the data sent by the STM32F746 is correct, and it is. Thus the problem comes from the nRF52840 side.

The SPI Setup Time is greater than 1 us, it is around 3 us.
The SPI Hold Time is greater than 2 us, it is around 2.8 us.
Note that I tried to have a Setup/Hold Time up to 10 us, same result.

Both SPIs are configured with CPOL=0 CPHA=0. I tried using baudrates between 421 KBit/s and 6.75 MBit/s, with the same shift on the first transfer. I cannot lower the baudrate further, due to STM32 limitation (max prescaler value is 256).

The SPI pins are first configured as GPIO input in order to keep the power consumption low.

static nrfx_spis_config_t tConfiguration = NRFX_SPIS_DEFAULT_CONFIG;

// Configure SPI Slave Pins
tConfiguration.mosi_pin = NRF_GPIO_PIN_MAP(0, 24);
tConfiguration.miso_pin = NRF_GPIO_PIN_MAP(0, 23);
tConfiguration.sck_pin = NRF_GPIO_PIN_MAP(0, 25);
tConfiguration.csn_pin = NRF_GPIO_PIN_MAP(0, 22);
tConfiguration.mode = NRF_SPIS_MODE_0; // CPOL 0 CPHA 0

// Configure pins as GPIO input as long as ST is shut down
nrf_gpio_cfg_input(tConfiguration.mosi_pin, NRF_GPIO_PIN_PULLDOWN);
nrf_gpio_cfg_input(tConfiguration.miso_pin, NRF_GPIO_PIN_PULLDOWN);
nrf_gpio_cfg_input(tConfiguration.sck_pin, NRF_GPIO_PIN_PULLDOWN);
nrf_gpio_cfg_input(tConfiguration.csn_pin, NRF_GPIO_PIN_PULLDOWN);

When a "communication phase" is required, the SPI pins are configured as SPI Slave:

static const nrfx_spis_t tInstance = NRFX_SPIS_INSTANCE(SCH_SPI_INSTANCE);


nrfx_err_t eErr = nrfx_spis_init(&tInstance, &tConfiguration, vEventHandler, NULL);
if (eErr != NRFX_SUCCESS)
    // Manage error

// Configure SPI Buffers
eErr = nrfx_spis_buffers_set(&tInstance, u8BufferTx, SCH_BUFFER_SIZE, u8BufferRx, SCH_BUFFER_SIZE);
if (eErr != NRFX_SUCCESS)
    // Manage error

Do you have any idea why I get this 1-bit shift ?