add GPIO to drive external amplifier

This commit is contained in:
philippe44
2020-02-03 17:25:42 -08:00
parent ee1d54a1ba
commit cb565da0eb
2 changed files with 48 additions and 19 deletions

View File

@@ -77,6 +77,7 @@ sure that using rate_delay would fix that
RESET_MIN_MAX(buffering);
#define STATS_PERIOD_MS 5000
#define STAT_STACK_SIZE (3*1024)
extern struct outputstate output;
extern struct buffer *streambuf;
@@ -92,18 +93,21 @@ static bool jack_mutes_amp;
static bool running, isI2SStarted;
static i2s_config_t i2s_config;
static int bytes_per_frame;
static thread_type thread, stats_thread;
static u8_t *obuf;
static frames_t oframes;
static bool spdif;
static size_t dma_buf_frames;
static pthread_t thread;
static TaskHandle_t stats_task;
static bool stats;
static int amp_gpio = -1;
DECLARE_ALL_MIN_MAX;
static int _i2s_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_i2s();
static void *output_thread_i2s_stats();
static void *output_thread_i2s(void *arg);
static void *output_thread_i2s_stats(void *arg);
static void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst, size_t *count);
static void (*jack_handler_chain)(bool inserted);
@@ -254,6 +258,16 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
if (jack_mutes_amp && jack_inserted_svc()) adac->speaker(false);
else adac->speaker(true);
p = config_alloc_get_default(NVS_TYPE_STR, "amp_GPIO", NULL, 0);
if (p) {
amp_gpio = atoi(p);
gpio_pad_select_gpio(amp_gpio);
gpio_set_direction(amp_gpio, GPIO_MODE_OUTPUT);
gpio_set_level(amp_gpio, 0);
LOG_INFO("setting amplifier GPIO %d", amp_gpio);
free(p);
}
esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
cfg.thread_name= "output_i2s";
@@ -263,11 +277,17 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
esp_pthread_set_cfg(&cfg);
pthread_create(&thread, NULL, output_thread_i2s, NULL);
cfg.thread_name= "output_i2s_sts";
cfg.prio = CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT - 1;
cfg.stack_size = 2048;
esp_pthread_set_cfg(&cfg);
pthread_create(&stats_thread, NULL, output_thread_i2s_stats, NULL);
// do we want stats
p = config_alloc_get_default(NVS_TYPE_STR, "stats", "n", 0);
stats = p && (*p == '1' || *p == 'Y' || *p == 'y');
free(p);
// memory still used but at least task is not created
if (stats) {
static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
static EXT_RAM_ATTR StackType_t xStack[STAT_STACK_SIZE] __attribute__ ((aligned (4)));
stats_task = xTaskCreateStatic( (TaskFunction_t) output_thread_i2s_stats, "output_i2s_sts", STAT_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer);
}
}
@@ -279,7 +299,7 @@ void output_close_i2s(void) {
running = false;
UNLOCK;
pthread_join(thread, NULL);
pthread_join(stats_thread, NULL);
if (stats) vTaskDelete(stats_task);
i2s_driver_uninstall(CONFIG_I2S_NUM);
free(obuf);
@@ -345,7 +365,7 @@ static int _i2s_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32
/****************************************************************************************
* Main output thread
*/
static void *output_thread_i2s() {
static void *output_thread_i2s(void *arg) {
size_t count = 0, bytes;
frames_t iframes = FRAME_BLOCK;
uint32_t timer_start = 0;
@@ -369,8 +389,11 @@ static void *output_thread_i2s() {
// manage led display & analogue
if (state != output.state) {
LOG_INFO("Output state is %d", output.state);
if (output.state == OUTPUT_OFF) led_blink(LED_GREEN, 100, 2500);
else if (output.state == OUTPUT_STOPPED) {
if (output.state == OUTPUT_OFF) {
led_blink(LED_GREEN, 100, 2500);
if (amp_gpio != -1) gpio_set_level(amp_gpio, 0);
LOG_INFO("switching off amp GPIO %d", amp_gpio);
} else if (output.state == OUTPUT_STOPPED) {
adac->speaker(false);
led_blink(LED_GREEN, 200, 1000);
} else if (output.state == OUTPUT_RUNNING) {
@@ -432,6 +455,7 @@ static void *output_thread_i2s() {
i2s_zero_dma_buffer(CONFIG_I2S_NUM);
i2s_start(CONFIG_I2S_NUM);
adac->power(ADAC_ON);
if (amp_gpio != -1) gpio_set_level(amp_gpio, 1);
}
// this does not work well as set_sample_rates resets the fifos (and it's too early)
@@ -476,13 +500,12 @@ static void *output_thread_i2s() {
/****************************************************************************************
* Stats output thread
*/
static void *output_thread_i2s_stats() {
//return;
while (running) {
LOCK;
static void *output_thread_i2s_stats(void *arg) {
while (1) {
// no need to lock
output_state state = output.state;
UNLOCK;
if(state>OUTPUT_STOPPED){
if(stats && state>OUTPUT_STOPPED){
LOG_INFO( "Output State: %d, current sample rate: %d, bytes per frame: %d",state,output.current_sample_rate, bytes_per_frame);
LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD1);
LOG_INFO( LINE_MIN_MAX_FORMAT_HEAD2);
@@ -502,7 +525,7 @@ static void *output_thread_i2s_stats() {
LOG_INFO(" ----------+----------+-----------+-----------+");
RESET_ALL_MIN_MAX;
}
usleep(STATS_PERIOD_MS *1000);
vTaskDelay( pdMS_TO_TICKS( STATS_PERIOD_MS ) );
}
return NULL;
}

View File

@@ -322,6 +322,12 @@ void register_default_nvs(){
ESP_LOGD(TAG,"Registering default value for key %s", "telnet_block");
config_set_default(NVS_TYPE_STR, "telnet_block", "500", 0);
ESP_LOGD(TAG,"Registering default value for key %s", "stats");
config_set_default(NVS_TYPE_STR, "stats", "n", 0);
ESP_LOGD(TAG,"Registering default value for key %s", "amp_GPIO");
config_set_default(NVS_TYPE_STR, "amp_GPIO", "", 0);
ESP_LOGD(TAG,"Done setting default values in nvs.");
}