Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions components/asic/asic.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ uint8_t ASIC_init(GlobalState * GLOBAL_STATE) {
return ESP_OK;
}

void ASIC_hold_reset_low(GlobalState * GLOBAL_STATE) {
switch (GLOBAL_STATE->device_model) {
case BITFORGE_NANO:
BM1370_hold_reset_low();
break;
default:
break;
}
}

uint8_t ASIC_get_asic_count(GlobalState * GLOBAL_STATE) {
switch (GLOBAL_STATE->device_model) {
case BITFORGE_NANO:
Expand Down
5 changes: 5 additions & 0 deletions components/asic/bm1370.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,11 @@ static void _reset(void)
vTaskDelay(100 / portTICK_PERIOD_MS);
}

void BM1370_hold_reset_low(void)
{
gpio_set_level(GPIO_ASIC_RESET, 0);
}

// static void _send_read_address(void)
// {

Expand Down
1 change: 1 addition & 0 deletions components/asic/include/asic.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define BITFORGE_NANO_ASIC_COUNT 2

uint8_t ASIC_init(GlobalState * GLOBAL_STATE);
void ASIC_hold_reset_low(GlobalState * GLOBAL_STATE);
uint8_t ASIC_get_asic_count(GlobalState * GLOBAL_STATE);
uint16_t ASIC_get_small_core_count(GlobalState * GLOBAL_STATE);
task_result * ASIC_process_work(GlobalState * GLOBAL_STATE);
Expand Down
1 change: 1 addition & 0 deletions components/asic/include/bm1370.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef struct __attribute__((__packed__))
} BM1370_job;

uint8_t BM1370_init(uint64_t frequency, uint16_t asic_count);
void BM1370_hold_reset_low(void);
void BM1370_send_work(void * GLOBAL_STATE, bm_job * next_bm_job);
void BM1370_set_job_difficulty_mask(int);
void BM1370_set_version_mask(uint32_t version_mask);
Expand Down
13 changes: 13 additions & 0 deletions main/global_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "asic_task.h"
#include "bm1370.h"
#include "common.h"
Expand Down Expand Up @@ -32,6 +33,14 @@ typedef enum
ASIC_BM1370,
} AsicModel;

typedef enum
{
MINING_STATE_MINING = 0,
MINING_STATE_PAUSING,
MINING_STATE_PAUSED,
MINING_STATE_RESUMING,
} MiningState;

// typedef struct
// {
// uint8_t (*init_fn)(uint64_t, uint16_t);
Expand Down Expand Up @@ -86,6 +95,8 @@ typedef struct
bool is_using_fallback;
char pool_connection_info[64];
uint16_t overheat_mode;
volatile bool mining_paused;
volatile MiningState mining_state;
uint16_t power_fault;
uint32_t lastClockSync;
bool is_screen_active;
Expand Down Expand Up @@ -144,6 +155,8 @@ typedef struct
portMUX_TYPE stratum_mux;

bool ASIC_initalized;
bool mining_control_ready;
TaskHandle_t power_management_task_handle;
bool psram_is_available;
} GlobalState;

Expand Down
101 changes: 100 additions & 1 deletion main/http_server/http_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,86 @@ static esp_err_t POST_restart(httpd_req_t * req)
return ESP_OK;
}

static const char * mining_state_name(MiningState state)
{
switch (state) {
case MINING_STATE_PAUSING:
return "pausing";
case MINING_STATE_PAUSED:
return "paused";
case MINING_STATE_RESUMING:
return "resuming";
case MINING_STATE_MINING:
default:
return "mining";
}
}

static esp_err_t set_mining_paused(httpd_req_t * req, bool paused)
{
if (is_network_allowed(req) != ESP_OK) {
return httpd_resp_send_err(req, HTTPD_401_UNAUTHORIZED, "Unauthorized");
}

if (!GLOBAL_STATE->mining_control_ready) {
httpd_resp_set_status(req, "503 Service Unavailable");
httpd_resp_set_type(req, "application/json");
return httpd_resp_sendstr(req, "{\"message\":\"Mining subsystem is not ready\"}");
}

if (set_cors_headers(req) != ESP_OK) {
httpd_resp_send_500(req);
return ESP_OK;
}

SystemModule * system = &GLOBAL_STATE->SYSTEM_MODULE;
system->mining_paused = paused;
if (paused) {
if (system->mining_state != MINING_STATE_PAUSED) {
system->mining_state = MINING_STATE_PAUSING;
}
} else if (system->mining_state != MINING_STATE_MINING) {
system->mining_state = MINING_STATE_RESUMING;
}

if (GLOBAL_STATE->power_management_task_handle != NULL) {
xTaskNotifyGive(GLOBAL_STATE->power_management_task_handle);
}

ESP_LOGI(TAG, "Mining %s by API request", paused ? "pause requested" : "resume requested");

cJSON * root = cJSON_CreateObject();
if (root == NULL) {
return httpd_resp_send_500(req);
}

cJSON_AddStringToObject(root, "message",
paused ? "Mining pause requested" : "Mining resume requested");
cJSON_AddBoolToObject(root, "miningPaused", paused);
cJSON_AddStringToObject(root, "miningState", mining_state_name(system->mining_state));

char * response = cJSON_PrintUnformatted(root);
cJSON_Delete(root);
if (response == NULL) {
return httpd_resp_send_500(req);
}

httpd_resp_set_type(req, "application/json");
esp_err_t result = httpd_resp_sendstr(req, response);
free(response);
return result;
}

