cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L476JG DMA MEMORY ---> SAI2-A

SWenn.1
Senior III

Have a file and I am trying to transfer it to SAI2. For some reason ???? I am not getting into the DMA Callback. DMA is in normal mode. Can anyone shed any light on this?

  /* USER CODE BEGIN 2 */
  HAL_DMA_RegisterCallback(&hdma_sai2_a, HAL_DMA_XFER_CPLT_CB_ID, &DMA_XferCmplt_Callback);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if (ISR.DMA_TxCmplt)
	  {
		  ISR.DMA_TxCmplt = F;
		  /*
		   * after each DMA check if high current
		   * if NOT then disable SAI dma
		   */
			if (adcValue[1] < (HIGH_CURRENT))
				hsai_BlockA2.Instance->CR1 &= ~SAI_xCR1_DMAEN;
	  }
 
	  if (ISR.A_ConversionComplete)
	  {
		  ISR.A_ConversionComplete = F;
		  /*
		   * checks to see if actuator has
		   * bottomed out due to high current
		   */
		  if (adcValue[1] > (HIGH_CURRENT))
		  {
			  hsai_BlockA2.Instance->CR1 |= SAI_xCR1_DMAEN;
 
			  /*
			   * if we are engaging and high current
			   * shut off motor drive and alarm
			   */
			  if (ISR.Sw_EngageFlag)
			  {
				  HAL_GPIO_WritePin(MotorCntrlA_GPIO_Port, MotorCntrlA_Pin, GPIO_PIN_RESET);
				  PlayAudio(a4_tone, a4_tone_length);
				  ISR.Sw_EngageFlag = F;
			  }
 
			  /*
			   * if we are dis-engaging and high current
			   * shut off motor drive and alarm
			   */
			  if (ISR.Sw_DisengageFlag)
			  {
				  HAL_GPIO_WritePin(MotorCntrlB_GPIO_Port, MotorCntrlB_Pin, GPIO_PIN_RESET);
				  PlayAudio(a4_tone, a4_tone_length);
				  ISR.Sw_DisengageFlag = F;
			  }
			  //dma buffer created by PlayAudio to audio chip
			  HAL_DMA_Start_IT(&hdma_sai2_a, (uint32_t)playout_buffer, (uint32_t)&hsai_BlockA2.Instance->DR, a4_tone_length);
		  }
	  }
void PlayAudio(const int16_t *buffer, int32_t n_samples)
{
	for (int i=0; i < n_samples; i++) {		// Duplicate each sample.  The SAI insists on 2 channels of mono
		playout_buffer[i*2] = buffer[i] * LEVEL_REDUCTION;
		playout_buffer[i*2+1] = buffer[i] * LEVEL_REDUCTION;
	}
}
 
void DMA_XferCmplt_Callback(DMA_HandleTypeDef *hdma)
{
	if (hdma == &hdma_sai2_a)
		ISR.DMA_TxCmplt = T;
}

1 ACCEPTED SOLUTION

Accepted Solutions
SWenn.1
Senior III

For the record....I figured out the problem....

Not sure why BUT it is CRITICAL that SAI2 is initialized AFTER DMA. if I swap these lines the code doesn't run and I get no audio.

  MX_DMA_Init();
  MX_SAI2_Init();

View solution in original post

4 REPLIES 4

Normal, as in not Circular?

Any errors flagging on the DMA Controller side, and over/under-run type conditions on the SAI side. Check peripheral registers.

Perhaps consider circular ping/pong type buffer arrangement.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
SWenn.1
Senior III

Correct....Normal as in not Circular....Can you tell me if I have missed setting up any register settings?

Hard to say as there are no register settings to be seen...

Sure it's not the typical CubeMX error caused by DMA init order?

As TDL said, check the DMA and SAI registers, also compare the addresses in the DMA registers with your buffers.

And check the adcValue[1], maybe that's shutting down your SAI or never gets it started?

SWenn.1
Senior III

For the record....I figured out the problem....

Not sure why BUT it is CRITICAL that SAI2 is initialized AFTER DMA. if I swap these lines the code doesn't run and I get no audio.

  MX_DMA_Init();
  MX_SAI2_Init();