From 190ac8ae558411ebde0a2514180d722609151eed Mon Sep 17 00:00:00 2001 From: Malte Heinzelmann Date: Tue, 4 Jun 2024 01:56:27 +0200 Subject: [PATCH] Added new display --- .gitmodules | 2 +- .idea/.name | 2 +- .idea/mch2022-firmware-esp32.iml | 2 +- .idea/misc.xml | 3 + .idea/vcs.xml | 1 - components/keyboard | 2 +- components/spi-st77xx/CMakeLists.txt | 4 + components/spi-st77xx/LICENSE | 8 + components/spi-st77xx/NOTES.txt | 0 components/spi-st77xx/README.md | 5 + components/spi-st77xx/component.mk | 3 + components/spi-st77xx/include/st77xx.h | 170 ++++++++ components/spi-st77xx/st77xx.c | 562 +++++++++++++++++++++++++ components/troopers24-bsp | 2 +- esp-idf-export.sh | 2 + main/nametag.c | 2 + 16 files changed, 764 insertions(+), 6 deletions(-) create mode 100644 components/spi-st77xx/CMakeLists.txt create mode 100644 components/spi-st77xx/LICENSE create mode 100644 components/spi-st77xx/NOTES.txt create mode 100644 components/spi-st77xx/README.md create mode 100644 components/spi-st77xx/component.mk create mode 100644 components/spi-st77xx/include/st77xx.h create mode 100644 components/spi-st77xx/st77xx.c create mode 100644 esp-idf-export.sh diff --git a/.gitmodules b/.gitmodules index 5968218..aa05213 100644 --- a/.gitmodules +++ b/.gitmodules @@ -47,7 +47,7 @@ url = git@github.com:hnzlmnn/esp32-component-controller.git [submodule "components/i2c-ktd2052"] path = components/i2c-ktd2052 - url = git@github.com:hnzlmnn/esp32-component-ktd2052.git + url = https://github.com/hnzlmnn/esp32-component-ktd2052 [submodule "components/pax-keyboard"] path = components/pax-keyboard url = https://github.com/robotman2412/pax-keyboard.git diff --git a/.idea/.name b/.idea/.name index cacf668..c7b81ee 100644 --- a/.idea/.name +++ b/.idea/.name @@ -1 +1 @@ -TROOPERS23 \ No newline at end of file +TROOPERS24 \ No newline at end of file diff --git a/.idea/mch2022-firmware-esp32.iml b/.idea/mch2022-firmware-esp32.iml index fc515c9..fd99360 100644 --- a/.idea/mch2022-firmware-esp32.iml +++ b/.idea/mch2022-firmware-esp32.iml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index c76f782..5cc8c60 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,8 @@ + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index d1630b8..6c6a61c 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -147,7 +147,6 @@ - diff --git a/components/keyboard b/components/keyboard index e8d659a..b2b2c11 160000 --- a/components/keyboard +++ b/components/keyboard @@ -1 +1 @@ -Subproject commit e8d659ac5c0f9bd95fb5a0323e993430c18f904e +Subproject commit b2b2c11a05ec056dc153b702fb8ccc35a795701d diff --git a/components/spi-st77xx/CMakeLists.txt b/components/spi-st77xx/CMakeLists.txt new file mode 100644 index 0000000..0c0f62e --- /dev/null +++ b/components/spi-st77xx/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register( + SRCS "st77xx.c" + INCLUDE_DIRS include +) diff --git a/components/spi-st77xx/LICENSE b/components/spi-st77xx/LICENSE new file mode 100644 index 0000000..00221d3 --- /dev/null +++ b/components/spi-st77xx/LICENSE @@ -0,0 +1,8 @@ +Copyright (c) 2024 Tom Bennellick & Malte Heinzelmann +Based on the ILI9341 driver by Nicolai Electronics. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/components/spi-st77xx/NOTES.txt b/components/spi-st77xx/NOTES.txt new file mode 100644 index 0000000..e69de29 diff --git a/components/spi-st77xx/README.md b/components/spi-st77xx/README.md new file mode 100644 index 0000000..5087ded --- /dev/null +++ b/components/spi-st77xx/README.md @@ -0,0 +1,5 @@ +# ESP32 component: ST77XX LCD display + +This *should* work with all ST77* drivers. However, it has only been tested with ST7789VI. + + diff --git a/components/spi-st77xx/component.mk b/components/spi-st77xx/component.mk new file mode 100644 index 0000000..369ec2e --- /dev/null +++ b/components/spi-st77xx/component.mk @@ -0,0 +1,3 @@ +# Component Makefile + +COMPONENT_ADD_INCLUDEDIRS := . diff --git a/components/spi-st77xx/include/st77xx.h b/components/spi-st77xx/include/st77xx.h new file mode 100644 index 0000000..b02f206 --- /dev/null +++ b/components/spi-st77xx/include/st77xx.h @@ -0,0 +1,170 @@ +/** + * Copyright (c) 2024 Tom Bennellick & Malte Heinzelmann + * Based on the ILI9341 driver by Nicolai Electronics. + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +#include +#include +#include +#include +#include +#include +#include + +#define ST77XX_WIDTH 320 +#define ST77XX_HEIGHT 240 +#define ST77XX_BUFFER_SIZE ST77XX_WIDTH * ST77XX_HEIGHT * 2 // Each pixel takes 16 bits +#define ST77XX_BPP 16 + +// Registers +#define ST77XX_NOP 0x00 +#define ST77XX_SWRESET 0x01 // Software Reset +#define ST77XX_RDDID 0x04 // Read Display ID +#define ST77XX_RDDST 0x09 // Read Display Status +#define ST77XX_RDDPM 0x0A // Read Display Power +#define ST77XX_RDDMADCTL 0x0B // Read Display Memory Data Access Mode +#define ST77XX_RDDCOLMOD 0x0C // Read Display Pixel +#define ST77XX_RDDIM 0x0D // Read Display Image +#define ST77XX_RDDSM 0x0E // Read Display Signal +#define ST77XX_RDDSDR 0x0F // Read Display Self Diagnostics +#define ST77XX_SLPIN 0x10 // Sleep In +#define ST77XX_SLPOUT 0x11 // Sleep Out +#define ST77XX_PTLON 0x12 // Partial Mode On +#define ST77XX_NORON 0x13 // Partial Mode Off +#define ST77XX_INVOFF 0x20 // Display Invert Off +#define ST77XX_INVON 0x21 // Display Invert On +#define ST77XX_GAMSET 0x26 // Display Invert On Gamma +#define ST77XX_DISPOFF 0x28 // Display Off +#define ST77XX_DISPON 0x29 // Display On +#define ST77XX_CASET 0x2A // Column Address Set +#define ST77XX_RASET 0x2B // Row Address Set +#define ST77XX_RAMWR 0x2C // Memory Write +#define ST77XX_RAMRD 0x2E // Memory Read +#define ST77XX_PTLAR 0x30 // Partial Start/End Address Set +#define ST77XX_VSCRDEF 0x33 // Vertical Scrolling Definition +#define ST77XX_TEOFF 0x34 // Tearing Effect Line Off +#define ST77XX_TEON 0x35 // Tearing Effect Line On +#define ST77XX_MADCTL 0x36 // Memory Data Access Control +#define ST77XX_VSCRSADD 0x37 // Vertical Scrolling Start Address +#define ST77XX_IDMOFF 0x38 // Idle Mode Off +#define ST77XX_IDMON 0x39 // Idle Mode On +#define ST77XX_COLMOD 0x3A // Interface Pixel Format +#define ST77XX_RAMWRC 0x3C // Memory Write Continue +#define ST77XX_RAMRDC 0x3E // Memory Read Continue +#define ST77XX_TESCAN 0x44 // Set Tear Scan Line +#define ST77XX_RDTESCAN 0x45 // Get Tear Scan Line +#define ST77XX_WRDISBV 0x51 // Set Display Brightness +#define ST77XX_RDDISBV 0x52 // Get Display Brightness +#define ST77XX_WRCTRLD 0x53 // Set Display Control +#define ST77XX_RDCTRLD 0x54 // Get Display Control +#define ST77XX_WRCACE 0x55 // Write content adaptive brightness control and Color enhancement +#define ST77XX_RDCABC 0x56 // Read content adaptive brightness control and Color enhancement +#define ST77XX_WRCABCMB 0x5E // Write CABC minimum brightness +#define ST77XX_RDCABCMB 0x5F // Read CABC minimum brightness +#define ST77XX_RDABCSDR 0x68 // Read Automatic Brightness Control Self-Diagnostic Result +#define ST77XX_PORCTRK 0xB2 // Porch setting +#define ST77XX_GCTRL 0xB7 // Gate Control +#define ST77XX_VCOMS 0xBB // VCOM setting +#define ST77XX_LCMCTRL 0xC0 // LCM Control +#define ST77XX_VDVVRHEN 0xC2 // VDV and VRH Command Enable +#define ST77XX_VRHS 0xC3 // VRH Set +#define ST77XX_VDVS 0xC4 // VDV Set +#define ST77XX_FRCTRL2 0xC6 // Frame Rate control in normal mode +#define ST77XX_PWCTRL1 0xD0 // Power Control 1 +#define ST77XX_RDID1 0xDA // Read ID1 +#define ST77XX_RDID2 0xDB // Read ID2 +#define ST77XX_RDID3 0xDC // Read ID3 +#define ST77XX_PVGAMCTRL 0xE0 // Positive Voltage Gamma control +#define ST77XX_NVGAMCTRL 0xE1 // Negative Voltage Gamma control + +// Extended command set +#define ST77XX_RGB_INTERFACE 0xB0 // RGB Interface Signal Control +#define ST77XX_FRMCTR1 0xB1 // Frame Rate Control (In Normal Mode) +#define ST77XX_FRMCTR2 0xB2 // Frame Rate Control (In Idle Mode) +#define ST77XX_FRMCTR3 0xB3 // Frame Rate Control (In Partial Mode) +#define ST77XX_INVTR 0xB4 // Display Inversion Control +#define ST77XX_BPC 0xB5 // Blanking Porch Control register +#define ST77XX_DFC 0xB6 // Display Function Control register +#define ST77XX_ETMOD 0xB7 // Entry Mode Set +#define ST77XX_BACKLIGHT1 0xB8 // Backlight Control 1 +#define ST77XX_BACKLIGHT2 0xB9 // Backlight Control 2 +#define ST77XX_BACKLIGHT3 0xBA // Backlight Control 3 +#define ST77XX_BACKLIGHT4 0xBB // Backlight Control 4 +#define ST77XX_BACKLIGHT5 0xBC // Backlight Control 5 +#define ST77XX_BACKLIGHT7 0xBE // Backlight Control 7 +#define ST77XX_BACKLIGHT8 0xBF // Backlight Control 8 +#define ST77XX_POWER1 0xC0 // Power Control 1 register +#define ST77XX_POWER2 0xC1 // Power Control 2 register +#define ST77XX_VCOM1 0xC5 // VCOM Control 1 register +#define ST77XX_VCOM2 0xC7 // VCOM Control 2 register +#define ST77XX_NVMWR 0xD0 // NV Memory Write +#define ST77XX_NVMPKEY 0xD1 // NV Memory Protection Key +#define ST77XX_RDNVM 0xD2 // NV Memory Status Read +#define ST77XX_READ_ID4 0xD3 // Read ID4 +#define ST77XX_PGAMMA 0xE0 // Positive Gamma Correction register +#define ST77XX_NGAMMA 0xE1 // Negative Gamma Correction register +#define ST77XX_DGAMCTRL1 0xE2 // Digital Gamma Control 1 +#define ST77XX_DGAMCTRL2 0xE3 // Digital Gamma Control 2 +#define ST77XX_INTERFACE 0xF6 // Interface control register + +// Extend register commands +#define ST77XX_POWERA 0xCB // Power control A register +#define ST77XX_POWERB 0xCF // Power control B register +#define ST77XX_DTCA 0xE8 // Driver timing control A +#define ST77XX_DTCB 0xEA // Driver timing control B +#define ST77XX_POWER_SEQ 0xED // Power on sequence register +#define ST77XX_3GAMMA_EN 0xF2 // 3 Gamma enable register +#define ST77XX_PRC 0xF7 // Pump ratio control register + +typedef void (*ST77XX_cb_t)(bool); // Callback for init / deinit + +typedef struct ST77XX { + // Pins + int spi_bus; + int pin_cs; + int pin_dcx; + int pin_reset; + // Configuration + uint8_t rotation; + bool color_mode; + bool reset_external_pullup; + uint32_t spi_speed; + uint32_t spi_max_transfer_size; + ST77XX_cb_t callback; + // Internal state + spi_device_handle_t spi_device; + bool dc_level; + // Mutex + SemaphoreHandle_t mutex; + SemaphoreHandle_t spi_semaphore; +} ST77XX; + +esp_err_t st77xx_init(ST77XX* device); +esp_err_t st77xx_deinit(ST77XX* device); + +esp_err_t st77xx_set_sleep(ST77XX* device, const bool state); +esp_err_t st77xx_set_display(ST77XX* device, const bool state); +esp_err_t st77xx_set_invert(ST77XX* device, const bool state); +esp_err_t st77xx_set_partial_scanning(ST77XX* device, const uint16_t start, const uint16_t end); +esp_err_t st77xx_set_tearing_effect_line(ST77XX* device, const bool state); +esp_err_t st77xx_set_idle_mode(ST77XX* device, const bool state); + +esp_err_t st77xx_write(ST77XX* device, const uint8_t *data); +esp_err_t st77xx_write_partial_direct(ST77XX* device, const uint8_t *buffer, uint16_t x, uint16_t y, uint16_t width, uint16_t height); +esp_err_t st77xx_write_partial(ST77XX* device, const uint8_t *buffer, uint16_t x, uint16_t y, uint16_t width, uint16_t height); + +esp_err_t st77xx_select(ST77XX* device, const bool mode); + +esp_err_t st77xx_power_en(ST77XX* device); + +#ifdef __cplusplus +} +#endif //__cplusplus diff --git a/components/spi-st77xx/st77xx.c b/components/spi-st77xx/st77xx.c new file mode 100644 index 0000000..45adf4d --- /dev/null +++ b/components/spi-st77xx/st77xx.c @@ -0,0 +1,562 @@ +/** + * Copyright (c) 2024 Tom Bennellick & Malte Heinzelmann + * Based on the spi ILI9341 driver by Nicolai Electronics. + * + * SPDX-License-Identifier: MIT + */ + +#include "include/st77xx.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *TAG = "st77XX"; + +static void IRAM_ATTR st77xx_spi_pre_transfer_callback(spi_transaction_t *t) { +// ILI9341* device = ((ILI9341*) t->user); +// gpio_set_level(device->pin_dcx, device->dc_level); +} + +const uint8_t st77xx_init_data[] = { + // Turn off display + ST77XX_DISPOFF, 0, + // Exit sleep mode + ST77XX_SLPOUT, 0, + // MADCTL: memory data access control Old: 0x88 + ST77XX_MADCTL, 1, 0x88, /* Page address order RGB order */ + // COLMOD: Interface Pixel format (18-bits per pixel @ 262K colors) + ST77XX_COLMOD, 1, 0x66, /* 18 bits per pixel, 262k of RGB interface */ + // PORCTRK: Porch setting + ST77XX_PORCTRK, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, /* Back porch, Front Porch, Separate porch control, Back porch idle, Back porch partial */ + // GCTRL: Gate Control + ST77XX_GCTRL, 1, 0x35, /* Probably dont change */ + // VCOMS: VCOM setting + ST77XX_VCOMS, 1, 0x2B, /* Probably dont change */ + // LCMCTRL: LCM Control + ST77XX_LCMCTRL, 1, 0x2C, /* Not sure what this does */ + // VDVVRHEN: VDV and VRH Command Enable + ST77XX_VDVVRHEN, 2, 0x01, 0xFF, /* Enable the below */ + // VRHS: VRH set + ST77XX_VRHS, 1, 0x11, /* Maybe colour correction? */ + // VDVS: VDV Set + ST77XX_VDVS, 1, 0x20, /* Maybe colour correction? */ + // FRCTRL2: Frame Rate control in normal mode + ST77XX_FRCTRL2, 1, 0x0F, /* 60Hz */ + // PWCTRL1: Power Control 1 + ST77XX_PWCTRL1, 2, 0xA4, 0xA1, /* Set voltages)*/ + // PVGAMCTRL: Positive Voltage Gamma control + ST77XX_PVGAMCTRL, 14, 0xD0, 0x00, 0x05, 0x0E, 0x15, 0x0D, 0x37, 0x43, 0x47, 0x09, 0x15, 0x12, 0x16, 0x19, + // NVGAMCTRL: Negative Voltage Gamma control + ST77XX_NVGAMCTRL, 14, 0xD0, 0x00, 0x05, 0x0D, 0x0C, 0x06, 0x2D, 0x44, 0x40, 0x0E, 0x1C, 0x18, 0x16, 0x19, + // X address set + ST77XX_CASET, 4, 0x00, 0x00, 0x00, 0xEF, + // Y address set + ST77XX_RASET, 4, 0x00, 0x00, 0x01, 0x3F, + // Display on + ST77XX_DISPON, 0, + 0x00 +}; + +esp_err_t ST7789VI_send(ST77XX* device, const uint8_t *data, const int len,const bool dc_level) { + if (len == 0) return ESP_OK; + if (device->spi_device == NULL) return ESP_FAIL; + + device->dc_level = dc_level; /* TODO: This is currently disabled, maybe put back?*/ + spi_transaction_t transaction = { + .length = len * 8, // transaction length is in bits + .tx_buffer = data, + .user = (void*) device, + }; + if (device->spi_semaphore != NULL) xSemaphoreTake(device->spi_semaphore, portMAX_DELAY); + esp_err_t res = spi_device_transmit(device->spi_device, &transaction); + if (device->spi_semaphore != NULL) xSemaphoreGive(device->spi_semaphore); + return res; +} + + +esp_err_t st77xx_send_command(ST77XX* device, const uint8_t cmd) +{ + esp_err_t err; + gpio_set_level(device->pin_dcx, 0); + err = ST7789VI_send(device, &cmd, 1, false); + return err; +} + +esp_err_t st77xx_send_data(ST77XX* device, const uint8_t* data, const uint16_t length) +{ + esp_err_t err; + gpio_set_level(device->pin_dcx, 1); + err = ST7789VI_send(device, data, length,true); + return err; +} + + +//esp_err_t st77xx_reset(ST77XX* device) { +// if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); +// esp_err_t res; +// if (device->pin_reset >= 0) { +// ESP_LOGI(TAG, "reset"); +// if (device->reset_external_pullup) { +// res = gpio_set_level(device->pin_reset, false); /* Checked 24 */ +// if (res != ESP_OK) return res; +// res = gpio_set_direction(device->pin_reset, GPIO_MODE_OUTPUT); /* Checked 24 */ +// if (res != ESP_OK) return res; +// vTaskDelay(50 / portTICK_PERIOD_MS); /* Checked 24 */ +// res = gpio_set_direction(device->pin_reset, GPIO_MODE_INPUT); /* Checked 24 */ +// if (res != ESP_OK) return res; +// vTaskDelay(50 / portTICK_PERIOD_MS); +// } else { +// res = gpio_set_level(device->pin_reset, false); +// if (res != ESP_OK) return res; +// vTaskDelay(50 / portTICK_PERIOD_MS); +// ESP_LOGI(TAG, "setting reset line to high"); +// res = gpio_set_level(device->pin_reset, true); +// if (res != ESP_OK) return res; +// vTaskDelay(50 / portTICK_PERIOD_MS); +// } +// } else { +// ESP_LOGI(TAG, "(no reset pin available)"); +// vTaskDelay(100 / portTICK_PERIOD_MS); +// } +// +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return ESP_OK; +//} + +uint8_t temp_fb [240 * 3]; + +uint8_t colour_bars [5][3] = { + {0xFF, 0x00, 0x00}, + {0x00, 0xFF, 0x00}, + {0x00, 0x00, 0xFF}, + {0xFF, 0xFF, 0x00}, + {0xFF, 0x00, 0xFF} +}; + +esp_err_t st77xx_reset(ST77XX* device) { + esp_err_t res; + res = gpio_set_level(device->pin_reset, false); + if (res != ESP_OK) return res; + + vTaskDelay(50 / portTICK_PERIOD_MS); + + res = gpio_set_level(device->pin_reset, true); + if (res != ESP_OK) return res; + + vTaskDelay(120 / portTICK_PERIOD_MS); /* This could possibly be shorter if a problem. */ + + ESP_LOGD(TAG, "Reset done"); + return ESP_OK; +} + +esp_err_t st77xx_write_init_data(ST77XX* device, const uint8_t * data) { + if (device->spi_device == NULL) return ESP_FAIL; + esp_err_t res; + uint8_t cmd, len; + while(true) { + cmd = *data++; + if (!cmd) return ESP_OK; //END + len = *data++; + res = st77xx_send_command(device, cmd); + if (res != ESP_OK) break; + if (len > 0) { + res = st77xx_send_data(device, data, len); + if (res != ESP_OK) break; + } + data += len; + } + vTaskDelay(50 / portTICK_PERIOD_MS); + return ESP_OK; +} + +esp_err_t st77xx_init(ST77XX* device) { + esp_err_t res; + + if (device->pin_dcx < 0) return ESP_FAIL; + if (device->pin_cs < 0) return ESP_FAIL; + + /*if (device->mutex == NULL) { + device->mutex = xSemaphoreCreateMutex(); + }*/ + + if (device->mutex != NULL) xSemaphoreGive(device->mutex); + + res = gpio_set_direction(device->pin_dcx, GPIO_MODE_OUTPUT); + if (res != ESP_OK) return res; + + if (!device->reset_external_pullup && device->pin_reset >= 0) { + res = gpio_hold_dis(device->pin_reset); + if (res != ESP_OK) return res; + + res = gpio_set_direction(device->pin_reset, GPIO_MODE_OUTPUT); + if (res != ESP_OK) return res; + } + + res = gpio_set_level(device->pin_dcx, true); + if (res != ESP_OK) return res; + + /* Setup SPI */ + if (device->spi_device == NULL) { + spi_device_interface_config_t devcfg = { + .command_bits = 0, + .address_bits = 0, + .dummy_bits = 0, + .mode = 0, // SPI mode 0 + .duty_cycle_pos = 128, + .cs_ena_pretrans = 0, + .cs_ena_posttrans = 0, + .clock_speed_hz = device->spi_speed, + .input_delay_ns = 0, + .spics_io_num = device->pin_cs, + .flags = SPI_DEVICE_HALFDUPLEX, + .queue_size = 1, + .pre_cb = st77xx_spi_pre_transfer_callback, // Handles D/C line + .post_cb = NULL + }; + res = spi_bus_add_device(device->spi_bus, &devcfg, &device->spi_device); + if (res != ESP_OK) return res; + } + + if (device->callback != NULL) { + device->callback(false); + } + + + ESP_LOGE(TAG, "IO Setup complete "); + + //Reset the LCD display + res = st77xx_reset(device); + if (res != ESP_OK) return res; + + ESP_LOGE(TAG, "DC pin %d", device->pin_dcx); + + //Send the initialization data to the LCD display + res = st77xx_write_init_data(device, st77xx_init_data); + if (res != ESP_OK) return res; + + + + + st77xx_send_command(device, ST77XX_RAMWR); /* Ram Write*/ + for (uint32_t j = 0; j < 240; j++) + { +// temp_fb[j * 3] = 0xff; //colour_bars[j/5][0]; +// temp_fb[j * 3 + 1] = 0x00;// colour_bars[j/5][0]; +// temp_fb[j * 3 + 2] = 0x00; //colour_bars[j/5][0]; + temp_fb[j * 3] = colour_bars[j/48][0]; + temp_fb[j * 3 + 1] = colour_bars[j/48][1]; + temp_fb[j * 3 + 2] = colour_bars[j/48][2]; +// ESP_LOGE(TAG, "%d ",j/5); + } + + for (uint32_t i = 0; i < 320; i++) { + st77xx_send_data(device, temp_fb, sizeof(temp_fb)); + } +// // +//// //Disable sleep mode +//// res = st77xx_set_sleep(device, false); +//// if (res != ESP_OK) return res; +//// +//// //Turn on the LCD +//// res = st77xx_send_command(device, ST77XX_DISPON); +//// if (res != ESP_OK) return res; +//// +//// //Configure orientation +//// res = st77xx_set_cfg(device, device->rotation, device->color_mode); +//// if (res != ESP_OK) return res; + + return ESP_OK; +} + +esp_err_t st77xx_deinit(ST77XX* device) { +return 0; + // if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); // Block access to the peripheral while deinitialized +// esp_err_t res; +// if (device->spi_device != NULL) { +// res = spi_bus_remove_device(device->spi_device); +// device->spi_device = NULL; +// if (res != ESP_OK) return res; +// } +// res = gpio_set_direction(device->pin_dcx, GPIO_MODE_INPUT); +// if (res != ESP_OK) return res; +// res = gpio_set_direction(device->pin_cs, GPIO_MODE_INPUT); +// if (res != ESP_OK) return res; +// if (device->callback != NULL) { +// device->callback(true); +// } +// res = st77xx_reset(device); +// if (res != ESP_OK) return res; +// return res; +} + +esp_err_t st77xx_select(ST77XX* device, const bool state) { + if (device->spi_device != NULL) return ESP_FAIL; + return gpio_set_level(device->pin_cs, !state); +} + +esp_err_t st77xx_write(ST77XX* device, const uint8_t *buffer) { + return st77xx_write_partial_direct(device, buffer, 0, 0, ST77XX_WIDTH, ST77XX_HEIGHT); +} + +esp_err_t st77xx_send(ST77XX* device, const uint8_t *data, const int len, const bool dc_level) { + if (len == 0) return ESP_OK; + if (device->spi_device == NULL) return ESP_FAIL; + device->dc_level = dc_level; + spi_transaction_t transaction = { + .length = len * 8, // transaction length is in bits + .tx_buffer = data, + .user = (void*) device, + }; + if (device->spi_semaphore != NULL) xSemaphoreTake(device->spi_semaphore, portMAX_DELAY); + esp_err_t res = spi_device_transmit(device->spi_device, &transaction); + if (device->spi_semaphore != NULL) xSemaphoreGive(device->spi_semaphore); + return res; +} + +esp_err_t st77xx_write_partial_direct(ST77XX* device, const uint8_t *buffer, uint16_t x, uint16_t y, uint16_t width, uint16_t height) { // Without conversion + // TODO: Implement + return 0; +// if (device->spi_device == NULL) return ESP_FAIL; +// if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); +// esp_err_t res = st77xx_set_addr_window(device, x, y, width, height); +// if (res != ESP_OK) { +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return res; +// } +// +// uint32_t position = 0; +// while (width * height * 2 - position > 0) { +// uint32_t length = device->spi_max_transfer_size; +// if (width * height * 2 - position < device->spi_max_transfer_size) length = width * height * 2 - position; +// +// res = st77xx_send(device, &buffer[position], length, true); +// if (res != ESP_OK) { +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return res; +// } +// position += length; +// } +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return res; +} + +esp_err_t st77xx_write_partial(ST77XX* device, const uint8_t *frameBuffer, uint16_t x, uint16_t y, uint16_t width, uint16_t height) { // With conversion +return 0; +// if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); +// +// if (device->spi_device == NULL) { +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return ESP_FAIL; +// } +// esp_err_t res = ESP_OK; +// +// uint8_t *buffer = heap_caps_malloc(device->spi_max_transfer_size, MALLOC_CAP_8BIT); +// if (buffer == NULL) { +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return ESP_FAIL; +// } +// +// while (width > 0) { +// uint16_t transactionWidth = width; +// if (transactionWidth*2 > device->spi_max_transfer_size) { +// transactionWidth = device->spi_max_transfer_size / 2; +// } +// res = st77xx_set_addr_window(device, x, y, transactionWidth, height); +// if (res != ESP_OK) { +// free(buffer); +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return res; +// } +// for (uint16_t currentLine = 0; currentLine < height; currentLine++) { +// for (uint16_t i = 0; imutex != NULL) xSemaphoreGive(device->mutex); +// return res; +// } +// } +// width -= transactionWidth; +// x += transactionWidth; +// } +// free(buffer); +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return res; +} + +esp_err_t st77xx_power_en(ST77XX* device) { +// if (device->pin_reset >= 0 && !device->reset_external_pullup) { +// ESP_LOGI(TAG, "keep state of pin %d", device->pin_reset); +// // If there is no external pullup, we need to keep the reset pin HIGH during sleep +// return gpio_hold_en(device->pin_reset); +// } + return ESP_OK; +} + + + + +// +//esp_err_t st77xx_set_sleep(ST77XX* device, const bool state) { +// esp_err_t res; +// ESP_LOGI(TAG, "sleep mode %s", state ? "on" : "off"); +// if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); +// if (state) { +// res = st77xx_send_command(device, ST77XX_SLPIN); +// if (res != ESP_OK) return res; +// } else { +// res = st77xx_send_command(device, ST77XX_SLPOUT); +// if (res != ESP_OK) return res; +// } +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return res; +//} +// +//esp_err_t st77xx_set_display(ST77XX* device, const bool state) { +// esp_err_t res; +// ESP_LOGI(TAG, "sleep display %s", state ? "on" : "off"); +// if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); +// +// if (state) { +// res = st77xx_send_command(device, ST77XX_DISPON); +// if (res != ESP_OK) return res; +// } else { +// res = st77xx_send_command(device, ST77XX_DISPOFF); +// if (res != ESP_OK) return res; +// } +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +// return res; +//} +// +//esp_err_t st77xx_set_invert(ST77XX* device, const bool state) { +// ESP_LOGI(TAG, "invert %s", state ? "on" : "off"); +// if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); +// +// if (state) { +// return st77xx_send_command(device, ST77XX_INVON); +// } else { +// return st77xx_send_command(device, ST77XX_INVOFF); +// } +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +//} +// +//esp_err_t st77xx_set_partial_scanning(ST77XX* device, const uint16_t start, const uint16_t end) { +// if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); +// if ((start == 0) && (end >= ST77XX_WIDTH - 1)) { +// ESP_LOGI(TAG, "partial scanning off"); +// return st77xx_send_command(device, ST77XX_NORON); +// } else { +// ESP_LOGI(TAG, "partial scanning on (%u to %u)", start, end); +// esp_err_t res = st77xx_send_command(device, ST77XX_PTLAR); +// if (res != ESP_OK) return res; +// res = st77xx_send_u32(device, (start << 16) | end); +// if (res != ESP_OK) return res; +// return st77xx_send_command(device, ST77XX_PTLON); +// } +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +//} +// +//esp_err_t st77xx_set_tearing_effect_line(ST77XX* device, const bool state) { +// ESP_LOGI(TAG, "tearing effect line %s", state ? "on" : "off"); +// if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); +// if (state) { +// return st77xx_send_command(device, ST77XX_TEON); +// } else { +// return st77xx_send_command(device, ST77XX_TEOFF); +// } +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +//} +// +//esp_err_t st77xx_set_idle_mode(ST77XX* device, const bool state) { +// ESP_LOGI(TAG, "idle mode %s", state ? "on" : "off"); +// if (device->mutex != NULL) xSemaphoreTake(device->mutex, portMAX_DELAY); +// if (state) { +// return st77xx_send_command(device, ST77XX_IDMON); +// } else { +// return st77xx_send_command(device, ST77XX_IDMOFF); +// } +// if (device->mutex != NULL) xSemaphoreGive(device->mutex); +//} + +//esp_err_t st77xx_send_u32(ST77XX* device, const uint32_t data) { +// uint8_t buffer[4]; +// buffer[0] = (data>>24)&0xFF; +// buffer[1] = (data>>16)&0xFF; +// buffer[2] = (data>> 8)&0xFF; +// buffer[3] = data &0xFF; +// return st77xx_send(device, buffer, 4, true); +//} + +//esp_err_t st77xx_set_addr_window(ST77XX* device, uint16_t x, uint16_t y, uint16_t w, uint16_t h) { +// uint32_t xa = ((uint32_t)x << 16) | (x+w-1); +// uint32_t ya = ((uint32_t)y << 16) | (y+h-1); +// esp_err_t res; +// res = st77xx_send_command(device, ST77XX_CASET); +// if (res != ESP_OK) return res; +// res = st77xx_send_u32(device, xa); +// if (res != ESP_OK) return res; +// res = st77xx_send_command(device, ST77XX_RASET); +// if (res != ESP_OK) return res; +// res = st77xx_send_u32(device, ya); +// if (res != ESP_OK) return res; +// res = st77xx_send_command(device, ST77XX_RAMWR); +// return res; +//} +// +//#define MADCTL_MY 0x80 ///< Bottom to topp +//#define MADCTL_MX 0x40 ///< Right to left +//#define MADCTL_MV 0x20 ///< Reverse Mode +//#define MADCTL_ML 0x10 ///< LCD refresh Bottom to top +//#define MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order +//#define MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order +//#define MADCTL_MH 0x04 ///< LCD refresh right to left +// +//esp_err_t st77xx_set_cfg(ST77XX* device, uint8_t rotation, bool color_mode) { +// rotation = rotation & 0x03; +// uint8_t m = 0; +// +// switch (rotation) { +// case 0: +// m |= MADCTL_MX; +// break; +// case 1: +// m |= MADCTL_MV; +// break; +// case 2: +// m |= MADCTL_MY; +// break; +// case 3: +// m |= (MADCTL_MX | MADCTL_MY | MADCTL_MV); +// break; +// } +// +// if (color_mode) { +// m |= MADCTL_BGR; +// } else { +// m |= MADCTL_RGB; +// } +// +// uint8_t commands[2] = {ST77XX_MADCTL, m}; +// esp_err_t res = st77xx_send(device, commands, 1, false); +// if (res != ESP_OK) return res; +// res = st77xx_send(device, commands+1, 1, true); +// return res; +//} diff --git a/components/troopers24-bsp b/components/troopers24-bsp index 9822bf9..21fb6bf 160000 --- a/components/troopers24-bsp +++ b/components/troopers24-bsp @@ -1 +1 @@ -Subproject commit 9822bf972a0097ebb897f9b9b7f49b3627d69af2 +Subproject commit 21fb6bfe7d5a5594b92a03889d09c36fd7ad5ce2 diff --git a/esp-idf-export.sh b/esp-idf-export.sh new file mode 100644 index 0000000..0766d46 --- /dev/null +++ b/esp-idf-export.sh @@ -0,0 +1,2 @@ + +source /home/hnzlmnn/ernw/dev/troopers/badge/tr24/troopers24-firmware-esp32/esp-idf/export.sh 1>&2 \ No newline at end of file diff --git a/main/nametag.c b/main/nametag.c index da75f38..23bdbbb 100644 --- a/main/nametag.c +++ b/main/nametag.c @@ -132,7 +132,9 @@ static void place_in_sleep(xQueueHandle button_queue) { fflush(stderr); vTaskDelay(pdMS_TO_TICKS(100)); gpio_hold_en(GPIO_LCD_BL); +#ifdef TR23 ili9341_power_en(get_ili9341()); +#endif gpio_deep_sleep_hold_en(); vTaskDelay(pdMS_TO_TICKS(100)); esp_deep_sleep_start();