2025-10-22 12:52 PM
What's wrong with my code? Every time I start a DMA transfer only 2 Bytes get transferred although I specified 16 bytes.
Also, I get an FIFO Error after transmit, whereas Transmit Complete is ok.
/* FUNCTION ************************************/
void SPI1_Init (void)
/*
***********************************************/
{
LL_SPI_Enable (SPI1);
LL_DMA_EnableIT_HT (DMA2, LL_DMA_STREAM_3);
LL_DMA_EnableIT_TE (DMA2, LL_DMA_STREAM_3);
LL_DMA_EnableIT_TC (DMA2, LL_DMA_STREAM_3);
LL_DMA_EnableIT_DME (DMA2, LL_DMA_STREAM_3);
LL_DMA_EnableIT_FE (DMA2, LL_DMA_STREAM_3);
} /* --- SPI1_Init --- */
/* FUNCTION ************************************/
void SPI1_Write_DMA (uint8_t *buff, uint16_t count)
/*
* Write a complete buffer to SPI with DMA
***********************************************/
{
uint32_t reg_addr;
reg_addr = LL_SPI_DMA_GetRegAddr(SPI1);
LL_DMA_ConfigAddresses (DMA2, LL_DMA_STREAM_3, (uint32_t)buff,
reg_addr, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetDataLength (DMA2, LL_DMA_STREAM_3, count);
LL_SPI_EnableDMAReq_TX (SPI1);
LL_DMA_EnableStream (DMA2, LL_DMA_STREAM_3); // Mem to Periph
} /* --- SPI1_Write_DMA --- */
/* FUNCTION ************************************/
void spi_output_DMA (void)
/*
***********************************************/
{
SPI1_Init ();
dma_SPI_write_complete = 0; // IRQ
W5500_CS_LOW;
SPI1_Write_DMA (spi_databuff, 16);
while (dma_SPI_write_complete == 0)
{
// wait for DMA finished
}
W5500_CS_HIGH;
delay_ms(20);
} /* --- spi_output_DMA --- */
2025-10-22 1:01 PM
> Every time I start a DMA transfer only 2 Bytes get transferred although I specified 16 bytes.
How do you know this?
Probably the issue is in a part of the code we haven't been shown, or how you're interpreting the result.
Does dma_SPI_write_complete get set to 1? How/where? Make sure it's done after the SPI is complete, not when the DMA is complete.
2025-10-22 1:19 PM
> How do you know this?
I see it on my oscilloscope. The chip select goes inactive after 2 bytes.
> Probably the issue is in a part of the code we haven't been shown
Perhaps ....
> or how you're interpreting the result.
I see it on my oscilloscope.
> Does dma_SPI_write_complete get set to 1? How/where?
Yes, it's done in the DMA2_Stream3_IRQHandler, which is called when the DMA transfer has been executed.
> Make sure it's done after the SPI is complete, not when the DMA is complete.
I cannot imagine to check SPI status bits if the DMA controller controls the SPI machine. How would have to be done this?
2025-10-22 2:02 PM
> Yes, it's done in the DMA2_Stream3_IRQHandler, which is called when the DMA transfer has been executed.
That's a problem. When DMA is done transferring its data to the SPI, the SPI still has to send it out on the line. If you raise CS at this point, you miss part the transaction.
Poll the SPI BSY flag for the end of the transaction. Other chip families have better ways of doing this. The reference manual discusses this in "28.3.9 SPI communication using DMA (direct memory addressing)"
Probably something else going on as well, as you shouldn't be getting TC flag with only 2/16 bytes being sent. Unless you have FIFO enabled, which it doesn't sound like.
2025-10-22 2:07 PM
A better (less CPU) way of doing this is to set it up as two-way transfer (even if MISO is not initialized) and de-assert CS when all bytes have been received, since that is necessarily after all bytes have been sent. This can be done in the receiving DMA stream interrupt.
2025-10-22 2:23 PM
> That's a problem. When DMA is done transferring its data to the SPI,
> the SPI still has to send it out on the line. If you raise CS at this point, you miss part
> the transaction. Poll the SPI BSY flag for the end of the transaction.
Ok, I will try this, but I'm not convinced that this is the solution. Just because the CS works independently from the SPI and the DMA machine (just done by port I/O). The SPI stream could run on for the full 16 bytes even if the CS has gone high, but it doesn't.
> Probably something else going on as well, as you shouldn't be getting
> TC flag with only 2/16 bytes being sent.
This is the point! I get a TC and a FIFO error. But I can't figure out what's the FIFO problem.
> Unless you have FIFO enabled, which it doesn't sound like.
No, the FIFO is not enabled. Everything is configured by CubeMX, so there shouldn't be any issue .... I can post the init code if desired.