试图在
STM32F746上使用DMA使SAI在TDM模式下工作。
需要传输 8 个立体声通道,样本长度为 16 位。所以 16 * 2 * 8 = 256 位帧。
初始化代码:
- hsai_BlockA1.Instance = SAI2_Block_A;
- hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL;
- hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_TX;
- hsai_BlockA1.Init.DataSize = SAI_DATASIZE_32;
- 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_FULL;
- 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 = 1;
- hsai_BlockA1.FrameInit.FSDefinition = SAI_FS_STARTFRAME;
- hsai_BlockA1.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
- hsai_BlockA1.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
- hsai_BlockA1.SlotInit.FirstBitOffset = 0;
- hsai_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
- hsai_BlockA1.SlotInit.SlotNumber = 8;
- hsai_BlockA1.SlotInit.SlotActive = 0x000000FF;
- HAL_SAI_Init(&hsai_BlockA1);
MSP 初始化:
- if(hsai->Instance==SAI2_Block_A)
- {
- /* Peripheral clock enable */
- /** Initializes the peripherals clock
- */
- PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
- PeriphClkInitStruct.PLLSAI.PLLSAIN = 316;
- PeriphClkInitStruct.PLLSAI.PLLSAIR = 2;
- PeriphClkInitStruct.PLLSAI.PLLSAIQ = 7;
- PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV2;
- PeriphClkInitStruct.PLLSAIDivQ = 1;
- PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
- PeriphClkInitStruct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLSAI;
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- if (SAI2_client == 0)
- {
- __HAL_RCC_SAI2_CLK_ENABLE();
- /* Peripheral interrupt init*/
- HAL_NVIC_SetPriority(SAI2_IRQn, 5, 0);
- HAL_NVIC_EnableIRQ(SAI2_IRQn);
- }
- SAI2_client ++;
- /**SAI2_A_Block_A GPIO Configuration
- PD11 ------> SAI2_SD_A
- PD12 ------> SAI2_FS_A
- PD13 ------> SAI2_SCK_A
- */
- GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Alternate = GPIO_AF8_SAI2;
- HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
- /* Peripheral DMA init*/
- hdma_sai2_a.Instance = DMA2_Stream4;
- hdma_sai2_a.Init.Channel = DMA_CHANNEL_3;
- 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_WORD;
- hdma_sai2_a.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
- hdma_sai2_a.Init.Mode = DMA_CIRCULAR;
- hdma_sai2_a.Init.Priority = DMA_PRIORITY_MEDIUM;
- hdma_sai2_a.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
- if (HAL_DMA_Init(&hdma_sai2_a) != HAL_OK)
- {
- Error_Handler();
- }
- /* 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_sai2_a);
- __HAL_LINKDMA(hsai,hdmatx,hdma_sai2_a);
- }
启动 DMA 后,DMA 流的 NDTR 寄存器被设置为 BufferSize-8(我假设由于 FIFO 大小为 8 字节)并且之后没有任何反应。没有产生任何中断。在软件轮询模式下,由于超时,我收到 HAL_ERROR。