static esp_err_t POST_mining_pause(httpd_req_t * req)
{
return set_mining_paused(req, true);
}

static esp_err_t POST_mining_resume(httpd_req_t * req)
{
return set_mining_paused(req, false);
}

/* Simple handler for getting system handler */
static esp_err_t GET_system_info(httpd_req_t * req)
{
Expand Down Expand Up @@ -755,7 +835,7 @@ static esp_err_t GET_system_info(httpd_req_t * req)
cJSON * root = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "power", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.power);
cJSON_AddNumberToObject(root, "voltage", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.voltage);
cJSON_AddNumberToObject(root, "current", Power_get_current(GLOBAL_STATE));
cJSON_AddNumberToObject(root, "current", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.current);
cJSON_AddNumberToObject(root, "temp", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.chip_temp_avg);
cJSON_AddNumberToObject(root, "vrTemp", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.vr_temp);
cJSON_AddNumberToObject(root, "maxPower", Power_get_max_settings(GLOBAL_STATE));
Expand Down Expand Up @@ -821,6 +901,9 @@ static esp_err_t GET_system_info(httpd_req_t * req)
cJSON_AddStringToObject(root, "runningPartition", esp_ota_get_running_partition()->label);

cJSON_AddNumberToObject(root, "overheat_mode", nvs_config_get_u16(NVS_CONFIG_OVERHEAT_MODE, 0));
cJSON_AddBoolToObject(root, "miningPaused", GLOBAL_STATE->SYSTEM_MODULE.mining_paused);
cJSON_AddStringToObject(root, "miningState",
mining_state_name(GLOBAL_STATE->SYSTEM_MODULE.mining_state));
cJSON_AddNumberToObject(root, "overclockEnabled", nvs_config_get_u16(NVS_CONFIG_OVERCLOCK_ENABLED, 0));

cJSON_AddNumberToObject(root, "autofanspeed", nvs_config_get_u16(NVS_CONFIG_AUTO_FAN_SPEED, 1));
Expand Down Expand Up @@ -1279,6 +1362,22 @@ esp_err_t start_rest_server(void * pvParameters)
.uri = "/api/system/restart", .method = HTTP_OPTIONS, .handler = handle_options_request, .user_ctx = NULL};
httpd_register_uri_handler(server, &system_restart_options_uri);

httpd_uri_t system_mining_pause_uri = {
.uri = "/api/system/pause", .method = HTTP_POST, .handler = POST_mining_pause, .user_ctx = rest_context};
httpd_register_uri_handler(server, &system_mining_pause_uri);

httpd_uri_t system_mining_pause_options_uri = {
.uri = "/api/system/pause", .method = HTTP_OPTIONS, .handler = handle_options_request, .user_ctx = NULL};
httpd_register_uri_handler(server, &system_mining_pause_options_uri);

httpd_uri_t system_mining_resume_uri = {
.uri = "/api/system/resume", .method = HTTP_POST, .handler = POST_mining_resume, .user_ctx = rest_context};
httpd_register_uri_handler(server, &system_mining_resume_uri);

httpd_uri_t system_mining_resume_options_uri = {
.uri = "/api/system/resume", .method = HTTP_OPTIONS, .handler = handle_options_request, .user_ctx = NULL};
httpd_register_uri_handler(server, &system_mining_resume_options_uri);

httpd_uri_t update_system_settings_uri = {
.uri = "/api/system", .method = HTTP_PATCH, .handler = PATCH_update_settings, .user_ctx = rest_context};
httpd_register_uri_handler(server, &update_system_settings_uri);
Expand Down
61 changes: 56 additions & 5 deletions main/http_server/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ components:
- isPSRAMAvailable
- isUsingFallbackStratum
- macAddr
- miningPaused
- miningState
- overheat_mode
- power
- runningPartition
Expand Down Expand Up @@ -146,7 +148,7 @@ components:
description: Actual measured ASIC core voltage
current:
type: number
description: Current draw in milliamps
description: Live board input current in milliamps, including while mining is paused
fallbackStratumPort:
type: number
description: Fallback stratum server port
Expand All @@ -158,7 +160,7 @@ components:
description: Fallback stratum username
fanrpm:
type: number
description: Current fan speed in RPM
description: Current fan speed in RPM, including while mining is paused
fanSpeed:
type: number
description: Current fan speed percentage
Expand Down Expand Up @@ -195,12 +197,19 @@ components:
macAddr:
type: string
description: Device MAC address
miningPaused:
type: boolean
description: Whether mining pause has been requested
miningState:
type: string
description: Current mining hardware transition state
enum: [mining, pausing, paused, resuming]
overheat_mode:
type: number
description: Overheat protection mode
power:
type: number
description: Power consumption in watts
description: Live board input power in watts, including controller and fans while mining is paused
runningPartition:
type: string
description: Currently active OTA partition
Expand Down Expand Up @@ -230,7 +239,7 @@ components:
description: Primary stratum username
temp:
type: number
description: Average chip temperature
description: Average ASIC temperature, or 0 while ASIC thermal diodes are unavailable during pause
uptimeSeconds:
type: number
description: System uptime in seconds
Expand All @@ -239,7 +248,7 @@ components:
description: Firmware version
voltage:
type: number
description: Input voltage
description: Live board input voltage in millivolts, including while mining is paused
vrTemp:
type: number
description: Voltage regulator temperature
Expand Down Expand Up @@ -376,6 +385,48 @@ components:
description: Internal server error

