реклама на сайте
подробности

 
 
> stm32f4 spi dma возврат HAL_BUSY
Alex_Golubev
сообщение Aug 31 2017, 12:15
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 280
Регистрация: 18-03-17
Пользователь №: 95 877



Привет.
Столкнулся с проблемой передачи и приема данных по spi.
Инициализация spi:
CODE
void MX_SPI4_Init(void)
{

hspi4.Instance = SPI4;
hspi4.Init.Mode = SPI_MODE_MASTER;
hspi4.Init.Direction = SPI_DIRECTION_2LINES;
hspi4.Init.DataSize = SPI_DATASIZE_8BIT;
hspi4.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi4.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi4.Init.NSS = SPI_NSS_SOFT;
hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi4.Init.TIMode = SPI_TIMODE_DISABLED;
hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
hspi4.Init.CRCPolynomial = 10;
HAL_SPI_Init(&hspi4);

}

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{

GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI3)
{
/* USER CODE BEGIN SPI3_MspInit 0 */

/* USER CODE END SPI3_MspInit 0 */
/* Peripheral clock enable */
__SPI3_CLK_ENABLE();

/**SPI3 GPIO Configuration
PC11 ------> SPI3_MISO
PC12 ------> SPI3_MOSI
PB3 ------> SPI3_SCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* USER CODE BEGIN SPI3_MspInit 1 */

/* USER CODE END SPI3_MspInit 1 */
}
else if(hspi->Instance==SPI4)
{
/* USER CODE BEGIN SPI4_MspInit 0 */

/* USER CODE END SPI4_MspInit 0 */
/* Peripheral clock enable */
__SPI4_CLK_ENABLE();

/**SPI4 GPIO Configuration
PE2 ------> SPI4_SCK
PE5 ------> SPI4_MISO
PE6 ------> SPI4_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI4;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

/* Peripheral DMA init*/

hdma_spi4_rx.Instance = DMA2_Stream3;
hdma_spi4_rx.Init.Channel = DMA_CHANNEL_5;
hdma_spi4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi4_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi4_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi4_rx.Init.Mode = DMA_NORMAL;
hdma_spi4_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_spi4_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_spi4_rx);

__HAL_LINKDMA(hspi,hdmarx,hdma_spi4_rx);

hdma_spi4_tx.Instance = DMA2_Stream4;
hdma_spi4_tx.Init.Channel = DMA_CHANNEL_5;
hdma_spi4_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi4_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi4_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi4_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi4_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi4_tx.Init.Mode = DMA_NORMAL;
hdma_spi4_tx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_spi4_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_spi4_tx);

__HAL_LINKDMA(hspi,hdmatx,hdma_spi4_tx);

/* USER CODE BEGIN SPI4_MspInit 1 */

/* USER CODE END SPI4_MspInit 1 */
}
else if(hspi->Instance==SPI5)
{
/* USER CODE BEGIN SPI5_MspInit 0 */

/* USER CODE END SPI5_MspInit 0 */
/* Peripheral clock enable */
__SPI5_CLK_ENABLE();

/**SPI5 GPIO Configuration
PF7 ------> SPI5_SCK
PF8 ------> SPI5_MISO
PF9 ------> SPI5_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

/* USER CODE BEGIN SPI5_MspInit 1 */

/* USER CODE END SPI5_MspInit 1 */
}

}

Передаю и принимаю данные с помощью функции:
Код
HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size);

При первом вызове функции все работает. При повторном вызове данной функции, функция возвращает
Код
return HAL_BUSY;

CODE
HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
{
uint32_t tmpstate = 0;
tmpstate = hspi->State;
if((tmpstate == HAL_SPI_STATE_READY) || ((hspi->Init.Mode == SPI_MODE_MASTER) && \
(hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmpstate == HAL_SPI_STATE_BUSY_RX)))
{
if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}

/* Check the parameters */
assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));

/* Process locked */
__HAL_LOCK(hspi);

/* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
if(hspi->State != HAL_SPI_STATE_BUSY_RX)
{
hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
}

/* Configure communication */
hspi->ErrorCode = HAL_SPI_ERROR_NONE;

hspi->pTxBuffPtr = (uint8_t*)pTxData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;

hspi->pRxBuffPtr = (uint8_t*)pRxData;
hspi->RxXferSize = Size;
hspi->RxXferCount = Size;

/*Init field not used in handle to zero */
hspi->RxISR = 0;
hspi->TxISR = 0;

/* Reset CRC Calculation */
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
SPI_RESET_CRC(hspi);
}

/* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
if(hspi->State == HAL_SPI_STATE_BUSY_RX)
{
/* Set the SPI Rx DMA Half transfer complete callback */
hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;

hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
}
else
{
/* Set the SPI Tx/Rx DMA Half transfer complete callback */
hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;

hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
}

/* Set the DMA error callback */
hspi->hdmarx->XferErrorCallback = SPI_DMAError;

/* Enable the Rx DMA Stream */
HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);

/* Enable Rx DMA Request */
hspi->Instance->CR2 |= SPI_CR2_RXDMAEN;

/* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
is performed in DMA reception complete callback */
hspi->hdmatx->XferCpltCallback = NULL;

if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
{
/* Set the DMA error callback */
hspi->hdmatx->XferErrorCallback = SPI_DMAError;
}
else
{
hspi->hdmatx->XferErrorCallback = NULL;
}

/* Enable the Tx DMA Stream */
HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);

/* Process Unlocked */
__HAL_UNLOCK(hspi);

/* Check if the SPI is already enabled */
if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
{
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(hspi);
}

/* Enable Tx DMA Request */
hspi->Instance->CR2 |= SPI_CR2_TXDMAEN;

return HAL_OK;
}
else
{
return HAL_BUSY;
}
}

Подскажите пожалуйста в чем дело? Почему SPI занят?

Сообщение отредактировал Alex_Golubev - Aug 31 2017, 12:27
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01325 секунд с 7
ELECTRONIX ©2004-2016