2021-06-21 09:36 AM
Good evening, I'm trying to interfacing a MEMS microphone MP34DT05TR in our board using interface SAI1 (SAI1_CK1 on PE1, SAI1_D1 on PD6). To get a faster result (I hoped!!) I used the cubemx to configure the interface and starting code. I see the clock and the (I suppose) the PDM signal on SAI1_D1 but in the following test code I read all zero in RxBuffer
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
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_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 */
HAL_SAI_Receive(&hsai_BlockA1, RxBuffer, 10, 100);
}
/* USER CODE END 3 */
}
Here is the initialization code:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 8;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
static void MX_SAI1_Init(void)
{
/* USER CODE BEGIN SAI1_Init 0 */
/* USER CODE END SAI1_Init 0 */
/* USER CODE BEGIN SAI1_Init 1 */
/* USER CODE END SAI1_Init 1 */
hsai_BlockA1.Instance = SAI1_Block_A;
hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL;
hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_RX;
hsai_BlockA1.Init.DataSize = SAI_DATASIZE_8;
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_EMPTY;
hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
hsai_BlockA1.Init.MonoStereoMode = SAI_MONOMODE;
hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
hsai_BlockA1.Init.PdmInit.Activation = ENABLE;
hsai_BlockA1.Init.PdmInit.MicPairsNbr = 1;
hsai_BlockA1.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
hsai_BlockA1.FrameInit.FrameLength = 16;
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 = 2;
hsai_BlockA1.SlotInit.SlotActive = 0x00000003;
if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SAI1_Init 2 */
/* USER CODE END SAI1_Init 2 */
}
void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/* SAI1 */
if(hsai->Instance==SAI1_Block_A)
{
/* Peripheral clock enable */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
if (SAI1_client == 0)
{
__HAL_RCC_SAI1_CLK_ENABLE();
}
SAI1_client ++;
/**SAI1_A_Block_A GPIO Configuration
PE2 ------> SAI1_CK1
PD6 ------> SAI1_D1
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_SAI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_SAI1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
}
After fix this problem, I would like to convert the input PDM data into PCM to check if the board "listen" something correct. How can I check this? Using an USB stick and creating an audio file? Is there a lib to convert PDM to PCM for the STM32H750?
Thanks in advance to anybody how can help me.
Regards,
D.M.
2021-06-22 08:00 AM
Hello @DMast.1 ,
You can use ST PDM2PCM library within CubeH7 mcu package:
\STM32Cube_FW_H7_V1.9.0\Projects\STM32H750B-DK\Demonstrations\STemWin\Modules\audio_player\Addons\PDM
I adivse you to have a look at these resources :
Hope this helps you :smiling_face_with_smiling_eyes:!
Imen
2021-06-22 08:12 AM
Hi Imen,
thanks but my problem is before using the library to converto the PDM to PCM. As I wrote before, maybe an error on initialize of peripheral, because the HAL_SAI_Receive reads always 0.
Regards,
Renato
2021-06-25 08:03 AM
Any suggestion?
2021-07-06 06:43 AM
Finally something start works....now I get data from mic in polling, but I would like to enable the DMA. I initialize as below, I get the ISR but I don't get data on destination buffer (may be a wrong mic setup sequence)
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SAI1_Init();
/* USER CODE BEGIN 2 */
/* Start the process receive DMA */
HAL_SAI_Receive_DMA(&hsai_BlockA1, RxBuffer, sizeof(RxBuffer));
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Here is the SAI1 init (SAI1_CK1 on PE2, SAI1_D1 on PD6)
static void MX_SAI1_Init(void)
{
/* USER CODE BEGIN SAI1_Init 0 */
/* USER CODE END SAI1_Init 0 */
/* USER CODE BEGIN SAI1_Init 1 */
/* USER CODE END SAI1_Init 1 */
hsai_BlockA1.Instance = SAI1_Block_A;
hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL;
hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_RX;
hsai_BlockA1.Init.DataSize = SAI_DATASIZE_8;
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_EMPTY;
hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_96K;//>>SAI_AUDIO_FREQUENCY_44K;
hsai_BlockA1.Init.MonoStereoMode = SAI_MONOMODE;
hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
hsai_BlockA1.Init.PdmInit.Activation = ENABLE;
hsai_BlockA1.Init.PdmInit.MicPairsNbr = 1;
hsai_BlockA1.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
hsai_BlockA1.FrameInit.FrameLength = 16;
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 = SAI_SLOTACTIVE_0;
hsai_BlockA1.SlotInit.SlotActive = 0x00000003;
if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SAI1_Init 2 */
/* USER CODE END SAI1_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
}
Where MspInit is:
void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/* SAI1 */
if(hsai->Instance==SAI1_Block_A)
{
/* Peripheral clock enable */
/** Initializes the peripherals clock */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_CLKP;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
if (SAI1_client == 0)
{
__HAL_RCC_SAI1_CLK_ENABLE();
}
SAI1_client ++;
/**SAI1_A_Block_A GPIO Configuration
PE2 ------> SAI1_CK1
PD6 ------> SAI1_D1
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_SAI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_SAI1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
__HAL_RCC_DMA2_CLK_ENABLE(); //>>__HAL_RCC_DMA1_CLK_ENABLE();
/* Configure the DMA handler for Reception process */
gSai1_hdma_Rx.Instance = DMA2_Stream5;//>>DMA1_Stream0;//>>SPI4_RX_DMA_STREAM;
gSai1_hdma_Rx.Init.Request = DMA_REQUEST_SAI1_A;
gSai1_hdma_Rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;//>>DMA_FIFOMODE_DISABLE;
gSai1_hdma_Rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
gSai1_hdma_Rx.Init.MemBurst = DMA_MBURST_SINGLE;//>>DMA_MBURST_INC4;
gSai1_hdma_Rx.Init.PeriphBurst = DMA_MBURST_SINGLE;//>>DMA_MBURST_INC4;
gSai1_hdma_Rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
gSai1_hdma_Rx.Init.PeriphInc = DMA_PINC_DISABLE;
gSai1_hdma_Rx.Init.MemInc = DMA_MINC_ENABLE;
gSai1_hdma_Rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;//>>DMA_PDATAALIGN_BYTE;
gSai1_hdma_Rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;//>>DMA_MDATAALIGN_BYTE;
gSai1_hdma_Rx.Init.Mode = DMA_CIRCULAR;//DMA_NORMAL;
gSai1_hdma_Rx.Init.Priority = DMA_PRIORITY_HIGH;
if( HAL_DMA_Init(&gSai1_hdma_Rx) == HAL_OK )
{
/* Select Callbacks functions called after Transfer complete and Transfer error */
/*
if(HAL_DMA_RegisterCallback(&gSai1_hdma_Rx, HAL_DMA_XFER_CPLT_CB_ID, SAI1_DMATransferCompletCplt) != HAL_OK)
{
}
*/
/*
if(HAL_DMA_RegisterCallback(&gSai1_hdma_Rx, HAL_DMA_XFER_ERROR_CB_ID, DMA_TransferErrorCallback) != HAL_OK)
{
Error_Handler();
}
*/
/* Associate the initialized DMA handle to the the SPI handle */
__HAL_LINKDMA(hsai, hdmarx, gSai1_hdma_Rx);
/* SAI DMA IRQ Channel configuration */
HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, AUDIO_IN_IRQ_PREPRIO, 0); //>>HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, AUDIO_IN_IRQ_PREPRIO, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn); //>>HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}
}
}
I get into this ISR, but doesn't read nothing:
/**
*
*/
void DMA2_Stream5_IRQHandler(void) //void DMA1_Stream0_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hsai_BlockA1);
}
What's wrong? Where cai I find the information about what DMA uses the SAI1_A?
After that I would like to convert PDM to PCM and then save data into USB file to check if the audio stream is converted correctly.
Thanks in advance to all who can help me on this issue.
Regards,
DM
2021-07-27 07:14 AM
Hello everybody,
I still have the problem....someone can help me?
2021-07-28 03:44 AM
Hi...an update....Finally I get the DMA isr but there is still a problem. After first transfer CPU enter in DMA Transfer Error Interrupt management.
Here is the sample code:
#define AUDIO_FREQUENCY AUDIO_FREQUENCY_96K //AUDIO_FREQUENCY_44K
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
if( MX_SAI1_ClockConfig(&hsai_BlockA1, AUDIO_FREQUENCY) != HAL_OK )
{
}
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SAI1_Init(AUDIO_FREQUENCY);
/* USER CODE BEGIN 2 */
/* Start the process receive DMA */
HAL_SAI_Receive_DMA(&hsai_BlockA1, RxBuffer, sizeof(RxBuffer));
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
static void MX_SAI1_Init(uint32_t SampleRate)
{
/* USER CODE BEGIN SAI1_Init 0 */
/* USER CODE END SAI1_Init 0 */
/* USER CODE BEGIN SAI1_Init 1 */
/* USER CODE END SAI1_Init 1 */
hsai_BlockA1.Instance = SAI1_Block_A;
hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL;
hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_RX;
hsai_BlockA1.Init.DataSize = SAI_DATASIZE_8;
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_EMPTY;
hsai_BlockA1.Init.AudioFrequency = SampleRate;//>>SAI_AUDIO_FREQUENCY_44K;
hsai_BlockA1.Init.MonoStereoMode = SAI_MONOMODE;
hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
hsai_BlockA1.Init.PdmInit.Activation = ENABLE;
hsai_BlockA1.Init.PdmInit.MicPairsNbr = 1;
hsai_BlockA1.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
hsai_BlockA1.FrameInit.FrameLength = 16;
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 = SAI_SLOTACTIVE_0;
hsai_BlockA1.SlotInit.SlotActive = 0x00000003;
if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SAI1_Init 2 */
/* USER CODE END SAI1_Init 2 */
}
#define AUDIO_IN_SAI_PDMx_DMAx_REQUEST DMA_REQUEST_SAI1_A
/* SAI DMA Stream Rx definitions */
#define AUDIO_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
#define AUDIO_SAIx_DMAx_CLK_DISABLE() __HAL_RCC_DMA1_CLK_DISABLE()
#define AUDIO_SAIx_DMAx_STREAM DMA1_Stream2
#define AUDIO_SAIx_PDMx_DMAx_REQUEST MDMA_REQUEST_DMA1_Stream2_TC //>> #define AUDIO_SAIx_DMAx_CHANNEL DMA1_CHANNEL_0
#define AUDIO_SAIx_DMAx_IRQ DMA1_Stream2_IRQn
#define AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
#define AUDIO_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
#define AUDIO_SAIx_DMAx_IRQHandler DMA1_Stream2_IRQHandler
/* Select the interrupt preemption priority and subpriority for the IT/DMA interrupt */
#define AUDIO_IN_IRQ_PREPRIO ((uint32_t)7) /* Select the preemption priority level(0 is the highest) */
void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/* SAI1 */
if(hsai->Instance==SAI1_Block_A)
{
/* Peripheral clock enable */
/** Initializes the peripherals clock */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_CLKP;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
if (SAI1_client == 0)
{
__HAL_RCC_SAI1_CLK_ENABLE();
}
SAI1_client ++;
/**SAI1_A_Block_A GPIO Configuration
PE2 ------> SAI1_CK1
PD6 ------> SAI1_D1
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_SAI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_SAI1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Enable the DMA clock */
AUDIO_SAIx_DMAx_CLK_ENABLE();
/* Configure the hdma_sai_rx handle parameters */
gSai1_hdma_Rx.Init.Request = AUDIO_IN_SAI_PDMx_DMAx_REQUEST; //gSai1_hdma_Rx.Init.Channel = AUDIO_SAIx_DMAx_CHANNEL;
gSai1_hdma_Rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
gSai1_hdma_Rx.Init.PeriphInc = DMA_PINC_DISABLE;
gSai1_hdma_Rx.Init.MemInc = DMA_MINC_ENABLE;
gSai1_hdma_Rx.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE;
gSai1_hdma_Rx.Init.MemDataAlignment = AUDIO_SAIx_DMAx_MEM_DATA_SIZE;
gSai1_hdma_Rx.Init.Mode = DMA_CIRCULAR;
gSai1_hdma_Rx.Init.Priority = DMA_PRIORITY_HIGH;
gSai1_hdma_Rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
gSai1_hdma_Rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
gSai1_hdma_Rx.Init.MemBurst = DMA_MBURST_SINGLE;
gSai1_hdma_Rx.Init.PeriphBurst = DMA_MBURST_SINGLE;
gSai1_hdma_Rx.Instance = AUDIO_SAIx_DMAx_STREAM;
/* Associate the DMA handle */
__HAL_LINKDMA(hsai, hdmarx, gSai1_hdma_Rx);
/* Deinitialize the Stream for new transfer */
HAL_DMA_DeInit(&gSai1_hdma_Rx);
/* Configure the DMA Stream */
HAL_DMA_Init(&gSai1_hdma_Rx);
/* I2S DMA IRQ Channel configuration */
HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ);
}
}
Any suggest about fix this issue. Thanks in advance.
DM
2021-09-09 05:59 AM
Hi all, at this moment finally I get data from DMA (Half Transfert and FullTranfert ISR)....now how can I proceed to convert the audio stream to PCM and then save if in a file (on usb stick)? Is there an example that can I get inspire to achive this final result?
Thanks to all how can help me.
Regards,
DM