2021-11-15 04:35 AM
I have done the implementation of 3 wire SPI using DMA and when I do SPI transfer using
HAL_SPI_Transmit_DMA(&SPIx_handle, (uint8_t *)TxBuffer, 8u); the HAL_SPI_GetState(&SPIx_handle) is stuck at HAL_SPI_STATE_BUSY_TX.
Not changing the state.
My configuration of SPI and DMA is similar to this query : STM32F405 SPI Transmit using DMA not working
Thanks in advance
Edit: First time posting query here, if anything needed additionally please comment
Edit 2: Earlier mentioned HAL_SPI_STATE_BUSY, updated to HAL_SPI_STATE_BUSY_TX
Solved! Go to Solution.
2021-11-16 09:45 PM
Hi JW,
Thanks for your response.
2021-11-16 09:58 PM
Hi TDK,
I checked with high priority, still the behavior is same
_inline_ static void spi5_dataTransfer(uint16_t *TxBuffer)
{
HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_DMA(&SPIx_handle, (uint8_t *)TxBuffer, 8u);
HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_SET);
while (HAL_SPI_GetState(&SPIx_handle) != HAL_SPI_STATE_READY);
}
the control is not stopping at while(mentioned above).
And SPI state remains in "HAL_SPI_STATE_BUSY_TX" state.
But if I disable the "while" as shown below
_inline_ static void spi5_dataTransfer(uint16_t *TxBuffer)
{
HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_DMA(&SPIx_handle, (uint8_t *)TxBuffer, 8u);
HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_SET);
// while (HAL_SPI_GetState(&SPIx_handle) != HAL_SPI_STATE_READY);
}
the ISR (DMA2_Stream4) is getting called at fixed interval(as I call spi5_dataTransfer() in a repeated task), so interrupt is enabled and working right?
Please correct me if am wrong.
NVIC set priority and enabled are done for both DMA stream and SPI
Kindly reply, as your replies are helping
2021-11-17 05:02 AM
> in a repeated task
RTOS?
Where do you call spi5_dataTransfer from? Aren't interrupts disabled globally at that point, or isn't it from an interrupt context with priority equal or higher than DMA2_Stream4 interrupt priority?
JW
2021-11-17 06:27 AM
Hi JW,
Thanks for the response
Not RTOS, a repeated task is created using a timer interrupt.
spi5_dataTransfer is called from this task.(No global interrupts are disabled)
I will look for issue from interrupt context and will update here.
2021-11-17 06:56 AM
> a repeated task is created using a timer interrupt.
> spi5_dataTransfer is called from this task
If spi5_dataTransfer is called from an interrupt, probably the DMA2_Stream4 IRQ has the same or lower priority than it. If you don't know what it's in, set a breakpoint and look at VECTACTIVE bits to determine which interrupt it's in.
> HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_RESET);
> HAL_SPI_Transmit_DMA(&SPIx_handle, (uint8_t *)TxBuffer, 8u);
> HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_SET);
If your intention is to hold NSS low until the transmission completes, you need to wait for it to complete. As written, the code will only set NSS low briefly, perhaps for a single bit or less, as the transmission will continue in the background. You can instead set NSS high in the receive complete callback function.
2021-11-18 03:11 AM
Hi TDK,
Thanks for the response.
You were correct about the interrupt,
For testing purpose, I changed to flow and called HAL_SPI_Transmit_DMA from main().
It worked fine for single byte transfer.
But when I pass multiple bytes( like 8, 25 etc) for last byte in the sequence is getting identified
Please see below, Here data send are "12345678", but only 8 is identified(Data from 1-7 also present in transfer but during the ChipSelect high clock is present)
another example if "ABCDEFGH" is send means H will be identified.
Note: HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_SET); is called inside HAL_SPI_TxCpltCallback() and is fine.
2021-11-18 03:20 AM
> But when I pass multiple bytes
How?
Post relevant portion of code.
JW
2021-11-18 03:24 AM
Hi JW
Thanks for the quick response
I pass
uint8_t aTxBuffer[] = "ABCDEFGH";
to this
void spi5_dataTransfer(uint8_t *TxBuffer)
{
HAL_GPIO_WritePin(SPIx_NSS_Port, SPIx_NSS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit_DMA(&SPIx_handle, TxBuffer, 8u); //8u //1u
while (HAL_SPI_GetState(&SPIx_handle) != HAL_SPI_STATE_READY);
}
2021-11-18 04:27 AM
> //8u //1u
Was the lower waveform (with red circles) taken with 8u or 1u?
And channel 3 displays the SPIx_NSS_Pin?
JW
2021-11-18 04:34 AM
Hi JW,
Thanks for your response
Lower waveform is taken with 8u.(Correct)
Channel 3 is NSS output.(Correct)
Issue is when the NSS is high, Clock also present. This is what I tried to showcase in image.