mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
170 lines
4.7 KiB
C
170 lines
4.7 KiB
C
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
/*
|
|
Tests for the dac device driver on ESP32 only
|
|
Hardware connection:
|
|
- ESP32: GPIO25 <---> GPIO26
|
|
*/
|
|
#include "sdkconfig.h"
|
|
#if CONFIG_IDF_TARGET_ESP32
|
|
|
|
#include "esp_system.h"
|
|
#include "driver/adc.h"
|
|
#include "unity.h"
|
|
#include "esp_system.h"
|
|
#include "esp_event.h"
|
|
#include "esp_wifi.h"
|
|
#include "esp_log.h"
|
|
#include "nvs_flash.h"
|
|
#include "test_utils.h"
|
|
#include "test_dac_audio_file.h"
|
|
#include "driver/i2s.h"
|
|
#include "driver/dac.h"
|
|
|
|
/*
|
|
* DAC DMA config.
|
|
*/
|
|
|
|
//enable record sound and save in flash
|
|
#define RECORD_IN_FLASH_EN (1)
|
|
//enable replay recorded sound in flash
|
|
#define REPLAY_FROM_FLASH_EN (1)
|
|
|
|
//i2s number
|
|
#define EXAMPLE_I2S_NUM (0)
|
|
//i2s sample rate
|
|
#define EXAMPLE_I2S_SAMPLE_RATE (16000)
|
|
//i2s data bits
|
|
#define EXAMPLE_I2S_SAMPLE_BITS (16)
|
|
//enable display buffer for debug
|
|
#define EXAMPLE_I2S_BUF_DEBUG (0)
|
|
//I2S read buffer length
|
|
#define EXAMPLE_I2S_READ_LEN (16 * 1024)
|
|
//I2S data format
|
|
#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT)
|
|
//I2S channel number
|
|
#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1))
|
|
|
|
/**
|
|
* @brief I2S ADC/DAC mode init.
|
|
*/
|
|
static void example_i2s_init(void)
|
|
{
|
|
int i2s_num = EXAMPLE_I2S_NUM;
|
|
i2s_config_t i2s_config = {
|
|
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN,
|
|
.sample_rate = EXAMPLE_I2S_SAMPLE_RATE,
|
|
.bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
|
|
.channel_format = EXAMPLE_I2S_FORMAT,
|
|
.intr_alloc_flags = 0,
|
|
.dma_buf_count = 2,
|
|
.dma_buf_len = 1024,
|
|
.use_apll = 0,
|
|
};
|
|
//install and start i2s driver
|
|
TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) );
|
|
//init DAC pad
|
|
TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN) );
|
|
}
|
|
|
|
static void example_i2s_deinit(void)
|
|
{
|
|
TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_DISABLE) );
|
|
TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) );
|
|
}
|
|
|
|
/**
|
|
* @brief Set i2s clock for example audio file
|
|
*/
|
|
static void example_set_file_play_mode(void)
|
|
{
|
|
TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, 16000, EXAMPLE_I2S_SAMPLE_BITS, 1) );
|
|
}
|
|
|
|
/**
|
|
* @brief Scale data to 16bit/32bit for I2S DMA output.
|
|
* DAC can only output 8bit data value.
|
|
* I2S DMA will still send 16 bit or 32bit data, the highest 8bit contains DAC data.
|
|
*/
|
|
static int example_i2s_dac_data_scale(uint8_t *d_buff, uint8_t *s_buff, uint32_t len)
|
|
{
|
|
uint32_t j = 0;
|
|
#if (EXAMPLE_I2S_SAMPLE_BITS == 16)
|
|
for (int i = 0; i < len; i++) {
|
|
d_buff[j++] = 0;
|
|
d_buff[j++] = s_buff[i];
|
|
}
|
|
return (len * 2);
|
|
#else
|
|
for (int i = 0; i < len; i++) {
|
|
d_buff[j++] = 0;
|
|
d_buff[j++] = 0;
|
|
d_buff[j++] = 0;
|
|
d_buff[j++] = s_buff[i];
|
|
}
|
|
return (len * 4);
|
|
#endif
|
|
}
|
|
/**
|
|
* @brief debug buffer data
|
|
*/
|
|
static void example_disp_buf(uint8_t *buf, int length)
|
|
{
|
|
printf("======\n");
|
|
for (int i = 0; i < length; i++) {
|
|
printf("%02x ", buf[i]);
|
|
if ((i + 1) % 8 == 0) {
|
|
printf("\n");
|
|
}
|
|
}
|
|
printf("======\n");
|
|
}
|
|
|
|
/**
|
|
* @brief Reset i2s clock and mode
|
|
*/
|
|
static void example_reset_play_mode(void)
|
|
{
|
|
TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, EXAMPLE_I2S_SAMPLE_RATE, EXAMPLE_I2S_SAMPLE_BITS, EXAMPLE_I2S_CHANNEL_NUM) );
|
|
}
|
|
|
|
TEST_CASE("DAC DMA output", "[dac]")
|
|
{
|
|
size_t bytes_written;
|
|
int i2s_read_len = EXAMPLE_I2S_READ_LEN;
|
|
uint8_t *i2s_write_buff = (uint8_t *) calloc(i2s_read_len, sizeof(char));
|
|
int offset = 0;
|
|
int tot_size = sizeof(audio_table);
|
|
printf("Playing file example: \n");
|
|
|
|
example_i2s_init();
|
|
example_set_file_play_mode();
|
|
|
|
while (offset < tot_size) {
|
|
int play_len = ((tot_size - offset) > (4 * 1024)) ? (4 * 1024) : (tot_size - offset);
|
|
int i2s_wr_len = example_i2s_dac_data_scale(i2s_write_buff, (uint8_t *)(audio_table + offset), play_len);
|
|
i2s_write(EXAMPLE_I2S_NUM, i2s_write_buff, i2s_wr_len, &bytes_written, portMAX_DELAY);
|
|
offset += play_len;
|
|
example_disp_buf((uint8_t *) i2s_write_buff, 32);
|
|
}
|
|
|
|
example_reset_play_mode();
|
|
free(i2s_write_buff);
|
|
|
|
example_i2s_deinit();
|
|
}
|
|
|
|
#endif // CONFIG_IDF_TARGET_ESP32
|