Skip to main content
Visitor II
August 26, 2020
Question

STM32WB and mic MP34DT05-A with PDM - error when reading data in mbed

  • August 26, 2020
  • 0 replies
  • 687 views

Hi all,

 

I try implement measuring sound level (SPL). I choose mic MP34DT05-A with PDM and connect to nucleo STM32WB55RG:

- data of mic connected to SAI_D1_PC3

- clock od mic connected to SAI1_CK1_PB8

- used the one mic so input of mic LR connected to GND (or VCC)

 

To generate code (setting of register) I used described example from section 4.3 of datasheet "Examples of configuration based on STM32CubeMX AN5027" and CubeMX. 

 

0693W000002lEOiQAM.jpg 

and DMA:

 

0693W000002lEPCQA2.jpg

Then I got two functions for the comprehensive PDM configuration:

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_16;
 hsai_BlockA1.Init.FirstBit = SAI_FIRSTBIT_LSB;
 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_DISABLE;
 hsai_BlockA1.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
 hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
 hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
 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_HIGH;
 hsai_BlockA1.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
 hsai_BlockA1.SlotInit.FirstBitOffset = 0;
 hsai_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
 hsai_BlockA1.SlotInit.SlotNumber = 1;
 hsai_BlockA1.SlotInit.SlotActive = 0x0000FFFF;
 if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN SAI1_Init 2 */
 tr_info("read status");
 tr_info("status sai '1' ready: %d", HAL_SAI_GetState(&hsai_BlockA1));
 /* USER CODE END SAI1_Init 2 */
}
 
static void MX_DMA_Init(void) 
{
 
 /* DMA controller clock enable */
 __HAL_RCC_DMAMUX1_CLK_ENABLE();
 __HAL_RCC_DMA1_CLK_ENABLE();
 
 /* DMA interrupt init */
 /* DMA1_Channel1_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 
}

So I put these funtions to simple mbed example code:

/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */
 
#include "mbed.h"
#include "ThisThread.h"
#include "mbed-trace/mbed_trace.h"
 
#define TRACE_GROUP "MAIN"
 
DigitalOut led1(LED1);
 
SAI_HandleTypeDef hsai_BlockA1;
 
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 tr_info("error");
 /* USER CODE END Error_Handler_Debug */
}
 
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_16;
 hsai_BlockA1.Init.FirstBit = SAI_FIRSTBIT_LSB;
 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_DISABLE;
 hsai_BlockA1.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
 hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
 hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
 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_HIGH;
 hsai_BlockA1.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
 hsai_BlockA1.SlotInit.FirstBitOffset = 0;
 hsai_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
 hsai_BlockA1.SlotInit.SlotNumber = 1;
 hsai_BlockA1.SlotInit.SlotActive = 0x0000FFFF;
 if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN SAI1_Init 2 */
 tr_info("read status");
 tr_info("status sai (if'1' => sai ready to use): %d", HAL_SAI_GetState(&hsai_BlockA1));
 /* USER CODE END SAI1_Init 2 */
}
 
static void MX_DMA_Init(void) 
{
 
 /* DMA controller clock enable */
 __HAL_RCC_DMAMUX1_CLK_ENABLE();
 __HAL_RCC_DMA1_CLK_ENABLE();
 
 /* DMA interrupt init */
 /* DMA1_Channel1_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 
}
 
int main()
{ 
 mbed_trace_init();
 mbed_trace_config_set(TRACE_ACTIVE_LEVEL_INFO);
 tr_info("START");
 
 MX_SAI1_Init();
 MX_DMA_Init();
 
 ThisThread::sleep_for(1000);
 
 uint16_t sound_len = 10;
 uint8_t sound_in[sound_len];
 
 while (true) {
 led1 = !led1;
 ThisThread::sleep_for(5000);
 uint8_t hal_status = HAL_SAI_Receive(&hsai_BlockA1, sound_in, 10, 1000);
 if (hal_status != HAL_OK)
 {
 tr_info("hal status (if '0' => OK): %d", hal_status);
 tr_info("status sai (if'1' => sai ready to use): %d,", HAL_SAI_GetState(&hsai_BlockA1));
 Error_Handler();
 } 
 else 
 {
 tr_info("hal status OK");
 tr_info("data: %s", mbed_trace_array(hsai_BlockA1.pBuffPtr, 10));
 tr_info("sound in %s", mbed_trace_array(sound_in, sound_len));
 } 
 }
}

To read mic data I used function:

HAL_SAI_Receive(&hsai_BlockA1, sound_in, 10, 1000);

 

but it recive error status HAL_ERROR

 

0693W000002lEPRQA2.jpg 

 

In mbed I don't change the clock setting so that may generate the error - I need connect clock to SAI periferia. Mbed doesn't give API to re-configure that - I don't want to do it on my own.

Or I made a configuration error.

 

someone can help me? I just need only read sound level not record or stream it anywhere.

 

    This topic has been closed for replies.