cancel
Showing results for 
Search instead for 
Did you mean: 

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

BRusl.1
Associate III

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 ?

17 REPLIES 17
AScha.3
Chief II

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 "Accept as Solution".

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

Some additional code where types are visible:

```

...

typedef struct {

 uint16_t buff[AUDIO_BUFFER_SIZE];

 volatile BUFFER_StateTypeDef state;

} AUDIO_BufferTypeDef;

...

static AUDIO_BufferTypeDef play_data;

...

AUDIO_ErrorTypeDef AUDIO_OUT_Start(void) {

 // fill first half of buf

 gen(play_data.buff, AUDIO_BUFFER_SIZE / 2); // size in shorts

 playback_state = AUDIO_STATE_PLAYING;

 play_data.state = BUFFER_FIRST_PLAYING;

 // plays data from both buffers, making interrupt in half

 return BSP_AUDIO_OUT_Play(play_data.buff, AUDIO_BUFFER_SIZE * 2); // size in bytes

}

```

AScha.3
Chief II

look with scope...wordclk is 16k ?

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

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
Associate III

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
Chief II

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 "Accept as Solution".
BRusl.1
Associate III

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
Chief II

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 "Accept as Solution".