Merge remote-tracking branch 'origin/master' into httpd

This commit is contained in:
Sebastien
2020-02-26 23:18:03 -05:00
17 changed files with 681 additions and 202 deletions

View File

@@ -71,7 +71,7 @@ static int i2c_port;
* init
*/
static bool init(int i2c_port_num, int i2s_num, i2s_config_t *i2s_config) {
esp_err_t res;
esp_err_t res = ESP_OK;
i2c_port = i2c_port_num;
@@ -144,8 +144,8 @@ static bool init(int i2c_port_num, int i2s_num, i2s_config_t *i2s_config) {
i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = CONFIG_I2S_BCK_IO, .ws_io_num = CONFIG_I2S_WS_IO,
.data_out_num = CONFIG_I2S_DO_IO, .data_in_num = CONFIG_I2S_DI_IO
};
i2s_driver_install(i2s_num, i2s_config, 0, NULL);
i2s_set_pin(i2s_num, &i2s_pin_config);
res |= i2s_driver_install(i2s_num, i2s_config, 0, NULL);
res |= i2s_set_pin(i2s_num, &i2s_pin_config);
// enable earphone & speaker
i2c_write_reg(SPKOUT_CTRL, 0x0220);
@@ -156,9 +156,9 @@ static bool init(int i2c_port_num, int i2s_num, i2s_config_t *i2s_config) {
ac101_set_spk_volume(100);
ac101_set_earph_volume(100);
ESP_LOGI(TAG, "DAC using I2S bck:%u, ws:%u, do:%u", i2s_pin_config.bck_io_num, i2s_pin_config.ws_io_num, i2s_pin_config.data_out_num);
ESP_LOGI(TAG, "DAC using I2S bck:%d, ws:%d, do:%d", i2s_pin_config.bck_io_num, i2s_pin_config.ws_io_num, i2s_pin_config.data_out_num);
return true;
return (res == ESP_OK);
}
/****************************************************************************************

View File

@@ -233,8 +233,8 @@ bool sb_display_init(void) {
displayer.mutex = xSemaphoreCreateMutex();
displayer.task = xTaskCreateStatic( (TaskFunction_t) displayer_task, "displayer_thread", SCROLL_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer);
// size scroller
scroller.scroll.max = (displayer.width * displayer.height / 8) * 10;
// size scroller (width + current screen)
scroller.scroll.max = (displayer.width * displayer.height / 8) * (10 + 1);
scroller.scroll.frame = malloc(scroller.scroll.max);
scroller.back.frame = malloc(displayer.width * displayer.height / 8);
scroller.frame = malloc(displayer.width * displayer.height / 8);
@@ -500,8 +500,9 @@ static void grfe_handler( u8_t *data, int len) {
displayer.dirty = false;
}
// draw new frame
GDS_DrawBitmapCBR(display, data + sizeof(struct grfe_packet), displayer.width, displayer.height);
// draw new frame, it might be less than full screen (small visu)
int width = ((len - sizeof(struct grfe_packet)) * 8) / displayer.height;
GDS_DrawBitmapCBR(display, data + sizeof(struct grfe_packet), width, displayer.height, GDS_COLOR_WHITE);
GDS_Update(display);
}
@@ -561,7 +562,7 @@ static void grfs_handler(u8_t *data, int len) {
// background excludes space taken by visu (if any)
scroller.back.width = displayer.width - ((visu.mode && visu.row < SB_HEIGHT) ? visu.width : 0);
// set scroller steps & beginning
if (pkt->direction == 1) {
scroller.scrolled = 0;
@@ -580,7 +581,8 @@ static void grfs_handler(u8_t *data, int len) {
scroller.scroll.size = offset + size;
LOG_INFO("scroller current size %u", scroller.scroll.size);
} else {
LOG_INFO("scroller too larger %u/%u", scroller.scroll.size + size, scroller.scroll.max);
LOG_INFO("scroller too larger %u/%u/%u", scroller.scroll.size + size, scroller.scroll.max, scroller.scroll.width);
scroller.scroll.width = scroller.scroll.size / (displayer.height / 8);
}
}
@@ -598,13 +600,13 @@ static void grfg_handler(u8_t *data, int len) {
scroller.width = htons(pkt->width);
memcpy(scroller.back.frame, data + sizeof(struct grfg_packet), len - sizeof(struct grfg_packet));
// update display asynchronously (frames are oganized by columns)
// update display asynchronously (frames are organized by columns)
memcpy(scroller.frame, scroller.back.frame, scroller.back.width * displayer.height / 8);
for (int i = 0; i < scroller.width * displayer.height / 8; i++) scroller.frame[i] |= scroller.scroll.frame[scroller.scrolled * displayer.height / 8 + i];
// can only write if we really own display
if (displayer.owned) {
GDS_DrawBitmapCBR(display, scroller.frame, scroller.back.width, displayer.height);
GDS_DrawBitmapCBR(display, scroller.frame, scroller.back.width, displayer.height, GDS_COLOR_WHITE);
GDS_Update(display);
}
@@ -636,7 +638,7 @@ static void visu_update(void) {
// reset bars for all cases first
for (int i = visu.n; --i >= 0;) visu.bars[i].current = 0;
if (visu_export.running && visu_export.running) {
if (visu_export.running) {
if (visu.mode == VISU_VUMETER) {
s16_t *iptr = visu_export.buffer;
@@ -704,15 +706,20 @@ static void visu_update(void) {
visu_export.level = 0;
pthread_mutex_unlock(&visu_export.mutex);
GDS_ClearExt(display, false, false, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1);
// don't refresh screen if all max are 0 (we were are somewhat idle)
int clear = 0;
for (int i = visu.n; --i >= 0;) clear = max(clear, visu.bars[i].max);
if (clear) GDS_ClearExt(display, false, false, visu.col, visu.row, visu.col + visu.width - 1, visu.row + visu.height - 1);
// there is much more optimization to be done here, like not redrawing bars unless needed
for (int i = visu.n; --i >= 0;) {
int x1 = visu.col + visu.border + visu.bar_border + i*(visu.bar_width + visu.bar_gap);
int y1 = visu.row + visu.height - 1;
if (visu.bars[i].current > visu.bars[i].max) visu.bars[i].max = visu.bars[i].current;
else if (visu.bars[i].max) visu.bars[i].max--;
else if (!clear) continue;
for (int j = 0; j <= visu.bars[i].current; j += 2)
GDS_DrawLine(display, x1, y1 - j, x1 + visu.bar_width - 1, y1 - j, GDS_COLOR_WHITE);
@@ -773,6 +780,9 @@ static void visu_handler( u8_t *data, int len) {
visu.border = htonl(pkt->border);
bars = htonl(pkt->bars);
visu.spectrum_scale = htonl(pkt->spectrum_scale) / 100.;
// might have a race condition with scroller message, so update width in case
if (scroller.active) scroller.back.width = displayer.width - visu.width;
} else {
// full screen visu, try to use bottom screen if available
visu.width = displayer.width;
@@ -855,7 +865,7 @@ static void displayer_task(void *args) {
memcpy(scroller.frame, scroller.back.frame, scroller.back.width * displayer.height / 8);
for (int i = 0; i < scroller.width * displayer.height / 8; i++) scroller.frame[i] |= scroller.scroll.frame[scroller.scrolled * displayer.height / 8 + i];
scroller.scrolled += scroller.by;
if (displayer.owned) GDS_DrawBitmapCBR(display, scroller.frame, scroller.width, displayer.height);
if (displayer.owned) GDS_DrawBitmapCBR(display, scroller.frame, scroller.width, displayer.height, GDS_COLOR_WHITE);
// short sleep & don't need background update
scroller.wake = scroller.speed;

View File

@@ -252,9 +252,9 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
// finally let DAC driver initialize I2C and I2S
if (dac_tas57xx.init(I2C_PORT, CONFIG_I2S_NUM, &i2s_config)) adac = &dac_tas57xx;
else if (dac_a1s.init(I2C_PORT, CONFIG_I2S_NUM, &i2s_config)) adac = &dac_a1s;
else {
dac_external.init(I2C_PORT, CONFIG_I2S_NUM, &i2s_config);
adac = &dac_external;
else if (!dac_external.init(I2C_PORT, CONFIG_I2S_NUM, &i2s_config)) {
LOG_WARN("DAC not configured and SPDIF not enabled, I2S will not continue");
return;
}
}

View File

@@ -27,7 +27,9 @@
#include "driver/gpio.h"
#include "adac.h"
#define VOLUME_GPIO 14
// this is the only hard-wired thing
#define VOLUME_GPIO 14
#define TAS575x 0x98
#define TAS578x 0x90
@@ -79,7 +81,7 @@ static int tas57_detect(void);
*/
static bool init(int i2c_port_num, int i2s_num, i2s_config_t *i2s_config) {
i2c_port = i2c_port_num;
// configure i2c
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
@@ -104,11 +106,6 @@ static bool init(int i2c_port_num, int i2s_num, i2s_config_t *i2s_config) {
LOG_INFO("TAS57xx DAC using I2C sda:%u, scl:%u", i2c_config.sda_io_num, i2c_config.scl_io_num);
// init volume & mute
gpio_pad_select_gpio(VOLUME_GPIO);
gpio_set_direction(VOLUME_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(VOLUME_GPIO, 0);
i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
for (int i = 0; tas57xx_init_sequence[i].reg != 0xff; i++) {
@@ -121,22 +118,26 @@ static bool init(int i2c_port_num, int i2s_num, i2s_config_t *i2s_config) {
}
i2c_master_stop(i2c_cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_port, i2c_cmd, 500 / portTICK_RATE_MS);
esp_err_t res = i2c_master_cmd_begin(i2c_port, i2c_cmd, 500 / portTICK_RATE_MS);
i2c_cmd_link_delete(i2c_cmd);
// configure I2S pins & install driver
i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = CONFIG_I2S_BCK_IO, .ws_io_num = CONFIG_I2S_WS_IO,
.data_out_num = CONFIG_I2S_DO_IO, .data_in_num = CONFIG_I2S_DI_IO,
};
i2s_driver_install(i2s_num, i2s_config, 0, NULL);
i2s_set_pin(i2s_num, &i2s_pin_config);
LOG_INFO("DAC using I2S bck:%u, ws:%u, do:%u", i2s_pin_config.bck_io_num, i2s_pin_config.ws_io_num, i2s_pin_config.data_out_num);
res |= i2s_driver_install(i2s_num, i2s_config, 0, NULL);
res |= i2s_set_pin(i2s_num, &i2s_pin_config);
LOG_INFO("DAC using I2S bck:%d, ws:%d, do:%d", i2s_pin_config.bck_io_num, i2s_pin_config.ws_io_num, i2s_pin_config.data_out_num);
if (ret != ESP_OK) {
LOG_ERROR("could not intialize TAS57xx %d", ret);
return false;
} else {
if (res == ESP_OK) {
// init volume & mute
gpio_pad_select_gpio(VOLUME_GPIO);
gpio_set_direction(VOLUME_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(VOLUME_GPIO, 0);
return true;
} else {
LOG_ERROR("could not intialize TAS57xx %d", res);
return false;
}
}