mirror of
https://github.com/skot/ESP-Miner.git
synced 2025-03-26 17:51:45 +01:00
Move the asic response handling into its own task
This commit is contained in:
parent
bc326499ea
commit
af22994402
@ -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){
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
105
main/tasks/asic_result_task.c
Normal file
105
main/tasks/asic_result_task.c
Normal file
@ -0,0 +1,105 @@
|
||||
#include "global_state.h"
|
||||
#include "work_queue.h"
|
||||
#include "serial.h"
|
||||
#include "bm1397.h"
|
||||
#include <string.h>
|
||||
#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
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
6
main/tasks/asic_result_task.h
Normal file
6
main/tasks/asic_result_task.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef ASIC_result_TASK_H_
|
||||
#define ASIC_result_TASK_H_
|
||||
|
||||
void ASIC_result_task(void * pvParameters);
|
||||
|
||||
#endif
|
@ -5,32 +5,30 @@
|
||||
#include <string.h>
|
||||
#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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user