2023-06-06 21:05:43 -04:00
2023-04-14 21:37:30 -04:00
# include "esp_event.h"
# include "esp_log.h"
# include "nvs_flash.h"
2023-06-06 21:05:43 -04:00
2023-08-26 12:28:17 -04:00
// #include "protocol_examples_common.h"
2023-08-26 12:21:41 -04:00
# include "main.h"
2023-04-14 21:37:30 -04:00
2023-09-17 00:01:54 -04:00
# include "asic_result_task.h"
2023-06-06 21:05:43 -04:00
# include "asic_task.h"
# include "create_jobs_task.h"
2023-09-17 00:01:54 -04:00
# include "esp_netif.h"
2024-06-12 15:05:14 +02:00
# include "system.h"
2023-08-26 12:21:41 -04:00
# include "http_server.h"
2023-09-17 00:01:54 -04:00
# include "nvs_config.h"
# include "serial.h"
# include "stratum_task.h"
2023-08-26 12:21:41 -04:00
# include "user_input_task.h"
2024-09-20 19:30:20 -04:00
static GlobalState GLOBAL_STATE = {
. extranonce_str = NULL ,
. extranonce_2_len = 0 ,
. abandon_work = 0 ,
. version_mask = 0 ,
. ASIC_initalized = false
} ;
2023-04-14 21:37:30 -04:00
2024-07-07 09:05:31 -04:00
static const char * TAG = " bitaxe " ;
2024-06-19 15:29:45 +02:00
static const double NONCE_SPACE = 4294967296.0 ; // 2^32
2023-04-14 21:37:30 -04:00
void app_main ( void )
{
2024-07-07 09:05:31 -04:00
ESP_LOGI ( TAG , " Welcome to the bitaxe - hack the planet! " ) ;
2023-09-17 00:01:54 -04:00
ESP_ERROR_CHECK ( nvs_flash_init ( ) ) ;
GLOBAL_STATE . POWER_MANAGEMENT_MODULE . frequency_value = nvs_config_get_u16 ( NVS_CONFIG_ASIC_FREQ , CONFIG_ASIC_FREQUENCY ) ;
2024-06-06 15:39:51 +02:00
ESP_LOGI ( TAG , " NVS_CONFIG_ASIC_FREQ %f " , ( float ) GLOBAL_STATE . POWER_MANAGEMENT_MODULE . frequency_value ) ;
2023-08-20 13:09:55 -04:00
2024-06-04 17:06:45 +02:00
GLOBAL_STATE . device_model_str = nvs_config_get_string ( NVS_CONFIG_DEVICE_MODEL , " " ) ;
if ( strcmp ( GLOBAL_STATE . device_model_str , " max " ) = = 0 ) {
ESP_LOGI ( TAG , " DEVICE: Max " ) ;
GLOBAL_STATE . device_model = DEVICE_MAX ;
2024-06-10 10:02:36 +02:00
GLOBAL_STATE . asic_count = 1 ;
GLOBAL_STATE . voltage_domain = 1 ;
2024-06-04 17:06:45 +02:00
} else if ( strcmp ( GLOBAL_STATE . device_model_str , " ultra " ) = = 0 ) {
ESP_LOGI ( TAG , " DEVICE: Ultra " ) ;
GLOBAL_STATE . device_model = DEVICE_ULTRA ;
2024-06-10 10:02:36 +02:00
GLOBAL_STATE . asic_count = 1 ;
GLOBAL_STATE . voltage_domain = 1 ;
2024-06-04 17:06:45 +02:00
} else if ( strcmp ( GLOBAL_STATE . device_model_str , " supra " ) = = 0 ) {
ESP_LOGI ( TAG , " DEVICE: Supra " ) ;
GLOBAL_STATE . device_model = DEVICE_SUPRA ;
2024-06-10 10:02:36 +02:00
GLOBAL_STATE . asic_count = 1 ;
GLOBAL_STATE . voltage_domain = 1 ;
2024-08-15 18:51:05 -04:00
} else if ( strcmp ( GLOBAL_STATE . device_model_str , " gamma " ) = = 0 ) {
ESP_LOGI ( TAG , " DEVICE: Gamma " ) ;
GLOBAL_STATE . device_model = DEVICE_GAMMA ;
GLOBAL_STATE . asic_count = 1 ;
GLOBAL_STATE . voltage_domain = 1 ;
2024-06-04 17:06:45 +02:00
} else {
ESP_LOGE ( TAG , " Invalid DEVICE model " ) ;
// maybe should return here to now execute anything with a faulty device parameter !
2024-06-18 01:18:51 -05:00
// this stops crashes/reboots and allows dev testing without an asic
GLOBAL_STATE . device_model = DEVICE_UNKNOWN ;
GLOBAL_STATE . asic_count = - 1 ;
GLOBAL_STATE . voltage_domain = 1 ;
2024-06-04 17:06:45 +02:00
}
2024-06-12 16:21:59 +02:00
GLOBAL_STATE . board_version = atoi ( nvs_config_get_string ( NVS_CONFIG_BOARD_VERSION , " 000 " ) ) ;
ESP_LOGI ( TAG , " Found Device Model: %s " , GLOBAL_STATE . device_model_str ) ;
ESP_LOGI ( TAG , " Found Board Version: %d " , GLOBAL_STATE . board_version ) ;
2024-06-04 17:06:45 +02:00
GLOBAL_STATE . asic_model_str = nvs_config_get_string ( NVS_CONFIG_ASIC_MODEL , " " ) ;
if ( strcmp ( GLOBAL_STATE . asic_model_str , " BM1366 " ) = = 0 ) {
2024-07-07 09:05:31 -04:00
ESP_LOGI ( TAG , " ASIC: %dx BM1366 (% " PRIu64 " cores) " , GLOBAL_STATE . asic_count , BM1366_CORE_COUNT ) ;
2024-06-04 17:06:45 +02:00
GLOBAL_STATE . asic_model = ASIC_BM1366 ;
2023-09-17 00:01:54 -04:00
AsicFunctions ASIC_functions = { . init_fn = BM1366_init ,
. receive_result_fn = BM1366_proccess_work ,
. set_max_baud_fn = BM1366_set_max_baud ,
. set_difficulty_mask_fn = BM1366_set_job_difficulty_mask ,
. send_work_fn = BM1366_send_work } ;
2024-07-07 09:05:31 -04:00
//GLOBAL_STATE.asic_job_frequency_ms = (NONCE_SPACE / (double) (GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value * BM1366_CORE_COUNT * 1000)) / (double) GLOBAL_STATE.asic_count; // version-rolling so Small Cores have different Nonce Space
2024-09-18 11:03:15 -05:00
GLOBAL_STATE . asic_job_frequency_ms = ASIC_BM1366_JOB_FREQUENCY_MS ; //2000ms
2024-06-02 09:06:00 -04:00
GLOBAL_STATE . initial_ASIC_difficulty = BM1366_INITIAL_DIFFICULTY ;
2023-08-20 13:09:55 -04:00
2024-08-15 18:51:05 -04:00
GLOBAL_STATE . ASIC_functions = ASIC_functions ;
} else if ( strcmp ( GLOBAL_STATE . asic_model_str , " BM1370 " ) = = 0 ) {
ESP_LOGI ( TAG , " ASIC: %dx BM1370 (% " PRIu64 " cores) " , GLOBAL_STATE . asic_count , BM1370_CORE_COUNT ) ;
GLOBAL_STATE . asic_model = ASIC_BM1370 ;
AsicFunctions ASIC_functions = { . init_fn = BM1370_init ,
. receive_result_fn = BM1370_proccess_work ,
. set_max_baud_fn = BM1370_set_max_baud ,
. set_difficulty_mask_fn = BM1370_set_job_difficulty_mask ,
. send_work_fn = BM1370_send_work } ;
//GLOBAL_STATE.asic_job_frequency_ms = (NONCE_SPACE / (double) (GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value * BM1370_CORE_COUNT * 1000)) / (double) GLOBAL_STATE.asic_count; // version-rolling so Small Cores have different Nonce Space
2024-09-18 11:03:15 -05:00
GLOBAL_STATE . asic_job_frequency_ms = ASIC_BM1370_JOB_FREQUENCY_MS ; //500ms
2024-08-15 18:51:05 -04:00
GLOBAL_STATE . initial_ASIC_difficulty = BM1370_INITIAL_DIFFICULTY ;
2024-02-04 00:19:33 -05:00
GLOBAL_STATE . ASIC_functions = ASIC_functions ;
2024-06-04 17:06:45 +02:00
} else if ( strcmp ( GLOBAL_STATE . asic_model_str , " BM1368 " ) = = 0 ) {
2024-07-07 09:05:31 -04:00
ESP_LOGI ( TAG , " ASIC: %dx BM1368 (% " PRIu64 " cores) " , GLOBAL_STATE . asic_count , BM1368_CORE_COUNT ) ;
2024-06-04 17:06:45 +02:00
GLOBAL_STATE . asic_model = ASIC_BM1368 ;
2024-02-04 00:19:33 -05:00
AsicFunctions ASIC_functions = { . init_fn = BM1368_init ,
. receive_result_fn = BM1368_proccess_work ,
. set_max_baud_fn = BM1368_set_max_baud ,
. set_difficulty_mask_fn = BM1368_set_job_difficulty_mask ,
. send_work_fn = BM1368_send_work } ;
2024-07-07 09:05:31 -04:00
//GLOBAL_STATE.asic_job_frequency_ms = (NONCE_SPACE / (double) (GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value * BM1368_CORE_COUNT * 1000)) / (double) GLOBAL_STATE.asic_count; // version-rolling so Small Cores have different Nonce Space
2024-09-18 11:03:15 -05:00
GLOBAL_STATE . asic_job_frequency_ms = ASIC_BM1368_JOB_FREQUENCY_MS ; //500ms
2024-06-02 09:06:00 -04:00
GLOBAL_STATE . initial_ASIC_difficulty = BM1368_INITIAL_DIFFICULTY ;
2024-02-04 00:19:33 -05:00
2023-08-20 13:09:55 -04:00
GLOBAL_STATE . ASIC_functions = ASIC_functions ;
2024-06-04 17:06:45 +02:00
} else if ( strcmp ( GLOBAL_STATE . asic_model_str , " BM1397 " ) = = 0 ) {
2024-07-07 09:05:31 -04:00
ESP_LOGI ( TAG , " ASIC: %dx BM1397 (% " PRIu64 " cores) " , GLOBAL_STATE . asic_count , BM1397_SMALL_CORE_COUNT ) ;
2024-06-04 17:06:45 +02:00
GLOBAL_STATE . asic_model = ASIC_BM1397 ;
2023-09-17 00:01:54 -04:00
AsicFunctions ASIC_functions = { . init_fn = BM1397_init ,
. receive_result_fn = BM1397_proccess_work ,
. set_max_baud_fn = BM1397_set_max_baud ,
. set_difficulty_mask_fn = BM1397_set_job_difficulty_mask ,
. send_work_fn = BM1397_send_work } ;
2024-06-19 15:29:45 +02:00
GLOBAL_STATE . asic_job_frequency_ms = ( NONCE_SPACE / ( double ) ( GLOBAL_STATE . POWER_MANAGEMENT_MODULE . frequency_value * BM1397_SMALL_CORE_COUNT * 1000 ) ) / ( double ) GLOBAL_STATE . asic_count ; // no version-rolling so same Nonce Space is splitted between Small Cores
2024-06-02 09:06:00 -04:00
GLOBAL_STATE . initial_ASIC_difficulty = BM1397_INITIAL_DIFFICULTY ;
2023-08-20 13:09:55 -04:00
GLOBAL_STATE . ASIC_functions = ASIC_functions ;
2023-09-17 00:01:54 -04:00
} else {
2024-06-04 17:06:45 +02:00
ESP_LOGE ( TAG , " Invalid ASIC model " ) ;
2023-09-26 23:52:22 -04:00
AsicFunctions ASIC_functions = { . init_fn = NULL ,
. receive_result_fn = NULL ,
. set_max_baud_fn = NULL ,
. set_difficulty_mask_fn = NULL ,
. send_work_fn = NULL } ;
GLOBAL_STATE . ASIC_functions = ASIC_functions ;
2024-06-04 17:06:45 +02:00
// maybe should return here to now execute anything with a faulty device parameter !
2023-08-20 13:09:55 -04:00
}
2024-06-04 17:06:45 +02:00
bool is_max = GLOBAL_STATE . asic_model = = ASIC_BM1397 ;
2024-03-18 00:46:59 -04:00
uint64_t best_diff = nvs_config_get_u64 ( NVS_CONFIG_BEST_DIFF , 0 ) ;
2024-05-21 16:40:16 -04:00
uint16_t should_self_test = nvs_config_get_u16 ( NVS_CONFIG_SELF_TEST , 0 ) ;
2024-03-18 00:46:59 -04:00
if ( should_self_test = = 1 & & ! is_max & & best_diff < 1 ) {
2024-03-17 15:37:41 -04:00
self_test ( ( void * ) & GLOBAL_STATE ) ;
2024-03-18 00:46:59 -04:00
vTaskDelay ( 60 * 60 * 1000 / portTICK_PERIOD_MS ) ;
2024-03-17 15:37:41 -04:00
}
2023-04-14 21:37:30 -04:00
2023-09-17 00:01:54 -04:00
xTaskCreate ( SYSTEM_task , " SYSTEM_task " , 4096 , ( void * ) & GLOBAL_STATE , 3 , NULL ) ;
2024-06-08 10:03:29 -04:00
xTaskCreate ( POWER_MANAGEMENT_task , " power mangement " , 8192 , ( void * ) & GLOBAL_STATE , 10 , NULL ) ;
2024-03-17 15:37:41 -04:00
2024-05-24 04:54:39 +02:00
// pull the wifi credentials and hostname out of NVS
2023-09-17 00:01:54 -04:00
char * wifi_ssid = nvs_config_get_string ( NVS_CONFIG_WIFI_SSID , WIFI_SSID ) ;
char * wifi_pass = nvs_config_get_string ( NVS_CONFIG_WIFI_PASS , WIFI_PASS ) ;
2024-05-24 04:54:39 +02:00
char * hostname = nvs_config_get_string ( NVS_CONFIG_HOSTNAME , HOSTNAME ) ;
2023-06-21 19:00:09 -04:00
2023-08-26 12:28:17 -04:00
// copy the wifi ssid to the global state
2024-06-18 01:18:51 -05:00
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 ;
2023-06-21 19:00:09 -04:00
2023-08-26 12:28:17 -04:00
// init and connect to wifi
2024-05-24 04:54:39 +02:00
wifi_init ( wifi_ssid , wifi_pass , hostname ) ;
2023-09-17 00:01:54 -04:00
start_rest_server ( ( void * ) & GLOBAL_STATE ) ;
2023-08-26 12:21:41 -04:00
EventBits_t result_bits = wifi_connect ( ) ;
2023-06-21 19:00:09 -04:00
2023-09-17 00:01:54 -04:00
if ( result_bits & WIFI_CONNECTED_BIT ) {
2023-06-21 19:00:09 -04:00
ESP_LOGI ( TAG , " Connected to SSID: %s " , wifi_ssid ) ;
strncpy ( GLOBAL_STATE . SYSTEM_MODULE . wifi_status , " Connected! " , 20 ) ;
2023-09-17 00:01:54 -04:00
} else if ( result_bits & WIFI_FAIL_BIT ) {
2023-06-21 19:00:09 -04:00
ESP_LOGE ( TAG , " Failed to connect to SSID: %s " , wifi_ssid ) ;
2023-09-17 00:01:54 -04:00
2023-06-21 19:00:09 -04:00
strncpy ( GLOBAL_STATE . SYSTEM_MODULE . wifi_status , " Failed to connect " , 20 ) ;
2023-08-26 12:21:41 -04:00
// User might be trying to configure with AP, just chill here
2023-08-26 12:28:17 -04:00
ESP_LOGI ( TAG , " Finished, waiting for user input. " ) ;
2023-09-17 00:01:54 -04:00
while ( 1 ) {
2023-08-26 12:21:41 -04:00
vTaskDelay ( 1000 / portTICK_PERIOD_MS ) ;
}
2023-09-17 00:01:54 -04:00
} else {
2023-06-21 19:00:09 -04:00
ESP_LOGE ( TAG , " UNEXPECTED EVENT " ) ;
strncpy ( GLOBAL_STATE . SYSTEM_MODULE . wifi_status , " unexpected error " , 20 ) ;
2023-08-26 12:21:41 -04:00
// User might be trying to configure with AP, just chill here
2023-08-26 12:28:17 -04:00
ESP_LOGI ( TAG , " Finished, waiting for user input. " ) ;
2023-09-17 00:01:54 -04:00
while ( 1 ) {
2023-08-26 12:21:41 -04:00
vTaskDelay ( 1000 / portTICK_PERIOD_MS ) ;
}
2023-06-21 19:00:09 -04:00
}
2023-06-13 23:47:12 -04:00
free ( wifi_ssid ) ;
free ( wifi_pass ) ;
2024-05-24 04:54:39 +02:00
free ( hostname ) ;
2023-04-14 21:37:30 -04:00
2023-08-26 12:28:17 -04:00
// set the startup_done flag
2023-06-21 19:00:09 -04:00
GLOBAL_STATE . SYSTEM_MODULE . startup_done = true ;
2023-09-26 23:52:22 -04:00
xTaskCreate ( USER_INPUT_task , " user input " , 8192 , ( void * ) & GLOBAL_STATE , 5 , NULL ) ;
2024-06-08 10:03:29 -04:00
2023-09-26 23:52:22 -04:00
if ( GLOBAL_STATE . ASIC_functions . init_fn ! = NULL ) {
wifi_softap_off ( ) ;
queue_init ( & GLOBAL_STATE . stratum_queue ) ;
queue_init ( & GLOBAL_STATE . ASIC_jobs_queue ) ;
SERIAL_init ( ) ;
2024-06-06 16:36:40 +02:00
( * GLOBAL_STATE . ASIC_functions . init_fn ) ( GLOBAL_STATE . POWER_MANAGEMENT_MODULE . frequency_value , GLOBAL_STATE . asic_count ) ;
2024-05-24 05:18:44 +02:00
SERIAL_set_baud ( ( * GLOBAL_STATE . ASIC_functions . set_max_baud_fn ) ( ) ) ;
SERIAL_clear_buffer ( ) ;
2023-09-26 23:52:22 -04:00
2024-09-20 19:30:20 -04:00
GLOBAL_STATE . ASIC_initalized = true ;
2023-09-26 23:52:22 -04:00
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 ) ;
}
2023-04-14 21:37:30 -04:00
}
2023-06-06 09:06:30 -04:00
2023-08-26 12:28:17 -04:00
void MINER_set_wifi_status ( wifi_status_t status , uint16_t retry_count )
{
2023-09-17 00:01:54 -04:00
if ( status = = WIFI_RETRYING ) {
2024-05-23 22:34:11 -04:00
snprintf ( GLOBAL_STATE . SYSTEM_MODULE . wifi_status , 20 , " Retrying: %d " , retry_count ) ;
2023-06-21 19:21:49 -04:00
return ;
2023-09-17 00:01:54 -04:00
} else if ( status = = WIFI_CONNECT_FAILED ) {
2023-06-21 19:21:49 -04:00
snprintf ( GLOBAL_STATE . SYSTEM_MODULE . wifi_status , 20 , " Connect Failed! " ) ;
return ;
}
}