Add IP address to display and allow editing of voltage, frequency from AxeOS

This commit is contained in:
Ben 2023-09-17 00:01:54 -04:00
parent ed67d44a54
commit a4c473188b
16 changed files with 459 additions and 568 deletions

View File

@ -1,44 +1,44 @@
#ifndef BM1366_H_
#define BM1366_H_
#include "common.h"
#include "driver/gpio.h"
#include "mining.h"
#include "common.h"
#define CRC5_MASK 0x1F
static const u_int64_t BM1366_FREQUENCY = CONFIG_ASIC_FREQUENCY;
// static const u_int64_t BM1366_FREQUENCY = CONFIG_ASIC_FREQUENCY;
static const u_int64_t BM1366_CORE_COUNT = 672;
static const u_int64_t BM1366_HASHRATE_S = BM1366_FREQUENCY * BM1366_CORE_COUNT * 1000000;
// 2^32
// static const u_int64_t NONCE_SPACE = 4294967296;
// static const u_int64_t BM1366_HASHRATE_S = BM1366_FREQUENCY * BM1366_CORE_COUNT * 1000000;
// 2^32
// static const u_int64_t NONCE_SPACE = 4294967296;
static const double BM1366_FULLSCAN_MS = 2140;
typedef struct
{
float frequency;
float frequency;
} bm1366Module;
typedef struct __attribute__((__packed__))
{
uint8_t job_id;
uint8_t num_midstates;
uint8_t starting_nonce[4];
uint8_t nbits[4];
uint8_t ntime[4];
uint8_t merkle_root[32];
uint8_t prev_block_hash[32];
uint8_t version[4];
uint8_t job_id;
uint8_t num_midstates;
uint8_t starting_nonce[4];
uint8_t nbits[4];
uint8_t ntime[4];
uint8_t merkle_root[32];
uint8_t prev_block_hash[32];
uint8_t version[4];
} BM1366_job;
void BM1366_init(u_int64_t frequency);
void BM1366_send_init(void);
void BM1366_send_work(void *GLOBAL_STATE, bm_job *next_bm_job);
void BM1366_send_work(void * GLOBAL_STATE, bm_job * next_bm_job);
void BM1366_set_job_difficulty_mask(int);
int BM1366_set_max_baud(void);
int BM1366_set_default_baud(void);
void BM1366_send_hash_frequency(float frequency);
task_result *BM1366_proccess_work(void *GLOBAL_STATE);
task_result * BM1366_proccess_work(void * GLOBAL_STATE);
#endif /* BM1366_H_ */

View File

@ -1,57 +1,57 @@
#ifndef BM1397_H_
#define BM1397_H_
#include "common.h"
#include "driver/gpio.h"
#include "mining.h"
#include "common.h"
#define CRC5_MASK 0x1F
static const u_int64_t ASIC_FREQUENCY = CONFIG_ASIC_FREQUENCY;
// static const u_int64_t ASIC_FREQUENCY = CONFIG_ASIC_FREQUENCY;
static const u_int64_t BM1397_CORE_COUNT = 672;
static const u_int64_t BM1397_HASHRATE_S = ASIC_FREQUENCY * BM1397_CORE_COUNT * 1000000;
// 2^32
// static const u_int64_t BM1397_HASHRATE_S = ASIC_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;
float frequency;
} bm1397Module;
typedef enum
{
JOB_PACKET = 0,
CMD_PACKET = 1,
JOB_PACKET = 0,
CMD_PACKET = 1,
} packet_type_t;
typedef enum
{
JOB_RESP = 0,
CMD_RESP = 1,
JOB_RESP = 0,
CMD_RESP = 1,
} response_type_t;
typedef struct __attribute__((__packed__))
{
uint8_t job_id;
uint8_t num_midstates;
uint8_t starting_nonce[4];
uint8_t nbits[4];
uint8_t ntime[4];
uint8_t merkle4[4];
uint8_t midstate[32];
uint8_t midstate1[32];
uint8_t midstate2[32];
uint8_t midstate3[32];
uint8_t job_id;
uint8_t num_midstates;
uint8_t starting_nonce[4];
uint8_t nbits[4];
uint8_t ntime[4];
uint8_t merkle4[4];
uint8_t midstate[32];
uint8_t midstate1[32];
uint8_t midstate2[32];
uint8_t midstate3[32];
} job_packet;
void BM1397_init(u_int64_t frequency);
void BM1397_send_work(void *GLOBAL_STATE, bm_job *next_bm_job);
void BM1397_send_work(void * GLOBAL_STATE, bm_job * next_bm_job);
void BM1397_set_job_difficulty_mask(int);
int BM1397_set_max_baud(void);
int BM1397_set_default_baud(void);
void BM1397_send_hash_frequency(float frequency);
task_result *BM1397_proccess_work(void *GLOBAL_STATE);
task_result * BM1397_proccess_work(void * GLOBAL_STATE);
#endif /* BM1397_H_ */

View File

