Multi device support refactoring

This commit is contained in:
Roman Mashta 2023-09-02 02:01:42 +03:00
parent 7a574d1b47
commit fc23e9797e
33 changed files with 43990 additions and 1124 deletions

View File

@ -136,10 +136,9 @@
#endif
#ifdef NERMINER_S3_DONGLE
#include <User_Setups/Setup300_TTGO_T_Dongle.h> //Just a stub. No driver implementation for S3 AMOLED in TFT_eSPI
#include <User_Setups/Setup300_TTGO_T_Dongle.h>
#endif
//#include <User_Setups/Setup301_BW16_ST7735.h> // Setup file for Bw16-based boards with ST7735 160 x 80 TFT
//#include <User_Setups/SetupX_Template.h> // Template file for a setup

View File

@ -5,7 +5,6 @@
#define TFT_WIDTH 80
#define TFT_HEIGHT 160
#define TFT_RST 1
#define TFT_MISO -1
#define TFT_MOSI 3

View File

@ -74,10 +74,13 @@ static void lcd_send_cmd(uint32_t cmd, uint8_t *dat, uint32_t len)
t.cmd = 0x02;
t.addr = cmd << 8;
// Serial.printf("t.addr:0x%X\r\n", t.addr);
if (len != 0) {
if (len != 0)
{
t.tx_buffer = dat;
t.length = 8 * len;
} else {
}
else
{
t.tx_buffer = NULL;
t.length = 0;
}
@ -85,7 +88,8 @@ static void lcd_send_cmd(uint32_t cmd, uint8_t *dat, uint32_t len)
TFT_CS_H;
#else
WriteComm(cmd);
if (len != 0) {
if (len != 0)
{
for (int i = 0; i < len; i++)
WriteData(dat[i]);
}
@ -138,7 +142,8 @@ void rm67162_init(void)
#endif
// Initialize the screen multiple times to prevent initialization failure
int i = 3;
while (i--) {
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++)
@ -155,14 +160,14 @@ void rm67162_init(void)
delay(120);
}
}
}
void lcd_setRotation(uint8_t r)
{
uint8_t gbr = TFT_MAD_RGB;
switch (r) {
switch (r)
{
case 0: // Portrait
// WriteData(gbr);
break;
@ -187,7 +192,8 @@ void lcd_address_set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{0x2c, {0x00}, 0x00},
};
for (uint32_t i = 0; i < 3; i++) {
for (uint32_t i = 0; i < 3; i++)
{
lcd_send_cmd(t[i].cmd, t[i].data, t[i].len);
}
}
@ -202,7 +208,8 @@ void lcd_fill(uint16_t xsta,
uint16_t w = xend - xsta;
uint16_t h = yend - ysta;
uint16_t *color_p = (uint16_t *)ps_malloc(w * h * 2);
if (!color_p) {
if (!color_p)
{
return;
}
memset(color_p, color, w * h * 2);
@ -229,24 +236,29 @@ void lcd_PushColors(uint16_t x,
lcd_address_set(x, y, x + width - 1, y + high - 1);
TFT_CS_L;
do {
do
{
size_t chunk_size = len;
spi_transaction_ext_t t = {0};
memset(&t, 0, sizeof(t));
if (first_send) {
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 {
}
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) {
if (chunk_size > SEND_BUF_SIZE)
{
chunk_size = SEND_BUF_SIZE;
}
t.base.tx_buffer = p;
@ -276,24 +288,29 @@ void lcd_PushColors(uint16_t *data, uint32_t len)
bool first_send = 1;
uint16_t *p = (uint16_t *)data;
TFT_CS_L;
do {
do
{
size_t chunk_size = len;
spi_transaction_ext_t t = {0};
memset(&t, 0, sizeof(t));
if (first_send) {
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 {
}
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) {
if (chunk_size > SEND_BUF_SIZE)
{
chunk_size = SEND_BUF_SIZE;
}
t.base.tx_buffer = p;

View File

@ -136,3 +136,4 @@ lib_deps =
mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient
https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4
https://github.com/FastLED/FastLED

View File

@ -10,14 +10,20 @@
#include "wManager.h"
#include "mining.h"
#include "monitor.h"
#include "display/display.h"
#include "drivers/display.h"
//3 seconds WDT
#define WDT_TIMEOUT 3
//15 minutes WDT for miner task
#define WDT_MINER_TIMEOUT 900
#ifdef PIN_BUTTON_1
OneButton button1(PIN_BUTTON_1);
#endif
#ifdef PIN_BUTTON_2
OneButton button2(PIN_BUTTON_2);
#endif
extern monitor_data mMonitor;
@ -42,29 +48,24 @@ void setup()
//disableCore1WDT();
// Setup the buttons
#if defined(NERDMINERV2) || defined(NERMINER_S3_AMOLED)
// Button 1 (Boot)
button1.setPressTicks(5000);
button1.attachClick(alternateScreenState);
button1.attachDoubleClick(alternateScreenRotation);
// Button 2 (GPIO14)
button2.setPressTicks(5000);
button2.attachClick(switchToNextScreen);
button2.attachLongPressStart(reset_configurations);
#elif defined(DEVKITV1)
//Standard ESP32-devKit
button1.setPressTicks(5000);
button1.attachLongPressStart(reset_configurations);
pinMode(LED_PIN, OUTPUT);
#elif defined(NERMINER_S3_DONGLE)
#if defined(PIN_BUTTON_1) && !defined(PIN_BUTTON_2) //One button device
button1.setPressTicks(5000);
button1.attachClick(switchToNextScreen);
button1.attachDoubleClick(alternateScreenRotation);
button1.attachLongPressStart(reset_configurations);
#endif
#if defined(PIN_BUTTON_1) && defined(PIN_BUTTON_2) //Button 1 of two button device
button1.setPressTicks(5000);
button1.attachClick(alternateScreenState);
button1.attachDoubleClick(alternateScreenRotation);
#endif
#if defined(PIN_BUTTON_2) //Button 2 of two button device
button2.setPressTicks(5000);
button2.attachClick(switchToNextScreen);
button2.attachLongPressStart(reset_configurations);
#endif
/******** INIT NERDMINER ************/
Serial.println("NerdMiner v2 starting......");
@ -78,9 +79,7 @@ void setup()
/******** SHOW LED INIT STATUS (devices without screen) *****/
mMonitor.NerdStatus = NM_waitingConfig;
#ifdef DEVKITV1
doLedStuff(LED_PIN);
#endif
doLedStuff(0);
/******** INIT WIFI ************/
init_WifiManager();
@ -131,14 +130,15 @@ void app_error_fault_handler(void *arg) {
void loop() {
// keep watching the push buttons:
#ifdef PIN_BUTTON_1
button1.tick();
#endif
#ifdef PIN_BUTTON_2
button2.tick();
#endif
wifiManagerProcess(); // avoid delays() in loop when non-blocking and other long running code
#ifdef DEVKITV1
doLedStuff(LED_PIN);
#endif
vTaskDelay(50 / portTICK_PERIOD_MS);
}

View File

@ -1,63 +0,0 @@
#include "display.h"
#ifdef NO_DISPLAY
DisplayDriver *currentDisplayDriver = &noDisplayDriver;
#endif
#ifdef T_DISPLAY
DisplayDriver *currentDisplayDriver = &tDisplayDriver;
#endif
#ifdef AMOLED_DISPLAY
DisplayDriver *currentDisplayDriver = &amoledDisplayDriver;
#endif
#ifdef DONGLE_DISPLAY
DisplayDriver *currentDisplayDriver = &dongleDisplayDriver;
#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);
}
// Animate the current cyclic screen
void animateCurrentScreen(unsigned long frame) {
currentDisplayDriver->animateCurrentScreen(frame);
}

View File

@ -1,43 +0,0 @@
#ifndef DRIVERS_H
#define DRIVERS_H
#if defined(DEVKITV1)
#define NO_DISPLAY
#elif defined(NERMINER_S3_AMOLED)
#define AMOLED_DISPLAY
#elif defined(NERMINER_S3_DONGLE)
#define DONGLE_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 void (*AnimateCurrentScreenFunction)(unsigned long frame);
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
AnimateCurrentScreenFunction animateCurrentScreen; // Animate the current cyclic screen
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;
extern DisplayDriver dongleDisplayDriver;
#define SCREENS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif // DRIVERS_H

View File

@ -1,225 +0,0 @@
#include "../drivers.h"
#ifdef AMOLED_DISPLAY
#include <rm67162.h>
#include <TFT_eSPI.h>
#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());
}
void amoledDisplay_AnimateCurrentScreen(unsigned long frame) {
}
CyclicScreenFunction amoledDisplayCyclicScreens[] = { amoledDisplay_MinerScreen, amoledDisplay_ClockScreen, amoledDisplay_GlobalHashScreen };
DisplayDriver amoledDisplayDriver = {
amoledDisplay_Init,
amoledDisplay_AlternateScreenState,
amoledDisplay_AlternateRotation,
amoledDisplay_LoadingScreen,
amoledDisplay_SetupScreen,
amoledDisplayCyclicScreens,
amoledDisplay_AnimateCurrentScreen,
SCREENS_ARRAY_SIZE(amoledDisplayCyclicScreens),
0,
WIDTH,
HEIGHT
};
#endif

View File

@ -1,135 +0,0 @@
#include "../drivers.h"
#ifdef DONGLE_DISPLAY
#include <TFT_eSPI.h>
#include "media/images.h"
#include "media/myFonts.h"
#include "media/Free_Fonts.h"
#include "version.h"
#include "monitor.h"
#include "OpenFontRender.h"
#define WIDTH 160
#define HEIGHT 80
#define BUFFER_WIDTH WIDTH
#define BUFFER_HEIGHT HEIGHT * 4
#define SCROLL_SPEED 1
int pos_y = 0;
int delta_y = SCROLL_SPEED;
int max_y = BUFFER_HEIGHT - HEIGHT;
OpenFontRender render;
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite background = TFT_eSprite(&tft);
#define BACK_COLOR TFT_BLACK
#define VALUE_COLOR TFT_WHITE
#define KEY_COLOR TFT_WHITE
#define CLEAR_SCREEN() \
int32_t x = 4, y = 8; \
background.setTextSize(1);\
background.setTextFont(FONT2);\
background.setTextColor(KEY_COLOR);\
background.fillRect(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT, BACK_COLOR);\
render.setFontSize(24);\
#define PRINT_STR(key, value, x, y)\
{\
background.drawString(String(key).c_str(), x, y);\
y -= 8;\
render.rdrawString(String(value).c_str(), WIDTH - 4, y, VALUE_COLOR);\
y += 40;\
max_y = y;\
}
#define PUSH_SCREEN() \
background.pushSprite(0,0);
void dongleDisplay_Init(void) {
tft.init();
tft.setRotation(3);
tft.setSwapBytes(true);
tft.fillScreen(TFT_RED);
background.createSprite(BUFFER_WIDTH, BUFFER_HEIGHT);
background.setSwapBytes(true);
render.setDrawer(background);
render.setLineSpaceRatio(0.9);
// 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 dongleDisplay_AlternateScreenState(void) {
}
void dongleDisplay_AlternateRotation(void) {
tft.getRotation() == 1 ? tft.setRotation(3) : tft.setRotation(1);
}
void dongleDisplay_MinerScreen(unsigned long mElapsed) {
mining_data data = getMiningData(mElapsed);
//Print background screen
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());
CLEAR_SCREEN();
PRINT_STR("M.Hashes", data.totalMHashes, x, y)
PRINT_STR("Templates", data.templates, x, y)
PRINT_STR("Best Diff", data.bestDiff, x, y)
PRINT_STR("Shares", data.completedShares, x, y)
PRINT_STR("Hash rate", data.currentHashRate, x, y)
PRINT_STR("Valids", data.valids, x, y)
PRINT_STR("Temp", data.temp, x, y)
PRINT_STR("Time", data.currentTime, x, y)
}
void dongleDisplay_LoadingScreen(void) {
CLEAR_SCREEN();
PRINT_STR("Initializing...","", x, y);
PUSH_SCREEN();
}
void dongleDisplay_SetupScreen(void) {
CLEAR_SCREEN();
PRINT_STR("Use WiFi for setup...","", x, y);
PUSH_SCREEN();
}
void dongleDisplay_AnimateCurrentScreen(unsigned long frame) {
if(pos_y >= max_y - HEIGHT) {
delta_y = -SCROLL_SPEED;
pos_y = max_y - HEIGHT;
} else if(pos_y <= 0) {
delta_y = SCROLL_SPEED;
pos_y = 0;
}
pos_y += delta_y;
background.pushSprite(0, -pos_y);
}
CyclicScreenFunction dongleDisplayCyclicScreens[] = { dongleDisplay_MinerScreen };
DisplayDriver dongleDisplayDriver = {
dongleDisplay_Init,
dongleDisplay_AlternateScreenState,
dongleDisplay_AlternateRotation,
dongleDisplay_LoadingScreen,
dongleDisplay_SetupScreen,
dongleDisplayCyclicScreens,
dongleDisplay_AnimateCurrentScreen,
SCREENS_ARRAY_SIZE(dongleDisplayCyclicScreens),
0,
WIDTH,
HEIGHT
};
#endif

View File

@ -1,60 +0,0 @@
#include "../drivers.h"
#ifdef NO_DISPLAY
#include <Arduino.h>
#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...");
}
void tDisplay_AnimateCurrentScreen(unsigned long frame) {
}
CyclicScreenFunction noDisplayCyclicScreens[] = { noDisplay_NoScreen };
DisplayDriver noDisplayDriver = {
noDisplay_Init,
noDisplay_AlternateScreenState,
noDisplay_AlternateRotation,
noDisplay_LoadingScreen,
noDisplay_SetupScreen,
noDisplayCyclicScreens,
noDisplay_AnimateCurrentScreen,
SCREENS_ARRAY_SIZE(noDisplayCyclicScreens),
0,
0,
0,
};
#endif

View File

@ -1,220 +0,0 @@
#include "../drivers.h"
#ifdef T_DISPLAY
#include <TFT_eSPI.h>
#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 tDisplay_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);
}
void tDisplay_AnimateCurrentScreen(unsigned long frame) {
}
CyclicScreenFunction tDisplayCyclicScreens[] = { tDisplay_MinerScreen, tDisplay_ClockScreen, tDisplay_GlobalHashScreen };
DisplayDriver tDisplayDriver = {
tDisplay_Init,
tDisplay_AlternateScreenState,
tDisplay_AlternateRotation,
tDisplay_LoadingScreen,
tDisplay_SetupScreen,
tDisplayCyclicScreens,
tDisplay_AnimateCurrentScreen,
SCREENS_ARRAY_SIZE(tDisplayCyclicScreens),
0,
WIDTH,
HEIGHT
};
#endif

View File

@ -0,0 +1,9 @@
#ifndef _ESP32_DEV_KIT_H
#define _ESP32_DEV_KIT_H
#define PIN_BUTTON_1 0
#define LED_PIN 2
#define NO_DISPLAY
#endif

View File

@ -0,0 +1,9 @@
#ifndef _LILYGO_S3_AMOLED_H
#define _LILYGO_S3_AMOLED_H
#define PIN_BUTTON_1 0
#define PIN_BUTTON_2 21
#define AMOLED_DISPLAY
#endif

View File

@ -0,0 +1,11 @@
#ifndef _LILYGO_S3_DONGLE_H
#define _LILYGO_S3_DONGLE_H
#define PIN_BUTTON_1 0
#define LED_DI_PIN 40
#define LED_CI_PIN 39
#define USE_LED
#define DONGLE_DISPLAY
#endif

View File

@ -0,0 +1,10 @@
#ifndef _LILYGO_S3_T_DISPLAY_H
#define _LILYGO_S3_T_DISPLAY_H
#define PIN_BUTTON_1 0
#define PIN_BUTTON_2 14
#define PIN_ENABLE5V 15
#define T_DISPLAY
#endif

View File

@ -0,0 +1,10 @@
#ifndef _NERD_MINER_V2_H
#define _NERD_MINER_V2_H
#define PIN_BUTTON_1 0
#define PIN_BUTTON_2 14
#define PIN_ENABLE5V 15
#define T_DISPLAY
#endif

77
src/drivers/display.cpp Normal file
View File

@ -0,0 +1,77 @@
#include "display.h"
#ifdef NO_DISPLAY
DisplayDriver *currentDisplayDriver = &noDisplayDriver;
#endif
#ifdef T_DISPLAY
DisplayDriver *currentDisplayDriver = &tDisplayDriver;
#endif
#ifdef AMOLED_DISPLAY
DisplayDriver *currentDisplayDriver = &amoledDisplayDriver;
#endif
#ifdef DONGLE_DISPLAY
DisplayDriver *currentDisplayDriver = &dongleDisplayDriver;
#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);
}
// Animate the current cyclic screen
void animateCurrentScreen(unsigned long frame)
{
currentDisplayDriver->animateCurrentScreen(frame);
}
// Do LED stuff
void doLedStuff(unsigned long frame)
{
currentDisplayDriver->doLedStuff(frame);
}

View File

@ -14,5 +14,6 @@ void drawLoadingScreen();
void drawSetupScreen();
void drawCurrentScreen(unsigned long mElapsed);
void animateCurrentScreen(unsigned long frame);
void doLedStuff(unsigned long frame);
#endif // DISPLAY_H

View File

@ -0,0 +1,246 @@
#include "../drivers.h"
#ifdef AMOLED_DISPLAY
#include <rm67162.h>
#include <TFT_eSPI.h>
#include "media/images_536_240.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
#define SOURCE_HEIGHT 170
#define MARGIN_LEFT 42
#define SCALE HEIGHT / SOURCE_HEIGHT
#define X(x) (MARGIN_LEFT + (x * SCALE))
#define Y(y) (y * SCALE)
#define FS(S) (S * SCALE)
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(FS(35));
render.setFontColor(TFT_BLACK);
render.rdrawString(data.currentHashRate.c_str(), X(118), Y(114), TFT_BLACK);
// Total hashes
render.setFontSize(FS(18));
render.rdrawString(data.totalMHashes.c_str(), X(268), Y(138), TFT_BLACK);
// Block templates
render.setFontSize(FS(18));
render.drawString(data.templates.c_str(), X(186), Y(20), 0xDEDB);
// Best diff
render.drawString(data.bestDiff.c_str(), X(186), Y(48), 0xDEDB);
// 32Bit shares
render.setFontSize(FS(18));
render.drawString(data.completedShares.c_str(), X(186), Y(76), 0xDEDB);
// Hores
render.setFontSize(FS(14));
render.rdrawString(data.timeMining.c_str(), X(315), Y(104), 0xDEDB);
// Valid Blocks
render.setFontSize(FS(24));
render.drawString(data.valids.c_str(), X(285), Y(56), 0xDEDB);
// Print Temp
render.setFontSize(FS(10));
render.rdrawString(data.temp.c_str(), X(239), Y(1), TFT_BLACK);
render.setFontSize(FS(4));
render.rdrawString(String(0).c_str(), X(244), Y(3), TFT_BLACK);
// Print Hour
render.setFontSize(FS(10));
render.rdrawString(data.currentTime.c_str(), X(286), Y(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(FS(25));
render.setFontColor(TFT_BLACK);
render.rdrawString(data.currentHashRate.c_str(), X(94), Y(129), TFT_BLACK);
// Print BTC Price
background.setFreeFont(FSSB12);
background.setTextSize(1);
background.setTextDatum(TL_DATUM);
background.setTextColor(TFT_BLACK);
background.drawString(data.btcPrice.c_str(), X(202), Y(3), GFXFF);
// Print BlockHeight
render.setFontSize(FS(18));
render.rdrawString(data.blockHeight.c_str(), X(254), Y(140), TFT_BLACK);
// Print Hour
background.setFreeFont(FF24);
background.setTextSize(2);
background.setTextColor(0xDEDB, TFT_BLACK);
background.drawString(data.currentTime.c_str(), X(130), Y(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(FSSB12);
background.setTextSize(1);
background.setTextDatum(TL_DATUM);
background.setTextColor(TFT_BLACK);
background.drawString(data.btcPrice.c_str(), X(198), Y(3), GFXFF);
// Print Hour
background.setFreeFont(FSSB12);
background.setTextSize(1);
background.setTextDatum(TL_DATUM);
background.setTextColor(TFT_BLACK);
background.drawString(data.currentTime.c_str(), X(268), Y(3), GFXFF);
// Print Last Pool Block
background.setFreeFont(FSS12);
background.setTextDatum(TR_DATUM);
background.setTextColor(0x9C92);
background.drawString(data.halfHourFee.c_str(), X(302), Y(52), GFXFF);
// Print Difficulty
background.setFreeFont(FSS12);
background.setTextDatum(TR_DATUM);
background.setTextColor(0x9C92);
background.drawString(data.netwrokDifficulty.c_str(), X(302), Y(88), GFXFF);
// Print Global Hashrate
render.setFontSize(FS(17));
render.rdrawString(data.globalHashRate.c_str(), X(274), Y(145), TFT_BLACK);
// Print BlockHeight
render.setFontSize(FS(28));
render.rdrawString(data.blockHeight.c_str(), X(140), Y(104), 0xDEDB);
// Draw percentage rectangle
int x2 = 2 + (138 * data.progressPercent / 100);
background.fillRect(2, Y(149), X(x2), Y(238), 0xDEDB);
// Print Remaining BLocks
background.setTextFont(FONT4);
background.setTextSize(1);
background.setTextDatum(MC_DATUM);
background.setTextColor(TFT_BLACK);
background.drawString(data.remainingBlocks.c_str(), X(72), Y(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, X(24), Y(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());
}
void amoledDisplay_AnimateCurrentScreen(unsigned long frame)
{
}
void amoledDisplay_DoLedStuff(unsigned long frame)
{
}
CyclicScreenFunction amoledDisplayCyclicScreens[] = {amoledDisplay_MinerScreen, amoledDisplay_ClockScreen, amoledDisplay_GlobalHashScreen};
DisplayDriver amoledDisplayDriver = {
amoledDisplay_Init,
amoledDisplay_AlternateScreenState,
amoledDisplay_AlternateRotation,
amoledDisplay_LoadingScreen,
amoledDisplay_SetupScreen,
amoledDisplayCyclicScreens,
amoledDisplay_AnimateCurrentScreen,
amoledDisplay_DoLedStuff,
SCREENS_ARRAY_SIZE(amoledDisplayCyclicScreens),
0,
WIDTH,
HEIGHT};
#endif

View File

@ -0,0 +1,212 @@
#include "../drivers.h"
#ifdef DONGLE_DISPLAY
#include <TFT_eSPI.h>
#include "media/images_160_80.h"
#include "media/myFonts.h"
#include "media/Free_Fonts.h"
#include "version.h"
#include "monitor.h"
#include "OpenFontRender.h"
#include <FastLED.h>
#define WIDTH 160
#define HEIGHT 80
#define BUFFER_WIDTH MinerWidth
#define BUFFER_HEIGHT MinerHeight
#define SCROLL_SPEED 2
int pos_y = 0;
int delta_y = SCROLL_SPEED;
int max_y = BUFFER_HEIGHT - HEIGHT;
OpenFontRender render;
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite background = TFT_eSprite(&tft);
#define MAX_BRIGHTNESS 16
#define SLOW_FADE 1;
#define FAST_FADE 4;
CRGB leds(0, 0, 0);
int brightness = 0;
int fadeDirection = 1;
int fadeAmount = 0;
extern monitor_data mMonitor;
#define BACK_COLOR TFT_BLACK
#define VALUE_COLOR TFT_WHITE
#define KEY_COLOR TFT_WHITE
#define RESET_SCREEN() \
int32_t x = 8, y = 8; \
background.setTextSize(1); \
background.setTextFont(FONT2); \
\
background.setTextColor(KEY_COLOR); \
\
render.setFontSize(18);
#define CLEAR_SCREEN() \
RESET_SCREEN(); \
background.fillRect(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT, BACK_COLOR); \
\
#define PRINT_STR(str) \
{ \
background.drawString(String(str).c_str(), x, y); \
y += 32; \
max_y = y; \
}
#define PRINT_VALUE(value) \
{ \
render.drawString(String(value).c_str(), x, y, VALUE_COLOR); \
y += 27; \
}
#define PUSH_SCREEN() \
background.pushSprite(0, 0);
void dongleDisplay_Init(void)
{
FastLED.addLeds<APA102, LED_DI_PIN, LED_CI_PIN, BGR>(&leds, 1);
FastLED.show();
tft.init();
tft.setRotation(3);
tft.setSwapBytes(true);
background.createSprite(BUFFER_WIDTH, BUFFER_HEIGHT);
background.setSwapBytes(true);
render.setDrawer(background);
render.setLineSpaceRatio(0.9);
// 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 dongleDisplay_AlternateScreenState(void)
{
}
void dongleDisplay_AlternateRotation(void)
{
tft.getRotation() == 1 ? tft.setRotation(3) : tft.setRotation(1);
}
void dongleDisplay_MinerScreen(unsigned long mElapsed)
{
max_y = BUFFER_HEIGHT;
mining_data data = getMiningData(mElapsed);
// Print background screen
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());
background.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen);
RESET_SCREEN();
x = 74;
y = 15;
render.setFontSize(20);
PRINT_VALUE(data.currentTime);
render.setFontSize(18);
x = 68;
y = 51;
PRINT_VALUE(data.currentHashRate);
PRINT_VALUE(data.valids);
PRINT_VALUE(data.templates);
PRINT_VALUE(data.bestDiff);
PRINT_VALUE(data.completedShares);
PRINT_VALUE(data.totalMHashes);
PRINT_VALUE(data.temp);
}
void dongleDisplay_LoadingScreen(void)
{
CLEAR_SCREEN();
PRINT_STR("Initializing...");
PUSH_SCREEN();
}
void dongleDisplay_SetupScreen(void)
{
CLEAR_SCREEN();
PRINT_STR("Use WiFi for setup...");
PUSH_SCREEN();
}
void dongleDisplay_AnimateCurrentScreen(unsigned long frame)
{
if (pos_y > max_y)
{
pos_y = 0;
}
if (pos_y > max_y - HEIGHT)
{
background.pushSprite(0, max_y - pos_y);
}
pos_y += delta_y;
background.pushSprite(0, -pos_y);
}
void dongleDisplay_DoLedStuff(unsigned long frame)
{
#ifdef USE_LED
switch (mMonitor.NerdStatus)
{
case NM_waitingConfig:
brightness = MAX_BRIGHTNESS;
leds.setRGB(255, 255, 0);
fadeAmount = 0;
break;
case NM_Connecting:
leds.setRGB(0, 0, 255);
fadeAmount = SLOW_FADE;
break;
case NM_hashing:
leds.setRGB(0, 0, 255);
fadeAmount = FAST_FADE;
break;
}
leds.fadeLightBy(0xFF - brightness);
FastLED.show();
brightness = brightness + (fadeDirection * fadeAmount);
if (brightness <= 0 || brightness >= MAX_BRIGHTNESS)
{
fadeDirection = -fadeDirection;
}
brightness = constrain(brightness, 0, MAX_BRIGHTNESS);
#endif
}
CyclicScreenFunction dongleDisplayCyclicScreens[] = {dongleDisplay_MinerScreen};
DisplayDriver dongleDisplayDriver = {
dongleDisplay_Init,
dongleDisplay_AlternateScreenState,
dongleDisplay_AlternateRotation,
dongleDisplay_LoadingScreen,
dongleDisplay_SetupScreen,
dongleDisplayCyclicScreens,
dongleDisplay_AnimateCurrentScreen,
dongleDisplay_DoLedStuff,
SCREENS_ARRAY_SIZE(dongleDisplayCyclicScreens),
0,
WIDTH,
HEIGHT};
#endif

View File

@ -0,0 +1,104 @@
#include "../drivers.h"
#ifdef NO_DISPLAY
#include <Arduino.h>
#include "monitor.h"
#include "wManager.h"
extern monitor_data mMonitor;
void noDisplay_Init(void)
{
Serial.println("No display driver initialized");
pinMode(LED_PIN, OUTPUT);
}
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...");
}
// Variables para controlar el parpadeo con millis()
unsigned long previousMillis = 0;
void noDisplay_DoLedStuff(unsigned long frame)
{
unsigned long currentMillis = millis();
switch (mMonitor.NerdStatus)
{
case NM_waitingConfig:
digitalWrite(LED_PIN, HIGH); // LED encendido de forma continua
break;
case NM_Connecting:
if (currentMillis - previousMillis >= 500)
{ // 0.5sec blink
previousMillis = currentMillis;
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Cambia el estado del LED
}
break;
case NM_hashing:
if (currentMillis - previousMillis >= 100)
{ // 0.1sec blink
previousMillis = currentMillis;
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Cambia el estado del LED
}
break;
}
}
void noDisplay_AnimateCurrentScreen(unsigned long frame)
{
}
CyclicScreenFunction noDisplayCyclicScreens[] = {noDisplay_NoScreen};
DisplayDriver noDisplayDriver = {
noDisplay_Init,
noDisplay_AlternateScreenState,
noDisplay_AlternateRotation,
noDisplay_LoadingScreen,
noDisplay_SetupScreen,
noDisplayCyclicScreens,
noDisplay_AnimateCurrentScreen,
noDisplay_DoLedStuff,
SCREENS_ARRAY_SIZE(noDisplayCyclicScreens),
0,
0,
0,
};
#endif

View File

@ -0,0 +1,234 @@
#include "../drivers.h"
#ifdef T_DISPLAY
#include <TFT_eSPI.h>
#include "media/images_320_170.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 tDisplay_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);
}
void tDisplay_AnimateCurrentScreen(unsigned long frame)
{
}
void tDisplay_DoLedStuff(unsigned long frame)
{
}
CyclicScreenFunction tDisplayCyclicScreens[] = {tDisplay_MinerScreen, tDisplay_ClockScreen, tDisplay_GlobalHashScreen};
DisplayDriver tDisplayDriver = {
tDisplay_Init,
tDisplay_AlternateScreenState,
tDisplay_AlternateRotation,
tDisplay_LoadingScreen,
tDisplay_SetupScreen,
tDisplayCyclicScreens,
tDisplay_AnimateCurrentScreen,
tDisplay_DoLedStuff,
SCREENS_ARRAY_SIZE(tDisplayCyclicScreens),
0,
WIDTH,
HEIGHT};
#endif

50
src/drivers/drivers.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef DRIVERS_H
#define DRIVERS_H
#if defined(NERDMINERV2)
#include "devices/nerdMinerV2.h"
#elif defined(DEVKITV1)
#include "devices/esp32DevKit.h"
#elif defined(TDISPLAY)
#include "devices/lilygoS3TDisplay.h"
#elif defined(NERMINER_S3_AMOLED)
#include "devices/lilygoS3Amoled.h"
#elif defined(NERMINER_S3_DONGLE)
#include "devices/lilygoS3Dongle.h"
#else
#error "No device defined"
#endif
typedef void (*AlternateFunction)(void);
typedef void (*DriverInitFunction)(void);
typedef void (*ScreenFunction)(void);
typedef void (*CyclicScreenFunction)(unsigned long mElapsed);
typedef void (*AnimateCurrentScreenFunction)(unsigned long frame);
typedef void (*DoLedStuff)(unsigned long frame);
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
AnimateCurrentScreenFunction animateCurrentScreen; // Animate the current cyclic screen
DoLedStuff doLedStuff; // Do LED stuff
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;
extern DisplayDriver dongleDisplayDriver;
#define SCREENS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif // DRIVERS_H

2427
src/media/images_160_80.h Normal file

File diff suppressed because it is too large Load Diff

40235
src/media/images_536_240.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
#include "mining.h"
#include "utils.h"
#include "monitor.h"
#include "display/display.h"
#include "drivers/display.h"
unsigned long templates = 0;
unsigned long hashes= 0;
@ -375,7 +375,8 @@ void runMiner(void * task_id) {
#define DELAY 100
#define REDRAW_EVERY 10
void runMonitor(void *name){
void runMonitor(void *name)
{
Serial.println("[MONITOR] started");
@ -385,8 +386,10 @@ void runMonitor(void *name){
unsigned long frame = 0;
while(1){
if((frame % REDRAW_EVERY) == 0){
while (1)
{
if ((frame % REDRAW_EVERY) == 0)
{
unsigned long mElapsed = millis() - mLastCheck;
mLastCheck = millis();
unsigned long currentKHashes = (Mhashes * 1000) + hashes / 1000;
@ -396,17 +399,18 @@ void runMonitor(void *name){
drawCurrentScreen(mElapsed);
// Monitor state when hashrate is 0.0
if(elapsedKHs == 0) {
if (elapsedKHs == 0)
{
Serial.printf(">>> [i] Miner: newJob>%s / inRun>%s) - Client: connected>%s / subscribed>%s / wificonnected>%s\n",
mMiner.newJob ? "true" : "false", mMiner.inRun ? "true" : "false",
client.connected() ? "true" : "false", isMinerSuscribed ? "true" : "false", WiFi.status() == WL_CONNECTED ? "true" : "false");
}
}
animateCurrentScreen(frame);
doLedStuff(frame);
// Pause the task for 1000ms
vTaskDelay(DELAY / portTICK_PERIOD_MS);
frame++;
}
}

View File

@ -209,37 +209,13 @@ String getTime(void){
return LocalHour;
}
// Variables para controlar el parpadeo con millis()
unsigned long previousMillis = 0;
void doLedStuff(int ledPin){
unsigned long currentMillis = millis();
switch (mMonitor.NerdStatus) {
case NM_waitingConfig: digitalWrite(ledPin, HIGH); // LED encendido de forma continua
break;
case NM_Connecting: if (currentMillis - previousMillis >= 500) { //0.5sec blink
previousMillis = currentMillis;
digitalWrite(ledPin, !digitalRead(ledPin)); // Cambia el estado del LED
}
break;
case NM_hashing: if (currentMillis - previousMillis >= 100) { //0.1sec blink
previousMillis = currentMillis;
digitalWrite(ledPin, !digitalRead(ledPin)); // Cambia el estado del LED
}
break;
}
}
String getCurrentHashRate(unsigned long mElapsed){
String getCurrentHashRate(unsigned long mElapsed)
{
return String((1.0 * (elapsedKHs * 1000)) / mElapsed, 2);
}
mining_data getMiningData(unsigned long mElapsed){
mining_data getMiningData(unsigned long mElapsed)
{
mining_data data;
char best_diff_string[16] = {0};
@ -267,7 +243,8 @@ mining_data getMiningData(unsigned long mElapsed){
return data;
}
clock_data getClockData(unsigned long mElapsed){
clock_data getClockData(unsigned long mElapsed)
{
clock_data data;
data.completedShares = shares;
@ -280,7 +257,8 @@ clock_data getClockData(unsigned long mElapsed){
return data;
}
coin_data getCoinData(unsigned long mElapsed){
coin_data getCoinData(unsigned long mElapsed)
{
coin_data data;
updateGlobalData(); // Update gData vars asking mempool APIs

View File

@ -88,7 +88,6 @@ typedef struct {
}coin_data;
void setup_monitor(void);
void doLedStuff(int ledPin);
mining_data getMiningData(unsigned long mElapsed);
clock_data getClockData(unsigned long mElapsed);

View File

@ -10,7 +10,7 @@
#include <ArduinoJson.h>
#include "wManager.h"
#include "monitor.h"
#include "display/display.h"
#include "drivers/display.h"
// JSON configuration file
#define JSON_CONFIG_FILE "/config.json"
@ -139,13 +139,15 @@ void init_WifiManager()
//Serial.setTxTimeoutMs(10);
//Init pin 15 to eneble 5V external power (LilyGo bug)
#ifdef PIN_ENABLE5V
pinMode(PIN_ENABLE5V, OUTPUT);
digitalWrite(PIN_ENABLE5V, HIGH);
#endif
// Change to true when testing to force configuration every time we run
bool forceConfig = false;
#if !defined(DEVKITV1) & !defined(NERMINER_S3_DONGLE)
#if defined(PIN_BUTTON_2)
// Check if button2 is pressed to enter configMode with actual configuration
if(!digitalRead(PIN_BUTTON_2)){
Serial.println(F("Button pressed to force start config mode"));

View File

@ -1,25 +1,3 @@
#ifdef NERDMINERV2
//Define config buttons for TTGO-TDisplay-s3
#define PIN_BUTTON_1 0
#define PIN_BUTTON_2 14
#define PIN_ENABLE5V 15
#elif defined(DEVKITV1)
//Standard ESP32-devKit
#define PIN_BUTTON_1 0
#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
#elif defined(NERMINER_S3_DONGLE)
#define PIN_BUTTON_1 0
#define PIN_BUTTON_2 -1
#define PIN_ENABLE5V -1
#endif
void init_WifiManager();
void wifiManagerProcess();
void reset_configurations();