cancel
Showing results for 
Search instead for 
Did you mean: 

SAI Problems in slave receiver mode

mickael2
Associate II

Hello,

I am trying to read sample from a AD7768 using a STM32F767. The data is feed to the SAI peripheral at 8Mhz. I used this code https://github.com/pavel-demin/stm32f7-discovery-usb-headset/blob/master/Drivers/BSP/STM32746G-Discovery/stm32746g_discovery_audio.c has reference.

I am reading sample in burst of few k bytes using the DMA. But approximately half the samples are wrongs. It looks like the first frame bit is read before the frame start which lead to a data frame shift of 1 bit. When it happens the bit LFSDET (Late frame synchronization detection) is set in the SR register. Sometime even if the data are correct the LFSDET bit is set.

I tried every frame synchronization and clock configuration but I cannot make it works. My best results are for [SAI_CLOCKSTROBING_FALLINGEDGE, SAI_FS_ACTIVE_HIGH, SAI_FS_BEFOREFIRSTBIT] and [SAI_CLOCKSTROBING_FALLINGEDGE, SAI_FS_ACTIVE_LOW SAI_FS_FIRSTBIT].

I use the following SAI initialization :

    __HAL_RCC_SAI1_CLK_ENABLE();
 
    _hsai1_a.Instance = SAI1_Block_A;
    _hsai1_a.Init.Protocol = SAI_FREE_PROTOCOL;
    _hsai1_a.Init.AudioMode = SAI_MODESLAVE_RX;
    _hsai1_a.Init.DataSize = SAI_DATASIZE_32;
    _hsai1_a.Init.FirstBit = SAI_FIRSTBIT_MSB;
    _hsai1_a.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
    _hsai1_a.Init.Synchro = SAI_ASYNCHRONOUS;
    _hsai1_a.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
    _hsai1_a.Init.NoDivider = SAI_MASTERDIVIDER_DISABLE;
    _hsai1_a.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_FULL;
    _hsai1_a.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
    _hsai1_a.Init.MonoStereoMode = SAI_STEREOMODE;
    _hsai1_a.Init.CompandingMode = SAI_NOCOMPANDING;
    _hsai1_a.FrameInit.FrameLength = 128;
    _hsai1_a.FrameInit.ActiveFrameLength = 1;
    
    _hsai1_a.FrameInit.FSDefinition = SAI_FS_STARTFRAME;
    #if 0
    _hsai1_a.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
    _hsai1_a.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
    #else 
    _hsai1_a.FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
    _hsai1_a.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
    #endif
    _hsai1_a.SlotInit.FirstBitOffset = 0;
    _hsai1_a.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
    _hsai1_a.SlotInit.SlotNumber = 4;
    _hsai1_a.SlotInit.SlotActive = 0x0000FFFF;
    if (HAL_SAI_Init(&_hsai1_a) != HAL_OK) {
      //Error_Handler();
      while(1);
    }

Electrics signals are good.

The full driver code is in attachment, it used with the pseudo-code :

_ad7768.initalize();
while(1){
    _ad7768.start(_buffer, _BUFFER_SIZE);
    _ad7768.wait_for_receive_complete();
    wait(1second);
}

I don't understand what is wrong with my setup. It looks like the FS signal is not detect as it should...

Did someone had the same problem ?

Do you have slave receiver code examples ?

Regards,

2 REPLIES 2
KChen.22
Associate

Hello, I am currently facing the same issue as you. Has this problem been resolved? Would you mind sharing the solution? Thank you.

Le7T
Associate

@KChen.22 @mickael2 

Here's a solution you might try:

1) SAI Settings:

ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE

FSPolarity = SAI_FS_ACTIVE_HIGH

FSOffset = SAI_FS_BEFORFIRSTBIT

Ref:en.STM32WB-Peripheral-Serial-Audio-Interface-SAI.pdf;ad7768-7768-4.pdf

2) The LFSDET Problem:

By default setting of AD7768,the Fmod = MCLK/32,DCLK = MCLK/8,DecimationRate = 1024.If MCLK = 32.768Mhz,the output data rate would be 1kHz(DRDY signal period = 1ms),but to transmit 128 bits data over DOUT pin only takes 31.25us,so there are more than 128 DCLK cycles between DRDY pluse,which causes the LFSDET problem.You can just disable the LFSDET interrupt,it won't affect the data reception.Or you can change AD7768 setting to match the DRDY signal period and the time for transmition,for example:Set Fmod = MCLK/32,DCLK = MCLK/8,DecimationRate = 32,the output data rate would be 32kHz(T = 31.25us),and time for transmition(128bits) is 31.25us,when the LFSDET bit would not be set.