En esta aplicación se mostrará cómo leer un archivo .wav de una memoria MicroSD para que Avanxe 7 funcione como un reproductor de audio.
Para facilitar la lectura de datos de la MicroSD se utiliza el ESP32 integrado en Avanxe 7, se encargará de inicializar y configurar la memoria así como generar la interfaz SPI.
IMPORTANTE: Leer la documentación oficial de ESPRESSIF y seguir los pasos para poder programar el ESP32 en Eclipse.
IR A LA PÁGINA OFICIAL DE ESPRESSIF
Se utiliza el protocolo RS232 para la transferencia de datos que lee el ESP32 de la memoria microSD, el protocolo cuenta con las siguientes características:
- 3 Megabaudios
- 1 bit de inicio
- 8 bits de datos
- 1 bit de paro
- Sin paridad
Para la microSD se utiliza el protocolo serial SPI, el código en C se encarga de obtener los parámetros que requiere la memoria y configura al ESP32 de manera automática. La conexión es la siguiente
El proyecto se divide en 2 partes:
- Código en VHDL que se encarga del control del DAC y adquisición de datos.
- Código en Eclipse para el ESP32 utilizando el framework oficial de Espressif ESP-IDF.
Código en VHDL
El código sigue la siguiente estructura:
Funciona como un puente entre el ESP32 y el DAC, utiliza un buffer de doble puerto en donde se almacenan temporalmente los datos del archivo WAV. También sincroniza los tiempos de muestreo que indica el formato de audio. Como el periodo de muestreo es mucho menor que el tiempo de adquisición de datos, el buffer se puede llenar de datos y esperar a que el DAC termine de leer todos los datos.
Código en Eclipse.
El framework ESP-IDF ofrece librerías y ejemplos sobre cómo leer o escribir en la microSD. Se utilizó el código de ejemplo creado por Espressif y se le añadió la comunicación UART para transferir los datos al FPGA.
IMPORTANTE: El archivo de audio debe ser formato WAV a un canal, frecuencia de muestro de 22050 y con una resolución de 8 bits para que el sistema funcione correctamente.
El código en C inicializa la memoria SD y después obtiene toda la información del archivo WAV que se puede observar en la terminal de Ecplise.
//Capturan los datos char data[4]; char data2[2]; long int val; //ChunkID //fgets(data, sizeof(data), f2); fread(data,sizeof(data),1,f2); ESP_LOGI(TAG, "ChunkID: '%s'",data); //ChunkSize //fgets(data, sizeof(data), f2); fread(data,sizeof(data),1,f2); val = ((data[3])<<24)+ ((data[2])<<16)+ ((data[1])<<8) + (data[0]); ESP_LOGI(TAG, "Chunk Size: '%li'",val); //Format fread(data,sizeof(data),1,f2); ESP_LOGI(TAG, "Format: '%s'",data); //Subchunk1ID fread(data,sizeof(data),1,f2); ESP_LOGI(TAG, "Subchunk1ID: '%s'",data); //Subchunk1Size fread(data,sizeof(data),1,f2); val = ((data[3])<<24)+ ((data[2])<<16)+ ((data[1])<<8) + (data[0]); ESP_LOGI(TAG, "Subchunk1Size Size: '%li'",val); //Audioformat fread(data2,sizeof(data2),1,f2); val = ((data2[1])<<8) + (data2[0]); ESP_LOGI(TAG, "Audioformat: '%li'",val); //NumChannels fread(data2,sizeof(data2),1,f2); val = ((data2[1])<<8) + (data2[0]); ESP_LOGI(TAG, "NumChannels: '%li'",val); //SampleRate fread(data,sizeof(data),1,f2); val = ((data[3])<<24)+ ((data[2])<<16)+ ((data[1])<<8) + (data[0]); ESP_LOGI(TAG, "SampleRate: '%li'",val); //ByteRate fread(data,sizeof(data),1,f2); val = ((data[3])<<24)+ ((data[2])<<16)+ ((data[1])<<8) + (data[0]); ESP_LOGI(TAG, "ByteRate: '%li'",val); //BlockAlign fread(data2,sizeof(data2),1,f2); val = ((data2[1])<<8) + (data2[0]); ESP_LOGI(TAG, "BlockAlign: '%li'",val); //BitsPerSample fread(data2,sizeof(data2),1,f2); val = ((data2[1])<<8) + (data2[0]); ESP_LOGI(TAG, "BitsPerSample: '%li'",val); //Subchunk2ID fread(data,sizeof(data),1,f2); ESP_LOGI(TAG, "Subchunk2ID: '%s'",data); //Subchunk2Size fread(data,sizeof(data),1,f2); val = ((data[3])<<24)+ ((data[2])<<16)+ ((data[1])<<8) + (data[0]); ESP_LOGI(TAG, "Subchunk2Size: '%li'",val);