diff --git a/components/cmd_i2c/CMakeLists.txt b/components/cmd_i2c/CMakeLists.txt new file mode 100644 index 00000000..12202eb7 --- /dev/null +++ b/components/cmd_i2c/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_SRCS "cmd_i2ctools.c") +set(COMPONENT_ADD_INCLUDEDIRS ".") + +register_component() diff --git a/components/cmd_i2c/cmd_i2ctools.c b/components/cmd_i2c/cmd_i2ctools.c new file mode 100644 index 00000000..60b6e607 --- /dev/null +++ b/components/cmd_i2c/cmd_i2ctools.c @@ -0,0 +1,410 @@ +/* cmd_i2ctools.c + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "cmd_i2ctools.h" +#include "argtable3/argtable3.h" +#include "driver/i2c.h" +#include "esp_console.h" +#include "esp_log.h" + +#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ +#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ +#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ +#define READ_BIT I2C_MASTER_READ /*!< I2C master read */ +#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ +#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ +#define ACK_VAL 0x0 /*!< I2C ack value */ +#define NACK_VAL 0x1 /*!< I2C nack value */ + +static const char *TAG = "cmd_i2ctools"; + +static gpio_num_t i2c_gpio_sda = 18; +static gpio_num_t i2c_gpio_scl = 19; +static uint32_t i2c_frequency = 100000; +static i2c_port_t i2c_port = I2C_NUM_0; + +static esp_err_t i2c_get_port(int port, i2c_port_t *i2c_port) +{ + if (port >= I2C_NUM_MAX) { + ESP_LOGE(TAG, "Wrong port number: %d", port); + return ESP_FAIL; + } + switch (port) { + case 0: + *i2c_port = I2C_NUM_0; + break; + case 1: + *i2c_port = I2C_NUM_1; + break; + default: + *i2c_port = I2C_NUM_0; + break; + } + return ESP_OK; +} + +static esp_err_t i2c_master_driver_initialize() +{ + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = i2c_gpio_sda, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_io_num = i2c_gpio_scl, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = i2c_frequency + }; + return i2c_param_config(i2c_port, &conf); +} + +static struct { + struct arg_int *port; + struct arg_int *freq; + struct arg_int *sda; + struct arg_int *scl; + struct arg_end *end; +} i2cconfig_args; + +static int do_i2cconfig_cmd(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&i2cconfig_args); + if (nerrors != 0) { + arg_print_errors(stderr, i2cconfig_args.end, argv[0]); + return 0; + } + + /* Check "--port" option */ + if (i2cconfig_args.port->count) { + if (i2c_get_port(i2cconfig_args.port->ival[0], &i2c_port) != ESP_OK) { + return 1; + } + } + /* Check "--freq" option */ + if (i2cconfig_args.freq->count) { + i2c_frequency = i2cconfig_args.freq->ival[0]; + } + /* Check "--sda" option */ + i2c_gpio_sda = i2cconfig_args.sda->ival[0]; + /* Check "--scl" option */ + i2c_gpio_scl = i2cconfig_args.scl->ival[0]; + return 0; +} + +static void register_i2cconfig(void) +{ + i2cconfig_args.port = arg_int0(NULL, "port", "<0|1>", "Set the I2C bus port number"); + i2cconfig_args.freq = arg_int0(NULL, "freq", "", "Set the frequency(Hz) of I2C bus"); + i2cconfig_args.sda = arg_int1(NULL, "sda", "", "Set the gpio for I2C SDA"); + i2cconfig_args.scl = arg_int1(NULL, "scl", "", "Set the gpio for I2C SCL"); + i2cconfig_args.end = arg_end(2); + const esp_console_cmd_t i2cconfig_cmd = { + .command = "i2cconfig", + .help = "Config I2C bus", + .hint = NULL, + .func = &do_i2cconfig_cmd, + .argtable = &i2cconfig_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&i2cconfig_cmd)); +} + +static int do_i2cdetect_cmd(int argc, char **argv) +{ + i2c_master_driver_initialize(); + i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); + uint8_t address; + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n"); + for (int i = 0; i < 128; i += 16) { + printf("%02x: ", i); + for (int j = 0; j < 16; j++) { + fflush(stdout); + address = i + j; + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (address << 1) | WRITE_BIT, ACK_CHECK_EN); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 50 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + if (ret == ESP_OK) { + printf("%02x ", address); + } else if (ret == ESP_ERR_TIMEOUT) { + printf("UU "); + } else { + printf("-- "); + } + } + printf("\r\n"); + } + + i2c_driver_delete(i2c_port); + return 0; +} + +static void register_i2cdectect(void) +{ + const esp_console_cmd_t i2cdetect_cmd = { + .command = "i2cdetect", + .help = "Scan I2C bus for devices", + .hint = NULL, + .func = &do_i2cdetect_cmd, + .argtable = NULL + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&i2cdetect_cmd)); +} + +static struct { + struct arg_int *chip_address; + struct arg_int *register_address; + struct arg_int *data_length; + struct arg_end *end; +} i2cget_args; + +static int do_i2cget_cmd(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&i2cget_args); + if (nerrors != 0) { + arg_print_errors(stderr, i2cget_args.end, argv[0]); + return 0; + } + + /* Check chip address: "-c" option */ + int chip_addr = i2cget_args.chip_address->ival[0]; + /* Check register address: "-r" option */ + int data_addr = -1; + if (i2cget_args.register_address->count) { + data_addr = i2cget_args.register_address->ival[0]; + } + /* Check data length: "-l" option */ + int len = 1; + if (i2cget_args.data_length->count) { + len = i2cget_args.data_length->ival[0]; + } + uint8_t *data = malloc(len); + + i2c_master_driver_initialize(); + i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + if (data_addr != -1) { + i2c_master_write_byte(cmd, chip_addr << 1 | WRITE_BIT, ACK_CHECK_EN); + i2c_master_write_byte(cmd, data_addr, ACK_CHECK_EN); + i2c_master_start(cmd); + } + i2c_master_write_byte(cmd, chip_addr << 1 | READ_BIT, ACK_CHECK_EN); + if (len > 1) { + i2c_master_read(cmd, data, len - 1, ACK_VAL); + } + i2c_master_read_byte(cmd, data + len - 1, NACK_VAL); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 1000 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + if (ret == ESP_OK) { + for (int i = 0; i < len; i++) { + printf("0x%02x ", data[i]); + if ((i + 1) % 16 == 0) { + printf("\r\n"); + } + } + if (len % 16) { + printf("\r\n"); + } + } else if (ret == ESP_ERR_TIMEOUT) { + ESP_LOGW(TAG, "Bus is busy"); + } else { + ESP_LOGW(TAG, "Read failed"); + } + free(data); + i2c_driver_delete(i2c_port); + return 0; +} + +static void register_i2cget(void) +{ + i2cget_args.chip_address = arg_int1("c", "chip", "", "Specify the address of the chip on that bus"); + i2cget_args.register_address = arg_int0("r", "register", "", "Specify the address on that chip to read from"); + i2cget_args.data_length = arg_int0("l", "length", "", "Specify the length to read from that data address"); + i2cget_args.end = arg_end(1); + const esp_console_cmd_t i2cget_cmd = { + .command = "i2cget", + .help = "Read registers visible through the I2C bus", + .hint = NULL, + .func = &do_i2cget_cmd, + .argtable = &i2cget_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&i2cget_cmd)); +} + +static struct { + struct arg_int *chip_address; + struct arg_int *register_address; + struct arg_int *data; + struct arg_end *end; +} i2cset_args; + +static int do_i2cset_cmd(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&i2cset_args); + if (nerrors != 0) { + arg_print_errors(stderr, i2cset_args.end, argv[0]); + return 0; + } + + /* Check chip address: "-c" option */ + int chip_addr = i2cset_args.chip_address->ival[0]; + /* Check register address: "-r" option */ + int data_addr = 0; + if (i2cset_args.register_address->count) { + data_addr = i2cset_args.register_address->ival[0]; + } + /* Check data: "-d" option */ + int len = i2cset_args.data->count; + + i2c_master_driver_initialize(); + i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, chip_addr << 1 | WRITE_BIT, ACK_CHECK_EN); + if (i2cset_args.register_address->count) { + i2c_master_write_byte(cmd, data_addr, ACK_CHECK_EN); + } + for (int i = 0; i < len; i++) { + i2c_master_write_byte(cmd, i2cset_args.data->ival[i], ACK_CHECK_EN); + } + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 1000 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + if (ret == ESP_OK) { + ESP_LOGI(TAG, "Write OK"); + } else if (ret == ESP_ERR_TIMEOUT) { + ESP_LOGW(TAG, "Bus is busy"); + } else { + ESP_LOGW(TAG, "Write Failed"); + } + i2c_driver_delete(i2c_port); + return 0; +} + +static void register_i2cset(void) +{ + i2cset_args.chip_address = arg_int1("c", "chip", "", "Specify the address of the chip on that bus"); + i2cset_args.register_address = arg_int0("r", "register", "", "Specify the address on that chip to read from"); + i2cset_args.data = arg_intn(NULL, NULL, "", 0, 256, "Specify the data to write to that data address"); + i2cset_args.end = arg_end(2); + const esp_console_cmd_t i2cset_cmd = { + .command = "i2cset", + .help = "Set registers visible through the I2C bus", + .hint = NULL, + .func = &do_i2cset_cmd, + .argtable = &i2cset_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&i2cset_cmd)); +} + +static struct { + struct arg_int *chip_address; + struct arg_int *size; + struct arg_end *end; +} i2cdump_args; + +static int do_i2cdump_cmd(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&i2cdump_args); + if (nerrors != 0) { + arg_print_errors(stderr, i2cdump_args.end, argv[0]); + return 0; + } + + /* Check chip address: "-c" option */ + int chip_addr = i2cdump_args.chip_address->ival[0]; + /* Check read size: "-s" option */ + int size = 1; + if (i2cdump_args.size->count) { + size = i2cdump_args.size->ival[0]; + } + if (size != 1 && size != 2 && size != 4) { + ESP_LOGE(TAG, "Wrong read size. Only support 1,2,4"); + return 1; + } + i2c_master_driver_initialize(); + i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); + uint8_t data_addr; + uint8_t data[4]; + int32_t block[16]; + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" + " 0123456789abcdef\r\n"); + for (int i = 0; i < 128; i += 16) { + printf("%02x: ", i); + for (int j = 0; j < 16; j += size) { + fflush(stdout); + data_addr = i + j; + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, chip_addr << 1 | WRITE_BIT, ACK_CHECK_EN); + i2c_master_write_byte(cmd, data_addr, ACK_CHECK_EN); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, chip_addr << 1 | READ_BIT, ACK_CHECK_EN); + if (size > 1) { + i2c_master_read(cmd, data, size - 1, ACK_VAL); + } + i2c_master_read_byte(cmd, data + size - 1, NACK_VAL); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 50 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + if (ret == ESP_OK) { + for (int k = 0; k < size; k++) { + printf("%02x ", data[k]); + block[j + k] = data[k]; + } + } else { + for (int k = 0; k < size; k++) { + printf("XX "); + block[j + k] = -1; + } + } + } + printf(" "); + for (int k = 0; k < 16; k++) { + if (block[k] < 0) { + printf("X"); + } + if ((block[k] & 0xff) == 0x00 || (block[k] & 0xff) == 0xff) { + printf("."); + } else if ((block[k] & 0xff) < 32 || (block[k] & 0xff) >= 127) { + printf("?"); + } else { + printf("%c", block[k] & 0xff); + } + } + printf("\r\n"); + } + i2c_driver_delete(i2c_port); + return 0; +} + +static void register_i2cdump(void) +{ + i2cdump_args.chip_address = arg_int1("c", "chip", "", "Specify the address of the chip on that bus"); + i2cdump_args.size = arg_int0("s", "size", "", "Specify the size of each read"); + i2cdump_args.end = arg_end(1); + const esp_console_cmd_t i2cdump_cmd = { + .command = "i2cdump", + .help = "Examine registers visible through the I2C bus", + .hint = NULL, + .func = &do_i2cdump_cmd, + .argtable = &i2cdump_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&i2cdump_cmd)); +} + +void register_i2ctools(void) +{ + register_i2cconfig(); + register_i2cdectect(); + register_i2cget(); + register_i2cset(); + register_i2cdump(); +} diff --git a/components/cmd_i2c/cmd_i2ctools.h b/components/cmd_i2c/cmd_i2ctools.h new file mode 100644 index 00000000..2bd39532 --- /dev/null +++ b/components/cmd_i2c/cmd_i2ctools.h @@ -0,0 +1,20 @@ +/* cmd_i2ctools.h + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +void register_i2ctools(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/cmd_i2c/component.mk b/components/cmd_i2c/component.mk new file mode 100644 index 00000000..59d5335c --- /dev/null +++ b/components/cmd_i2c/component.mk @@ -0,0 +1,4 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# +COMPONENT_ADD_INCLUDEDIRS := . \ No newline at end of file diff --git a/components/driver_i2s/CMakeLists.txt b/components/driver_i2s/CMakeLists.txt new file mode 100644 index 00000000..78bef683 --- /dev/null +++ b/components/driver_i2s/CMakeLists.txt @@ -0,0 +1,7 @@ +set(COMPONENT_ADD_INCLUDEDIRS .) + +set(COMPONENT_SRCS "tas5756m.c") + +set(COMPONENT_REQUIRES console spi_flash) + +register_component() diff --git a/components/driver_i2s/component.mk b/components/driver_i2s/component.mk new file mode 100644 index 00000000..31c65100 --- /dev/null +++ b/components/driver_i2s/component.mk @@ -0,0 +1,12 @@ +# +# Component Makefile +# +# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, +# this will take the sources in the src/ directory, compile them and link them into +# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, +# please read the SDK documents if you need to do this. +# + +COMPONENT_ADD_INCLUDEDIRS := . +CFLAGS += -Os -DPOSIX -DLINKALL -DLOOPBACK -DNO_FAAD -DEMBEDDED -DTREMOR_ONLY -DBYTES_PER_FRAME=4 +CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG diff --git a/components/driver_i2s/tas5756m.c b/components/driver_i2s/tas5756m.c new file mode 100644 index 00000000..e69de29b diff --git a/components/platform_esp32/cmd_decl.h b/components/platform_esp32/cmd_decl.h index 983b6e97..dc88939e 100644 --- a/components/platform_esp32/cmd_decl.h +++ b/components/platform_esp32/cmd_decl.h @@ -15,6 +15,7 @@ extern "C" { #include "cmd_system.h" #include "cmd_wifi.h" #include "cmd_nvs.h" +#include "cmd_i2ctools.h" #ifdef __cplusplus } diff --git a/components/platform_esp32/console.c b/components/platform_esp32/console.c index 1f9e52cf..0bacaa7e 100644 --- a/components/platform_esp32/console.c +++ b/components/platform_esp32/console.c @@ -31,7 +31,7 @@ pthread_t thread_console; static void * console_thread(); void console_start(); static const char * TAG = "console"; -extern char current_namespace[]; + /* Prompt to be printed before each line. * This can be customized, made dynamic, etc. */ @@ -238,6 +238,7 @@ void console_start() { register_wifi(); register_nvs(); register_squeezelite(); + register_i2ctools(); printf("\n" "Type 'help' to get the list of commands.\n" "Use UP/DOWN arrows to navigate through command history.\n" diff --git a/components/platform_esp32/perf_trace.h b/components/platform_esp32/perf_trace.h index 357e10be..5ded9c9d 100644 --- a/components/platform_esp32/perf_trace.h +++ b/components/platform_esp32/perf_trace.h @@ -16,7 +16,7 @@ #define SET_MIN_MAX_SIZED(val,var,siz) var=val; if(varmax_##var) max_##var=var; count_##var++; avgtot_##var+= var;size_##var=siz #define RESET_MIN_MAX(var) min_##var=PERF_MAX; max_##var=0; avgtot_##var=0;count_##var=0;var=0;size_##var=0 #define RESET_MIN_MAX_DURATION(var) min_##var=PERF_MAX; max_##var=0; avgtot_##var=0;count_##var=0;var=0 -#define DECLARE_MIN_MAX(var) static uint32_t min_##var = PERF_MAX, max_##var = 0, size_##var = 0, count_##var=0;uint64_t avgtot_##var = 0; uint32_t var=0 +#define DECLARE_MIN_MAX(var) static uint32_t min_##var = PERF_MAX, max_##var = 0, size_##var = 0, count_##var=0;static uint64_t avgtot_##var = 0; static uint32_t var=0 #define DECLARE_MIN_MAX_DURATION(var) static uint32_t min_##var = PERF_MAX, max_##var = 0, count_##var=0; uint64_t avgtot_##var = 0; uint32_t var=0 #define LINE_MIN_MAX_AVG(var) (uint32_t)(count_##var>0?avgtot_##var/count_##var:0) diff --git a/main/output_dac.c b/main/output_dac.c index f7499d3e..6b64c205 100644 --- a/main/output_dac.c +++ b/main/output_dac.c @@ -2,6 +2,7 @@ #include "driver/i2s.h" #include "perf_trace.h" #include +#include "time.h" #define DECLARE_ALL_MIN_MAX \ @@ -71,11 +72,13 @@ static i2s_config_t i2s_config; static int out_bytes_per_frame; static thread_type thread; +static thread_type stats_thread; +DECLARE_ALL_MIN_MAX; static int _dac_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr); static void *output_thread_dac(); -extern void wait_for_frames(size_t frames, uint8_t pct); +static void *output_thread_dac_stats(); /**************************************************************************************** * set output volume @@ -180,8 +183,24 @@ PTHREAD_SET_NAME("output_dac"); pthread_attr_destroy(&attr); #endif #if WIN - thread = CreateThread(NULL, OUTPUT_THREAD_STACK_SIZE, (LPTHREAD_START_ROUTINE)&output_thread, NULL, 0, NULL); + thread = CreateThread(NULL, OUTPUT_THREAD_STACK_SIZE, (LPTHREAD_START_ROUTINE)&output_thread_dac, NULL, 0, NULL); #endif + + +PTHREAD_SET_NAME("output_dac_sts"); + +#if LINUX || OSX || FREEBSD || POSIX + pthread_attr_init(&attr); +#ifdef PTHREAD_STACK_MIN + pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN+OUTPUT_THREAD_STACK_SIZE ); +#endif + pthread_create(&stats_thread, &attr, output_thread_dac_stats, NULL); + pthread_attr_destroy(&attr); +#endif +#if WIN + thread = CreateThread(NULL, OUTPUT_THREAD_STACK_SIZE, (LPTHREAD_START_ROUTINE)&output_thread_dac_stats, NULL, 0, NULL); +#endif + LOG_INFO("Init completed."); } @@ -252,6 +271,41 @@ static int _dac_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32 return (int)BYTES_TO_FRAME(actual_out_bytes); } +static void *output_thread_dac_stats() { + while (running) { + LOCK; + output_state state = output.state; + UNLOCK; + if(state>OUTPUT_STOPPED){ + LOG_INFO( "Output State: %d, current sample rate: %d, bytes per frame: %d",state,output.current_sample_rate, out_bytes_per_frame); + LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1); + LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2); + LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD3); + LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD4); + LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s)); + LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o)); + LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("dac buf used",loci2sbuf)); + LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER); + LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("i2swrite",i2savailable)); + LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req)); + LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec)); + LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("overflow",over)); + LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER); + LOG_INFO(""); + LOG_INFO(" ----------+----------+-----------+-----------+ "); + LOG_INFO(" max (us) | min (us) | avg(us) | count | "); + LOG_INFO(" ----------+----------+-----------+-----------+ "); + LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering)); + LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("i2s tfr(us)",i2s_time)); + LOG_INFO(" ----------+----------+-----------+-----------+"); + RESET_ALL_MIN_MAX; + } + usleep(STATS_PERIOD_MS *1000); + } + return NULL; +} + + @@ -268,8 +322,6 @@ static void *output_thread_dac() { static int count = 0; output_state state; - DECLARE_ALL_MIN_MAX; - while (running) { i2s_bytes_written=0; frames=0; @@ -356,46 +408,6 @@ static void *output_thread_dac() { } - - /* - * Statistics reporting - */ - count++; - TIMED_SECTION_START_MS(STATS_PERIOD_MS); - if(state>OUTPUT_STOPPED){ - - LOG_INFO( "count:%d, Output State: %d, current sample rate: %d, bytes per frame: %d, avg cycle duration (ms): %d",count,state,output.current_sample_rate, out_bytes_per_frame,STATS_PERIOD_MS/count); - LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1); - LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2); - LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD3); - LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD4); - LOG_INFO(LINE_MIN_MAX_FORMAT_STREAM, LINE_MIN_MAX_STREAM("stream",s)); - LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("output",o)); - LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("dac buf used",loci2sbuf)); - LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER); - LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("i2swrite",i2savailable)); - LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("requested",req)); - LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("received",rec)); - LOG_INFO(LINE_MIN_MAX_FORMAT,LINE_MIN_MAX("overflow",over)); - LOG_INFO(LINE_MIN_MAX_FORMAT_FOOTER); - LOG_INFO(""); - LOG_INFO(" ----------+----------+-----------+-----------+ "); - LOG_INFO(" max (us) | min (us) | avg(us) | count | "); - LOG_INFO(" ----------+----------+-----------+-----------+ "); - LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("Buffering(us)",buffering)); - LOG_INFO(LINE_MIN_MAX_DURATION_FORMAT,LINE_MIN_MAX_DURATION("i2s tfr(us)",i2s_time)); - LOG_INFO(" ----------+----------+-----------+-----------+"); - RESET_ALL_MIN_MAX; - } - else { - LOG_INFO( "count:%d, Output State: %d",count,state); - } - count=0; - TIMED_SECTION_END; - /* - * End Statistics reporting - */ - } return 0; } diff --git a/main/utils.c b/main/utils.c index ec495545..764feb1b 100644 --- a/main/utils.c +++ b/main/utils.c @@ -613,14 +613,7 @@ uint8_t get_bytes_per_frame(output_format fmt) assert(bpf>0); return bpf; } -/**************************************************************************************** - * Wait for a duration based on a frame count - */ -extern struct outputstate output; -void wait_for_frames(size_t frames, uint8_t pct) -{ - usleep((1000* frames/output.current_sample_rate*pct/100) ); -} + char * get_output_state_desc(output_state state){ switch (state) { case OUTPUT_OFF: diff --git a/sdkconfig b/sdkconfig index c9647151..5b4f7b75 100644 --- a/sdkconfig +++ b/sdkconfig @@ -91,6 +91,7 @@ CONFIG_EXAMPLE_OPEN=y # CONFIG_EXAMPLE_WPA2 is not set CONFIG_INCLUDE_FLAC=y CONFIG_INCLUDE_FAAD=y +# CONFIG_INCLUDE_MAD is not set CONFIG_INCLUDE_VORBIS=y CONFIG_INCLUDE_ALAC=y # CONFIG_DACAUDIO is not set