paths:
/api/system/pause:
post:
summary: Pause mining while keeping the controller online
responses:
"200":
description: Pause request accepted
content:
application/json:
schema:
type: object
required: [message, miningPaused, miningState]
properties:
message:
type: string
miningPaused:
type: boolean
miningState:
type: string
enum: [mining, pausing, paused, resuming]
"503":
description: Mining subsystem is not ready
/api/system/resume:
post:
summary: Resume mining and reinitialize the ASIC chain
responses:
"200":
description: Resume request accepted
content:
application/json:
schema:
type: object
required: [message, miningPaused, miningState]
properties:
message:
type: string
miningPaused:
type: boolean
miningState:
type: string
enum: [mining, pausing, paused, resuming]
"503":
description: Mining subsystem is not ready
/api/system/wifi/scan:
get:
summary: Scan for available WiFi networks
Expand Down
4 changes: 3 additions & 1 deletion main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ void app_main(void)

SYSTEM_init_peripherals(&GLOBAL_STATE);

xTaskCreate(POWER_MANAGEMENT_task, "power management", 8192, (void *) &GLOBAL_STATE, 10, NULL);
xTaskCreate(POWER_MANAGEMENT_task, "power management", 8192, (void *) &GLOBAL_STATE, 10,
&GLOBAL_STATE.power_management_task_handle);

//start the API for AxeOS
start_rest_server((void *) &GLOBAL_STATE);
Expand Down Expand Up @@ -175,6 +176,7 @@ void app_main(void)
SERIAL_clear_buffer();

GLOBAL_STATE.ASIC_initalized = true;
GLOBAL_STATE.mining_control_ready = true;

xTaskCreate(stratum_task, "stratum admin", 8192, (void *) &GLOBAL_STATE, 5, NULL);
xTaskCreate(create_jobs_task, "stratum miner", 8192, (void *) &GLOBAL_STATE, 10, NULL);
Expand Down
4 changes: 4 additions & 0 deletions main/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ void SYSTEM_init_system(GlobalState * GLOBAL_STATE)
module->overheat_mode = nvs_config_get_u16(NVS_CONFIG_OVERHEAT_MODE, 0);
ESP_LOGI(TAG, "Initial overheat_mode value: %d", module->overheat_mode);

// Pause is intentionally not persisted: every clean boot starts mining.
module->mining_paused = false;
module->mining_state = MINING_STATE_MINING;

//Initialize power_fault fault mode
module->power_fault = 0;

Expand Down
5 changes: 5 additions & 0 deletions main/tasks/asic_result_task.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ void ASIC_result_task(void *pvParameters)

while (1)
{
if (!GLOBAL_STATE->ASIC_initalized) {
vTaskDelay(100 / portTICK_PERIOD_MS);
continue;
}

//task_result *asic_result = (*GLOBAL_STATE->ASIC_functions.receive_result_fn)(GLOBAL_STATE);
task_result *asic_result = ASIC_process_work(GLOBAL_STATE);

Expand Down
6 changes: 6 additions & 0 deletions main/tasks/asic_task.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ void ASIC_task(void *pvParameters)

bm_job *next_bm_job = (bm_job *)queue_dequeue(&GLOBAL_STATE->ASIC_jobs_queue);

if (!GLOBAL_STATE->ASIC_initalized) {
free_bm_job(next_bm_job);
vTaskDelay(100 / portTICK_PERIOD_MS);
continue;
}

if (next_bm_job->pool_diff != GLOBAL_STATE->stratum_difficulty)
{
ESP_LOGI(TAG, "New pool difficulty %.2f", next_bm_job->pool_diff);
Expand Down
4 changes: 3 additions & 1 deletion main/tasks/create_jobs_task.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ void create_jobs_task(void *pvParameters)
}

uint64_t extranonce_2 = 0;
while (queue_count(&GLOBAL_STATE->stratum_queue) < 1 && GLOBAL_STATE->abandon_work == 0)
while (queue_count(&GLOBAL_STATE->stratum_queue) < 1 &&
GLOBAL_STATE->abandon_work == 0 &&
!GLOBAL_STATE->SYSTEM_MODULE.mining_paused)
{
if (should_generate_more_work(GLOBAL_STATE))
{
Expand Down
Loading
Loading