cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WBA54 SAI Slave mode DMA cannot stop and reinitiate

HuangFan
Associate

STM32WBA54 SAI work in slave mode with DMA: SAI1_Block_A Slave out, SAI1_Block_B Slave in. 

test code as:

  MX_SAI1_Init();

//in

  __HAL_LINKDMA(&hsai_BlockB1, hdmarx, handle_GPDMA1_Channel2);
  MX_RxQueue_Config();
  HAL_DMAEx_List_SetCircularMode(&RxQueue);
  HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel2, &RxQueue);
  if (HAL_SAI_Receive_DMA(&hsai_BlockB1, (uint8_t *) aSrcBuff, SAI_MAX_BUFF_SIZE*2) != HAL_OK)
  {
 
   }
 
//Out
__HAL_LINKDMA(&hsai_BlockA1, hdmatx, handle_GPDMA1_Channel1);
  MX_TxQueue_Config();
  HAL_DMAEx_List_SetCircularMode(&TxQueue);
HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel1, &TxQueue);
if (HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *)aSnkBuff, SAI_MAX_BUFF_SIZE*2) != HAL_OK)
 {
 }
 
TxDMA = HAL_SAI_DMAStop(&hsai_BlockA1);
RxDMA = HAL_SAI_DMAStop(&hsai_BlockB1); 
TxSai = HAL_SAI_DeInit(&hsai_BlockA1);
RxSai = HAL_SAI_DeInit(&hsai_BlockB1);
 
HAL_SAI_DMAStop() and HAL_SAI_DeInit() all return HAL_ERROR;
 
Debug into the function and find that SAI_Disable() inside always return HAL_TIMEOUT for CR1_SAIEN cannot be cleared. But if SAI work in Master mode, it will be OK. In my test, there is no SAI mater or slave was connected, from my understanding, when SAI was in Slave mode and there is no Master to provide the CLK, the function  HAL_SAI_Transmit_DMA() start the DMA transfer but the transfer will be blocked for not CLK. And at this situation the SAI will waiting for the CLK to complete the transfer or the CR1_SAIEN bit cannot be cleared, am I right? 
 
while in Master mode the HAL_SAI_Transmit_DMA() could Start the DMA transfer successfully, and the SAI DMA could stop and de-initiate successfully.  
 
In my project, the SAI need to Support both Master and Slave mode, use the appropriate mode according to connected device. And I've already finished the Master mode, the SAI could be stop successfully if audio was off and restart SAI if audio was on. but When In Slave mode, SAI cannot be stopped the de-initiate successfully and this will also affect restarting the SAI.
 
what could I do to stop the SAI in slave mode? 
 
 

static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai)
{
uint32_t count = SAI_DEFAULT_TIMEOUT * (SystemCoreClock / 7U / 1000U);
HAL_StatusTypeDef status = HAL_OK;

/* Disable the SAI instance */
__HAL_SAI_DISABLE(hsai);

do
{
/* Check for the Timeout */
if (count == 0U)
{
/* Update error code */
hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
status = HAL_TIMEOUT;
break;
}
count--;
} while ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != 0U);

return status;
}

0 REPLIES 0