Page 1 of 1

Facing issues with SPI (Master) on ESP32C3

Posted: Sat Jan 04, 2025 8:35 pm
by HareeshS
Hello!

I'm trying to establish communication between an ESP32C3 and an STM32 microcontroller, where the ESP32 behaves as the master, and STM32, the slave.
For testing purposes I am using the SEEEDStudio XIAO ESP32C3 dev kit.

All I'm trying to do is send and receive a byte via SPI (full duplex mode) between the 2 devices. The ESP32 is configured to send 0xA5, while the STM32 is configured to send 0xAA.
When I probe the SPI signals with a DSO, I can see the MOSI signal carries 0xA5 (as expected) but the MISO signal carries 0x80 instead of 0xAA.
If I disconnect the MISO signal from the ESP32 while keeping the rest of the signals connected, the MISO line carries 0xAA, indicating to me the ESP32 is causing issues with the data. There are no hardware pull ups or downs on these signal lines, nor am I enabling any SW PU/PDs on either applications.

I am attaching the relevant snippets of my test code (for both ESP32 and STM32) for reference. Am I doing something wrong? I have tried configuring the ESP32 using the GPIO driver to disable any PU/PD but that has not worked as well.

Also to note, the CS signal is currently not being used on the STM32 side - as for testing I am simply looping the SPI transmit function in an infinite loop with the timeout maxed - I do not suspect this to be a problem as I have verified via placing breakpoints after the SPI transmit function on the STM32 application that the function is indeed blocking until a transaction is initiated and completed by the ESP32.

ESP32 Code

Code: Select all

#define SPI_HOST SPI2_HOST
#define GPIO_MOSI 10
#define GPIO_MISO 9
#define GPIO_SCLK 8
#define GPIO_CS 20

void app_main(void) {
  spi_bus_config_t buscfg = {.mosi_io_num = GPIO_MOSI,
                             .miso_io_num = GPIO_MISO,
                             .sclk_io_num = GPIO_SCLK,
                             .quadwp_io_num = -1,
                             .quadhd_io_num = -1,
                             .max_transfer_sz = 4};

  ret = spi_bus_initialize(SPI_HOST, &buscfg, SPI_DMA_CH_AUTO);
  
  spi_device_interface_config_t devcfg = {
      .clock_speed_hz = 2 * 1000 * 1000,
      .mode = 0,
      .spics_io_num = GPIO_CS,
      .queue_size = 1,
  };

  spi_device_handle_t spi;
  spi_bus_add_device(SPI_HOST, &devcfg, &spi);
 
  uint8_t tx_data = 0xA5;
  uint8_t rx_data = 0x00;

  spi_transaction_t trans = {
      .length = 8,
      .tx_buffer = &tx_data,
      .rx_buffer = &rx_data,
  };

  ret = spi_device_transmit(spi, &trans);
}
STM32 Code - (redacting irrelevant boilerplate/autogenerated code)

Code: Select all

int main(void) {
	MX_SPI1_Init();
	
	uint8_t tx = 0xAA;
	while (1) {
		HAL_SPI_Transmit(&hspi1, &tx, 1, 0xFFFFFFFF);
	}
}

void MX_SPI1_Init(void)
{
  SPI_AutonomousModeConfTypeDef HAL_SPI_AutonomousMode_Cfg_Struct = {0};

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_SLAVE;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 0x7;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
  hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
  hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  hspi1.Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY;
  hspi1.Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_SPI_AutonomousMode_Cfg_Struct.TriggerState = SPI_AUTO_MODE_DISABLE;
  HAL_SPI_AutonomousMode_Cfg_Struct.TriggerSelection = SPI_GRP1_GPDMA_CH0_TCF_TRG;
  HAL_SPI_AutonomousMode_Cfg_Struct.TriggerPolarity = SPI_TRIG_POLARITY_RISING;
  if (HAL_SPIEx_SetConfigAutonomousMode(&hspi1, &HAL_SPI_AutonomousMode_Cfg_Struct) != HAL_OK)
  {
    Error_Handler();
  }
}
I am also attaching screenshots from the DSO for clarity. First screenshot is when MISO is physically disconnected from ESP32, and second one is when it is connected back.
SDS00007.png
SDS00007.png (22.1 KiB) Viewed 915 times
SDS00008.png
SDS00008.png (22.16 KiB) Viewed 915 times