Skip to content

Commit

Permalink
system_task state machine is now the main state machine.
Browse files Browse the repository at this point in the history
  • Loading branch information
skot committed Sep 10, 2024
1 parent 1d26a03 commit d99c255
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 73 deletions.
141 changes: 114 additions & 27 deletions main/main.c
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@

#include "esp_event.h"
#include "esp_log.h"
#include "esp_err.h"
#include "freertos/event_groups.h"

#include "main.h"
#include "i2c_master.h"
#include "asic_result_task.h"
#include "asic_task.h"
#include "create_jobs_task.h"
#include "system_task.h"
#include "system.h"
#include "nvs_device.h"
#include "stratum_task.h"
#include "self_test.h"
#include "network.h"
#include "display_task.h"

// Enum for display states
typedef enum {
MAIN_STATE_INIT,
MAIN_STATE_NET_CONNECT,
MAIN_STATE_ASIC_INIT,
MAIN_STATE_POOL_CONNECT,
MAIN_STATE_MINING_INIT,
MAIN_STATE_IDLE,
} MainState;

// Struct for display state machine
typedef struct {
MainState state;
} MainStateMachine;

static MainStateMachine mainStateMachine;

// Declare a variable to hold the created event group.
EventGroupHandle_t mainEventGroup;

static GlobalState GLOBAL_STATE = {.extranonce_str = NULL, .extranonce_2_len = 0, .abandon_work = 0, .version_mask = 0};

