2015-10-07 02:45 AM
I have a SPI slave (RX only) and need to use it with CRC check enabled (STM32F4, 8bit CRC generator of SPI unit).
To process the high amount of data, I use a P2M DMA. What is the correct way to stop/cancel a DMA transfer, before it is completed? Currently, I do it in this way:void
init(
void
){
HAL_SPI_Receive_DMA(&hspi1, SPI_RX_Buffer, 10);
//start DMA
}
void
HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi){
HAL_SPI_Receive_DMA(&hspi1, SPI_RX_Buffer, 10);
//restart DMA
}
void
BUTTON_PRESS(
void
){
HAL_DMA_Abort(&hdma_spi1_rx);
// Aborting a (possibly incomplete) DMA transfer
HAL_SPI_Receive_DMA(&hspi1, SPI_RX_Buffer, 15);
//restart DMA with different length
}
This works fine, but only, if the
CRC check is disabled!
//..
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
HAL_SPI_Init(&hspi1);
//..
If I enable the CRC check:
//..
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;
hspi1.Init.CRCPolynomial = 0x10;
HAL_SPI_Init(&hspi1);
//..
it hangs in the function
HAL_DMA_Abort();
Specifically on the line
__HAL_DMA_DISABLE(hdma);
which is a macro for
hdma->Instance->CR &= ~DMA_SxCR_EN
So my question in summary:
How do I properly stop/cancel a SPI RX DMA transfer, when the CRC generator is enabled?
2015-10-12 05:59 AM
I asked the ST Support to look into this.
They very quickly replied and told me this:There is a bug in the library. The DMA stop triggers the DMA interrupt and the driver expects data. I created some workaround that should work. Instead of just calling DMA stop you must call:
__disable_irq();
/* might not be necessary */
hspi1.hdmarx->XferCpltCallback = NULL;
HAL_SPI_DMAStop(&hspi1);
__enable_irq();
/* might not be necessary */
Disable interrupt might not be necessary.
This fix works for me as expected!
Note:
I am currently using the latest versions:
STM32Cube_FW_F4_V1.8.0 including STM32F4xx_HAL_Driver (V 1.4.0) and CMSIS (V 2.4).
Disabling/enabling the irqs was not necessacy for me.