cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2S_TxCpltCallback is called only once

eunoia
Associate

I'm testing whether HAL_I2S_TxCpltCallback or HAL_I2S_TxHalfCpltCallback is called properly by setting i2s to normal and periodically calling HAL_I2S_Transmit_DMA. However, HAL_I2S_TxCpltCallback or HAL_I2S_TxHalfCpltCallback is called only once and not again. I want to use i2s in normal mode, not circular mode, so I'm testing like below. Is there something wrong?

When I check the return value with status = HAL_I2S_Transmit_DMA(&hi2s2, audioBuffer, AUDIO_BUFFER_SIZE);, HAL_BUSY(2) is returned.

 

while (1)
{
	HAL_I2S_Transmit_DMA(&hi2s2, audioBuffer, AUDIO_BUFFER_SIZE);
	HAL_Delay(1000);
}

void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
{
	dma_count++;

}

void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
{
	dma_count++;
}

 

3 REPLIES 3
AScha.3
Chief III

>I want to use i2s in normal mode, not circular mode, so I'm testing like below. Is there something wrong?

Nothing wrong.

I2S "normal" = standard, you have to use with all I2S DACs .This is the protocol of the transfer.

 

But the DMA mode is the point :

 

Start DMA in "normal" mode, transfers data one time. end.

In circular mode, its sending continuous. (the usual DMA mode for constant working DAC or ADC on I2S )

So - just your decision, what it should do: normal DMA = one block , circular DMA = continuous stream.

If you feel a post has answered your question, please click "Accept as Solution".

Thanks for your reply
Since you are calling HAL_I2S_Transmit_DMA every second
Shouldn't HAL_I2S_TxCpltCallback be called every second?

nonono--- wrong.

You set all in Cube : I2S mode, DMA circular and half-word (if using 16b data words).

 

Then in prog you just start it once - then its running...

just in callbacks you put new data in the 1/2 block of the whole data array.

like here, in my audio player : (just i use the SAI for I2S, so you replace the SAI-calls with I2S-calls)

 

  HAL_SAI_RegisterCallback(&hsai_BlockA1, HAL_SAI_TX_HALFCOMPLETE_CB_ID, HAL_SAI_TxHalfCpltCallback);
  HAL_SAI_RegisterCallback(&hsai_BlockA1, HAL_SAI_TX_COMPLETE_CB_ID, HAL_SAI_TxCpltCallback);

 fresult = HAL_DMA_Init(&hdma_sai1_a); // set DMA data stream -> SAI

 for(int a=0;a<4096*2; a++)playbuf[a]=0; 	// clear dac i2s buf = silence

  fresult = HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *)playbuf , (sizeof(playbuf))/4); // start continuous data stream  

 

btw :    the playbuffer is 16 KB size, giving about 40ms for every callback, to fill new data in. Or just 00 , for silence/pause/stop.

If you feel a post has answered your question, please click "Accept as Solution".