static const char * TAG = "main";
Expand All @@ -24,6 +43,9 @@ void app_main(void)
{
ESP_LOGI(TAG, "Welcome to the bitaxe - hack the planet!");

// Initialize the main state machine
mainStateMachine.state = MAIN_STATE_INIT;

//init I2C
if (i2c_master_init() != ESP_OK) {
ESP_LOGE(TAG, "Failed to init I2C");
Expand Down Expand Up @@ -53,36 +75,101 @@ void app_main(void)
vTaskDelay(60 * 60 * 1000 / portTICK_PERIOD_MS);
}

xTaskCreate(SYSTEM_task, "SYSTEM_task", 4096, (void *) &GLOBAL_STATE, 3, NULL);
xTaskCreate(POWER_MANAGEMENT_task, "power mangement", 8192, (void *) &GLOBAL_STATE, 10, NULL);
//xTaskCreate(SYSTEM_task, "SYSTEM_task", 4096, (void *) &GLOBAL_STATE, 3, NULL);

//get the WiFi connected
if (Network_connect(&GLOBAL_STATE) != ESP_OK) {
ESP_LOGE(TAG, "Failed to connect to WiFi");
return;
}

// // set the startup_done flag
// GLOBAL_STATE.SYSTEM_MODULE.startup_done = true;

if (GLOBAL_STATE.ASIC_functions.init_fn != NULL) {

Network_AP_off();
System_init_system(&GLOBAL_STATE);

queue_init(&GLOBAL_STATE.stratum_queue);
queue_init(&GLOBAL_STATE.ASIC_jobs_queue);
xTaskCreate(POWER_MANAGEMENT_task, "power mangement", 8192, (void *) &GLOBAL_STATE, 10, NULL);

SERIAL_init();
(*GLOBAL_STATE.ASIC_functions.init_fn)(GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value, GLOBAL_STATE.asic_count);
SERIAL_set_baud((*GLOBAL_STATE.ASIC_functions.set_max_baud_fn)());
SERIAL_clear_buffer();
Display_mining_state();

Display_mining_state();
/* Attempt to create the event group. */
mainEventGroup = xEventGroupCreate();
EventBits_t eventBits;
if (mainEventGroup == NULL) {
ESP_LOGE(TAG, "Main Event group creation failed");
return;
}

xTaskCreate(stratum_task, "stratum admin", 8192, (void *) &GLOBAL_STATE, 5, NULL);
xTaskCreate(create_jobs_task, "stratum miner", 8192, (void *) &GLOBAL_STATE, 10, NULL);
xTaskCreate(ASIC_task, "asic", 8192, (void *) &GLOBAL_STATE, 10, NULL);
xTaskCreate(ASIC_result_task, "asic result", 8192, (void *) &GLOBAL_STATE, 15, NULL);
EventBits_t result_bits;

while(1) {

switch (mainStateMachine.state) {
case MAIN_STATE_INIT:
mainStateMachine.state = MAIN_STATE_NET_CONNECT;
break;

case MAIN_STATE_NET_CONNECT:

result_bits = Network_connect(&GLOBAL_STATE);

if (result_bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG, "Connected to SSID: %s", GLOBAL_STATE.SYSTEM_MODULE.ssid);
//strncpy(GLOBAL_STATE.SYSTEM_MODULE.wifi_status, "Connected!", 20);
mainStateMachine.state = MAIN_STATE_ASIC_INIT;
Network_AP_off();
eventBits = xEventGroupSetBits(mainEventGroup, eBIT_0);
continue;
} else if (result_bits & WIFI_FAIL_BIT) {
ESP_LOGE(TAG, "Failed to connect to SSID: %s", GLOBAL_STATE.SYSTEM_MODULE.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.");
//wait 1 second
vTaskDelay(1000 / portTICK_PERIOD_MS);
continue;
} 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.");
//wait 1 second
vTaskDelay(1000 / portTICK_PERIOD_MS);
continue;
}
break;

case MAIN_STATE_ASIC_INIT:
//initialize the stratum queues
queue_init(&GLOBAL_STATE.stratum_queue);
queue_init(&GLOBAL_STATE.ASIC_jobs_queue);

//init serial ports and buffers for ASIC communications
SERIAL_init();
//call the ASIC init function (pointer)
(*GLOBAL_STATE.ASIC_functions.init_fn)(GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value, GLOBAL_STATE.asic_count);
SERIAL_set_baud((*GLOBAL_STATE.ASIC_functions.set_max_baud_fn)());
SERIAL_clear_buffer();

mainStateMachine.state = MAIN_STATE_POOL_CONNECT;
break;

case MAIN_STATE_POOL_CONNECT:
xTaskCreate(stratum_task, "stratum task", 8192, (void *) &GLOBAL_STATE, 5, NULL);
xTaskCreate(create_jobs_task, "create jobs task", 8192, (void *) &GLOBAL_STATE, 10, NULL);
mainStateMachine.state = MAIN_STATE_MINING_INIT;
break;

case MAIN_STATE_MINING_INIT:
xTaskCreate(ASIC_task, "asic task", 8192, (void *) &GLOBAL_STATE, 10, NULL);
xTaskCreate(ASIC_result_task, "asic result task", 8192, (void *) &GLOBAL_STATE, 15, NULL);
mainStateMachine.state = MAIN_STATE_IDLE;
break;

case MAIN_STATE_IDLE:
//wait here for 5s or an event
eventBits = xEventGroupWaitBits(
mainEventGroup,
eBIT_0 | eBIT_1, //events to wait for
pdTRUE, // Clear event bits before returning
pdFALSE, // only require one bit to be set
10000 / portTICK_PERIOD_MS); // timeout
break;

default:
break;
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions main/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@

#include "connect.h"

/* Generic bit definitions. */
#define eBIT_0 ( 0x01UL )
#define eBIT_1 ( 0x02UL )
#define eBIT_2 ( 0x04UL )
#define eBIT_3 ( 0x08UL )
#define eBIT_4 ( 0x10UL )
#define eBIT_5 ( 0x20UL )
#define eBIT_6 ( 0x40UL )
#define eBIT_7 ( 0x80UL )

void MINER_set_wifi_status(wifi_status_t status, uint16_t retry_count);

#endif /* MAIN_H_ */
55 changes: 28 additions & 27 deletions main/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@

#include "display_task.h"
#include "http_server.h"
#include "connect.h"
#include "network.h"

static const char * TAG = "network";
//static const char * TAG = "network";

esp_err_t Network_connect(GlobalState * GLOBAL_STATE) {
EventBits_t Network_connect(GlobalState * GLOBAL_STATE) {

char * wifi_ssid;
char * wifi_pass;
Expand All @@ -26,35 +25,37 @@ esp_err_t Network_connect(GlobalState * GLOBAL_STATE) {
// init and connect to wifi
wifi_init(wifi_ssid, wifi_pass, hostname);
start_rest_server((void *) GLOBAL_STATE);
EventBits_t result_bits = wifi_connect();

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) {
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) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
} 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) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}

free(wifi_ssid);
free(wifi_pass);
free(hostname);

return ESP_OK;
//EventBits_t result_bits = wifi_connect(); //wait here forever for wifi to connect

return wifi_connect(); //wait here forever for wifi to connect

// 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) {
// 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) {
// vTaskDelay(1000 / portTICK_PERIOD_MS);
// }
// } 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) {
// vTaskDelay(1000 / portTICK_PERIOD_MS);
// }
// }
//return ESP_OK;
}

void Network_AP_off(void) {
Expand Down
3 changes: 2 additions & 1 deletion main/network.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "esp_err.h"
#include "global_state.h"
#include "connect.h"

esp_err_t Network_connect(GlobalState *);
EventBits_t Network_connect(GlobalState *);
void Network_AP_off(void);
void Network_set_wifi_status(GlobalState * GLOBAL_STATE, wifi_status_t status, uint16_t retry_count);
37 changes: 24 additions & 13 deletions main/tasks/display_task.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ EventGroupHandle_t displayEventGroup;

//static variables
static const char * TAG = "DisplayTask";
static uint8_t current_screen;

//static function prototypes
static void IRAM_ATTR gpio_isr_handler(void* arg);
Expand Down Expand Up @@ -59,7 +58,7 @@ void DISPLAY_task(void * pvParameters) {

init_gpio(); // Initialize GPIO for button input

current_screen = 0;
module->screen_page = 0;

ESP_LOGI(TAG, "DISPLAY_task started");

Expand All @@ -69,17 +68,27 @@ void DISPLAY_task(void * pvParameters) {
the event group. Clear the bits before exiting. */
eventBits = xEventGroupWaitBits(
displayEventGroup, /* The event group being tested. */
eBIT_0 | eBIT_4, /* The bits within the event group to wait for. */
BUTTON_BIT | OVERHEAT_BIT, /* The bits within the event group to wait for. */
pdTRUE, /* BIT_0 & BIT_4 should be cleared before returning. */
pdFALSE, /* Don't wait for both bits, either bit will do. */
(10000 / portTICK_PERIOD_MS) ); /* Wait a maximum of 10s for either bit to be set. */

//debounce button
if (eventBits & BUTTON_BIT) {
vTaskDelay(100 / portTICK_PERIOD_MS);
}

//catch overheat event
if (eventBits & OVERHEAT_BIT) {
displayStateMachine.state = DISPLAY_STATE_ERROR;
}

//clear display
System_clear_display(GLOBAL_STATE);

switch (displayStateMachine.state) {
case DISPLAY_STATE_SPLASH:
splash_screen(&GLOBAL_STATE);
splash_screen(GLOBAL_STATE);
displayStateMachine.state = DISPLAY_STATE_INIT;
break;

Expand All @@ -89,15 +98,15 @@ void DISPLAY_task(void * pvParameters) {

case DISPLAY_STATE_MINING:

if (eventBits & eBIT_0) {
if (eventBits & BUTTON_BIT) {
// Handle button press
ESP_LOGI(TAG, "Button pressed, switching to next screen");
ESP_LOGI(TAG, "Button pressed, next screen: %d", module->screen_page);
// Handle button press logic here
} else {
ESP_LOGI(TAG, "No button press detected, cycling through screens");
}

switch (current_screen) {
switch (module->screen_page) {
case 0:
System_update_system_performance(GLOBAL_STATE);
break;
Expand All @@ -108,11 +117,12 @@ void DISPLAY_task(void * pvParameters) {
System_update_esp32_info(GLOBAL_STATE);
break;
}
current_screen = (current_screen + 1) % 3;
module->screen_page = (module->screen_page + 1) % 3;

break;
case DISPLAY_STATE_ERROR:
// Handle off state
System_show_overheat_screen(GLOBAL_STATE);
SYSTEM_update_overheat_mode(GLOBAL_STATE); // Check for changes
break;
default:
// Handle unknown state
Expand Down Expand Up @@ -169,6 +179,7 @@ static void splash_screen(GlobalState * GLOBAL_STATE) {
char display_data[20];

snprintf(display_data, 20, "bitaxe%s %d", GLOBAL_STATE->device_model_str, GLOBAL_STATE->board_version);
ESP_LOGI(TAG, "Displaying splash screen: %s", display_data);

switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
Expand Down Expand Up @@ -197,9 +208,9 @@ void System_init_connection(GlobalState * GLOBAL_STATE)
case DEVICE_SUPRA:
case DEVICE_GAMMA:
if (OLED_status()) {
memset(module->oled_buf, 0, 20);
snprintf(module->oled_buf, 20, "Connecting to SSID:");
OLED_writeString(0, 0, module->oled_buf);
OLED_clear();
OLED_writeString(0, 0, "Connecting to WiFi:");
OLED_writeString(0, 1, module->ssid);
}
break;
default:
Expand Down Expand Up @@ -232,7 +243,7 @@ static void IRAM_ATTR gpio_isr_handler(void* arg) {
// Set bit 0 and bit 4 in xEventGroup.
xResult = xEventGroupSetBitsFromISR(
displayEventGroup, // The event group being updated.
eBIT_0, // The bits being set.
BUTTON_BIT, // The bits being set.
&xHigherPriorityTaskWoken);

// Was the message posted successfully?
Expand Down
Loading

0 comments on commit d99c255

Please sign in to comment.