2016-06-15 04:01 AM
Hello everyone.
I am a bit stuck with SAI configuration for STM32F446 MCU. What I want to get is a full duplex SAI, working with PCM-coded signal coming from bluetooth module. Now I am trying to configure the SAI bus. To do so I use StdPeripheral Drivers set. First, I select the clock source for SAI and configure its frequency:
void
PLLSAI_Config(
void
)
{
/* Configure PLLI2S prescalers */
/* PLLI2S_VCO : VCO_344M */
/* SAI_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 344/7 = 142 Mhz */
RCC_PLLI2SConfig(16, 344, 2, 7, 2);
/* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ = 142/1 = 142 Mhz */
RCC_SAIPLLI2SClkDivConfig(1);
/* Configure Clock source for SAI */
RCC_SAICLKConfig(RCC_SAIInstance_SAI1, RCC_SAICLKSource_PLLI2S);
/* Enable PLLI2S Clock */
RCC_PLLI2SCmd(ENABLE);
/* Wait till PLLI2S is ready */
while
(RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY) == RESET)
{
}
LOG_OUT(
''SAI clocks configured\n''
);
}
Second, I configure GPIO pins as alternate functions, no problem here.
Third configure SAI bus, enable the interrupts, enable SAI:
SAI_InitTypeDef tx_cfg =
{
.SAI_Protocol = SAI_Free_Protocol,
.SAI_AudioMode = SAI_Mode_MasterTx,
.SAI_DataSize = SAI_DataSize_16b,
.SAI_FirstBit = SAI_FirstBit_MSB,
.SAI_ClockStrobing = SAI_ClockStrobing_RisingEdge,
.SAI_Synchro = SAI_Asynchronous,
.SAI_OUTDRIV = SAI_OutputDrive_Disabled,
.SAI_NoDivider = SAI_MasterDivider_Enabled,
.SAI_FIFOThreshold = SAI_FIFOThreshold_HalfFull,
};
SAI_InitTypeDef rx_cfg =
{
.SAI_Protocol = SAI_Free_Protocol,
.SAI_AudioMode = SAI_Mode_SlaveRx,
.SAI_DataSize = SAI_DataSize_16b,
.SAI_FirstBit = SAI_FirstBit_MSB,
.SAI_ClockStrobing = SAI_ClockStrobing_RisingEdge,
.SAI_Synchro = SAI_Synchronous,
.SAI_OUTDRIV = SAI_OutputDrive_Disabled,
.SAI_NoDivider = SAI_MasterDivider_Enabled,
.SAI_FIFOThreshold = SAI_FIFOThreshold_HalfFull,
};
SAI_FrameInitTypeDef frame_cfg =
{
.SAI_FrameLength = 16U * 2,
.SAI_ActiveFrameLength = 1U,
.SAI_FSDefinition = SAI_FS_StartFrame,
.SAI_FSPolarity = SAI_FS_ActiveLow,
.SAI_FSOffset = SAI_FS_BeforeFirstBit,
};
SAI_SlotInitTypeDef slot_cfg =
{
.SAI_FirstBitOffset = 0U,
.SAI_SlotSize = SAI_SlotSize_16b,
.SAI_SlotNumber = 2,
.SAI_SlotActive = SAI_SlotActive_ALL,
};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SAI1, ENABLE);
uint32_t tmpdiv = ((uint32_t)49152000) / (16000 * 512);
tx_cfg.SAI_MasterDivider = tmpdiv;
rx_cfg.SAI_MasterDivider = tmpdiv;
SAI_Init(SAI1_Block_A, &tx_cfg);
SAI_Init(SAI1_Block_B, &rx_cfg);
SAI_FrameInit(SAI1_Block_A, &frame_cfg);
SAI_FrameInit(SAI1_Block_B, &frame_cfg);
SAI_SlotInit(SAI1_Block_A, &slot_cfg);
SAI_SlotInit(SAI1_Block_B, &slot_cfg);
SAI_FlushFIFO(SAI1_Block_A);
SAI_FlushFIFO(SAI1_Block_B);
SAI_MonoModeConfig(SAI1_Block_A, SAI_MonoMode);
SAI_MonoModeConfig(SAI1_Block_B, SAI_MonoMode);
NVIC_SetPriority(SAI1_IRQn, 0);
NVIC_EnableIRQ(SAI1_IRQn);
uint32_t intsf = SAI_IT_FREQ | SAI_IT_OVRUDR | SAI_IT_AFSDET | SAI_IT_LFSDET | SAI_IT_CNRDY;
SAI_ITConfig(SAI1_Block_A, intsf, ENABLE);
SAI_ITConfig(SAI1_Block_B, intsf, ENABLE);
SAI_Cmd(SAI1_Block_A, ENABLE);
SAI_Cmd(SAI1_Block_B, ENABLE);
But then nothing happens, I don't have any interrupts or what is more strange I even don't have a clock on SCK pin of the MCU. Could someone give me any hints where to dig further? May be I messed up with configuration or clocks?
Thanks!
#audio #sai #pcm
2016-06-27 04:58 AM
Hi xoroxo,
I suggest you refer to the SAI_Audio example available in the F4 StdPeriph_Lib package (STM32F4xx_DSP_StdPeriph_Lib_V1.7.1\Project\STM32F4xx_StdPeriph_Examples\SAI\SAI_Audio). The example runs on STM32F429xx/439xx devices but you may take it as a start point to configure your SAI using STM32F446.You find dedicated SAI examples for STM32F446 devices if you use Cube: STM32Cube_FW_F4_V1.12.0\Projects\STM32446E_EVAL\Examples\SAI-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.