Skip to main content
BRusl.1
Associate II
May 5, 2023
Question

STM32F723 DISCO, Audio play/record example - SAI interrupts twice fast then expected

  • May 5, 2023
  • 17 replies
  • 4200 views

Hi,

Having STM32F723 DISCO with simple play/record example. Need to process sound by 20ms periods, so I've calculated PCM buffer size as :

```

#define AUDIO_CHANNELS         2

#define AUDIO_PCM_BIT_RESOLUTION    16

#define AUDIO_SAMPLE_LENGTH_MS     20

#define AUDIO_SAMPLE_SIZE        (AUDIO_CHANNELS * (SAMPLE_RATE/1000) * AUDIO_SAMPLE_LENGTH_MS)

#define AUDIO_PERIODS          2

#define AUDIO_BUFFER_SIZE        (AUDIO_SAMPLE_SIZE * AUDIO_PERIODS)

```

So I'm expect the HAL_SAI_TxHalfCpltCallback & HAL_SAI_TxCpltCallback to trigger each 20ms, but it triggers each 10ms:

```

[0000:00:00:00.000] Firmware v1.0 started, h/w rev: 0x1000

[0000:00:00:00.000] System clock: 216 MHz, HCLK/AHB clock: 216 MHz, PCLK1/APB1 clock: 54 MHz, PCLK2/APB2 clock: 108 MHz

[0000:00:00:00.655] SAI clock: 49.142856 MHz

[0000:00:00:00.655] Audio inited: Sample rate: 16000, channels: 2, period length: 20 ms, AUDIO_PCM16BIT_SAMPLE_SIZE: 640, doubled AUDIO_PCM16BIT_BUFFER_SIZE: 1280

[0000:00:00:00.655] Board inited

[0000:00:00:00.655] App started

[0000:00:00:00.655] Generating sine table for 200Hz

[0000:00:00:00.832] Sine table gen completed

[0000:00:00:00.833] Audio started

[0000:00:00:00.843] BSP_AUDIO_OUT_HalfTransfer_CallBack

[0000:00:00:00.853] BSP_AUDIO_OUT_TransferComplete_CallBack

[0000:00:00:00.863] BSP_AUDIO_OUT_HalfTransfer_CallBack

[0000:00:00:00.873] BSP_AUDIO_OUT_TransferComplete_CallBack

```

What can be the problem ?

This topic has been closed for replies.

17 replies

AScha.3
Super User
May 5, 2023

you set for 20ms chunk 1280 Byte (320 int16 x 2 ch) , ok.

but for half.. and cplt... callback each buffer needs to be 1280 B.

then each half plays 20ms , as you expect. :)

If you feel a post has answered your question, please click on " Best Answer ".
BRusl.1
BRusl.1Author
Associate II
May 5, 2023

Not bytes. 1280 is PCM16BIT - this is uint16_t type which 2 bytes long

AScha.3
Super User
May 5, 2023

look with scope...wordclk is 16k ?

If you feel a post has answered your question, please click on " Best Answer ".
BRusl.1
BRusl.1Author
Associate II
May 5, 2023

Can you please clarify the "wordclk" ? Anyway I can't look with scope as both chips (STM32F723IEK & WM8994) are BGA. The BSP code (stm32f723e_discovery_audio.c) taken unchanged from STM32F7Cube

BRusl.1
BRusl.1Author
Associate II
May 5, 2023

Found some test points at devkit, measured:

TP7 (SAI2_SCK_A) - 1.025MHz

TP11 (SAI2_FS_A) - 16.03KHz

TP6 (SAI2_MCLK_A) - 4.098MHz

AScha.3
Super User
May 5, 2023

ok, wordclk = frame fs , 16k - ok.

but bitclk 1 M , should be 16k x 2 ch x 16 bit -> 512k .

so now we know: you send 4 words/frame or 2 words 32 bit data in 16 bit data slot ...?

If you feel a post has answered your question, please click on " Best Answer ".
BRusl.1
BRusl.1Author
Associate II
May 5, 2023

Yes, you are right. I suspect that original ST BSP code from stm32f723e_discovery_audio.c is buggy - if anybody try to use their stock Audio_playback_and_record example then wrong playback speed will be noticeable.

The actual code there is:

