0

I am trying to retrieve sound from MEMS microphones of my board, STM32F746G-Discovery. I am trying to use BSP Library. My board has wm8994 audio codec, and its schematic is here.

I wrote a code which appears below:

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stm32746g_discovery_audio.h"
#include "wm8994.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define AUDIO_BLOCK_SIZE   ((uint32_t)0xFFFE)
#define AUDIO_NB_BLOCKS    ((uint32_t)4)
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

I2C_HandleTypeDef hi2c3;

SAI_HandleTypeDef hsai_BlockA2;
SAI_HandleTypeDef hsai_BlockB2;
DMA_HandleTypeDef hdma_sai2_b;
DMA_HandleTypeDef hdma_sai2_a;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_SAI2_Init(void);
static void MX_I2C3_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
void BSP_AUDIO_IN_TransferComplete_CallBack(void);
void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t  audio_rec_buffer_state;
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */
    uint8_t res = 0;
    uint16_t  internal_buffer[AUDIO_BLOCK_SIZE];
    uint32_t bytesread = 0;
    /* USER CODE END 1 */

    /* Enable I-Cache---------------------------------------------------------*/
    SCB_EnableICache();

    /* Enable D-Cache---------------------------------------------------------*/
    SCB_EnableDCache();

    /* 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_DMA_Init();
    MX_SAI2_Init();
    MX_I2C3_Init();
    MX_USART1_UART_Init();
    /* USER CODE BEGIN 2 */
    audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    res = BSP_AUDIO_IN_Init(INPUT_DEVICE_DIGITAL_MICROPHONE_2, 35, AUDIO_FREQUENCY_44K);

    if(!res) {
        res = BSP_AUDIO_IN_Record(internal_buffer, AUDIO_BLOCK_SIZE);
        for (int block_number = 0; block_number < AUDIO_NB_BLOCKS; ++block_number) {
            while(audio_rec_buffer_state != BUFFER_OFFSET_HALF);
            audio_rec_buffer_state = BUFFER_OFFSET_NONE;
            while(audio_rec_buffer_state != BUFFER_OFFSET_FULL);
            audio_rec_buffer_state = BUFFER_OFFSET_NONE;
        }
        BSP_AUDIO_IN_Stop(CODEC_PDWN_SW);
        BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, 35, AUDIO_FREQUENCY_44K);
        BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
        res = BSP_AUDIO_OUT_Play(internal_buffer, AUDIO_BLOCK_SIZE);
        BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW);
    }
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

// Callback Functions
void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
  audio_rec_buffer_state = BUFFER_OFFSET_FULL;
  return;
}

void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
  audio_rec_buffer_state = BUFFER_OFFSET_HALF;
  return;
}

The problem here is that when I perform debugging, the program enters an IRQ function, and cannot exit from there. The function is below:

void DMA2_Stream7_IRQHandler(void)
{
  /* USER CODE BEGIN DMA2_Stream7_IRQn 0 */

  /* USER CODE END DMA2_Stream7_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_sai2_b);
  /* USER CODE BEGIN DMA2_Stream7_IRQn 1 */

  /* USER CODE END DMA2_Stream7_IRQn 1 */
}
    

What's the problem? I hope everything is clear. I am very new to stm32 so I am very sorry if I forget something. Thank you for your response in advance. Note: I actually wanted to add photos of configuration of SAI peripherals in CubeMX, but I needed to add a lot of links so stackoverflow though my question as spam. I therefore had to remove them.

11
  • Nowhere in your [posted] code do you initialize hdma_sai2_b. That is, during initlialization, I would expect something like (e.g.): init_dma_handle(&hdma_sai2_b,dma_channel_number); You call MX_SAI2_Init. But, from here: github.com/lvgl/lv_port_stm32f746_disco_atollic/blob/master/… it's a static function that does (e.g.): hsai_BlockA2.Instance = SAI2_Block_A; So, your version has to do a lot of that. So, the struct has bogus values or some other init is needed. I'd dump out the struct and ensure it's valid. You can breakpoint on the isr and single step ... Commented Jun 19, 2022 at 0:15
  • ... to see what it likes or doesn't like. That is, where inside HAL_DMA_IRQHandler is it spinning [forever]. There's an awful lot of STM provided/generated code that is a black box (i.e. you have to trust it does the right thing for your configuration). Commented Jun 19, 2022 at 0:20
  • @CraigEstey, I totally agree with you. I confused that the initialization of SAI components. However, when I debug, I saw that everything initialize clearly inside the BSP_AUDIO_IN_Init function. And I also performed debugging on the IRQHandler function, I expected the program to go into an error case, however, it made an assignment to halfXfercpltClbck(or sth like this) property of a variable which derived from a struct, SAI_HandleTypedef. Commented Jun 19, 2022 at 12:02
  • Additionally, what can I initialize with a function like init_dma_handle. I looked at the link you sent but I couldn't find the definition of the lv_init, tft_init, touchpad_init, functions. I wanted to look at it to get inspiration. Commented Jun 19, 2022 at 12:04
  • It can be one of the two things (and you can check which one specifically): either it hangs inside HAL_DMA_IRQHandler or it keeps calling this interrupt again and again and again. Put a breakpoint at the HAL_DMA_Handler and use debug. See if you keep arriving at that line multiple times or just one. (I suspect interrupt keeps firing indefinitely, but I need a confirmation). Commented Jun 20, 2022 at 12:59

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.