From 59fc87505aa7399d4fe694afcb904a533c8aaf70 Mon Sep 17 00:00:00 2001 From: Skot Date: Mon, 7 Oct 2024 23:52:03 -0400 Subject: [PATCH] moved _init_system() out of SYSTEM_Task() to avoid I2c init race condition. --- main/TPS546.c | 50 ++-- main/main.c | 11 + main/system.c | 357 +++++++++++++++-------------- main/system.h | 4 + main/tasks/power_management_task.c | 2 +- 5 files changed, 226 insertions(+), 198 deletions(-) diff --git a/main/TPS546.c b/main/TPS546.c index a6f2bdd7..5967cd22 100644 --- a/main/TPS546.c +++ b/main/TPS546.c @@ -364,26 +364,26 @@ int TPS546_init(void) TPS546_write_entire_config(); //} - /* Show temperature */ - ESP_LOGI(TAG, "--------------------------------"); - ESP_LOGI(TAG, "Temp: %d", TPS546_get_temperature()); + // /* Show temperature */ + // ESP_LOGI(TAG, "--------------------------------"); + // ESP_LOGI(TAG, "Temp: %d", TPS546_get_temperature()); - /* Show switching frequency */ - TPS546_get_frequency(); - TPS546_set_frequency(650); + // /* Show switching frequency */ + // TPS546_get_frequency(); + // TPS546_set_frequency(650); /* Show voltage settings */ TPS546_show_voltage_settings(); - TPS546_print_status(); + //TPS546_print_status(); - ESP_LOGI(TAG, "-----------VOLTAGE/CURRENT---------------------"); - /* Get voltage input (SLINEAR11) */ - TPS546_get_vin(); - /* Get output current (SLINEAR11) */ - TPS546_get_iout(); - /* Get voltage output (ULINEAR16) */ - TPS546_get_vout(); + // ESP_LOGI(TAG, "-----------VOLTAGE/CURRENT---------------------"); + // /* Get voltage input (SLINEAR11) */ + // ESP_LOGI(TAG, "READ_VIN: %.2fV", TPS546_get_vin()); + // /* Get output current (SLINEAR11) */ + // ESP_LOGI(TAG, "READ_IOUT: %.2fA", TPS546_get_iout()); + // /* Get voltage output (ULINEAR16) */ + // ESP_LOGI(TAG, "READ_VOUT: %.2fV", TPS546_get_vout()); ESP_LOGI(TAG, "-----------TIMING---------------------"); smb_read_word(PMBUS_TON_DELAY, &u16_value); @@ -729,56 +729,56 @@ void TPS546_show_voltage_settings(void) /* VIN_ON SLINEAR11 */ smb_read_word(PMBUS_VIN_ON, &u16_value); f_value = slinear11_2_float(u16_value); - ESP_LOGI(TAG, "VIN ON set to: %f", f_value); + ESP_LOGI(TAG, "VIN ON set to: %.2f", f_value); /* VIN_OFF SLINEAR11 */ smb_read_word(PMBUS_VIN_OFF, &u16_value); f_value = slinear11_2_float(u16_value); - ESP_LOGI(TAG, "VIN OFF set to: %f", f_value); + ESP_LOGI(TAG, "VIN OFF set to: %.2f", f_value); /* VOUT_MAX */ smb_read_word(PMBUS_VOUT_MAX, &u16_value); f_value = ulinear16_2_float(u16_value); - ESP_LOGI(TAG, "Vout Max set to: %f V", f_value); + ESP_LOGI(TAG, "Vout Max set to: %.2f V", f_value); /* VOUT_OV_FAULT_LIMIT */ smb_read_word(PMBUS_VOUT_OV_FAULT_LIMIT, &u16_value); f_value = ulinear16_2_float(u16_value); - ESP_LOGI(TAG, "Vout OV Fault Limit: %f V", f_value); + ESP_LOGI(TAG, "Vout OV Fault Limit: %.2f V", f_value); /* VOUT_OV_WARN_LIMIT */ smb_read_word(PMBUS_VOUT_OV_WARN_LIMIT, &u16_value); f_value = ulinear16_2_float(u16_value); - ESP_LOGI(TAG, "Vout OV Warn Limit: %f V", f_value); + ESP_LOGI(TAG, "Vout OV Warn Limit: %.2f V", f_value); /* VOUT_MARGIN_HIGH */ smb_read_word(PMBUS_VOUT_MARGIN_HIGH, &u16_value); f_value = ulinear16_2_float(u16_value); - ESP_LOGI(TAG, "Vout Margin HIGH: %f V", f_value); + ESP_LOGI(TAG, "Vout Margin HIGH: %.2f V", f_value); /* --- VOUT_COMMAND --- */ smb_read_word(PMBUS_VOUT_COMMAND, &u16_value); f_value = ulinear16_2_float(u16_value); - ESP_LOGI(TAG, "Vout set to: %f V", f_value); + ESP_LOGI(TAG, "Vout set to: %.2f V", f_value); /* VOUT_MARGIN_LOW */ smb_read_word(PMBUS_VOUT_MARGIN_LOW, &u16_value); f_value = ulinear16_2_float(u16_value); - ESP_LOGI(TAG, "Vout Margin LOW: %f V", f_value); + ESP_LOGI(TAG, "Vout Margin LOW: %.2f V", f_value); /* VOUT_UV_WARN_LIMIT */ smb_read_word(PMBUS_VOUT_UV_WARN_LIMIT, &u16_value); f_value = ulinear16_2_float(u16_value); - ESP_LOGI(TAG, "Vout UV Warn Limit: %f V", f_value); + ESP_LOGI(TAG, "Vout UV Warn Limit: %.2f V", f_value); /* VOUT_UV_FAULT_LIMIT */ smb_read_word(PMBUS_VOUT_UV_FAULT_LIMIT, &u16_value); f_value = ulinear16_2_float(u16_value); - ESP_LOGI(TAG, "Vout UV Fault Limit: %f V", f_value); + ESP_LOGI(TAG, "Vout UV Fault Limit: %.2f V", f_value); /* VOUT_MIN */ smb_read_word(PMBUS_VOUT_MIN, &u16_value); f_value = ulinear16_2_float(u16_value); - ESP_LOGI(TAG, "Vout Min set to: %f V", f_value); + ESP_LOGI(TAG, "Vout Min set to: %.2f V", f_value); } diff --git a/main/main.c b/main/main.c index 2e60ecbb..b36216c1 100644 --- a/main/main.c +++ b/main/main.c @@ -16,6 +16,7 @@ #include "serial.h" #include "stratum_task.h" #include "user_input_task.h" +#include "i2c_bitaxe.h" static GlobalState GLOBAL_STATE = { .extranonce_str = NULL, @@ -31,6 +32,14 @@ static const double NONCE_SPACE = 4294967296.0; // 2^32 void app_main(void) { ESP_LOGI(TAG, "Welcome to the bitaxe - hack the planet!"); + + // Init I2C + ESP_ERROR_CHECK(i2c_bitaxe_init()); + ESP_LOGI(TAG, "I2C initialized successfully"); + + //wait for I2C to init + vTaskDelay(100 / portTICK_PERIOD_MS); + ESP_ERROR_CHECK(nvs_flash_init()); GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value = nvs_config_get_u16(NVS_CONFIG_ASIC_FREQ, CONFIG_ASIC_FREQUENCY); @@ -144,6 +153,8 @@ void app_main(void) vTaskDelay(60 * 60 * 1000 / portTICK_PERIOD_MS); } + SYSTEM_init_system(&GLOBAL_STATE); + xTaskCreate(SYSTEM_task, "SYSTEM_task", 4096, (void *) &GLOBAL_STATE, 3, NULL); xTaskCreate(POWER_MANAGEMENT_task, "power mangement", 8192, (void *) &GLOBAL_STATE, 10, NULL); diff --git a/main/system.c b/main/system.c index 04ba56ab..21058d4b 100644 --- a/main/system.c +++ b/main/system.c @@ -40,22 +40,23 @@ static esp_netif_ip_info_t ip_info; QueueHandle_t user_input_queue; -static esp_err_t ensure_overheat_mode_config() { - uint16_t overheat_mode = nvs_config_get_u16(NVS_CONFIG_OVERHEAT_MODE, UINT16_MAX); - - if (overheat_mode == UINT16_MAX) { - // Key doesn't exist or couldn't be read, set the default value - nvs_config_set_u16(NVS_CONFIG_OVERHEAT_MODE, 0); - ESP_LOGI(TAG, "Default value for overheat_mode set to 0"); - } else { - // Key exists, log the current value - ESP_LOGI(TAG, "Existing overheat_mode value: %d", overheat_mode); - } - - return ESP_OK; -} - -static void _init_system(GlobalState * GLOBAL_STATE) +//local function prototypes +static esp_err_t ensure_overheat_mode_config(); +static void _show_overheat_screen(GlobalState * GLOBAL_STATE); +static void _update_hashrate(GlobalState * GLOBAL_STATE); +static void _update_shares(GlobalState * GLOBAL_STATE); +static void _clear_display(GlobalState * GLOBAL_STATE); +static void _init_connection(GlobalState * GLOBAL_STATE); +static void _update_connection(GlobalState * GLOBAL_STATE); +static void _update_system_performance(GlobalState * GLOBAL_STATE); +static void _update_system_info(GlobalState * GLOBAL_STATE); +static void _update_esp32_info(GlobalState * GLOBAL_STATE); +static void show_ap_information(const char * error, GlobalState * GLOBAL_STATE); + +static void _check_for_best_diff(GlobalState * GLOBAL_STATE, double diff, uint8_t job_id); +static void _suffix_string(uint64_t val, char * buf, size_t bufsiz, int sigdigits); + +void SYSTEM_init_system(GlobalState * GLOBAL_STATE) { SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; @@ -98,18 +99,6 @@ static void _init_system(GlobalState * GLOBAL_STATE) // set the wifi_status to blank memset(module->wifi_status, 0, 20); - // test the LEDs - // ESP_LOGI(TAG, "Init LEDs!"); - // ledc_init(); - // led_set(); - - // Init I2C - ESP_ERROR_CHECK(i2c_bitaxe_init()); - ESP_LOGI(TAG, "I2C initialized successfully"); - - //wait for I2C to init - vTaskDelay(100 / portTICK_PERIOD_MS); - // Initialize the core voltage regulator VCORE_init(GLOBAL_STATE); VCORE_set_voltage(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0, GLOBAL_STATE); @@ -150,8 +139,81 @@ static void _init_system(GlobalState * GLOBAL_STATE) } netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + + user_input_queue = xQueueCreate(10, sizeof(char[10])); // Create a queue to handle user input events + + _clear_display(GLOBAL_STATE); + _init_connection(GLOBAL_STATE); } + + +void SYSTEM_task(void * pvParameters) +{ + GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; + SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; + + //_init_system(GLOBAL_STATE); + + char input_event[10]; + ESP_LOGI(TAG, "SYSTEM_task started"); + + while (GLOBAL_STATE->ASIC_functions.init_fn == NULL) { + show_ap_information("ASIC MODEL INVALID", GLOBAL_STATE); + vTaskDelay(5000 / portTICK_PERIOD_MS); + } + + // show the connection screen + while (!module->startup_done) { + _update_connection(GLOBAL_STATE); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + + while (1) { + // Check for overheat mode + if (module->overheat_mode == 1) { + _show_overheat_screen(GLOBAL_STATE); + vTaskDelay(5000 / portTICK_PERIOD_MS); // Update every 5 seconds + SYSTEM_update_overheat_mode(GLOBAL_STATE); // Check for changes + continue; // Skip the normal screen cycle + } + + // Automatically cycle through screens + for (int screen = 0; screen < 3; screen++) { + _clear_display(GLOBAL_STATE); + module->screen_page = screen; + + switch (module->screen_page) { + case 0: + _update_system_performance(GLOBAL_STATE); + break; + case 1: + _update_system_info(GLOBAL_STATE); + break; + case 2: + _update_esp32_info(GLOBAL_STATE); + break; + } + + // Wait for 10 seconds or until a button press + for (int i = 0; i < 10; i++) { + if (xQueueReceive(user_input_queue, &input_event, pdMS_TO_TICKS(1000))) { + if (strcmp(input_event, "SHORT") == 0) { + ESP_LOGI(TAG, "Short button press detected, switching to next screen"); + screen = (screen + 1) % 3; // Move to next screen + break; + } else if (strcmp(input_event, "LONG") == 0) { + ESP_LOGI(TAG, "Long button press detected, toggling WiFi SoftAP"); + toggle_wifi_softap(); // Toggle AP + } + } + } + } + } +} + + + void SYSTEM_update_overheat_mode(GlobalState * GLOBAL_STATE) { SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; @@ -163,6 +225,92 @@ void SYSTEM_update_overheat_mode(GlobalState * GLOBAL_STATE) } } +void SYSTEM_notify_accepted_share(GlobalState * GLOBAL_STATE) +{ + SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; + + module->shares_accepted++; + _update_shares(GLOBAL_STATE); +} +void SYSTEM_notify_rejected_share(GlobalState * GLOBAL_STATE) +{ + SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; + + module->shares_rejected++; + _update_shares(GLOBAL_STATE); +} + +void SYSTEM_notify_mining_started(GlobalState * GLOBAL_STATE) +{ + SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; + + module->duration_start = esp_timer_get_time(); +} + +void SYSTEM_notify_new_ntime(GlobalState * GLOBAL_STATE, uint32_t ntime) +{ + SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; + + // Hourly clock sync + if (module->lastClockSync + (60 * 60) > ntime) { + return; + } + ESP_LOGI(TAG, "Syncing clock"); + module->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) +{ + 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->initial_ASIC_difficulty; + module->historical_hashrate_time_stamps[module->historical_hashrate_rolling_index] = esp_timer_get_time(); + + module->historical_hashrate_rolling_index = (module->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++; + } else { + module->duration_start = + module->historical_hashrate_time_stamps[(module->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]; + } + + double duration = (double) (esp_timer_get_time() - module->duration_start) / 1000000; + + double rolling_rate = (sum * 4294967296) / (duration * 1000000000); + if (module->historical_hashrate_init < HISTORY_LENGTH) { + module->current_hashrate = rolling_rate; + } else { + // More smoothing + module->current_hashrate = ((module->current_hashrate * 9) + rolling_rate) / 10; + } + + _update_hashrate(GLOBAL_STATE); + + // logArrayContents(historical_hashrate, HISTORY_LENGTH); + // logArrayContents(historical_hashrate_time_stamps, HISTORY_LENGTH); + + _check_for_best_diff(GLOBAL_STATE, found_diff, job_id); +} + + +/// +/// LOCAL FUNCTIONS +/// static void _show_overheat_screen(GlobalState * GLOBAL_STATE) { SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; @@ -544,152 +692,17 @@ static void _suffix_string(uint64_t val, char * buf, size_t bufsiz, int sigdigit } } -void SYSTEM_task(void * pvParameters) -{ - GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - _init_system(GLOBAL_STATE); - user_input_queue = xQueueCreate(10, sizeof(char[10])); // Create a queue to handle user input events - - _clear_display(GLOBAL_STATE); - _init_connection(GLOBAL_STATE); - - char input_event[10]; - ESP_LOGI(TAG, "SYSTEM_task started"); - - while (GLOBAL_STATE->ASIC_functions.init_fn == NULL) { - show_ap_information("ASIC MODEL INVALID", GLOBAL_STATE); - vTaskDelay(5000 / portTICK_PERIOD_MS); - } - - // show the connection screen - while (!module->startup_done) { - _update_connection(GLOBAL_STATE); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - - while (1) { - // Check for overheat mode - if (module->overheat_mode == 1) { - _show_overheat_screen(GLOBAL_STATE); - vTaskDelay(5000 / portTICK_PERIOD_MS); // Update every 5 seconds - SYSTEM_update_overheat_mode(GLOBAL_STATE); // Check for changes - continue; // Skip the normal screen cycle - } - - // Automatically cycle through screens - for (int screen = 0; screen < 3; screen++) { - _clear_display(GLOBAL_STATE); - module->screen_page = screen; - - switch (module->screen_page) { - case 0: - _update_system_performance(GLOBAL_STATE); - break; - case 1: - _update_system_info(GLOBAL_STATE); - break; - case 2: - _update_esp32_info(GLOBAL_STATE); - break; - } - - // Wait for 10 seconds or until a button press - for (int i = 0; i < 10; i++) { - if (xQueueReceive(user_input_queue, &input_event, pdMS_TO_TICKS(1000))) { - if (strcmp(input_event, "SHORT") == 0) { - ESP_LOGI(TAG, "Short button press detected, switching to next screen"); - screen = (screen + 1) % 3; // Move to next screen - break; - } else if (strcmp(input_event, "LONG") == 0) { - ESP_LOGI(TAG, "Long button press detected, toggling WiFi SoftAP"); - toggle_wifi_softap(); // Toggle AP - } - } - } - } - } -} - -void SYSTEM_notify_accepted_share(GlobalState * GLOBAL_STATE) -{ - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - module->shares_accepted++; - _update_shares(GLOBAL_STATE); -} -void SYSTEM_notify_rejected_share(GlobalState * GLOBAL_STATE) -{ - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - module->shares_rejected++; - _update_shares(GLOBAL_STATE); -} - -void SYSTEM_notify_mining_started(GlobalState * GLOBAL_STATE) -{ - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - module->duration_start = esp_timer_get_time(); -} - -void SYSTEM_notify_new_ntime(GlobalState * GLOBAL_STATE, uint32_t ntime) -{ - SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; - - // Hourly clock sync - if (module->lastClockSync + (60 * 60) > ntime) { - return; - } - ESP_LOGI(TAG, "Syncing clock"); - module->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) -{ - 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->initial_ASIC_difficulty; - module->historical_hashrate_time_stamps[module->historical_hashrate_rolling_index] = esp_timer_get_time(); - - module->historical_hashrate_rolling_index = (module->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++; - } else { - module->duration_start = - module->historical_hashrate_time_stamps[(module->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]; - } - - double duration = (double) (esp_timer_get_time() - module->duration_start) / 1000000; +static esp_err_t ensure_overheat_mode_config() { + uint16_t overheat_mode = nvs_config_get_u16(NVS_CONFIG_OVERHEAT_MODE, UINT16_MAX); - double rolling_rate = (sum * 4294967296) / (duration * 1000000000); - if (module->historical_hashrate_init < HISTORY_LENGTH) { - module->current_hashrate = rolling_rate; + if (overheat_mode == UINT16_MAX) { + // Key doesn't exist or couldn't be read, set the default value + nvs_config_set_u16(NVS_CONFIG_OVERHEAT_MODE, 0); + ESP_LOGI(TAG, "Default value for overheat_mode set to 0"); } else { - // More smoothing - module->current_hashrate = ((module->current_hashrate * 9) + rolling_rate) / 10; + // Key exists, log the current value + ESP_LOGI(TAG, "Existing overheat_mode value: %d", overheat_mode); } - _update_hashrate(GLOBAL_STATE); - - // logArrayContents(historical_hashrate, HISTORY_LENGTH); - // logArrayContents(historical_hashrate_time_stamps, HISTORY_LENGTH); - - _check_for_best_diff(GLOBAL_STATE, found_diff, job_id); + return ESP_OK; } diff --git a/main/system.h b/main/system.h index 27330ddc..d8782dc5 100644 --- a/main/system.h +++ b/main/system.h @@ -3,6 +3,7 @@ #include "global_state.h" +void SYSTEM_init_system(GlobalState * GLOBAL_STATE); void SYSTEM_task(void * parameters); void SYSTEM_notify_accepted_share(GlobalState * GLOBAL_STATE); @@ -11,4 +12,7 @@ void SYSTEM_notify_found_nonce(GlobalState * GLOBAL_STATE, double found_diff, ui void SYSTEM_notify_mining_started(GlobalState * GLOBAL_STATE); void SYSTEM_notify_new_ntime(GlobalState * GLOBAL_STATE, uint32_t ntime); +void SYSTEM_update_overheat_mode(GlobalState * GLOBAL_STATE); + + #endif /* SYSTEM_H_ */ diff --git a/main/tasks/power_management_task.c b/main/tasks/power_management_task.c index be019d1c..68a76b9b 100644 --- a/main/tasks/power_management_task.c +++ b/main/tasks/power_management_task.c @@ -116,7 +116,7 @@ void POWER_MANAGEMENT_task(void * pvParameters) default: } - vTaskDelay(4000 / portTICK_PERIOD_MS); + vTaskDelay(500 / portTICK_PERIOD_MS); uint16_t last_core_voltage = 0.0; uint16_t last_asic_frequency = power_management->frequency_value;