Decodificación de mp3 con Helix lib en Stm32f411

0

Estoy enviando cuadros autocontenidos de mp3 desde la PC a mi STM32f411 (placa Discovery) a través de FTDI, en el microcontrolador descodifico la trama y envío datos pcm descodificados a un códec DAC externo (en una placa) a través de I2S. Estoy usando DMA tanto para UART como para I2S. Los datos pcm decodificados tienen una longitud variable y es por eso que no puedo usar DMA con doble búfer, al menos de manera sencilla.

Aquí está mi devolución de llamada I2S:

void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s){
  int err_code = 0;
  if(i2s_flag) {
    HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t *)pcm1, len_pcm1);
    HAL_UART_Transmit(&huart2, _ok, 2, 10);
    HAL_UART_Receive(&huart2, (uint8_t *)&len_frame1, 2, 10);
    if(HAL_UART_Receive_DMA(&huart2, uart_buffer1, len_frame1) != HAL_OK){
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
    }
    buffer2_addr = uart_buffer2;
    err_code = decode_frame(&buffer2_addr, &len_frame2, pcm2, &len_pcm2);
  } else {
    HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t *)pcm1, len_pcm1);
    HAL_UART_Transmit(&huart2, _ok, 2, 10);
    HAL_UART_Receive(&huart2, (uint8_t *)&len_frame2, 2, 10);    
    if(HAL_UART_Receive_DMA(&huart2, uart_buffer2, len_frame2) != HAL_OK) {
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
    }
    buffer1_addr = uart_buffer1;
    err_code = decode_frame(&buffer1_addr, &len_frame1, pcm1, &len_pcm1);
  }
  i2s_flag = !i2s_flag;
  if(err_code) {
    err_code *= -1;
    HAL_UART_Transmit(&huart2, &err_code, 2, 10);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
  } else {
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
  }
}

En el lado de la PC, estoy usando el script de Python para crear cuadros de mp3 y recopilar códigos de error.

Puedo escuchar música, es bastante distinguible, el problema de los artefactos de sonido, algunos crujidos, que ocurren principalmente en los ritmos musicales. Al mismo tiempo, recibo un error de Helix lib (ERR_MP3_INVALID_FRAMEHEADER = -6) ~ 5 veces por segundo. He intentado decodificar cuadros de mp3 en bucle principal sin DMA e interrupciones y envié datos de pcm a la PC, los reuní en wav y obtuve un resultado excelente (sin ningún error de Helix). No puedo entender por qué exactamente en la interrupción me devuelve un error. Además, he comprobado si ocurre un problema en UART y definitivamente puedo decir que estoy obteniendo datos confiables y que la demora no afecta los tiempos I2S. Ya pasé decenas de horas depurando ese problema, pero todo fue en vano.

Stackexchange eres mi última esperanza!

ACTUALIZACIÓN 11.08.2018:

Usando la función HardFault_Handler, he leído registros cuando el microcontrolador se apaga (sucede al azar, puede ser que sea la consecuencia del problema real) y el registro BFAR me devuelve una dirección 0x20020000 y de acuerdo con mi script de vinculador (.ld) es la final de la memoria RAM. Así que, en la actualidad, asumo que es un desbordamiento de pila, un flujo de flujo de pila o ambos. ¡Cualquier consejo o sugerencia será muy apreciado!

SOLVED!

Ok, lo resolví! El problema estaba aquí (intenta encontrar el error):

uint16_t len_frame1 = 0, len_frame2 = 0;

¿Lo encontraste? Si es así entonces genial! Déjame saber dónde está el error f !

Rastreé el error y descubrí que len_frame1 no quería cambiar su estado desde cero, parece que fue declarado constante, pero en realidad, como se puede ver arriba, no lo hizo, al mismo tiempo que con len_frame2 todo fue De acuerdo. ¡Cualquier explicación o suposición sobre lo que realmente sucedió en mi código será muy apreciada!

P.S. Incluso después de que se resolvió el problema, conseguí esos crujidos en el borde de dos marcos de pcm. El sonido era mucho mejor, pero aún no estaba limpio. Supongo que eso sucede porque STM no proporciona SCLK cuando no hay nada que transmitir y es por eso que el sonido interrumpe y eso produce esos artefactos de sonido. Desafortunadamente no tengo un analizador digital para apoyar mi teoría. Finalmente, hice DMA circular con pcm-swap-reservoir donde los datos de pcm van después de la decodificación y eso solía llenar el búfer de DMA en las interrupciones "semi-completas" y "completas".

¡Espero que este mini-artículo sea útil para alguien! : D

    
pregunta Anton Rak

0 respuestas

Lea otras preguntas en las etiquetas