AnsweredAssumed Answered

STM32L476 SAI2 MCLK generation

Question asked by Def on Feb 10, 2017
Latest reply on Feb 14, 2017 by Def

Hi,

 

I'm trying to communicate with ADAU1761 via SAI, STM32L476 is master. I sucessfully connected to it via I2C, now I need to send data. I dont have much experience with SAI. The task is to play 22.05kHz 16 bit WAVE and also record audio. I used SAI2A for RX, SAI2B for TX, 4 pins mode (ADC_SDATA - SAI2_SD_A, DAC_SDATA - SAI2_SD_B, LRCLK - SAI2_FS_A, BCLK - SAI2_SCK_A). I saw this guide but instead of using SAI2A for TX I use it for RX. As far I as understood ADAU1761 needs MCLK to record/play audio. When I use HAL_SAI_Transmit() the MCLK is not generated, I checked it with logic analyzer. However with HAL_SAI_Receive() MCLK is present. Is there any way to generate MCLK during HAL_SAI_Transmit() with this configuration? Maybe somebody has some experience with interfacing STM32 and ADAU17xx or ADAU14xx DSPs. Here is my configuration:

 

 

 

void MX_SAI2_Init(void)
{

hsai_BlockA2.Instance = SAI2_Block_A;
hsai_BlockA2.Init.Protocol = SAI_FREE_PROTOCOL;
hsai_BlockA2.Init.AudioMode = SAI_MODEMASTER_RX;
hsai_BlockA2.Init.DataSize = SAI_DATASIZE_16;
hsai_BlockA2.Init.FirstBit = SAI_FIRSTBIT_MSB;
hsai_BlockA2.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
hsai_BlockA2.Init.Synchro = SAI_ASYNCHRONOUS;
hsai_BlockA2.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
hsai_BlockA2.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
hsai_BlockA2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
hsai_BlockA2.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_22K;
hsai_BlockA2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
hsai_BlockA2.Init.MonoStereoMode = SAI_STEREOMODE;
hsai_BlockA2.Init.CompandingMode = SAI_NOCOMPANDING;
hsai_BlockA2.FrameInit.FrameLength = 32;
hsai_BlockA2.FrameInit.ActiveFrameLength = 16;
hsai_BlockA2.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
hsai_BlockA2.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
hsai_BlockA2.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
hsai_BlockA2.SlotInit.FirstBitOffset = 0;
hsai_BlockA2.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
hsai_BlockA2.SlotInit.SlotNumber = 2;
hsai_BlockA2.SlotInit.SlotActive = 0x00000003;
if (HAL_SAI_Init(&hsai_BlockA2) != HAL_OK)
{
Error_Handler();
}

hsai_BlockB2.Instance = SAI2_Block_B;
hsai_BlockB2.Init.Protocol = SAI_FREE_PROTOCOL;
hsai_BlockB2.Init.AudioMode = SAI_MODESLAVE_TX;
hsai_BlockB2.Init.DataSize = SAI_DATASIZE_16;
hsai_BlockB2.Init.FirstBit = SAI_FIRSTBIT_MSB;
hsai_BlockB2.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
hsai_BlockB2.Init.Synchro = SAI_SYNCHRONOUS;
hsai_BlockB2.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
hsai_BlockB2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
hsai_BlockB2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
hsai_BlockB2.Init.MonoStereoMode = SAI_STEREOMODE;
hsai_BlockB2.Init.CompandingMode = SAI_NOCOMPANDING;
hsai_BlockB2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
hsai_BlockB2.FrameInit.FrameLength = 32;
hsai_BlockB2.FrameInit.ActiveFrameLength = 16;
hsai_BlockB2.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
hsai_BlockB2.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
hsai_BlockB2.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
hsai_BlockB2.SlotInit.FirstBitOffset = 0;
hsai_BlockB2.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
hsai_BlockB2.SlotInit.SlotNumber = 2;
hsai_BlockB2.SlotInit.SlotActive = 0x00000003;
if (HAL_SAI_Init(&hsai_BlockB2) != HAL_OK)
{
Error_Handler();
}

}

 

 

DMA SAI2A init:

 

hdma_sai2_a.Instance = DMA1_Channel6;
hdma_sai2_a.Init.Request = DMA_REQUEST_1;
hdma_sai2_a.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sai2_a.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sai2_a.Init.MemInc = DMA_MINC_ENABLE;
hdma_sai2_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_sai2_a.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_sai2_a.Init.Mode = DMA_CIRCULAR;
hdma_sai2_a.Init.Priority = DMA_PRIORITY_HIGH;

 

 

DMA SAI2B init:

 

hdma_sai2_b.Instance = DMA1_Channel7;
hdma_sai2_b.Init.Request = DMA_REQUEST_1;
hdma_sai2_b.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sai2_b.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sai2_b.Init.MemInc = DMA_MINC_ENABLE;
hdma_sai2_b.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_sai2_b.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_sai2_b.Init.Mode = DMA_CIRCULAR;
hdma_sai2_b.Init.Priority = DMA_PRIORITY_HIGH;

Outcomes