Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,5 @@ jobs:
generate_release_notes: true
make_latest: true
fail_on_unmatched_files: true
files: ${{ github.workspace }}/firmware/*/*.bin
files: ${{ github.workspace }}/**/*.bin

5 changes: 4 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
post:post_build_merge.py
board_build.f_cpu = 240000000L
monitor_filters =
esp32_exception_decoder
time
Expand All @@ -613,7 +613,10 @@ build_flags =
-D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1
-D NERDMINERV2=1
-D CORE_DEBUG_LEVEL=0
-D CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=0
;-D DEBUG_MINING=1
;To enable I2C mining in future: -D ENABLE_I2C_MINING=1
lib_deps =
https://github.com/takkaO/OpenFontRender#v1.2
bblanchon/ArduinoJson@^6.21.5
Expand Down
36 changes: 28 additions & 8 deletions src/NerdMinerV2.ino.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,24 @@ void setup()
// Higher prio monitor task
Serial.println("");
Serial.println("Initiating tasks...");
char *name = (char*) malloc(32);
sprintf(name, "(%s)", "Monitor");
BaseType_t res1 = xTaskCreatePinnedToCore(runMonitor, "Monitor", 10000, (void*)name, 5, NULL,1);
static const char monitor_name[] = "(Monitor)";
#if defined(CONFIG_IDF_TARGET_ESP32)
// Reduced stack for ESP32 classic to save memory
BaseType_t res1 = xTaskCreatePinnedToCore(runMonitor, "Monitor", 8000, (void*)monitor_name, 5, NULL,1);
#else
BaseType_t res1 = xTaskCreatePinnedToCore(runMonitor, "Monitor", 10000, (void*)monitor_name, 5, NULL,1);
#endif

/******** CREATE STRATUM TASK *****/
sprintf(name, "(%s)", "Stratum");
#if defined(ESP32_2432S028R) || defined(ESP32_2432S028_2USB)
// Free a little bit of the heap to the screen
BaseType_t res2 = xTaskCreatePinnedToCore(runStratumWorker, "Stratum", 13500, (void*)name, 4, NULL,1);
static const char stratum_name[] = "(Stratum)";
#if defined(CONFIG_IDF_TARGET_ESP32) && !defined(ESP32_2432S028R) && !defined(ESP32_2432S028_2USB)
// Reduced stack for ESP32 classic to save memory
BaseType_t res2 = xTaskCreatePinnedToCore(runStratumWorker, "Stratum", 12000, (void*)stratum_name, 4, NULL,1);
#elif defined(ESP32_2432S028R) || defined(ESP32_2432S028_2USB)
// Free a little bit of the heap to the screen
BaseType_t res2 = xTaskCreatePinnedToCore(runStratumWorker, "Stratum", 13500, (void*)stratum_name, 4, NULL,1);
#else
BaseType_t res2 = xTaskCreatePinnedToCore(runStratumWorker, "Stratum", 15000, (void*)name, 4, NULL,1);
BaseType_t res2 = xTaskCreatePinnedToCore(runStratumWorker, "Stratum", 15000, (void*)stratum_name, 4, NULL,1);
#endif

/******** CREATE MINER TASKS *****/
Expand All @@ -152,14 +159,27 @@ void setup()
//BaseType_t res = xTaskCreate(runWorker, name, 35000, (void*)name, 1, NULL);
TaskHandle_t minerTask1, minerTask2 = NULL;
#ifdef HARDWARE_SHA265
#if defined(CONFIG_IDF_TARGET_ESP32)
//xTaskCreate(minerWorkerHw, "MinerHw-0", 3584, (void*)0, 3, &minerTask1); // Reduced for ESP32 classic
xTaskCreate(minerWorkerSw, "MinerSw-0", 5000, (void*)0, 1, &minerTask1); // Reduced for ESP32 classic
#else
xTaskCreate(minerWorkerHw, "MinerHw-0", 4096, (void*)0, 3, &minerTask1);
#endif
#else
#if defined(CONFIG_IDF_TARGET_ESP32)
xTaskCreate(minerWorkerSw, "MinerSw-0", 5000, (void*)0, 1, &minerTask1); // Reduced for ESP32 classic
#else
xTaskCreate(minerWorkerSw, "MinerSw-0", 6000, (void*)0, 1, &minerTask1);
#endif
#endif
esp_task_wdt_add(minerTask1);

