From bdffef1f373cd82b018e5361660fb21a91473b28 Mon Sep 17 00:00:00 2001 From: Roman Mashta Date: Mon, 28 Aug 2023 23:54:13 +0300 Subject: [PATCH] Display drivers initial implementation --- lib/TFT_eSPI/User_Setup_Select.h | 4 + lib/rm67162/pins_config.h | 41 +++ lib/rm67162/rm67162.cpp | 332 ++++++++++++++++++++ lib/rm67162/rm67162.h | 57 ++++ platformio.ini | 19 +- src/NerdMinerV2.ino.cpp | 56 +--- src/display/display.cpp | 54 ++++ src/display/display.h | 17 + src/display/drivers.h | 38 +++ src/display/drivers/amoledDisplayDriver.cpp | 221 +++++++++++++ src/display/drivers/noDisplayDriver.cpp | 55 ++++ src/display/drivers/tDisplayDriver.cpp | 216 +++++++++++++ src/mining.cpp | 22 +- src/monitor.cpp | 281 ++++------------- src/monitor.h | 43 ++- src/version.h | 6 + src/wManager.cpp | 8 +- src/wManager.h | 5 + 18 files changed, 1183 insertions(+), 292 deletions(-) create mode 100644 lib/rm67162/pins_config.h create mode 100644 lib/rm67162/rm67162.cpp create mode 100644 lib/rm67162/rm67162.h create mode 100644 src/display/display.cpp create mode 100644 src/display/display.h create mode 100644 src/display/drivers.h create mode 100644 src/display/drivers/amoledDisplayDriver.cpp create mode 100644 src/display/drivers/noDisplayDriver.cpp create mode 100644 src/display/drivers/tDisplayDriver.cpp create mode 100644 src/version.h diff --git a/lib/TFT_eSPI/User_Setup_Select.h b/lib/TFT_eSPI/User_Setup_Select.h index 91238c5..afb08b9 100644 --- a/lib/TFT_eSPI/User_Setup_Select.h +++ b/lib/TFT_eSPI/User_Setup_Select.h @@ -130,6 +130,10 @@ #ifdef NERDMINERV2 #include #endif +#ifdef NERMINER_S3_AMOLED +#include //Just a stub. No driver implementation for S3 AMOLED in TFT_eSPI +#endif + //#include // Setup file for Bw16-based boards with ST7735 160 x 80 TFT //#include // Template file for a setup diff --git a/lib/rm67162/pins_config.h b/lib/rm67162/pins_config.h new file mode 100644 index 0000000..837c147 --- /dev/null +++ b/lib/rm67162/pins_config.h @@ -0,0 +1,41 @@ +#pragma once + +/***********************config*************************/ +#define LCD_USB_QSPI_DREVER 1 + +#define SPI_FREQUENCY 75000000 +#define TFT_SPI_MODE SPI_MODE0 +#define TFT_SPI_HOST SPI2_HOST + +#define EXAMPLE_LCD_H_RES 536 +#define EXAMPLE_LCD_V_RES 240 +#define LVGL_LCD_BUF_SIZE (EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES) + +/***********************config*************************/ + +#define TFT_WIDTH 240 +#define TFT_HEIGHT 536 +#define SEND_BUF_SIZE (0x4000) //(LCD_WIDTH * LCD_HEIGHT + 8) / 10 + +#define TFT_TE 9 +#define TFT_SDO 8 + +#define TFT_DC 7 +#define TFT_RES 17 +#define TFT_CS 6 +#define TFT_MOSI 18 +#define TFT_SCK 47 + +#define TFT_QSPI_CS 6 +#define TFT_QSPI_SCK 47 +#define TFT_QSPI_D0 18 +#define TFT_QSPI_D1 7 +#define TFT_QSPI_D2 48 +#define TFT_QSPI_D3 5 +#define TFT_QSPI_RST 17 + +#define PIN_LED 38 +#define PIN_BAT_VOLT 4 + +#define PIN_BUTTON_1 0 +#define PIN_BUTTON_2 21 \ No newline at end of file diff --git a/lib/rm67162/rm67162.cpp b/lib/rm67162/rm67162.cpp new file mode 100644 index 0000000..b271783 --- /dev/null +++ b/lib/rm67162/rm67162.cpp @@ -0,0 +1,332 @@ +#include "rm67162.h" +#include "SPI.h" +#include "Arduino.h" +#include "driver/spi_master.h" + +const static lcd_cmd_t rm67162_spi_init[] = { + {0xFE, {0x00}, 0x01}, // PAGE + {0x35, {0x00}, 0x00}, //TE ON + // {0x34, {0x00}, 0x00}, //TE OFF + {0x36, {0x00}, 0x01}, // Scan Direction Control + {0x3A, {0x75}, 0x01}, // Interface Pixel Format 16bit/pixel + // {0x3A, {0x76}, 0x01}, //Interface Pixel Format 18bit/pixel + // {0x3A, {0x77}, 0x01}, //Interface Pixel Format 24bit/pixel + {0x51, {0x00}, 0x01}, // Write Display Brightness MAX_VAL=0XFF + {0x11, {0x00}, 0x01 | 0x80}, // Sleep Out + {0x29, {0x00}, 0x01 | 0x80}, // Display on + {0x51, {0xD0}, 0x01}, // Write Display Brightness MAX_VAL=0XFF +}; + +const static lcd_cmd_t rm67162_qspi_init[] = { + {0x11, {0x00}, 0x80}, // Sleep Out + // {0x44, {0x01, 0x66}, 0x02}, //Set_Tear_Scanline + // {0x35, {0x00}, 0x00}, //TE ON + // {0x34, {0x00}, 0x00}, //TE OFF + // {0x36, {0x00}, 0x01}, //Scan Direction Control + {0x3A, {0x55}, 0x01}, // Interface Pixel Format 16bit/pixel + // {0x3A, {0x66}, 0x01}, //Interface Pixel Format 18bit/pixel + // {0x3A, {0x77}, 0x01}, //Interface Pixel Format 24bit/pixel + {0x51, {0x00}, 0x01}, // Write Display Brightness MAX_VAL=0XFF + {0x29, {0x00}, 0x80}, // Display on + {0x51, {0xD0}, 0x01}, // Write Display Brightness MAX_VAL=0XFF +}; + +static spi_device_handle_t spi; + +static void WriteComm(uint8_t data) +{ + TFT_CS_L; + SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, TFT_SPI_MODE)); + TFT_DC_L; + SPI.write(data); + TFT_DC_H; + SPI.endTransaction(); + TFT_CS_H; +} + +static void WriteData(uint8_t data) +{ + TFT_CS_L; + SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, TFT_SPI_MODE)); + TFT_DC_H; + SPI.write(data); + SPI.endTransaction(); + TFT_CS_H; +} + +static void WriteData16(uint16_t data) +{ + TFT_CS_L; + SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, TFT_SPI_MODE)); + TFT_DC_H; + SPI.write16(data); + SPI.endTransaction(); + TFT_CS_H; +} + +static void lcd_send_cmd(uint32_t cmd, uint8_t *dat, uint32_t len) +{ +#if LCD_USB_QSPI_DREVER == 1 + TFT_CS_L; + spi_transaction_t t; + memset(&t, 0, sizeof(t)); + t.flags = (SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR); + t.cmd = 0x02; + t.addr = cmd << 8; + // Serial.printf("t.addr:0x%X\r\n", t.addr); + if (len != 0) { + t.tx_buffer = dat; + t.length = 8 * len; + } else { + t.tx_buffer = NULL; + t.length = 0; + } + spi_device_polling_transmit(spi, &t); + TFT_CS_H; +#else + WriteComm(cmd); + if (len != 0) { + for (int i = 0; i < len; i++) + WriteData(dat[i]); + } +#endif +} + +void rm67162_init(void) +{ + pinMode(TFT_CS, OUTPUT); + pinMode(TFT_RES, OUTPUT); + + TFT_RES_L; + delay(300); + TFT_RES_H; + delay(200); + +#if LCD_USB_QSPI_DREVER == 1 + esp_err_t ret; + + spi_bus_config_t buscfg = { + .data0_io_num = TFT_QSPI_D0, + .data1_io_num = TFT_QSPI_D1, + .sclk_io_num = TFT_QSPI_SCK, + .data2_io_num = TFT_QSPI_D2, + .data3_io_num = TFT_QSPI_D3, + .max_transfer_sz = (SEND_BUF_SIZE * 16) + 8, + .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_GPIO_PINS /* | + SPICOMMON_BUSFLAG_QUAD */ + , + }; + spi_device_interface_config_t devcfg = { + .command_bits = 8, + .address_bits = 24, + .mode = TFT_SPI_MODE, + .clock_speed_hz = SPI_FREQUENCY, + .spics_io_num = -1, + // .spics_io_num = TFT_QSPI_CS, + .flags = SPI_DEVICE_HALFDUPLEX, + .queue_size = 17, + }; + ret = spi_bus_initialize(TFT_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO); + ESP_ERROR_CHECK(ret); + ret = spi_bus_add_device(TFT_SPI_HOST, &devcfg, &spi); + ESP_ERROR_CHECK(ret); + +#else + SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS); + SPI.setFrequency(SPI_FREQUENCY); + pinMode(TFT_DC, OUTPUT); +#endif + // Initialize the screen multiple times to prevent initialization failure + int i = 3; + while (i--) { +#if LCD_USB_QSPI_DREVER == 1 + const lcd_cmd_t *lcd_init = rm67162_qspi_init; + for (int i = 0; i < sizeof(rm67162_qspi_init) / sizeof(lcd_cmd_t); i++) +#else + const lcd_cmd_t *lcd_init = rm67162_spi_init; + for (int i = 0; i < sizeof(rm67162_spi_init) / sizeof(lcd_cmd_t); i++) +#endif + { + lcd_send_cmd(lcd_init[i].cmd, + (uint8_t *)lcd_init[i].data, + lcd_init[i].len & 0x7f); + + if (lcd_init[i].len & 0x80) + delay(120); + } + } + +} + +void lcd_setRotation(uint8_t r) +{ + uint8_t gbr = TFT_MAD_RGB; + + switch (r) { + case 0: // Portrait + // WriteData(gbr); + break; + case 1: // Landscape (Portrait + 90) + gbr = TFT_MAD_MX | TFT_MAD_MV | gbr; + break; + case 2: // Inverter portrait + gbr = TFT_MAD_MX | TFT_MAD_MY | gbr; + break; + case 3: // Inverted landscape + gbr = TFT_MAD_MV | TFT_MAD_MY | gbr; + break; + } + lcd_send_cmd(TFT_MADCTL, &gbr, 1); +} + +void lcd_address_set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) +{ + lcd_cmd_t t[3] = { + {0x2a, {uint8_t(x1 >> 8), (uint8_t)x1, (uint8_t)(x2 >> 8), (uint8_t) x2}, 0x04}, + {0x2b, {uint8_t(y1 >> 8), (uint8_t)y1, (uint8_t)(y2 >> 8), (uint8_t) y2}, 0x04}, + {0x2c, {0x00}, 0x00}, + }; + + for (uint32_t i = 0; i < 3; i++) { + lcd_send_cmd(t[i].cmd, t[i].data, t[i].len); + } +} + +void lcd_fill(uint16_t xsta, + uint16_t ysta, + uint16_t xend, + uint16_t yend, + uint16_t color) +{ + + uint16_t w = xend - xsta; + uint16_t h = yend - ysta; + uint16_t *color_p = (uint16_t *)ps_malloc(w * h * 2); + if (!color_p) { + return; + } + memset(color_p, color, w * h * 2); + lcd_PushColors(xsta, ysta, w, h, color_p); + free(color_p); +} + +void lcd_DrawPoint(uint16_t x, uint16_t y, uint16_t color) +{ + lcd_address_set(x, y, x + 1, y + 1); + lcd_PushColors(&color, 1); +} + +void lcd_PushColors(uint16_t x, + uint16_t y, + uint16_t width, + uint16_t high, + uint16_t *data) +{ +#if LCD_USB_QSPI_DREVER == 1 + bool first_send = 1; + size_t len = width * high; + uint16_t *p = (uint16_t *)data; + + lcd_address_set(x, y, x + width - 1, y + high - 1); + TFT_CS_L; + do { + size_t chunk_size = len; + spi_transaction_ext_t t = {0}; + memset(&t, 0, sizeof(t)); + if (first_send) { + t.base.flags = + SPI_TRANS_MODE_QIO /* | SPI_TRANS_MODE_DIOQIO_ADDR */; + t.base.cmd = 0x32 /* 0x12 */; + t.base.addr = 0x002C00; + first_send = 0; + } else { + t.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD | + SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY; + t.command_bits = 0; + t.address_bits = 0; + t.dummy_bits = 0; + } + if (chunk_size > SEND_BUF_SIZE) { + chunk_size = SEND_BUF_SIZE; + } + t.base.tx_buffer = p; + t.base.length = chunk_size * 16; + + // spi_device_queue_trans(spi, (spi_transaction_t *)&t, portMAX_DELAY); + spi_device_polling_transmit(spi, (spi_transaction_t *)&t); + len -= chunk_size; + p += chunk_size; + } while (len > 0); + TFT_CS_H; + +#else + lcd_address_set(x, y, x + width - 1, y + high - 1); + TFT_CS_L; + SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, TFT_SPI_MODE)); + TFT_DC_H; + SPI.writeBytes((uint8_t *)data, width * high * 2); + SPI.endTransaction(); + TFT_CS_H; +#endif +} + +void lcd_PushColors(uint16_t *data, uint32_t len) +{ +#if LCD_USB_QSPI_DREVER == 1 + bool first_send = 1; + uint16_t *p = (uint16_t *)data; + TFT_CS_L; + do { + size_t chunk_size = len; + spi_transaction_ext_t t = {0}; + memset(&t, 0, sizeof(t)); + if (first_send) { + t.base.flags = + SPI_TRANS_MODE_QIO /* | SPI_TRANS_MODE_DIOQIO_ADDR */; + t.base.cmd = 0x32 /* 0x12 */; + t.base.addr = 0x002C00; + first_send = 0; + } else { + t.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD | + SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY; + t.command_bits = 0; + t.address_bits = 0; + t.dummy_bits = 0; + } + if (chunk_size > SEND_BUF_SIZE) { + chunk_size = SEND_BUF_SIZE; + } + t.base.tx_buffer = p; + t.base.length = chunk_size * 16; + + // spi_device_queue_trans(spi, (spi_transaction_t *)&t, portMAX_DELAY); + spi_device_polling_transmit(spi, (spi_transaction_t *)&t); + len -= chunk_size; + p += chunk_size; + } while (len > 0); + TFT_CS_H; + +#else + TFT_CS_L; + SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, TFT_SPI_MODE)); + TFT_DC_H; + SPI.writeBytes((uint8_t *)data, len * 2); + SPI.endTransaction(); + TFT_CS_H; +#endif +} + +void lcd_sleep() +{ + lcd_send_cmd(0x10, NULL, 0); +} + +void lcd_on() +{ + lcd_send_cmd(0x29, NULL, 0x00); +} + +void lcd_off() +{ + lcd_send_cmd(0x28, NULL, 0x00); +} diff --git a/lib/rm67162/rm67162.h b/lib/rm67162/rm67162.h new file mode 100644 index 0000000..ce2d523 --- /dev/null +++ b/lib/rm67162/rm67162.h @@ -0,0 +1,57 @@ +#pragma once + +#include "stdint.h" +#include "pins_config.h" + +#define TFT_MADCTL 0x36 +#define TFT_MAD_MY 0x80 +#define TFT_MAD_MX 0x40 +#define TFT_MAD_MV 0x20 +#define TFT_MAD_ML 0x10 +#define TFT_MAD_BGR 0x08 +#define TFT_MAD_MH 0x04 +#define TFT_MAD_RGB 0x00 + +#define TFT_INVOFF 0x20 +#define TFT_INVON 0x21 + +#define TFT_SCK_H digitalWrite(TFT_SCK, 1); +#define TFT_SCK_L digitalWrite(TFT_SCK, 0); +#define TFT_SDA_H digitalWrite(TFT_MOSI, 1); +#define TFT_SDA_L digitalWrite(TFT_MOSI, 0); + +#define TFT_RES_H digitalWrite(TFT_RES, 1); +#define TFT_RES_L digitalWrite(TFT_RES, 0); +#define TFT_DC_H digitalWrite(TFT_DC, 1); +#define TFT_DC_L digitalWrite(TFT_DC, 0); +#define TFT_CS_H digitalWrite(TFT_CS, 1); +#define TFT_CS_L digitalWrite(TFT_CS, 0); + +typedef struct +{ + uint8_t cmd; + uint8_t data[4]; + uint8_t len; +} lcd_cmd_t; + +void rm67162_init(void); + +// Set the display window size +void lcd_address_set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); +void lcd_setRotation(uint8_t r); +void lcd_DrawPoint(uint16_t x, uint16_t y, uint16_t color); +void lcd_fill(uint16_t xsta, + uint16_t ysta, + uint16_t xend, + uint16_t yend, + uint16_t color); +void lcd_PushColors(uint16_t x, + uint16_t y, + uint16_t width, + uint16_t high, + uint16_t *data); +void lcd_PushColors(uint16_t *data, uint32_t len); +void lcd_sleep(); + +void lcd_on(); +void lcd_off(); \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index f33cba1..c6aac96 100644 --- a/platformio.ini +++ b/platformio.ini @@ -97,4 +97,21 @@ lib_deps = https://github.com/tzapu/WiFiManager.git mathertel/OneButton @ ^2.0.3 arduino-libraries/NTPClient - ;https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4 \ No newline at end of file + ;https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4 + +[env:NerminerV2-S3-AMOLED] +platform = espressif32 +board = lilygo-t-display-s3 +framework = arduino + +build_flags = + -DNERMINER_S3_AMOLED + -DBOARD_HAS_PSRAM + -DARDUINO_USB_CDC_ON_BOOT +lib_deps = + https://github.com/takkaO/OpenFontRender + bblanchon/ArduinoJson@^6.21.2 + https://github.com/tzapu/WiFiManager.git + mathertel/OneButton @ ^2.0.3 + arduino-libraries/NTPClient + https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4 diff --git a/src/NerdMinerV2.ino.cpp b/src/NerdMinerV2.ino.cpp index c0ebf37..e44556f 100644 --- a/src/NerdMinerV2.ino.cpp +++ b/src/NerdMinerV2.ino.cpp @@ -4,19 +4,13 @@ #include #include #include -#include // Graphics and font library #include #include "mbedtls/md.h" -#include "media/images.h" -#include "media/myFonts.h" -#include "media/Free_Fonts.h" -#include "OpenFontRender.h" #include "wManager.h" #include "mining.h" #include "monitor.h" - -#define CURRENT_VERSION "V1.6.1" +#include "display/display.h" //3 seconds WDT #define WDT_TIMEOUT 3 @@ -26,34 +20,15 @@ OneButton button1(PIN_BUTTON_1); OneButton button2(PIN_BUTTON_2); -OpenFontRender render; extern monitor_data mMonitor; /**********************⚡ GLOBAL Vars *******************************/ -TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h -TFT_eSprite background = TFT_eSprite(&tft); // Invoke library sprite unsigned long start = millis(); const char* ntpServer = "pool.ntp.org"; //void runMonitor(void *name); -void alternate_screen_state() { - #ifdef NERDMINERV2 - int screen_state= digitalRead(TFT_BL); - //Serial.printf("Screen state is '%s', switching to '%s'", screen_state, !screen_state); - Serial.println("Switching display state"); - digitalWrite(TFT_BL, !screen_state); - #endif -} - -void alternate_screen_rotation() { - tft.getRotation() == 1 ? tft.setRotation(3) : tft.setRotation(1); - -} - - - /********* INIT *****/ void setup() { @@ -67,14 +42,14 @@ void setup() //disableCore1WDT(); // Setup the buttons - #ifdef NERDMINERV2 + #if defined(NERDMINERV2) || defined(NERMINER_S3_AMOLED) // Button 1 (Boot) button1.setPressTicks(5000); - button1.attachClick(alternate_screen_state); - button1.attachDoubleClick(alternate_screen_rotation); + button1.attachClick(alternateScreenState); + button1.attachDoubleClick(alternateScreenRotation); // Button 2 (GPIO14) button2.setPressTicks(5000); - button2.attachClick(changeScreen); + button2.attachClick(switchToNextScreen); button2.attachLongPressStart(reset_configurations); #elif defined(DEVKITV1) //Standard ESP32-devKit @@ -89,28 +64,11 @@ void setup() /******** INIT NERDMINER ************/ Serial.println("NerdMiner v2 starting......"); - /******** INIT DISPLAY ************/ - tft.init(); - tft.setRotation(1); - tft.setSwapBytes(true);// Swap the colour byte order when rendering - background.createSprite(initWidth,initHeight); //Background Sprite - background.setSwapBytes(true); - render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background) - render.setLineSpaceRatio(0.9); //Espaciado entre texto - - // Load the font and check it can be read OK - //if (render.loadFont(NotoSans_Bold, sizeof(NotoSans_Bold))) { - if (render.loadFont(DigitalNumbers, sizeof(DigitalNumbers))){ - Serial.println("Initialise error"); - return; - } + initDisplay(); /******** PRINT INIT SCREEN *****/ - tft.fillScreen(TFT_BLACK); - tft.pushImage(0, 0, initWidth, initHeight, initScreen); - tft.setTextColor(TFT_BLACK); - tft.drawString(CURRENT_VERSION, 24, 147, FONT2); + drawLoadingScreen(); delay(2000); /******** SHOW LED INIT STATUS (devices without screen) *****/ diff --git a/src/display/display.cpp b/src/display/display.cpp new file mode 100644 index 0000000..db5b80b --- /dev/null +++ b/src/display/display.cpp @@ -0,0 +1,54 @@ +#include "display.h" + +#ifdef NO_DISPLAY +DisplayDriver *currentDisplayDriver = &noDisplayDriver; +#endif + +#ifdef T_DISPLAY +DisplayDriver *currentDisplayDriver = &tDisplayDriver; +#endif + +#ifdef AMOLED_DISPLAY +DisplayDriver *currentDisplayDriver = &amoledDisplayDriver; +#endif + +// Initialize the display +void initDisplay() { + currentDisplayDriver->initDisplay(); +} + +// Alternate screen state +void alternateScreenState() { + currentDisplayDriver->alternateScreenState(); +} + +// Alternate screen rotation +void alternateScreenRotation() { + currentDisplayDriver->alternateScreenRotation(); +} + +// Draw the loading screen +void drawLoadingScreen() { + currentDisplayDriver->loadingScreen(); +} + +// Draw the setup screen +void drawSetupScreen() { + currentDisplayDriver->setupScreen(); +} + +// Reset the current cyclic screen to the first one +void resetToFirstScreen() { + currentDisplayDriver->current_cyclic_screen = 0; +} + +// Switches to the next cyclic screen without drawing it +void switchToNextScreen() { + currentDisplayDriver->current_cyclic_screen = (currentDisplayDriver->current_cyclic_screen + 1) % currentDisplayDriver->num_cyclic_screens; +} + +// Draw the current cyclic screen +void drawCurrentScreen(unsigned long mElapsed) { + currentDisplayDriver->cyclic_screens[currentDisplayDriver->current_cyclic_screen](mElapsed); +} + diff --git a/src/display/display.h b/src/display/display.h new file mode 100644 index 0000000..3c03a6f --- /dev/null +++ b/src/display/display.h @@ -0,0 +1,17 @@ +#ifndef DISPLAY_H +#define DISPLAY_H + +#include "drivers.h" + +extern DisplayDriver *currentDisplayDriver; + +void initDisplay(); +void alternateScreenState(); +void alternateScreenRotation(); +void switchToNextScreen(); +void resetToFirstScreen(); +void drawLoadingScreen(); +void drawSetupScreen(); +void drawCurrentScreen(unsigned long mElapsed); + +#endif // DISPLAY_H diff --git a/src/display/drivers.h b/src/display/drivers.h new file mode 100644 index 0000000..663270a --- /dev/null +++ b/src/display/drivers.h @@ -0,0 +1,38 @@ +#ifndef DRIVERS_H +#define DRIVERS_H + +#if defined(DEVKITV1) + #define NO_DISPLAY +#elif defined(NERMINER_S3_AMOLED) + #define AMOLED_DISPLAY +#else + #define T_DISPLAY +#endif + +typedef void (*AlternateFunction)(void); +typedef void (*DriverInitFunction)(void); +typedef void (*ScreenFunction)(void); +typedef void (*CyclicScreenFunction)(unsigned long mElapsed); + +typedef struct { + DriverInitFunction initDisplay; // Initialize the display + AlternateFunction alternateScreenState; // Alternate screen state + AlternateFunction alternateScreenRotation; // Alternate screen rotation + ScreenFunction loadingScreen; // Explicit loading screen + ScreenFunction setupScreen; // Explicit setup screen + CyclicScreenFunction *cyclic_screens; // Array of cyclic screens + int num_cyclic_screens; // Number of cyclic screens + int current_cyclic_screen; // Current cyclic screen being displayed + int screenWidth; // Screen width + int screenHeight; // Screen height +} DisplayDriver; + +extern DisplayDriver *currentDisplayDriver; + +extern DisplayDriver noDisplayDriver; +extern DisplayDriver tDisplayDriver; +extern DisplayDriver amoledDisplayDriver; + +#define SCREENS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +#endif // DRIVERS_H diff --git a/src/display/drivers/amoledDisplayDriver.cpp b/src/display/drivers/amoledDisplayDriver.cpp new file mode 100644 index 0000000..51e418a --- /dev/null +++ b/src/display/drivers/amoledDisplayDriver.cpp @@ -0,0 +1,221 @@ +#include "../drivers.h" + +#ifdef AMOLED_DISPLAY + +#include +#include +#include "media/images.h" +#include "media/myFonts.h" +#include "media/Free_Fonts.h" +#include "version.h" +#include "monitor.h" +#include "OpenFontRender.h" + +#define WIDTH 536 +#define HEIGHT 240 + +OpenFontRender render; +TFT_eSPI tft = TFT_eSPI(); +TFT_eSprite background = TFT_eSprite(&tft); + +void amoledDisplay_Init(void) { + rm67162_init(); + lcd_setRotation(1); + + background.createSprite(WIDTH, HEIGHT); + background.setSwapBytes(true); + render.setDrawer(background); + render.setLineSpaceRatio(0.9); + + if (render.loadFont(DigitalNumbers, sizeof(DigitalNumbers))){ + Serial.println("Initialise error"); + return; + } +} + +int screen_state= 1; +void amoledDisplay_AlternateScreenState(void) { + screen_state == 1 ? lcd_off() : lcd_on(); + screen_state ^= 1; +} + +int screen_rotation = 1; +void amoledDisplay_AlternateRotation(void) { + screen_rotation == 1 ? lcd_setRotation(3) : lcd_setRotation(1); + screen_rotation ^= 1; +} + +void amoledDisplay_MinerScreen(unsigned long mElapsed) { + mining_data data = getMiningData(mElapsed); + + //Print background screen + background.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen); + + Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", + data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); + + //Hashrate + render.setFontSize(35); + render.setCursor(19, 118); + render.setFontColor(TFT_BLACK); + + render.rdrawString(data.currentHashRate.c_str(), 118, 114, TFT_BLACK); + //Total hashes + render.setFontSize(18); + render.rdrawString(data.totalMHashes.c_str(), 268, 138, TFT_BLACK); + //Block templates + render.setFontSize(18); + render.drawString(data.templates.c_str(), 186, 20, 0xDEDB); + //Best diff + render.drawString(data.bestDiff.c_str(), 186, 48, 0xDEDB); + //32Bit shares + render.setFontSize(18); + render.drawString(data.completedShares.c_str(), 186, 76, 0xDEDB); + //Hores + render.setFontSize(14); + render.rdrawString(data.timeMining.c_str(), 315, 104, 0xDEDB); + + //Valid Blocks + render.setFontSize(24); + render.drawString(data.valids.c_str(), 285, 56, 0xDEDB); + + //Print Temp + render.setFontSize(10); + render.rdrawString(data.temp.c_str(), 239, 1, TFT_BLACK); + + render.setFontSize(4); + render.rdrawString(String(0).c_str(), 244, 3, TFT_BLACK); + + //Print Hour + render.setFontSize(10); + render.rdrawString(data.currentTime.c_str(), 286, 1, TFT_BLACK); + + //Push prepared background to screen + lcd_PushColors(0, 0, WIDTH, HEIGHT, (uint16_t *)background.getPointer()); +} + +void amoledDisplay_ClockScreen(unsigned long mElapsed) { + clock_data data = getClockData(mElapsed); + + //Print background screen + background.pushImage(0, 0, minerClockWidth, minerClockHeight, minerClockScreen); + + Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", + data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); + + //Hashrate + render.setFontSize(25); + render.setCursor(19, 122); + render.setFontColor(TFT_BLACK); + render.rdrawString(data.currentHashRate.c_str(), 94, 129, TFT_BLACK); + + //Print BTC Price + background.setFreeFont(FSSB9); + background.setTextSize(1); + background.setTextDatum(TL_DATUM); + background.setTextColor(TFT_BLACK); + background.drawString(data.btcPrice.c_str(), 202, 3, GFXFF); + + //Print BlockHeight + render.setFontSize(18); + render.rdrawString(data.blockHeight.c_str(), 254, 140, TFT_BLACK); + + //Print Hour + background.setFreeFont(FF23); + background.setTextSize(2); + background.setTextColor(0xDEDB, TFT_BLACK); + + background.drawString(data.currentTime.c_str(), 130, 50, GFXFF); + + //Push prepared background to screen + lcd_PushColors(0, 0, WIDTH, HEIGHT, (uint16_t *)background.getPointer()); +} + +void amoledDisplay_GlobalHashScreen(unsigned long mElapsed) { + coin_data data = getCoinData(mElapsed); + + //Print background screen + background.pushImage(0, 0, globalHashWidth, globalHashHeight, globalHashScreen); + + Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", + data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); + + //Print BTC Price + background.setFreeFont(FSSB9); + background.setTextSize(1); + background.setTextDatum(TL_DATUM); + background.setTextColor(TFT_BLACK); + background.drawString(data.btcPrice.c_str(), 198, 3, GFXFF); + + //Print Hour + background.setFreeFont(FSSB9); + background.setTextSize(1); + background.setTextDatum(TL_DATUM); + background.setTextColor(TFT_BLACK); + background.drawString(data.currentTime.c_str(), 268, 3, GFXFF); + + //Print Last Pool Block + background.setFreeFont(FSS9); + background.setTextDatum(TR_DATUM); + background.setTextColor(0x9C92); + background.drawString(data.halfHourFee.c_str(), 302, 52, GFXFF); + + //Print Difficulty + background.setFreeFont(FSS9); + background.setTextDatum(TR_DATUM); + background.setTextColor(0x9C92); + background.drawString(data.netwrokDifficulty.c_str(), 302, 88, GFXFF); + + //Print Global Hashrate + render.setFontSize(17); + render.rdrawString(data.globalHashRate.c_str(), 274, 145, TFT_BLACK); + + //Print BlockHeight + render.setFontSize(28); + render.rdrawString(data.blockHeight.c_str(), 140, 104, 0xDEDB); + + //Draw percentage rectangle + int x2 = 2 + (138*data.progressPercent/100); + background.fillRect(2, 149, x2, 168, 0xDEDB); + + //Print Remaining BLocks + background.setTextFont(FONT2); + background.setTextSize(1); + background.setTextDatum(MC_DATUM); + background.setTextColor(TFT_BLACK); + background.drawString(data.remainingBlocks.c_str(), 72, 159, FONT2); + + //Push prepared background to screen + lcd_PushColors(0, 0, WIDTH, HEIGHT, (uint16_t *)background.getPointer()); +} + +void amoledDisplay_LoadingScreen(void) { + background.fillScreen(TFT_BLACK); + background.pushImage(0, 0, initWidth, initHeight, initScreen); + background.setTextColor(TFT_BLACK); + background.drawString(CURRENT_VERSION, 24, 147, FONT2); + + lcd_PushColors(0, 0, WIDTH, HEIGHT, (uint16_t *)background.getPointer()); +} + +void amoledDisplay_SetupScreen(void) { + background.pushImage(0, 0, setupModeWidth, setupModeHeight, setupModeScreen); + + lcd_PushColors(0, 0, WIDTH, HEIGHT, (uint16_t *)background.getPointer()); +} + +CyclicScreenFunction amoledDisplayCyclicScreens[] = { amoledDisplay_MinerScreen, amoledDisplay_ClockScreen, amoledDisplay_GlobalHashScreen }; + +DisplayDriver amoledDisplayDriver = { + amoledDisplay_Init, + amoledDisplay_AlternateScreenState, + amoledDisplay_AlternateRotation, + amoledDisplay_LoadingScreen, + amoledDisplay_SetupScreen, + amoledDisplayCyclicScreens, + SCREENS_ARRAY_SIZE(amoledDisplayCyclicScreens), + 0, + WIDTH, + HEIGHT +}; +#endif \ No newline at end of file diff --git a/src/display/drivers/noDisplayDriver.cpp b/src/display/drivers/noDisplayDriver.cpp new file mode 100644 index 0000000..a16f497 --- /dev/null +++ b/src/display/drivers/noDisplayDriver.cpp @@ -0,0 +1,55 @@ +#include "../drivers.h" + +#ifdef NO_DISPLAY + +#include +#include "monitor.h" + +void noDisplay_Init(void) { + Serial.println("No display driver initialized"); +} + +void noDisplay_AlternateScreenState(void) { +} + +void noDisplay_AlternateRotation(void) { +} + +void noDisplay_NoScreen(unsigned long mElapsed) { + mining_data data = getMiningData(mElapsed); + + //Print hashrate to serial + Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", + data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); + + //Print extended data to serial for no display devices + // Serial.printf(">>> Valid blocks: %s\n", data.valids.c_str()); + // Serial.printf(">>> Block templates: %s\n", data.templates.c_str()); + // Serial.printf(">>> Best difficulty: %s\n", data.bestDiff.c_str()); + // Serial.printf(">>> 32Bit shares: %s\n", data.completedShares.c_str()); + // Serial.printf(">>> Temperature: %s\n", data.temp.c_str()); + // Serial.printf(">>> Total MHashes: %s\n", data.totalMHashes.c_str()); + // Serial.printf(">>> Time mining: %s\n", data.timeMining.c_str()); +} +void noDisplay_LoadingScreen(void) { + Serial.println("Initializing..."); + } +void noDisplay_SetupScreen(void) { + Serial.println("Setup..."); + } + +CyclicScreenFunction noDisplayCyclicScreens[] = { noDisplay_NoScreen }; + +DisplayDriver noDisplayDriver = { + noDisplay_Init, + noDisplay_AlternateScreenState, + noDisplay_AlternateRotation, + noDisplay_LoadingScreen, + noDisplay_SetupScreen, + noDisplayCyclicScreens, + SCREENS_ARRAY_SIZE(noDisplayCyclicScreens), + 0, + 0, + 0, +}; +#endif \ No newline at end of file diff --git a/src/display/drivers/tDisplayDriver.cpp b/src/display/drivers/tDisplayDriver.cpp new file mode 100644 index 0000000..085c683 --- /dev/null +++ b/src/display/drivers/tDisplayDriver.cpp @@ -0,0 +1,216 @@ +#include "../drivers.h" + +#ifdef T_DISPLAY + +#include +#include "media/images.h" +#include "media/myFonts.h" +#include "media/Free_Fonts.h" +#include "version.h" +#include "monitor.h" +#include "OpenFontRender.h" + +#define WIDTH 340 +#define HEIGHT 170 + +OpenFontRender render; +TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h +TFT_eSprite background = TFT_eSprite(&tft); // Invoke library sprite + +void smoledDisplay_Init(void) { + tft.init(); + tft.setRotation(1); + tft.setSwapBytes(true);// Swap the colour byte order when rendering + background.createSprite(WIDTH, HEIGHT); //Background Sprite + background.setSwapBytes(true); + render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background) + render.setLineSpaceRatio(0.9); //Espaciado entre texto + + // Load the font and check it can be read OK + //if (render.loadFont(NotoSans_Bold, sizeof(NotoSans_Bold))) { + if (render.loadFont(DigitalNumbers, sizeof(DigitalNumbers))){ + Serial.println("Initialise error"); + return; + } +} + +void tDisplay_AlternateScreenState(void) { + int screen_state= digitalRead(TFT_BL); + Serial.println("Switching display state"); + digitalWrite(TFT_BL, !screen_state); +} + +void tDisplay_AlternateRotation(void) { + tft.getRotation() == 1 ? tft.setRotation(3) : tft.setRotation(1); +} + +void tDisplay_MinerScreen(unsigned long mElapsed) { + mining_data data = getMiningData(mElapsed); + + //Print background screen + background.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen); + + Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", + data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); + + //Hashrate + render.setFontSize(35); + render.setCursor(19, 118); + render.setFontColor(TFT_BLACK); + + render.rdrawString(data.currentHashRate.c_str(), 118, 114, TFT_BLACK); + //Total hashes + render.setFontSize(18); + render.rdrawString(data.totalMHashes.c_str(), 268, 138, TFT_BLACK); + //Block templates + render.setFontSize(18); + render.drawString(data.templates.c_str(), 186, 20, 0xDEDB); + //Best diff + render.drawString(data.bestDiff.c_str(), 186, 48, 0xDEDB); + //32Bit shares + render.setFontSize(18); + render.drawString(data.completedShares.c_str(), 186, 76, 0xDEDB); + //Hores + render.setFontSize(14); + render.rdrawString(data.timeMining.c_str(), 315, 104, 0xDEDB); + + //Valid Blocks + render.setFontSize(24); + render.drawString(data.valids.c_str(), 285, 56, 0xDEDB); + + //Print Temp + render.setFontSize(10); + render.rdrawString(data.temp.c_str(), 239, 1, TFT_BLACK); + + render.setFontSize(4); + render.rdrawString(String(0).c_str(), 244, 3, TFT_BLACK); + + //Print Hour + render.setFontSize(10); + render.rdrawString(data.currentTime.c_str(), 286, 1, TFT_BLACK); + + //Push prepared background to screen + background.pushSprite(0,0); +} + +void tDisplay_ClockScreen(unsigned long mElapsed) { + clock_data data = getClockData(mElapsed); + + //Print background screen + background.pushImage(0, 0, minerClockWidth, minerClockHeight, minerClockScreen); + + Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", + data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); + + //Hashrate + render.setFontSize(25); + render.setCursor(19, 122); + render.setFontColor(TFT_BLACK); + render.rdrawString(data.currentHashRate.c_str(), 94, 129, TFT_BLACK); + + //Print BTC Price + background.setFreeFont(FSSB9); + background.setTextSize(1); + background.setTextDatum(TL_DATUM); + background.setTextColor(TFT_BLACK); + background.drawString(data.btcPrice.c_str(), 202, 3, GFXFF); + + //Print BlockHeight + render.setFontSize(18); + render.rdrawString(data.blockHeight.c_str(), 254, 140, TFT_BLACK); + + //Print Hour + background.setFreeFont(FF23); + background.setTextSize(2); + background.setTextColor(0xDEDB, TFT_BLACK); + + background.drawString(data.currentTime.c_str(), 130, 50, GFXFF); + + //Push prepared background to screen + background.pushSprite(0,0); +} + +void tDisplay_GlobalHashScreen(unsigned long mElapsed) { + coin_data data = getCoinData(mElapsed); + + //Print background screen + background.pushImage(0, 0, globalHashWidth, globalHashHeight, globalHashScreen); + + Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", + data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); + + //Print BTC Price + background.setFreeFont(FSSB9); + background.setTextSize(1); + background.setTextDatum(TL_DATUM); + background.setTextColor(TFT_BLACK); + background.drawString(data.btcPrice.c_str(), 198, 3, GFXFF); + + //Print Hour + background.setFreeFont(FSSB9); + background.setTextSize(1); + background.setTextDatum(TL_DATUM); + background.setTextColor(TFT_BLACK); + background.drawString(data.currentTime.c_str(), 268, 3, GFXFF); + + //Print Last Pool Block + background.setFreeFont(FSS9); + background.setTextDatum(TR_DATUM); + background.setTextColor(0x9C92); + background.drawString(data.halfHourFee.c_str(), 302, 52, GFXFF); + + //Print Difficulty + background.setFreeFont(FSS9); + background.setTextDatum(TR_DATUM); + background.setTextColor(0x9C92); + background.drawString(data.netwrokDifficulty.c_str(), 302, 88, GFXFF); + + //Print Global Hashrate + render.setFontSize(17); + render.rdrawString(data.globalHashRate.c_str(), 274, 145, TFT_BLACK); + + //Print BlockHeight + render.setFontSize(28); + render.rdrawString(data.blockHeight.c_str(), 140, 104, 0xDEDB); + + //Draw percentage rectangle + int x2 = 2 + (138*data.progressPercent/100); + background.fillRect(2, 149, x2, 168, 0xDEDB); + + //Print Remaining BLocks + background.setTextFont(FONT2); + background.setTextSize(1); + background.setTextDatum(MC_DATUM); + background.setTextColor(TFT_BLACK); + background.drawString(data.remainingBlocks.c_str(), 72, 159, FONT2); + + //Push prepared background to screen + background.pushSprite(0,0); +} + +void tDisplay_LoadingScreen(void) { + tft.fillScreen(TFT_BLACK); + tft.pushImage(0, 0, initWidth, initHeight, initScreen); + tft.setTextColor(TFT_BLACK); + tft.drawString(CURRENT_VERSION, 24, 147, FONT2); +} + +void tDisplay_SetupScreen(void) { + tft.pushImage(0, 0, setupModeWidth, setupModeHeight, setupModeScreen); +} + +CyclicScreenFunction tDisplayCyclicScreens[] = { tDisplay_MinerScreen, tDisplay_ClockScreen, tDisplay_GlobalHashScreen }; + +DisplayDriver tDisplayDriver = { + smoledDisplay_Init, + tDisplay_AlternateScreenState, + tDisplay_AlternateRotation, + tDisplay_LoadingScreen, + tDisplay_SetupScreen, + tDisplayCyclicScreens, + SCREENS_ARRAY_SIZE(tDisplayCyclicScreens), + 0, + WIDTH, + HEIGHT +}; +#endif \ No newline at end of file diff --git a/src/mining.cpp b/src/mining.cpp index 98d1ed8..61b77b6 100644 --- a/src/mining.cpp +++ b/src/mining.cpp @@ -2,16 +2,13 @@ #include #include #include -#include // Graphics and font library for ILI9341 driver chip #include "ShaTests/nerdSHA256.h" //#include "ShaTests/nerdSHA256plus.h" -#include "media/Free_Fonts.h" -#include "media/images.h" -#include "OpenFontRender.h" #include "stratum.h" #include "mining.h" #include "utils.h" #include "monitor.h" +#include "display/display.h" unsigned long templates = 0; unsigned long hashes= 0; @@ -31,9 +28,6 @@ extern int portNumber; extern char btcString[80]; IPAddress serverIP(1, 1, 1, 1); //Temporally save poolIPaddres -extern OpenFontRender render; -extern TFT_eSprite background; - //Global work data static WiFiClient client; static miner_data mMiner; //Global miner data (Create a miner class TODO) @@ -383,11 +377,8 @@ void runMonitor(void *name){ Serial.println("[MONITOR] started"); unsigned long mLastCheck = 0; - mMonitor.screen = SCREEN_MINING; - - #ifdef DEVKITV1 - mMonitor.screen = NO_SCREEN; - #endif + + resetToFirstScreen(); while(1){ @@ -398,12 +389,7 @@ void runMonitor(void *name){ elapsedKHs = currentKHashes - totalKHashes; totalKHashes = currentKHashes; - switch(mMonitor.screen){ - case SCREEN_MINING: show_MinerScreen(mElapsed); break; - case SCREEN_CLOCK: show_ClockScreen(mElapsed); break; - case SCREEN_GLOBAL: show_GlobalHashScreen(mElapsed); break; - case NO_SCREEN: show_NoScreen(mElapsed); break; - } + drawCurrentScreen(mElapsed); //Monitor state when hashrate is 0.0 if(elapsedKHs == 0) { diff --git a/src/monitor.cpp b/src/monitor.cpp index 02f3033..b2e0634 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -1,10 +1,6 @@ #include #include -#include // Graphics and font library for ILI9341 driver chip -#include "media/Free_Fonts.h" -#include "media/images.h" #include "mbedtls/md.h" -#include "OpenFontRender.h" #include "HTTPClient.h" #include #include @@ -24,8 +20,6 @@ extern unsigned int valids; // increased if blockhash <= target extern double best_diff; // track best diff -extern OpenFontRender render; -extern TFT_eSprite background; extern monitor_data mMonitor; extern int GMTzone; //Gotten from saved config @@ -215,213 +209,6 @@ String getTime(void){ return LocalHour; } -void changeScreen(void){ - mMonitor.screen++; - if(mMonitor.screen> SCREEN_GLOBAL) mMonitor.screen = SCREEN_MINING; -} - -void show_NoScreen(unsigned long mElapsed){ - char CurrentHashrate[10] = {0}; - sprintf(CurrentHashrate, "%.2f", (1.0*(elapsedKHs*1000))/mElapsed); - - //Print hashrate to serial - Serial.printf(">>> Completed %d share(s), %d Khashes, avg. hashrate %s KH/s\n", - shares, totalKHashes, CurrentHashrate); -} - -void show_MinerScreen(unsigned long mElapsed){ - - //Print background screen - background.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen); - - char CurrentHashrate[10] = {0}; - sprintf(CurrentHashrate, "%.2f", (1.0*(elapsedKHs*1000))/mElapsed); - - //Serial.println("[runMonitor Task] -> Printing results on screen "); - - Serial.printf(">>> Completed %d share(s), %d Khashes, avg. hashrate %s KH/s\n", - shares, totalKHashes, CurrentHashrate); - - //Hashrate - render.setFontSize(35); - render.setCursor(19, 118); - render.setFontColor(TFT_BLACK); - - render.rdrawString(CurrentHashrate, 118, 114, TFT_BLACK); - //Total hashes - render.setFontSize(18); - render.rdrawString(String(Mhashes).c_str(), 268, 138, TFT_BLACK); - //Block templates - render.setFontSize(18); - render.drawString(String(templates).c_str(), 186, 20, 0xDEDB); - //Best diff - char best_diff_string[16] = {0}; - suffix_string(best_diff, best_diff_string, 16, 0); - render.setFontSize(18); - render.drawString(String(best_diff_string).c_str(), 186, 48, 0xDEDB); - //32Bit shares - render.setFontSize(18); - render.drawString(String(shares).c_str(), 186, 76, 0xDEDB); - //Hores - char timeMining[15]; - - unsigned long secElapsed = millis() / 1000; - int days = secElapsed / 86400; - int hours = (secElapsed - (days * 86400)) / 3600; //Number of seconds in an hour - int mins = (secElapsed - (days * 86400) - (hours * 3600)) / 60; //Remove the number of hours and calculate the minutes. - int secs = secElapsed - (days * 86400) - (hours * 3600) - (mins * 60); - sprintf(timeMining, "%01d %02d:%02d:%02d", days, hours, mins, secs); - render.setFontSize(14); - render.rdrawString(String(timeMining).c_str(), 315, 104, 0xDEDB); - - //Valid Blocks - render.setFontSize(24); - render.drawString(String(valids).c_str(), 285, 56, 0xDEDB); - - //Print Temp - String temp = String(temperatureRead(), 0); - render.setFontSize(10); - render.rdrawString(String(temp).c_str(), 239, 1, TFT_BLACK); - - render.setFontSize(4); - render.rdrawString(String(0).c_str(), 244, 3, TFT_BLACK); - - //Print Hour - render.setFontSize(10); - render.rdrawString(getTime().c_str(), 286, 1, TFT_BLACK); - - // pool url - /*background.setTextSize(1); - background.setTextDatum(MC_DATUM); - background.setTextColor(0xDEDB); - background.drawString(String(poolString), 59, 85, FONT2);*/ - - //Push prepared background to screen - background.pushSprite(0,0); -} - - -void show_ClockScreen(unsigned long mElapsed){ - - //Print background screen - background.pushImage(0, 0, minerClockWidth, minerClockHeight, minerClockScreen); - - char CurrentHashrate[10] = {0}; - sprintf(CurrentHashrate, "%.2f", (1.0*(elapsedKHs*1000))/mElapsed); - - //Serial.println("[runMonitor Task] -> Printing results on screen "); - - Serial.printf(">>> Completed %d share(s), %d Khashes, avg. hashrate %s KH/s\n", - shares, totalKHashes, CurrentHashrate); - - //Hashrate - render.setFontSize(25); - render.setCursor(19, 122); - render.setFontColor(TFT_BLACK); - - render.rdrawString(CurrentHashrate, 94, 129, TFT_BLACK); - - //Print BTC Price - //render.setFontSize(22); - //render.drawString(getBTCprice().c_str(), 202, 3, TFT_BLACK); - background.setFreeFont(FSSB9); - background.setTextSize(1); - background.setTextDatum(TL_DATUM); - background.setTextColor(TFT_BLACK); - background.drawString(getBTCprice().c_str(), 202, 3, GFXFF); - - //Print BlockHeight - render.setFontSize(18); - render.rdrawString(getBlockHeight().c_str(), 254, 140, TFT_BLACK); - - //Print Hour - background.setFreeFont(FF23); - background.setTextSize(2); - background.setTextColor(0xDEDB, TFT_BLACK); - - //background.setTexSize(2); - background.drawString(getTime().c_str(), 130, 50, GFXFF); - //render.setFontColor(TFT_WHITE); - //render.setFontSize(110); - //render.rdrawString(getTime().c_str(), 290, 40, TFT_WHITE); - - //Push prepared background to screen - background.pushSprite(0,0); -} - -void show_GlobalHashScreen(unsigned long mElapsed){ - - //Print background screen - background.pushImage(0, 0, globalHashWidth, globalHashHeight, globalHashScreen); - - char CurrentHashrate[10] = {0}; - sprintf(CurrentHashrate, "%.2f", (1.0*(elapsedKHs*1000))/mElapsed); - - //Serial.println("[runMonitor Task] -> Printing results on screen "); - - Serial.printf(">>> Completed %d share(s), %d Khashes, avg. hashrate %s KH/s\n", - shares, totalKHashes, CurrentHashrate); - - //Hashrate - updateGlobalData(); //Update gData vars asking mempool APIs - - //Print BTC Price - background.setFreeFont(FSSB9); - background.setTextSize(1); - background.setTextDatum(TL_DATUM); - background.setTextColor(TFT_BLACK); - background.drawString(getBTCprice().c_str(), 198, 3, GFXFF); - - //Print Hour - background.setFreeFont(FSSB9); - background.setTextSize(1); - background.setTextDatum(TL_DATUM); - background.setTextColor(TFT_BLACK); - background.drawString(getTime().c_str(), 268, 3, GFXFF); - - //Print Last Pool Block - background.setFreeFont(FSS9); - background.setTextDatum(TR_DATUM); - background.setTextColor(0x9C92); - String temp = String(gData.halfHourFee) + " sat/vB"; - background.drawString(temp.c_str(), 302, 52, GFXFF); - - //Print Difficulty - background.setFreeFont(FSS9); - background.setTextDatum(TR_DATUM); - background.setTextColor(0x9C92); - background.drawString(gData.difficulty.c_str(), 302, 88, GFXFF); - - //Print Global Hashrate - render.setFontSize(17); - render.rdrawString(gData.globalHash.c_str(), 274, 145, TFT_BLACK); - - //Print BlockHeight - render.setFontSize(28); - gData.currentBlock = getBlockHeight(); - render.rdrawString(gData.currentBlock.c_str(), 140, 104, 0xDEDB); - - //Draw percentage rectangle - //width percent bar 140 - 2 - unsigned long cBlock = gData.currentBlock.toInt(); - gData.remainingBlocks = (((cBlock / HALVING_BLOCKS)+1) * HALVING_BLOCKS) - cBlock; - gData.progressPercent = (HALVING_BLOCKS-gData.remainingBlocks)*100/HALVING_BLOCKS; - int x2 = 2 + (138*gData.progressPercent/100); - background.fillRect(2, 149, x2, 168, 0xDEDB); - - //Print Remaining BLocks - //background.setFreeFont(FSSB9); - background.setTextFont(FONT2); - background.setTextSize(1); - background.setTextDatum(MC_DATUM); - background.setTextColor(TFT_BLACK); - temp = String(gData.remainingBlocks) + " BLOCKS"; - background.drawString(temp.c_str(), 72, 159, FONT2);//GFXFF); - - //Push prepared background to screen - background.pushSprite(0,0); -} - // Variables para controlar el parpadeo con millis() unsigned long previousMillis = 0; @@ -446,4 +233,72 @@ void doLedStuff(int ledPin){ } break; } +} + +String getCurrentHashRate(unsigned long mElapsed){ + return String((1.0 * (elapsedKHs * 1000)) / mElapsed, 2); +} + +mining_data getMiningData(unsigned long mElapsed){ + mining_data data; + + char best_diff_string[16] = {0}; + suffix_string(best_diff, best_diff_string, 16, 0); + + char timeMining[15] = {0}; + unsigned long secElapsed = millis() / 1000; + int days = secElapsed / 86400; + int hours = (secElapsed - (days * 86400)) / 3600; //Number of seconds in an hour + int mins = (secElapsed - (days * 86400) - (hours * 3600)) / 60; //Remove the number of hours and calculate the minutes. + int secs = secElapsed - (days * 86400) - (hours * 3600) - (mins * 60); + sprintf(timeMining, "%01d %02d:%02d:%02d", days, hours, mins, secs); + + data.completedShares = shares; + data.totalMHashes = Mhashes; + data.totalKHashes = totalKHashes; + data.currentHashRate = getCurrentHashRate(mElapsed); + data.templates = templates; + data.bestDiff = best_diff_string; + data.timeMining = timeMining; + data.valids = valids; + data.temp = String(temperatureRead(), 0); + data.currentTime = getTime(); + + return data; +} + +clock_data getClockData(unsigned long mElapsed){ + clock_data data; + + data.completedShares = shares; + data.totalKHashes = totalKHashes; + data.currentHashRate = getCurrentHashRate(mElapsed); + data.btcPrice = getBTCprice(); + data.blockHeight = getBlockHeight(); + data.currentTime = getTime(); + + return data; +} + +coin_data getCoinData(unsigned long mElapsed){ + coin_data data; + + updateGlobalData(); //Update gData vars asking mempool APIs + + data.completedShares = shares; + data.totalKHashes = totalKHashes; + data.currentHashRate = getCurrentHashRate(mElapsed); + data.btcPrice = getBTCprice(); + data.currentTime = getTime(); + data.halfHourFee = String(gData.halfHourFee) + " sat/vB"; + data.netwrokDifficulty = gData.difficulty; + data.globalHashRate = gData.globalHash; + data.blockHeight = getBlockHeight(); + + unsigned long currentBlock = data.blockHeight.toInt(); + unsigned long remainingBlocks = (((currentBlock / HALVING_BLOCKS)+1) * HALVING_BLOCKS) - currentBlock; + data.progressPercent = (HALVING_BLOCKS - remainingBlocks) * 100 / HALVING_BLOCKS; + data.remainingBlocks = String(remainingBlocks) + " BLOCKS"; + + return data; } \ No newline at end of file diff --git a/src/monitor.h b/src/monitor.h index 1e1aaac..12e8e14 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -51,14 +51,47 @@ typedef struct{ int halfHourFee; }global_data; +typedef struct { + String completedShares; + String totalMHashes; + String totalKHashes; + String currentHashRate; + String templates; + String bestDiff; + String timeMining; + String valids; + String temp; + String currentTime; +}mining_data; +typedef struct { + String completedShares; + String totalKHashes; + String currentHashRate; + String btcPrice; + String blockHeight; + String currentTime; +}clock_data; + +typedef struct { + String completedShares; + String totalKHashes; + String currentHashRate; + String btcPrice; + String currentTime; + String halfHourFee; + String netwrokDifficulty; + String globalHashRate; + String blockHeight; + float progressPercent; + String remainingBlocks; +}coin_data; void setup_monitor(void); -void show_MinerScreen(unsigned long mElapsed); -void show_ClockScreen(unsigned long mElapsed); -void show_GlobalHashScreen(unsigned long mElapsed); -void show_NoScreen(unsigned long mElapsed); -void changeScreen(void); void doLedStuff(int ledPin); +mining_data getMiningData(unsigned long mElapsed); +clock_data getClockData(unsigned long mElapsed); +coin_data getCoinData(unsigned long mElapsed); + #endif //MONITOR_API_H \ No newline at end of file diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..3ca4b5e --- /dev/null +++ b/src/version.h @@ -0,0 +1,6 @@ +#ifndef VERSION_H +#define VERSION_H + +#define CURRENT_VERSION "V1.6.1" + +#endif // VERSION_H diff --git a/src/wManager.cpp b/src/wManager.cpp index 48bba09..f4c6b09 100644 --- a/src/wManager.cpp +++ b/src/wManager.cpp @@ -8,10 +8,9 @@ #include #include -#include "media/images.h" -#include // Graphics and font library #include "wManager.h" #include "monitor.h" +#include "display/display.h" // JSON configuration file #define JSON_CONFIG_FILE "/config.json" @@ -28,9 +27,6 @@ int GMTzone = 2; //Currently selected in spain // Define WiFiManager Object WiFiManager wm; - - -extern TFT_eSPI tft; // tft variable declared on main extern monitor_data mMonitor; void saveConfigFile() @@ -222,7 +218,7 @@ void init_WifiManager() { //No configuramos timeout al modulo wm.setConfigPortalBlocking(true); //Hacemos que el portal SI bloquee el firmware - tft.pushImage(0, 0, setupModeWidth, setupModeHeight, setupModeScreen); + drawSetupScreen(); if (!wm.startConfigPortal("NerdMinerAP","MineYourCoins")) { Serial.println("failed to connect and hit timeout"); diff --git a/src/wManager.h b/src/wManager.h index 14fffab..c969b31 100644 --- a/src/wManager.h +++ b/src/wManager.h @@ -10,6 +10,11 @@ #define PIN_BUTTON_2 19 //Not used #define PIN_ENABLE5V 21 //Not used #define LED_PIN 2 +#elif defined(NERMINER_S3_AMOLED) +#define PIN_BUTTON_1 0 +#define PIN_BUTTON_2 21 +#define PIN_ENABLE5V 15 + #endif void init_WifiManager();