diff --git a/components/asic/asic.c b/components/asic/asic.c index 3310577aa..8e41f4ecb 100644 --- a/components/asic/asic.c +++ b/components/asic/asic.c @@ -1,55 +1,51 @@ #include - #include - #include "bm1397.h" #include "bm1366.h" #include "bm1368.h" #include "bm1370.h" - #include "asic.h" #include "device_config.h" +#include "power_management_module.h" #include "frequency_transition_bmXX.h" -static const double NONCE_SPACE = 4294967296.0; // 2^32 - static const char *TAG = "asic"; -uint8_t ASIC_init(GlobalState * GLOBAL_STATE) +uint8_t ASIC_init() { - ESP_LOGI(TAG, "Initializing %s", GLOBAL_STATE->DEVICE_CONFIG.family.asic.name); + ESP_LOGI(TAG, "Initializing %s", DEVICE_CONFIG.family.asic.name); - switch (GLOBAL_STATE->DEVICE_CONFIG.family.asic.id) { + switch (DEVICE_CONFIG.family.asic.id) { case BM1397: - return BM1397_init(GLOBAL_STATE->POWER_MANAGEMENT_MODULE.frequency_value, GLOBAL_STATE->DEVICE_CONFIG.family.asic_count, GLOBAL_STATE->DEVICE_CONFIG.family.asic.difficulty); + return BM1397_init(POWER_MANAGEMENT_MODULE.frequency_value, DEVICE_CONFIG.family.asic_count, DEVICE_CONFIG.family.asic.difficulty); case BM1366: - return BM1366_init(GLOBAL_STATE->POWER_MANAGEMENT_MODULE.frequency_value, GLOBAL_STATE->DEVICE_CONFIG.family.asic_count, GLOBAL_STATE->DEVICE_CONFIG.family.asic.difficulty); + return BM1366_init(POWER_MANAGEMENT_MODULE.frequency_value, DEVICE_CONFIG.family.asic_count, DEVICE_CONFIG.family.asic.difficulty); case BM1368: - return BM1368_init(GLOBAL_STATE->POWER_MANAGEMENT_MODULE.frequency_value, GLOBAL_STATE->DEVICE_CONFIG.family.asic_count, GLOBAL_STATE->DEVICE_CONFIG.family.asic.difficulty); + return BM1368_init(POWER_MANAGEMENT_MODULE.frequency_value, DEVICE_CONFIG.family.asic_count, DEVICE_CONFIG.family.asic.difficulty); case BM1370: - return BM1370_init(GLOBAL_STATE->POWER_MANAGEMENT_MODULE.frequency_value, GLOBAL_STATE->DEVICE_CONFIG.family.asic_count, GLOBAL_STATE->DEVICE_CONFIG.family.asic.difficulty); + return BM1370_init(POWER_MANAGEMENT_MODULE.frequency_value, DEVICE_CONFIG.family.asic_count, DEVICE_CONFIG.family.asic.difficulty); } return ESP_OK; } -task_result * ASIC_process_work(GlobalState * GLOBAL_STATE) +task_result * ASIC_process_work() { - switch (GLOBAL_STATE->DEVICE_CONFIG.family.asic.id) { + switch (DEVICE_CONFIG.family.asic.id) { case BM1397: - return BM1397_process_work(GLOBAL_STATE); + return BM1397_process_work(); case BM1366: - return BM1366_process_work(GLOBAL_STATE); + return BM1366_process_work(); case BM1368: - return BM1368_process_work(GLOBAL_STATE); + return BM1368_process_work(); case BM1370: - return BM1370_process_work(GLOBAL_STATE); + return BM1370_process_work(); } return NULL; } -int ASIC_set_max_baud(GlobalState * GLOBAL_STATE) +int ASIC_set_max_baud() { - switch (GLOBAL_STATE->DEVICE_CONFIG.family.asic.id) { + switch (DEVICE_CONFIG.family.asic.id) { case BM1397: return BM1397_set_max_baud(); case BM1366: @@ -62,27 +58,27 @@ int ASIC_set_max_baud(GlobalState * GLOBAL_STATE) return 0; } -void ASIC_send_work(GlobalState * GLOBAL_STATE, void * next_job) +void ASIC_send_work(void * next_job) { - switch (GLOBAL_STATE->DEVICE_CONFIG.family.asic.id) { + switch (DEVICE_CONFIG.family.asic.id) { case BM1397: - BM1397_send_work(GLOBAL_STATE, next_job); + BM1397_send_work(next_job); break; case BM1366: - BM1366_send_work(GLOBAL_STATE, next_job); + BM1366_send_work(next_job); break; case BM1368: - BM1368_send_work(GLOBAL_STATE, next_job); + BM1368_send_work(next_job); break; case BM1370: - BM1370_send_work(GLOBAL_STATE, next_job); + BM1370_send_work(next_job); break; } } -void ASIC_set_version_mask(GlobalState * GLOBAL_STATE, uint32_t mask) +void ASIC_set_version_mask(uint32_t mask) { - switch (GLOBAL_STATE->DEVICE_CONFIG.family.asic.id) { + switch (DEVICE_CONFIG.family.asic.id) { case BM1397: BM1397_set_version_mask(mask); break; @@ -98,36 +94,21 @@ void ASIC_set_version_mask(GlobalState * GLOBAL_STATE, uint32_t mask) } } -bool ASIC_set_frequency(GlobalState * GLOBAL_STATE, float frequency) +bool ASIC_set_frequency(float target_frequency) { - switch (GLOBAL_STATE->DEVICE_CONFIG.family.asic.id) { + switch (DEVICE_CONFIG.family.asic.id) { case BM1397: ESP_LOGE(TAG, "Frequency transition not implemented for BM1397"); return false; case BM1366: - do_frequency_transition(frequency, BM1366_send_hash_frequency); + do_frequency_transition(target_frequency, BM1366_send_hash_frequency); return true; case BM1368: - do_frequency_transition(frequency, BM1368_send_hash_frequency); + do_frequency_transition(target_frequency, BM1368_send_hash_frequency); return true; case BM1370: - do_frequency_transition(frequency, BM1370_send_hash_frequency); + do_frequency_transition(target_frequency, BM1370_send_hash_frequency); return true; } return false; } - -double ASIC_get_asic_job_frequency_ms(GlobalState * GLOBAL_STATE) -{ - switch (GLOBAL_STATE->DEVICE_CONFIG.family.asic.id) { - case BM1397: - // no version-rolling so same Nonce Space is splitted between Small Cores - return (NONCE_SPACE / (double) (GLOBAL_STATE->POWER_MANAGEMENT_MODULE.frequency_value * GLOBAL_STATE->DEVICE_CONFIG.family.asic.small_core_count * 1000)) / (double) GLOBAL_STATE->DEVICE_CONFIG.family.asic_count; - case BM1366: - return 2000; - case BM1368: - case BM1370: - return 500; - } - return 500; -} diff --git a/components/asic/bm1366.c b/components/asic/bm1366.c index 10050345a..063c0c3fb 100644 --- a/components/asic/bm1366.c +++ b/components/asic/bm1366.c @@ -1,10 +1,9 @@ #include "bm1366.h" #include "crc.h" -#include "global_state.h" #include "serial.h" #include "utils.h" - +#include "asic_task_module.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -254,10 +253,9 @@ int BM1366_set_max_baud(void) static uint8_t id = 0; -void BM1366_send_work(void * pvParameters, bm_job * next_bm_job) +void BM1366_send_work(bm_job * next_bm_job) { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; BM1366_job job; id = (id + 8) % 128; @@ -270,15 +268,15 @@ void BM1366_send_work(void * pvParameters, bm_job * next_bm_job) memcpy(job.prev_block_hash, next_bm_job->prev_block_hash_be, 32); memcpy(&job.version, &next_bm_job->version, 4); - 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]); + if (ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) { + free_bm_job(ASIC_TASK_MODULE.active_jobs[job.job_id]); } - GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] = next_bm_job; + 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); + pthread_mutex_lock(&ASIC_TASK_MODULE.valid_jobs_lock); + ASIC_TASK_MODULE.valid_jobs[job.job_id] = 1; + pthread_mutex_unlock(&ASIC_TASK_MODULE.valid_jobs_lock); //debug sent jobs - this can get crazy if the interval is short #if BM1366_DEBUG_JOBS @@ -288,7 +286,7 @@ void BM1366_send_work(void * pvParameters, bm_job * next_bm_job) _send_BM1366((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t *)&job, sizeof(BM1366_job), BM1366_DEBUG_WORK); } -task_result * BM1366_process_work(void * pvParameters) +task_result * BM1366_process_work() { bm1366_asic_result_t asic_result = {0}; @@ -302,14 +300,13 @@ task_result * BM1366_process_work(void * pvParameters) uint32_t version_bits = (ntohs(asic_result.version) << 13); // shift the 16 bit value left 13 ESP_LOGI(TAG, "Job ID: %02X, Core: %d/%d, Ver: %08" PRIX32, job_id, core_id, small_core_id, version_bits); - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - if (GLOBAL_STATE->valid_jobs[job_id] == 0) { + if (ASIC_TASK_MODULE.valid_jobs[job_id] == 0) { ESP_LOGW(TAG, "Invalid job found, 0x%02X", job_id); return NULL; } - uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->version | version_bits; + uint32_t rolled_version = ASIC_TASK_MODULE.active_jobs[job_id]->version | version_bits; result.job_id = job_id; result.nonce = asic_result.nonce; diff --git a/components/asic/bm1368.c b/components/asic/bm1368.c index 696bd987d..d16665246 100644 --- a/components/asic/bm1368.c +++ b/components/asic/bm1368.c @@ -1,7 +1,7 @@ #include "bm1368.h" #include "crc.h" -#include "global_state.h" +#include "asic_task_module.h" #include "serial.h" #include "utils.h" @@ -201,9 +201,8 @@ int BM1368_set_max_baud(void) static uint8_t id = 0; -void BM1368_send_work(void * pvParameters, bm_job * next_bm_job) +void BM1368_send_work(bm_job * next_bm_job) { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; BM1368_job job; id = (id + 24) % 128; @@ -216,15 +215,15 @@ void BM1368_send_work(void * pvParameters, bm_job * next_bm_job) memcpy(job.prev_block_hash, next_bm_job->prev_block_hash_be, 32); memcpy(&job.version, &next_bm_job->version, 4); - 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]); + if (ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) { + free_bm_job(ASIC_TASK_MODULE.active_jobs[job.job_id]); } - GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] = next_bm_job; + 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); + pthread_mutex_lock(&ASIC_TASK_MODULE.valid_jobs_lock); + ASIC_TASK_MODULE.valid_jobs[job.job_id] = 1; + pthread_mutex_unlock(&ASIC_TASK_MODULE.valid_jobs_lock); #if BM1368_DEBUG_JOBS ESP_LOGI(TAG, "Send Job: %02X", job.job_id); @@ -233,7 +232,7 @@ void BM1368_send_work(void * pvParameters, bm_job * next_bm_job) _send_BM1368((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t *)&job, sizeof(BM1368_job), BM1368_DEBUG_WORK); } -task_result * BM1368_process_work(void * pvParameters) +task_result * BM1368_process_work() { bm1368_asic_result_t asic_result = {0}; @@ -247,14 +246,13 @@ task_result * BM1368_process_work(void * pvParameters) uint32_t version_bits = (ntohs(asic_result.version) << 13); ESP_LOGI(TAG, "Job ID: %02X, Core: %d/%d, Ver: %08" PRIX32, job_id, core_id, small_core_id, version_bits); - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - if (GLOBAL_STATE->valid_jobs[job_id] == 0) { + if (ASIC_TASK_MODULE.valid_jobs[job_id] == 0) { ESP_LOGW(TAG, "Invalid job found, 0x%02X", job_id); return NULL; } - uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->version | version_bits; + uint32_t rolled_version = ASIC_TASK_MODULE.active_jobs[job_id]->version | version_bits; result.job_id = job_id; result.nonce = asic_result.nonce; diff --git a/components/asic/bm1370.c b/components/asic/bm1370.c index 38b759c1c..82d357312 100644 --- a/components/asic/bm1370.c +++ b/components/asic/bm1370.c @@ -1,7 +1,7 @@ #include "bm1370.h" #include "crc.h" -#include "global_state.h" +#include "asic_task_module.h" #include "serial.h" #include "utils.h" @@ -11,12 +11,13 @@ #include "frequency_transition_bmXX.h" #include "pll.h" +#include #include #include #include #include #include -#include +#include #define BM1370_CHIP_ID 0x1370 #define BM1370_CHIP_ID_RESPONSE_LENGTH 11 @@ -34,6 +35,7 @@ #define MISC_CONTROL 0x18 + typedef struct __attribute__((__packed__)) { uint16_t preamble; @@ -281,10 +283,8 @@ int BM1370_set_max_baud(void) static uint8_t id = 0; -void BM1370_send_work(void * pvParameters, bm_job * next_bm_job) +void BM1370_send_work(bm_job * next_bm_job) { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - BM1370_job job; id = (id + 24) % 128; job.job_id = id; @@ -296,25 +296,25 @@ void BM1370_send_work(void * pvParameters, bm_job * next_bm_job) memcpy(job.prev_block_hash, next_bm_job->prev_block_hash_be, 32); memcpy(&job.version, &next_bm_job->version, 4); - 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]); + if (ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) { + free_bm_job(ASIC_TASK_MODULE.active_jobs[job.job_id]); } - GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] = next_bm_job; + 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); + pthread_mutex_lock(&ASIC_TASK_MODULE.valid_jobs_lock); + ASIC_TASK_MODULE.valid_jobs[job.job_id] = 1; + pthread_mutex_unlock(&ASIC_TASK_MODULE.valid_jobs_lock); - //debug sent jobs - this can get crazy if the interval is short - #if BM1370_DEBUG_JOBS +// debug sent jobs - this can get crazy if the interval is short +#if BM1370_DEBUG_JOBS ESP_LOGI(TAG, "Send Job: %02X", job.job_id); - #endif +#endif - _send_BM1370((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t *)&job, sizeof(BM1370_job), BM1370_DEBUG_WORK); + _send_BM1370((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t *) &job, sizeof(BM1370_job), BM1370_DEBUG_WORK); } -task_result * BM1370_process_work(void * pvParameters) +task_result * BM1370_process_work() { bm1370_asic_result_t asic_result = {0}; @@ -335,14 +335,12 @@ task_result * BM1370_process_work(void * pvParameters) uint32_t version_bits = (ntohs(asic_result.version) << 13); // shift the 16 bit value left 13 ESP_LOGI(TAG, "Job ID: %02X, Core: %d/%d, Ver: %08" PRIX32, job_id, core_id, small_core_id, version_bits); - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - - if (GLOBAL_STATE->valid_jobs[job_id] == 0) { + if (ASIC_TASK_MODULE.valid_jobs[job_id] == 0) { ESP_LOGW(TAG, "Invalid job nonce found, 0x%02X", job_id); return NULL; } - uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->version | version_bits; + uint32_t rolled_version = ASIC_TASK_MODULE.active_jobs[job_id]->version | version_bits; result.job_id = job_id; result.nonce = asic_result.nonce; diff --git a/components/asic/bm1397.c b/components/asic/bm1397.c index 18eac0926..cf9538a47 100644 --- a/components/asic/bm1397.c +++ b/components/asic/bm1397.c @@ -14,7 +14,7 @@ #include "utils.h" #include "crc.h" #include "mining.h" -#include "global_state.h" +#include "asic_task_module.h" #include "pll.h" #define BM1397_CHIP_ID 0x1397 @@ -295,9 +295,9 @@ int BM1397_set_max_baud(void) static uint8_t id = 0; -void BM1397_send_work(void *pvParameters, bm_job *next_bm_job) +void BM1397_send_work(bm_job *next_bm_job) { - GlobalState *GLOBAL_STATE = (GlobalState *)pvParameters; + job_packet job; // max job number is 128 @@ -320,16 +320,16 @@ void BM1397_send_work(void *pvParameters, bm_job *next_bm_job) memcpy(job.midstate3, next_bm_job->midstate3, 32); } - if (GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) + if (ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) { - free_bm_job(GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id]); + free_bm_job(ASIC_TASK_MODULE.active_jobs[job.job_id]); } - GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] = next_bm_job; + 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); + pthread_mutex_lock(&ASIC_TASK_MODULE.valid_jobs_lock); + ASIC_TASK_MODULE.valid_jobs[job.job_id] = 1; + pthread_mutex_unlock(&ASIC_TASK_MODULE.valid_jobs_lock); #if BM1397_DEBUG_JOBS ESP_LOGI(TAG, "Send Job: %02X", job.job_id); @@ -338,7 +338,7 @@ void BM1397_send_work(void *pvParameters, bm_job *next_bm_job) _send_BM1397((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t *)&job, sizeof(job_packet), BM1397_DEBUG_WORK); } -task_result *BM1397_process_work(void *pvParameters) +task_result *BM1397_process_work() { bm1397_asic_result_t asic_result = {0}; @@ -352,17 +352,17 @@ task_result *BM1397_process_work(void *pvParameters) uint8_t rx_job_id = asic_result.job_id & 0xfc; uint8_t rx_midstate_index = asic_result.job_id & 0x03; - GlobalState *GLOBAL_STATE = (GlobalState *)pvParameters; - if (GLOBAL_STATE->valid_jobs[rx_job_id] == 0) + + if (ASIC_TASK_MODULE.valid_jobs[rx_job_id] == 0) { ESP_LOGW(TAG, "Invalid job nonce found, id=%d", rx_job_id); return NULL; } - uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version; + uint32_t rolled_version = 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); + rolled_version = increment_bitmask(rolled_version, ASIC_TASK_MODULE.active_jobs[rx_job_id]->version_mask); } // ASIC may return the same nonce multiple times diff --git a/components/asic/frequency_transition_bmXX.c b/components/asic/frequency_transition_bmXX.c index 257a121f0..7de19ac8e 100644 --- a/components/asic/frequency_transition_bmXX.c +++ b/components/asic/frequency_transition_bmXX.c @@ -1,7 +1,6 @@ #include "frequency_transition_bmXX.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include #define EPSILON 0.0001f diff --git a/components/asic/include/asic.h b/components/asic/include/asic.h index 74c5dc002..3e9449bc5 100644 --- a/components/asic/include/asic.h +++ b/components/asic/include/asic.h @@ -2,15 +2,14 @@ #define ASIC_H #include -#include "global_state.h" #include "common.h" -uint8_t ASIC_init(GlobalState * GLOBAL_STATE); -task_result * ASIC_process_work(GlobalState * GLOBAL_STATE); -int ASIC_set_max_baud(GlobalState * GLOBAL_STATE); -void ASIC_send_work(GlobalState * GLOBAL_STATE, void * next_job); -void ASIC_set_version_mask(GlobalState * GLOBAL_STATE, uint32_t mask); -bool ASIC_set_frequency(GlobalState * GLOBAL_STATE, float target_frequency); -double ASIC_get_asic_job_frequency_ms(GlobalState * GLOBAL_STATE); + +uint8_t ASIC_init(); +task_result * ASIC_process_work(); +int ASIC_set_max_baud(); +void ASIC_send_work(void * next_job); +void ASIC_set_version_mask(uint32_t mask); +bool ASIC_set_frequency(float target_frequency); #endif // ASIC_H diff --git a/components/asic/include/bm1366.h b/components/asic/include/bm1366.h index 7aab6c60b..ffe4c9de6 100644 --- a/components/asic/include/bm1366.h +++ b/components/asic/include/bm1366.h @@ -22,11 +22,11 @@ typedef struct __attribute__((__packed__)) } BM1366_job; uint8_t BM1366_init(float frequency, uint16_t asic_count, uint16_t difficulty); -void BM1366_send_work(void * GLOBAL_STATE, bm_job * next_bm_job); +void BM1366_send_work(bm_job * next_bm_job); void BM1366_set_version_mask(uint32_t version_mask); int BM1366_set_max_baud(void); int BM1366_set_default_baud(void); void BM1366_send_hash_frequency(float frequency); -task_result * BM1366_process_work(void * GLOBAL_STATE); +task_result * BM1366_process_work(); #endif /* BM1366_H_ */ diff --git a/components/asic/include/bm1368.h b/components/asic/include/bm1368.h index 63848fa15..35786a27a 100644 --- a/components/asic/include/bm1368.h +++ b/components/asic/include/bm1368.h @@ -22,11 +22,11 @@ typedef struct __attribute__((__packed__)) } BM1368_job; uint8_t BM1368_init(float frequency, uint16_t asic_count, uint16_t difficulty); -void BM1368_send_work(void * GLOBAL_STATE, bm_job * next_bm_job); +void BM1368_send_work(bm_job * next_bm_job); void BM1368_set_version_mask(uint32_t version_mask); int BM1368_set_max_baud(void); int BM1368_set_default_baud(void); void BM1368_send_hash_frequency(float frequency); -task_result * BM1368_process_work(void * GLOBAL_STATE); +task_result * BM1368_process_work(); #endif /* BM1368_H_ */ diff --git a/components/asic/include/bm1370.h b/components/asic/include/bm1370.h index 2b618a824..80382f9d8 100644 --- a/components/asic/include/bm1370.h +++ b/components/asic/include/bm1370.h @@ -22,11 +22,11 @@ typedef struct __attribute__((__packed__)) } BM1370_job; uint8_t BM1370_init(float frequency, uint16_t asic_count, uint16_t difficulty); -void BM1370_send_work(void * GLOBAL_STATE, bm_job * next_bm_job); +void BM1370_send_work(bm_job * next_bm_job); void BM1370_set_version_mask(uint32_t version_mask); int BM1370_set_max_baud(void); int BM1370_set_default_baud(void); void BM1370_send_hash_frequency(float frequency); -task_result * BM1370_process_work(void * GLOBAL_STATE); +task_result * BM1370_process_work(); #endif /* BM1370_H_ */ diff --git a/components/asic/include/bm1397.h b/components/asic/include/bm1397.h index 174849a5c..e3b126d50 100644 --- a/components/asic/include/bm1397.h +++ b/components/asic/include/bm1397.h @@ -24,11 +24,11 @@ typedef struct __attribute__((__packed__)) } job_packet; uint8_t BM1397_init(float frequency, uint16_t asic_count, uint16_t difficulty); -void BM1397_send_work(void * GLOBAL_STATE, bm_job * next_bm_job); +void BM1397_send_work(bm_job * next_bm_job); void BM1397_set_version_mask(uint32_t version_mask); int BM1397_set_max_baud(void); int BM1397_set_default_baud(void); void BM1397_send_hash_frequency(float frequency); -task_result * BM1397_process_work(void * GLOBAL_STATE); +task_result * BM1397_process_work(); #endif /* BM1397_H_ */ diff --git a/components/connect/connect.c b/components/connect/connect.c index 673bb4545..fa1a9d681 100644 --- a/components/connect/connect.c +++ b/components/connect/connect.c @@ -11,10 +11,9 @@ #include "lwip/sys.h" #include "nvs_flash.h" #include "esp_wifi_types_generic.h" - #include "connect.h" -#include "global_state.h" #include "nvs_config.h" +#include "wifi_module.h" // Maximum number of access points to scan #define MAX_AP_COUNT 20 @@ -137,7 +136,6 @@ esp_err_t wifi_scan(wifi_ap_record_simple_t *ap_records, uint16_t *ap_count) static void event_handler(void * arg, esp_event_base_t event_base, int32_t event_id, void * event_data) { - GlobalState *GLOBAL_STATE = (GlobalState *)arg; if (event_base == WIFI_EVENT) { if (event_id == WIFI_EVENT_SCAN_DONE) { @@ -156,13 +154,13 @@ static void event_handler(void * arg, esp_event_base_t event_base, int32_t event if (event_id == WIFI_EVENT_STA_START) { ESP_LOGI(TAG, "Connecting..."); - strcpy(GLOBAL_STATE->SYSTEM_MODULE.wifi_status, "Connecting..."); + strcpy(WIFI_MODULE.wifi_status, "Connecting..."); esp_wifi_connect(); } if (event_id == WIFI_EVENT_STA_CONNECTED) { ESP_LOGI(TAG, "Connected!"); - strcpy(GLOBAL_STATE->SYSTEM_MODULE.wifi_status, "Connected!"); + strcpy(WIFI_MODULE.wifi_status, "Connected!"); } if (event_id == WIFI_EVENT_STA_DISCONNECTED) { @@ -176,12 +174,12 @@ static void event_handler(void * arg, esp_event_base_t event_base, int32_t event if (clients_connected_to_ap > 0) { ESP_LOGI(TAG, "Client(s) connected to AP, not retrying..."); - sprintf(GLOBAL_STATE->SYSTEM_MODULE.wifi_status, "Config AP connected!"); + sprintf(WIFI_MODULE.wifi_status, "Config AP connected!"); return; } - sprintf(GLOBAL_STATE->SYSTEM_MODULE.wifi_status, "%s (Error %d, retry #%d)", get_wifi_reason_string(event->reason), event->reason, s_retry_num); - ESP_LOGI(TAG, "Wi-Fi status: %s", GLOBAL_STATE->SYSTEM_MODULE.wifi_status); + sprintf(WIFI_MODULE.wifi_status, "%s (Error %d, retry #%d)", get_wifi_reason_string(event->reason), event->reason, s_retry_num); + ESP_LOGI(TAG, "Wi-Fi status: %s", WIFI_MODULE.wifi_status); // Wait a little vTaskDelay(5000 / portTICK_PERIOD_MS); @@ -193,12 +191,12 @@ static void event_handler(void * arg, esp_event_base_t event_base, int32_t event if (event_id == WIFI_EVENT_AP_START) { ESP_LOGI(TAG, "Configuration Access Point enabled"); - GLOBAL_STATE->SYSTEM_MODULE.ap_enabled = true; + WIFI_MODULE.ap_enabled = true; } if (event_id == WIFI_EVENT_AP_STOP) { ESP_LOGI(TAG, "Configuration Access Point disabled"); - GLOBAL_STATE->SYSTEM_MODULE.ap_enabled = false; + WIFI_MODULE.ap_enabled = false; } if (event_id == WIFI_EVENT_AP_STACONNECTED) { @@ -212,14 +210,14 @@ static void event_handler(void * arg, esp_event_base_t event_base, int32_t event if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t * event = (ip_event_got_ip_t *) event_data; - snprintf(GLOBAL_STATE->SYSTEM_MODULE.ip_addr_str, IP4ADDR_STRLEN_MAX, IPSTR, IP2STR(&event->ip_info.ip)); + snprintf(WIFI_MODULE.ip_addr_str, IP4ADDR_STRLEN_MAX, IPSTR, IP2STR(&event->ip_info.ip)); - ESP_LOGI(TAG, "IP Address: %s", GLOBAL_STATE->SYSTEM_MODULE.ip_addr_str); + ESP_LOGI(TAG, "IP Address: %s", WIFI_MODULE.ip_addr_str); s_retry_num = 0; - GLOBAL_STATE->SYSTEM_MODULE.is_connected = true; + WIFI_MODULE.is_connected = true; - ESP_LOGI(TAG, "Connected to SSID: %s", GLOBAL_STATE->SYSTEM_MODULE.ssid); + ESP_LOGI(TAG, "Connected to SSID: %s", WIFI_MODULE.ssid); wifi_softap_off(); } @@ -326,12 +324,11 @@ esp_netif_t * wifi_init_sta(const char * wifi_ssid, const char * wifi_pass) void wifi_init(void * pvParameters) { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; char * wifi_ssid = nvs_config_get_string(NVS_CONFIG_WIFI_SSID, CONFIG_ESP_WIFI_SSID); // copy the wifi ssid to the global state - strncpy(GLOBAL_STATE->SYSTEM_MODULE.ssid, wifi_ssid, sizeof(GLOBAL_STATE->SYSTEM_MODULE.ssid)); - GLOBAL_STATE->SYSTEM_MODULE.ssid[sizeof(GLOBAL_STATE->SYSTEM_MODULE.ssid)-1] = 0; + strncpy(WIFI_MODULE.ssid, wifi_ssid, sizeof(WIFI_MODULE.ssid)); + WIFI_MODULE.ssid[sizeof(WIFI_MODULE.ssid)-1] = 0; free(wifi_ssid); @@ -340,8 +337,8 @@ void wifi_init(void * pvParameters) esp_event_handler_instance_t instance_any_id; esp_event_handler_instance_t instance_got_ip; - ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, GLOBAL_STATE, &instance_any_id)); - ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, GLOBAL_STATE, &instance_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip)); /* Initialize Wi-Fi */ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); @@ -350,10 +347,10 @@ void wifi_init(void * pvParameters) wifi_softap_on(); /* Initialize AP */ - wifi_init_softap(GLOBAL_STATE->SYSTEM_MODULE.ap_ssid); + wifi_init_softap(WIFI_MODULE.ap_ssid); /* Skip connection if SSID is null */ - if (strlen(GLOBAL_STATE->SYSTEM_MODULE.ssid) == 0) { + if (strlen(WIFI_MODULE.ssid) == 0) { ESP_LOGI(TAG, "No WiFi SSID provided, skipping connection"); /* Start WiFi */ @@ -369,7 +366,7 @@ void wifi_init(void * pvParameters) /* Initialize STA */ ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); - esp_netif_t * esp_netif_sta = wifi_init_sta(GLOBAL_STATE->SYSTEM_MODULE.ssid, wifi_pass); + esp_netif_t * esp_netif_sta = wifi_init_sta(WIFI_MODULE.ssid, wifi_pass); free(wifi_pass); diff --git a/components/connect/include/connect.h b/components/connect/include/connect.h index 17d9e043b..ad9f6bdc4 100644 --- a/components/connect/include/connect.h +++ b/components/connect/include/connect.h @@ -15,7 +15,7 @@ typedef struct { } wifi_ap_record_simple_t; void toggle_wifi_softap(void); -void wifi_init(void * GLOBAL_STATE); +void wifi_init(); esp_err_t wifi_scan(wifi_ap_record_simple_t *ap_records, uint16_t *ap_count); esp_err_t get_wifi_current_rssi(int8_t *rssi); diff --git a/components/stratum/stratum_api.c b/components/stratum/stratum_api.c index e07ab486e..552cdc5c8 100644 --- a/components/stratum/stratum_api.c +++ b/components/stratum/stratum_api.c @@ -321,7 +321,7 @@ void STRATUM_V1_parse(StratumApiV1Message * message, const char * stratum_json) char * extranonce_str = cJSON_GetArrayItem(params, 0)->valuestring; uint32_t extranonce_2_len = cJSON_GetArrayItem(params, 1)->valueint; if (extranonce_2_len > MAX_EXTRANONCE_2_LEN) { - ESP_LOGW(TAG, "Extranonce_2_len %u exceeds maximum %d, clamping to maximum", + ESP_LOGW(TAG, "Extranonce_2_len %lu exceeds maximum %d, clamping to maximum", extranonce_2_len, MAX_EXTRANONCE_2_LEN); extranonce_2_len = MAX_EXTRANONCE_2_LEN; } diff --git a/main/asic_task_module.h b/main/asic_task_module.h new file mode 100644 index 000000000..35578f53e --- /dev/null +++ b/main/asic_task_module.h @@ -0,0 +1,21 @@ +#ifndef ASIC_TASK_MODULE_H_ +#define ASIC_TASK_MODULE_H_ + +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include +#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; + //semaphone + SemaphoreHandle_t semaphore; + pthread_mutex_t valid_jobs_lock; + uint8_t * valid_jobs; +} AsicTaskModule; + +extern AsicTaskModule ASIC_TASK_MODULE; +#endif \ No newline at end of file diff --git a/main/bap/bap.c b/main/bap/bap.c index 16687b2ae..47f6439df 100644 --- a/main/bap/bap.c +++ b/main/bap/bap.c @@ -18,18 +18,10 @@ static const char *TAG = "BAP"; QueueHandle_t bap_uart_send_queue = NULL; SemaphoreHandle_t bap_uart_send_mutex = NULL; SemaphoreHandle_t bap_subscription_mutex = NULL; -GlobalState *bap_global_state = NULL; -esp_err_t BAP_init(GlobalState *state) { +esp_err_t BAP_init() { ESP_LOGI(TAG, "Initializing BAP system"); - if (!state) { - ESP_LOGE(TAG, "Invalid global state pointer"); - return ESP_ERR_INVALID_ARG; - } - - bap_global_state = state; - esp_err_t ret; bap_subscription_mutex = xSemaphoreCreateMutex(); @@ -68,14 +60,14 @@ esp_err_t BAP_init(GlobalState *state) { } // Initialize command handlers - ret = BAP_handlers_init(state); + ret = BAP_handlers_init(); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize handlers: %s", esp_err_to_name(ret)); return ret; } // Send initialization message - BAP_send_init_message(state); + BAP_send_init_message(); // Start UART receive task ret = BAP_start_uart_receive_task(); @@ -85,7 +77,7 @@ esp_err_t BAP_init(GlobalState *state) { } // Start mode-aware BAP management task - ret = BAP_start_mode_management_task(state); + ret = BAP_start_mode_management_task(); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to start BAP mode management task: %s", esp_err_to_name(ret)); return ret; diff --git a/main/bap/bap.h b/main/bap/bap.h index 98933f297..64cf503a8 100644 --- a/main/bap/bap.h +++ b/main/bap/bap.h @@ -10,7 +10,6 @@ #define BAP_H_ #include "esp_err.h" -#include "global_state.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/semphr.h" @@ -24,7 +23,6 @@ extern QueueHandle_t bap_uart_send_queue; extern SemaphoreHandle_t bap_uart_send_mutex; extern SemaphoreHandle_t bap_subscription_mutex; -extern GlobalState *bap_global_state; #ifdef __cplusplus extern "C" { @@ -42,7 +40,7 @@ extern "C" { * @param state Global state pointer * @return ESP_OK on success, error code otherwise */ -esp_err_t BAP_init(GlobalState *state); +esp_err_t BAP_init(); #ifdef __cplusplus } diff --git a/main/bap/bap_handlers.c b/main/bap/bap_handlers.c index e472945fd..08d8a155a 100644 --- a/main/bap/bap_handlers.c +++ b/main/bap/bap_handlers.c @@ -18,6 +18,10 @@ #include "bap_subscription.h" #include "bap.h" #include "asic.h" +#include "wifi_module.h" +#include "device_config.h" +#include "power_management_module.h" +#include "pool_module.h" static const char *TAG = "BAP_HANDLERS"; @@ -170,7 +174,7 @@ void BAP_handle_subscription(const char *parameter, const char *value) { } // Check if we're in AP mode - subscriptions not allowed - if (!bap_global_state || !bap_global_state->SYSTEM_MODULE.is_connected) { + if (!WIFI_MODULE.is_connected) { ESP_LOGW(TAG, "Subscription not allowed in AP mode"); BAP_send_message(BAP_CMD_ERR, parameter, "ap_mode_no_subscriptions"); return; @@ -199,7 +203,7 @@ void BAP_handle_request(const char *parameter, const char *value) { } // Check if we're in AP mode - most requests not allowed - if (!bap_global_state || !bap_global_state->SYSTEM_MODULE.is_connected) { + if (!WIFI_MODULE.is_connected) { ESP_LOGW(TAG, "Request not allowed in AP mode"); BAP_send_message(BAP_CMD_ERR, parameter, "ap_mode_no_requests"); return; @@ -211,31 +215,22 @@ void BAP_handle_request(const char *parameter, const char *value) { return; } - if (!bap_global_state) { - ESP_LOGE(TAG, "Global state not available for request"); - return; - } - - BAP_send_request(param, bap_global_state); + BAP_send_request(param); } -void BAP_send_request(bap_parameter_t param, GlobalState *state) { - if (!state) { - ESP_LOGE(TAG, "Invalid global state for request"); - return; - } +void BAP_send_request(bap_parameter_t param) { //ESP_LOGI(TAG, "Sending request response for %s", BAP_parameter_to_string(param)); switch (param) { case BAP_PARAM_SYSTEM_INFO: - BAP_send_message(BAP_CMD_RES, "deviceModel", state->DEVICE_CONFIG.family.name); - BAP_send_message(BAP_CMD_RES, "asicModel", state->DEVICE_CONFIG.family.asic.name); + BAP_send_message(BAP_CMD_RES, "deviceModel", DEVICE_CONFIG.family.name); + BAP_send_message(BAP_CMD_RES, "asicModel", DEVICE_CONFIG.family.asic.name); char port_str[6]; - snprintf(port_str, sizeof(port_str),"%u", state->SYSTEM_MODULE.pool_port); - BAP_send_message(BAP_CMD_RES, "pool", state->SYSTEM_MODULE.pool_url); + snprintf(port_str, sizeof(port_str),"%u", POOL_MODULE.pools[POOL_MODULE.active_pool_idx].port); + BAP_send_message(BAP_CMD_RES, "pool", POOL_MODULE.pools[POOL_MODULE.active_pool_idx].url); BAP_send_message(BAP_CMD_RES, "poolPort", port_str); - BAP_send_message(BAP_CMD_RES, "poolUser", state->SYSTEM_MODULE.pool_user); + BAP_send_message(BAP_CMD_RES, "poolUser", POOL_MODULE.pools[POOL_MODULE.active_pool_idx].user); break; default: @@ -254,16 +249,10 @@ void BAP_handle_settings(const char *parameter, const char *value) { return; } - if (!bap_global_state) { - ESP_LOGE(TAG, "Global state not available for settings"); - BAP_send_message(BAP_CMD_ERR, parameter, "system_not_ready"); - return; - } - bap_parameter_t param = BAP_parameter_from_string(parameter); // In AP mode, only allow SSID and password settings - if (!bap_global_state->SYSTEM_MODULE.is_connected) { + if (!WIFI_MODULE.is_connected) { if (param != BAP_PARAM_SSID && param != BAP_PARAM_PASSWORD) { ESP_LOGW(TAG, "Setting '%s' not allowed in AP mode", parameter); BAP_send_message(BAP_CMD_ERR, parameter, "ap_mode_limited_settings"); @@ -285,12 +274,12 @@ void BAP_handle_settings(const char *parameter, const char *value) { //ESP_LOGI(TAG, "Setting ASIC frequency to %.2f MHz", target_frequency); - bool success = ASIC_set_frequency(bap_global_state, target_frequency); + bool success = ASIC_set_frequency(target_frequency); if (success) { //ESP_LOGI(TAG, "Frequency successfully set to %.2f MHz", target_frequency); - bap_global_state->POWER_MANAGEMENT_MODULE.frequency_value = target_frequency; + POWER_MANAGEMENT_MODULE.frequency_value = target_frequency; nvs_config_set_u16(NVS_CONFIG_ASIC_FREQUENCY, target_frequency); char freq_str[32]; @@ -408,7 +397,7 @@ void BAP_handle_settings(const char *parameter, const char *value) { } } -esp_err_t BAP_handlers_init(GlobalState *state) { +esp_err_t BAP_handlers_init() { // Clear all handlers memset(handlers, 0, sizeof(handlers)); diff --git a/main/bap/bap_handlers.h b/main/bap/bap_handlers.h index 0d1b367aa..b8a18686d 100644 --- a/main/bap/bap_handlers.h +++ b/main/bap/bap_handlers.h @@ -9,7 +9,6 @@ #define BAP_HANDLERS_H_ #include "esp_err.h" -#include "global_state.h" #include "bap_protocol.h" #ifdef __cplusplus @@ -58,7 +57,7 @@ void BAP_handle_request(const char *parameter, const char *value); * @param param Parameter type * @param state Global state pointer */ -void BAP_send_request(bap_parameter_t param, GlobalState *state); +void BAP_send_request(bap_parameter_t param); /** * @brief Handle settings change @@ -72,7 +71,7 @@ void BAP_handle_settings(const char *parameter, const char *value); * @param state Global state pointer * @return ESP_OK on success, error code otherwise */ -esp_err_t BAP_handlers_init(GlobalState *state); +esp_err_t BAP_handlers_init(); #ifdef __cplusplus } diff --git a/main/bap/bap_subscription.c b/main/bap/bap_subscription.c index c15d44103..bad51ab33 100644 --- a/main/bap/bap_subscription.c +++ b/main/bap/bap_subscription.c @@ -18,6 +18,9 @@ #include "bap_uart.h" #include "bap.h" #include "connect.h" +#include "system_module.h" +#include "power_management_module.h" +#include "wifi_module.h" static const char *TAG = "BAP_SUBSCRIPTION"; @@ -113,11 +116,7 @@ void BAP_subscription_handle_unsubscribe(const char *parameter, const char *valu } } -void BAP_send_subscription_update(GlobalState *state) { - if (!state) { - ESP_LOGE(TAG, "Invalid global state"); - return; - } +void BAP_send_subscription_update() { uint32_t current_time = esp_timer_get_time() / 1000; @@ -146,7 +145,7 @@ void BAP_send_subscription_update(GlobalState *state) { case BAP_PARAM_HASHRATE: { char hashrate_str[32]; - snprintf(hashrate_str, sizeof(hashrate_str), "%.2f", state->SYSTEM_MODULE.current_hashrate); + snprintf(hashrate_str, sizeof(hashrate_str), "%.2f", SYSTEM_MODULE.current_hashrate); BAP_send_message_with_queue(BAP_CMD_RES, "hashrate", hashrate_str); } break; @@ -154,10 +153,10 @@ void BAP_send_subscription_update(GlobalState *state) { case BAP_PARAM_TEMPERATURE: { char temp_str[32]; - snprintf(temp_str, sizeof(temp_str), "%f", state->POWER_MANAGEMENT_MODULE.chip_temp_avg); + snprintf(temp_str, sizeof(temp_str), "%f", POWER_MANAGEMENT_MODULE.chip_temp_avg); BAP_send_message_with_queue(BAP_CMD_RES, "chipTemp", temp_str); - snprintf(temp_str, sizeof(temp_str), "%f", state->POWER_MANAGEMENT_MODULE.vr_temp); + snprintf(temp_str, sizeof(temp_str), "%f", POWER_MANAGEMENT_MODULE.vr_temp); BAP_send_message_with_queue(BAP_CMD_RES, "vrTemp", temp_str); } break; @@ -165,7 +164,7 @@ void BAP_send_subscription_update(GlobalState *state) { case BAP_PARAM_POWER: { char power_str[32]; - snprintf(power_str, sizeof(power_str), "%.2f", state->POWER_MANAGEMENT_MODULE.power); + snprintf(power_str, sizeof(power_str), "%.2f", POWER_MANAGEMENT_MODULE.power); BAP_send_message_with_queue(BAP_CMD_RES, "power", power_str); } break; @@ -173,7 +172,7 @@ void BAP_send_subscription_update(GlobalState *state) { case BAP_PARAM_VOLTAGE: { char voltage_str[32]; - snprintf(voltage_str, sizeof(voltage_str), "%.2f", state->POWER_MANAGEMENT_MODULE.voltage); + snprintf(voltage_str, sizeof(voltage_str), "%.2f", POWER_MANAGEMENT_MODULE.voltage); BAP_send_message_with_queue(BAP_CMD_RES, "voltage", voltage_str); } break; @@ -181,7 +180,7 @@ void BAP_send_subscription_update(GlobalState *state) { case BAP_PARAM_CURRENT: { char current_str[32]; - snprintf(current_str, sizeof(current_str), "%.2f", state->POWER_MANAGEMENT_MODULE.current); + snprintf(current_str, sizeof(current_str), "%.2f", POWER_MANAGEMENT_MODULE.current); BAP_send_message_with_queue(BAP_CMD_RES, "current", current_str); } break; @@ -189,7 +188,7 @@ void BAP_send_subscription_update(GlobalState *state) { case BAP_PARAM_SHARES: { char shares_ar_str[64]; - snprintf(shares_ar_str, sizeof(shares_ar_str), "%lld/%lld", state->SYSTEM_MODULE.shares_accepted, state->SYSTEM_MODULE.shares_rejected); + snprintf(shares_ar_str, sizeof(shares_ar_str), "%lld/%lld", SYSTEM_MODULE.shares_accepted, SYSTEM_MODULE.shares_rejected); BAP_send_message_with_queue(BAP_CMD_RES, "shares", shares_ar_str); } @@ -198,7 +197,7 @@ void BAP_send_subscription_update(GlobalState *state) { case BAP_PARAM_FAN_SPEED: { char fan_speed_str[32]; - snprintf(fan_speed_str, sizeof(fan_speed_str), "%d", state->POWER_MANAGEMENT_MODULE.fan_rpm); + snprintf(fan_speed_str, sizeof(fan_speed_str), "%d", POWER_MANAGEMENT_MODULE.fan_rpm); BAP_send_message_with_queue(BAP_CMD_RES, "fan_speed", fan_speed_str); } break; @@ -206,7 +205,7 @@ void BAP_send_subscription_update(GlobalState *state) { case BAP_PARAM_BEST_DIFFICULTY: { char best_diff_str[32]; - snprintf(best_diff_str, sizeof(best_diff_str), "%s", state->SYSTEM_MODULE.best_diff_string); + snprintf(best_diff_str, sizeof(best_diff_str), "%s", SYSTEM_MODULE.best_diff_string); BAP_send_message_with_queue(BAP_CMD_RES, "best_difficulty", best_diff_str); } break; @@ -217,16 +216,16 @@ void BAP_send_subscription_update(GlobalState *state) { char wifi_status_str[256]; char rssi_str[32]; char ip_str[32]; - snprintf(ssid_str, sizeof(ssid_str), "%s", state->SYSTEM_MODULE.ssid); - snprintf(wifi_status_str, sizeof(wifi_status_str), "%s", state->SYSTEM_MODULE.wifi_status); + snprintf(ssid_str, sizeof(ssid_str), "%s", WIFI_MODULE.ssid); + snprintf(wifi_status_str, sizeof(wifi_status_str), "%s", WIFI_MODULE.wifi_status); int8_t current_rssi = -128; // no connection - if (state->SYSTEM_MODULE.is_connected) { + if (WIFI_MODULE.is_connected) { get_wifi_current_rssi(¤t_rssi); } snprintf(rssi_str, sizeof(rssi_str), "%d", current_rssi); - snprintf(ip_str, sizeof(ip_str), "%s", state->SYSTEM_MODULE.ip_addr_str); + snprintf(ip_str, sizeof(ip_str), "%s", WIFI_MODULE.ip_addr_str); BAP_send_message_with_queue(BAP_CMD_RES, "wifi_ssid", ssid_str); BAP_send_message_with_queue(BAP_CMD_RES, "wifi_rssi", rssi_str); BAP_send_message_with_queue(BAP_CMD_RES, "wifi_ip", ip_str); @@ -245,10 +244,9 @@ void BAP_send_subscription_update(GlobalState *state) { } static void subscription_update_task(void *pvParameters) { - GlobalState *state = (GlobalState *)pvParameters; while (1) { - BAP_send_subscription_update(state); + BAP_send_subscription_update(); vTaskDelay(pdMS_TO_TICKS(1000)); } @@ -256,19 +254,18 @@ static void subscription_update_task(void *pvParameters) { } static void mode_management_task(void *pvParameters) { - GlobalState *state = (GlobalState *)pvParameters; bool was_connected = false; bool subscription_task_started = false; ESP_LOGI(TAG, "BAP mode management task started"); while (1) { - bool is_connected = state->SYSTEM_MODULE.is_connected; + bool is_connected = WIFI_MODULE.is_connected; // Check for mode transitions if (!was_connected && !is_connected) { // AP mode - send periodic AP messages - BAP_send_ap_message(state); + BAP_send_ap_message(); vTaskDelay(pdMS_TO_TICKS(5000)); } else if (!was_connected && is_connected) { // Transition from AP to connected mode @@ -276,7 +273,7 @@ static void mode_management_task(void *pvParameters) { // Start subscription task for connected mode if (!subscription_task_started) { - esp_err_t ret = BAP_start_subscription_task(state); + esp_err_t ret = BAP_start_subscription_task(); if (ret == ESP_OK) { subscription_task_started = true; ESP_LOGI(TAG, "Subscription task started for connected mode"); @@ -301,17 +298,14 @@ static void mode_management_task(void *pvParameters) { vTaskDelete(NULL); } -esp_err_t BAP_start_mode_management_task(GlobalState *state) { - if (!state) { - ESP_LOGE(TAG, "Invalid global state"); - return ESP_ERR_INVALID_ARG; - } +esp_err_t BAP_start_mode_management_task() { + xTaskCreate( mode_management_task, "bap_mode_mgmt", 4096, - state, + NULL, 5, NULL ); @@ -320,17 +314,13 @@ esp_err_t BAP_start_mode_management_task(GlobalState *state) { return ESP_OK; } -esp_err_t BAP_start_subscription_task(GlobalState *state) { - if (!state) { - ESP_LOGE(TAG, "Invalid global state"); - return ESP_ERR_INVALID_ARG; - } +esp_err_t BAP_start_subscription_task() { xTaskCreate( subscription_update_task, "subscription_up", 4096, - state, + NULL, 5, &subscription_task_handle ); diff --git a/main/bap/bap_subscription.h b/main/bap/bap_subscription.h index ff1f5843c..ce142054a 100644 --- a/main/bap/bap_subscription.h +++ b/main/bap/bap_subscription.h @@ -11,7 +11,6 @@ #include #include #include "esp_err.h" -#include "global_state.h" #include "bap_protocol.h" #ifdef __cplusplus @@ -49,21 +48,21 @@ void BAP_subscription_handle_unsubscribe(const char *parameter, const char *valu * @brief Send subscription updates for all active subscriptions * @param state Global state pointer */ -void BAP_send_subscription_update(GlobalState *state); +void BAP_send_subscription_update(); /** * @brief Start mode management task * @param state Global state pointer * @return ESP_OK on success, error code otherwise */ -esp_err_t BAP_start_mode_management_task(GlobalState *state); +esp_err_t BAP_start_mode_management_task(); /** * @brief Start subscription update task * @param state Global state pointer * @return ESP_OK on success, error code otherwise */ -esp_err_t BAP_start_subscription_task(GlobalState *state); +esp_err_t BAP_start_subscription_task(); #ifdef __cplusplus } diff --git a/main/bap/bap_uart.c b/main/bap/bap_uart.c index a19315ad6..3f78e4c11 100644 --- a/main/bap/bap_uart.c +++ b/main/bap/bap_uart.c @@ -99,7 +99,7 @@ void BAP_send_message_with_queue(bap_command_t cmd, const char *parameter, const } } -void BAP_send_init_message(GlobalState *state) { +void BAP_send_init_message() { const char *init_message = "BAP UART Interface Initialized\r\n"; esp_err_t ret = uart_write_bytes(BAP_UART_NUM, init_message, strlen(init_message)); if (ret < 0) { @@ -109,7 +109,7 @@ void BAP_send_init_message(GlobalState *state) { } } -void BAP_send_ap_message(GlobalState *state) { +void BAP_send_ap_message() { BAP_send_message(BAP_CMD_CMD, "mode", "ap_mode"); } diff --git a/main/bap/bap_uart.h b/main/bap/bap_uart.h index 52a388fa7..52a8e4bc2 100644 --- a/main/bap/bap_uart.h +++ b/main/bap/bap_uart.h @@ -13,7 +13,6 @@ #include "freertos/task.h" #include "freertos/queue.h" #include "freertos/semphr.h" -#include "global_state.h" #include "bap_protocol.h" #ifdef __cplusplus @@ -51,13 +50,13 @@ void BAP_send_message_with_queue(bap_command_t cmd, const char *parameter, const * @brief Send initialization message * @param state Global state (can be NULL) */ -void BAP_send_init_message(GlobalState *state); +void BAP_send_init_message(); /** * @brief Send AP mode message * @param state Global state (can be NULL) */ -void BAP_send_ap_message(GlobalState *state); +void BAP_send_ap_message(); /** diff --git a/main/device_config.c b/main/device_config.c index fd4ed6a11..170888ea0 100644 --- a/main/device_config.c +++ b/main/device_config.c @@ -1,16 +1,15 @@ #include #include "device_config.h" #include "nvs_config.h" -#include "global_state.h" + #include "esp_log.h" #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) static const char * TAG = "device_config"; -esp_err_t device_config_init(void * pvParameters) +esp_err_t device_config_init() { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; // TODO: Read board version from eFuse @@ -18,11 +17,11 @@ esp_err_t device_config_init(void * pvParameters) for (int i = 0 ; i < ARRAY_SIZE(default_configs); i++) { if (strcmp(default_configs[i].board_version, board_version) == 0) { - GLOBAL_STATE->DEVICE_CONFIG = default_configs[i]; + DEVICE_CONFIG = default_configs[i]; - ESP_LOGI(TAG, "Device Model: %s", GLOBAL_STATE->DEVICE_CONFIG.family.name); - ESP_LOGI(TAG, "Board Version: %s", GLOBAL_STATE->DEVICE_CONFIG.board_version); - ESP_LOGI(TAG, "ASIC: %dx %s (%d cores)", GLOBAL_STATE->DEVICE_CONFIG.family.asic_count, GLOBAL_STATE->DEVICE_CONFIG.family.asic.name, GLOBAL_STATE->DEVICE_CONFIG.family.asic.core_count); + ESP_LOGI(TAG, "Device Model: %s", DEVICE_CONFIG.family.name); + ESP_LOGI(TAG, "Board Version: %s", DEVICE_CONFIG.board_version); + ESP_LOGI(TAG, "ASIC: %dx %s (%d cores)", DEVICE_CONFIG.family.asic_count, DEVICE_CONFIG.family.asic.name, DEVICE_CONFIG.family.asic.core_count); free(board_version); return ESP_OK; @@ -31,15 +30,15 @@ esp_err_t device_config_init(void * pvParameters) ESP_LOGI(TAG, "Custom Board Version: %s", board_version); - GLOBAL_STATE->DEVICE_CONFIG.board_version = strdup(board_version); + DEVICE_CONFIG.board_version = strdup(board_version); char * device_model = nvs_config_get_string(NVS_CONFIG_DEVICE_MODEL, "unknown"); for (int i = 0 ; i < ARRAY_SIZE(default_families); i++) { if (strcasecmp(default_families[i].name, device_model) == 0) { - GLOBAL_STATE->DEVICE_CONFIG.family = default_families[i]; + DEVICE_CONFIG.family = default_families[i]; - ESP_LOGI(TAG, "Device Model: %s", GLOBAL_STATE->DEVICE_CONFIG.family.name); + ESP_LOGI(TAG, "Device Model: %s", DEVICE_CONFIG.family.name); break; } @@ -49,27 +48,27 @@ esp_err_t device_config_init(void * pvParameters) for (int i = 0 ; i < ARRAY_SIZE(default_asic_configs); i++) { if (strcasecmp(default_asic_configs[i].name, asic_model) == 0) { - GLOBAL_STATE->DEVICE_CONFIG.family.asic = default_asic_configs[i]; + DEVICE_CONFIG.family.asic = default_asic_configs[i]; - ESP_LOGI(TAG, "ASIC: %dx %s (%d cores)", GLOBAL_STATE->DEVICE_CONFIG.family.asic_count, GLOBAL_STATE->DEVICE_CONFIG.family.asic.name, GLOBAL_STATE->DEVICE_CONFIG.family.asic.core_count); + ESP_LOGI(TAG, "ASIC: %dx %s (%d cores)", DEVICE_CONFIG.family.asic_count, DEVICE_CONFIG.family.asic.name, DEVICE_CONFIG.family.asic.core_count); break; } } - GLOBAL_STATE->DEVICE_CONFIG.plug_sense = nvs_config_get_u16(NVS_CONFIG_PLUG_SENSE, 0) != 0; - GLOBAL_STATE->DEVICE_CONFIG.asic_enable = nvs_config_get_u16(NVS_CONFIG_ASIC_ENABLE, 0) != 0; - GLOBAL_STATE->DEVICE_CONFIG.EMC2101 = nvs_config_get_u16(NVS_CONFIG_EMC2101, 0) != 0; - GLOBAL_STATE->DEVICE_CONFIG.EMC2103 = nvs_config_get_u16(NVS_CONFIG_EMC2103, 0) != 0; - GLOBAL_STATE->DEVICE_CONFIG.emc_internal_temp = nvs_config_get_u16(NVS_CONFIG_EMC_INTERNAL_TEMP, 0) != 0; - GLOBAL_STATE->DEVICE_CONFIG.emc_ideality_factor = nvs_config_get_u16(NVS_CONFIG_EMC_IDEALITY_FACTOR, 0); - GLOBAL_STATE->DEVICE_CONFIG.emc_beta_compensation = nvs_config_get_u16(NVS_CONFIG_EMC_BETA_COMPENSATION, 0); - GLOBAL_STATE->DEVICE_CONFIG.emc_temp_offset = nvs_config_get_i32(NVS_CONFIG_EMC_TEMP_OFFSET, 0); - GLOBAL_STATE->DEVICE_CONFIG.DS4432U = nvs_config_get_u16(NVS_CONFIG_DS4432U, 0) != 0; - GLOBAL_STATE->DEVICE_CONFIG.INA260 = nvs_config_get_u16(NVS_CONFIG_INA260, 0) != 0; - GLOBAL_STATE->DEVICE_CONFIG.TPS546 = nvs_config_get_u16(NVS_CONFIG_TPS546, 0) != 0; + DEVICE_CONFIG.plug_sense = nvs_config_get_u16(NVS_CONFIG_PLUG_SENSE, 0) != 0; + DEVICE_CONFIG.asic_enable = nvs_config_get_u16(NVS_CONFIG_ASIC_ENABLE, 0) != 0; + DEVICE_CONFIG.EMC2101 = nvs_config_get_u16(NVS_CONFIG_EMC2101, 0) != 0; + DEVICE_CONFIG.EMC2103 = nvs_config_get_u16(NVS_CONFIG_EMC2103, 0) != 0; + DEVICE_CONFIG.emc_internal_temp = nvs_config_get_u16(NVS_CONFIG_EMC_INTERNAL_TEMP, 0) != 0; + DEVICE_CONFIG.emc_ideality_factor = nvs_config_get_u16(NVS_CONFIG_EMC_IDEALITY_FACTOR, 0); + DEVICE_CONFIG.emc_beta_compensation = nvs_config_get_u16(NVS_CONFIG_EMC_BETA_COMPENSATION, 0); + DEVICE_CONFIG.emc_temp_offset = nvs_config_get_i32(NVS_CONFIG_EMC_TEMP_OFFSET, 0); + DEVICE_CONFIG.DS4432U = nvs_config_get_u16(NVS_CONFIG_DS4432U, 0) != 0; + DEVICE_CONFIG.INA260 = nvs_config_get_u16(NVS_CONFIG_INA260, 0) != 0; + DEVICE_CONFIG.TPS546 = nvs_config_get_u16(NVS_CONFIG_TPS546, 0) != 0; // test values - GLOBAL_STATE->DEVICE_CONFIG.power_consumption_target = nvs_config_get_u16(NVS_CONFIG_POWER_CONSUMPTION_TARGET, 0); + DEVICE_CONFIG.power_consumption_target = nvs_config_get_u16(NVS_CONFIG_POWER_CONSUMPTION_TARGET, 0); free(board_version); free(device_model); diff --git a/main/device_config.h b/main/device_config.h index cfde3bf3b..e0bc0554e 100644 --- a/main/device_config.h +++ b/main/device_config.h @@ -128,6 +128,7 @@ static const DeviceConfig default_configs[] = { { .board_version = "800", .family = FAMILY_GAMMA_TURBO, .EMC2103 = true, .emc_temp_offset = -10, .TPS546 = true, .power_consumption_target = 12, }, }; -esp_err_t device_config_init(void * pvParameters); +esp_err_t device_config_init(); +extern DeviceConfig DEVICE_CONFIG; #endif /* DEVICE_CONFIG_H_ */ diff --git a/main/display.c b/main/display.c index 8ac3cdea0..7dcefe163 100644 --- a/main/display.c +++ b/main/display.c @@ -11,13 +11,16 @@ #include "lvgl.h" #include "lvgl__lvgl/src/themes/lv_theme_private.h" #include "esp_lvgl_port.h" -#include "global_state.h" + #include "nvs_config.h" #include "i2c_bitaxe.h" #include "driver/i2c_master.h" #include "driver/i2c_types.h" #include "esp_lcd_panel_ssd1306.h" #include "esp_lcd_sh1107.h" +#include "system_module.h" +#include "display.h" +#include "state_module.h" #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) @@ -47,15 +50,15 @@ static void theme_apply(lv_theme_t *theme, lv_obj_t *obj) { } } -static esp_err_t read_display_config(GlobalState * GLOBAL_STATE) +static esp_err_t read_display_config() { char * display_config = nvs_config_get_string(NVS_CONFIG_DISPLAY, DEFAULT_DISPLAY); for (int i = 0 ; i < ARRAY_SIZE(display_configs); i++) { if (strcmp(display_configs[i].name, display_config) == 0) { - GLOBAL_STATE->DISPLAY_CONFIG = display_configs[i]; + DISPLAY_CONFIG = display_configs[i]; - ESP_LOGI(TAG, "%s", GLOBAL_STATE->DISPLAY_CONFIG.name); + ESP_LOGI(TAG, "%s", DISPLAY_CONFIG.name); free(display_config); return ESP_OK; } @@ -65,15 +68,13 @@ static esp_err_t read_display_config(GlobalState * GLOBAL_STATE) return ESP_FAIL; } -esp_err_t display_init(void * pvParameters) +esp_err_t display_init() { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - - ESP_RETURN_ON_ERROR(read_display_config(GLOBAL_STATE), TAG, "Failed to read display config"); + ESP_RETURN_ON_ERROR(read_display_config(), TAG, "Failed to read display config"); const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG(); - if (GLOBAL_STATE->DISPLAY_CONFIG.display == NONE) { + if (DISPLAY_CONFIG.display == NONE) { ESP_LOGI(TAG, "Initialize LVGL"); ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL init failed"); lv_display_create(1, 1); @@ -92,7 +93,7 @@ esp_err_t display_init(void * pvParameters) .lcd_param_bits = LCD_PARAM_BITS, }; - switch (GLOBAL_STATE->DISPLAY_CONFIG.display) { + switch (DISPLAY_CONFIG.display) { case SSD1306: case SSD1309: io_config.dc_bit_offset = 6; @@ -114,11 +115,11 @@ esp_err_t display_init(void * pvParameters) .reset_gpio_num = -1, }; - switch (GLOBAL_STATE->DISPLAY_CONFIG.display) { + switch (DISPLAY_CONFIG.display) { case SSD1306: case SSD1309: esp_lcd_panel_ssd1306_config_t ssd1306_config = { - .height = GLOBAL_STATE->DISPLAY_CONFIG.v_res, + .height = DISPLAY_CONFIG.v_res, }; panel_config.vendor_config = &ssd1306_config; ESP_RETURN_ON_ERROR(esp_lcd_new_panel_ssd1306(io_handle, &panel_config, &panel_handle), TAG, "No display found"); @@ -147,10 +148,10 @@ esp_err_t display_init(void * pvParameters) const lvgl_port_display_cfg_t disp_cfg = { .io_handle = io_handle, .panel_handle = panel_handle, - .buffer_size = GLOBAL_STATE->DISPLAY_CONFIG.h_res * GLOBAL_STATE->DISPLAY_CONFIG.v_res, + .buffer_size = DISPLAY_CONFIG.h_res * DISPLAY_CONFIG.v_res, .double_buffer = true, - .hres = GLOBAL_STATE->DISPLAY_CONFIG.h_res, - .vres = GLOBAL_STATE->DISPLAY_CONFIG.v_res, + .hres = DISPLAY_CONFIG.h_res, + .vres = DISPLAY_CONFIG.v_res, .monochrome = true, .color_format = LV_COLOR_FORMAT_I1, .flags = { @@ -199,10 +200,10 @@ esp_err_t display_init(void * pvParameters) // Only turn on the screen when it has been cleared ESP_RETURN_ON_ERROR(display_on(true), TAG, "Display on failed"); - GLOBAL_STATE->SYSTEM_MODULE.is_screen_active = true; + STATE_MODULE.is_screen_active = true; } else { ESP_LOGW(TAG, "No display found or panel init failed. Screen not active."); - GLOBAL_STATE->SYSTEM_MODULE.is_screen_active = false; + STATE_MODULE.is_screen_active = false; } ESP_LOGI(TAG, "Display init success!"); diff --git a/main/display.h b/main/display.h index 8a73b1b1b..56828fcd8 100644 --- a/main/display.h +++ b/main/display.h @@ -24,7 +24,9 @@ static const DisplayConfig display_configs[] = { { .name = "SH1107 (128x128)", .display = SH1107, .h_res = 128, .v_res = 128, }, }; -esp_err_t display_init(void * pvParameters); +esp_err_t display_init(); esp_err_t display_on(bool display_on); +extern DisplayConfig DISPLAY_CONFIG; + #endif /* DISPLAY_H_ */ diff --git a/main/global_state.h b/main/global_state.h deleted file mode 100644 index c4398bd08..000000000 --- a/main/global_state.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef GLOBAL_STATE_H_ -#define GLOBAL_STATE_H_ - -#include -#include -#include "asic_task.h" -#include "common.h" -#include "power_management_task.h" -#include "statistics_task.h" -#include "serial.h" -#include "stratum_api.h" -#include "work_queue.h" -#include "device_config.h" -#include "display.h" - -#define STRATUM_USER CONFIG_STRATUM_USER -#define FALLBACK_STRATUM_USER CONFIG_FALLBACK_STRATUM_USER - -#define HISTORY_LENGTH 100 -#define DIFF_STRING_SIZE 10 - -typedef struct { - char message[64]; - uint32_t count; -} RejectedReasonStat; - -typedef struct -{ - double duration_start; - int historical_hashrate_rolling_index; - double historical_hashrate_time_stamps[HISTORY_LENGTH]; - double historical_hashrate[HISTORY_LENGTH]; - int historical_hashrate_init; - double current_hashrate; - int64_t start_time; - uint64_t shares_accepted; - uint64_t shares_rejected; - uint64_t work_received; - RejectedReasonStat rejected_reason_stats[10]; - int rejected_reason_stats_count; - int screen_page; - uint64_t best_nonce_diff; - char best_diff_string[DIFF_STRING_SIZE]; - uint64_t best_session_nonce_diff; - char best_session_diff_string[DIFF_STRING_SIZE]; - bool FOUND_BLOCK; - char ssid[32]; - char wifi_status[256]; - char ip_addr_str[16]; // IP4ADDR_STRLEN_MAX - char ap_ssid[32]; - bool ap_enabled; - bool is_connected; - char * pool_url; - char * fallback_pool_url; - uint16_t pool_port; - uint16_t fallback_pool_port; - char * pool_user; - char * fallback_pool_user; - char * pool_pass; - char * fallback_pool_pass; - uint16_t pool_difficulty; - uint16_t fallback_pool_difficulty; - bool pool_extranonce_subscribe; - bool fallback_pool_extranonce_subscribe; - double response_time; - bool is_using_fallback; - uint16_t overheat_mode; - uint16_t power_fault; - uint32_t lastClockSync; - bool is_screen_active; - bool is_firmware_update; - char firmware_update_filename[20]; - char firmware_update_status[20]; - char * asic_status; -} SystemModule; - -typedef struct -{ - bool is_active; - bool is_finished; - char *message; - char *result; - char *finished; -} SelfTestModule; - -typedef struct -{ - work_queue stratum_queue; - work_queue ASIC_jobs_queue; - - SystemModule SYSTEM_MODULE; - DeviceConfig DEVICE_CONFIG; - DisplayConfig DISPLAY_CONFIG; - AsicTaskModule ASIC_TASK_MODULE; - PowerManagementModule POWER_MANAGEMENT_MODULE; - SelfTestModule SELF_TEST_MODULE; - StatisticsModule STATISTICS_MODULE; - - char * extranonce_str; - int extranonce_2_len; - int abandon_work; - - uint8_t * valid_jobs; - pthread_mutex_t valid_jobs_lock; - - uint32_t pool_difficulty; - bool new_set_mining_difficulty_msg; - uint32_t version_mask; - bool new_stratum_version_rolling_msg; - - int sock; - - // A message ID that must be unique per request that expects a response. - // For requests not expecting a response (called notifications), this is null. - int send_uid; - - bool ASIC_initalized; - bool psram_is_available; - - int block_height; - char * scriptsig; - char network_diff_string[DIFF_STRING_SIZE]; -} GlobalState; - -#endif /* GLOBAL_STATE_H_ */ diff --git a/main/http_server/axe-os/api/system/asic_settings.c b/main/http_server/axe-os/api/system/asic_settings.c index 1a87aa0d3..98ffb5d4f 100644 --- a/main/http_server/axe-os/api/system/asic_settings.c +++ b/main/http_server/axe-os/api/system/asic_settings.c @@ -2,21 +2,16 @@ #include "esp_log.h" #include "esp_http_server.h" #include "cJSON.h" -#include "global_state.h" +#include "device_config.h" #include "asic.h" // static const char *TAG = "asic_settings"; -static GlobalState *GLOBAL_STATE = NULL; + // Function declarations from http_server.c extern esp_err_t is_network_allowed(httpd_req_t *req); extern esp_err_t set_cors_headers(httpd_req_t *req); -// Initialize the ASIC API with the global state -void asic_api_init(GlobalState *global_state) { - GLOBAL_STATE = global_state; -} - /* Handler for system asic endpoint */ esp_err_t GET_system_asic(httpd_req_t *req) { @@ -35,28 +30,28 @@ esp_err_t GET_system_asic(httpd_req_t *req) cJSON *root = cJSON_CreateObject(); // Add ASIC model to the JSON object - cJSON_AddStringToObject(root, "ASICModel", GLOBAL_STATE->DEVICE_CONFIG.family.asic.name); - cJSON_AddStringToObject(root, "deviceModel", GLOBAL_STATE->DEVICE_CONFIG.family.name); - cJSON_AddStringToObject(root, "swarmColor", GLOBAL_STATE->DEVICE_CONFIG.family.swarm_color); - cJSON_AddNumberToObject(root, "asicCount", GLOBAL_STATE->DEVICE_CONFIG.family.asic_count); + cJSON_AddStringToObject(root, "ASICModel", DEVICE_CONFIG.family.asic.name); + cJSON_AddStringToObject(root, "deviceModel", DEVICE_CONFIG.family.name); + cJSON_AddStringToObject(root, "swarmColor", DEVICE_CONFIG.family.swarm_color); + cJSON_AddNumberToObject(root, "asicCount", DEVICE_CONFIG.family.asic_count); - cJSON_AddNumberToObject(root, "defaultFrequency", GLOBAL_STATE->DEVICE_CONFIG.family.asic.default_frequency_mhz); + cJSON_AddNumberToObject(root, "defaultFrequency", DEVICE_CONFIG.family.asic.default_frequency_mhz); // Create arrays for frequency and voltage options based on ASIC model cJSON *freqOptions = cJSON_CreateArray(); size_t count = 0; - while (GLOBAL_STATE->DEVICE_CONFIG.family.asic.frequency_options[count] != 0) { - cJSON_AddItemToArray(freqOptions, cJSON_CreateNumber(GLOBAL_STATE->DEVICE_CONFIG.family.asic.frequency_options[count])); + while (DEVICE_CONFIG.family.asic.frequency_options[count] != 0) { + cJSON_AddItemToArray(freqOptions, cJSON_CreateNumber(DEVICE_CONFIG.family.asic.frequency_options[count])); count++; } cJSON_AddItemToObject(root, "frequencyOptions", freqOptions); - cJSON_AddNumberToObject(root, "defaultVoltage", GLOBAL_STATE->DEVICE_CONFIG.family.asic.default_voltage_mv); + cJSON_AddNumberToObject(root, "defaultVoltage", DEVICE_CONFIG.family.asic.default_voltage_mv); cJSON *voltageOptions = cJSON_CreateArray(); count = 0; - while (GLOBAL_STATE->DEVICE_CONFIG.family.asic.voltage_options[count] != 0) { - cJSON_AddItemToArray(voltageOptions, cJSON_CreateNumber(GLOBAL_STATE->DEVICE_CONFIG.family.asic.voltage_options[count])); + while (DEVICE_CONFIG.family.asic.voltage_options[count] != 0) { + cJSON_AddItemToArray(voltageOptions, cJSON_CreateNumber(DEVICE_CONFIG.family.asic.voltage_options[count])); count++; } cJSON_AddItemToObject(root, "voltageOptions", voltageOptions); diff --git a/main/http_server/axe-os/api/system/asic_settings.h b/main/http_server/axe-os/api/system/asic_settings.h index 2bd55cd4f..228ae3bb3 100644 --- a/main/http_server/axe-os/api/system/asic_settings.h +++ b/main/http_server/axe-os/api/system/asic_settings.h @@ -2,12 +2,10 @@ #define ASIC_API_SETTINGS_H_ #include -#include "global_state.h" + // Function to handle the /api/system/asic endpoint esp_err_t GET_system_asic(httpd_req_t *req); -// Initialize the ASIC API with the global state -void asic_api_init(GlobalState *global_state); #endif // ASIC_API_SETTINGS_H_ diff --git a/main/http_server/http_server.c b/main/http_server/http_server.c index 2cebf3456..fcdeb44e6 100644 --- a/main/http_server/http_server.c +++ b/main/http_server/http_server.c @@ -1,20 +1,20 @@ -#include #include +#include #include #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "freertos/task.h" #include "esp_chip_info.h" #include "esp_http_server.h" #include "esp_log.h" #include "esp_random.h" #include "esp_spiffs.h" #include "esp_timer.h" -#include "esp_wifi.h" #include "esp_vfs.h" +#include "esp_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" #include "dns_server.h" #include "esp_mac.h" @@ -28,20 +28,26 @@ #include "lwip/sockets.h" #include "lwip/sys.h" +#include "TPS546.h" +#include "asic.h" +#include "axe-os/api/system/asic_settings.h" #include "cJSON.h" -#include "global_state.h" +#include "connect.h" + +#include "http_server.h" #include "nvs_config.h" -#include "vcore.h" #include "power.h" -#include "connect.h" -#include "asic.h" -#include "TPS546.h" #include "statistics_task.h" -#include "theme_api.h" // Add theme API include -#include "axe-os/api/system/asic_settings.h" -#include "http_server.h" +#include "theme_api.h" // Add theme API include +#include "vcore.h" #include "system.h" +#include "power_management_module.h" #include "websocket.h" +#include "system_module.h" +#include "device_config.h" +#include "wifi_module.h" +#include "pool_module.h" +#include "state_module.h" #define JSON_ALL_STATS_ELEMENT_SIZE 120 #define JSON_DASHBOARD_STATS_ELEMENT_SIZE 60 @@ -51,7 +57,6 @@ static const char * CORS_TAG = "CORS"; static char axeOSVersion[32]; -static GlobalState * GLOBAL_STATE; static httpd_handle_t server = NULL; /* Handler for WiFi scan endpoint */ @@ -92,7 +97,6 @@ static esp_err_t GET_wifi_scan(httpd_req_t *req) return ESP_OK; } - #define REST_CHECK(a, str, goto_tag, ...) \ do { \ if (!(a)) { \ @@ -169,7 +173,7 @@ static uint32_t extract_origin_ip_addr(char *origin) esp_err_t is_network_allowed(httpd_req_t * req) { - if (GLOBAL_STATE->SYSTEM_MODULE.ap_enabled == true) { + if (WIFI_MODULE.ap_enabled == true) { ESP_LOGI(CORS_TAG, "Device in AP mode. Allowing CORS."); return ESP_OK; } @@ -630,7 +634,7 @@ static esp_err_t GET_system_info(httpd_req_t * req) char * fallbackStratumUser = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_USER, CONFIG_FALLBACK_STRATUM_USER); char * display = nvs_config_get_string(NVS_CONFIG_DISPLAY, "SSD1306 (128x32)"); float frequency = nvs_config_get_float(NVS_CONFIG_ASIC_FREQUENCY_FLOAT, CONFIG_ASIC_FREQUENCY); - float expected_hashrate = frequency * GLOBAL_STATE->DEVICE_CONFIG.family.asic.small_core_count * GLOBAL_STATE->DEVICE_CONFIG.family.asic_count / 1000.0; + float expected_hashrate = frequency * DEVICE_CONFIG.family.asic.small_core_count * DEVICE_CONFIG.family.asic_count / 1000.0; uint8_t mac[6]; esp_wifi_get_mac(WIFI_IF_STA, mac); @@ -641,50 +645,50 @@ static esp_err_t GET_system_info(httpd_req_t * req) get_wifi_current_rssi(&wifi_rssi); cJSON * root = cJSON_CreateObject(); - cJSON_AddNumberToObject(root, "power", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.power); - cJSON_AddNumberToObject(root, "voltage", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.voltage); - cJSON_AddNumberToObject(root, "current", Power_get_current(GLOBAL_STATE)); - cJSON_AddNumberToObject(root, "temp", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.chip_temp_avg); - cJSON_AddNumberToObject(root, "temp2", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.chip_temp2_avg); - cJSON_AddNumberToObject(root, "vrTemp", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.vr_temp); - cJSON_AddNumberToObject(root, "maxPower", GLOBAL_STATE->DEVICE_CONFIG.family.max_power); - cJSON_AddNumberToObject(root, "nominalVoltage", GLOBAL_STATE->DEVICE_CONFIG.family.nominal_voltage); - cJSON_AddNumberToObject(root, "hashRate", GLOBAL_STATE->SYSTEM_MODULE.current_hashrate); + cJSON_AddNumberToObject(root, "power", POWER_MANAGEMENT_MODULE.power); + cJSON_AddNumberToObject(root, "voltage", POWER_MANAGEMENT_MODULE.voltage); + cJSON_AddNumberToObject(root, "current", Power_get_current()); + cJSON_AddNumberToObject(root, "temp", POWER_MANAGEMENT_MODULE.chip_temp_avg); + cJSON_AddNumberToObject(root, "temp2", POWER_MANAGEMENT_MODULE.chip_temp2_avg); + cJSON_AddNumberToObject(root, "vrTemp", POWER_MANAGEMENT_MODULE.vr_temp); + cJSON_AddNumberToObject(root, "maxPower", DEVICE_CONFIG.family.max_power); + cJSON_AddNumberToObject(root, "nominalVoltage", DEVICE_CONFIG.family.nominal_voltage); + cJSON_AddNumberToObject(root, "hashRate", SYSTEM_MODULE.current_hashrate); cJSON_AddNumberToObject(root, "expectedHashrate", expected_hashrate); - cJSON_AddStringToObject(root, "bestDiff", GLOBAL_STATE->SYSTEM_MODULE.best_diff_string); - cJSON_AddStringToObject(root, "bestSessionDiff", GLOBAL_STATE->SYSTEM_MODULE.best_session_diff_string); - cJSON_AddNumberToObject(root, "poolDifficulty", GLOBAL_STATE->pool_difficulty); + cJSON_AddStringToObject(root, "bestDiff", SYSTEM_MODULE.best_diff_string); + cJSON_AddStringToObject(root, "bestSessionDiff", SYSTEM_MODULE.best_session_diff_string); + cJSON_AddNumberToObject(root, "poolDifficulty", POOL_MODULE.pool_difficulty); - cJSON_AddNumberToObject(root, "isUsingFallbackStratum", GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback); + cJSON_AddNumberToObject(root, "isUsingFallbackStratum", POOL_MODULE.active_pool_idx != POOL_MODULE.default_pool_idx); - cJSON_AddNumberToObject(root, "isPSRAMAvailable", GLOBAL_STATE->psram_is_available); + cJSON_AddNumberToObject(root, "isPSRAMAvailable", STATE_MODULE.psram_is_available); cJSON_AddNumberToObject(root, "freeHeap", esp_get_free_heap_size()); - cJSON_AddNumberToObject(root, "coreVoltage", nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE)); - cJSON_AddNumberToObject(root, "coreVoltageActual", VCORE_get_voltage_mv(GLOBAL_STATE)); + cJSON_AddNumberToObject(root, "coreVoltage", POWER_MANAGEMENT_MODULE.core_voltage); + cJSON_AddNumberToObject(root, "coreVoltageActual", VCORE_get_voltage_mv()); cJSON_AddNumberToObject(root, "frequency", frequency); cJSON_AddStringToObject(root, "ssid", ssid); cJSON_AddStringToObject(root, "macAddr", formattedMac); cJSON_AddStringToObject(root, "hostname", hostname); - cJSON_AddStringToObject(root, "wifiStatus", GLOBAL_STATE->SYSTEM_MODULE.wifi_status); + cJSON_AddStringToObject(root, "wifiStatus", WIFI_MODULE.wifi_status); cJSON_AddNumberToObject(root, "wifiRSSI", wifi_rssi); - cJSON_AddNumberToObject(root, "apEnabled", GLOBAL_STATE->SYSTEM_MODULE.ap_enabled); - cJSON_AddNumberToObject(root, "sharesAccepted", GLOBAL_STATE->SYSTEM_MODULE.shares_accepted); - cJSON_AddNumberToObject(root, "sharesRejected", GLOBAL_STATE->SYSTEM_MODULE.shares_rejected); + cJSON_AddNumberToObject(root, "apEnabled", WIFI_MODULE.ap_enabled); + cJSON_AddNumberToObject(root, "sharesAccepted", SYSTEM_MODULE.shares_accepted); + cJSON_AddNumberToObject(root, "sharesRejected", SYSTEM_MODULE.shares_rejected); cJSON *error_array = cJSON_CreateArray(); cJSON_AddItemToObject(root, "sharesRejectedReasons", error_array); - - for (int i = 0; i < GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats_count; i++) { - cJSON *error_obj = cJSON_CreateObject(); - cJSON_AddStringToObject(error_obj, "message", GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats[i].message); - cJSON_AddNumberToObject(error_obj, "count", GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats[i].count); + + for (int i = 0; i < SYSTEM_MODULE.rejected_reason_stats_count; i++) { + cJSON * error_obj = cJSON_CreateObject(); + cJSON_AddStringToObject(error_obj, "message", SYSTEM_MODULE.rejected_reason_stats[i].message); + cJSON_AddNumberToObject(error_obj, "count", SYSTEM_MODULE.rejected_reason_stats[i].count); cJSON_AddItemToArray(error_array, error_obj); } - cJSON_AddNumberToObject(root, "uptimeSeconds", (esp_timer_get_time() - GLOBAL_STATE->SYSTEM_MODULE.start_time) / 1000000); - cJSON_AddNumberToObject(root, "smallCoreCount", GLOBAL_STATE->DEVICE_CONFIG.family.asic.small_core_count); - cJSON_AddStringToObject(root, "ASICModel", GLOBAL_STATE->DEVICE_CONFIG.family.asic.name); + cJSON_AddNumberToObject(root, "uptimeSeconds", (esp_timer_get_time() - SYSTEM_MODULE.start_time) / 1000000); + cJSON_AddNumberToObject(root, "smallCoreCount", DEVICE_CONFIG.family.asic.small_core_count); + cJSON_AddStringToObject(root, "ASICModel", DEVICE_CONFIG.family.asic.name); cJSON_AddStringToObject(root, "stratumURL", stratumURL); cJSON_AddNumberToObject(root, "stratumPort", nvs_config_get_u16(NVS_CONFIG_STRATUM_PORT, CONFIG_STRATUM_PORT)); cJSON_AddStringToObject(root, "stratumUser", stratumUser); @@ -695,13 +699,13 @@ static esp_err_t GET_system_info(httpd_req_t * req) cJSON_AddStringToObject(root, "fallbackStratumUser", fallbackStratumUser); cJSON_AddNumberToObject(root, "fallbackStratumSuggestedDifficulty", nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_DIFFICULTY, CONFIG_FALLBACK_STRATUM_DIFFICULTY)); cJSON_AddNumberToObject(root, "fallbackStratumExtranonceSubscribe", nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_EXTRANONCE_SUBSCRIBE, FALLBACK_STRATUM_EXTRANONCE_SUBSCRIBE)); - cJSON_AddNumberToObject(root, "responseTime", GLOBAL_STATE->SYSTEM_MODULE.response_time); + cJSON_AddNumberToObject(root, "responseTime", POOL_MODULE.response_time); cJSON_AddStringToObject(root, "version", esp_app_get_description()->version); cJSON_AddStringToObject(root, "axeOSVersion", axeOSVersion); cJSON_AddStringToObject(root, "idfVersion", esp_get_idf_version()); - cJSON_AddStringToObject(root, "boardVersion", GLOBAL_STATE->DEVICE_CONFIG.board_version); + cJSON_AddStringToObject(root, "boardVersion", DEVICE_CONFIG.board_version); cJSON_AddStringToObject(root, "runningPartition", esp_ota_get_running_partition()->label); cJSON_AddNumberToObject(root, "overheat_mode", nvs_config_get_u16(NVS_CONFIG_OVERHEAT_MODE, 0)); @@ -713,21 +717,20 @@ static esp_err_t GET_system_info(httpd_req_t * req) cJSON_AddNumberToObject(root, "autofanspeed", nvs_config_get_u16(NVS_CONFIG_AUTO_FAN_SPEED, 1)); - cJSON_AddNumberToObject(root, "fanspeed", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.fan_perc); + cJSON_AddNumberToObject(root, "fanspeed", POWER_MANAGEMENT_MODULE.fan_perc); cJSON_AddNumberToObject(root, "minFanSpeed", nvs_config_get_u16(NVS_CONFIG_MIN_FAN_SPEED, 25)); cJSON_AddNumberToObject(root, "temptarget", nvs_config_get_u16(NVS_CONFIG_TEMP_TARGET, 60)); - cJSON_AddNumberToObject(root, "fanrpm", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.fan_rpm); + cJSON_AddNumberToObject(root, "fanrpm", POWER_MANAGEMENT_MODULE.fan_rpm); cJSON_AddNumberToObject(root, "statsFrequency", nvs_config_get_u16(NVS_CONFIG_STATISTICS_FREQUENCY, 0)); - - if (GLOBAL_STATE->SYSTEM_MODULE.power_fault > 0) { - cJSON_AddStringToObject(root, "power_fault", VCORE_get_fault_string(GLOBAL_STATE)); + if (STATE_MODULE.power_fault > 0) { + cJSON_AddStringToObject(root, "power_fault", VCORE_get_fault_string()); } - if (GLOBAL_STATE->block_height > 0) { - cJSON_AddNumberToObject(root, "blockHeight", GLOBAL_STATE->block_height); - cJSON_AddStringToObject(root, "scriptsig", GLOBAL_STATE->scriptsig); - cJSON_AddStringToObject(root, "networkDifficulty", GLOBAL_STATE->network_diff_string); + if (SYSTEM_MODULE.block_height > 0) { + cJSON_AddNumberToObject(root, "blockHeight", SYSTEM_MODULE.block_height); + cJSON_AddStringToObject(root, "scriptsig", SYSTEM_MODULE.scriptsig); + cJSON_AddStringToObject(root, "networkDifficulty", SYSTEM_MODULE.network_diff_string); } free(ssid); @@ -763,14 +766,15 @@ int create_json_statistics_all(cJSON * root) cJSON * statsArray = cJSON_AddArrayToObject(root, "statistics"); - if (NULL != GLOBAL_STATE->STATISTICS_MODULE.statisticsList) { - StatisticsNodePtr node = *GLOBAL_STATE->STATISTICS_MODULE.statisticsList; // double pointer + if (NULL != STATISTICS_MODULE.statisticsList) + { + StatisticsNodePtr node = *STATISTICS_MODULE.statisticsList; // double pointer struct StatisticsData statsData; while (NULL != node) { node = statisticData(node, &statsData); - cJSON *valueArray = cJSON_CreateArray(); + cJSON_AddItemToArray(valueArray, cJSON_CreateNumber(statsData.hashrate)); cJSON_AddItemToArray(valueArray, cJSON_CreateNumber(statsData.chipTemperature)); cJSON_AddItemToArray(valueArray, cJSON_CreateNumber(statsData.vrTemperature)); @@ -801,8 +805,8 @@ int create_json_statistics_dashboard(cJSON * root) // create array for dashboard statistics cJSON * statsArray = cJSON_AddArrayToObject(root, "statistics"); - if (NULL != GLOBAL_STATE->STATISTICS_MODULE.statisticsList) { - StatisticsNodePtr node = *GLOBAL_STATE->STATISTICS_MODULE.statisticsList; // double pointer + if (NULL != STATISTICS_MODULE.statisticsList) { + StatisticsNodePtr node = *STATISTICS_MODULE.statisticsList; // double pointer struct StatisticsData statsData; while (NULL != node) { @@ -895,9 +899,9 @@ esp_err_t POST_WWW_update(httpd_req_t * req) return ESP_OK; } - GLOBAL_STATE->SYSTEM_MODULE.is_firmware_update = true; - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_filename, 20, "www.bin"); - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Starting..."); + STATE_MODULE.is_firmware_update = true; + snprintf(STATE_MODULE.firmware_update_filename, 20, "www.bin"); + snprintf(STATE_MODULE.firmware_update_status, 20, "Starting..."); char buf[1000]; int remaining = req->content_len; @@ -924,20 +928,19 @@ esp_err_t POST_WWW_update(httpd_req_t * req) if (recv_len == HTTPD_SOCK_ERR_TIMEOUT) { continue; } else if (recv_len <= 0) { - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Protocol Error"); + snprintf(STATE_MODULE.firmware_update_status, 20, "Protocol Error"); httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Protocol Error"); return ESP_OK; } if (esp_partition_write(www_partition, www_partition->size - remaining, (const void *) buf, recv_len) != ESP_OK) { - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Write Error"); + snprintf(STATE_MODULE.firmware_update_status, 20, "Write Error"); httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Write Error"); return ESP_OK; } - uint8_t percentage = 100 - ((remaining * 100 / req->content_len)); - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Working (%d%%)", percentage); + snprintf(STATE_MODULE.firmware_update_status, 20, "Working (%d%%)", percentage); remaining -= recv_len; } @@ -946,9 +949,8 @@ esp_err_t POST_WWW_update(httpd_req_t * req) readAxeOSVersion(); - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Finished..."); vTaskDelay(1000 / portTICK_PERIOD_MS); - GLOBAL_STATE->SYSTEM_MODULE.is_firmware_update = false; + STATE_MODULE.is_firmware_update = false; return ESP_OK; } @@ -969,10 +971,10 @@ esp_err_t POST_OTA_update(httpd_req_t * req) httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Not allowed in AP mode"); return ESP_OK; } - - GLOBAL_STATE->SYSTEM_MODULE.is_firmware_update = true; - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_filename, 20, "esp-miner.bin"); - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Starting..."); + + STATE_MODULE.is_firmware_update = true; + snprintf(STATE_MODULE.firmware_update_filename, 20, "esp-miner.bin"); + snprintf(STATE_MODULE.firmware_update_status, 20, "Starting..."); char buf[1000]; esp_ota_handle_t ota_handle; @@ -990,7 +992,7 @@ esp_err_t POST_OTA_update(httpd_req_t * req) // Serious Error: Abort OTA } else if (recv_len <= 0) { - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Protocol Error"); + snprintf(STATE_MODULE.firmware_update_status, 20, "Protocol Error"); httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Protocol Error"); return ESP_OK; } @@ -998,26 +1000,26 @@ esp_err_t POST_OTA_update(httpd_req_t * req) // Successful Upload: Flash firmware chunk if (esp_ota_write(ota_handle, (const void *) buf, recv_len) != ESP_OK) { esp_ota_abort(ota_handle); - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Write Error"); + snprintf(STATE_MODULE.firmware_update_status, 20, "Write Error"); httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Write Error"); return ESP_OK; } uint8_t percentage = 100 - ((remaining * 100 / req->content_len)); - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Working (%d%%)", percentage); + snprintf(STATE_MODULE.firmware_update_status, 20, "Working (%d%%)", percentage); remaining -= recv_len; } // Validate and switch to new OTA image and reboot if (esp_ota_end(ota_handle) != ESP_OK || esp_ota_set_boot_partition(ota_partition) != ESP_OK) { - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Validation Error"); + snprintf(STATE_MODULE.firmware_update_status, 20, "Validation Error"); httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Validation / Activation Error"); return ESP_OK; } - snprintf(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, 20, "Rebooting..."); + snprintf(STATE_MODULE.firmware_update_status, 20, "Rebooting..."); httpd_resp_sendstr(req, "Firmware update complete, rebooting now!\n"); ESP_LOGI(TAG, "Restarting System because of Firmware update complete"); @@ -1041,12 +1043,10 @@ esp_err_t http_404_error_handler(httpd_req_t * req, httpd_err_code_t err) return ESP_OK; } -esp_err_t start_rest_server(void * pvParameters) +esp_err_t start_rest_server() { - GLOBAL_STATE = (GlobalState *) pvParameters; // Initialize the ASIC API with the global state - asic_api_init(GLOBAL_STATE); const char * base_path = ""; bool enter_recovery = false; diff --git a/main/http_server/http_server.h b/main/http_server/http_server.h index 46036f54f..0fe41ea1a 100644 --- a/main/http_server/http_server.h +++ b/main/http_server/http_server.h @@ -1,9 +1,7 @@ #ifndef HTTP_SERVER_H_ #define HTTP_SERVER_H_ - #include -esp_err_t is_network_allowed(httpd_req_t * req); -esp_err_t start_rest_server(void *pvParameters); +esp_err_t start_rest_server(); -#endif /* HTTP_SERVER_H_ */ +#endif \ No newline at end of file diff --git a/main/http_server/websocket.h b/main/http_server/websocket.h index 6ae6160f3..477768477 100644 --- a/main/http_server/websocket.h +++ b/main/http_server/websocket.h @@ -6,6 +6,7 @@ #define MESSAGE_QUEUE_SIZE (128) #define MAX_WEBSOCKET_CLIENTS (10) +esp_err_t is_network_allowed(httpd_req_t * req); esp_err_t websocket_handler(httpd_req_t * req); void websocket_task(void * pvParameters); void websocket_close_fn(httpd_handle_t hd, int sockfd); diff --git a/main/main.c b/main/main.c index 63c886532..73130c64d 100644 --- a/main/main.c +++ b/main/main.c @@ -1,27 +1,46 @@ -#include "esp_event.h" #include "esp_log.h" #include "esp_psram.h" -#include "nvs_flash.h" - +#include "adc.h" +#include "asic.h" +#include "asic_reset.h" #include "asic_result_task.h" #include "asic_task.h" +#include "asic_task_module.h" +#include "connect.h" #include "create_jobs_task.h" -#include "statistics_task.h" -#include "system.h" +#include "device_config.h" #include "http_server.h" -#include "serial.h" -#include "stratum_task.h" #include "i2c_bitaxe.h" -#include "adc.h" #include "nvs_device.h" #include "self_test.h" -#include "asic.h" +#include "serial.h" +#include "statistics_task.h" #include "bap/bap.h" +#include "stratum_task.h" +#include "system.h" +#include "power_management_module.h" +#include "power_management_task.h" +#include "system_module.h" +#include "self_test_module.h" +#include "mining_module.h" #include "device_config.h" -#include "connect.h" -#include "asic_reset.h" - -static GlobalState GLOBAL_STATE; +#include "display.h" +#include "work_queue.h" +#include "wifi_module.h" +#include "pool_module.h" +#include "state_module.h" + +SystemModule SYSTEM_MODULE; +PowerManagementModule POWER_MANAGEMENT_MODULE; +DeviceConfig DEVICE_CONFIG; +DisplayConfig DISPLAY_CONFIG; +AsicTaskModule ASIC_TASK_MODULE; +SelfTestModule SELF_TEST_MODULE; +StatisticsModule STATISTICS_MODULE; +mining_queues MINING_MODULE; +WifiSettings WIFI_MODULE; +PoolModule POOL_MODULE; +StateModule STATE_MODULE; static const char * TAG = "bitaxe"; @@ -31,9 +50,9 @@ void app_main(void) if (!esp_psram_is_initialized()) { ESP_LOGE(TAG, "No PSRAM available on ESP32 device!"); - GLOBAL_STATE.psram_is_available = false; + STATE_MODULE.psram_is_available = false; } else { - GLOBAL_STATE.psram_is_available = true; + STATE_MODULE.psram_is_available = true; } // Init I2C @@ -52,28 +71,27 @@ void app_main(void) return; } - if (device_config_init(&GLOBAL_STATE) != ESP_OK) { + if (device_config_init() != ESP_OK) { ESP_LOGE(TAG, "Failed to init device config"); return; } - if (self_test(&GLOBAL_STATE)) return; + if (self_test()) return; - SYSTEM_init_system(&GLOBAL_STATE); - statistics_init(&GLOBAL_STATE); + SYSTEM_init_system(); + statistics_init(); // init AP and connect to wifi - wifi_init(&GLOBAL_STATE); + wifi_init(); - SYSTEM_init_peripherals(&GLOBAL_STATE); + SYSTEM_init_peripherals(); - xTaskCreate(POWER_MANAGEMENT_task, "power management", 8192, (void *) &GLOBAL_STATE, 10, NULL); - - //start the API for AxeOS - start_rest_server((void *) &GLOBAL_STATE); + xTaskCreate(POWER_MANAGEMENT_task, "power management", 8192, NULL,10, NULL); + // start the API for AxeOS + start_rest_server(); // Initialize BAP interface - esp_err_t bap_ret = BAP_init(&GLOBAL_STATE); + esp_err_t bap_ret = BAP_init(); if (bap_ret != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize BAP interface: %d", bap_ret); // Continue anyway, as BAP is not critical for core functionality @@ -81,35 +99,37 @@ void app_main(void) ESP_LOGI(TAG, "BAP interface initialized successfully"); } - while (!GLOBAL_STATE.SYSTEM_MODULE.is_connected) { + while (!WIFI_MODULE.is_connected) { vTaskDelay(100 / portTICK_PERIOD_MS); } - queue_init(&GLOBAL_STATE.stratum_queue); - queue_init(&GLOBAL_STATE.ASIC_jobs_queue); + queue_init(&MINING_MODULE.stratum_queue); + queue_init(&MINING_MODULE.ASIC_jobs_queue); if (asic_reset() != ESP_OK) { - GLOBAL_STATE.SYSTEM_MODULE.asic_status = "ASIC reset failed"; + STATE_MODULE.asic_status = "ASIC reset failed"; ESP_LOGE(TAG, "ASIC reset failed!"); return; } SERIAL_init(); - if (ASIC_init(&GLOBAL_STATE) == 0) { - GLOBAL_STATE.SYSTEM_MODULE.asic_status = "Chip count 0"; + ESP_LOGE(TAG, "ASIC_init id:%i count:%i diff:%i", DEVICE_CONFIG.family.asic.id, DEVICE_CONFIG.family.asic_count, + DEVICE_CONFIG.family.asic.difficulty); + if (ASIC_init(POWER_MANAGEMENT_MODULE.frequency_value, DEVICE_CONFIG.family.asic_count, + DEVICE_CONFIG.family.asic.difficulty) == 0) { + STATE_MODULE.asic_status = "Chip count 0"; ESP_LOGE(TAG, "Chip count 0"); return; } - SERIAL_set_baud(ASIC_set_max_baud(&GLOBAL_STATE)); + SERIAL_set_baud(ASIC_set_max_baud()); SERIAL_clear_buffer(); - GLOBAL_STATE.ASIC_initalized = true; - - 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); - xTaskCreate(statistics_task, "statistics", 8192, (void *) &GLOBAL_STATE, 3, NULL); + STATE_MODULE.ASIC_initalized = true; + xTaskCreate(stratum_task, "stratum admin", 8192, NULL, 5, NULL); + xTaskCreate(create_jobs_task, "stratum miner", 8192, NULL, 10, NULL); + xTaskCreate(ASIC_task, "asic", 8192, NULL, 10, NULL); + xTaskCreate(ASIC_result_task, "asic result", 8192, NULL, 15, NULL); + xTaskCreate(statistics_task, "statistics", 8192, NULL, 3, NULL); } diff --git a/main/mining_module.h b/main/mining_module.h new file mode 100644 index 000000000..3259d4644 --- /dev/null +++ b/main/mining_module.h @@ -0,0 +1,89 @@ +#ifndef MINING_MODULE_H_ +#define MINING_MODULE_H_ + +#include +#include +#include +//seems to be unused. get set from Kconfig +#define STRATUM_USER CONFIG_STRATUM_USER +#define FALLBACK_STRATUM_USER CONFIG_FALLBACK_STRATUM_USER + +#define QUEUE_SIZE 12 + +/** + * A structure representing a work queue. + */ +typedef struct +{ + /** + * Buffer holding the elements of the queue. + */ + void *buffer[QUEUE_SIZE]; + /** + * Index of the front element in the circular buffer. + */ + int head; + /** + * Index of the back element in the circular buffer. + */ + int tail; + /** + * Current number of elements in the queue. + */ + int count; + /** + * Mutex used to synchronize access to this work queue. + */ + pthread_mutex_t lock; + /** + * Condition variable that signals when the queue is not empty. + */ + pthread_cond_t not_empty; + /** + * Condition variable that signals when the queue is not full. + */ + pthread_cond_t not_full; +} work_queue; + +/** + * A structure containing various mining-related queues and parameters. + */ +typedef struct{ + /** + * Queue for stratum-related jobs. + */ + work_queue stratum_queue; + /** + * Queue for ASIC job tasks. + */ + work_queue ASIC_jobs_queue; + /** + * String to hold extra nonces used in mining. + */ + char * extranonce_str; + /** + * Length of the second extra nonce. + */ + int extranonce_2_len; + /** + * Flag to indicate if the current job should be abandoned. + */ + int abandon_work; + + /** + * Indicates if a new set mining difficulty message is available. + */ + bool new_set_mining_difficulty_msg; + /** + * Version mask for stratum protocol handling. + */ + uint32_t version_mask; + /** + * Indicates if there's a new stratum version rolling message. + */ + bool new_stratum_version_rolling_msg; + +}mining_queues; + +extern mining_queues MINING_MODULE; +#endif \ No newline at end of file diff --git a/main/nvs_device.c b/main/nvs_device.c index 052ee431b..98737344b 100644 --- a/main/nvs_device.c +++ b/main/nvs_device.c @@ -8,7 +8,7 @@ #include "nvs_device.h" #include "connect.h" -#include "global_state.h" + esp_err_t NVSDevice_init(void) { esp_err_t err = nvs_flash_init(); diff --git a/main/nvs_device.h b/main/nvs_device.h index 2654916c8..4a4274ec3 100644 --- a/main/nvs_device.h +++ b/main/nvs_device.h @@ -3,7 +3,7 @@ #include #include "esp_err.h" -#include "global_state.h" + esp_err_t NVSDevice_init(void); diff --git a/main/pool_module.h b/main/pool_module.h new file mode 100644 index 000000000..0aa715b15 --- /dev/null +++ b/main/pool_module.h @@ -0,0 +1,41 @@ +#ifndef POOL_MODULE_H_ +#define POOL_MODULE_H_ + +#include +#define STRATUM_POOL_CAPACITY 2 +typedef struct +{ + // The URL of the mining pool. + char * url; + // The port number on which the mining pool operates. + uint16_t port; + // The username for authenticating with the mining pool. + char * user; + // The password for authenticating with the mining pool. + char * pass; + // The suggested difficulty level set on the mining pool. + uint16_t difficulty; + // A flag indicating whether the mining pool supports extranonce subscription. + bool extranonce_subscribe; +} stratum_pool; + +typedef struct +{ + // The configured pools to connect to. + stratum_pool pools[STRATUM_POOL_CAPACITY]; + + // The currently active pool. + uint8_t active_pool_idx; + + // The difficulty level set on the active mining pool. + uint16_t pool_difficulty; + + // The average response time of the main mining pool to requests. + double response_time; + + // A flag indicating if the system is currently using the fallback pool instead of the main one. + uint8_t default_pool_idx; +}PoolModule; + +extern PoolModule POOL_MODULE; +#endif diff --git a/main/power/INA260.c b/main/power/INA260.c index c1296196c..48c6aa7c5 100644 --- a/main/power/INA260.c +++ b/main/power/INA260.c @@ -1,5 +1,4 @@ #include -#include "esp_log.h" #include "i2c_bitaxe.h" #include "INA260.h" diff --git a/main/power/INA260.h b/main/power/INA260.h index ea524d741..000965e19 100644 --- a/main/power/INA260.h +++ b/main/power/INA260.h @@ -1,7 +1,8 @@ #ifndef INA260_H_ #define INA260_H_ -#include "i2c_bitaxe.h" +#include "esp_err.h" +#include #define INA260_I2CADDR_DEFAULT 0x40 ///< INA260 default i2c address #define INA260_REG_CONFIG 0x00 ///< Configuration register diff --git a/main/power/TPS546.c b/main/power/TPS546.c index ef7cbada1..5aada647d 100644 --- a/main/power/TPS546.c +++ b/main/power/TPS546.c @@ -11,6 +11,8 @@ #include "i2c_bitaxe.h" #include "TPS546.h" +#include "state_module.h" + //#define DEBUG_TPS546_MEAS 1 //uncomment to debug TPS546 measurements //#define DEBUG_TPS546_STATUS 1 //uncomment to debug TPS546 status bits @@ -729,20 +731,19 @@ float TPS546_get_vout(void) } } -esp_err_t TPS546_check_status(GlobalState * GLOBAL_STATE) { +esp_err_t TPS546_check_status() { - SystemModule * SYSTEM_MODULE = &GLOBAL_STATE->SYSTEM_MODULE; uint16_t status; ESP_RETURN_ON_ERROR(smb_read_word(PMBUS_STATUS_WORD, &status), TAG, "Failed to read STATUS_WORD"); //determine if this is a fault we care about if (status & (TPS546_STATUS_OFF | TPS546_STATUS_VOUT_OV | TPS546_STATUS_IOUT_OC | TPS546_STATUS_VIN_UV | TPS546_STATUS_TEMP)) { - if (SYSTEM_MODULE->power_fault == 0) { + if (STATE_MODULE.power_fault == 0) { ESP_RETURN_ON_ERROR(TPS546_parse_status(status), TAG, "Failed to parse STATUS_WORD"); - SYSTEM_MODULE->power_fault = 1; + STATE_MODULE.power_fault = 1; } } else { - SYSTEM_MODULE->power_fault = 0; + STATE_MODULE.power_fault = 0; } return ESP_OK; } diff --git a/main/power/TPS546.h b/main/power/TPS546.h index 81e95390f..8b012a012 100644 --- a/main/power/TPS546.h +++ b/main/power/TPS546.h @@ -5,7 +5,7 @@ #include #include -#include "global_state.h" + #define TPS546_I2CADDR 0x24 // TPS546 i2c address #define TPS546_I2CADDR_ALERT 0x0C // TPS546 SMBus Alert address @@ -181,9 +181,10 @@ float TPS546_get_iout(void); float TPS546_get_vout(void); esp_err_t TPS546_set_vout(float volts); void TPS546_show_voltage_settings(void); +//not used void TPS546_print_status(void); -esp_err_t TPS546_check_status(GlobalState * GLOBAL_STATE); +esp_err_t TPS546_check_status(); esp_err_t TPS546_clear_faults(void); const char* TPS546_get_error_message(void); //Get the current TPS error message diff --git a/main/power/power.c b/main/power/power.c index 02025c97b..eddf3f357 100644 --- a/main/power/power.c +++ b/main/power/power.c @@ -1,15 +1,15 @@ #include "TPS546.h" #include "INA260.h" -#include "DS4432U.h" #include "power.h" +#include "device_config.h" -float Power_get_current(GlobalState * GLOBAL_STATE) +float Power_get_current() { - if (GLOBAL_STATE->DEVICE_CONFIG.TPS546) { + if (DEVICE_CONFIG.TPS546) { return TPS546_get_iout() * 1000.0; } - if (GLOBAL_STATE->DEVICE_CONFIG.INA260) { + if (DEVICE_CONFIG.INA260) { // TODO: Does this check still need to happen? if (INA260_installed() == true) { return INA260_read_current(); @@ -19,19 +19,19 @@ float Power_get_current(GlobalState * GLOBAL_STATE) return 0.0; } -float Power_get_power(GlobalState * GLOBAL_STATE) +float Power_get_power() { float power = 0.0; float current = 0.0; - if (GLOBAL_STATE->DEVICE_CONFIG.TPS546) { + if (DEVICE_CONFIG.TPS546) { current = TPS546_get_iout() * 1000.0; // calculate regulator power (in milliwatts) power = (TPS546_get_vout() * current) / 1000.0; // The power reading from the TPS546 is only it's output power. So the rest of the Bitaxe power is not accounted for. - power += GLOBAL_STATE->DEVICE_CONFIG.family.power_offset; // Add offset for the rest of the Bitaxe power. TODO: this better. + power += DEVICE_CONFIG.family.power_offset; // Add offset for the rest of the Bitaxe power. TODO: this better. } - if (GLOBAL_STATE->DEVICE_CONFIG.INA260) { + if (DEVICE_CONFIG.INA260) { // TODO: Does this check still need to happen? if (INA260_installed() == true) { power = INA260_read_power() / 1000.0; @@ -41,12 +41,12 @@ float Power_get_power(GlobalState * GLOBAL_STATE) return power; } -float Power_get_input_voltage(GlobalState * GLOBAL_STATE) +float Power_get_input_voltage() { - if (GLOBAL_STATE->DEVICE_CONFIG.TPS546) { + if (DEVICE_CONFIG.TPS546) { return TPS546_get_vin() * 1000.0; } - if (GLOBAL_STATE->DEVICE_CONFIG.INA260) { + if (DEVICE_CONFIG.INA260) { // TODO: Does this check still need to happen? if (INA260_installed() == true) { return INA260_read_voltage(); @@ -56,9 +56,9 @@ float Power_get_input_voltage(GlobalState * GLOBAL_STATE) return 0.0; } -float Power_get_vreg_temp(GlobalState * GLOBAL_STATE) +float Power_get_vreg_temp() { - if (GLOBAL_STATE->DEVICE_CONFIG.TPS546) { + if (DEVICE_CONFIG.TPS546) { return TPS546_get_temperature(); } diff --git a/main/power/power.h b/main/power/power.h index 7a4cab67b..eeea3e4be 100644 --- a/main/power/power.h +++ b/main/power/power.h @@ -1,12 +1,9 @@ #ifndef POWER_H #define POWER_H -#include -#include "global_state.h" - -float Power_get_current(GlobalState * GLOBAL_STATE); -float Power_get_power(GlobalState * GLOBAL_STATE); -float Power_get_input_voltage(GlobalState * GLOBAL_STATE); -float Power_get_vreg_temp(GlobalState * GLOBAL_STATE); +float Power_get_current(); +float Power_get_power(); +float Power_get_input_voltage(); +float Power_get_vreg_temp(); #endif // POWER_H diff --git a/main/power/vcore.c b/main/power/vcore.c index fcdb15ae6..593e25a13 100644 --- a/main/power/vcore.c +++ b/main/power/vcore.c @@ -8,6 +8,7 @@ #include "TPS546.h" #include "INA260.h" #include "driver/gpio.h" +#include "device_config.h" #define GPIO_ASIC_ENABLE CONFIG_GPIO_ASIC_ENABLE #define GPIO_PLUG_SENSE CONFIG_GPIO_PLUG_SENSE @@ -46,15 +47,15 @@ static TPS546_CONFIG TPS546_CONFIG_GAMMA = { .TPS546_INIT_IOUT_OC_FAULT_LIMIT = 30.00 /* A */ }; -esp_err_t VCORE_init(GlobalState * GLOBAL_STATE) { - if (GLOBAL_STATE->DEVICE_CONFIG.DS4432U) { +esp_err_t VCORE_init() { + if (DEVICE_CONFIG.DS4432U) { ESP_RETURN_ON_ERROR(DS4432U_init(), TAG, "DS4432 init failed!"); } - if (GLOBAL_STATE->DEVICE_CONFIG.INA260) { + if (DEVICE_CONFIG.INA260) { ESP_RETURN_ON_ERROR(INA260_init(), TAG, "INA260 init failed!"); } - if (GLOBAL_STATE->DEVICE_CONFIG.TPS546) { - switch (GLOBAL_STATE->DEVICE_CONFIG.family.asic_count) { + if (DEVICE_CONFIG.TPS546) { + switch (DEVICE_CONFIG.family.asic_count) { case 1: ESP_RETURN_ON_ERROR(TPS546_init(TPS546_CONFIG_GAMMA), TAG, "TPS546 init failed!"); break; @@ -64,7 +65,7 @@ esp_err_t VCORE_init(GlobalState * GLOBAL_STATE) { } } - if (GLOBAL_STATE->DEVICE_CONFIG.plug_sense) { + if (DEVICE_CONFIG.plug_sense) { gpio_config_t barrel_jack_conf = { .pin_bit_mask = (1ULL << GPIO_PLUG_SENSE), .mode = GPIO_MODE_INPUT, @@ -73,7 +74,7 @@ esp_err_t VCORE_init(GlobalState * GLOBAL_STATE) { int barrel_jack_plugged_in = gpio_get_level(GPIO_PLUG_SENSE); gpio_set_direction(GPIO_ASIC_ENABLE, GPIO_MODE_OUTPUT); - if (barrel_jack_plugged_in == 1 || GLOBAL_STATE->DEVICE_CONFIG.asic_enable) { + if (barrel_jack_plugged_in == 1 || DEVICE_CONFIG.asic_enable) { gpio_set_level(GPIO_ASIC_ENABLE, 0); } else { // turn ASIC off @@ -84,41 +85,41 @@ esp_err_t VCORE_init(GlobalState * GLOBAL_STATE) { return ESP_OK; } -esp_err_t VCORE_set_voltage(GlobalState * GLOBAL_STATE, float core_voltage) +esp_err_t VCORE_set_voltage(float core_voltage) { ESP_LOGI(TAG, "Set ASIC voltage = %.3fV", core_voltage); - if (GLOBAL_STATE->DEVICE_CONFIG.DS4432U) { + if (DEVICE_CONFIG.DS4432U) { if (core_voltage != 0.0f) { ESP_RETURN_ON_ERROR(DS4432U_set_voltage(core_voltage), TAG, "DS4432U set voltage failed!"); } } - if (GLOBAL_STATE->DEVICE_CONFIG.TPS546) { + if (DEVICE_CONFIG.TPS546) { ESP_RETURN_ON_ERROR(TPS546_set_vout(core_voltage), TAG, "TPS546 set voltage failed!"); } - if (core_voltage == 0.0f && GLOBAL_STATE->DEVICE_CONFIG.asic_enable) { + if (core_voltage == 0.0f && DEVICE_CONFIG.asic_enable) { gpio_set_level(GPIO_ASIC_ENABLE, 1); } return ESP_OK; } -int16_t VCORE_get_voltage_mv(GlobalState * GLOBAL_STATE) +int16_t VCORE_get_voltage_mv() { // TODO: What about hex? return ADC_get_vcore(); } -esp_err_t VCORE_check_fault(GlobalState * GLOBAL_STATE) +esp_err_t VCORE_check_fault() { - if (GLOBAL_STATE->DEVICE_CONFIG.TPS546) { - ESP_RETURN_ON_ERROR(TPS546_check_status(GLOBAL_STATE), TAG, "TPS546 check status failed!"); + if (DEVICE_CONFIG.TPS546) { + ESP_RETURN_ON_ERROR(TPS546_check_status(), TAG, "TPS546 check status failed!"); } return ESP_OK; } -const char* VCORE_get_fault_string(GlobalState * GLOBAL_STATE) { - if (GLOBAL_STATE->DEVICE_CONFIG.TPS546) { +const char* VCORE_get_fault_string() { + if (DEVICE_CONFIG.TPS546) { return TPS546_get_error_message(); } return NULL; diff --git a/main/power/vcore.h b/main/power/vcore.h index ee7766e89..c1691fd76 100644 --- a/main/power/vcore.h +++ b/main/power/vcore.h @@ -1,12 +1,12 @@ #ifndef VCORE_H_ #define VCORE_H_ -#include "global_state.h" +#include "esp_err.h" -esp_err_t VCORE_init(GlobalState * GLOBAL_STATE); -esp_err_t VCORE_set_voltage(GlobalState * GLOBAL_STATE, float core_voltage); -int16_t VCORE_get_voltage_mv(GlobalState * GLOBAL_STATE); -esp_err_t VCORE_check_fault(GlobalState * GLOBAL_STATE); -const char* VCORE_get_fault_string(GlobalState * GLOBAL_STATE); +esp_err_t VCORE_init(); +esp_err_t VCORE_set_voltage(float core_voltage); +int16_t VCORE_get_voltage_mv(); +esp_err_t VCORE_check_fault(); +const char* VCORE_get_fault_string(); #endif /* VCORE_H_ */ diff --git a/main/power_management_module.h b/main/power_management_module.h new file mode 100644 index 000000000..5afe1a646 --- /dev/null +++ b/main/power_management_module.h @@ -0,0 +1,33 @@ +#ifndef POWER_MANAGMENT_MODULE_H_ +#define POWER_MANAGMENT_MODULE_H_ +/** + * @brief Structure representing a Power Management Module + */ +typedef struct +{ + /** @brief Fan percentage (0-100) */ + uint16_t fan_perc; + /** @brief Fan speed in revolutions per minute (RPM) */ + uint16_t fan_rpm; + /** @brief Array containing temperatures of up to 6 chips (in Celsius) */ + float chip_temp[6]; + /** @brief Average temperature of the chips (in Celsius) */ + float chip_temp_avg; + float chip_temp2_avg; + /** @brief Voltage regulator temperature (VR temp) in Celsius */ + float vr_temp; + /** @brief Input voltage value in Volts */ + float voltage; + /** @brief Frequency value in Hertz */ + float frequency_value; + /** @brief Power consumption in Watts */ + float power; + /** @brief Current draw in Amperes */ + float current; + /** @brief Core voltage (Vcore) in Volts */ + float core_voltage; +} PowerManagementModule; + +extern PowerManagementModule POWER_MANAGEMENT_MODULE; + +#endif \ No newline at end of file diff --git a/main/screen.c b/main/screen.c index 04d30b3f0..1328b0eb1 100644 --- a/main/screen.c +++ b/main/screen.c @@ -1,17 +1,25 @@ -#include -#include "esp_log.h" -#include "esp_err.h" -#include "esp_check.h" -#include "lvgl.h" -#include "esp_lvgl_port.h" -#include "global_state.h" #include "screen.h" -#include "nvs_config.h" -#include "display.h" #include "connect.h" +#include "display.h" +#include "esp_check.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_lvgl_port.h" #include "esp_timer.h" - -typedef enum { +#include "power_management_task.h" +#include "lvgl.h" +#include "nvs_config.h" +#include +#include "system_module.h" +#include "self_test_module.h" +#include "device_config.h" +#include "power_management_module.h" +#include "wifi_module.h" +#include "pool_module.h" +#include "state_module.h" + +typedef enum +{ SCR_SELF_TEST, SCR_OVERHEAT, SCR_ASIC_STATUS, @@ -41,18 +49,15 @@ static screen_t current_screen = -1; static int current_screen_time_ms; static int current_screen_delay_ms; -// static int screen_chars; static int screen_lines; -static GlobalState * GLOBAL_STATE; - static lv_obj_t *self_test_message_label; static lv_obj_t *self_test_result_label; static lv_obj_t *self_test_finished_label; static lv_obj_t *overheat_ip_addr_label; -static lv_obj_t *asic_status_label; +static lv_obj_t * asic_status_label; static lv_obj_t *mining_block_height_label; static lv_obj_t *mining_network_difficulty_label; @@ -132,7 +137,8 @@ static lv_obj_t * create_scr_self_test() { return scr; } -static lv_obj_t * create_scr_overheat(SystemModule * module) { +static lv_obj_t * create_scr_overheat() +{ lv_obj_t * scr = create_flex_screen(4); lv_obj_t *label1 = lv_label_create(scr); @@ -151,7 +157,8 @@ static lv_obj_t * create_scr_overheat(SystemModule * module) { return scr; } -static lv_obj_t * create_scr_asic_status(SystemModule * module) { +static lv_obj_t * create_scr_asic_status() +{ lv_obj_t * scr = create_flex_screen(2); lv_obj_t *label1 = lv_label_create(scr); @@ -163,8 +170,9 @@ static lv_obj_t * create_scr_asic_status(SystemModule * module) { return scr; } -static lv_obj_t * create_scr_welcome(SystemModule * module) { - lv_obj_t * scr = create_flex_screen(3); +static lv_obj_t * create_scr_welcome() +{ + lv_obj_t * scr = create_flex_screen(4); lv_obj_t *label1 = lv_label_create(scr); lv_obj_set_width(label1, LV_HOR_RES); @@ -178,13 +186,14 @@ static lv_obj_t * create_scr_welcome(SystemModule * module) { lv_obj_t *label2 = lv_label_create(scr); lv_label_set_text(label2, "Wi-Fi (for setup):"); - lv_obj_t *label3 = lv_label_create(scr); - lv_label_set_text(label3, module->ap_ssid); + lv_obj_t * label3 = lv_label_create(scr); + lv_label_set_text(label3, WIFI_MODULE.ap_ssid); return scr; } -static lv_obj_t * create_scr_firmware(SystemModule * module) { +static lv_obj_t * create_scr_firmware() +{ lv_obj_t * scr = create_flex_screen(3); lv_obj_t *label1 = lv_label_create(scr); @@ -198,13 +207,14 @@ static lv_obj_t * create_scr_firmware(SystemModule * module) { return scr; } -static lv_obj_t * create_scr_connection(SystemModule * module) { +static lv_obj_t * create_scr_connection() +{ lv_obj_t * scr = create_flex_screen(4); lv_obj_t *label1 = lv_label_create(scr); lv_obj_set_width(label1, LV_HOR_RES); lv_label_set_long_mode(label1, LV_LABEL_LONG_SCROLL_CIRCULAR); - lv_label_set_text_fmt(label1, "Wi-Fi: %s", module->ssid); + lv_label_set_text_fmt(label1, "Wi-Fi: %s", WIFI_MODULE.ssid); connection_wifi_status_label = lv_label_create(scr); lv_obj_set_width(connection_wifi_status_label, LV_HOR_RES); @@ -213,8 +223,8 @@ static lv_obj_t * create_scr_connection(SystemModule * module) { lv_obj_t *label3 = lv_label_create(scr); lv_label_set_text(label3, "Wi-Fi (for setup):"); - lv_obj_t *label4 = lv_label_create(scr); - lv_label_set_text(label4, module->ap_ssid); + lv_obj_t * label4 = lv_label_create(scr); + lv_label_set_text(label4, WIFI_MODULE.ap_ssid); return scr; } @@ -247,7 +257,8 @@ static lv_obj_t * create_scr_osmu_logo() { return scr; } -static lv_obj_t * create_scr_urls(SystemModule * module) { +static lv_obj_t * create_scr_urls() +{ lv_obj_t * scr = create_flex_screen(4); lv_obj_t *label1 = lv_label_create(scr); @@ -265,24 +276,6 @@ static lv_obj_t * create_scr_urls(SystemModule * module) { return scr; } -static lv_obj_t * create_scr_stats() { - lv_obj_t * scr = create_flex_screen(4); - - stats_hashrate_label = lv_label_create(scr); - lv_label_set_text(stats_hashrate_label, "Gh/s: --"); - - stats_efficiency_label = lv_label_create(scr); - lv_label_set_text(stats_efficiency_label, "J/Th: --"); - - stats_difficulty_label = lv_label_create(scr); - lv_label_set_text(stats_difficulty_label, "Best: --"); - - stats_temp_label = lv_label_create(scr); - lv_label_set_text(stats_temp_label, "Temp: --"); - - return scr; -} - static lv_obj_t * create_scr_mining() { lv_obj_t * scr = create_flex_screen(4); @@ -303,6 +296,24 @@ static lv_obj_t * create_scr_mining() { return scr; } +static lv_obj_t * create_scr_stats() { + lv_obj_t * scr = create_flex_screen(4); + + stats_hashrate_label = lv_label_create(scr); + lv_label_set_text(stats_hashrate_label, "Gh/s: --"); + + stats_efficiency_label = lv_label_create(scr); + lv_label_set_text(stats_efficiency_label, "J/Th: --"); + + stats_difficulty_label = lv_label_create(scr); + lv_label_set_text(stats_difficulty_label, "Best: --"); + + stats_temp_label = lv_label_create(scr); + lv_label_set_text(stats_temp_label, "Temp: --"); + + return scr; +} + static lv_obj_t * create_scr_wifi() { lv_obj_t * scr = create_flex_screen(4); @@ -362,58 +373,54 @@ static void screen_update_cb(lv_timer_t * timer) } } - if (GLOBAL_STATE->SELF_TEST_MODULE.is_active) { - SelfTestModule * self_test = &GLOBAL_STATE->SELF_TEST_MODULE; - - lv_label_set_text(self_test_message_label, self_test->message); + if (SELF_TEST_MODULE.is_active) { + lv_label_set_text(self_test_message_label, SELF_TEST_MODULE.message); - if (self_test->is_finished && !self_test_finished) { + if (SELF_TEST_MODULE.is_finished && !self_test_finished) { self_test_finished = true; - lv_label_set_text(self_test_result_label, self_test->result); - lv_label_set_text(self_test_finished_label, self_test->finished); + lv_label_set_text(self_test_result_label, SELF_TEST_MODULE.result); + lv_label_set_text(self_test_finished_label, SELF_TEST_MODULE.finished); } screen_show(SCR_SELF_TEST); return; } - if (GLOBAL_STATE->SYSTEM_MODULE.is_firmware_update) { - if (strcmp(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_filename, lv_label_get_text(firmware_update_scr_filename_label)) != 0) { - lv_label_set_text(firmware_update_scr_filename_label, GLOBAL_STATE->SYSTEM_MODULE.firmware_update_filename); + if (STATE_MODULE.is_firmware_update) { + if (strcmp(STATE_MODULE.firmware_update_filename, lv_label_get_text(firmware_update_scr_filename_label)) != 0) { + lv_label_set_text(firmware_update_scr_filename_label, STATE_MODULE.firmware_update_filename); } - if (strcmp(GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status, lv_label_get_text(firmware_update_scr_status_label)) != 0) { - lv_label_set_text(firmware_update_scr_status_label, GLOBAL_STATE->SYSTEM_MODULE.firmware_update_status); + if (strcmp(STATE_MODULE.firmware_update_status, lv_label_get_text(firmware_update_scr_status_label)) != 0) { + lv_label_set_text(firmware_update_scr_status_label, STATE_MODULE.firmware_update_status); } screen_show(SCR_FIRMWARE); return; } - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - if (module->asic_status) { - lv_label_set_text(asic_status_label, module->asic_status); + if (STATE_MODULE.asic_status) { + lv_label_set_text(asic_status_label, STATE_MODULE.asic_status); screen_show(SCR_ASIC_STATUS); return; } - if (module->overheat_mode == 1) { - if (strcmp(module->ip_addr_str, lv_label_get_text(overheat_ip_addr_label)) != 0) { - lv_label_set_text(overheat_ip_addr_label, module->ip_addr_str); + if (STATE_MODULE.overheat_mode == 1) { + if (strcmp(WIFI_MODULE.ip_addr_str, lv_label_get_text(overheat_ip_addr_label)) != 0) { + lv_label_set_text(urls_ip_addr_label, WIFI_MODULE.ip_addr_str); } screen_show(SCR_OVERHEAT); return; } - if (module->ssid[0] == '\0') { + if (WIFI_MODULE.ssid[0] == '\0') { screen_show(SCR_WELCOME); return; } - if (module->ap_enabled) { - if (strcmp(module->wifi_status, lv_label_get_text(connection_wifi_status_label)) != 0) { - lv_label_set_text(connection_wifi_status_label, module->wifi_status); + if (WIFI_MODULE.ap_enabled) { + if (strcmp(WIFI_MODULE.wifi_status, lv_label_get_text(connection_wifi_status_label)) != 0) { + lv_label_set_text(connection_wifi_status_label, WIFI_MODULE.wifi_status); } screen_show(SCR_CONNECTION); @@ -424,64 +431,61 @@ static void screen_update_cb(lv_timer_t * timer) current_screen_time_ms += SCREEN_UPDATE_MS; - PowerManagementModule * power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE; - - char *pool_url = module->is_using_fallback ? module->fallback_pool_url : module->pool_url; + char * pool_url = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].url; if (strcmp(lv_label_get_text(urls_mining_url_label), pool_url) != 0) { lv_label_set_text(urls_mining_url_label, pool_url); } - if (strcmp(lv_label_get_text(urls_ip_addr_label), module->ip_addr_str) != 0) { - lv_label_set_text(urls_ip_addr_label, module->ip_addr_str); + if (strcmp(lv_label_get_text(urls_mining_url_label), WIFI_MODULE.ip_addr_str) != 0) { + lv_label_set_text(urls_ip_addr_label, WIFI_MODULE.ip_addr_str); } - if (current_hashrate != module->current_hashrate) { - lv_label_set_text_fmt(stats_hashrate_label, "Gh/s: %.2f", module->current_hashrate); + if (current_hashrate != SYSTEM_MODULE.current_hashrate) { + lv_label_set_text_fmt(stats_hashrate_label, "Gh/s: %.2f", SYSTEM_MODULE.current_hashrate); } - if (current_power != power_management->power || current_hashrate != module->current_hashrate) { - if (power_management->power > 0 && module->current_hashrate > 0) { - float efficiency = power_management->power / (module->current_hashrate / 1000.0); + if (current_power != POWER_MANAGEMENT_MODULE.power || current_hashrate != SYSTEM_MODULE.current_hashrate) { + if (POWER_MANAGEMENT_MODULE.power > 0 && SYSTEM_MODULE.current_hashrate > 0) { + float efficiency = POWER_MANAGEMENT_MODULE.power / (SYSTEM_MODULE.current_hashrate / 1000.0); lv_label_set_text_fmt(stats_efficiency_label, "J/Th: %.2f", efficiency); } - current_power = power_management->power; + current_power = POWER_MANAGEMENT_MODULE.power; } - current_hashrate = module->current_hashrate; + current_hashrate = SYSTEM_MODULE.current_hashrate; - if (current_difficulty != module->best_session_nonce_diff) { - if (module->FOUND_BLOCK) { + if (current_difficulty != SYSTEM_MODULE.best_session_nonce_diff) { + if (STATE_MODULE.FOUND_BLOCK) { lv_obj_set_width(stats_difficulty_label, LV_HOR_RES); lv_label_set_long_mode(stats_difficulty_label, LV_LABEL_LONG_SCROLL_CIRCULAR); - lv_label_set_text_fmt(stats_difficulty_label, "Best: %s !!! BLOCK FOUND !!!", module->best_session_diff_string); + lv_label_set_text_fmt(stats_difficulty_label, "Best: %s !!! BLOCK FOUND !!!", SYSTEM_MODULE.best_session_diff_string); } else { - lv_label_set_text_fmt(stats_difficulty_label, "Best: %s/%s", module->best_session_diff_string, module->best_diff_string); + lv_label_set_text_fmt(stats_difficulty_label, "Best: %s/%s", SYSTEM_MODULE.best_session_diff_string, SYSTEM_MODULE.best_diff_string); } - current_difficulty = module->best_session_nonce_diff; + current_difficulty = SYSTEM_MODULE.best_session_nonce_diff; } - if (current_chip_temp != power_management->chip_temp_avg) { - if (power_management->chip_temp_avg > 0) { - lv_label_set_text_fmt(stats_temp_label, "Temp: %.1f °C", power_management->chip_temp_avg); - } - current_chip_temp = power_management->chip_temp_avg; + if (current_chip_temp != POWER_MANAGEMENT_MODULE.chip_temp_avg && POWER_MANAGEMENT_MODULE.chip_temp_avg > 0) { + lv_label_set_text_fmt(stats_temp_label, "Temp: %.1f C", POWER_MANAGEMENT_MODULE.chip_temp_avg); } + current_chip_temp = POWER_MANAGEMENT_MODULE.chip_temp_avg; + - if (current_block_height != GLOBAL_STATE->block_height) { - lv_label_set_text_fmt(mining_block_height_label, "Block: %d", GLOBAL_STATE->block_height); - current_block_height = GLOBAL_STATE->block_height; + if (current_block_height != SYSTEM_MODULE.block_height) { + lv_label_set_text_fmt(mining_block_height_label, "Block: %d", SYSTEM_MODULE.block_height); + current_block_height = SYSTEM_MODULE.block_height; } - if (strcmp(&lv_label_get_text(mining_network_difficulty_label)[9], GLOBAL_STATE->network_diff_string) != 0) { - lv_label_set_text_fmt(mining_network_difficulty_label, "Difficulty: %s", GLOBAL_STATE->network_diff_string); + if (strcmp(&lv_label_get_text(mining_network_difficulty_label)[9], SYSTEM_MODULE.network_diff_string) != 0) { + lv_label_set_text_fmt(mining_network_difficulty_label, "Difficulty: %s", SYSTEM_MODULE.network_diff_string); } - if (GLOBAL_STATE->scriptsig != NULL && strcmp(lv_label_get_text(mining_scriptsig_label), GLOBAL_STATE->scriptsig) != 0) { - lv_label_set_text(mining_scriptsig_label, GLOBAL_STATE->scriptsig); + if (SYSTEM_MODULE.scriptsig != NULL && strcmp(lv_label_get_text(mining_scriptsig_label), SYSTEM_MODULE.scriptsig) != 0) { + lv_label_set_text(mining_scriptsig_label, SYSTEM_MODULE.scriptsig); } // Update WiFi RSSI periodically int8_t rssi_value = -128; - if (GLOBAL_STATE->SYSTEM_MODULE.is_connected) { + if (WIFI_MODULE.is_connected) { get_wifi_current_rssi(&rssi_value); } @@ -506,9 +510,9 @@ static void screen_update_cb(lv_timer_t * timer) current_rssi_value = rssi_value; } - uint32_t shares_accepted = module->shares_accepted; - uint32_t shares_rejected = module->shares_rejected; - uint32_t work_received = module->work_received; + uint32_t shares_accepted = SYSTEM_MODULE.shares_accepted; + uint32_t shares_rejected = SYSTEM_MODULE.shares_rejected; + uint32_t work_received = SYSTEM_MODULE.work_received; if (current_shares_accepted != shares_accepted || current_shares_rejected != shares_rejected @@ -532,7 +536,7 @@ static void screen_update_cb(lv_timer_t * timer) } } - if (module->FOUND_BLOCK) { + if (STATE_MODULE.FOUND_BLOCK) { if (current_screen != SCR_STATS) { screen_show(SCR_STATS); } @@ -563,7 +567,7 @@ static void uptime_update_cb(lv_timer_t * timer) { if (wifi_uptime_label) { char uptime[50]; - uint32_t uptime_seconds = (esp_timer_get_time() - GLOBAL_STATE->SYSTEM_MODULE.start_time) / 1000000; + uint32_t uptime_seconds = (esp_timer_get_time() - SYSTEM_MODULE.start_time) / 1000000; uint32_t days = uptime_seconds / (24 * 3600); uptime_seconds %= (24 * 3600); @@ -588,25 +592,22 @@ static void uptime_update_cb(lv_timer_t * timer) } } -esp_err_t screen_start(void * pvParameters) +esp_err_t screen_start() { // screen_chars = lv_display_get_horizontal_resolution(NULL) / 6; screen_lines = lv_display_get_vertical_resolution(NULL) / 8; - - GLOBAL_STATE = (GlobalState *) pvParameters; - - if (GLOBAL_STATE->SYSTEM_MODULE.is_screen_active) { - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; + + if (STATE_MODULE.is_screen_active) { screens[SCR_SELF_TEST] = create_scr_self_test(); - screens[SCR_OVERHEAT] = create_scr_overheat(module); - screens[SCR_ASIC_STATUS] = create_scr_asic_status(module); - screens[SCR_WELCOME] = create_scr_welcome(module); - screens[SCR_FIRMWARE] = create_scr_firmware(module); - screens[SCR_CONNECTION] = create_scr_connection(module); - screens[SCR_BITAXE_LOGO] = create_scr_bitaxe_logo(GLOBAL_STATE->DEVICE_CONFIG.family.name, GLOBAL_STATE->DEVICE_CONFIG.board_version); + screens[SCR_OVERHEAT] = create_scr_overheat(); + screens[SCR_ASIC_STATUS] = create_scr_asic_status(); + screens[SCR_WELCOME] = create_scr_welcome(); + screens[SCR_FIRMWARE] = create_scr_firmware(); + screens[SCR_CONNECTION] = create_scr_connection(); + screens[SCR_BITAXE_LOGO] = create_scr_bitaxe_logo(DEVICE_CONFIG.family.name, DEVICE_CONFIG.board_version); screens[SCR_OSMU_LOGO] = create_scr_osmu_logo(); - screens[SCR_URLS] = create_scr_urls(module); + screens[SCR_URLS] = create_scr_urls(); screens[SCR_STATS] = create_scr_stats(); screens[SCR_MINING] = create_scr_mining(); screens[SCR_WIFI] = create_scr_wifi(); diff --git a/main/screen.h b/main/screen.h index 03e919ed5..e872baea4 100644 --- a/main/screen.h +++ b/main/screen.h @@ -1,7 +1,9 @@ #ifndef SCREEN_H_ #define SCREEN_H_ -esp_err_t screen_start(void * pvParameters); +#include "esp_event.h" + +esp_err_t screen_start(); void screen_next(void); #endif /* SCREEN_H_ */ diff --git a/main/self_test/self_test.c b/main/self_test/self_test.c index 84fc2ccf7..7a0123234 100644 --- a/main/self_test/self_test.c +++ b/main/self_test/self_test.c @@ -7,32 +7,37 @@ #include "esp_log.h" #include "esp_timer.h" -#include "i2c_bitaxe.h" #include "DS4432U.h" #include "EMC2101.h" #include "INA260.h" +#include "TPS546.h" #include "adc.h" -#include "global_state.h" -#include "nvs_config.h" -#include "nvs_flash.h" #include "display.h" -#include "screen.h" -#include "input.h" -#include "vcore.h" -#include "utils.h" -#include "TPS546.h" #include "esp_psram.h" + +#include "i2c_bitaxe.h" +#include "input.h" +#include "nvs_config.h" +#include "nvs_flash.h" #include "power.h" +#include "screen.h" #include "thermal.h" -#include "power_management_task.h" +#include "utils.h" +#include "vcore.h" -#include "bm1397.h" +#include "asic.h" +#include "asic_reset.h" #include "bm1366.h" #include "bm1368.h" #include "bm1370.h" -#include "asic.h" +#include "bm1397.h" #include "device_config.h" -#include "asic_reset.h" +#include "power_management_task.h" +#include "power_management_module.h" +#include "asic_task_module.h" +#include "serial.h" +#include "self_test_module.h" +#include "state_module.h" #define GPIO_ASIC_ENABLE CONFIG_GPIO_ASIC_ENABLE @@ -55,10 +60,11 @@ static const char * TAG = "self_test"; static SemaphoreHandle_t longPressSemaphore; static bool isFactoryTest = false; -//local function prototypes -static void tests_done(GlobalState * GLOBAL_STATE, bool test_result); +// local function prototypes +static void tests_done(bool test_result); -static bool should_test() { +static bool should_test() +{ uint64_t is_factory_flash = nvs_config_get_u64(NVS_CONFIG_BEST_DIFF, 0) < 1; uint16_t is_self_test_flag_set = nvs_config_get_u16(NVS_CONFIG_SELF_TEST, 0); if (is_factory_flash && is_self_test_flag_set) { @@ -76,14 +82,14 @@ static void reset_self_test() { xSemaphoreGive(longPressSemaphore); } -static void display_msg(char * msg, GlobalState * GLOBAL_STATE) +static void display_msg(char * msg) { - GLOBAL_STATE->SELF_TEST_MODULE.message = msg; + SELF_TEST_MODULE.message = msg; } -static esp_err_t test_fan_sense(GlobalState * GLOBAL_STATE) +static esp_err_t test_fan_sense() { - uint16_t fan_speed = Thermal_get_fan_speed(&GLOBAL_STATE->DEVICE_CONFIG); + uint16_t fan_speed = Thermal_get_fan_speed(); ESP_LOGI(TAG, "fanSpeed: %d", fan_speed); if (fan_speed > FAN_SPEED_TARGET_MIN) { return ESP_OK; @@ -91,7 +97,7 @@ static esp_err_t test_fan_sense(GlobalState * GLOBAL_STATE) //fan test failed ESP_LOGE(TAG, "FAN test failed!"); - display_msg("FAN:WARN", GLOBAL_STATE); + display_msg("FAN:WARN"); return ESP_FAIL; } @@ -117,9 +123,9 @@ static esp_err_t test_TPS546_power_consumption(int target_power, int margin) return ESP_FAIL; } -static esp_err_t test_core_voltage(GlobalState * GLOBAL_STATE) +static esp_err_t test_core_voltage() { - uint16_t core_voltage = VCORE_get_voltage_mv(GLOBAL_STATE); + uint16_t core_voltage = VCORE_get_voltage_mv(); ESP_LOGI(TAG, "Voltage: %u", core_voltage); if (core_voltage > CORE_VOLTAGE_TARGET_MIN && core_voltage < CORE_VOLTAGE_TARGET_MAX) { @@ -127,18 +133,19 @@ static esp_err_t test_core_voltage(GlobalState * GLOBAL_STATE) } //tests failed ESP_LOGE(TAG, "Core Voltage TEST FAIL, INCORRECT CORE VOLTAGE"); - display_msg("VCORE:FAIL", GLOBAL_STATE); + display_msg("VCORE:FAIL"); return ESP_FAIL; } -esp_err_t test_display(GlobalState * GLOBAL_STATE) { +esp_err_t test_display() +{ // Display testing - if (display_init(GLOBAL_STATE) != ESP_OK) { - display_msg("DISPLAY:FAIL", GLOBAL_STATE); + if (display_init() != ESP_OK) { + display_msg("DISPLAY:FAIL"); return ESP_FAIL; } - if (GLOBAL_STATE->SYSTEM_MODULE.is_screen_active) { + if (STATE_MODULE.is_screen_active) { ESP_LOGI(TAG, "DISPLAY init success!"); } else { ESP_LOGW(TAG, "DISPLAY not found!"); @@ -147,10 +154,11 @@ esp_err_t test_display(GlobalState * GLOBAL_STATE) { return ESP_OK; } -esp_err_t test_input(GlobalState * GLOBAL_STATE) { +esp_err_t test_input() +{ // Input testing if (input_init(NULL, reset_self_test) != ESP_OK) { - display_msg("INPUT:FAIL", GLOBAL_STATE); + display_msg("INPUT:FAIL"); return ESP_FAIL; } @@ -159,10 +167,11 @@ esp_err_t test_input(GlobalState * GLOBAL_STATE) { return ESP_OK; } -esp_err_t test_screen(GlobalState * GLOBAL_STATE) { +esp_err_t test_screen() +{ // Screen testing - if (screen_start(GLOBAL_STATE) != ESP_OK) { - display_msg("SCREEN:FAIL", GLOBAL_STATE); + if (screen_start() != ESP_OK) { + display_msg("SCREEN:FAIL"); return ESP_FAIL; } @@ -171,45 +180,49 @@ esp_err_t test_screen(GlobalState * GLOBAL_STATE) { return ESP_OK; } -esp_err_t init_voltage_regulator(GlobalState * GLOBAL_STATE) { - ESP_RETURN_ON_ERROR(VCORE_init(GLOBAL_STATE), TAG, "VCORE init failed!"); +esp_err_t init_voltage_regulator() +{ + ESP_RETURN_ON_ERROR(VCORE_init(), TAG, "VCORE init failed!"); + + ESP_RETURN_ON_ERROR(VCORE_set_voltage(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0), TAG, + "VCORE set voltage failed!"); - ESP_RETURN_ON_ERROR(VCORE_set_voltage(GLOBAL_STATE, nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0), TAG, "VCORE set voltage failed!"); - return ESP_OK; } -esp_err_t test_vreg_faults(GlobalState * GLOBAL_STATE) { - //check for faults on the voltage regulator - ESP_RETURN_ON_ERROR(VCORE_check_fault(GLOBAL_STATE), TAG, "VCORE check fault failed!"); +esp_err_t test_vreg_faults() +{ + // check for faults on the voltage regulator + ESP_RETURN_ON_ERROR(VCORE_check_fault(), TAG, "VCORE check fault failed!"); - if (GLOBAL_STATE->SYSTEM_MODULE.power_fault) { + if (STATE_MODULE.power_fault) { return ESP_FAIL; } return ESP_OK; } -esp_err_t test_voltage_regulator(GlobalState * GLOBAL_STATE) { - - //enable the voltage regulator GPIO on HW that supports it - if (GLOBAL_STATE->DEVICE_CONFIG.asic_enable) { +esp_err_t test_voltage_regulator() +{ + + // enable the voltage regulator GPIO on HW that supports it + if (DEVICE_CONFIG.asic_enable) { gpio_set_direction(GPIO_ASIC_ENABLE, GPIO_MODE_OUTPUT); gpio_set_level(GPIO_ASIC_ENABLE, 0); } - if (init_voltage_regulator(GLOBAL_STATE) != ESP_OK) { + if (init_voltage_regulator() != ESP_OK) { ESP_LOGE(TAG, "VCORE init failed!"); - display_msg("VCORE:FAIL", GLOBAL_STATE); - //tests_done(GLOBAL_STATE, false); + display_msg("VCORE:FAIL"); + // tests_done(TESTS_FAILED); return ESP_FAIL; } // VCore regulator testing - if (GLOBAL_STATE->DEVICE_CONFIG.DS4432U) { + if (DEVICE_CONFIG.DS4432U) { if (DS4432U_test() != ESP_OK) { ESP_LOGE(TAG, "DS4432 test failed!"); - display_msg("DS4432U:FAIL", GLOBAL_STATE); - //tests_done(GLOBAL_STATE, false); + display_msg("DS4432U:FAIL"); + // tests_done(TESTS_FAILED); return ESP_FAIL; } } @@ -218,21 +231,22 @@ esp_err_t test_voltage_regulator(GlobalState * GLOBAL_STATE) { return ESP_OK; } -esp_err_t test_init_peripherals(GlobalState * GLOBAL_STATE) { - - if (GLOBAL_STATE->DEVICE_CONFIG.EMC2101) { +esp_err_t test_init_peripherals() +{ + + if (DEVICE_CONFIG.EMC2101) { ESP_RETURN_ON_ERROR(EMC2101_init(), TAG, "EMC2101 init failed!"); EMC2101_set_fan_speed(1); - if (GLOBAL_STATE->DEVICE_CONFIG.emc_ideality_factor != 0x00) { - EMC2101_set_ideality_factor(GLOBAL_STATE->DEVICE_CONFIG.emc_ideality_factor); - EMC2101_set_beta_compensation(GLOBAL_STATE->DEVICE_CONFIG.emc_beta_compensation); + if (DEVICE_CONFIG.emc_ideality_factor != 0x00) { + EMC2101_set_ideality_factor(DEVICE_CONFIG.emc_ideality_factor); + EMC2101_set_beta_compensation(DEVICE_CONFIG.emc_beta_compensation); } } // TODO: EMC2103 - if (GLOBAL_STATE->DEVICE_CONFIG.INA260) { + if (DEVICE_CONFIG.INA260) { ESP_RETURN_ON_ERROR(INA260_init(), TAG, "INA260 init failed!"); } @@ -240,10 +254,11 @@ esp_err_t test_init_peripherals(GlobalState * GLOBAL_STATE) { return ESP_OK; } -esp_err_t test_psram(GlobalState * GLOBAL_STATE){ - if(!esp_psram_is_initialized()) { +esp_err_t test_psram() +{ + if (!esp_psram_is_initialized()) { ESP_LOGE(TAG, "No PSRAM available on ESP32!"); - display_msg("PSRAM:FAIL", GLOBAL_STATE); + display_msg("PSRAM:FAIL"); return ESP_FAIL; } return ESP_OK; @@ -258,9 +273,8 @@ esp_err_t test_psram(GlobalState * GLOBAL_STATE){ * @param pvParameters Pointer to the parameters passed to the task (if any). * @return true if the self-test was run, false if it was skipped. */ -bool self_test(void * pvParameters) +bool self_test() { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; // Should we run the self-test? if (!should_test()) return false; @@ -271,7 +285,7 @@ bool self_test(void * pvParameters) ESP_LOGI(TAG, "Running manual self-test"); } - GLOBAL_STATE->SELF_TEST_MODULE.is_active = true; + SELF_TEST_MODULE.is_active = true; // Create a binary semaphore longPressSemaphore = xSemaphoreCreateBinary(); @@ -280,96 +294,99 @@ bool self_test(void * pvParameters) if (longPressSemaphore == NULL) { ESP_LOGE(TAG, "Failed to create semaphore"); - return true; + return false; } + if (test_psram() != ESP_OK) { //Run PSRAM test - if(test_psram(GLOBAL_STATE) != ESP_OK) { ESP_LOGE(TAG, "NO PSRAM on device!"); - tests_done(GLOBAL_STATE, false); + tests_done(false); } + if (test_display() != ESP_OK) { //Run display tests - if (test_display(GLOBAL_STATE) != ESP_OK) { ESP_LOGE(TAG, "Display test failed!"); - tests_done(GLOBAL_STATE, false); + tests_done(false); } + if (test_input() != ESP_OK) { //Run input tests - if (test_input(GLOBAL_STATE) != ESP_OK) { ESP_LOGE(TAG, "Input test failed!"); - tests_done(GLOBAL_STATE, false); + tests_done(false); } + if (test_screen() != ESP_OK) { //Run screen tests - if (test_screen(GLOBAL_STATE) != ESP_OK) { ESP_LOGE(TAG, "Screen test failed!"); - tests_done(GLOBAL_STATE, false); + tests_done(false); } + if (test_init_peripherals() != ESP_OK) { //Init peripherals EMC2101 and INA260 (if present) - if (test_init_peripherals(GLOBAL_STATE) != ESP_OK) { ESP_LOGE(TAG, "Peripherals init failed!"); - tests_done(GLOBAL_STATE, false); + tests_done(false); } + if (test_voltage_regulator() != ESP_OK) { //Voltage Regulator Testing - if (test_voltage_regulator(GLOBAL_STATE) != ESP_OK) { ESP_LOGE(TAG, "Voltage Regulator test failed!"); - tests_done(GLOBAL_STATE, false); + tests_done(false); } if (asic_reset() != ESP_OK) { ESP_LOGE(TAG, "ASIC reset failed!"); - tests_done(GLOBAL_STATE, false); + tests_done(false); } //test for number of ASICs if (SERIAL_init() != ESP_OK) { ESP_LOGE(TAG, "SERIAL init failed!"); - tests_done(GLOBAL_STATE, false); + tests_done(false); } - POWER_MANAGEMENT_init_frequency(&GLOBAL_STATE->POWER_MANAGEMENT_MODULE); + POWER_MANAGEMENT_init_frequency(); + uint8_t chips_detected = + ASIC_init(POWER_MANAGEMENT_MODULE.frequency_value, + DEVICE_CONFIG.family.asic_count, + DEVICE_CONFIG.family.asic.difficulty); + uint8_t chips_expected = DEVICE_CONFIG.family.asic_count; - GLOBAL_STATE->DEVICE_CONFIG.family.asic.difficulty = DIFFICULTY; + DEVICE_CONFIG.family.asic.difficulty = DIFFICULTY; - uint8_t chips_detected = ASIC_init(GLOBAL_STATE); - uint8_t chips_expected = GLOBAL_STATE->DEVICE_CONFIG.family.asic_count; ESP_LOGI(TAG, "%u chips detected, %u expected", chips_detected, chips_expected); if (chips_detected != chips_expected) { ESP_LOGE(TAG, "SELF-TEST FAIL, %d of %d CHIPS DETECTED", chips_detected, chips_expected); char error_buf[20]; snprintf(error_buf, 20, "ASIC:FAIL %d CHIPS", chips_detected); - display_msg(error_buf, GLOBAL_STATE); - tests_done(GLOBAL_STATE, false); + display_msg(error_buf); + tests_done(false); } + if (test_vreg_faults() != ESP_OK) { //test for voltage regulator faults - if (test_vreg_faults(GLOBAL_STATE) != ESP_OK) { ESP_LOGE(TAG, "VCORE check fault failed!"); char error_buf[20]; snprintf(error_buf, 20, "VCORE:PWR FAULT"); - display_msg(error_buf, GLOBAL_STATE); - tests_done(GLOBAL_STATE, false); + display_msg(error_buf); + tests_done(false); } + int baud = ASIC_set_max_baud(); //setup and test hashrate - int baud = ASIC_set_max_baud(GLOBAL_STATE); vTaskDelay(10 / portTICK_PERIOD_MS); if (SERIAL_set_baud(baud) != ESP_OK) { ESP_LOGE(TAG, "SERIAL set baud failed!"); - tests_done(GLOBAL_STATE, false); + tests_done(false); } - GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128); - GLOBAL_STATE->valid_jobs = malloc(sizeof(uint8_t) * 128); + ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128); + ASIC_TASK_MODULE.valid_jobs = malloc(sizeof(uint8_t) * 128); for (int i = 0; i < 128; i++) { - GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[i] = NULL; - GLOBAL_STATE->valid_jobs[i] = 0; + ASIC_TASK_MODULE.active_jobs[i] = NULL; + ASIC_TASK_MODULE.valid_jobs[i] = 0; } vTaskDelay(1000 / portTICK_PERIOD_MS); @@ -413,9 +430,9 @@ bool self_test(void * pvParameters) ESP_LOGI(TAG, "Sending work"); - //(*GLOBAL_STATE->ASIC_functions.send_work_fn)(GLOBAL_STATE, &job); - ASIC_send_work(GLOBAL_STATE, &job); - + //(*GLOBAL_STATE.ASIC_functions.send_work_fn)(&job); + ASIC_send_work(&job); + double start = esp_timer_get_time(); double sum = 0; double duration = 0; @@ -423,11 +440,12 @@ bool self_test(void * pvParameters) double hashtest_timeout = 5; while (duration < hashtest_timeout) { - task_result * asic_result = ASIC_process_work(GLOBAL_STATE); + task_result * asic_result = ASIC_process_work(); if (asic_result != NULL) { // check the nonce difficulty double nonce_diff = test_nonce_value(&job, asic_result->nonce, asic_result->rolled_version); sum += DIFFICULTY; + hash_rate = (sum * 4294967296) / (duration * 1000000000); ESP_LOGI(TAG, "Nonce %lu Nonce difficulty %.32f.", asic_result->nonce, nonce_diff); @@ -438,68 +456,69 @@ bool self_test(void * pvParameters) ESP_LOGI(TAG, "Hashrate: %f", hash_rate); - float expected_hashrate_mhs = GLOBAL_STATE->POWER_MANAGEMENT_MODULE.frequency_value - * GLOBAL_STATE->DEVICE_CONFIG.family.asic.small_core_count - * GLOBAL_STATE->DEVICE_CONFIG.family.asic.hashrate_test_percentage_target - / 1000.0f; + float expected_hashrate_mhs = POWER_MANAGEMENT_MODULE.frequency_value * DEVICE_CONFIG.family.asic.small_core_count * + DEVICE_CONFIG.family.asic.hashrate_test_percentage_target / 1000.0f; if (hash_rate < expected_hashrate_mhs) { - display_msg("HASHRATE:FAIL", GLOBAL_STATE); - tests_done(GLOBAL_STATE, false); + display_msg("HASHRATE:FAIL"); + tests_done(false); } - free(GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs); - free(GLOBAL_STATE->valid_jobs); + free(ASIC_TASK_MODULE.active_jobs); + free(ASIC_TASK_MODULE.valid_jobs); - if (test_core_voltage(GLOBAL_STATE) != ESP_OK) { - tests_done(GLOBAL_STATE, false); + if (test_core_voltage() != ESP_OK) { + tests_done(false); } // TODO: Maybe make a test equivalent for test values - if (GLOBAL_STATE->DEVICE_CONFIG.INA260) { - if (test_INA260_power_consumption(GLOBAL_STATE->DEVICE_CONFIG.power_consumption_target, POWER_CONSUMPTION_MARGIN) != ESP_OK) { - ESP_LOGE(TAG, "INA260 Power Draw Failed, target %.2f", (float)GLOBAL_STATE->DEVICE_CONFIG.power_consumption_target); - display_msg("POWER:FAIL", GLOBAL_STATE); - tests_done(GLOBAL_STATE, false); + if (DEVICE_CONFIG.INA260) { + if (test_INA260_power_consumption(DEVICE_CONFIG.power_consumption_target, POWER_CONSUMPTION_MARGIN) != ESP_OK) { + ESP_LOGE(TAG, "INA260 Power Draw Failed, target %.2f", (float) DEVICE_CONFIG.power_consumption_target); + display_msg("POWER:FAIL"); + tests_done(false); } } - if (GLOBAL_STATE->DEVICE_CONFIG.TPS546) { - if (test_TPS546_power_consumption(GLOBAL_STATE->DEVICE_CONFIG.power_consumption_target, POWER_CONSUMPTION_MARGIN) != ESP_OK) { - ESP_LOGE(TAG, "TPS546 Power Draw Failed, target %.2f", (float)GLOBAL_STATE->DEVICE_CONFIG.power_consumption_target); - display_msg("POWER:FAIL", GLOBAL_STATE); - tests_done(GLOBAL_STATE, false); + if (DEVICE_CONFIG.TPS546) { + if (test_TPS546_power_consumption(DEVICE_CONFIG.power_consumption_target, POWER_CONSUMPTION_MARGIN) != ESP_OK) { + ESP_LOGE(TAG, "TPS546 Power Draw Failed, target %.2f", (float) DEVICE_CONFIG.power_consumption_target); + display_msg("POWER:FAIL"); + tests_done(false); } } - if (test_fan_sense(GLOBAL_STATE) != ESP_OK) { - ESP_LOGE(TAG, "Fan test failed!"); - tests_done(GLOBAL_STATE, false); + if (test_fan_sense() != ESP_OK) { + ESP_LOGE(TAG, "Fan test failed!"); + tests_done(false); } - tests_done(GLOBAL_STATE, true); + tests_done(true); return true; } -static void tests_done(GlobalState * GLOBAL_STATE, bool isTestPassed) +static void tests_done(bool test_result) { - VCORE_set_voltage(GLOBAL_STATE, 0.0f); + VCORE_set_voltage(0.0f); - if (isTestPassed) { + if (test_result) { if (isFactoryTest) { ESP_LOGI(TAG, "Self-test flag cleared"); nvs_config_set_u16(NVS_CONFIG_SELF_TEST, 0); } ESP_LOGI(TAG, "SELF-TEST PASS! -- Press RESET button to restart."); - GLOBAL_STATE->SELF_TEST_MODULE.result = "SELF-TEST PASS!"; - GLOBAL_STATE->SELF_TEST_MODULE.finished = "Press RESET button to restart."; + SELF_TEST_MODULE.result = "SELF-TEST PASS!"; + SELF_TEST_MODULE.finished = "Press RESET button to restart."; } else { // isTestFailed - GLOBAL_STATE->SELF_TEST_MODULE.result = "SELF-TEST FAIL!"; + SELF_TEST_MODULE.result = "SELF-TEST FAIL!"; if (isFactoryTest) { - ESP_LOGI(TAG, "SELF-TEST FAIL! -- Hold BOOT button for 2 seconds to cancel self-test, or press RESET to run self-test again."); - GLOBAL_STATE->SELF_TEST_MODULE.finished = "Hold BOOT button for 2 seconds to cancel self-test, or press RESET to run self-test again."; - GLOBAL_STATE->SELF_TEST_MODULE.is_finished = true; + ESP_LOGI( + TAG, + "SELF-TEST FAIL! -- Hold BOOT button for 2 seconds to cancel self-test, or press RESET to run self-test again."); + SELF_TEST_MODULE.finished = + "Hold BOOT button for 2 seconds to cancel self-test, or press RESET to run self-test again."; + SELF_TEST_MODULE.is_finished = true; while (1) { // Wait here forever until reset_self_test() gives the longPressSemaphore if (xSemaphoreTake(longPressSemaphore, portMAX_DELAY) == pdTRUE) { @@ -512,9 +531,8 @@ static void tests_done(GlobalState * GLOBAL_STATE, bool isTestPassed) } } else { ESP_LOGI(TAG, "SELF-TEST FAIL -- Press RESET button to restart."); - GLOBAL_STATE->SELF_TEST_MODULE.finished = "Press RESET button to restart."; + SELF_TEST_MODULE.finished = "Press RESET button to restart."; } - } - GLOBAL_STATE->SELF_TEST_MODULE.is_finished = true; + SELF_TEST_MODULE.is_finished = true; } diff --git a/main/self_test/self_test.h b/main/self_test/self_test.h index 17f0f383c..322e4f6c5 100644 --- a/main/self_test/self_test.h +++ b/main/self_test/self_test.h @@ -1,6 +1,6 @@ #ifndef SELF_TEST_H_ #define SELF_TEST_H_ -bool self_test(void * pvParameters); +bool self_test(); #endif diff --git a/main/self_test_module.h b/main/self_test_module.h new file mode 100644 index 000000000..324e79260 --- /dev/null +++ b/main/self_test_module.h @@ -0,0 +1,15 @@ +#ifndef SELFT_TEST_MODULE_H_ +#define SELFT_TEST_MODULE_H_ + +typedef struct +{ + bool is_active; + bool is_finished; + char * message; + char *result; + char *finished; +} SelfTestModule; + +extern SelfTestModule SELF_TEST_MODULE; + +#endif \ No newline at end of file diff --git a/main/state_module.h b/main/state_module.h new file mode 100644 index 000000000..3c9d4a2e2 --- /dev/null +++ b/main/state_module.h @@ -0,0 +1,40 @@ +#ifndef STATE_MODULE_H_ +#define STATE_MODULE_H_ + +typedef struct +{ + // A flag indicating if a block has been found during mining. + bool FOUND_BLOCK; + + // The current overheat mode setting for managing thermal conditions. + uint16_t overheat_mode; + + // Status information about power faults encountered by the device. + uint16_t power_fault; + + + + // A flag indicating whether the screen is currently active. + bool is_screen_active; + + // A flag indicating if a firmware update process is ongoing. + bool is_firmware_update; + + // Filename for the firmware file being used or to be updated. + char firmware_update_filename[20]; + + // Status of the ongoing firmware update process. + char firmware_update_status[20]; + + // Current status string describing ASIC (Application-Specific Integrated Circuit) operation. + char * asic_status; + + // A flag indicating if the ASIC is initialized and ready for operations. + bool ASIC_initalized; + + // A flag indicating whether PSRAM (Pseudo-Static RAM) is available on the device. + bool psram_is_available; +}StateModule; + +extern StateModule STATE_MODULE; +#endif \ No newline at end of file diff --git a/main/system.c b/main/system.c index 220407fad..a9cf54fed 100644 --- a/main/system.c +++ b/main/system.c @@ -30,99 +30,130 @@ #include "vcore.h" #include "thermal.h" #include "utils.h" +#include "asic_task_module.h" +#include "system_module.h" +#include "device_config.h" +#include "pool_module.h" +#include "state_module.h" + static const char * TAG = "system"; //local function prototypes static esp_err_t ensure_overheat_mode_config(); -static void _check_for_best_diff(GlobalState * GLOBAL_STATE, double diff, uint8_t job_id); +static void _check_for_best_diff( double diff, uint8_t job_id); + +typedef struct +{ + // The starting time for a certain period of mining activity. + double duration_start; + + // The index to keep track of the rolling historical hashrate data. + int historical_hashrate_rolling_index; + + // An array to store timestamps corresponding to historical hashrate values. + double historical_hashrate_time_stamps[HISTORY_LENGTH]; + + // An array to store historical hashrate values over a defined period. + double historical_hashrate[HISTORY_LENGTH]; + + // A flag indicating if the historical hashrate data is initialized. + int historical_hashrate_init; + + +} HashHistory; +HashHistory HASH_HISTORY; + +// Timestamp of the last clock synchronization event. +uint32_t lastClockSync; -void SYSTEM_init_system(GlobalState * GLOBAL_STATE) +// The difficulty (nonce) for the best solution found during mining. +uint64_t best_nonce_diff; +void SYSTEM_init_system() { - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - module->duration_start = 0; - module->historical_hashrate_rolling_index = 0; - module->historical_hashrate_init = 0; - module->current_hashrate = 0; - module->screen_page = 0; - module->shares_accepted = 0; - module->shares_rejected = 0; - module->best_nonce_diff = nvs_config_get_u64(NVS_CONFIG_BEST_DIFF, 0); - module->best_session_nonce_diff = 0; - module->start_time = esp_timer_get_time(); - module->lastClockSync = 0; - module->FOUND_BLOCK = false; + + HASH_HISTORY.duration_start = 0; + HASH_HISTORY.historical_hashrate_rolling_index = 0; + HASH_HISTORY.historical_hashrate_init = 0; + SYSTEM_MODULE.current_hashrate = 0; + SYSTEM_MODULE.shares_accepted = 0; + SYSTEM_MODULE.shares_rejected = 0; + SYSTEM_MODULE.best_session_nonce_diff = 0; + best_nonce_diff = nvs_config_get_u64(NVS_CONFIG_BEST_DIFF, 0); + SYSTEM_MODULE.start_time = esp_timer_get_time(); + lastClockSync = 0; + STATE_MODULE.FOUND_BLOCK = false; // set the pool url - module->pool_url = nvs_config_get_string(NVS_CONFIG_STRATUM_URL, CONFIG_STRATUM_URL); - module->fallback_pool_url = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_URL, CONFIG_FALLBACK_STRATUM_URL); + POOL_MODULE.pools[0].url = nvs_config_get_string(NVS_CONFIG_STRATUM_URL, CONFIG_STRATUM_URL); + POOL_MODULE.pools[1].url = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_URL, CONFIG_FALLBACK_STRATUM_URL); // set the pool port - module->pool_port = nvs_config_get_u16(NVS_CONFIG_STRATUM_PORT, CONFIG_STRATUM_PORT); - module->fallback_pool_port = nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_PORT, CONFIG_FALLBACK_STRATUM_PORT); + POOL_MODULE.pools[0].port = nvs_config_get_u16(NVS_CONFIG_STRATUM_PORT, CONFIG_STRATUM_PORT); + POOL_MODULE.pools[1].port = nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_PORT, CONFIG_FALLBACK_STRATUM_PORT); // set the pool user - module->pool_user = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, CONFIG_STRATUM_USER); - module->fallback_pool_user = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_USER, CONFIG_FALLBACK_STRATUM_USER); + POOL_MODULE.pools[0].user = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, CONFIG_STRATUM_USER); + POOL_MODULE.pools[1].user = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_USER, CONFIG_FALLBACK_STRATUM_USER); // set the pool password - module->pool_pass = nvs_config_get_string(NVS_CONFIG_STRATUM_PASS, CONFIG_STRATUM_PW); - module->fallback_pool_pass = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_PASS, CONFIG_FALLBACK_STRATUM_PW); + POOL_MODULE.pools[0].pass = nvs_config_get_string(NVS_CONFIG_STRATUM_PASS, CONFIG_STRATUM_PW); + POOL_MODULE.pools[1].pass = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_PASS, CONFIG_FALLBACK_STRATUM_PW); // set the pool difficulty - module->pool_difficulty = nvs_config_get_u16(NVS_CONFIG_STRATUM_DIFFICULTY, CONFIG_STRATUM_DIFFICULTY); - module->fallback_pool_difficulty = nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_DIFFICULTY, CONFIG_FALLBACK_STRATUM_DIFFICULTY); + POOL_MODULE.pools[0].difficulty = nvs_config_get_u16(NVS_CONFIG_STRATUM_DIFFICULTY, CONFIG_STRATUM_DIFFICULTY); + POOL_MODULE.pools[1].difficulty = + nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_DIFFICULTY, CONFIG_FALLBACK_STRATUM_DIFFICULTY); // set the pool extranonce subscribe - module->pool_extranonce_subscribe = nvs_config_get_u16(NVS_CONFIG_STRATUM_EXTRANONCE_SUBSCRIBE, STRATUM_EXTRANONCE_SUBSCRIBE); - module->fallback_pool_extranonce_subscribe = nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_EXTRANONCE_SUBSCRIBE, FALLBACK_STRATUM_EXTRANONCE_SUBSCRIBE); + POOL_MODULE.pools[0].extranonce_subscribe = + nvs_config_get_u16(NVS_CONFIG_STRATUM_EXTRANONCE_SUBSCRIBE, STRATUM_EXTRANONCE_SUBSCRIBE); + POOL_MODULE.pools[1].extranonce_subscribe = + nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_EXTRANONCE_SUBSCRIBE, FALLBACK_STRATUM_EXTRANONCE_SUBSCRIBE); // set fallback to false. - module->is_using_fallback = false; + POOL_MODULE.default_pool_idx = 0; // Initialize overheat_mode - module->overheat_mode = nvs_config_get_u16(NVS_CONFIG_OVERHEAT_MODE, 0); - ESP_LOGI(TAG, "Initial overheat_mode value: %d", module->overheat_mode); + STATE_MODULE.overheat_mode = nvs_config_get_u16(NVS_CONFIG_OVERHEAT_MODE, 0); + ESP_LOGI(TAG, "Initial overheat_mode value: %d", STATE_MODULE.overheat_mode); //Initialize power_fault fault mode - module->power_fault = 0; + STATE_MODULE.power_fault = 0; // set the best diff string - suffixString(module->best_nonce_diff, module->best_diff_string, DIFF_STRING_SIZE, 0); - suffixString(module->best_session_nonce_diff, module->best_session_diff_string, DIFF_STRING_SIZE, 0); + suffixString(best_nonce_diff, SYSTEM_MODULE.best_diff_string, DIFF_STRING_SIZE, 0); + suffixString(SYSTEM_MODULE.best_session_nonce_diff, SYSTEM_MODULE.best_session_diff_string, DIFF_STRING_SIZE, 0); } -esp_err_t SYSTEM_init_peripherals(GlobalState * GLOBAL_STATE) { +esp_err_t SYSTEM_init_peripherals() { ESP_RETURN_ON_ERROR(gpio_install_isr_service(0), TAG, "Error installing ISR service"); // Initialize the core voltage regulator - ESP_RETURN_ON_ERROR(VCORE_init(GLOBAL_STATE), TAG, "VCORE init failed!"); - ESP_RETURN_ON_ERROR(VCORE_set_voltage(GLOBAL_STATE, nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0), TAG, "VCORE set voltage failed!"); + ESP_RETURN_ON_ERROR(VCORE_init(), TAG, "VCORE init failed!"); + ESP_RETURN_ON_ERROR(VCORE_set_voltage(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0), TAG, "VCORE set voltage failed!"); - ESP_RETURN_ON_ERROR(Thermal_init(&GLOBAL_STATE->DEVICE_CONFIG), TAG, "Thermal init failed!"); + ESP_RETURN_ON_ERROR(Thermal_init(DEVICE_CONFIG), TAG, "Thermal init failed!"); vTaskDelay(500 / portTICK_PERIOD_MS); // Ensure overheat_mode config exists ESP_RETURN_ON_ERROR(ensure_overheat_mode_config(), TAG, "Failed to ensure overheat_mode config"); - ESP_RETURN_ON_ERROR(display_init(GLOBAL_STATE), TAG, "Display init failed!"); + ESP_RETURN_ON_ERROR(display_init(), TAG, "Display init failed!"); ESP_RETURN_ON_ERROR(input_init(screen_next, toggle_wifi_softap), TAG, "Input init failed!"); - ESP_RETURN_ON_ERROR(screen_start(GLOBAL_STATE), TAG, "Screen start failed!"); + ESP_RETURN_ON_ERROR(screen_start(), TAG, "Screen start failed!"); return ESP_OK; } -void SYSTEM_notify_accepted_share(GlobalState * GLOBAL_STATE) +void SYSTEM_notify_accepted_share() { - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - module->shares_accepted++; + SYSTEM_MODULE.shares_accepted++; } static int compare_rejected_reason_stats(const void *a, const void *b) { @@ -131,124 +162,115 @@ static int compare_rejected_reason_stats(const void *a, const void *b) { return (eb->count > ea->count) - (ea->count > eb->count); } -void SYSTEM_notify_rejected_share(GlobalState * GLOBAL_STATE, char * error_msg) +void SYSTEM_notify_rejected_share(char * error_msg) { - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - module->shares_rejected++; + SYSTEM_MODULE.shares_rejected++; - for (int i = 0; i < module->rejected_reason_stats_count; i++) { - if (strncmp(module->rejected_reason_stats[i].message, error_msg, sizeof(module->rejected_reason_stats[i].message) - 1) == 0) { - module->rejected_reason_stats[i].count++; + for (int i = 0; i < SYSTEM_MODULE.rejected_reason_stats_count; i++) { + if (strncmp(SYSTEM_MODULE.rejected_reason_stats[i].message, error_msg, sizeof(SYSTEM_MODULE.rejected_reason_stats[i].message) - 1) == 0) { + SYSTEM_MODULE.rejected_reason_stats[i].count++; return; } } - if (module->rejected_reason_stats_count < sizeof(module->rejected_reason_stats)) { - strncpy(module->rejected_reason_stats[module->rejected_reason_stats_count].message, + if (SYSTEM_MODULE.rejected_reason_stats_count < sizeof(SYSTEM_MODULE.rejected_reason_stats)) { + strncpy(SYSTEM_MODULE.rejected_reason_stats[SYSTEM_MODULE.rejected_reason_stats_count].message, error_msg, - sizeof(module->rejected_reason_stats[module->rejected_reason_stats_count].message) - 1); - module->rejected_reason_stats[module->rejected_reason_stats_count].message[sizeof(module->rejected_reason_stats[module->rejected_reason_stats_count].message) - 1] = '\0'; // Ensure null termination - module->rejected_reason_stats[module->rejected_reason_stats_count].count = 1; - module->rejected_reason_stats_count++; + sizeof(SYSTEM_MODULE.rejected_reason_stats[SYSTEM_MODULE.rejected_reason_stats_count].message) - 1); + SYSTEM_MODULE.rejected_reason_stats[SYSTEM_MODULE.rejected_reason_stats_count].message[sizeof(SYSTEM_MODULE.rejected_reason_stats[SYSTEM_MODULE.rejected_reason_stats_count].message) - 1] = '\0'; // Ensure null termination + SYSTEM_MODULE.rejected_reason_stats[SYSTEM_MODULE.rejected_reason_stats_count].count = 1; + SYSTEM_MODULE.rejected_reason_stats_count++; } - if (module->rejected_reason_stats_count > 1) { - qsort(module->rejected_reason_stats, module->rejected_reason_stats_count, - sizeof(module->rejected_reason_stats[0]), compare_rejected_reason_stats); + if (SYSTEM_MODULE.rejected_reason_stats_count > 1) { + qsort(SYSTEM_MODULE.rejected_reason_stats, SYSTEM_MODULE.rejected_reason_stats_count, + sizeof(SYSTEM_MODULE.rejected_reason_stats[0]), compare_rejected_reason_stats); } } -void SYSTEM_notify_mining_started(GlobalState * GLOBAL_STATE) +void SYSTEM_notify_mining_started() { - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - module->duration_start = esp_timer_get_time(); + HASH_HISTORY.duration_start = esp_timer_get_time(); } -void SYSTEM_notify_new_ntime(GlobalState * GLOBAL_STATE, uint32_t ntime) +void SYSTEM_notify_new_ntime( uint32_t ntime) { - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - // Hourly clock sync - if (module->lastClockSync + (60 * 60) > ntime) { + if (lastClockSync + (60 * 60) > ntime) { return; } ESP_LOGI(TAG, "Syncing clock"); - module->lastClockSync = ntime; + lastClockSync = ntime; struct timeval tv; tv.tv_sec = ntime; tv.tv_usec = 0; settimeofday(&tv, NULL); } -void SYSTEM_notify_found_nonce(GlobalState * GLOBAL_STATE, double found_diff, uint8_t job_id) +void SYSTEM_notify_found_nonce(double found_diff, uint8_t job_id) { - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - // Calculate the time difference in seconds with sub-second precision // hashrate = (nonce_difficulty * 2^32) / time_to_find - module->historical_hashrate[module->historical_hashrate_rolling_index] = GLOBAL_STATE->DEVICE_CONFIG.family.asic.difficulty; - module->historical_hashrate_time_stamps[module->historical_hashrate_rolling_index] = esp_timer_get_time(); + HASH_HISTORY.historical_hashrate[HASH_HISTORY.historical_hashrate_rolling_index] = DEVICE_CONFIG.family.asic.difficulty; + HASH_HISTORY.historical_hashrate_time_stamps[HASH_HISTORY.historical_hashrate_rolling_index] = esp_timer_get_time(); - module->historical_hashrate_rolling_index = (module->historical_hashrate_rolling_index + 1) % HISTORY_LENGTH; + HASH_HISTORY.historical_hashrate_rolling_index = (HASH_HISTORY.historical_hashrate_rolling_index + 1) % HISTORY_LENGTH; // ESP_LOGI(TAG, "nonce_diff %.1f, ttf %.1f, res %.1f", nonce_diff, duration, // historical_hashrate[historical_hashrate_rolling_index]); - if (module->historical_hashrate_init < HISTORY_LENGTH) { - module->historical_hashrate_init++; + if (HASH_HISTORY.historical_hashrate_init < HISTORY_LENGTH) { + HASH_HISTORY.historical_hashrate_init++; } else { - module->duration_start = - module->historical_hashrate_time_stamps[(module->historical_hashrate_rolling_index + 1) % HISTORY_LENGTH]; + HASH_HISTORY.duration_start = + HASH_HISTORY.historical_hashrate_time_stamps[(HASH_HISTORY.historical_hashrate_rolling_index + 1) % HISTORY_LENGTH]; } double sum = 0; - for (int i = 0; i < module->historical_hashrate_init; i++) { - sum += module->historical_hashrate[i]; + for (int i = 0; i < HASH_HISTORY.historical_hashrate_init; i++) { + sum += HASH_HISTORY.historical_hashrate[i]; } - double duration = (double) (esp_timer_get_time() - module->duration_start) / 1000000; + double duration = (double) (esp_timer_get_time() - HASH_HISTORY.duration_start) / 1000000; double rolling_rate = (sum * 4294967296) / (duration * 1000000000); - if (module->historical_hashrate_init < HISTORY_LENGTH) { - module->current_hashrate = rolling_rate; + if (HASH_HISTORY.historical_hashrate_init < HISTORY_LENGTH) { + SYSTEM_MODULE.current_hashrate = rolling_rate; } else { // More smoothing - module->current_hashrate = ((module->current_hashrate * 9) + rolling_rate) / 10; + SYSTEM_MODULE.current_hashrate = ((SYSTEM_MODULE.current_hashrate * 9) + rolling_rate) / 10; } - + // logArrayContents(historical_hashrate, HISTORY_LENGTH); // logArrayContents(historical_hashrate_time_stamps, HISTORY_LENGTH); - _check_for_best_diff(GLOBAL_STATE, found_diff, job_id); + _check_for_best_diff(found_diff, job_id); } -static void _check_for_best_diff(GlobalState * GLOBAL_STATE, double diff, uint8_t job_id) +static void _check_for_best_diff( double diff, uint8_t job_id) { - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - if ((uint64_t) diff > module->best_session_nonce_diff) { - module->best_session_nonce_diff = (uint64_t) diff; - suffixString((uint64_t) diff, module->best_session_diff_string, DIFF_STRING_SIZE, 0); + if ((uint64_t) diff > SYSTEM_MODULE.best_session_nonce_diff) { + SYSTEM_MODULE.best_session_nonce_diff = (uint64_t) diff; + suffixString((uint64_t) diff, SYSTEM_MODULE.best_session_diff_string, DIFF_STRING_SIZE, 0); } - double network_diff = networkDifficulty(GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->target); + double network_diff = networkDifficulty(ASIC_TASK_MODULE.active_jobs[job_id]->target); if (diff > network_diff) { - module->FOUND_BLOCK = true; + STATE_MODULE.FOUND_BLOCK = true; ESP_LOGI(TAG, "FOUND BLOCK!!!!!!!!!!!!!!!!!!!!!! %f > %f", diff, network_diff); } - if ((uint64_t) diff <= module->best_nonce_diff) { + if ((uint64_t) diff <= best_nonce_diff) { return; } - module->best_nonce_diff = (uint64_t) diff; + best_nonce_diff = (uint64_t) diff; - nvs_config_set_u64(NVS_CONFIG_BEST_DIFF, module->best_nonce_diff); + nvs_config_set_u64(NVS_CONFIG_BEST_DIFF, best_nonce_diff); // make the best_nonce_diff into a string - suffixString((uint64_t) diff, module->best_diff_string, DIFF_STRING_SIZE, 0); + suffixString((uint64_t) diff, SYSTEM_MODULE.best_diff_string, DIFF_STRING_SIZE, 0); ESP_LOGI(TAG, "Network diff: %f", network_diff); } diff --git a/main/system.h b/main/system.h index ae0752e0e..5273554af 100644 --- a/main/system.h +++ b/main/system.h @@ -2,8 +2,11 @@ #define SYSTEM_H_ #include "esp_err.h" -#include "global_state.h" + + +void SYSTEM_init_system(); +esp_err_t SYSTEM_init_peripherals(); #ifdef CONFIG_STRATUM_EXTRANONCE_SUBSCRIBE #define STRATUM_EXTRANONCE_SUBSCRIBE 1 #else @@ -16,13 +19,11 @@ #define FALLBACK_STRATUM_EXTRANONCE_SUBSCRIBE 0 #endif -void SYSTEM_init_system(GlobalState * GLOBAL_STATE); -esp_err_t SYSTEM_init_peripherals(GlobalState * GLOBAL_STATE); -void SYSTEM_notify_accepted_share(GlobalState * GLOBAL_STATE); -void SYSTEM_notify_rejected_share(GlobalState * GLOBAL_STATE, char * error_msg); -void SYSTEM_notify_found_nonce(GlobalState * GLOBAL_STATE, double found_diff, uint8_t job_id); -void SYSTEM_notify_mining_started(GlobalState * GLOBAL_STATE); -void SYSTEM_notify_new_ntime(GlobalState * GLOBAL_STATE, uint32_t ntime); +void SYSTEM_notify_accepted_share(); +void SYSTEM_notify_rejected_share(char * error_msg); +void SYSTEM_notify_found_nonce( double found_diff, uint8_t job_id); +void SYSTEM_notify_mining_started(); +void SYSTEM_notify_new_ntime( uint32_t ntime); #endif /* SYSTEM_H_ */ diff --git a/main/system_module.h b/main/system_module.h new file mode 100644 index 000000000..b2a034ed0 --- /dev/null +++ b/main/system_module.h @@ -0,0 +1,69 @@ +#ifndef SYSTEM_MODULE_H_ +#define SYSTEM_MODULE_H_ + +#include +#include + +#define STRATUM_USER CONFIG_STRATUM_USER +#define FALLBACK_STRATUM_USER CONFIG_FALLBACK_STRATUM_USER + +#define HISTORY_LENGTH 100 +#define DIFF_STRING_SIZE 10 + +typedef struct +{ + char message[64]; + uint32_t count; +} RejectedReasonStat; + + + +typedef struct +{ + + + // The current calculated hashrate of the system at this moment. + double current_hashrate; + + // The average hashrate over a defined period of time. + double avg_hashrate; + + // The hashrate without accounting for errors or invalid data points. + double hashrate_no_error; + + // The hashrate accounting for errors or invalid data points. + double hashrate_error; + // The starting timestamp of the mining session. + int64_t start_time; + + // A count of shares that have been accepted by the pool. + uint64_t shares_accepted; + + // A count of shares that have been rejected by the pool. + uint64_t shares_rejected; + + // An array to store statistics about reasons for share rejections. + RejectedReasonStat rejected_reason_stats[10]; + + // The number of different rejection reason statistics recorded. + int rejected_reason_stats_count; + + // A string representing the difficulty of the best nonce in readable format. + char best_diff_string[DIFF_STRING_SIZE]; + + // The difficulty (nonce) for the best solution found in this session. + uint64_t best_session_nonce_diff; + + // A string representing the difficulty of the best session nonce in readable format. + char best_session_diff_string[DIFF_STRING_SIZE]; + uint64_t work_received; + int block_height; + char * scriptsig; + char network_diff_string[DIFF_STRING_SIZE]; + +} SystemModule; + +extern SystemModule SYSTEM_MODULE; + + +#endif \ No newline at end of file diff --git a/main/tasks/asic_result_task.c b/main/tasks/asic_result_task.c index a95cb3d8c..5fee07a5c 100644 --- a/main/tasks/asic_result_task.c +++ b/main/tasks/asic_result_task.c @@ -2,24 +2,23 @@ #include "system.h" #include "work_queue.h" -#include "serial.h" #include #include "esp_log.h" -#include "nvs_config.h" #include "utils.h" #include "stratum_task.h" #include "asic.h" +#include "asic_task_module.h" +#include "pool_module.h" static const char *TAG = "asic_result"; void ASIC_result_task(void *pvParameters) { - GlobalState *GLOBAL_STATE = (GlobalState *)pvParameters; while (1) { - //task_result *asic_result = (*GLOBAL_STATE->ASIC_functions.receive_result_fn)(GLOBAL_STATE); - task_result *asic_result = ASIC_process_work(GLOBAL_STATE); + //task_result *asic_result = (*GLOBAL_STATE.ASIC_functions.receive_result_fn)(GLOBAL_STATE); + task_result *asic_result = ASIC_process_work(); if (asic_result == NULL) { @@ -28,13 +27,13 @@ void ASIC_result_task(void *pvParameters) uint8_t job_id = asic_result->job_id; - if (GLOBAL_STATE->valid_jobs[job_id] == 0) + if (ASIC_TASK_MODULE.valid_jobs[job_id] == 0) { ESP_LOGW(TAG, "Invalid job nonce found, 0x%02X", job_id); continue; } - bm_job *active_job = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]; + bm_job *active_job = ASIC_TASK_MODULE.active_jobs[job_id]; // check the nonce difficulty double nonce_diff = test_nonce_value(active_job, asic_result->nonce, asic_result->rolled_version); @@ -43,23 +42,13 @@ void ASIC_result_task(void *pvParameters) if (nonce_diff >= active_job->pool_diff) { - char * user = GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback ? GLOBAL_STATE->SYSTEM_MODULE.fallback_pool_user : GLOBAL_STATE->SYSTEM_MODULE.pool_user; - int ret = STRATUM_V1_submit_share( - GLOBAL_STATE->sock, - GLOBAL_STATE->send_uid++, - user, - active_job->jobid, + stratum_submit_share(active_job->jobid, active_job->extranonce2, active_job->ntime, asic_result->nonce, asic_result->rolled_version ^ active_job->version); - - if (ret < 0) { - ESP_LOGI(TAG, "Unable to write share to socket. Closing connection. Ret: %d (errno %d: %s)", ret, errno, strerror(errno)); - stratum_close_connection(GLOBAL_STATE); - } } - SYSTEM_notify_found_nonce(GLOBAL_STATE, nonce_diff, job_id); + SYSTEM_notify_found_nonce(nonce_diff, job_id); } } diff --git a/main/tasks/asic_task.c b/main/tasks/asic_task.c index 07dcde0fd..6de294ec7 100644 --- a/main/tasks/asic_task.c +++ b/main/tasks/asic_task.c @@ -6,44 +6,62 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" - +#include "asic_task.h" #include "asic.h" +#include "power_management_module.h" +#include "mining_module.h" +#include "device_config.h" +#include "asic_task_module.h" static const char *TAG = "asic_task"; // static bm_job ** active_jobs; is required to keep track of the active jobs since the +const double NONCE_SPACE = 4294967296.0; // 2^32 + +double ASIC_get_asic_job_frequency_ms(float frequency) +{ + switch (DEVICE_CONFIG.family.asic.id) { + case BM1397: + // no version-rolling so same Nonce Space is splitted between Small Cores + return (NONCE_SPACE / (double) (frequency * DEVICE_CONFIG.family.asic.small_core_count * 1000)) / (double) DEVICE_CONFIG.family.asic_count; + case BM1366: + return 2000; + default: + return 500; + } +} void ASIC_task(void *pvParameters) { - GlobalState *GLOBAL_STATE = (GlobalState *)pvParameters; + //initialize the semaphore - GLOBAL_STATE->ASIC_TASK_MODULE.semaphore = xSemaphoreCreateBinary(); + ASIC_TASK_MODULE.semaphore = xSemaphoreCreateBinary(); - GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128); - GLOBAL_STATE->valid_jobs = malloc(sizeof(uint8_t) * 128); + ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128); + ASIC_TASK_MODULE.valid_jobs = malloc(sizeof(uint8_t) * 128); for (int i = 0; i < 128; i++) { - GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[i] = NULL; - GLOBAL_STATE->valid_jobs[i] = 0; + ASIC_TASK_MODULE.active_jobs[i] = NULL; + ASIC_TASK_MODULE.valid_jobs[i] = 0; } - double asic_job_frequency_ms = ASIC_get_asic_job_frequency_ms(GLOBAL_STATE); + double asic_job_frequency_ms = ASIC_get_asic_job_frequency_ms(POWER_MANAGEMENT_MODULE.frequency_value); ESP_LOGI(TAG, "ASIC Job Interval: %.2f ms", asic_job_frequency_ms); - SYSTEM_notify_mining_started(GLOBAL_STATE); + SYSTEM_notify_mining_started(); ESP_LOGI(TAG, "ASIC Ready!"); while (1) { - bm_job *next_bm_job = (bm_job *)queue_dequeue(&GLOBAL_STATE->ASIC_jobs_queue); + bm_job *next_bm_job = (bm_job *)queue_dequeue(&MINING_MODULE.ASIC_jobs_queue); - //(*GLOBAL_STATE->ASIC_functions.send_work_fn)(GLOBAL_STATE, next_bm_job); // send the job to the ASIC - ASIC_send_work(GLOBAL_STATE, next_bm_job); + //(*GLOBAL_STATE.ASIC_functions.send_work_fn)(next_bm_job); // send the job to the ASIC + ASIC_send_work(next_bm_job); // Time to execute the above code is ~0.3ms // Delay for ASIC(s) to finish the job //vTaskDelay((asic_job_frequency_ms - 0.3) / portTICK_PERIOD_MS); - xSemaphoreTake(GLOBAL_STATE->ASIC_TASK_MODULE.semaphore, asic_job_frequency_ms / portTICK_PERIOD_MS); + xSemaphoreTake(ASIC_TASK_MODULE.semaphore, asic_job_frequency_ms / portTICK_PERIOD_MS); } } diff --git a/main/tasks/asic_task.h b/main/tasks/asic_task.h index a39144385..af90f8039 100644 --- a/main/tasks/asic_task.h +++ b/main/tasks/asic_task.h @@ -1,19 +1,10 @@ #ifndef ASIC_TASK_H_ #define ASIC_TASK_H_ -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.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; - //semaphone - SemaphoreHandle_t semaphore; -} AsicTaskModule; + void ASIC_task(void *pvParameters); + + #endif /* ASIC_TASK_H_ */ diff --git a/main/tasks/create_jobs_task.c b/main/tasks/create_jobs_task.c index 757f88551..3612dec52 100644 --- a/main/tasks/create_jobs_task.c +++ b/main/tasks/create_jobs_task.c @@ -1,30 +1,31 @@ -#include #include +#include -#include "work_queue.h" -#include "global_state.h" #include "esp_log.h" #include "esp_system.h" + #include "mining.h" #include "string.h" - +#include "work_queue.h" +#include "freertos/FreeRTOS.h" +#include "asic_task_module.h" #include "asic.h" +#include "mining_module.h" +#include "pool_module.h" -static const char *TAG = "create_jobs_task"; +static const char * TAG = "create_jobs_task"; #define QUEUE_LOW_WATER_MARK 10 // Adjust based on your requirements -static bool should_generate_more_work(GlobalState *GLOBAL_STATE); -static void generate_work(GlobalState *GLOBAL_STATE, mining_notify *notification, uint64_t extranonce_2, uint32_t difficulty); +static bool should_generate_more_work(); +static void generate_work(mining_notify *notification, uint64_t extranonce_2, uint32_t difficulty); -void create_jobs_task(void *pvParameters) +void create_jobs_task(void * pvParameters) { - GlobalState *GLOBAL_STATE = (GlobalState *)pvParameters; - uint32_t difficulty = GLOBAL_STATE->pool_difficulty; - while (1) - { - mining_notify *mining_notification = (mining_notify *)queue_dequeue(&GLOBAL_STATE->stratum_queue); + uint32_t difficulty = POOL_MODULE.pool_difficulty; + while (1) { + mining_notify * mining_notification = (mining_notify *) queue_dequeue(&MINING_MODULE.stratum_queue); if (mining_notification == NULL) { ESP_LOGE(TAG, "Failed to dequeue mining notification"); vTaskDelay(100 / portTICK_PERIOD_MS); // Wait a bit before trying again @@ -33,25 +34,21 @@ void create_jobs_task(void *pvParameters) ESP_LOGI(TAG, "New Work Dequeued %s", mining_notification->job_id); - if (GLOBAL_STATE->new_set_mining_difficulty_msg) - { - ESP_LOGI(TAG, "New pool difficulty %lu", GLOBAL_STATE->pool_difficulty); - difficulty = GLOBAL_STATE->pool_difficulty; - GLOBAL_STATE->new_set_mining_difficulty_msg = false; + if (MINING_MODULE.new_set_mining_difficulty_msg) { + ESP_LOGI(TAG, "New pool difficulty %i", POOL_MODULE.pool_difficulty); + difficulty = POOL_MODULE.pool_difficulty; } - if (GLOBAL_STATE->new_stratum_version_rolling_msg) { - ESP_LOGI(TAG, "Set chip version rolls %i", (int)(GLOBAL_STATE->version_mask >> 13)); - ASIC_set_version_mask(GLOBAL_STATE, GLOBAL_STATE->version_mask); - GLOBAL_STATE->new_stratum_version_rolling_msg = false; + if (MINING_MODULE.new_stratum_version_rolling_msg) { + ESP_LOGI(TAG, "Set chip version rolls %i", (int)(MINING_MODULE.version_mask >> 13)); + ASIC_set_version_mask(MINING_MODULE.version_mask); + MINING_MODULE.new_stratum_version_rolling_msg = false; } uint64_t extranonce_2 = 0; - while (GLOBAL_STATE->stratum_queue.count < 1 && GLOBAL_STATE->abandon_work == 0) - { - if (should_generate_more_work(GLOBAL_STATE)) - { - generate_work(GLOBAL_STATE, mining_notification, extranonce_2, difficulty); + while (MINING_MODULE.stratum_queue.count < 1 && MINING_MODULE.abandon_work == 0) { + if (should_generate_more_work()) { + generate_work(mining_notification, extranonce_2, difficulty); // Increase extranonce_2 for the next job. extranonce_2++; @@ -63,25 +60,24 @@ void create_jobs_task(void *pvParameters) } } - if (GLOBAL_STATE->abandon_work == 1) - { - GLOBAL_STATE->abandon_work = 0; - ASIC_jobs_queue_clear(&GLOBAL_STATE->ASIC_jobs_queue); - xSemaphoreGive(GLOBAL_STATE->ASIC_TASK_MODULE.semaphore); + if (MINING_MODULE.abandon_work == 1) { + MINING_MODULE.abandon_work = 0; + ASIC_jobs_queue_clear(&MINING_MODULE.ASIC_jobs_queue); + xSemaphoreGive(ASIC_TASK_MODULE.semaphore); } STRATUM_V1_free_mining_notify(mining_notification); } } -static bool should_generate_more_work(GlobalState *GLOBAL_STATE) +static bool should_generate_more_work() { - return GLOBAL_STATE->ASIC_jobs_queue.count < QUEUE_LOW_WATER_MARK; + return MINING_MODULE.ASIC_jobs_queue.count < QUEUE_LOW_WATER_MARK; } -static void generate_work(GlobalState *GLOBAL_STATE, mining_notify *notification, uint64_t extranonce_2, uint32_t difficulty) +static void generate_work(mining_notify *notification, uint64_t extranonce_2, uint32_t difficulty) { - char *extranonce_2_str = extranonce_2_generate(extranonce_2, GLOBAL_STATE->extranonce_2_len); + char * extranonce_2_str = extranonce_2_generate(extranonce_2, MINING_MODULE.extranonce_2_len); if (extranonce_2_str == NULL) { ESP_LOGE(TAG, "Failed to generate extranonce_2"); return; @@ -89,7 +85,8 @@ static void generate_work(GlobalState *GLOBAL_STATE, mining_notify *notification //print generated extranonce_2 //ESP_LOGI(TAG, "Generated extranonce_2: %s", extranonce_2_str); - char *coinbase_tx = construct_coinbase_tx(notification->coinbase_1, notification->coinbase_2, GLOBAL_STATE->extranonce_str, extranonce_2_str); + char * coinbase_tx = + construct_coinbase_tx(notification->coinbase_1, notification->coinbase_2, MINING_MODULE.extranonce_str, extranonce_2_str); if (coinbase_tx == NULL) { ESP_LOGE(TAG, "Failed to construct coinbase_tx"); free(extranonce_2_str); @@ -104,9 +101,9 @@ static void generate_work(GlobalState *GLOBAL_STATE, mining_notify *notification return; } - bm_job next_job = construct_bm_job(notification, merkle_root, GLOBAL_STATE->version_mask, difficulty); + bm_job next_job = construct_bm_job(notification, merkle_root, MINING_MODULE.version_mask, difficulty); - bm_job *queued_next_job = malloc(sizeof(bm_job)); + bm_job * queued_next_job = malloc(sizeof(bm_job)); if (queued_next_job == NULL) { ESP_LOGE(TAG, "Failed to allocate memory for queued_next_job"); free(extranonce_2_str); @@ -118,9 +115,9 @@ static void generate_work(GlobalState *GLOBAL_STATE, mining_notify *notification memcpy(queued_next_job, &next_job, sizeof(bm_job)); queued_next_job->extranonce2 = extranonce_2_str; // Transfer ownership queued_next_job->jobid = strdup(notification->job_id); - queued_next_job->version_mask = GLOBAL_STATE->version_mask; + queued_next_job->version_mask = MINING_MODULE.version_mask; - queue_enqueue(&GLOBAL_STATE->ASIC_jobs_queue, queued_next_job); + queue_enqueue(&MINING_MODULE.ASIC_jobs_queue, queued_next_job); free(coinbase_tx); free(merkle_root); diff --git a/main/tasks/power_management_task.c b/main/tasks/power_management_task.c index 6b9664760..07e5b9542 100644 --- a/main/tasks/power_management_task.c +++ b/main/tasks/power_management_task.c @@ -3,7 +3,6 @@ #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "global_state.h" #include "math.h" #include "mining.h" #include "nvs_config.h" @@ -14,6 +13,10 @@ #include "PID.h" #include "power.h" #include "asic.h" +#include "power_management_module.h" +#include "state_module.h" +#include "wifi_module.h" +#include "device_config.h" #define POLL_RATE 1800 #define MAX_TEMP 90.0 @@ -47,7 +50,7 @@ int pid_startup_counter = 0; PIDController pid; -void POWER_MANAGEMENT_init_frequency(PowerManagementModule * power_management) +void POWER_MANAGEMENT_init_frequency() { float frequency = nvs_config_get_float(NVS_CONFIG_ASIC_FREQUENCY_FLOAT, -1); if (frequency < 0) { // fallback if the float value is not yet set @@ -58,21 +61,16 @@ void POWER_MANAGEMENT_init_frequency(PowerManagementModule * power_management) ESP_LOGI(TAG, "ASIC Frequency: %g MHz", frequency); - power_management->frequency_value = frequency; + POWER_MANAGEMENT_MODULE.frequency_value = frequency; } void POWER_MANAGEMENT_task(void * pvParameters) { ESP_LOGI(TAG, "Starting"); - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - - PowerManagementModule * power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE; - SystemModule * sys_module = &GLOBAL_STATE->SYSTEM_MODULE; - - POWER_MANAGEMENT_init_frequency(power_management); + POWER_MANAGEMENT_init_frequency(); - float last_asic_frequency = power_management->frequency_value; + float last_asic_frequency = POWER_MANAGEMENT_MODULE.frequency_value; pid_setPoint = (double)nvs_config_get_u16(NVS_CONFIG_TEMP_TARGET, pid_setPoint); min_fan_pct = (double)nvs_config_get_u16(NVS_CONFIG_MIN_FAN_SPEED, min_fan_pct); @@ -91,36 +89,34 @@ void POWER_MANAGEMENT_task(void * pvParameters) // Refresh PID setpoint from NVS in case it was changed via API pid_setPoint = (double)nvs_config_get_u16(NVS_CONFIG_TEMP_TARGET, pid_setPoint); - power_management->voltage = Power_get_input_voltage(GLOBAL_STATE); - power_management->power = Power_get_power(GLOBAL_STATE); + POWER_MANAGEMENT_MODULE.voltage = Power_get_input_voltage(); + POWER_MANAGEMENT_MODULE.power = Power_get_power(); - power_management->fan_rpm = Thermal_get_fan_speed(&GLOBAL_STATE->DEVICE_CONFIG); - power_management->chip_temp_avg = Thermal_get_chip_temp(GLOBAL_STATE); - power_management->chip_temp2_avg = Thermal_get_chip_temp2(GLOBAL_STATE); + POWER_MANAGEMENT_MODULE.fan_rpm = Thermal_get_fan_speed(); + POWER_MANAGEMENT_MODULE.chip_temp_avg = Thermal_get_chip_temp(); + POWER_MANAGEMENT_MODULE.chip_temp2_avg = Thermal_get_chip_temp2(); + POWER_MANAGEMENT_MODULE.vr_temp = Power_get_vreg_temp(); - power_management->vr_temp = Power_get_vreg_temp(GLOBAL_STATE); // ASIC Thermal Diode will give bad readings if the ASIC is turned off - // if(power_management->voltage < tps546_config.TPS546_INIT_VOUT_MIN){ + // if(POWER_MANAGEMENT_MODULE.voltage < tps546_config.TPS546_INIT_VOUT_MIN){ // goto looper; // } //overheat mode if the voltage regulator or ASIC is too hot bool asic_overheat = - power_management->chip_temp_avg > THROTTLE_TEMP - || power_management->chip_temp2_avg > THROTTLE_TEMP; + POWER_MANAGEMENT_MODULE.chip_temp_avg > THROTTLE_TEMP + || POWER_MANAGEMENT_MODULE.chip_temp2_avg > THROTTLE_TEMP; - if ((power_management->vr_temp > TPS546_THROTTLE_TEMP || asic_overheat) && (power_management->frequency_value > 50 || power_management->voltage > 1000)) { - if (power_management->chip_temp2_avg > 0) { - ESP_LOGE(TAG, "OVERHEAT! VR: %fC ASIC1: %fC ASIC2: %fC", power_management->vr_temp, power_management->chip_temp_avg, power_management->chip_temp2_avg); + if ((POWER_MANAGEMENT_MODULE.vr_temp > TPS546_THROTTLE_TEMP || asic_overheat) && (POWER_MANAGEMENT_MODULE.frequency_value > 50 || POWER_MANAGEMENT_MODULE.voltage > 1000)) { + if (POWER_MANAGEMENT_MODULE.chip_temp2_avg > 0) { + ESP_LOGE(TAG, "OVERHEAT! VR: %fC ASIC1: %fC ASIC2: %fC", POWER_MANAGEMENT_MODULE.vr_temp, POWER_MANAGEMENT_MODULE.chip_temp_avg, POWER_MANAGEMENT_MODULE.chip_temp2_avg); } else { - ESP_LOGE(TAG, "OVERHEAT! VR: %fC ASIC: %fC", power_management->vr_temp, power_management->chip_temp_avg); + ESP_LOGE(TAG, "OVERHEAT! VR: %fC ASIC: %fC", POWER_MANAGEMENT_MODULE.vr_temp, POWER_MANAGEMENT_MODULE.chip_temp_avg); } - power_management->fan_perc = 100; - Thermal_set_fan_percent(&GLOBAL_STATE->DEVICE_CONFIG, 1); // Turn off core voltage - VCORE_set_voltage(GLOBAL_STATE, 0.0f); + VCORE_set_voltage(0.0f); nvs_config_set_u16(NVS_CONFIG_ASIC_VOLTAGE, 1000); nvs_config_set_u16(NVS_CONFIG_ASIC_FREQUENCY, 50); @@ -133,11 +129,11 @@ void POWER_MANAGEMENT_task(void * pvParameters) //enable the PID auto control for the FAN if set if (nvs_config_get_u16(NVS_CONFIG_AUTO_FAN_SPEED, 1) == 1) { - if (power_management->chip_temp_avg >= 0) { // Ignore invalid temperature readings (-1) - if (power_management->chip_temp2_avg > 0) { - pid_input = (power_management->chip_temp_avg + power_management->chip_temp2_avg) / 2.0; // TODO: Or max of both? + if (POWER_MANAGEMENT_MODULE.chip_temp_avg >= 0) { // Ignore invalid temperature readings (-1) + if (POWER_MANAGEMENT_MODULE.chip_temp2_avg > 0) { + pid_input = (POWER_MANAGEMENT_MODULE.chip_temp_avg + POWER_MANAGEMENT_MODULE.chip_temp2_avg) / 2.0; // TODO: Or max of both? } else { - pid_input = power_management->chip_temp_avg; + pid_input = POWER_MANAGEMENT_MODULE.chip_temp_avg; } // Hold and Ramp logic for startup D value @@ -171,23 +167,23 @@ void POWER_MANAGEMENT_task(void * pvParameters) // Uncomment for debugging PID output directly after compute // ESP_LOGD(TAG, "DEBUG: PID raw output: %.2f%%, Input: %.1f, SetPoint: %.1f", pid_output, pid_input, pid_setPoint); - power_management->fan_perc = (uint16_t) pid_output; - Thermal_set_fan_percent(&GLOBAL_STATE->DEVICE_CONFIG, pid_output / 100.0); + POWER_MANAGEMENT_MODULE.fan_perc = (uint16_t) pid_output; + Thermal_set_fan_percent(pid_output / 100.0); ESP_LOGI(TAG, "Temp: %.1f °C, SetPoint: %.1f °C, Output: %.1f%% (P:%.1f I:%.1f D_val:%.1f D_start_val:%.1f)", pid_input, pid_setPoint, pid_output, pid.dispKp, pid.dispKi, pid.dispKd, pid_d_startup); // Log current effective Kp, Ki, Kd } else { - if (GLOBAL_STATE->SYSTEM_MODULE.ap_enabled) { - ESP_LOGW(TAG, "AP mode with invalid temperature reading: %.1f °C - Setting fan to 70%%", power_management->chip_temp_avg); - power_management->fan_perc = 70; - Thermal_set_fan_percent(&GLOBAL_STATE->DEVICE_CONFIG, 0.7); + if (WIFI_MODULE.ap_enabled) { + ESP_LOGW(TAG, "AP mode with invalid temperature reading: %.1f °C - Setting fan to 70%%", POWER_MANAGEMENT_MODULE.chip_temp_avg); + POWER_MANAGEMENT_MODULE.fan_perc = 70; + Thermal_set_fan_percent(0.7); } else { - ESP_LOGW(TAG, "Ignoring invalid temperature reading: %.1f °C", power_management->chip_temp_avg); + ESP_LOGW(TAG, "Ignoring invalid temperature reading: %.1f °C", POWER_MANAGEMENT_MODULE.chip_temp_avg); } } } else { // Manual fan speed float fs = (float) nvs_config_get_u16(NVS_CONFIG_FAN_SPEED, 100); - power_management->fan_perc = fs; - Thermal_set_fan_percent(&GLOBAL_STATE->DEVICE_CONFIG, (float) fs / 100.0); + POWER_MANAGEMENT_MODULE.fan_perc = fs; + Thermal_set_fan_percent((float) fs / 100.0); } uint16_t core_voltage = nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE); @@ -195,17 +191,17 @@ void POWER_MANAGEMENT_task(void * pvParameters) if (core_voltage != last_core_voltage) { ESP_LOGI(TAG, "setting new vcore voltage to %umV", core_voltage); - VCORE_set_voltage(GLOBAL_STATE, (double) core_voltage / 1000.0); + VCORE_set_voltage((double) core_voltage / 1000.0); last_core_voltage = core_voltage; } if (asic_frequency != last_asic_frequency) { ESP_LOGI(TAG, "New ASIC frequency requested: %g MHz (current: %g MHz)", asic_frequency, last_asic_frequency); - bool success = ASIC_set_frequency(GLOBAL_STATE, asic_frequency); + bool success = ASIC_set_frequency((float)asic_frequency); if (success) { - power_management->frequency_value = asic_frequency; + POWER_MANAGEMENT_MODULE.frequency_value = (float)asic_frequency; } last_asic_frequency = asic_frequency; @@ -214,12 +210,12 @@ void POWER_MANAGEMENT_task(void * pvParameters) // Check for changing of overheat mode uint16_t new_overheat_mode = nvs_config_get_u16(NVS_CONFIG_OVERHEAT_MODE, 0); - if (new_overheat_mode != sys_module->overheat_mode) { - sys_module->overheat_mode = new_overheat_mode; - ESP_LOGI(TAG, "Overheat mode updated to: %d", sys_module->overheat_mode); + if (new_overheat_mode != STATE_MODULE.overheat_mode) { + STATE_MODULE.overheat_mode = new_overheat_mode; + ESP_LOGI(TAG, "Overheat mode updated to: %d", STATE_MODULE.overheat_mode); } - VCORE_check_fault(GLOBAL_STATE); + VCORE_check_fault(); // looper: vTaskDelay(POLL_RATE / portTICK_PERIOD_MS); diff --git a/main/tasks/power_management_task.h b/main/tasks/power_management_task.h index 3344c6609..8a6179a57 100644 --- a/main/tasks/power_management_task.h +++ b/main/tasks/power_management_task.h @@ -1,22 +1,12 @@ #ifndef POWER_MANAGEMENT_TASK_H_ #define POWER_MANAGEMENT_TASK_H_ -typedef struct -{ - uint16_t fan_perc; - uint16_t fan_rpm; - float chip_temp[6]; - float chip_temp_avg; - float chip_temp2_avg; - float vr_temp; - float voltage; - float frequency_value; - float power; - float current; -} PowerManagementModule; +#define POLL_RATE 500 -void POWER_MANAGEMENT_init_frequency(PowerManagementModule * power_management); +void POWER_MANAGEMENT_init_frequency(); void POWER_MANAGEMENT_task(void * pvParameters); + + #endif diff --git a/main/tasks/statistics_task.c b/main/tasks/statistics_task.c index 14cae9300..316967f06 100644 --- a/main/tasks/statistics_task.c +++ b/main/tasks/statistics_task.c @@ -5,11 +5,13 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "statistics_task.h" -#include "global_state.h" + #include "nvs_config.h" #include "power.h" #include "connect.h" #include "vcore.h" +#include "power_management_module.h" +#include "system_module.h" #define DEFAULT_POLL_RATE 5000 @@ -103,21 +105,16 @@ void clearStatisticData() } } -void statistics_init(void * pvParameters) +void statistics_init() { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - GLOBAL_STATE->STATISTICS_MODULE.statisticsList = &statisticsDataStart; + STATISTICS_MODULE.statisticsList = &statisticsDataStart; } void statistics_task(void * pvParameters) { ESP_LOGI(TAG, "Starting"); - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - SystemModule * sys_module = &GLOBAL_STATE->SYSTEM_MODULE; - PowerManagementModule * power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE; struct StatisticsData statsData = {}; - TickType_t taskWakeTime = xTaskGetTickCount(); while (1) { @@ -132,17 +129,18 @@ void statistics_task(void * pvParameters) get_wifi_current_rssi(&wifiRSSI); statsData.timestamp = currentTime; - statsData.hashrate = sys_module->current_hashrate; - statsData.chipTemperature = power_management->chip_temp_avg; - statsData.vrTemperature = power_management->vr_temp; - statsData.power = power_management->power; - statsData.voltage = power_management->voltage; - statsData.current = Power_get_current(GLOBAL_STATE); - statsData.coreVoltageActual = VCORE_get_voltage_mv(GLOBAL_STATE); - statsData.fanSpeed = power_management->fan_perc; - statsData.fanRPM = power_management->fan_rpm; + statsData.hashrate = SYSTEM_MODULE.current_hashrate; + statsData.chipTemperature = POWER_MANAGEMENT_MODULE.chip_temp_avg; + statsData.vrTemperature = POWER_MANAGEMENT_MODULE.vr_temp; + statsData.power = POWER_MANAGEMENT_MODULE.power; + statsData.voltage = POWER_MANAGEMENT_MODULE.voltage; + statsData.current = Power_get_current(); + statsData.coreVoltageActual = VCORE_get_voltage_mv(); + statsData.fanSpeed = POWER_MANAGEMENT_MODULE.fan_perc; + statsData.fanRPM = POWER_MANAGEMENT_MODULE.fan_rpm; statsData.wifiRSSI = wifiRSSI; statsData.freeHeap = esp_get_free_heap_size(); + statsData.frequency = POWER_MANAGEMENT_MODULE.frequency_value; addStatisticData(&statsData); } diff --git a/main/tasks/statistics_task.h b/main/tasks/statistics_task.h index b3dc144d2..fdd33fbc6 100644 --- a/main/tasks/statistics_task.h +++ b/main/tasks/statistics_task.h @@ -12,8 +12,10 @@ struct StatisticsData float vrTemperature; float power; float voltage; + uint16_t frequency; float current; int16_t coreVoltageActual; + int16_t coreVoltage; uint16_t fanSpeed; uint16_t fanRPM; int8_t wifiRSSI; @@ -31,7 +33,7 @@ StatisticsNodePtr addStatisticData(StatisticsNodePtr data); StatisticsNextNodePtr statisticData(StatisticsNodePtr nodeIn, StatisticsNodePtr dataOut); void clearStatisticData(); -void statistics_init(void * pvParameters); +void statistics_init(); void statistics_task(void * pvParameters); - +extern StatisticsModule STATISTICS_MODULE; #endif // STATISTICS_TASK_H_ diff --git a/main/tasks/stratum_task.c b/main/tasks/stratum_task.c index 9c4c17495..832237b5b 100644 --- a/main/tasks/stratum_task.c +++ b/main/tasks/stratum_task.c @@ -1,7 +1,7 @@ #include "esp_log.h" #include "connect.h" #include "system.h" -#include "global_state.h" + #include "lwip/dns.h" #include #include "nvs_config.h" @@ -14,6 +14,11 @@ #include "esp_timer.h" #include #include "utils.h" +#include "asic_task_module.h" +#include "system_module.h" +#include "mining_module.h" +#include "device_config.h" +#include "pool_module.h" #define MAX_RETRY_ATTEMPTS 3 #define MAX_CRITICAL_RETRY_ATTEMPTS 5 @@ -28,6 +33,13 @@ static StratumApiV1Message stratum_api_v1_message = {}; static const char * primary_stratum_url; static uint16_t primary_stratum_port; + //maybe need a stratum module +int sock; + +// A message ID that must be unique per request that expects a response. +// For requests not expecting a response (called notifications), this is null. +int send_uid; + struct timeval tcp_snd_timeout = { .tv_sec = 5, .tv_usec = 0 @@ -47,43 +59,62 @@ bool is_wifi_connected() { } } -void cleanQueue(GlobalState * GLOBAL_STATE) { +void cleanQueue() { ESP_LOGI(TAG, "Clean Jobs: clearing queue"); - GLOBAL_STATE->abandon_work = 1; - queue_clear(&GLOBAL_STATE->stratum_queue); + MINING_MODULE.abandon_work = 1; + queue_clear(&MINING_MODULE.stratum_queue); - pthread_mutex_lock(&GLOBAL_STATE->valid_jobs_lock); - ASIC_jobs_queue_clear(&GLOBAL_STATE->ASIC_jobs_queue); + pthread_mutex_lock(&ASIC_TASK_MODULE.valid_jobs_lock); + ASIC_jobs_queue_clear(&MINING_MODULE.ASIC_jobs_queue); for (int i = 0; i < 128; i = i + 4) { - GLOBAL_STATE->valid_jobs[i] = 0; + ASIC_TASK_MODULE.valid_jobs[i] = 0; } - pthread_mutex_unlock(&GLOBAL_STATE->valid_jobs_lock); + pthread_mutex_unlock(&ASIC_TASK_MODULE.valid_jobs_lock); } -void stratum_reset_uid(GlobalState * GLOBAL_STATE) +void stratum_reset_uid() { ESP_LOGI(TAG, "Resetting stratum uid"); - GLOBAL_STATE->send_uid = 1; + send_uid = 1; } -void stratum_close_connection(GlobalState * GLOBAL_STATE) +void stratum_close_connection() { - if (GLOBAL_STATE->sock < 0) { + if (sock < 0) { ESP_LOGE(TAG, "Socket already shutdown, not shutting down again.."); return; } ESP_LOGE(TAG, "Shutting down socket and restarting..."); - shutdown(GLOBAL_STATE->sock, SHUT_RDWR); - close(GLOBAL_STATE->sock); - cleanQueue(GLOBAL_STATE); + shutdown(sock, SHUT_RDWR); + close(sock); + cleanQueue(); vTaskDelay(1000 / portTICK_PERIOD_MS); } -void stratum_primary_heartbeat(void * pvParameters) +int stratum_submit_share(char * jobid, char * extranonce2, uint32_t ntime, uint32_t nonce, uint32_t version) +{ + char * user = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].user; + int ret = STRATUM_V1_submit_share( + sock, + send_uid++, + user, + jobid, + extranonce2, + ntime, + nonce, + version); + + if (ret < 0) { + ESP_LOGI(TAG, "Unable to write share to socket. Closing connection. Ret: %d (errno %d: %s)", ret, errno, strerror(errno)); + stratum_close_connection(); + } + return ret; +} + +void stratum_primary_heartbeat() { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; ESP_LOGI(TAG, "Starting heartbeat thread for primary pool: %s:%d", primary_stratum_url, primary_stratum_port); vTaskDelay(10000 / portTICK_PERIOD_MS); @@ -98,7 +129,7 @@ void stratum_primary_heartbeat(void * pvParameters) while (1) { - if (GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback == false) { + if (POOL_MODULE.active_pool_idx == POOL_MODULE.default_pool_idx) { vTaskDelay(10000 / portTICK_PERIOD_MS); continue; } @@ -146,8 +177,8 @@ void stratum_primary_heartbeat(void * pvParameters) } int send_uid = 1; - STRATUM_V1_subscribe(sock, send_uid++, GLOBAL_STATE->DEVICE_CONFIG.family.asic.name); - STRATUM_V1_authorize(sock, send_uid++, GLOBAL_STATE->SYSTEM_MODULE.pool_user, GLOBAL_STATE->SYSTEM_MODULE.pool_pass); + STRATUM_V1_subscribe(sock, send_uid++, DEVICE_CONFIG.family.asic.name); + STRATUM_V1_authorize(sock, send_uid++, POOL_MODULE.pools[POOL_MODULE.active_pool_idx].user, POOL_MODULE.pools[POOL_MODULE.active_pool_idx].pass); char recv_buffer[BUFFER_SIZE]; memset(recv_buffer, 0, BUFFER_SIZE); @@ -163,8 +194,7 @@ void stratum_primary_heartbeat(void * pvParameters) if (strstr(recv_buffer, "mining.notify") != NULL) { ESP_LOGI(TAG, "Heartbeat successful and in fallback mode. Switching back to primary."); - GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback = false; - stratum_close_connection(GLOBAL_STATE); + stratum_close_connection(); continue; } @@ -172,10 +202,10 @@ void stratum_primary_heartbeat(void * pvParameters) } } -void decode_mining_notification(GlobalState * GLOBAL_STATE, const mining_notify *mining_notification) +void decode_mining_notification(const mining_notify *mining_notification) { double network_difficulty = networkDifficulty(mining_notification->target); - suffixString(network_difficulty, GLOBAL_STATE->network_diff_string, DIFF_STRING_SIZE, 0); + suffixString(network_difficulty, SYSTEM_MODULE.network_diff_string, DIFF_STRING_SIZE, 0); int coinbase_1_len = strlen(mining_notification->coinbase_1) / 2; int coinbase_2_len = strlen(mining_notification->coinbase_2) / 2; @@ -199,12 +229,12 @@ void decode_mining_notification(GlobalState * GLOBAL_STATE, const mining_notify hex2bin(mining_notification->coinbase_1 + (coinbase_1_offset * 2), (uint8_t *)&block_height, block_height_len); coinbase_1_offset += block_height_len; - if (block_height != GLOBAL_STATE->block_height) { + if (block_height != SYSTEM_MODULE.block_height) { ESP_LOGI(TAG, "Block height %d", block_height); - GLOBAL_STATE->block_height = block_height; + SYSTEM_MODULE.block_height = block_height; } - size_t scriptsig_length = scriptsig_len - 1 - block_height_len - (strlen(GLOBAL_STATE->extranonce_str) / 2) - GLOBAL_STATE->extranonce_2_len; + size_t scriptsig_length = scriptsig_len - 1 - block_height_len - (strlen(MINING_MODULE.extranonce_str) / 2) - MINING_MODULE.extranonce_2_len; if (scriptsig_length <= 0) return; char * scriptsig = malloc(scriptsig_length + 1); @@ -228,11 +258,11 @@ void decode_mining_notification(GlobalState * GLOBAL_STATE, const mining_notify scriptsig[scriptsig_length] = '\0'; - if (GLOBAL_STATE->scriptsig == NULL || strcmp(scriptsig, GLOBAL_STATE->scriptsig) != 0) { + if (SYSTEM_MODULE.scriptsig == NULL || strcmp(scriptsig, SYSTEM_MODULE.scriptsig) != 0) { ESP_LOGI(TAG, "Scriptsig: %s", scriptsig); - char * previous_miner_tag = GLOBAL_STATE->scriptsig; - GLOBAL_STATE->scriptsig = scriptsig; + char * previous_miner_tag = SYSTEM_MODULE.scriptsig; + SYSTEM_MODULE.scriptsig = scriptsig; free(previous_miner_tag); } else { free(scriptsig); @@ -241,14 +271,13 @@ void decode_mining_notification(GlobalState * GLOBAL_STATE, const mining_notify void stratum_task(void * pvParameters) { - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - primary_stratum_url = GLOBAL_STATE->SYSTEM_MODULE.pool_url; - primary_stratum_port = GLOBAL_STATE->SYSTEM_MODULE.pool_port; - char * stratum_url = GLOBAL_STATE->SYSTEM_MODULE.pool_url; - uint16_t port = GLOBAL_STATE->SYSTEM_MODULE.pool_port; - bool extranonce_subscribe = GLOBAL_STATE->SYSTEM_MODULE.pool_extranonce_subscribe; - uint16_t difficulty = GLOBAL_STATE->SYSTEM_MODULE.pool_difficulty; + primary_stratum_url = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].url; + primary_stratum_port = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].port; + char * stratum_url = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].url; + uint16_t port = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].port; + bool extranonce_subscribe = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].extranonce_subscribe; + uint16_t difficulty = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].difficulty; STRATUM_V1_initialize_buffer(); char host_ip[20]; @@ -269,33 +298,32 @@ void stratum_task(void * pvParameters) if (retry_attempts >= MAX_RETRY_ATTEMPTS) { - if (GLOBAL_STATE->SYSTEM_MODULE.fallback_pool_url == NULL || GLOBAL_STATE->SYSTEM_MODULE.fallback_pool_url[0] == '\0') { + POOL_MODULE.active_pool_idx = POOL_MODULE.active_pool_idx+1 % STRATUM_POOL_CAPACITY; + if (POOL_MODULE.pools[POOL_MODULE.active_pool_idx].url == NULL || POOL_MODULE.pools[POOL_MODULE.active_pool_idx].url[0] == '\0') { ESP_LOGI(TAG, "Unable to switch to fallback. No url configured. (retries: %d)...", retry_attempts); - GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback = false; retry_attempts = 0; continue; } - GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback = !GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback; // Reset share stats at failover - for (int i = 0; i < GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats_count; i++) { - GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats[i].count = 0; - GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats[i].message[0] = '\0'; + for (int i = 0; i < SYSTEM_MODULE.rejected_reason_stats_count; i++) { + SYSTEM_MODULE.rejected_reason_stats[i].count = 0; + SYSTEM_MODULE.rejected_reason_stats[i].message[0] = '\0'; } - GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats_count = 0; - GLOBAL_STATE->SYSTEM_MODULE.shares_accepted = 0; - GLOBAL_STATE->SYSTEM_MODULE.shares_rejected = 0; - GLOBAL_STATE->SYSTEM_MODULE.work_received = 0; + SYSTEM_MODULE.rejected_reason_stats_count = 0; + SYSTEM_MODULE.shares_accepted = 0; + SYSTEM_MODULE.shares_rejected = 0; + SYSTEM_MODULE.work_received = 0; ESP_LOGI(TAG, "Switching target due to too many failures (retries: %d)...", retry_attempts); retry_attempts = 0; } - stratum_url = GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback ? GLOBAL_STATE->SYSTEM_MODULE.fallback_pool_url : GLOBAL_STATE->SYSTEM_MODULE.pool_url; - port = GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback ? GLOBAL_STATE->SYSTEM_MODULE.fallback_pool_port : GLOBAL_STATE->SYSTEM_MODULE.pool_port; - extranonce_subscribe = GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback ? GLOBAL_STATE->SYSTEM_MODULE.fallback_pool_extranonce_subscribe : GLOBAL_STATE->SYSTEM_MODULE.pool_extranonce_subscribe; - difficulty = GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback ? GLOBAL_STATE->SYSTEM_MODULE.fallback_pool_difficulty : GLOBAL_STATE->SYSTEM_MODULE.pool_difficulty; + stratum_url = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].url; + port = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].port; + extranonce_subscribe = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].extranonce_subscribe; + difficulty = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].difficulty; struct hostent *dns_addr = gethostbyname(stratum_url); if (dns_addr == NULL) { @@ -312,9 +340,9 @@ void stratum_task(void * pvParameters) dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(port); - GLOBAL_STATE->sock = socket(addr_family, SOCK_STREAM, ip_protocol); + sock = socket(addr_family, SOCK_STREAM, ip_protocol); vTaskDelay(300 / portTICK_PERIOD_MS); - if (GLOBAL_STATE->sock < 0) { + if (sock < 0) { ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); if (++retry_critical_attempts > MAX_CRITICAL_RETRY_ATTEMPTS) { ESP_LOGE(TAG, "Max retry attempts reached, restarting..."); @@ -326,88 +354,87 @@ void stratum_task(void * pvParameters) retry_critical_attempts = 0; ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, port); - int err = connect(GLOBAL_STATE->sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6)); + int err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6)); if (err != 0) { retry_attempts++; ESP_LOGE(TAG, "Socket unable to connect to %s:%d (errno %d: %s)", stratum_url, port, errno, strerror(errno)); // close the socket - shutdown(GLOBAL_STATE->sock, SHUT_RDWR); - close(GLOBAL_STATE->sock); + shutdown(sock, SHUT_RDWR); + close(sock); // instead of restarting, retry this every 5 seconds vTaskDelay(5000 / portTICK_PERIOD_MS); continue; } - if (setsockopt(GLOBAL_STATE->sock, SOL_SOCKET, SO_SNDTIMEO, &tcp_snd_timeout, sizeof(tcp_snd_timeout)) != 0) { + if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tcp_snd_timeout, sizeof(tcp_snd_timeout)) != 0) { ESP_LOGE(TAG, "Fail to setsockopt SO_SNDTIMEO"); } - if (setsockopt(GLOBAL_STATE->sock, SOL_SOCKET, SO_RCVTIMEO , &tcp_rcv_timeout, sizeof(tcp_rcv_timeout)) != 0) { + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO , &tcp_rcv_timeout, sizeof(tcp_rcv_timeout)) != 0) { ESP_LOGE(TAG, "Fail to setsockopt SO_RCVTIMEO "); } - stratum_reset_uid(GLOBAL_STATE); - cleanQueue(GLOBAL_STATE); + stratum_reset_uid(); + cleanQueue(); ///// Start Stratum Action // mining.configure - ID: 1 - STRATUM_V1_configure_version_rolling(GLOBAL_STATE->sock, GLOBAL_STATE->send_uid++, &GLOBAL_STATE->version_mask); + STRATUM_V1_configure_version_rolling(sock, send_uid++, &MINING_MODULE.version_mask); // mining.subscribe - ID: 2 - STRATUM_V1_subscribe(GLOBAL_STATE->sock, GLOBAL_STATE->send_uid++, GLOBAL_STATE->DEVICE_CONFIG.family.asic.name); + STRATUM_V1_subscribe(sock, send_uid++, DEVICE_CONFIG.family.asic.name); - char * username = GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback ? GLOBAL_STATE->SYSTEM_MODULE.fallback_pool_user : GLOBAL_STATE->SYSTEM_MODULE.pool_user; - char * password = GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback ? GLOBAL_STATE->SYSTEM_MODULE.fallback_pool_pass : GLOBAL_STATE->SYSTEM_MODULE.pool_pass; + char * username = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].user; + char * password = POOL_MODULE.pools[POOL_MODULE.active_pool_idx].pass; - int authorize_message_id = GLOBAL_STATE->send_uid++; + int authorize_message_id = send_uid++; //mining.authorize - ID: 3 - STRATUM_V1_authorize(GLOBAL_STATE->sock, authorize_message_id, username, password); + STRATUM_V1_authorize(sock, authorize_message_id, username, password); STRATUM_V1_stamp_tx(authorize_message_id); // Everything is set up, lets make sure we don't abandon work unnecessarily. - GLOBAL_STATE->abandon_work = 0; + MINING_MODULE.abandon_work = 0; while (1) { - char * line = STRATUM_V1_receive_jsonrpc_line(GLOBAL_STATE->sock); + char * line = STRATUM_V1_receive_jsonrpc_line(sock); if (!line) { ESP_LOGE(TAG, "Failed to receive JSON-RPC line, reconnecting..."); retry_attempts++; - stratum_close_connection(GLOBAL_STATE); + stratum_close_connection(); break; } double response_time_ms = STRATUM_V1_get_response_time_ms(stratum_api_v1_message.message_id); if (response_time_ms >= 0) { ESP_LOGI(TAG, "Stratum response time: %.2f ms", response_time_ms); - GLOBAL_STATE->SYSTEM_MODULE.response_time = response_time_ms; + POOL_MODULE.response_time = response_time_ms; } STRATUM_V1_parse(&stratum_api_v1_message, line); free(line); if (stratum_api_v1_message.method == MINING_NOTIFY) { - GLOBAL_STATE->SYSTEM_MODULE.work_received++; - SYSTEM_notify_new_ntime(GLOBAL_STATE, stratum_api_v1_message.mining_notification->ntime); + SYSTEM_notify_new_ntime(stratum_api_v1_message.mining_notification->ntime); if (stratum_api_v1_message.should_abandon_work && - (GLOBAL_STATE->stratum_queue.count > 0 || GLOBAL_STATE->ASIC_jobs_queue.count > 0)) { - cleanQueue(GLOBAL_STATE); + (MINING_MODULE.stratum_queue.count > 0 || MINING_MODULE.ASIC_jobs_queue.count > 0)) { + cleanQueue(); } - if (GLOBAL_STATE->stratum_queue.count == QUEUE_SIZE) { - mining_notify * next_notify_json_str = (mining_notify *) queue_dequeue(&GLOBAL_STATE->stratum_queue); + if (MINING_MODULE.stratum_queue.count == QUEUE_SIZE) { + mining_notify * next_notify_json_str = (mining_notify *) queue_dequeue(&MINING_MODULE.stratum_queue); STRATUM_V1_free_mining_notify(next_notify_json_str); } - queue_enqueue(&GLOBAL_STATE->stratum_queue, stratum_api_v1_message.mining_notification); - decode_mining_notification(GLOBAL_STATE, stratum_api_v1_message.mining_notification); + queue_enqueue(&MINING_MODULE.stratum_queue, stratum_api_v1_message.mining_notification); + decode_mining_notification(stratum_api_v1_message.mining_notification); } else if (stratum_api_v1_message.method == MINING_SET_DIFFICULTY) { ESP_LOGI(TAG, "Set pool difficulty: %ld", stratum_api_v1_message.new_difficulty); - GLOBAL_STATE->pool_difficulty = stratum_api_v1_message.new_difficulty; - GLOBAL_STATE->new_set_mining_difficulty_msg = true; + POOL_MODULE.pool_difficulty = stratum_api_v1_message.new_difficulty; + MINING_MODULE.new_set_mining_difficulty_msg = true; } else if (stratum_api_v1_message.method == MINING_SET_VERSION_MASK || stratum_api_v1_message.method == STRATUM_RESULT_VERSION_MASK) { ESP_LOGI(TAG, "Set version mask: %08lx", stratum_api_v1_message.version_mask); - GLOBAL_STATE->version_mask = stratum_api_v1_message.version_mask; - GLOBAL_STATE->new_stratum_version_rolling_msg = true; + MINING_MODULE.version_mask = stratum_api_v1_message.version_mask; + MINING_MODULE.new_stratum_version_rolling_msg = true; } else if (stratum_api_v1_message.method == MINING_SET_EXTRANONCE || stratum_api_v1_message.method == STRATUM_RESULT_SUBSCRIBE) { // Validate extranonce_2_len to prevent buffer overflow @@ -417,21 +444,21 @@ void stratum_task(void * pvParameters) stratum_api_v1_message.extranonce_2_len = MAX_EXTRANONCE_2_LEN; } ESP_LOGI(TAG, "Set extranonce: %s, extranonce_2_len: %d", stratum_api_v1_message.extranonce_str, stratum_api_v1_message.extranonce_2_len); - char * old_extranonce_str = GLOBAL_STATE->extranonce_str; - GLOBAL_STATE->extranonce_str = stratum_api_v1_message.extranonce_str; - GLOBAL_STATE->extranonce_2_len = stratum_api_v1_message.extranonce_2_len; + char * old_extranonce_str = MINING_MODULE.extranonce_str; + MINING_MODULE.extranonce_str = stratum_api_v1_message.extranonce_str; + MINING_MODULE.extranonce_2_len = stratum_api_v1_message.extranonce_2_len; free(old_extranonce_str); } else if (stratum_api_v1_message.method == CLIENT_RECONNECT) { ESP_LOGE(TAG, "Pool requested client reconnect..."); - stratum_close_connection(GLOBAL_STATE); + stratum_close_connection(); break; } else if (stratum_api_v1_message.method == STRATUM_RESULT) { if (stratum_api_v1_message.response_success) { ESP_LOGI(TAG, "message result accepted"); - SYSTEM_notify_accepted_share(GLOBAL_STATE); + SYSTEM_notify_accepted_share(); } else { ESP_LOGW(TAG, "message result rejected: %s", stratum_api_v1_message.error_str); - SYSTEM_notify_rejected_share(GLOBAL_STATE, stratum_api_v1_message.error_str); + SYSTEM_notify_rejected_share(stratum_api_v1_message.error_str); } } else if (stratum_api_v1_message.method == STRATUM_RESULT_SETUP) { // Reset retry attempts after successfully receiving data. @@ -439,10 +466,10 @@ void stratum_task(void * pvParameters) if (stratum_api_v1_message.response_success) { ESP_LOGI(TAG, "setup message accepted"); if (stratum_api_v1_message.message_id == authorize_message_id) { - STRATUM_V1_suggest_difficulty(GLOBAL_STATE->sock, GLOBAL_STATE->send_uid++, difficulty); + STRATUM_V1_suggest_difficulty(sock, send_uid++, difficulty); } if (extranonce_subscribe) { - STRATUM_V1_extranonce_subscribe(GLOBAL_STATE->sock, GLOBAL_STATE->send_uid++); + STRATUM_V1_extranonce_subscribe(sock, send_uid++); } } else { ESP_LOGE(TAG, "setup message rejected: %s", stratum_api_v1_message.error_str); diff --git a/main/tasks/stratum_task.h b/main/tasks/stratum_task.h index 5ad9375a3..53ab850af 100644 --- a/main/tasks/stratum_task.h +++ b/main/tasks/stratum_task.h @@ -2,6 +2,7 @@ #define STRATUM_TASK_H_ void stratum_task(void *pvParameters); -void stratum_close_connection(GlobalState * GLOBAL_STATE); +void stratum_close_connection(); +int stratum_submit_share(char * jobid, char * extranonce2, uint32_t ntime,uint32_t nonce,uint32_t version); #endif \ No newline at end of file diff --git a/main/thermal/thermal.c b/main/thermal/thermal.c index 89b3735f4..8493fda25 100644 --- a/main/thermal/thermal.c +++ b/main/thermal/thermal.c @@ -1,26 +1,27 @@ #include "thermal.h" - +#include "device_config.h" #include "esp_log.h" -#include "EMC2101.h" +#include "state_module.h" #include "EMC2103.h" +#include "EMC2101.h" static const char * TAG = "thermal"; -esp_err_t Thermal_init(DeviceConfig * DEVICE_CONFIG) +esp_err_t Thermal_init() { - if (DEVICE_CONFIG->EMC2101) { - ESP_LOGI(TAG, "Initializing EMC2101 (Temperature offset: %dC)", DEVICE_CONFIG->emc_temp_offset); + if (DEVICE_CONFIG.EMC2101) { + ESP_LOGI(TAG, "Initializing EMC2101 (Temperature offset: %dC)", DEVICE_CONFIG.emc_temp_offset); esp_err_t res = EMC2101_init(); // TODO: Improve this check. - if (DEVICE_CONFIG->emc_ideality_factor != 0x00) { - ESP_LOGI(TAG, "EMC2101 configuration: Ideality Factor: %02x, Beta Compensation: %02x", DEVICE_CONFIG->emc_ideality_factor, DEVICE_CONFIG->emc_beta_compensation); - EMC2101_set_ideality_factor(DEVICE_CONFIG->emc_ideality_factor); - EMC2101_set_beta_compensation(DEVICE_CONFIG->emc_beta_compensation); + if (DEVICE_CONFIG.emc_ideality_factor != 0x00) { + ESP_LOGI(TAG, "EMC2101 configuration: Ideality Factor: %02x, Beta Compensation: %02x", DEVICE_CONFIG.emc_ideality_factor, DEVICE_CONFIG.emc_beta_compensation); + EMC2101_set_ideality_factor(DEVICE_CONFIG.emc_ideality_factor); + EMC2101_set_beta_compensation(DEVICE_CONFIG.emc_beta_compensation); } return res; } - if (DEVICE_CONFIG->EMC2103) { - ESP_LOGI(TAG, "Initializing EMC2103 (Temperature offset: %dC)", DEVICE_CONFIG->emc_temp_offset); + if (DEVICE_CONFIG.EMC2103) { + ESP_LOGI(TAG, "Initializing EMC2103 (Temperature offset: %dC)", DEVICE_CONFIG.emc_temp_offset); return EMC2103_init(); } @@ -28,56 +29,56 @@ esp_err_t Thermal_init(DeviceConfig * DEVICE_CONFIG) } //percent is a float between 0.0 and 1.0 -esp_err_t Thermal_set_fan_percent(DeviceConfig * DEVICE_CONFIG, float percent) +esp_err_t Thermal_set_fan_percent(float percent) { - if (DEVICE_CONFIG->EMC2101) { + if (DEVICE_CONFIG.EMC2101) { EMC2101_set_fan_speed(percent); } - if (DEVICE_CONFIG->EMC2103) { + if (DEVICE_CONFIG.EMC2103) { EMC2103_set_fan_speed(percent); } return ESP_OK; } -uint16_t Thermal_get_fan_speed(DeviceConfig * DEVICE_CONFIG) +uint16_t Thermal_get_fan_speed() { - if (DEVICE_CONFIG->EMC2101) { + if (DEVICE_CONFIG.EMC2101) { return EMC2101_get_fan_speed(); } - if (DEVICE_CONFIG->EMC2103) { + if (DEVICE_CONFIG.EMC2103) { return EMC2103_get_fan_speed(); } return 0; } -float Thermal_get_chip_temp(GlobalState * GLOBAL_STATE) +float Thermal_get_chip_temp() { - if (!GLOBAL_STATE->ASIC_initalized) { + if (!STATE_MODULE.ASIC_initalized) { return -1; } - int8_t temp_offset = GLOBAL_STATE->DEVICE_CONFIG.emc_temp_offset; - if (GLOBAL_STATE->DEVICE_CONFIG.EMC2101) { - if (GLOBAL_STATE->DEVICE_CONFIG.emc_internal_temp) { + int8_t temp_offset = DEVICE_CONFIG.emc_temp_offset; + if (DEVICE_CONFIG.EMC2101) { + if (DEVICE_CONFIG.emc_internal_temp) { return EMC2101_get_internal_temp() + temp_offset; } else { return EMC2101_get_external_temp() + temp_offset; } } - if (GLOBAL_STATE->DEVICE_CONFIG.EMC2103) { + if (DEVICE_CONFIG.EMC2103) { return EMC2103_get_external_temp() + temp_offset; } return -1; } -float Thermal_get_chip_temp2(GlobalState * GLOBAL_STATE) +float Thermal_get_chip_temp2() { - if (!GLOBAL_STATE->ASIC_initalized) { + if (!STATE_MODULE.ASIC_initalized) { return -1; } - int8_t temp_offset = GLOBAL_STATE->DEVICE_CONFIG.emc_temp_offset; - if (GLOBAL_STATE->DEVICE_CONFIG.EMC2103) { + int8_t temp_offset = DEVICE_CONFIG.emc_temp_offset; + if (DEVICE_CONFIG.EMC2103) { return EMC2103_get_external_temp2() + temp_offset; } return -1; diff --git a/main/thermal/thermal.h b/main/thermal/thermal.h index 190ab75bd..63c103371 100644 --- a/main/thermal/thermal.h +++ b/main/thermal/thermal.h @@ -3,13 +3,14 @@ #include -#include "global_state.h" -esp_err_t Thermal_init(DeviceConfig * DEVICE_CONFIG); -esp_err_t Thermal_set_fan_percent(DeviceConfig * DEVICE_CONFIG, float percent); -uint16_t Thermal_get_fan_speed(DeviceConfig * DEVICE_CONFIG); +esp_err_t Thermal_init(); +esp_err_t Thermal_set_fan_percent(float percent); +uint16_t Thermal_get_fan_speed(); -float Thermal_get_chip_temp(GlobalState * GLOBAL_STATE); -float Thermal_get_chip_temp2(GlobalState * GLOBAL_STATE); +esp_err_t Thermal_init(); +float Thermal_get_chip_temp2(); +float Thermal_get_chip_temp(); +uint16_t Thermal_get_fan_speed(); #endif // THERMAL_H diff --git a/main/wifi_module.h b/main/wifi_module.h new file mode 100644 index 000000000..f6cb4f9dc --- /dev/null +++ b/main/wifi_module.h @@ -0,0 +1,26 @@ +#ifndef WIFI_MODULE_H_ +#define WIFI_MODULE_H_ + +typedef struct +{ + // The SSID of the WiFi network to which the system is connected. + char ssid[32]; + + // Status information about the current state of the WiFi connection. + char wifi_status[256]; + + // A string representing the IP address currently assigned to the device. + char ip_addr_str[16]; // IP4ADDR_STRLEN_MAX + + // The SSID of the access point when operating in Access Point mode. + char ap_ssid[32]; + + // A flag indicating if the device is enabled as an access point. + bool ap_enabled; + + // A flag indicating whether the device is connected to a network. + bool is_connected; +}WifiSettings; + +extern WifiSettings WIFI_MODULE; +#endif \ No newline at end of file diff --git a/main/work_queue.c b/main/work_queue.c index 00dfc3572..92ff135a0 100644 --- a/main/work_queue.c +++ b/main/work_queue.c @@ -1,5 +1,8 @@ #include "work_queue.h" #include "esp_log.h" +#include +#include "mining.h" + void queue_init(work_queue *queue) { diff --git a/main/work_queue.h b/main/work_queue.h index 121e35420..9f5a28bfc 100644 --- a/main/work_queue.h +++ b/main/work_queue.h @@ -1,21 +1,8 @@ #ifndef WORK_QUEUE_H #define WORK_QUEUE_H -#include -#include "mining.h" +#include "mining_module.h" -#define QUEUE_SIZE 12 - -typedef struct -{ - void *buffer[QUEUE_SIZE]; - int head; - int tail; - int count; - pthread_mutex_t lock; - pthread_cond_t not_empty; - pthread_cond_t not_full; -} work_queue; void queue_init(work_queue *queue); void queue_enqueue(work_queue *queue, void *new_work);