#if (SOC_CPU_CORES_NUM >= 2)
#if defined(CONFIG_IDF_TARGET_ESP32)
xTaskCreate(minerWorkerSw, "MinerSw-1", 5000, (void*)1, 1, &minerTask2); // Reduced for ESP32 classic
#else
xTaskCreate(minerWorkerSw, "MinerSw-1", 6000, (void*)1, 1, &minerTask2);
#endif
esp_task_wdt_add(minerTask2);
#endif

Expand Down
10 changes: 5 additions & 5 deletions src/drivers/displays/tDisplayV1Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ void tDisplay_BTCprice(unsigned long mElapsed)

// Hashrate
render.setFontSize(25);
render.setCursor(19, 122);
render.setCursor(19, 120);
render.setFontColor(TFT_BLACK);
render.rdrawString(data.currentHashRate.c_str(), 70, 103, TFT_BLACK);

Expand All @@ -222,11 +222,11 @@ void tDisplay_BTCprice(unsigned long mElapsed)
background.drawString(data.currentTime.c_str(), 148, 1, GFXFF);

// Print BTC Price
background.setFreeFont(FF24);
background.setTextDatum(TR_DATUM);
background.setFreeFont(FF23);
background.setTextDatum(TL_DATUM);
background.setTextSize(1);
background.setTextColor(0xDEDB, TFT_BLACK);
background.drawString(data.btcPrice.c_str(), 70, 25, GFXFF);
background.drawString(data.btcPrice.c_str(), 82, 50, GFXFF);

// Push prepared background to screen
background.pushSprite(0, 0);
Expand All @@ -253,7 +253,7 @@ void tDisplay_DoLedStuff(unsigned long frame)
{
}

CyclicScreenFunction tDisplayCyclicScreens[] = {tDisplay_MinerScreen, tDisplay_ClockScreen, tDisplay_GlobalHashScreen};
CyclicScreenFunction tDisplayCyclicScreens[] = {tDisplay_MinerScreen, tDisplay_ClockScreen, tDisplay_GlobalHashScreen, tDisplay_BTCprice};

