From 55b9960da73a8015eb00f19ab34e50b7ac6519df Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 13 Jun 2023 09:26:43 -0400 Subject: [PATCH] temperature protection init --- components/bm1397/bm1397.c | 26 ++++---- components/bm1397/include/bm1397.h | 9 +-- main/CMakeLists.txt | 1 + main/global_state.h | 3 +- main/miner.c | 4 +- main/system.c | 25 ++++--- main/tasks/power_management_task.c | 103 +++++++++++++++++++++++++++++ main/tasks/power_management_task.h | 16 +++++ 8 files changed, 155 insertions(+), 32 deletions(-) create mode 100644 main/tasks/power_management_task.c create mode 100644 main/tasks/power_management_task.h diff --git a/components/bm1397/bm1397.c b/components/bm1397/bm1397.c index 928dce6f..42d591df 100644 --- a/components/bm1397/bm1397.c +++ b/components/bm1397/bm1397.c @@ -27,11 +27,11 @@ static const char *TAG = "bm1397Module"; -/// @brief -/// @param ftdi -/// @param header -/// @param data -/// @param len +/// @brief +/// @param ftdi +/// @param header +/// @param data +/// @param len static void _send_BM1397(uint8_t header, uint8_t * data, uint8_t data_len, bool debug) { packet_type_t packet_type = (header & TYPE_JOB) ? JOB_PACKET : CMD_PACKET; uint8_t total_length = (packet_type == JOB_PACKET) ? (data_len+6) : (data_len+5); @@ -106,7 +106,7 @@ static int _largest_power_of_two(int num) { } // borrowed from cgminer driver-gekko.c calc_gsf_freq() -static void _send_hash_frequency(float frequency) { +void BM1397_send_hash_frequency(float frequency) { unsigned char prefreq1[9] = {0x00, 0x70, 0x0F, 0x0F, 0x0F, 0x00}; //prefreq - pll0_divider @@ -120,10 +120,10 @@ static void _send_hash_frequency(float frequency) { int i; //bound the frequency setting - if (frequency < 100) { - f1 = 100; - } else if (frequency > 800) { - f1 = 800; + if (frequency < 13) { + f1 = 13; + } else if (frequency > 500) { + f1 = 500; } else { f1 = frequency; } @@ -206,7 +206,7 @@ static void _send_init(void) { BM1397_set_default_baud(); - _send_hash_frequency(BM1397_FREQUENCY); + BM1397_send_hash_frequency(BM1397_FREQUENCY); } @@ -245,7 +245,7 @@ void BM1397_init(void) { //send the init command _send_read_address(); - + _send_init(); @@ -289,7 +289,7 @@ void BM1397_set_job_difficulty_mask(int difficulty){ //The char is read in backwards to the register so we need to reverse them //So a mask of 512 looks like 0b00000000 00000000 00000001 1111111 //and not 0b00000000 00000000 10000000 1111111 - + job_difficulty_mask[5 - i] = _reverse_bits(value); } diff --git a/components/bm1397/include/bm1397.h b/components/bm1397/include/bm1397.h index fc334752..b5f758e0 100644 --- a/components/bm1397/include/bm1397.h +++ b/components/bm1397/include/bm1397.h @@ -28,19 +28,19 @@ static const u_int64_t BM1397_CORE_COUNT = 672; static const u_int64_t BM1397_HASHRATE_S = BM1397_FREQUENCY * BM1397_CORE_COUNT * 1000000; //2^32 static const u_int64_t NONCE_SPACE = 4294967296; -static const double BM1397_FULLSCAN_MS = ((double)NONCE_SPACE / (double)BM1397_HASHRATE_S) * 1000; +static const double BM1397_FULLSCAN_MS = ((double)NONCE_SPACE / (double)BM1397_HASHRATE_S) * 1000; typedef struct { - + float frequency; } bm1397Module; typedef enum { - JOB_PACKET = 0, + JOB_PACKET = 0, CMD_PACKET = 1, } packet_type_t; typedef enum { - JOB_RESP = 0, + JOB_RESP = 0, CMD_RESP = 1, } response_type_t; @@ -72,5 +72,6 @@ void BM1397_send_work(struct job_packet *job); void BM1397_set_job_difficulty_mask(int); int BM1397_set_max_baud(void); void BM1397_set_default_baud(void); +void BM1397_send_hash_frequency(float frequency); #endif /* BM1397_H_ */ \ No newline at end of file diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 99f00b8c..6cf71825 100755 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -14,6 +14,7 @@ SRCS "./tasks/create_jobs_task.c" "./tasks/asic_task.c" "./tasks/asic_result_task.c" + "./tasks/power_management_task.c" INCLUDE_DIRS "." "tasks" diff --git a/main/global_state.h b/main/global_state.h index 7e6c4a7a..c15be9c6 100644 --- a/main/global_state.h +++ b/main/global_state.h @@ -6,7 +6,7 @@ #include "system.h" #include "stratum_api.h" #include "asic_task.h" - +#include "power_management_task.h" #define STRATUM_USER CONFIG_STRATUM_USER @@ -19,6 +19,7 @@ typedef struct { bm1397Module BM1397_MODULE; SystemModule SYSTEM_MODULE; AsicTaskModule ASIC_TASK_MODULE; + PowerManagementModule POWER_MANAGEMENT_MODULE; char * extranonce_str; diff --git a/main/miner.c b/main/miner.c index 444a8151..592fe151 100755 --- a/main/miner.c +++ b/main/miner.c @@ -32,7 +32,7 @@ void app_main(void) //ESP_ERROR_CHECK(esp_netif_init()); //ESP_ERROR_CHECK(esp_event_loop_create_default()); - xTaskCreate(SYSTEM_task, "SYSTEM_task", 4096, (void*)&GLOBAL_STATE.SYSTEM_MODULE, 10, NULL); + xTaskCreate(SYSTEM_task, "SYSTEM_task", 4096, (void*)&GLOBAL_STATE, 3, NULL); ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); wifi_init_sta(); @@ -46,7 +46,9 @@ void app_main(void) xTaskCreate(stratum_task, "stratum admin", 8192, (void*)&GLOBAL_STATE, 5, NULL); xTaskCreate(create_jobs_task, "stratum miner", 8192, (void*)&GLOBAL_STATE, 10, NULL); + xTaskCreate(POWER_MANAGEMENT_task, "power mangement", 8192, (void*)&GLOBAL_STATE, 10, NULL); xTaskCreate(ASIC_task, "asic", 8192, (void*)&GLOBAL_STATE, 10, NULL); xTaskCreate(ASIC_result_task, "asic result", 8192, (void*)&GLOBAL_STATE, 15, NULL); + } diff --git a/main/system.c b/main/system.c index 019ea00a..585f1845 100644 --- a/main/system.c +++ b/main/system.c @@ -16,6 +16,7 @@ #include #include #include +#include "global_state.h" static const char *TAG = "SystemModule"; @@ -117,31 +118,27 @@ static void _clear_display(void){ } -static void _update_system_info(SystemModule* module) { +static void _update_system_info(GlobalState *GLOBAL_STATE) { - - uint16_t fan_speed = EMC2101_get_fan_speed(); - float chip_temp = EMC2101_get_chip_temp(); - float voltage = INA260_read_voltage(); - float power = INA260_read_power() / 1000; - float current = INA260_read_current(); + SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE; + PowerManagementModule * power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE; if (OLED_status()) { memset(module->oled_buf, 0, 20); - snprintf(module->oled_buf, 20, " Fan: %d RPM", fan_speed); + snprintf(module->oled_buf, 20, " Fan: %d RPM", power_management->fan_speed); OLED_writeString(0, 0, module->oled_buf); memset(module->oled_buf, 0, 20); - snprintf(module->oled_buf, 20, "Temp: %.1f C", chip_temp); + snprintf(module->oled_buf, 20, "Temp: %.1f C", power_management->chip_temp); OLED_writeString(0, 1, module->oled_buf); memset(module->oled_buf, 0, 20); - snprintf(module->oled_buf, 20, " Pwr: %.3f W", power); + snprintf(module->oled_buf, 20, " Pwr: %.3f W", power_management->power); OLED_writeString(0, 2, module->oled_buf); memset(module->oled_buf, 0, 20); - snprintf(module->oled_buf, 20, " %i mV: %i mA",(int)voltage, (int)current); + snprintf(module->oled_buf, 20, " %i mV: %i mA",(int)power_management->voltage, (int)power_management->current); OLED_writeString(0, 3, module->oled_buf); } @@ -222,7 +219,9 @@ static void _check_for_best_diff(SystemModule * module, double diff, uint32_t nb void SYSTEM_task(void *pvParameters) { - SystemModule *module = (SystemModule*)pvParameters; + GlobalState *GLOBAL_STATE = (GlobalState*)pvParameters; + SystemModule *module = &GLOBAL_STATE->SYSTEM_MODULE; + _init_system(module); while(1){ @@ -233,7 +232,7 @@ void SYSTEM_task(void *pvParameters) { _clear_display(); module->screen_page = 1; - _update_system_info(module); + _update_system_info(GLOBAL_STATE); vTaskDelay(10000 / portTICK_RATE_MS); _clear_display(); diff --git a/main/tasks/power_management_task.c b/main/tasks/power_management_task.c new file mode 100644 index 00000000..e81aa945 --- /dev/null +++ b/main/tasks/power_management_task.c @@ -0,0 +1,103 @@ +#include "global_state.h" +#include +#include "esp_log.h" +#include "mining.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "bm1397.h" +#include "EMC2101.h" +#include "INA260.h" +#include "math.h" + +#define POLL_RATE 1000/60 +#define MAX_TEMP 90.0 +#define THROTTLE_TEMP 70.0 +#define THROTTLE_TEMP_RANGE (MAX_TEMP - THROTTLE_TEMP) + +static const char * TAG = "power_management"; + +static float _fbound(float value, float lower_bound, float upper_bound) +{ + if (value < lower_bound) + return lower_bound; + if (value > upper_bound) + return upper_bound; + + return value; +} + +void _power_init(PowerManagementModule * power_management){ + power_management->frequency_multiplier = 1; + power_management->frequency_value = BM1397_FREQUENCY; + +} + +void POWER_MANAGEMENT_task(void * pvParameters){ + + GlobalState *GLOBAL_STATE = (GlobalState*)pvParameters; + //bm1397Module * bm1397 = &GLOBAL_STATE->BM1397_MODULE; + PowerManagementModule * power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE; + _power_init(power_management); + + int last_frequency_increase = 0; + while(1){ + power_management->fan_speed = EMC2101_get_fan_speed(); + power_management->chip_temp = EMC2101_get_chip_temp(); + power_management->voltage = INA260_read_voltage(); + power_management->power = INA260_read_power() / 1000; + power_management->current = INA260_read_current(); + + float old_multiplier = power_management->frequency_multiplier; + float old_frequency = power_management->frequency_value; + + + //float voltage_multiplier = _fbound((power_management->voltage - 4.5) * 2, 0, 1); + + // power_management->frequency_multiplier = voltage_multiplier; + + + + float temperature_multiplier = 1; + float over_temp = -(THROTTLE_TEMP - power_management->chip_temp); + if(over_temp > 0){ + temperature_multiplier = (THROTTLE_TEMP_RANGE - over_temp)/THROTTLE_TEMP_RANGE; + } + + power_management->frequency_multiplier = temperature_multiplier; + + + + float target_frequency = _fbound(power_management->frequency_multiplier * BM1397_FREQUENCY, 0, BM1397_FREQUENCY); + + if(target_frequency < 13){ + // TODO: Turn the chip off + } + + + if(power_management->frequency_value > target_frequency){ + power_management->frequency_value = target_frequency; + last_frequency_increase = 0; + BM1397_send_hash_frequency(power_management->frequency_value); + ESP_LOGI(TAG, "target %f, Freq %f, Temp %f, Power %f", target_frequency, power_management->frequency_value, power_management->chip_temp, power_management->power); + }else{ + if( + last_frequency_increase > 250 && + power_management->frequency_value != BM1397_FREQUENCY + ){ + float add = power_management->frequency_value - (((power_management->frequency_value * 29.0) + target_frequency)/30.0); + power_management->frequency_value += _fbound(add, 2 , 10); + BM1397_send_hash_frequency(power_management->frequency_value); + ESP_LOGI(TAG, "target %f, Freq %f, Temp %f, Power %f", target_frequency, power_management->frequency_value, power_management->chip_temp, power_management->power); + last_frequency_increase = 125; + }else{ + last_frequency_increase++; + } + } + + + + + //ESP_LOGI(TAG, "target %f, Freq %f, Temp %f, Power %f", target_frequency, power_management->frequency_value, power_management->chip_temp, power_management->power); + vTaskDelay(POLL_RATE / portTICK_RATE_MS); + } +} \ No newline at end of file diff --git a/main/tasks/power_management_task.h b/main/tasks/power_management_task.h new file mode 100644 index 00000000..d38f6561 --- /dev/null +++ b/main/tasks/power_management_task.h @@ -0,0 +1,16 @@ +#ifndef POWER_MANAGEMENT_TASK_H_ +#define POWER_MANAGEMENT_TASK_H_ + +typedef struct { + uint16_t fan_speed; + float chip_temp; + float voltage; + float frequency_multiplier; + float frequency_value; + float power; + float current; +} PowerManagementModule; + +void POWER_MANAGEMENT_task(void * pvParameters); + +#endif \ No newline at end of file