|
void MX_SAI2_Init(void)
{
HAL_SAI_DeInit(&SAI2B_RX_Handler); //清除以前的配置
SAI2B_RX_Handler.Instance = SAI2_Block_B;
SAI2B_RX_Handler.Init.Protocol = SAI_FREE_PROTOCOL; //自由协议(支持I2S/LSB/MSB/TDM/PCM/DSP等协议)
SAI2B_RX_Handler.Init.AudioMode = SAI_MODEMASTER_RX;
SAI2B_RX_Handler.Init.Synchro = SAI_ASYNCHRONOUS;
SAI2B_RX_Handler.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE; //SAI_OUTPUTDRIVE_ENABLE; //立即驱动音频模块输出;
SAI2B_RX_Handler.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; //使能主时钟分频器(MCKDIV)
SAI2B_RX_Handler.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY; //SAI_FIFOTHRESHOLD_EMPTY; //SAI_FIFOTHRESHOLD_FULL
SAI2B_RX_Handler.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_48K;
SAI2B_RX_Handler.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
SAI2B_RX_Handler.Init.MonoStereoMode = SAI_STEREOMODE; //立体声模式
SAI2B_RX_Handler.Init.CompandingMode = SAI_NOCOMPANDING;
SAI2B_RX_Handler.Init.TriState = SAI_OUTPUT_NOTRELEASED;
//帧设置
SAI2B_RX_Handler.FrameInit.FrameLength=128; //设置帧长度为32,左通道16个SCK,右通道16个SCK.
SAI2B_RX_Handler.FrameInit.ActiveFrameLength=16; //设置帧同步有效电平长度,在I2S模式下=1/2帧长.
SAI2B_RX_Handler.FrameInit.FSDefinition=SAI_FS_STARTFRAME; //SAI_FS_CHANNEL_IDENTIFICATION;//FS信号为SOF信号+通道识别信号
SAI2B_RX_Handler.FrameInit.FSPolarity=SAI_FS_ACTIVE_LOW; //FS低电平有效(下降沿)
SAI2B_RX_Handler.FrameInit.FSOffset=SAI_FS_FIRSTBIT; //SAI_FS_BEFOREFIRSTBIT; //在slot0的第一位的前一位使能FS,以匹配飞利浦标准
//SLOT设置
SAI2B_RX_Handler.SlotInit.FirstBitOffset=0; //slot偏移(FBOFF)为0
SAI2B_RX_Handler.SlotInit.SlotSize=SAI_SLOTSIZE_16B; //slot大小为16位
SAI2B_RX_Handler.SlotInit.SlotNumber=8; //slot数为8个
SAI2B_RX_Handler.SlotInit.SlotActive=SAI_SLOTACTIVE_0|SAI_SLOTACTIVE_1|SAI_SLOTACTIVE_2|SAI_SLOTACTIVE_3|SAI_SLOTACTIVE_4|SAI_SLOTACTIVE_5|SAI_SLOTACTIVE_6|SAI_SLOTACTIVE_7;
if (HAL_SAI_InitProtocol(&SAI2B_RX_Handler, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 8) != HAL_OK)
{
Error_Handler();
}
}
static uint32_t SAI2_client =0;
static uint32_t FMC_Initialized = 0;
void HAL_SAI_MspInit(SAI_HandleTypeDef* saiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if (FMC_Initialized)
{
return;
}
FMC_Initialized = 1;
/* SAI2 */
if(saiHandle->Instance==SAI2_Block_B)
{
/* SAI2 clock enable */
// Initializes the peripherals clock
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI2B;
PeriphClkInitStruct.Sai2BClockSelection = RCC_SAI2BCLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
if (SAI2_client == 0)
{
__HAL_RCC_SAI2_CLK_ENABLE();
}
SAI2_client ++;
/**SAI2_B_Block_B GPIO Configuration
PC0 ------> SAI2_FS_B
PA0 ------> SAI2_SD_B
PA2 ------> SAI2_SCK_B
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_SAI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_SAI2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral DMA init*/
SAI2B_RXhdma_Handler.Instance = DMA1_Stream0;
SAI2B_RXhdma_Handler.Init.Request = DMA_REQUEST_SAI2_B;
SAI2B_RXhdma_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;
SAI2B_RXhdma_Handler.Init.PeriphInc = DMA_PINC_DISABLE;
SAI2B_RXhdma_Handler.Init.MemInc = DMA_MINC_ENABLE;
SAI2B_RXhdma_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
SAI2B_RXhdma_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
SAI2B_RXhdma_Handler.Init.Mode = DMA_CIRCULAR;
SAI2B_RXhdma_Handler.Init.Priority = DMA_PRIORITY_LOW;
SAI2B_RXhdma_Handler.Init.FIFOMode = DMA_FIFOMODE_ENABLE; //DMA_FIFOMODE_DISABLE; //DMA_FIFOMODE_ENABLE;
SAI2B_RXhdma_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
SAI2B_RXhdma_Handler.Init.MemBurst = DMA_MBURST_SINGLE;
SAI2B_RXhdma_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_DeInit(&SAI2B_RXhdma_Handler);
if (HAL_DMA_Init(&SAI2B_RXhdma_Handler) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&SAI2B_RX_Handler,hdmarx,SAI2B_RXhdma_Handler);
__HAL_LINKDMA(&SAI2B_RX_Handler,hdmatx,SAI2B_RXhdma_Handler);
HAL_DMA_RegisterCallback(&SAI2B_RXhdma_Handler, HAL_DMA_XFER_CPLT_CB_ID, BSP_SAI_REC_M0_RX_Callback);
HAL_DMA_RegisterCallback(&SAI2B_RXhdma_Handler, HAL_DMA_XFER_M1CPLT_CB_ID, BSP_SAI_REC_M1_RX_Callback);
//用不到的中断可以直接关闭
//DMA1_Stream1->CR &= ~DMA_IT_DME;
//DMA1_Stream1->CR &= ~DMA_IT_TE;
}
}
static uint32_t FMC_DeInitialized = 0;
void HAL_SAI_MspDeInit(SAI_HandleTypeDef* saiHandle)
{
/* USER CODE END FMC_MspDeInit 0 */
if (FMC_DeInitialized) {
return;
}
FMC_DeInitialized = 1;
/* SAI2 */
if(saiHandle->Instance==SAI2_Block_B)
{
SAI2_client --;
if (SAI2_client == 0)
{
/* Peripheral clock disable */
__HAL_RCC_SAI2_CLK_DISABLE();
HAL_NVIC_DisableIRQ(SAI2_IRQn);
}
/**SAI2_B_Block_B GPIO Configuration
PC0 ------> SAI2_FS_B
PA0 ------> SAI2_SD_B
PA2 ------> SAI2_SCK_B
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_2);
HAL_DMA_DeInit(saiHandle->hdmarx);
HAL_DMA_DeInit(saiHandle->hdmatx);
}
}
//SAI开始播放
void SAI_REC_Start(void)
{
HAL_DMA_DeInit(SAI2B_RX_Handler.hdmarx);
__HAL_DMA_DISABLE(&SAI2B_RXhdma_Handler); //先关闭接收DMA
HAL_Delay(1); //10us延时,防止-O2优化出问题
/* Change the DMA state */
SAI2B_RXhdma_Handler.State = HAL_DMA_STATE_READY;
//开启双缓冲,及缓冲区的大小
HAL_DMAEx_MultiBufferStart_IT(&SAI2B_RXhdma_Handler, (uint32_t)&SAI2B_RX_Handler.Instance->DR, (uint32_t)sai_rec_buf1, (uint32_t)sai_rec_buf2, 8); //SAI_RX_DMA_BUF_SIZE/2);
/* Several peripheral DMA handle pointers point to the same DMA handle.
Be aware that there is only one channel to perform all the requested DMAs. */
__HAL_LINKDMA(&SAI2B_RX_Handler,hdmarx,SAI2B_RXhdma_Handler);
__HAL_LINKDMA(&SAI2B_RX_Handler,hdmatx,SAI2B_RXhdma_Handler);
__HAL_DMA_ENABLE_IT(&SAI2B_RXhdma_Handler, DMA_IT_TC);
__HAL_DMA_ENABLE_IT(&SAI2B_RXhdma_Handler, DMA_IT_HT);
//开启 DMA1 Stream1 的中断
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0x02, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
__HAL_SAI_ENABLE(&SAI2B_RX_Handler); //使能SAI
HAL_Delay(1);
__HAL_DMA_ENABLE(&SAI2B_RXhdma_Handler); //开启DMA RX传输
}
|
|