2015-10-19 01:53 AM
Hello all,
I work with a STM32F427 and the HAL libraries, and i want tu use the SPI with DMA. Configuration : The chip is in slave mode and receive datas from an ADC converter. The Clock and NSS are generated by two timers, and I can watch the datas on an scope. PS : I tried to use the SPI in polling mode and it works fine.So, here is my problem:
When I try tu use the SPI with DMA, several interruptions occure (I put an incrementing variable in the callback) and after that (kinda randomly) I have a HardFault. After a long time of debugg and looking for solutions on forum and documentation I hope someone have a clue here. I let here the part of my code concerning the DMA and SPI so, perhaps you can see something wrong: Declarations:SPI_HandleTypeDef spi4Handle;
uint16_t buf_rx[6];
// SPI4
SPI Init :
void
Start_SPI4()
{
spi4Handle.Instance = SPI4;
spi4Handle.Init.BaudRatePrescaler = 0;
spi4Handle.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
spi4Handle.Init.CLKPhase = SPI_PHASE_1EDGE;
spi4Handle.Init.CLKPolarity = SPI_POLARITY_HIGH;
spi4Handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spi4Handle.Init.CRCPolynomial = 1;
spi4Handle.Init.DataSize = SPI_DATASIZE_16BIT;
spi4Handle.Init.FirstBit = SPI_FIRSTBIT_MSB;
spi4Handle.Init.TIMode = SPI_TIMODE_DISABLE;
spi4Handle.Init.Mode = SPI_MODE_SLAVE;
spi4Handle.Init.NSS = SPI_NSS_HARD_INPUT;
if
(HAL_SPI_Init(&spi4Handle) != HAL_OK)
{
Error_Handler();
}
if
(HAL_SPI_Receive_DMA(&spi4Handle,(uint8_t*)buf_rx,buf_rx_size) != HAL_OK)
{
Error_Handler();
}
#ifdef DEBUG_USR
trace_printf(
''\n SPI4 enabled''
);
#endif
}
SPI MspInit & DMA Init:
void
HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
if
(hspi->Instance == SPI4) {
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_SPI4_CLK_ENABLE();
__GPIOE_CLK_ENABLE();
DMA_HandleTypeDef hdma_rx;
__HAL_RCC_DMA2_CLK_ENABLE();
// SCK PIN
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI4;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
// MOSI PIN
GPIO_InitStruct.Pin = GPIO_PIN_6;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
// MISO PIN
GPIO_InitStruct.Pin = GPIO_PIN_5;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
// NSS PIN
GPIO_InitStruct.Pin = GPIO_PIN_4;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
// Configure the DMA handler for Transmission process
hdma_rx.Instance = DMA2_Stream0;
hdma_rx.Init.Channel = DMA_CHANNEL_4;
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_rx.Init.Mode = DMA_CIRCULAR;
hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_rx.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&hdma_rx);
// Associate the initalized DMA handle to the the SPI handle
__HAL_LINKDMA(hspi, hdmarx, hdma_rx);
// NVIC configuration for DMA transfer complete interrupt
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
}
Callback:
void
HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *spi)
{
if
(spi->Instance == SPI4)
{
voie1 = buf_rx[0];
voie2 = buf_rx[1];
voie3 = buf_rx[2];
voie4 = buf_rx[3];
voie5 = buf_rx[4];
voie6 = buf_rx[5];
if
( (cpt++) > 10000 ) cpt = 0;
// Debug variable
}
}
IRQHandler :
void
DMA2_Stream0_IRQHandler(
void
)
{
HAL_NVIC_ClearPending(DMA2_Stream0_IRQn);
HAL_DMA_IRQHandler(spi4Handle.hdmarx);
}
Error Handler (Just to show that it does nothing):
void
Error_Handler()
{
//TODO
}
If it can be usefull I let you a screenshot of the Hard Fault :
[url=http://imgshare.free.fr/][img]http://imgshare.free.fr/uploads/cff65565a9.png[/img][/url] Tell me if something is unclear or if you need more informations. Thank you, and sorry for my English. Maxence. #hardfault #stm32f4 #dma #spi2015-10-19 06:00 AM
Looks like whatever callback is being used by HAL_DMA_IRQHandler() is vectoring off into some RAM based address (stack). Make sure you aren't using any local structures where globals ones are needed.
2015-10-19 09:16 AM
So many thanks clive1, you are right.
After looking at the declaration of the variable used in the ''HAL_DMA_IRQHandler()''I saw that this variable has a local range. I was so focused on the working of the function that I forget the basis.
Regards, Maxence