cancel
Showing results for 
Search instead for 
Did you mean: 

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

PawelM
Associate III

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.

 

0 REPLIES 0