SPI DMA HELP! what is going on ?????
- December 15, 2018
- 7 replies
- 1711 views
any help would be very much appreciated.
for the past few weeks I have been trying to get SPI & DMA working with HAL
what an up hill struggle !
still only scratching the surface of it and this coding is not for the faint hearted or people that give up easily.
OK
I gave up using NSS hardware chip select at this doesn't seem to work correctly and more hassle than its worth ! you have to keep disabling the spi module and then re-enabling bit 6
So I decided use a standard GPIO pin for my chip select, so much easier!
1) set the Chip Select GPIO pin Low before the HAL_SPI_Transmit_DMA
2) issue the HAL_SPI_Transmit_DMA data
3) in the spi transmit complete interrupt, set the Chip Select Pin High
so I am able to send 3 packets of SPI DATA via the DMA in my init code before my main loop
SPI INIT
/* SPI2 init function */
void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_1LINE;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
}DMA INIT
hdma_spi2_tx.Instance = DMA1_Stream4;
hdma_spi2_tx.Init.Channel = DMA_CHANNEL_0;
hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi2_tx.Init.Mode = DMA_NORMAL;
hdma_spi2_tx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_spi2_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_spi2_tx.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_spi2_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(spiHandle, hdmatx, hdma_spi2_tx);
/* SPI2 interrupt Init */
HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);while (HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY)
{
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, LOW);
HAL_SPI_Transmit_DMA( &hspi2, (uint8_t*) MCP23017_INIT, 3 ) ;
while (HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY)
{
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, LOW);
HAL_SPI_Transmit_DMA( &hspi2, (uint8_t*) MCP23017_INITB, 3 ) ;
while (HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY)
{
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, LOW);
HAL_SPI_Transmit_DMA( &hspi2, (uint8_t*) MCP23017_INITB2, 3 ) ;Then when I try to send some more SPI data and check first for SPI busy it always reports busy ???
What is going on ???
I sent 3 packets and only 3 packets, how can the SPI TX report it busy ??
have had a logic analyser and only 3 spi packet are show, no more spi data should be in any buffer and this spi peripheral should NOT report BUSY!
can anyone please help, these HAL drivers and ST32 chips are seriously hard work!
any help will be very much appreciated