Перейти к содержанию
    

stm32f4 spi dma возврат HAL_BUSY

Привет.

Столкнулся с проблемой передачи и приема данных по spi.

Инициализация spi:

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;

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Привет.

Столкнулся с проблемой передачи и приема данных по spi.

 

 

Так может он еще передает? Через какой промежуток идет следующий вызов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не передает. Пробовал while(HAL_SPI_TransmitReceive_DMA(...)!=HAL_OK);

Просто программа весит на цикли и все. Нашел в интернете https://community.st.com/thread/26273 у человека такая же проблема, но не ясно как проблему решили.

Изменено пользователем Alex_Golubev

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не передает. Пробовал while(HAL_SPI_TransmitReceive_DMA(...)!=HAL_OK);

Просто программа весит на цикли и все.

 

клок разрешен?

ПС увидел

 

эээ!!! Так у вас в одном место spi3, а в другом spi4 )))

Изменено пользователем 0men

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С spi3

void MX_SPI3_Init(void)
{

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

}

работаю через обычную функцию

HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);

Полет нормальный. А вот с spi4 через DMA и вот глюки.

Изменено пользователем Alex_Golubev

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...