From ce790a412e2234e44a17a5320487da8e76e7a2a8 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Mon, 20 Jan 2020 22:15:11 -0800 Subject: [PATCH] add Vcc_GPIO & handle LMS 32-pixels fixed display height --- components/services/display.h | 2 +- components/services/driver_SSD1306.c | 37 +++++++++++++++------------- components/services/services.c | 17 +++++++++++++ components/squeezelite/display.c | 7 +++--- main/esp_app_main.c | 3 +++ 5 files changed, 45 insertions(+), 21 deletions(-) diff --git a/components/services/display.h b/components/services/display.h index 6a760a0c..fdd7d852 100644 --- a/components/services/display.h +++ b/components/services/display.h @@ -32,5 +32,5 @@ extern struct display_s { void (*text)(enum display_pos_e pos, int attribute, char *msg); void (*update)(void); void (*draw)(int x1, int y1, int x2, int y2, bool by_column, u8_t *data); - void (*draw_cbr)(u8_t *data); + void (*draw_cbr)(u8_t *data, int height); // height is the # of columns in data, as oppoosed to display height (0 = display height) } *display; \ No newline at end of file diff --git a/components/services/driver_SSD1306.c b/components/services/driver_SSD1306.c index c01a8ad0..e860bf28 100644 --- a/components/services/driver_SSD1306.c +++ b/components/services/driver_SSD1306.c @@ -37,7 +37,7 @@ static const char *TAG = "display"; // handlers static bool init(char *config, char *welcome); static void text(enum display_pos_e pos, int attribute, char *text); -static void draw_cbr(u8_t *data); +static void draw_cbr(u8_t *data, int height); static void draw(int x1, int y1, int x2, int y2, bool by_column, u8_t *data); static void brightness(u8_t level); static void on(bool state); @@ -143,7 +143,7 @@ static void text(enum display_pos_e pos, int attribute, char *text) { /**************************************************************************************** * Process graphic display data from column-oriented bytes, MSbit first */ -static void draw_cbr(u8_t *data) { +static void draw_cbr(u8_t *data, int height) { #ifndef FULL_REFRESH // force addressing mode by rows if (AddressMode != AddressMode_Horizontal) { @@ -152,8 +152,7 @@ static void draw_cbr(u8_t *data) { } // try to minimize I2C traffic which is very slow - // TODO: this should move to grfe - int rows = (Display.Height > 32) ? 4 : Display.Height / 8; + int rows = (height ? height : Display.Height) / 8; for (int r = 0; r < rows; r++) { uint8_t first = 0, last; uint8_t *optr = Display.Framebuffer + r*Display.Width, *iptr = data + r; @@ -177,14 +176,14 @@ static void draw_cbr(u8_t *data) { } } #else - int len = (Display.Width * Display.Height) / 8; - - // to be verified, but this is as fast as using a pointer on data - for (int i = len - 1; i >= 0; i--) Display.Framebuffer[i] = BitReverseTable256[data[i]]; - - // 64 pixels display are not handled by LMS (bitmap is 32 pixels) - // TODO: this should move to grfe - if (Display.Height > 32) SSD1306_SetPageAddress( &Display, 0, 32/8-1); + if (!height) height = Display->Height; + + // copy data in frame buffer + for (int c = 0; c < Display.Width; c++) + for (int r = 0; r < height / 8; r++) + Display.Framebuffer[c*Display.Height/8 + r] = BitReverseTable256[data[c*height/8 +r]]; + + SSD1306_SetPageAddress( &Display, 0, height / 8 - 1); // force addressing mode by columns if (AddressMode != AddressMode_Vertical) { @@ -192,12 +191,13 @@ static void draw_cbr(u8_t *data) { SSD1306_SetDisplayAddressMode( &Display, AddressMode ); } - SSD1306_WriteRawData(&Display, Display.Framebuffer, len); + SSD1306_WriteRawData(&Display, Display.Framebuffer, Display.Width * Display.Heigth); #endif } /**************************************************************************************** * Process graphic display data MSBit first + * WARNING: this has not been tested yet */ static void draw(int x1, int y1, int x2, int y2, bool by_column, u8_t *data) { @@ -209,11 +209,14 @@ static void draw(int x1, int y1, int x2, int y2, bool by_column, u8_t *data) { // default end point to display size if (x2 == -1) x2 = Display.Width - 1; if (y2 == -1) y2 = Display.Height - 1; - + // set addressing mode to match data - if (by_column && AddressMode != AddressMode_Vertical) { - AddressMode = AddressMode_Vertical; - SSD1306_SetDisplayAddressMode( &Display, AddressMode ); + if (by_column) { + + if (AddressMode != AddressMode_Vertical) { + AddressMode = AddressMode_Vertical; + SSD1306_SetDisplayAddressMode( &Display, AddressMode ); + } // copy the window and do row/col exchange for (int r = y1/8; r <= y2/8; r++) { diff --git a/components/services/services.c b/components/services/services.c index 280cf4b8..671a4be1 100644 --- a/components/services/services.c +++ b/components/services/services.c @@ -29,6 +29,8 @@ static const char *TAG = "services"; * */ void services_init(void) { + char *nvs_item; + gpio_install_isr_service(0); #ifdef CONFIG_SQUEEZEAMP @@ -38,6 +40,21 @@ void services_init(void) { } #endif + // set fixed gpio if any + if ((nvs_item = config_alloc_get(NVS_TYPE_STR, "Vcc_GPIO")) != NULL) { + char *p = nvs_item; + while (p && *p) { + int gpio = atoi(p); + gpio_pad_select_gpio(gpio); + gpio_set_direction(gpio, GPIO_MODE_OUTPUT); + gpio_set_level(gpio, 1); + p = strchr(p, ','); + ESP_LOGI(TAG, "set GPIO %u to Vcc", gpio); + if (p) p++; + } + free(nvs_item); + } + const i2c_config_t * i2c_config = config_i2c_get(&i2c_system_port); ESP_LOGI(TAG,"Configuring I2C sda:%d scl:%d port:%u speed:%u", i2c_config->sda_io_num, i2c_config->scl_io_num, i2c_system_port, i2c_config->master.clk_speed); diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c index ee375c6a..50ccafbf 100644 --- a/components/squeezelite/display.c +++ b/components/squeezelite/display.c @@ -67,6 +67,7 @@ static struct scroller_s { #define SCROLL_STACK_SIZE 2048 #define LINELEN 40 +#define HEIGHT 32 static log_level loglevel = lINFO; static SemaphoreHandle_t display_sem; @@ -283,7 +284,7 @@ static void vfdc_handler( u8_t *_data, int bytes_read) { static void grfe_handler( u8_t *data, int len) { scroller.active = false; xSemaphoreTake(display_sem, portMAX_DELAY); - display->draw_cbr(data + sizeof(struct grfe_packet)); + display->draw_cbr(data + sizeof(struct grfe_packet), HEIGHT); xSemaphoreGive(display_sem); } @@ -390,7 +391,7 @@ static void scroll_task(void *args) { break; } - display->draw_cbr(frame); + display->draw_cbr(frame, HEIGHT); xSemaphoreGive(display_sem); usleep(scroller.speed * 1000); } @@ -400,7 +401,7 @@ static void scroll_task(void *args) { memcpy(frame, scroller.back_frame, len); for (int i = 0; i < scroll_len; i++) frame[i] |= scroller.scroll_frame[i]; xSemaphoreTake(display_sem, portMAX_DELAY); - display->draw_cbr(frame); + display->draw_cbr(frame, HEIGHT); xSemaphoreGive(display_sem); // pause for required time and continue (or not) diff --git a/main/esp_app_main.c b/main/esp_app_main.c index 782cec7a..9a5de0d7 100644 --- a/main/esp_app_main.c +++ b/main/esp_app_main.c @@ -306,6 +306,9 @@ void register_default_nvs(){ ESP_LOGD(TAG,"Registering default value for key %s", "i2c_config"); config_set_default(NVS_TYPE_STR, "i2c_config", "", 0); + ESP_LOGD(TAG,"Registering default value for key %s", "Vcc_GPIO"); + config_set_default(NVS_TYPE_STR, "Vcc_GPIO", "", 0); + ESP_LOGD(TAG,"Done setting default values in nvs."); }