```

static void SAIx_Out_Init(uint32_t AudioFreq)

{

 /* Initialize the haudio_out_sai Instance parameter */

 haudio_out_sai.Instance = AUDIO_OUT_SAIx;

  

 /* Disable SAI peripheral to allow access to SAI internal registers */

 __HAL_SAI_DISABLE(&haudio_out_sai);

  

 /* Configure SAI_Block_x 

 LSBFirst: Disabled 

 DataSize: 16 */

 haudio_out_sai.Init.MonoStereoMode = SAI_STEREOMODE;

 haudio_out_sai.Init.AudioFrequency = AudioFreq;

 haudio_out_sai.Init.AudioMode = SAI_MODEMASTER_TX;

 haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLED;

 haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL;

 haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;

 haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;

 haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;

 haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS;

 haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;

 haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;

 haudio_out_sai.Init.SynchroExt   = SAI_SYNCEXT_DISABLE;

 haudio_out_sai.Init.CompandingMode = SAI_NOCOMPANDING;

 haudio_out_sai.Init.TriState    = SAI_OUTPUT_NOTRELEASED;

 haudio_out_sai.Init.Mckdiv     = 0;

   

 /* Configure SAI_Block_x Frame 

 Frame Length: 64

 Frame active Length: 32

 FS Definition: Start frame + Channel Side identification

 FS Polarity: FS active Low

 FS Offset: FS asserted one bit before the first bit of slot 0 */ 

 haudio_out_sai.FrameInit.FrameLength = 64;

 haudio_out_sai.FrameInit.ActiveFrameLength = 32;

 haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;

 haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;

 haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;

  

 /* Configure SAI Block_x Slot 

 Slot First Bit Offset: 0

 Slot Size : 16

 Slot Number: 4

 Slot Active: All slot actives */

 haudio_out_sai.SlotInit.FirstBitOffset = 0;

 haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;

 haudio_out_sai.SlotInit.SlotNumber = 4; 

 haudio_out_sai.SlotInit.SlotActive = CODEC_AUDIOFRAME_SLOT_0123;

 HAL_SAI_Init(&haudio_out_sai);

  

 /* Enable SAI peripheral to generate MCLK */

 __HAL_SAI_ENABLE(&haudio_out_sai);

```

I suspect that FrameInit.FrameLength & ActiveFrameLength are incorrect, right ?

AScha.3
Super User
May 5, 2023

depends....what it should be. 64b frame + 32b active : looks like 16b in 32b frames (some dacs use this).

BUT : slot no. 4 -> is 4 channel output ...thats wrong, if there is stereo dac.

slot must be 2 . for stereo. try.

and your dac setting is 16b in 32b frame ? left just. ?

and : freeprotocol ??? not I2S ? i use SAI_I2S_STANDARD .

ok, i looked... you send to WM8994 ? is 4 ch dac, what mode is it programmed to?

If you feel a post has answered your question, please click on " Best Answer ".
BRusl.1
BRusl.1Author
Associate II
May 5, 2023

If I change SlotInit.SlotNumber to 2 then I'm having correct 20 ms interrupts :

```

[0000:00:00:00.552] BSP_AUDIO_OUT_HalfTransfer_CallBack

[0000:00:00:00.572] BSP_AUDIO_OUT_TransferComplete_CallBack

```

But TP7 (SAI2_SCK_A) is still shows 1.025Mhz and now no sound at all. The SAI_I2S_STANDARD do not change anything here.

BRusl.1
BRusl.1Author
Associate II
May 5, 2023

I do not touch WM8994 modes - all left as is from stm32f723e_discovery_audio.c

BRusl.1
BRusl.1Author
Associate II
May 5, 2023

Found the issue, I've called the :

```

if (BSP_AUDIO_OUT_Init((spk ? OUTPUT_DEVICE_SPEAKER : OUTPUT_DEVICE_HEADPHONE), AUDIO_DEFAULT_VOLUME, SAMPLE_RATE))

 return AUDIO_ERROR_IO;

if (BSP_AUDIO_IN_Init(SAMPLE_RATE, AUDIO_PCM_BIT_RESOLUTION, AUDIO_CHANNELS))

 return AUDIO_ERROR_IO;

```

But looks like BSP_AUDIO_IN_Init mangles the SAI settings, if I comment out the BSP_AUDIO_IN_Init() then playback work as expected !

Seems like full duplex was never tested or intented in stock BSP code ;(

Thanks AScha for pointing out to the problem, though I still do not understand how it is working with SAI2_SCK_A 1.025Mhz

AScha.3
Super User
May 5, 2023

1M because 4 slot (= channels) are sent, but only 2 filled with data, 2 slots as dummy (null filled);

so 64 b in a frame, but 32 b (2 x 16 b ) is the real data.

If you feel a post has answered your question, please click on " Best Answer ".