@ -1,16 +1,16 @@
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/lwip_napt.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"
#include "lwip/err.h"
#include "lwip/lwip_napt.h"
#include "lwip/sys.h"
#include "nvs_flash.h"
#include <string.h>
#include "connect.h"
#include "main.h"
@ -49,60 +49,54 @@
/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;
static const char *TAG = "wifi station";
static const char * TAG = "wifi station";
static int s_retry_num = 0;
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
static void event_handler(void * arg, esp_event_base_t event_base, int32_t event_id, void * event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
// Wait a little
vTaskDelay(1000 / portTICK_PERIOD_MS);
if (s_retry_num < WIFI_MAXIMUM_RETRY)
{
if (s_retry_num < WIFI_MAXIMUM_RETRY) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
ESP_LOGI(TAG, "Retrying WiFi connection...");
MINER_set_wifi_status(WIFI_RETRYING, s_retry_num);
}
else
{
} else {
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
ESP_LOGI(TAG, "connect to the AP fail");
ESP_LOGI(TAG, "Could not connect to WiFi.");
MINER_set_wifi_status(WIFI_CONNECT_FAILED, 0);
}
}
else 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;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
} else 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;
ESP_LOGI(TAG, "Bitaxe ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
esp_netif_t *wifi_init_softap(void)
esp_netif_t * wifi_init_softap(void)
{
esp_netif_t *esp_netif_ap = esp_netif_create_default_wifi_ap();
esp_netif_t * esp_netif_ap = esp_netif_create_default_wifi_ap();
wifi_config_t wifi_ap_config = {
.ap = {
.ssid = "Bitaxe",
.ssid_len = strlen("Bitaxe"),
.channel = 1,
.max_connection = 30,
.authmode = WIFI_AUTH_OPEN,
.pmf_cfg = {
.required = false,
.ap =
{
.ssid = "Bitaxe",
.ssid_len = strlen("Bitaxe"),
.channel = 1,
.max_connection = 30,
.authmode = WIFI_AUTH_OPEN,
.pmf_cfg =
{
.required = false,
},
},
},
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_ap_config));
@ -115,13 +109,10 @@ void toggle_wifi_softap(void)
wifi_mode_t mode = WIFI_MODE_NULL;
ESP_ERROR_CHECK(esp_wifi_get_mode(&mode));
if (mode == WIFI_MODE_APSTA)
{
if (mode == WIFI_MODE_APSTA) {
ESP_LOGI(TAG, "ESP_WIFI Access Point Off");
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
}
else
{
} else {
ESP_LOGI(TAG, "ESP_WIFI Access Point On");
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA));
}
@ -134,25 +125,26 @@ void wifi_softap_off(void)
}
/* Initialize wifi station */
esp_netif_t *wifi_init_sta(const char *wifi_ssid, const char *wifi_pass)
esp_netif_t * wifi_init_sta(const char * wifi_ssid, const char * wifi_pass)
{
esp_netif_t *esp_netif_sta = esp_netif_create_default_wifi_sta();
esp_netif_t * esp_netif_sta = esp_netif_create_default_wifi_sta();
wifi_config_t wifi_sta_config = {
.sta = {
/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
*/
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
// .sae_pwe_h2e = ESP_WIFI_SAE_MODE,
// .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER,
},
.sta =
{
/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
*/
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
// .sae_pwe_h2e = ESP_WIFI_SAE_MODE,
// .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER,
},
};
strncpy((char *)wifi_sta_config.sta.ssid, wifi_ssid, 31);
strncpy((char *) wifi_sta_config.sta.ssid, wifi_ssid, 31);
wifi_sta_config.sta.ssid[31] = '\0';
strncpy((char *)wifi_sta_config.sta.password, wifi_pass, 63);
strncpy((char *) wifi_sta_config.sta.password, wifi_pass, 63);
wifi_sta_config.sta.password[63] = '\0';
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_sta_config));
@ -162,7 +154,7 @@ esp_netif_t *wifi_init_sta(const char *wifi_ssid, const char *wifi_pass)
return esp_netif_sta;
}
void wifi_init(const char *wifi_ssid, const char *wifi_pass)
void wifi_init(const char * wifi_ssid, const char * wifi_pass)
{
s_wifi_event_group = xEventGroupCreate();
@ -182,11 +174,11 @@ void wifi_init(const char *wifi_ssid, const char *wifi_pass)
/* Initialize AP */
ESP_LOGI(TAG, "ESP_WIFI Access Point On");
esp_netif_t *esp_netif_ap = wifi_init_softap();
esp_netif_t * esp_netif_ap = wifi_init_softap();
/* Initialize STA */
ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
esp_netif_t *esp_netif_sta = wifi_init_sta(wifi_ssid, wifi_pass);
esp_netif_t * esp_netif_sta = wifi_init_sta(wifi_ssid, wifi_pass);
/* Start WiFi */
ESP_ERROR_CHECK(esp_wifi_start());
@ -200,11 +192,7 @@ EventBits_t wifi_connect(void)
{
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
* happened. */

View File

@ -1,8 +1,8 @@
#pragma once
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include <arpa/inet.h>
#include <lwip/netdb.h>
#include "freertos/event_groups.h"
@ -30,5 +30,5 @@ typedef enum
void toggle_wifi_softap(void);
void wifi_softap_off(void);
void wifi_init(const char *wifi_ssid, const char *wifi_pass);
void wifi_init(const char * wifi_ssid, const char * wifi_pass);
EventBits_t wifi_connect(void);

View File

@ -1,5 +1,8 @@
<div class="button-row">
<button (click)="restart()" class="btn btn-danger restart">Restart</button>
</div>
<div class="card">
<h2>Edit</h2>
<h2>Settings</h2>
<ng-container *ngIf="form != null">
<form [formGroup]="form">
<div class="form-group">
@ -22,13 +25,21 @@
<label>Stratum User: </label>
<input formControlName="stratumUser" type="text">
</div>
<div class="form-group">
<label>Frequency </label>
<input formControlName="frequency" type="number">
</div>
<div class="form-group">
<label>Core Voltage</label>
<input formControlName="coreVoltage" type="number">
</div>
</form>
</ng-container>
<div>You must restart this device after saving for changes to take effect.</div>
<div class="mt-2">
<button (click)="updateSystem()" class="btn btn-primary mr-2">Save</button>
<button [routerLink]="['/']" class="btn btn-secondary">Cancel</button>
</div>

View File

@ -1,3 +1,8 @@
input {
min-width: 500px
}
.restart {
margin-bottom: 1.5rem;
}

View File

@ -33,6 +33,8 @@ export class EditComponent {
stratumUser: [info.stratumUser, [Validators.required]],
ssid: [info.ssid, [Validators.required]],
wifiPass: [info.wifiPass, [Validators.required]],
coreVoltage: [info.coreVoltage, [Validators.required]],
frequency: [info.frequency, [Validators.required]],
});
});
}
@ -115,4 +117,11 @@ export class EditComponent {
}
});
}
public restart() {
this.systemService.restart().subscribe(res => {
});
this.toastr.success('Success!', 'Bitaxe restarted');
}
}

View File

@ -3,7 +3,7 @@
</ng-template>
<ng-container>
<div class="button-row">
<button [routerLink]="['edit']" class="btn btn-primary edit">Edit</button>
<button [routerLink]="['edit']" class="btn btn-primary edit">Settings</button>
<button (click)="restart()" class="btn btn-danger restart">Restart</button>
</div>
@ -82,10 +82,17 @@
<td>{{info.current | number: '0.0-0'}} <small>mA</small></td>
</tr>
<tr>
<td>Frequency:</td>
<td>{{info.frequency}} <small>Mhz</small></td>
</tr>
<tr>
<td>Core Voltage:</td>
<td>{{info.coreVoltage}} <small>mV</small></td>
</tr>
<tr>
<td>Measured Core Voltage:</td>
<td>{{info.coreVoltageActual}} <small>mV</small></td>
</tr>
<tr>
<td>Fan Speed:</td>
@ -105,9 +112,13 @@
<table *ngIf="info$ | async as info; else loading">
<tr>
<td> Hash Rate:</td>
<td>{{info.hashRate | number: '1.2-2'}}Gh/s</td>
<td>{{info.hashRate | number: '1.2-2'}} <small>Gh/s</small></td>
</tr>
<tr>
<td>Efficiency:</td>
<td>{{info.power / (info.hashRate/1000) | number: '1.2-2'}} <small>W/Th</small></td>
</tr>
<tr>
<td>Best Difficulty:</td>
<td>{{info.bestDiff}}</td>

View File

@ -25,6 +25,7 @@ table>tr>td {
.edit {
margin-bottom: 1.5rem;
margin-right: 1.5rem;
}
@ -33,10 +34,7 @@ table>tr>td {
}
.button-row {
display: flex;
justify-content: space-between;
}
#logs {
height: 500px;

View File

@ -38,7 +38,8 @@ export class SystemService {
"ASICModel": "BM1366",
"stratumURL": "192.168.1.242",
"stratumPort": 3333,
"stratumUser": "bc1q99n3pu025yyu0jlywpmwzalyhm36tg5u37w20d.bitaxe-U1"
"stratumUser": "bc1q99n3pu025yyu0jlywpmwzalyhm36tg5u37w20d.bitaxe-U1",
"frequency": 485
}
).pipe(delay(1000));
}

View File

@ -18,5 +18,6 @@ export interface ISystemInfo {
ASICModel: string,
stratumURL: string,
stratumPort: number,
stratumUser: string
stratumUser: string,
frequency: number
}

View File