DisplayDriver tDisplayV1Driver = {
tDisplay_Init,
Expand Down
66 changes: 37 additions & 29 deletions src/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,24 @@
#include <list>
#include <map>
#include "mbedtls/sha256.h"
//I2C mining support (disabled by default for performance)
#ifdef ENABLE_I2C_MINING
#include "i2c_master.h"
#define I2C_SLAVE_ENABLED
#endif

//10 Jobs per second
#define NONCE_PER_JOB_SW 4096
#define NONCE_PER_JOB_HW 16*1024

//#define I2C_SLAVE
// Reduce memory usage for ESP32 classic to prevent crashes
#if defined(CONFIG_IDF_TARGET_ESP32)
#define NONCE_PER_JOB_SW 2048 // Reduced from 4096
#define NONCE_PER_JOB_HW 8*1024 // Reduced from 16*1024
#define JOB_QUEUE_SIZE 2 // Reduced queue size
#define RESULT_QUEUE_SIZE 8 // Reduced result queue
#else
#define NONCE_PER_JOB_SW 4096 // Normal for S3/S2/C3
#define NONCE_PER_JOB_HW 16*1024
#define JOB_QUEUE_SIZE 4 // Normal queue size
#define RESULT_QUEUE_SIZE 16 // Normal result queue
#endif

//#define SHA256_VALIDATE
//#define RANDOM_NONCE
Expand Down Expand Up @@ -93,8 +104,11 @@ bool checkPoolConnection(void) {
//Try connecting pool IP
if (!client.connect(serverIP, Settings.PoolPort)) {
Serial.println("Imposible to connect to : " + Settings.PoolAddress);
WiFi.hostByName(Settings.PoolAddress.c_str(), serverIP);
Serial.printf("Resolved DNS got: %s\n", serverIP.toString());
// Only retry DNS resolution if we have an invalid IP
if (serverIP == IPAddress(1,1,1,1)) {
WiFi.hostByName(Settings.PoolAddress.c_str(), serverIP);
Serial.printf("Resolved DNS got: %s\n", serverIP.toString());
}
return false;
}

Expand Down Expand Up @@ -229,7 +243,7 @@ void runStratumWorker(void *name) {

std::map<uint32_t, std::shared_ptr<Submition>> s_submition_map;

#ifdef I2C_SLAVE
#ifdef I2C_SLAVE_ENABLED_ENABLED
std::vector<uint8_t> i2c_slave_vector;

//scan for i2c slaves
Expand Down Expand Up @@ -330,7 +344,8 @@ void runStratumWorker(void *name) {
//Read pending messages from pool
while(client.connected() && client.available())
{
String line = client.readStringUntil('\n');
static String line; // Reutilizar el mismo objeto String
line = client.readStringUntil('\n');
//Serial.println(" Received message from pool");
stratum_method result = parse_mining_method(line);
switch (result)
Expand Down Expand Up @@ -384,7 +399,7 @@ void runStratumWorker(void *name) {
#ifdef RANDOM_NONCE
nonce_pool = RandomGet() & RANDOM_NONCE_MASK;
#else
#ifdef I2C_SLAVE
#ifdef I2C_SLAVE_ENABLED
if (!i2c_slave_vector.empty())
nonce_pool = 0x10000000;
else
Expand Down Expand Up @@ -419,7 +434,7 @@ void runStratumWorker(void *name) {
#endif
}
}
#ifdef I2C_SLAVE
#ifdef I2C_SLAVE_ENABLED
//Nonce for nonce_pool starts from 0x10000000
//For i2c slave we give nonces from 0x20000000, that is 0x10000000 nonces per slave
i2c_feed_slaves(i2c_slave_vector, job_pool & 0xFF, 0x20, currentPoolDifficulty, mMiner.bytearray_blockheader);
Expand Down Expand Up @@ -468,7 +483,7 @@ void runStratumWorker(void *name) {
}

std::list<std::shared_ptr<JobResult>> job_result_list;
#ifdef I2C_SLAVE
#ifdef I2C_SLAVE_ENABLED
if (i2c_slave_vector.empty() || job_pool == 0xFFFFFFFF)
{
vTaskDelay(50 / portTICK_PERIOD_MS); //Small delay
Expand Down Expand Up @@ -516,7 +531,7 @@ void runStratumWorker(void *name) {
s_job_result_list.clear();

#if 1
while (s_job_request_list_sw.size() < 4)
while (s_job_request_list_sw.size() < JOB_QUEUE_SIZE)
{
JobPush( s_job_request_list_sw, job_pool, nonce_pool, NONCE_PER_JOB_SW, currentPoolDifficulty, mMiner.bytearray_blockheader, diget_mid, bake);
#ifdef RANDOM_NONCE
Expand All @@ -528,7 +543,7 @@ void runStratumWorker(void *name) {
#endif

#ifdef HARDWARE_SHA265
while (s_job_request_list_hw.size() < 4)
while (s_job_request_list_hw.size() < JOB_QUEUE_SIZE)
{
#if defined(CONFIG_IDF_TARGET_ESP32)
JobPush( s_job_request_list_hw, job_pool, nonce_pool, NONCE_PER_JOB_HW, currentPoolDifficulty, sha_buffer_swap, hw_midstate, bake);
Expand Down Expand Up @@ -598,7 +613,7 @@ void minerWorkerSw(void * task_id)
std::lock_guard<std::mutex> lock(s_job_mutex);
if (result)
{
if (s_job_result_list.size() < 16)
if (s_job_result_list.size() < RESULT_QUEUE_SIZE)
s_job_result_list.push_back(result);
result.reset();
}
Expand Down Expand Up @@ -804,7 +819,7 @@ void minerWorkerHw(void * task_id)
std::lock_guard<std::mutex> lock(s_job_mutex);
if (result)
{
if (s_job_result_list.size() < 16)
if (s_job_result_list.size() < RESULT_QUEUE_SIZE)
s_job_result_list.push_back(result);
result.reset();
}
Expand Down Expand Up @@ -835,17 +850,13 @@ void minerWorkerHw(void * task_id)
uint32_t nend = job->nonce_start + job->nonce_count;
for (uint32_t n = job->nonce_start; n < nend; ++n)
{
//nerd_sha_hal_wait_idle();
nerd_sha_ll_write_digest(digest_mid);
//nerd_sha_hal_wait_idle();
nerd_sha_ll_fill_text_block_sha256(sha_buffer, n);
//sha_ll_continue_block(SHA2_256);
REG_WRITE(SHA_CONTINUE_REG, 1);

sha_ll_load(SHA2_256);
nerd_sha_hal_wait_idle();
nerd_sha_ll_fill_text_block_sha256_inter();
//sha_ll_start_block(SHA2_256);
REG_WRITE(SHA_START_REG, 1);
sha_ll_load(SHA2_256);
nerd_sha_hal_wait_idle();
Expand Down Expand Up @@ -1045,7 +1056,7 @@ void minerWorkerHw(void * task_id)
std::lock_guard<std::mutex> lock(s_job_mutex);
if (result)
{
if (s_job_result_list.size() < 16)
if (s_job_result_list.size() < RESULT_QUEUE_SIZE)
s_job_result_list.push_back(result);
result.reset();
}
Expand All @@ -1067,32 +1078,27 @@ void minerWorkerHw(void * task_id)
memcpy(sha_buffer, job->sha_buffer, 80);

esp_sha_lock_engine(SHA2_256);
uint32_t processed_nonces = 0; // Track actually processed nonces
for (uint32_t n = 0; n < job->nonce_count; ++n)
{
//((uint32_t*)(sha_buffer+64+12))[0] = __builtin_bswap32(job->nonce_start+n);

//sha_hal_hash_block(SHA2_256, s_test_buffer, 64/4, true);
//nerd_sha_hal_wait_idle();
nerd_sha_ll_fill_text_block_sha256(sha_buffer);
sha_ll_start_block(SHA2_256);

//sha_hal_hash_block(SHA2_256, s_test_buffer+64, 64/4, false);
nerd_sha_hal_wait_idle();
nerd_sha_ll_fill_text_block_sha256_upper(sha_buffer+64, job->nonce_start+n);
sha_ll_continue_block(SHA2_256);

nerd_sha_hal_wait_idle();
sha_ll_load(SHA2_256);

//sha_hal_hash_block(SHA2_256, interResult, 64/4, true);
nerd_sha_hal_wait_idle();
nerd_sha_ll_fill_text_block_sha256_double();
sha_ll_start_block(SHA2_256);

nerd_sha_hal_wait_idle();
sha_ll_load(SHA2_256);
if (nerd_sha_ll_read_digest_swap_if(hash))
{
processed_nonces++; // Only count successful hash operations
//~5 per second
double diff_hash = diff_from_target(hash);
if (diff_hash > result->difficulty)
Expand All @@ -1109,10 +1115,12 @@ void minerWorkerHw(void * task_id)
(uint8_t)(n & 0xFF) == 0 &&
s_working_current_job_id != job_in_work)
{
result->nonce_count = n+1;
result->nonce_count = processed_nonces; // Use actual processed count
break;
}
}
// Update final count with actual processed nonces
result->nonce_count = processed_nonces;
esp_sha_unlock_engine(SHA2_256);
} else
vTaskDelay(2 / portTICK_PERIOD_MS);
Expand Down
Loading