cancel
Showing results for 
Search instead for 
Did you mean: 

My MCLK on SAI1 Block A stopped working?

Jeremy Vance_2
Associate III
Posted on November 03, 2017 at 17:25

I have been developing a TDM audio system for a multi-mono output system.  I had the SAI1 BlockA working great a few weeks ago but now I'm not getting anything out of the MCLK or other pins.  I haven't changed the init code and have even tried going back to straight STM32CubeMX code to see if it would fix the issues.

Here is the Init Code for my 44100Hz Sampled Audio:

void MX_SAI1_Init(void)

{

hsai_BlockA1.Instance = SAI1_Block_A;

hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL;

hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_TX;

hsai_BlockA1.Init.DataSize = SAI_DATASIZE_16;

hsai_BlockA1.Init.FirstBit = SAI_FIRSTBIT_MSB;

hsai_BlockA1.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;

hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;

hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;

hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;

hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_HF;

hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;

hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;

hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;

hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;

hsai_BlockA1.Init.TriState = SAI_OUTPUT_NOTRELEASED;

hsai_BlockA1.FrameInit.FrameLength = 256;

hsai_BlockA1.FrameInit.ActiveFrameLength = 32;

hsai_BlockA1.FrameInit.FSDefinition = SAI_FS_STARTFRAME;

hsai_BlockA1.FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;

hsai_BlockA1.FrameInit.FSOffset = SAI_FS_FIRSTBIT;

hsai_BlockA1.SlotInit.FirstBitOffset = 0;

hsai_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_32B;

hsai_BlockA1.SlotInit.SlotNumber = 8;

hsai_BlockA1.SlotInit.SlotActive = 0x0000FFFF;

if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

__HAL_SAI_ENABLE(&hsai_BlockA1);

}

static uint32_t SAI1_client =0;

void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)

{

GPIO_InitTypeDef GPIO_InitStruct;

/* SAI1 */

if(hsai->Instance==SAI1_Block_A)

{

/* SAI1 clock enable */

if (SAI1_client == 0)

{

__HAL_RCC_SAI1_CLK_ENABLE();

/* Peripheral interrupt init*/

HAL_NVIC_SetPriority(SAI1_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(SAI1_IRQn);

}

SAI1_client ++;

/**SAI1_A_Block_A GPIO Configuration

PE2 ------> SAI1_MCLK_A

PE4 ------> SAI1_FS_A

PE5 ------> SAI1_SCK_A

PE6 ------> SAI1_SD_A

*/

GPIO_InitStruct.Pin = MCLK_Pin|LRCLK_Pin|BCLK_Pin|TDMO_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitStruct.Alternate = GPIO_AF6_SAI1;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

/* Peripheral DMA init*/

hdma_sai1_a.Instance = DMA2_Stream1;

hdma_sai1_a.Init.Channel = DMA_CHANNEL_0;

hdma_sai1_a.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_sai1_a.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_sai1_a.Init.MemInc = DMA_MINC_ENABLE;

hdma_sai1_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

hdma_sai1_a.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

hdma_sai1_a.Init.Mode = DMA_CIRCULAR;

hdma_sai1_a.Init.Priority = DMA_PRIORITY_VERY_HIGH;

hdma_sai1_a.Init.FIFOMode = DMA_FIFOMODE_ENABLE;

hdma_sai1_a.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;

hdma_sai1_a.Init.MemBurst = DMA_MBURST_SINGLE;

hdma_sai1_a.Init.PeriphBurst = DMA_PBURST_SINGLE;

if (HAL_DMA_Init(&hdma_sai1_a) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

/* Several peripheral DMA handle pointers point to the same DMA handle.

Be aware that there is only one stream to perform all the requested DMAs. */

__HAL_LINKDMA(hsai,hdmarx,hdma_sai1_a);

__HAL_LINKDMA(hsai,hdmatx,hdma_sai1_a);

}

}

I'm not getting any errors and the code is running at the right speed but I'm not getting anything out of the SAI block.  I have tried calling __HAL_SAI_ENABLE multiple times as well as trying to send zero'd data over DMA or polling mode.  I see no MCLK transitions on my oscilloscope.  The pins are connected just to the DAC pins through 100R resistors.

Can someone help me?  I'm using a STM32F746VGT6.  I have tried 3 different boards now with the same issue.

#sai #stm32f746
2 REPLIES 2
Jeremy Vance_2
Associate III
Posted on November 03, 2017 at 18:47

Okay, there must be something wrong with my code because I cannot get the F7 discovery board to work either.  I can toggle the MCLK pins manually but the SAI controller is not working but no errors.

Here is my main: 

int main(void)

{

HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */

SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_DMA_Init();

MX_I2C1_Init();

MX_I2C2_Init();

MX_SAI1_Init();

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

}

No errors but no MCLK waveform on PE2 either.

Posted on November 03, 2017 at 22:41

Further inspection reveals that only the MCLK on PE2 is constant low.  All other signals, BICK, LRCK, SD all work as expected.

Can someone tell me what I've done wrong here?  The DAC I'm using will not go active until it has an MCLK signal.

Thanks,

Jeremy