From af22994402456d1150865ed9b5e19c441b21e723 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 12 Jun 2023 20:08:31 -0400 Subject: [PATCH] Move the asic response handling into its own task --- components/bm1397/serial.c | 2 +- main/CMakeLists.txt | 1 + main/global_state.h | 2 + main/miner.c | 4 +- main/tasks/asic_result_task.c | 105 ++++++++++++++++++++++++++++++++++ main/tasks/asic_result_task.h | 6 ++ main/tasks/asic_task.c | 99 ++++++-------------------------- main/tasks/asic_task.h | 10 +++- 8 files changed, 143 insertions(+), 86 deletions(-) create mode 100644 main/tasks/asic_result_task.c create mode 100644 main/tasks/asic_result_task.h diff --git a/components/bm1397/serial.c b/components/bm1397/serial.c index 9d4535e5..3cc55f15 100644 --- a/components/bm1397/serial.c +++ b/components/bm1397/serial.c @@ -38,7 +38,7 @@ void SERIAL_init(void) { //Install UART driver (we don't need an event queue here) //tx buffer 0 so the tx time doesn't overlap with the job wait time // by returning before the job is written - uart_driver_install(UART_NUM_1, BUF_SIZE * 2, 0, 0, NULL, 0); + uart_driver_install(UART_NUM_1, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0); } void SERIAL_set_baud(int baud){ diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 839ed9d4..99f00b8c 100755 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -13,6 +13,7 @@ SRCS "./tasks/stratum_task.c" "./tasks/create_jobs_task.c" "./tasks/asic_task.c" + "./tasks/asic_result_task.c" INCLUDE_DIRS "." "tasks" diff --git a/main/global_state.h b/main/global_state.h index 6d6938fe..7e6c4a7a 100644 --- a/main/global_state.h +++ b/main/global_state.h @@ -5,6 +5,7 @@ #include "bm1397.h" #include "system.h" #include "stratum_api.h" +#include "asic_task.h" @@ -17,6 +18,7 @@ typedef struct { bm1397Module BM1397_MODULE; SystemModule SYSTEM_MODULE; + AsicTaskModule ASIC_TASK_MODULE; char * extranonce_str; diff --git a/main/miner.c b/main/miner.c index 884eed5d..4474e085 100755 --- a/main/miner.c +++ b/main/miner.c @@ -11,6 +11,7 @@ #include "create_jobs_task.h" #include "global_state.h" #include "serial.h" +#include "asic_result_task.h" static GlobalState GLOBAL_STATE = { .extranonce_str = NULL, @@ -45,8 +46,9 @@ void app_main(void) BM1397_init(); - xTaskCreate(stratum_task, "stratum admin", 8192, (void*)&GLOBAL_STATE, 15, NULL); + xTaskCreate(stratum_task, "stratum admin", 8192, (void*)&GLOBAL_STATE, 5, NULL); xTaskCreate(create_jobs_task, "stratum miner", 8192, (void*)&GLOBAL_STATE, 10, NULL); xTaskCreate(ASIC_task, "asic", 8192, (void*)&GLOBAL_STATE, 10, NULL); + xTaskCreate(ASIC_result_task, "asic result", 8192, (void*)&GLOBAL_STATE, 15, NULL); } diff --git a/main/tasks/asic_result_task.c b/main/tasks/asic_result_task.c new file mode 100644 index 00000000..6192dd75 --- /dev/null +++ b/main/tasks/asic_result_task.c @@ -0,0 +1,105 @@ +#include "global_state.h" +#include "work_queue.h" +#include "serial.h" +#include "bm1397.h" +#include +#include "esp_log.h" + +const char * TAG = "asic_result"; + +void ASIC_result_task(void * pvParameters) +{ + + GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters; + + uint8_t buf[CHUNK_SIZE]; + memset(buf, 0, 1024); + SERIAL_clear_buffer(); + uint32_t prev_nonce = 0; + + while(1){ + + //wait for a response, wait time is pretty arbitrary + int received = SERIAL_rx(buf, 9, 60000); + + if (received < 0) { + ESP_LOGI(TAG, "Error in serial RX"); + continue; + } else if(received == 0){ + // Didn't find a solution, restart and try again + continue; + } + + if(received != 9 || buf[0] != 0xAA || buf[1] != 0x55){ + ESP_LOGI(TAG, "Serial RX invalid %i", received); + ESP_LOG_BUFFER_HEX(TAG, buf, received); + continue; + } + + uint8_t nonce_found = 0; + uint32_t first_nonce = 0; + + struct nonce_response nonce; + memcpy((void *) &nonce, buf, sizeof(struct nonce_response)); + + uint8_t rx_job_id = nonce.job_id & 0xfc; + uint8_t rx_midstate_index = nonce.job_id & 0x03; + + if (GLOBAL_STATE->valid_jobs[rx_job_id] == 0) { + ESP_LOGI(TAG, "Invalid job nonce found, id=%d", nonce.job_id); + } + + // ASIC may return the same nonce multiple times + // or one that was already found + // most of the time it behavies however + if (nonce_found == 0) { + first_nonce = nonce.nonce; + nonce_found = 1; + } else if (nonce.nonce == first_nonce) { + // stop if we've already seen this nonce + break; + } + + if (nonce.nonce == prev_nonce) { + continue; + } else { + prev_nonce = nonce.nonce; + } + + // check the nonce difficulty + double nonce_diff = test_nonce_value( + GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id], + nonce.nonce, + rx_midstate_index + ); + + ESP_LOGI(TAG, "Nonce difficulty %.2f of %d.", nonce_diff, GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->pool_diff); + + if (nonce_diff > GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->pool_diff) + { + SYSTEM_notify_found_nonce( + &GLOBAL_STATE->SYSTEM_MODULE, + GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->pool_diff, + nonce_diff, + GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->target + ); + + uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version; + for (int i = 0; i < rx_midstate_index; i++) { + rolled_version = increment_bitmask(rolled_version, GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version_mask); + } + + STRATUM_V1_submit_share( + GLOBAL_STATE->sock, + STRATUM_USER, + GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->jobid, + GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->extranonce2, + GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->ntime, + nonce.nonce, + rolled_version ^ GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version + ); + } + + } + +} \ No newline at end of file diff --git a/main/tasks/asic_result_task.h b/main/tasks/asic_result_task.h new file mode 100644 index 00000000..c97b84e9 --- /dev/null +++ b/main/tasks/asic_result_task.h @@ -0,0 +1,6 @@ +#ifndef ASIC_result_TASK_H_ +#define ASIC_result_TASK_H_ + +void ASIC_result_task(void * pvParameters); + +#endif \ No newline at end of file diff --git a/main/tasks/asic_task.c b/main/tasks/asic_task.c index f5673a7a..070b990c 100644 --- a/main/tasks/asic_task.c +++ b/main/tasks/asic_task.c @@ -5,32 +5,30 @@ #include #include "esp_log.h" +#include "driver/i2c.h" + + static const char *TAG = "ASIC_task"; // static bm_job ** active_jobs; is required to keep track of the active jobs since the -// ASIC may not return the nonce in the same order as the jobs were sent -// it also may return a previous nonce under some circumstances -// so we keep a list of jobs indexed by the job id -static bm_job ** active_jobs; + void ASIC_task(void * pvParameters) { GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters; - uint8_t buf[CHUNK_SIZE]; - memset(buf, 0, 1024); uint8_t id = 0; - active_jobs = malloc(sizeof(bm_job *) * 128); + GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128); GLOBAL_STATE->valid_jobs = malloc(sizeof(uint8_t) * 128); for (int i = 0; i < 128; i++) { - active_jobs[i] = NULL; + GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[i] = NULL; GLOBAL_STATE->valid_jobs[i] = 0; } - uint32_t prev_nonce = 0; + int baud = BM1397_set_max_baud(); SERIAL_set_baud(baud); @@ -38,6 +36,7 @@ void ASIC_task(void * pvParameters) SYSTEM_notify_mining_started(&GLOBAL_STATE->SYSTEM_MODULE); ESP_LOGI(TAG, "ASIC Ready!"); while (1) { + bm_job * next_bm_job = (bm_job *) queue_dequeue(&GLOBAL_STATE->ASIC_jobs_queue); if(next_bm_job->pool_diff != GLOBAL_STATE->stratum_difficulty){ @@ -68,89 +67,23 @@ void ASIC_task(void * pvParameters) memcpy(job.midstate3, next_bm_job->midstate3, 32); } - if (active_jobs[job.job_id] != NULL) { - free_bm_job(active_jobs[job.job_id]); + if (GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) { + free_bm_job(GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id]); } - active_jobs[job.job_id] = next_bm_job; + GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] = next_bm_job; pthread_mutex_lock(&GLOBAL_STATE->valid_jobs_lock); GLOBAL_STATE-> valid_jobs[job.job_id] = 1; pthread_mutex_unlock(&GLOBAL_STATE->valid_jobs_lock); - SERIAL_clear_buffer(); + + + BM1397_send_work(&job); //send the job to the ASIC - //wait for a response - int received = SERIAL_rx(buf, 9, BM1397_FULLSCAN_MS); + //Time to execute the above code is ~0.3ms + vTaskDelay((BM1397_FULLSCAN_MS - 0.3 ) / portTICK_RATE_MS); - if (received < 0) { - ESP_LOGI(TAG, "Error in serial RX"); - continue; - } else if(received == 0){ - // Didn't find a solution, restart and try again - continue; - } - - if(received != 9 || buf[0] != 0xAA || buf[1] != 0x55){ - ESP_LOGI(TAG, "Serial RX invalid %i", received); - ESP_LOG_BUFFER_HEX(TAG, buf, received); - continue; - } - - uint8_t nonce_found = 0; - uint32_t first_nonce = 0; - - struct nonce_response nonce; - memcpy((void *) &nonce, buf, sizeof(struct nonce_response)); - - uint8_t rx_job_id = nonce.job_id & 0xfc; - uint8_t rx_midstate_index = nonce.job_id & 0x03; - - if (GLOBAL_STATE->valid_jobs[rx_job_id] == 0) { - ESP_LOGI(TAG, "Invalid job nonce found, id=%d", nonce.job_id); - } - - // ASIC may return the same nonce multiple times - // or one that was already found - // most of the time it behavies however - if (nonce_found == 0) { - first_nonce = nonce.nonce; - nonce_found = 1; - } else if (nonce.nonce == first_nonce) { - // stop if we've already seen this nonce - break; - } - - if (nonce.nonce == prev_nonce) { - continue; - } else { - prev_nonce = nonce.nonce; - } - - // check the nonce difficulty - double nonce_diff = test_nonce_value(active_jobs[rx_job_id], nonce.nonce, rx_midstate_index); - - ESP_LOGI(TAG, "Nonce difficulty %.2f of %d.", nonce_diff, active_jobs[rx_job_id]->pool_diff); - - if (nonce_diff > active_jobs[rx_job_id]->pool_diff) - { - SYSTEM_notify_found_nonce(&GLOBAL_STATE->SYSTEM_MODULE, active_jobs[rx_job_id]->pool_diff, nonce_diff, next_bm_job->target); - - uint32_t rolled_version = active_jobs[rx_job_id]->version; - for (int i = 0; i < rx_midstate_index; i++) { - rolled_version = increment_bitmask(rolled_version, active_jobs[rx_job_id]->version_mask); - } - - STRATUM_V1_submit_share( - GLOBAL_STATE->sock, - STRATUM_USER, - active_jobs[rx_job_id]->jobid, - active_jobs[rx_job_id]->extranonce2, - active_jobs[rx_job_id]->ntime, - nonce.nonce, - rolled_version ^ active_jobs[rx_job_id]->version - ); - } } } diff --git a/main/tasks/asic_task.h b/main/tasks/asic_task.h index b2b63e8a..d92292a7 100644 --- a/main/tasks/asic_task.h +++ b/main/tasks/asic_task.h @@ -1,6 +1,14 @@ #ifndef ASIC_TASK_H_ #define ASIC_TASK_H_ +#include "mining.h" +typedef struct { + // ASIC may not return the nonce in the same order as the jobs were sent +// it also may return a previous nonce under some circumstances +// so we keep a list of jobs indexed by the job id + bm_job ** active_jobs; +} AsicTaskModule; + void ASIC_task(void * pvParameters); -#endif \ No newline at end of file +#endif \ No newline at end of file