diff --git a/README.md b/README.md index 690e7f4d..bbea47aa 100644 --- a/README.md +++ b/README.md @@ -188,13 +188,14 @@ Ground -------------------------- coax signal ground The NVS parameter "display_config" sets the parameters for an optional display. Syntax is ``` I2C,width=,height=[address=][,reset=][,HFlip][,VFlip][driver=SSD1306|SSD1326[:1|4]|SSD1327|SH1106] -SPI,width=,height=,cs=[,back=][,reset=][,speed=][,HFlip][,VFlip][driver=SSD1306|SSD1322|SSD1326[:1|4]|SSD1327|SH1106|SSD1675|ST7735|ST7789|ILI9341[:16|18][,rotate]] +SPI,width=,height=,cs=[,back=][,reset=][,speed=][,HFlip][,VFlip][driver=SSD1306|SSD1322|SSD1326[:1|4]|SSD1327|SH1106|SSD1675|ST7735|ST7789|ILI9341[:16|18][,rotate]][,mode=] ``` - back: a LED backlight used by some older devices (ST7735). It is PWM controlled for brightness - reset: some display have a reset pin that is should normally be pulled up if unused - VFlip and HFlip are optional can be used to change display orientation - rotate: for non-square *drivers*, move to portrait mode. Note that *width* and *height* must be inverted then - Default speed is 8000000 (8MHz) but SPI can work up to 26MHz or even 40MHz +- mode: Default mode = 0. Some display modules use different transaction line timings. Check the module documentation if a non-standard mode is required. - SH1106 is 128x64 monochrome I2C/SPI [here]((https://www.waveshare.com/wiki/1.3inch_OLED_HAT)) - SSD1306 is 128x32 monochrome I2C/SPI [here](https://www.buydisplay.com/i2c-blue-0-91-inch-oled-display-module-128x32-arduino-raspberry-pi) - SSD1322 is 256x64 grayscale 16-levels SPI in multiple sizes [here](https://www.buydisplay.com/oled-display/oled-display-module?resolution=159) - it is very nice diff --git a/components/display/core/gds_default_if.h b/components/display/core/gds_default_if.h index cb6324b3..a657d17e 100644 --- a/components/display/core/gds_default_if.h +++ b/components/display/core/gds_default_if.h @@ -11,7 +11,7 @@ bool GDS_I2CInit( int PortNumber, int SDA, int SCL, int speed ); bool GDS_I2CAttachDevice( struct GDS_Device* Device, int Width, int Height, int I2CAddress, int RSTPin, int BacklightPin ); bool GDS_SPIInit( int SPI, int DC ); -bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int Speed, int BacklightPin ); +bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int Speed, int BacklightPin, int Mode ); #ifdef __cplusplus } diff --git a/components/display/core/ifaces/default_if_spi.c b/components/display/core/ifaces/default_if_spi.c index 1f047584..b561c297 100644 --- a/components/display/core/ifaces/default_if_spi.c +++ b/components/display/core/ifaces/default_if_spi.c @@ -34,7 +34,7 @@ bool GDS_SPIInit( int SPI, int DC ) { return true; } -bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int BackLightPin, int Speed ) { +bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int BackLightPin, int Speed, int Mode ) { spi_device_interface_config_t SPIDeviceConfig = { }; spi_device_handle_t SPIDevice; @@ -48,6 +48,7 @@ bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int SPIDeviceConfig.clock_speed_hz = Speed > 0 ? Speed : SPI_MASTER_FREQ_8M; SPIDeviceConfig.spics_io_num = CSPin; SPIDeviceConfig.queue_size = 1; + SPIDeviceConfig.mode = Mode; SPIDeviceConfig.flags = SPI_DEVICE_NO_DUMMY; if (Device->SPIParams) Device->SPIParams(SPIDeviceConfig.clock_speed_hz, &SPIDeviceConfig.mode, &SPIDeviceConfig.cs_ena_pretrans, &SPIDeviceConfig.cs_ena_posttrans); diff --git a/components/display/display.c b/components/display/display.c index 371cbdeb..3a963af4 100644 --- a/components/display/display.c +++ b/components/display/display.c @@ -119,14 +119,15 @@ void display_init(char *welcome) { ESP_LOGI(TAG, "Display is I2C on port %u", address); } else if (strcasestr(config, "SPI") && spi_system_host != -1) { - int CS_pin = -1, speed = 0; + int CS_pin = -1, speed = 0, mode = 0; PARSE_PARAM(config, "cs", '=', CS_pin); PARSE_PARAM(config, "speed", '=', speed); + PARSE_PARAM(config, "mode", '=', mode); init = true; GDS_SPIInit( spi_system_host, spi_system_dc_gpio ); - GDS_SPIAttachDevice( display, width, height, CS_pin, RST_pin, backlight_pin, speed ); + GDS_SPIAttachDevice( display, width, height, CS_pin, RST_pin, backlight_pin, speed, mode ); ESP_LOGI(TAG, "Display is SPI host %u with cs:%d", spi_system_host, CS_pin); } else { diff --git a/components/platform_console/cmd_i2ctools.c b/components/platform_console/cmd_i2ctools.c index 18c78efb..4a2863c0 100644 --- a/components/platform_console/cmd_i2ctools.c +++ b/components/platform_console/cmd_i2ctools.c @@ -101,6 +101,7 @@ static struct { struct arg_int *reset; struct arg_lit *clear; struct arg_lit *invert; + struct arg_int *mode; struct arg_end *end; } i2cdisp_args; @@ -377,6 +378,13 @@ static int do_i2c_set_display(int argc, char **argv) } /* Check "--cs" option */ nerrors +=is_output_gpio(i2cdisp_args.cs,f,&config.CS_pin, false); + /* Check "--mode" option */ + if (i2cdisp_args.mode->count) { + config.mode=i2cdisp_args.mode->ival[0]; + } + else { + config.mode = 0; + } } nerrors +=is_output_gpio(i2cdisp_args.reset,f,&config.RST_pin, false); @@ -964,6 +972,9 @@ cJSON * i2c_set_display_cb(){ cJSON_AddBoolToObject(values,"hf",conf->hflip); cJSON_AddBoolToObject(values,"vf",conf->vflip); cJSON_AddBoolToObject(values,"invert",conf->invert); + if(conf->mode>=0){ + cJSON_AddNumberToObject(values,"mode",conf->mode); + } } return values; } @@ -986,6 +997,7 @@ static void register_i2c_set_display(){ i2cdisp_args.rotate = arg_lit0("r", "rotate", "Rotate 180 degrees"); i2cdisp_args.invert = arg_lit0("i", "invert", "Invert colors"); i2cdisp_args.clear = arg_lit0(NULL, "clear", "clear configuration and return"); + i2cdisp_args.mode = arg_int0("m", "mode", "","SPI Only. Transaction Line Mode (Default 0)"); i2cdisp_args.end = arg_end(8); const esp_console_cmd_t i2c_set_display= { .command = CFG_TYPE_HW("display"), diff --git a/components/services/accessors.c b/components/services/accessors.c index 8bc4b18d..c386d77e 100644 --- a/components/services/accessors.c +++ b/components/services/accessors.c @@ -352,6 +352,10 @@ esp_err_t config_display_set(const display_config_t * config){ snprintf(config_buffer2,buffer_size,"%s,speed=%i",config_buffer,config->speed); strcpy(config_buffer,config_buffer2); } + if(config->mode >=0 && strcasecmp("SPI",config->type)==0){ + snprintf(config_buffer2,buffer_size,"%s,mode=%i",config_buffer,config->mode); + strcpy(config_buffer,config_buffer2); + } snprintf(config_buffer2,buffer_size,"%s,driver=%s%s%s%s",config_buffer,config->drivername,config->hflip?",HFlip":"",config->vflip?",VFlip":"",config->rotate?",rotate":""); strcpy(config_buffer,config_buffer2); log_send_messaging(MESSAGING_INFO,"Updating display configuration to %s",config_buffer); @@ -465,6 +469,7 @@ const display_config_t * config_display_get(){ .rotate = false, .invert = false, .colorswap = 0, + .mode = 0, }; char *config = config_alloc_get(NVS_TYPE_STR, "display_config"); if (!config) { @@ -484,6 +489,7 @@ const display_config_t * config_display_get(){ PARSE_PARAM(config, "address", '=', dstruct.address); PARSE_PARAM(config, "cs", '=', dstruct.CS_pin); PARSE_PARAM(config, "speed", '=', dstruct.speed); + PARSE_PARAM(config, "mode", '=', dstruct.mode); if (strstr(config, "I2C") ) dstruct.type=i2c_name_type; if (strstr(config, "SPI") ) dstruct.type=spi_name_type; diff --git a/components/services/accessors.h b/components/services/accessors.h index d7c9c640..6a65b820 100644 --- a/components/services/accessors.h +++ b/components/services/accessors.h @@ -33,6 +33,7 @@ typedef struct { bool rotate; bool invert; int colorswap; + int mode; } display_config_t; typedef struct eth_config_struct {