cancel
Showing results for 
Search instead for 
Did you mean: 

SPI + DMA only transmitting half of total bytes sent?

MFolk.1
Senior

I am trying to setup SPI communication via DMA on the STM32L4S9AII6 MCU. It seems to be half working as you see in the image "SPI Bug". In this test I am sending a string of 6 bytes. As you can see, only the first half make it out of the MCU alive, but the MCU is obviously trying to send the full 6 bytes. This is over the SPI3 peripheral. Also note the PB12 signal at the bottom of the "SPI Bug" image attached. This is a GPO pin that I assert high when the "HAL_SPI_TxHalfCpltCallback" callback function is called. Likewise, I de-assert the same pin low when the "HAL_SPI_TxCpltCallback" callback function is called. Not sure why the half-transfer complete callback function is getting called at the beginning of the transfer. Maybe that is a hint as to what is wrong here.

I am also successfully using UART1 + DMA where I am consistently able to send messages with many bytes.

Yes, I have "MX_DMA_Init();" before all other peripherals that use DMA. By the way, when does ST plan to fix this bug, it has been there for at least a couple of years.

/* Initialize all configured peripherals */

 MX_DMA_Init();

 MX_GPIO_Init();

 MX_I2C1_Init();

 MX_OCTOSPI1_Init();

 MX_OCTOSPI2_Init();

 MX_SPI1_Init();

 MX_SPI2_Init();

 MX_SPI3_Init();

 MX_ADC1_Init();

 MX_I2C2_Init();

 MX_IWDG_Init();

 MX_USART1_UART_Init();

 MX_DAC1_Init();

Here is how I have SPI3 configured. Note that I have adjusted many settings with no avail.

static void MX_SPI3_Init(void)

{

 /* USER CODE BEGIN SPI3_Init 0 */

 /* USER CODE END SPI3_Init 0 */

 /* USER CODE BEGIN SPI3_Init 1 */

 /* USER CODE END SPI3_Init 1 */

 /* SPI3 parameter configuration*/

 hspi3.Instance = SPI3;

 hspi3.Init.Mode = SPI_MODE_MASTER;

 hspi3.Init.Direction = SPI_DIRECTION_2LINES;

 hspi3.Init.DataSize = SPI_DATASIZE_8BIT;

 hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;

 hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;

 hspi3.Init.NSS = SPI_NSS_HARD_OUTPUT;

 hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;

 hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;

 hspi3.Init.TIMode = SPI_TIMODE_DISABLE;

 hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

 hspi3.Init.CRCPolynomial = 7;

 hspi3.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

 hspi3.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;

 if (HAL_SPI_Init(&hspi3) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN SPI3_Init 2 */

 /* USER CODE END SPI3_Init 2 */

}

Is this a bug anyone else has seen before?

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
MFolk.1
Senior

Sorry everyone. My suspicion was correct that it was a hardware issue. As previously mentioned, I needed to remove U6 from the STM32L4R9I-EVAL dev board. SPI communication now works like a charm.

View solution in original post

6 REPLIES 6
TDK
Guru

Show the code you use to send the data. The bug is not in the initialization.

The DMA initialization bug is fixed (again) but persists in projects created when it was broken.

https://community.st.com/s/question/0D53W00001EzCmCSAV/mxdmainit-order-in-the-mainc-file-generated-by-stm32cubemx-how-to-fix

If you feel a post has answered your question, please click "Accept as Solution".
S.Ma
Principal

Ignore the half transfer interrupt if not needed, or disable it manually.

MFolk.1
Senior

char bufferLocal[6] = "$12345";

PRINTF("Spi3ArTx = %s \n", bufferLocal); // Print via Uart (Works great)

HAL_SPI_Transmit_DMA(&hspi3, (uint8_t *)bufferLocal, strlen(bufferLocal));

I should also mention that PRINTF here eventually makes a DMA Tx call the same way.

HAL_UART_Transmit_DMA(&huart1, (uint8_t *)bufferLocal, strlen(bufferLocal));

I just realized that this may actually be a hardware issue. I am using the STM32L4R9I-EVAL dev board. I noticed that the MOSI pin (PG11) is routed through a 33 ohm resister (R196) to SIO5 (a "Serial Data Input & Output" pin) of U6 (MX25LM51245GXDI00), which is a flash IC. I guess I didn't think this would be an issue because of how difficult this would be to break this connection. I'm probably wrong. I will try to figure out how I'm going to desolder the 0402 resistor and get a test point to one of its pads. I'll let you know what I find out.

I don't see any issues within the presented code.

The half-complete interrupt may be triggering early due to data packing, as the HT event fires when the DMA is done transferring data, not when that data has been sent out. Writing more bytes (say, 100) instead of 6 would confirm.

If you feel a post has answered your question, please click "Accept as Solution".

Is SPI DMA configured to transfer bytes?

MFolk.1
Senior

Sorry everyone. My suspicion was correct that it was a hardware issue. As previously mentioned, I needed to remove U6 from the STM32L4R9I-EVAL dev board. SPI communication now works like a charm.