@ -1,49 +1,46 @@
#include "http_server.h"
#include "global_state.h"
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include <string.h>
#include <fcntl.h>
#include "esp_http_server.h"
#include "esp_chip_info.h"
#include "esp_random.h"
#include "esp_log.h"
#include "esp_vfs.h"
#include "cJSON.h"
#include "esp_spiffs.h"
#include "esp_log.h"
#include "adc.h"
#include "cJSON.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_vfs.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"
#include "global_state.h"
#include "nvs_config.h"
#include <fcntl.h>
#include <string.h>
#include <sys/param.h>
#include "esp_netif.h"
#include "esp_mac.h"
#include "esp_netif.h"
#include "esp_ota_ops.h"
#include "esp_wifi.h"
#include "lwip/err.h"
#include "lwip/inet.h"
#include "lwip/lwip_napt.h"
#include "lwip/netdb.h"
#include "lwip/sockets.h"
#include "lwip/lwip_napt.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "esp_ota_ops.h"
static const char *TAG = "http_server";
static const char * TAG = "http_server";
static GlobalState *GLOBAL_STATE;
static GlobalState * GLOBAL_STATE;
static httpd_handle_t server = NULL;
static int fd = -1;
#define REST_CHECK(a, str, goto_tag, ...) \
do \
{ \
if (!(a)) \
{ \
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
goto goto_tag; \
} \
#define REST_CHECK(a, str, goto_tag, ...) \
do { \
if (!(a)) { \
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
goto goto_tag; \
} \
} while (0)
#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + 128)
@ -59,25 +56,15 @@ typedef struct rest_server_context
esp_err_t init_fs(void)
{
esp_vfs_spiffs_conf_t conf = {
.base_path = "",
.partition_label = NULL,
.max_files = 5,
.format_if_mount_failed = false};
esp_vfs_spiffs_conf_t conf = {.base_path = "", .partition_label = NULL, .max_files = 5, .format_if_mount_failed = false};
esp_err_t ret = esp_vfs_spiffs_register(&conf);
if (ret != ESP_OK)
{
if (ret == ESP_FAIL)
{
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount or format filesystem");
}
else if (ret == ESP_ERR_NOT_FOUND)
{
} else if (ret == ESP_ERR_NOT_FOUND) {
ESP_LOGE(TAG, "Failed to find SPIFFS partition");
}
else
{
} else {
ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
}
return ESP_FAIL;
@ -85,12 +72,9 @@ esp_err_t init_fs(void)
size_t total = 0, used = 0;
ret = esp_spiffs_info(NULL, &total, &used);
if (ret != ESP_OK)
{
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret));
}
else
{
} else {
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
}
return ESP_OK;
@ -99,66 +83,50 @@ esp_err_t init_fs(void)
/* Function for stopping the webserver */
void stop_webserver(httpd_handle_t server)
{
if (server)
{
if (server) {
/* Stop the httpd server */
httpd_stop(server);
}
}
/* Set HTTP response content type according to file extension */
static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filepath)
static esp_err_t set_content_type_from_file(httpd_req_t * req, const char * filepath)
{
const char *type = "text/plain";
if (CHECK_FILE_EXTENSION(filepath, ".html"))
{
const char * type = "text/plain";
if (CHECK_FILE_EXTENSION(filepath, ".html")) {
type = "text/html";
}
else if (CHECK_FILE_EXTENSION(filepath, ".js"))
{
} else if (CHECK_FILE_EXTENSION(filepath, ".js")) {
type = "application/javascript";
}
else if (CHECK_FILE_EXTENSION(filepath, ".css"))
{
} else if (CHECK_FILE_EXTENSION(filepath, ".css")) {
type = "text/css";
}
else if (CHECK_FILE_EXTENSION(filepath, ".png"))
{
} else if (CHECK_FILE_EXTENSION(filepath, ".png")) {
type = "image/png";
}
else if (CHECK_FILE_EXTENSION(filepath, ".ico"))
{
} else if (CHECK_FILE_EXTENSION(filepath, ".ico")) {
type = "image/x-icon";
}
else if (CHECK_FILE_EXTENSION(filepath, ".svg"))
{
} else if (CHECK_FILE_EXTENSION(filepath, ".svg")) {
type = "text/xml";
}
return httpd_resp_set_type(req, type);
}
/* Send HTTP response with the contents of the requested file */
static esp_err_t rest_common_get_handler(httpd_req_t *req)
static esp_err_t rest_common_get_handler(httpd_req_t * req)
{
char filepath[FILE_PATH_MAX];
uint8_t filePathLength = sizeof(filepath);
rest_server_context_t *rest_context = (rest_server_context_t *)req->user_ctx;
rest_server_context_t * rest_context = (rest_server_context_t *) req->user_ctx;
strlcpy(filepath, rest_context->base_path, filePathLength);
if (req->uri[strlen(req->uri) - 1] == '/')
{
if (req->uri[strlen(req->uri) - 1] == '/') {
strlcat(filepath, "/index.html", filePathLength);
}
else
{
} else {
httpd_resp_set_hdr(req, "Cache-Control", "max-age=2592000");
strlcat(filepath, req->uri, filePathLength);
}
set_content_type_from_file(req, filepath);
strcat(filepath, ".gz");
int fd = open(filepath, O_RDONLY, 0);
if (fd == -1)
{
if (fd == -1) {
ESP_LOGE(TAG, "Failed to open file : %s", filepath);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
@ -167,21 +135,16 @@ static esp_err_t rest_common_get_handler(httpd_req_t *req)
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
char *chunk = rest_context->scratch;
char * chunk = rest_context->scratch;
ssize_t read_bytes;
do
{
do {
/* Read file in chunks into the scratch buffer */
read_bytes = read(fd, chunk, SCRATCH_BUFSIZE);
if (read_bytes == -1)
{
if (read_bytes == -1) {
ESP_LOGE(TAG, "Failed to read file : %s", filepath);
}
else if (read_bytes > 0)
{
} else if (read_bytes > 0) {
/* Send the buffer contents as HTTP response chunk */
if (httpd_resp_send_chunk(req, chunk, read_bytes) != ESP_OK)
{
if (httpd_resp_send_chunk(req, chunk, read_bytes) != ESP_OK) {
close(fd);
ESP_LOGE(TAG, "File sending failed!");
/* Abort sending file */
@ -200,23 +163,20 @@ static esp_err_t rest_common_get_handler(httpd_req_t *req)
return ESP_OK;
}
static esp_err_t PATCH_update_settings(httpd_req_t *req)
static esp_err_t PATCH_update_settings(httpd_req_t * req)
{
int total_len = req->content_len;
int cur_len = 0;
char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch;
char * buf = ((rest_server_context_t *) (req->user_ctx))->scratch;
int received = 0;
if (total_len >= SCRATCH_BUFSIZE)
{
if (total_len >= SCRATCH_BUFSIZE) {
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "content too long");
return ESP_FAIL;
}
while (cur_len < total_len)
{
while (cur_len < total_len) {
received = httpd_req_recv(req, buf + cur_len, total_len);
if (received <= 0)
{
if (received <= 0) {
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to post control value");
return ESP_FAIL;
@ -225,32 +185,37 @@ static esp_err_t PATCH_update_settings(httpd_req_t *req)
}
buf[total_len] = '\0';
cJSON *root = cJSON_Parse(buf);
char *stratumURL = cJSON_GetObjectItem(root, "stratumURL")->valuestring;
char *stratumUser = cJSON_GetObjectItem(root, "stratumUser")->valuestring;
cJSON * root = cJSON_Parse(buf);
char * stratumURL = cJSON_GetObjectItem(root, "stratumURL")->valuestring;
char * stratumUser = cJSON_GetObjectItem(root, "stratumUser")->valuestring;
uint16_t stratumPort = cJSON_GetObjectItem(root, "stratumPort")->valueint;
char *ssid = cJSON_GetObjectItem(root, "ssid")->valuestring;
char *wifiPass = cJSON_GetObjectItem(root, "wifiPass")->valuestring;
char * ssid = cJSON_GetObjectItem(root, "ssid")->valuestring;
char * wifiPass = cJSON_GetObjectItem(root, "wifiPass")->valuestring;
uint16_t coreVoltage = cJSON_GetObjectItem(root, "coreVoltage")->valueint;
uint16_t frequency = cJSON_GetObjectItem(root, "frequency")->valueint;
nvs_config_set_string(NVS_CONFIG_STRATUM_URL, stratumURL);
nvs_config_set_string(NVS_CONFIG_STRATUM_USER, stratumUser);
nvs_config_set_u16(NVS_CONFIG_STRATUM_PORT, stratumPort);
nvs_config_set_string(NVS_CONFIG_WIFI_SSID, ssid);
nvs_config_set_string(NVS_CONFIG_WIFI_PASS, wifiPass);
nvs_config_set_u16(NVS_CONFIG_ASIC_VOLTAGE, coreVoltage);
nvs_config_set_u16(NVS_CONFIG_ASIC_FREQ, frequency);
cJSON_Delete(root);
httpd_resp_send_chunk(req, NULL, 0);
return ESP_OK;
}
static esp_err_t POST_restart(httpd_req_t *req)
static esp_err_t POST_restart(httpd_req_t * req)
{
esp_restart();
return ESP_OK;
}
/* Simple handler for getting system handler */
static esp_err_t GET_system_info(httpd_req_t *req)
static esp_err_t GET_system_info(httpd_req_t * req)
{
httpd_resp_set_type(req, "application/json");
@ -260,12 +225,12 @@ static esp_err_t GET_system_info(httpd_req_t *req)
httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type");
httpd_resp_set_hdr(req, "Access-Control-Allow-Credentials", "true");
char *ssid = nvs_config_get_string(NVS_CONFIG_WIFI_SSID, CONFIG_ESP_WIFI_SSID);
char *wifiPass = nvs_config_get_string(NVS_CONFIG_WIFI_PASS, CONFIG_ESP_WIFI_PASSWORD);
char *stratumURL = nvs_config_get_string(NVS_CONFIG_STRATUM_URL, CONFIG_STRATUM_URL);
char *stratumUser = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, CONFIG_STRATUM_USER);
char * ssid = nvs_config_get_string(NVS_CONFIG_WIFI_SSID, CONFIG_ESP_WIFI_SSID);
char * wifiPass = nvs_config_get_string(NVS_CONFIG_WIFI_PASS, CONFIG_ESP_WIFI_PASSWORD);
char * stratumURL = nvs_config_get_string(NVS_CONFIG_STRATUM_URL, CONFIG_STRATUM_URL);
char * stratumUser = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, CONFIG_STRATUM_USER);
cJSON *root = cJSON_CreateObject();
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", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.current);
@ -275,7 +240,9 @@ static esp_err_t GET_system_info(httpd_req_t *req)
cJSON_AddStringToObject(root, "bestDiff", GLOBAL_STATE->SYSTEM_MODULE.best_diff_string);
cJSON_AddNumberToObject(root, "freeHeap", esp_get_free_heap_size());
cJSON_AddNumberToObject(root, "coreVoltage", ADC_get_vcore());
cJSON_AddNumberToObject(root, "coreVoltage", nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE));
cJSON_AddNumberToObject(root, "coreVoltageActual", ADC_get_vcore());
cJSON_AddNumberToObject(root, "frequency", nvs_config_get_u16(NVS_CONFIG_ASIC_FREQ, CONFIG_ASIC_FREQUENCY));
cJSON_AddStringToObject(root, "ssid", ssid);
cJSON_AddStringToObject(root, "wifiPass", wifiPass);
cJSON_AddStringToObject(root, "wifiStatus", GLOBAL_STATE->SYSTEM_MODULE.wifi_status);
@ -292,21 +259,21 @@ static esp_err_t GET_system_info(httpd_req_t *req)
free(stratumURL);
free(stratumUser);
const char *sys_info = cJSON_Print(root);
const char * sys_info = cJSON_Print(root);
httpd_resp_sendstr(req, sys_info);
free(sys_info);
cJSON_Delete(root);
return ESP_OK;
}
esp_err_t POST_WWW_update(httpd_req_t *req)
esp_err_t POST_WWW_update(httpd_req_t * req)
{
char buf[1000];
int remaining = req->content_len;
const esp_partition_t *www_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, "www");
if (www_partition == NULL)
{
const esp_partition_t * www_partition =
esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, "www");
if (www_partition == NULL) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "WWW partition not found");
return ESP_FAIL;
}
@ -314,22 +281,17 @@ esp_err_t POST_WWW_update(httpd_req_t *req)
// Erase the entire www partition before writing
ESP_ERROR_CHECK(esp_partition_erase_range(www_partition, 0, www_partition->size));
while (remaining > 0)
{
while (remaining > 0) {
int recv_len = httpd_req_recv(req, buf, MIN(remaining, sizeof(buf)));
if (recv_len == HTTPD_SOCK_ERR_TIMEOUT)
{
if (recv_len == HTTPD_SOCK_ERR_TIMEOUT) {
continue;
}
else if (recv_len <= 0)
{
} else if (recv_len <= 0) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Protocol Error");
return ESP_FAIL;
}
if (esp_partition_write(www_partition, www_partition->size - remaining, (const void *)buf, recv_len) != ESP_OK)
{
if (esp_partition_write(www_partition, www_partition->size - remaining, (const void *) buf, recv_len) != ESP_OK) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Write Error");
return ESP_FAIL;
}
@ -344,35 +306,30 @@ esp_err_t POST_WWW_update(httpd_req_t *req)
/*
* Handle OTA file upload
*/
esp_err_t POST_OTA_update(httpd_req_t *req)
esp_err_t POST_OTA_update(httpd_req_t * req)
{
char buf[1000];
esp_ota_handle_t ota_handle;
int remaining = req->content_len;
const esp_partition_t *ota_partition = esp_ota_get_next_update_partition(NULL);
const esp_partition_t * ota_partition = esp_ota_get_next_update_partition(NULL);
ESP_ERROR_CHECK(esp_ota_begin(ota_partition, OTA_SIZE_UNKNOWN, &ota_handle));
while (remaining > 0)
{
while (remaining > 0) {
int recv_len = httpd_req_recv(req, buf, MIN(remaining, sizeof(buf)));
// Timeout Error: Just retry
if (recv_len == HTTPD_SOCK_ERR_TIMEOUT)
{
if (recv_len == HTTPD_SOCK_ERR_TIMEOUT) {
continue;
// Serious Error: Abort OTA
}
else if (recv_len <= 0)
{
} else if (recv_len <= 0) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Protocol Error");
return ESP_FAIL;
}
// Successful Upload: Flash firmware chunk
if (esp_ota_write(ota_handle, (const void *)buf, recv_len) != ESP_OK)
{
if (esp_ota_write(ota_handle, (const void *) buf, recv_len) != ESP_OK) {
esp_ota_abort(ota_handle);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Flash Error");
return ESP_FAIL;
@ -382,8 +339,7 @@ esp_err_t POST_OTA_update(httpd_req_t *req)
}
// 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)
{
if (esp_ota_end(ota_handle) != ESP_OK || esp_ota_set_boot_partition(ota_partition) != ESP_OK) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Validation / Activation Error");
return ESP_FAIL;
}
@ -396,19 +352,18 @@ esp_err_t POST_OTA_update(httpd_req_t *req)
return ESP_OK;
}
void log_to_websocket(const char *format, va_list args)
void log_to_websocket(const char * format, va_list args)
{
char log_buffer[1000];
char log_buffer[2048];
vsnprintf(log_buffer, sizeof(log_buffer), format, args);
httpd_ws_frame_t ws_pkt;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.payload = (uint8_t *)log_buffer;
ws_pkt.payload = (uint8_t *) log_buffer;
ws_pkt.len = strlen(log_buffer);
ws_pkt.type = HTTPD_WS_TYPE_TEXT;
vprintf(format, args);
if (httpd_ws_send_frame_async(server, fd, &ws_pkt) != ESP_OK)
{
if (httpd_ws_send_frame_async(server, fd, &ws_pkt) != ESP_OK) {
esp_log_set_vprintf(vprintf);
}
}
@ -417,11 +372,10 @@ void log_to_websocket(const char *format, va_list args)
* This handler echos back the received ws data
* and triggers an async send if certain message received
*/
esp_err_t echo_handler(httpd_req_t *req)
esp_err_t echo_handler(httpd_req_t * req)
{
if (req->method == HTTP_GET)
{
if (req->method == HTTP_GET) {
ESP_LOGI(TAG, "Handshake done, the new connection was opened");
fd = httpd_req_to_sockfd(req);
esp_log_set_vprintf(log_to_websocket);
@ -430,15 +384,15 @@ esp_err_t echo_handler(httpd_req_t *req)
return ESP_OK;
}
esp_err_t start_rest_server(void *pvParameters)
esp_err_t start_rest_server(void * pvParameters)
{
GLOBAL_STATE = (GlobalState *)pvParameters;
const char *base_path = "";
GLOBAL_STATE = (GlobalState *) pvParameters;
const char * base_path = "";
ESP_ERROR_CHECK(init_fs());
REST_CHECK(base_path, "wrong base path", err);
rest_server_context_t *rest_context = calloc(1, sizeof(rest_server_context_t));
rest_server_context_t * rest_context = calloc(1, sizeof(rest_server_context_t));
REST_CHECK(rest_context, "No memory for rest context", err);
strlcpy(rest_context->base_path, base_path, sizeof(rest_context->base_path));
@ -450,54 +404,30 @@ esp_err_t start_rest_server(void *pvParameters)
/* URI handler for fetching system info */
httpd_uri_t system_info_get_uri = {
.uri = "/api/system/info",
.method = HTTP_GET,
.handler = GET_system_info,
.user_ctx = rest_context};
.uri = "/api/system/info", .method = HTTP_GET, .handler = GET_system_info, .user_ctx = rest_context};
httpd_register_uri_handler(server, &system_info_get_uri);
httpd_uri_t system_restart_uri = {
.uri = "/api/system/restart",
.method = HTTP_POST,
.handler = POST_restart,
.user_ctx = rest_context};
.uri = "/api/system/restart", .method = HTTP_POST, .handler = POST_restart, .user_ctx = rest_context};
httpd_register_uri_handler(server, &system_restart_uri);
httpd_uri_t update_system_settings_uri = {
.uri = "/api/system",
.method = HTTP_PATCH,
.handler = PATCH_update_settings,
.user_ctx = rest_context};
.uri = "/api/system", .method = HTTP_PATCH, .handler = PATCH_update_settings, .user_ctx = rest_context};
httpd_register_uri_handler(server, &update_system_settings_uri);
httpd_uri_t update_post_ota_firmware = {
.uri = "/api/system/OTA",
.method = HTTP_POST,
.handler = POST_OTA_update,
.user_ctx = NULL};
.uri = "/api/system/OTA", .method = HTTP_POST, .handler = POST_OTA_update, .user_ctx = NULL};
httpd_register_uri_handler(server, &update_post_ota_firmware);
httpd_uri_t update_post_ota_www = {
.uri = "/api/system/OTAWWW",
.method = HTTP_POST,
.handler = POST_WWW_update,
.user_ctx = NULL};
.uri = "/api/system/OTAWWW", .method = HTTP_POST, .handler = POST_WWW_update, .user_ctx = NULL};
httpd_register_uri_handler(server, &update_post_ota_www);
httpd_uri_t ws = {
.uri = "/api/ws",
.method = HTTP_GET,
.handler = echo_handler,
.user_ctx = NULL,
.is_websocket = true};
httpd_uri_t ws = {.uri = "/api/ws", .method = HTTP_GET, .handler = echo_handler, .user_ctx = NULL, .is_websocket = true};
httpd_register_uri_handler(server, &ws);
/* URI handler for getting web server files */
httpd_uri_t common_get_uri = {
.uri = "/*",
.method = HTTP_GET,
.handler = rest_common_get_handler,
.user_ctx = rest_context};
httpd_uri_t common_get_uri = {.uri = "/*", .method = HTTP_GET, .handler = rest_common_get_handler, .user_ctx = rest_context};
httpd_register_uri_handler(server, &common_get_uri);
return ESP_OK;

View File

@ -6,108 +6,91 @@
// #include "protocol_examples_common.h"
#include "main.h"
#include "stratum_task.h"
#include "asic_result_task.h"
#include "asic_task.h"
#include "create_jobs_task.h"
#include "global_state.h"
#include "serial.h"
#include "asic_result_task.h"
#include "nvs_config.h"
#include "http_server.h"
#include "esp_netif.h"
#include "global_state.h"
#include "http_server.h"
#include "nvs_config.h"
#include "serial.h"
#include "stratum_task.h"
#include "user_input_task.h"
#define ASIC_MODEL CONFIG_ASIC_MODEL
static GlobalState GLOBAL_STATE = {
.extranonce_str = NULL,
.extranonce_2_len = 0,
.abandon_work = 0,
.version_mask = 0,
.POWER_MANAGEMENT_MODULE = {
.frequency_multiplier = 1,
.frequency_value = ASIC_FREQUENCY}};
static GlobalState GLOBAL_STATE = {.extranonce_str = NULL, .extranonce_2_len = 0, .abandon_work = 0, .version_mask = 0};
static const char *TAG = "miner";
static const char * TAG = "miner";
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
if (strcmp(ASIC_MODEL, "BM1366") == 0)
{
ESP_LOGI(TAG, "NVS_CONFIG_ASIC_FREQ %f", (float) nvs_config_get_u16(NVS_CONFIG_ASIC_FREQ, CONFIG_ASIC_FREQUENCY));
GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value = nvs_config_get_u16(NVS_CONFIG_ASIC_FREQ, CONFIG_ASIC_FREQUENCY);
if (strcmp(ASIC_MODEL, "BM1366") == 0) {
ESP_LOGI(TAG, "ASIC: BM1366");
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};
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};
GLOBAL_STATE.asic_job_frequency_ms = BM1366_FULLSCAN_MS;
GLOBAL_STATE.ASIC_functions = ASIC_functions;
}
else if (strcmp(ASIC_MODEL, "BM1397") == 0)
{
} else if (strcmp(ASIC_MODEL, "BM1397") == 0) {
ESP_LOGI(TAG, "ASIC: BM1397");
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};
GLOBAL_STATE.asic_job_frequency_ms = BM1397_FULLSCAN_MS;
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};
uint16_t bm1397_hashrate = GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value * BM1397_CORE_COUNT * 1000000;
GLOBAL_STATE.asic_job_frequency_ms = ((double) NONCE_SPACE / (double) bm1397_hashrate) * 1000;
GLOBAL_STATE.ASIC_functions = ASIC_functions;
}
else
{
} else {
ESP_LOGI(TAG, "Invalid ASIC model");
exit(EXIT_FAILURE);
}
ESP_LOGI(TAG, "Welcome to the bitaxe!");
// wait between 0 and 5 seconds for multiple units
vTaskDelay(rand() % 5001 / portTICK_PERIOD_MS);
ESP_ERROR_CHECK(nvs_flash_init());
xTaskCreate(SYSTEM_task, "SYSTEM_task", 4096, (void *)&GLOBAL_STATE, 3, NULL);
xTaskCreate(SYSTEM_task, "SYSTEM_task", 4096, (void *) &GLOBAL_STATE, 3, NULL);
// pull the wifi credentials out of NVS
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);
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);
// copy the wifi ssid to the global state
strncpy(GLOBAL_STATE.SYSTEM_MODULE.ssid, wifi_ssid, 20);
// init and connect to wifi
wifi_init(wifi_ssid, wifi_pass);
start_rest_server((void *)&GLOBAL_STATE);
start_rest_server((void *) &GLOBAL_STATE);
EventBits_t result_bits = wifi_connect();
if (result_bits & WIFI_CONNECTED_BIT)
{
if (result_bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG, "Connected to SSID: %s", wifi_ssid);
strncpy(GLOBAL_STATE.SYSTEM_MODULE.wifi_status, "Connected!", 20);
}
else if (result_bits & WIFI_FAIL_BIT)
{
} else if (result_bits & WIFI_FAIL_BIT) {
ESP_LOGE(TAG, "Failed to connect to SSID: %s", wifi_ssid);
strncpy(GLOBAL_STATE.SYSTEM_MODULE.wifi_status, "Failed to connect", 20);
// User might be trying to configure with AP, just chill here
ESP_LOGI(TAG, "Finished, waiting for user input.");
while (1)
{
while (1) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
else
{
} else {
ESP_LOGE(TAG, "UNEXPECTED EVENT");
strncpy(GLOBAL_STATE.SYSTEM_MODULE.wifi_status, "unexpected error", 20);
// User might be trying to configure with AP, just chill here
ESP_LOGI(TAG, "Finished, waiting for user input.");
while (1)
{
while (1) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
@ -127,24 +110,21 @@ void app_main(void)
// set the startup_done flag
GLOBAL_STATE.SYSTEM_MODULE.startup_done = 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(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);
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);
xTaskCreate(USER_INPUT_task, "user input", 8192, (void *)&GLOBAL_STATE, 5, NULL);
xTaskCreate(USER_INPUT_task, "user input", 8192, (void *) &GLOBAL_STATE, 5, NULL);
}
void MINER_set_wifi_status(wifi_status_t status, uint16_t retry_count)
{
if (status == WIFI_RETRYING)
{
if (status == WIFI_RETRYING) {
snprintf(GLOBAL_STATE.SYSTEM_MODULE.wifi_status, 20, "Retrying: %d/%d", retry_count, WIFI_MAXIMUM_RETRY);
return;
}
else if (status == WIFI_CONNECT_FAILED)
{
} else if (status == WIFI_CONNECT_FAILED) {
snprintf(GLOBAL_STATE.SYSTEM_MODULE.wifi_status, 20, "Connect Failed!");
return;
}

View File

@ -1,19 +1,18 @@
#include "nvs_config.h"
#include "nvs.h"
#include "esp_log.h"
#include "nvs.h"
#include <string.h>
#define NVS_CONFIG_NAMESPACE "main"
static const char *TAG = "nvs_config";
static const char * TAG = "nvs_config";
char *nvs_config_get_string(const char *key, const char *default_value)
char * nvs_config_get_string(const char * key, const char * default_value)
{
nvs_handle handle;
esp_err_t err;
err = nvs_open(NVS_CONFIG_NAMESPACE, NVS_READONLY, &handle);
if (err != ESP_OK)
{
if (err != ESP_OK) {
// ESP_LOGW(TAG, "Key %s not found in nvs, using default value", key);
return strdup(default_value);
}
@ -21,17 +20,15 @@ char *nvs_config_get_string(const char *key, const char *default_value)
size_t size = 0;
err = nvs_get_str(handle, key, NULL, &size);
if (err != ESP_OK)
{
if (err != ESP_OK) {
// ESP_LOGW(TAG, "Key %s not found in nvs, using default value", key);
return strdup(default_value);
}
char *out = malloc(size);
char * out = malloc(size);
err = nvs_get_str(handle, key, out, &size);
if (err != ESP_OK)
{
if (err != ESP_OK) {
// ESP_LOGW(TAG, "Key %s not found in nvs, using default value", key);
free(out);
return strdup(default_value);
@ -41,21 +38,19 @@ char *nvs_config_get_string(const char *key, const char *default_value)
return out;
}
void nvs_config_set_string(const char *key, const char *value)
void nvs_config_set_string(const char * key, const char * value)
{
nvs_handle handle;
esp_err_t err;
err = nvs_open(NVS_CONFIG_NAMESPACE, NVS_READWRITE, &handle);
if (err != ESP_OK)
{
if (err != ESP_OK) {
// ESP_LOGW(TAG, "Could not open nvs");
return;
}
err = nvs_set_str(handle, key, value);
if (err != ESP_OK)
{
if (err != ESP_OK) {
// ESP_LOGW(TAG, "Could not write nvs key: %s, value: %s", key, value);
return;
}
@ -64,23 +59,21 @@ void nvs_config_set_string(const char *key, const char *value)
return;
}
uint16_t nvs_config_get_u16(const char *key, const uint16_t default_value)
uint16_t nvs_config_get_u16(const char * key, const uint16_t default_value)
{
nvs_handle handle;
esp_err_t err;
err = nvs_open(NVS_CONFIG_NAMESPACE, NVS_READONLY, &handle);
if (err != ESP_OK)
{
// ESP_LOGW(TAG, "Key %s not found in nvs, using default value", key);
if (err != ESP_OK) {
ESP_LOGW(TAG, "Key %s not found in nvs, using default value", key);
return default_value;
}
uint16_t out;
err = nvs_get_u16(handle, key, &out);
if (err != ESP_OK)
{
// ESP_LOGW(TAG, "Key %s not found in nvs, using default value", key);
if (err != ESP_OK) {
ESP_LOGW(TAG, "Key %s not found in nvs, using default value", key);
return default_value;
}
@ -88,22 +81,20 @@ uint16_t nvs_config_get_u16(const char *key, const uint16_t default_value)
return out;
}
void nvs_config_set_u16(const char *key, const uint16_t value)
void nvs_config_set_u16(const char * key, const uint16_t value)
{
nvs_handle handle;
esp_err_t err;
err = nvs_open(NVS_CONFIG_NAMESPACE, NVS_READWRITE, &handle);
if (err != ESP_OK)
{
// ESP_LOGW(TAG, "Could not open nvs");
if (err != ESP_OK) {
ESP_LOGW(TAG, "Could not open nvs");
return;
}
err = nvs_set_u16(handle, key, value);
if (err != ESP_OK)
{
// ESP_LOGW(TAG, "Could not write nvs key: %s, value: %u", key, value);
if (err != ESP_OK) {
ESP_LOGW(TAG, "Could not write nvs key: %s, value: %u", key, value);
return;
}

View File

@ -1,32 +1,40 @@
#include "esp_log.h"
#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "driver/i2c.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "led_controller.h"
#include "DS4432U.h"
#include "EMC2101.h"
#include "INA260.h"
#include "adc.h"
#include "oled.h"
#include <sys/time.h>
#include "system.h"
#include <stdint.h>
#include <math.h>
#include <inttypes.h>
#include "global_state.h"
#include "esp_timer.h"
static const char *TAG = "SystemModule";
#include "connect.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "global_state.h"
#include "led_controller.h"
#include "lwip/inet.h"
#include "nvs_config.h"
#include "oled.h"
#include "system.h"
#include <inttypes.h>
#include <math.h>
#include <stdint.h>
#include <sys/time.h>
static const char * TAG = "SystemModule";
#define ASIC_VOLTAGE CONFIG_ASIC_VOLTAGE
// #define ASIC_VOLTAGE CONFIG_ASIC_VOLTAGE
#define ASIC_MODEL CONFIG_ASIC_MODEL
static void _suffix_string(uint64_t, char *, size_t, int);
static void _init_system(SystemModule *module)
static esp_netif_t * netif;
static esp_netif_ip_info_t ip_info;
static void _init_system(SystemModule * module)
{
module->duration_start = 0;
@ -67,39 +75,34 @@ static void _init_system(SystemModule *module)
ADC_init();
// DS4432U tests
DS4432U_set_vcore(ASIC_VOLTAGE / 1000.0);
DS4432U_set_vcore(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0);
// Fan Tests
EMC2101_init();
if (strcmp(ASIC_MODEL, "BM1366") == 0)
{
if (strcmp(ASIC_MODEL, "BM1366") == 0) {
EMC2101_set_fan_speed(0);
}
else
{
} else {
EMC2101_set_fan_speed(1);
}
vTaskDelay(500 / portTICK_PERIOD_MS);
// oled
if (!OLED_init())
{
if (!OLED_init()) {
ESP_LOGI(TAG, "OLED init failed!");
}
else
{
} else {
ESP_LOGI(TAG, "OLED init success!");
// clear the oled screen
OLED_fill(0);
}
netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
}
static void _update_hashrate(GlobalState *GLOBAL_STATE)
static void _update_hashrate(GlobalState * GLOBAL_STATE)
{
SystemModule *module = &GLOBAL_STATE->SYSTEM_MODULE;
SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE;
if (module->screen_page != 0)
{
if (module->screen_page != 0) {
return;
}
@ -107,14 +110,14 @@ static void _update_hashrate(GlobalState *GLOBAL_STATE)
OLED_clearLine(0);
memset(module->oled_buf, 0, 20);
snprintf(module->oled_buf, 20, "Gh%s: %.1f W/Th: %.1f", module->historical_hashrate_init < HISTORY_LENGTH ? "*" : "", module->current_hashrate, efficiency);
snprintf(module->oled_buf, 20, "Gh%s: %.1f W/Th: %.1f", module->historical_hashrate_init < HISTORY_LENGTH ? "*" : "",
module->current_hashrate, efficiency);
OLED_writeString(0, 0, module->oled_buf);
}
static void _update_shares(SystemModule *module)
static void _update_shares(SystemModule * module)
{
if (module->screen_page != 0)
{
if (module->screen_page != 0) {
return;
}
OLED_clearLine(1);
@ -123,10 +126,9 @@ static void _update_shares(SystemModule *module)
OLED_writeString(0, 1, module->oled_buf);
}
static void _update_best_diff(SystemModule *module)
static void _update_best_diff(SystemModule * module)
{
if (module->screen_page != 0)
{
if (module->screen_page != 0) {
return;
}
OLED_clearLine(3);
@ -143,14 +145,13 @@ static void _clear_display(void)
OLED_clearLine(3);
}
static void _update_system_info(GlobalState *GLOBAL_STATE)
static void _update_system_info(GlobalState * GLOBAL_STATE)
{
SystemModule *module = &GLOBAL_STATE->SYSTEM_MODULE;
PowerManagementModule *power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE;
SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE;
PowerManagementModule * power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE;
if (OLED_status())
{
if (OLED_status()) {
memset(module->oled_buf, 0, 20);
snprintf(module->oled_buf, 20, " Fan: %d RPM", power_management->fan_speed);
@ -165,20 +166,19 @@ static void _update_system_info(GlobalState *GLOBAL_STATE)
OLED_writeString(0, 2, module->oled_buf);
memset(module->oled_buf, 0, 20);
snprintf(module->oled_buf, 20, " %i mV: %i mA", (int)power_management->voltage, (int)power_management->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);
}
}
static void _update_esp32_info(SystemModule *module)
static void _update_esp32_info(SystemModule * module)
{
uint32_t free_heap_size = esp_get_free_heap_size();
uint16_t vcore = ADC_get_vcore();
if (OLED_status())
{
if (OLED_status()) {
memset(module->oled_buf, 0, 20);
snprintf(module->oled_buf, 20, "FH: %lu bytes", free_heap_size);
@ -188,28 +188,30 @@ static void _update_esp32_info(SystemModule *module)
snprintf(module->oled_buf, 20, "vCore: %u mV", vcore);
OLED_writeString(0, 1, module->oled_buf);
// memset(oled_buf, 0, 20);
// snprintf(oled_buf, 20, "Pwr: %.2f W", power);
// OLED_writeString(0, 2, oled_buf);
esp_netif_get_ip_info(netif, &ip_info);
char ip_address_str[IP4ADDR_STRLEN_MAX];
esp_ip4addr_ntoa(&ip_info.ip, ip_address_str, IP4ADDR_STRLEN_MAX);
memset(module->oled_buf, 0, 20);
snprintf(module->oled_buf, 20, "IP: %s", ip_address_str);
OLED_writeString(0, 2, module->oled_buf);
}
}
static void _init_connection(SystemModule *module)
static void _init_connection(SystemModule * module)
{
if (OLED_status())
{
if (OLED_status()) {
memset(module->oled_buf, 0, 20);
snprintf(module->oled_buf, 20, "Connecting to ssid:");
OLED_writeString(0, 0, module->oled_buf);
}
}
static void _update_connection(SystemModule *module)
static void _update_connection(SystemModule * module)
{
if (OLED_status())
{
if (OLED_status()) {
OLED_clearLine(2);
memset(module->oled_buf, 0, 20);
snprintf(module->oled_buf, 20, "%s", module->ssid);
@ -222,20 +224,19 @@ static void _update_connection(SystemModule *module)
}
}
static void _update_system_performance(GlobalState *GLOBAL_STATE)
static void _update_system_performance(GlobalState * GLOBAL_STATE)
{
SystemModule *module = &GLOBAL_STATE->SYSTEM_MODULE;
SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE;
// Calculate the uptime in seconds
double uptime_in_seconds = (esp_timer_get_time() - module->start_time) / 1000000;
int uptime_in_days = uptime_in_seconds / (3600 * 24);
int remaining_seconds = (int)uptime_in_seconds % (3600 * 24);
int remaining_seconds = (int) uptime_in_seconds % (3600 * 24);
int uptime_in_hours = remaining_seconds / 3600;
remaining_seconds %= 3600;
int uptime_in_minutes = remaining_seconds / 60;
if (OLED_status())
{
if (OLED_status()) {
_update_hashrate(GLOBAL_STATE);
_update_shares(module);
@ -252,25 +253,23 @@ static double _calculate_network_difficulty(uint32_t nBits)
uint32_t mantissa = nBits & 0x007fffff; // Extract the mantissa from nBits
uint8_t exponent = (nBits >> 24) & 0xff; // Extract the exponent from nBits
double target = (double)mantissa * pow(256, (exponent - 3)); // Calculate the target value
double target = (double) mantissa * pow(256, (exponent - 3)); // Calculate the target value
double difficulty = (pow(2, 208) * 65535) / target; // Calculate the difficulty
return difficulty;
}
static void _check_for_best_diff(SystemModule *module, double diff, uint32_t nbits)
static void _check_for_best_diff(SystemModule * module, double diff, uint32_t nbits)
{
if (diff < module->best_nonce_diff)
{
if (diff < module->best_nonce_diff) {
return;
}
module->best_nonce_diff = diff;
// make the best_nonce_diff into a string
_suffix_string((uint64_t)diff, module->best_diff_string, DIFF_STRING_SIZE, 0);
_suffix_string((uint64_t) diff, module->best_diff_string, DIFF_STRING_SIZE, 0);
double network_diff = _calculate_network_difficulty(nbits);
if (diff > network_diff)
{
if (diff > network_diff) {
module->FOUND_BLOCK = true;
ESP_LOGI(TAG, "FOUND BLOCK!!!!!!!!!!!!!!!!!!!!!! %f > %f", diff, network_diff);
}
@ -279,7 +278,7 @@ static void _check_for_best_diff(SystemModule *module, double diff, uint32_t nbi
/* Convert a uint64_t value into a truncated string for displaying with its
* associated suitable for Mega, Giga etc. Buf array needs to be long enough */
static void _suffix_string(uint64_t val, char *buf, size_t bufsiz, int sigdigits)
static void _suffix_string(uint64_t val, char * buf, size_t bufsiz, int sigdigits)
{
const double dkilo = 1000.0;
const uint64_t kilo = 1000ull;
@ -292,56 +291,40 @@ static void _suffix_string(uint64_t val, char *buf, size_t bufsiz, int sigdigits
bool decimal = true;
double dval;
if (val >= exa)
{
if (val >= exa) {
val /= peta;
dval = (double)val / dkilo;
dval = (double) val / dkilo;
strcpy(suffix, "E");
}
else if (val >= peta)
{
} else if (val >= peta) {
val /= tera;
dval = (double)val / dkilo;
dval = (double) val / dkilo;
strcpy(suffix, "P");
}
else if (val >= tera)
{
} else if (val >= tera) {
val /= giga;
dval = (double)val / dkilo;
dval = (double) val / dkilo;
strcpy(suffix, "T");
}
else if (val >= giga)
{
} else if (val >= giga) {
val /= mega;
dval = (double)val / dkilo;
dval = (double) val / dkilo;
strcpy(suffix, "G");
}
else if (val >= mega)
{
} else if (val >= mega) {
val /= kilo;
dval = (double)val / dkilo;
dval = (double) val / dkilo;
strcpy(suffix, "M");
}
else if (val >= kilo)
{
dval = (double)val / dkilo;
} else if (val >= kilo) {
dval = (double) val / dkilo;
strcpy(suffix, "k");
}
else
{
} else {
dval = val;
decimal = false;
}
if (!sigdigits)
{
if (!sigdigits) {
if (decimal)
snprintf(buf, bufsiz, "%.3g%s", dval, suffix);
else
snprintf(buf, bufsiz, "%d%s", (unsigned int)dval, suffix);
}
else
{
snprintf(buf, bufsiz, "%d%s", (unsigned int) dval, suffix);
} else {
/* Always show sigdigits + 1, padded on right with zeroes
* followed by suffix */
int ndigits = sigdigits - 1 - (dval > 0.0 ? floor(log10(dval)) : 0);
@ -350,11 +333,11 @@ static void _suffix_string(uint64_t val, char *buf, size_t bufsiz, int sigdigits
}
}
void SYSTEM_task(void *pvParameters)
void SYSTEM_task(void * pvParameters)
{
GlobalState *GLOBAL_STATE = (GlobalState *)pvParameters;
SystemModule *module = &GLOBAL_STATE->SYSTEM_MODULE;
GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters;
SystemModule * module = &GLOBAL_STATE->SYSTEM_MODULE;
_init_system(module);
@ -362,14 +345,12 @@ void SYSTEM_task(void *pvParameters)
_init_connection(module);
// show the connection screen
while (!module->startup_done)
{
while (!module->startup_done) {
_update_connection(module);
vTaskDelay(100 / portTICK_PERIOD_MS);
}
while (1)
{
while (1) {
_clear_display();
module->screen_page = 0;
_update_system_performance(GLOBAL_STATE);
@ -387,27 +368,26 @@ void SYSTEM_task(void *pvParameters)
}
}
void SYSTEM_notify_accepted_share(SystemModule *module)
void SYSTEM_notify_accepted_share(SystemModule * module)
{
module->shares_accepted++;
_update_shares(module);
}
void SYSTEM_notify_rejected_share(SystemModule *module)
void SYSTEM_notify_rejected_share(SystemModule * module)
{
module->shares_rejected++;
_update_shares(module);
}
void SYSTEM_notify_mining_started(SystemModule *module)
void SYSTEM_notify_mining_started(SystemModule * module)
{
module->duration_start = esp_timer_get_time();
}
void SYSTEM_notify_new_ntime(SystemModule *module, uint32_t ntime)
void SYSTEM_notify_new_ntime(SystemModule * module, uint32_t ntime)
{
// Hourly clock sync
if (module->lastClockSync + (60 * 60) > ntime)
{
if (module->lastClockSync + (60 * 60) > ntime) {
return;
}
ESP_LOGI(TAG, "Syncing clock");
@ -418,7 +398,7 @@ void SYSTEM_notify_new_ntime(SystemModule *module, uint32_t ntime)
settimeofday(&tv, NULL);
}
void SYSTEM_notify_found_nonce(SystemModule *module, double pool_diff, double found_diff, uint32_t nbits)
void SYSTEM_notify_found_nonce(SystemModule * module, double pool_diff, double found_diff, uint32_t nbits)
{
// Calculate the time difference in seconds with sub-second precision
@ -430,31 +410,26 @@ void SYSTEM_notify_found_nonce(SystemModule *module, double pool_diff, double fo
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]);
// 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)
{
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];
} 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++)
{
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 duration = (double) (esp_timer_get_time() - module->duration_start) / 1000000;
double rolling_rate = (sum * 4294967296) / (duration * 1000000000);
if (module->historical_hashrate_init < HISTORY_LENGTH)
{
if (module->historical_hashrate_init < HISTORY_LENGTH) {
module->current_hashrate = rolling_rate;
}
else
{
} else {
// More smoothing
module->current_hashrate = ((module->current_hashrate * 9) + rolling_rate) / 10;
}

View File

@ -1,15 +1,16 @@
#include "global_state.h"
#include <string.h>
#include "esp_log.h"
#include "mining.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "bm1397.h"
#include "DS4432U.h"
#include "EMC2101.h"
#include "INA260.h"
#include "bm1397.h"
#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"
#include "serial.h"
#include "DS4432U.h"
#include <string.h>
#define POLL_RATE 5000
#define MAX_TEMP 90.0
@ -21,7 +22,7 @@
#define VOLTAGE_RANGE (VOLTAGE_START_THROTTLE - VOLTAGE_MIN_THROTTLE)
#define ASIC_MODEL CONFIG_ASIC_MODEL
static const char *TAG = "power_management";
static const char * TAG = "power_management";
static float _fbound(float value, float lower_bound, float upper_bound)
{
@ -33,108 +34,98 @@ static float _fbound(float value, float lower_bound, float upper_bound)
return value;
}
void POWER_MANAGEMENT_task(void *pvParameters)
void POWER_MANAGEMENT_task(void * pvParameters)
{
GlobalState *GLOBAL_STATE = (GlobalState *)pvParameters;
GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters;
PowerManagementModule *power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE;
PowerManagementModule * power_management = &GLOBAL_STATE->POWER_MANAGEMENT_MODULE;
power_management->frequency_multiplier = 1;
int last_frequency_increase = 0;
bool read_power = INA260_installed();
while (1)
{
if (read_power == true)
{
uint16_t frequency_target = nvs_config_get_u16(NVS_CONFIG_ASIC_FREQ, CONFIG_ASIC_FREQUENCY);
while (1) {
if (read_power == true) {
power_management->voltage = INA260_read_voltage();
power_management->power = INA260_read_power() / 1000;
power_management->current = INA260_read_current();
}
power_management->fan_speed = EMC2101_get_fan_speed();
if (strcmp(ASIC_MODEL, "BM1397") == 0)
{
if (strcmp(ASIC_MODEL, "BM1397") == 0) {
power_management->chip_temp = EMC2101_get_external_temp();
// Voltage
// We'll throttle between 4.9v and 3.5v
float voltage_multiplier = _fbound((power_management->voltage - VOLTAGE_MIN_THROTTLE) * (1 / (float)VOLTAGE_RANGE), 0, 1);
float voltage_multiplier =
_fbound((power_management->voltage - VOLTAGE_MIN_THROTTLE) * (1 / (float) VOLTAGE_RANGE), 0, 1);
// Temperature
float temperature_multiplier = 1;
float over_temp = -(THROTTLE_TEMP - power_management->chip_temp);
if (over_temp > 0)
{
if (over_temp > 0) {
temperature_multiplier = (THROTTLE_TEMP_RANGE - over_temp) / THROTTLE_TEMP_RANGE;
}
float lowest_multiplier = 1;
float multipliers[2] = {voltage_multiplier, temperature_multiplier};
for (int i = 0; i < 2; i++)
{
if (multipliers[i] < lowest_multiplier)
{
for (int i = 0; i < 2; i++) {
if (multipliers[i] < lowest_multiplier) {
lowest_multiplier = multipliers[i];
}
}
power_management->frequency_multiplier = lowest_multiplier;
float target_frequency = _fbound(power_management->frequency_multiplier * ASIC_FREQUENCY, 0, ASIC_FREQUENCY);
float target_frequency = _fbound(power_management->frequency_multiplier * frequency_target, 0, frequency_target);
if (target_frequency < 50)
{
if (target_frequency < 50) {
// TODO: Turn the chip off
}
// chip is coming back from a low/no voltage event
if (power_management->frequency_value < 50 && target_frequency > 50)
{
if (power_management->frequency_value < 50 && target_frequency > 50) {
// TODO recover gracefully?
esp_restart();
}
if (power_management->frequency_value > target_frequency)
{
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 > 120 &&
power_management->frequency_value != ASIC_FREQUENCY)
{
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 > 120 && power_management->frequency_value != frequency_target) {
float add = (target_frequency + power_management->frequency_value) / 2;
power_management->frequency_value += _fbound(add, 2, 20);
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);
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 = 60;
}
else
{
} else {
last_frequency_increase++;
}
}
}
else if (strcmp(ASIC_MODEL, "BM1366") == 0)
{
} else if (strcmp(ASIC_MODEL, "BM1366") == 0) {
power_management->chip_temp = EMC2101_get_internal_temp() + 5;
if (power_management->fan_speed < 10)
{
if (power_management->fan_speed < 10) {
ESP_LOGE(TAG, "Detected fan speed too slow, setting vCore to 0");
DS4432U_set_vcore(0);
}
}
// ESP_LOGI(TAG, "target %f, Freq %f, Volt %f, Power %f", target_frequency, power_management->frequency_value, power_management->voltage, power_management->power);
// ESP_LOGI(TAG, "target %f, Freq %f, Volt %f, Power %f", target_frequency, power_management->frequency_value,
// power_management->voltage, power_management->power);
vTaskDelay(POLL_RATE / portTICK_PERIOD_MS);
}
}