STM32f427 - SPI with DMA problem (HardFault)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-10-19 1: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 #spi- Labels:
-
DMA
-
SPI
-
STM32F4 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-10-19 6: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.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-10-19 9: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