Make selftest failing non-fatal (#524)

* switched selftest fail to be non fatal

* switched to BOOT longpress to reboot after selftest

* lots and lots of error handling cleanup. <slippery slope>

* move around the DS4432U_Init() function call
This commit is contained in:
Skot 2024-11-30 09:02:09 -06:00 committed by GitHub
parent e9b30ba779
commit 22cb8bf4e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 339 additions and 173 deletions

View File

@ -5,10 +5,10 @@
#define CHUNK_SIZE 1024
int SERIAL_send(uint8_t *, int, bool);
void SERIAL_init(void);
esp_err_t SERIAL_init(void);
void SERIAL_debug_rx(void);
int16_t SERIAL_rx(uint8_t *, uint16_t, uint16_t);
void SERIAL_clear_buffer(void);
void SERIAL_set_baud(int baud);
esp_err_t SERIAL_set_baud(int baud);
#endif /* SERIAL_H_ */

View File

@ -20,7 +20,7 @@
static const char *TAG = "serial";
void SERIAL_init(void)
esp_err_t SERIAL_init(void)
{
ESP_LOGI(TAG, "Initializing serial");
// Configure UART1 parameters
@ -33,24 +33,26 @@ void SERIAL_init(void)
.rx_flow_ctrl_thresh = 122,
};
// Configure UART1 parameters
uart_param_config(UART_NUM_1, &uart_config);
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_param_config(UART_NUM_1, &uart_config));
// Set UART1 pins(TX: IO17, RX: I018)
uart_set_pin(UART_NUM_1, ECHO_TEST_TXD, ECHO_TEST_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_set_pin(UART_NUM_1, ECHO_TEST_TXD, ECHO_TEST_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
// Install UART driver (we don't need an event queue here)
// tx buffer 0 so the tx time doesn't overlap with the job wait time
// by returning before the job is written
uart_driver_install(UART_NUM_1, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0);
return uart_driver_install(UART_NUM_1, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0);
}
void SERIAL_set_baud(int baud)
esp_err_t SERIAL_set_baud(int baud)
{
ESP_LOGI(TAG, "Changing UART baud to %i", baud);
// Make sure that we are done writing before setting a new baudrate.
uart_wait_tx_done(UART_NUM_1, 1000 / portTICK_PERIOD_MS);
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_wait_tx_done(UART_NUM_1, 1000 / portTICK_PERIOD_MS));
uart_set_baudrate(UART_NUM_1, baud);
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_set_baudrate(UART_NUM_1, baud));
return ESP_OK;
}
int SERIAL_send(uint8_t *data, int len, bool debug)

View File

@ -47,12 +47,13 @@ esp_err_t DS4432U_get_current_code(uint8_t output, uint8_t *code) {
return i2c_bitaxe_register_read(ds4432u_dev_handle, reg, code, 1);
}
bool DS4432U_test(void)
esp_err_t DS4432U_test(void)
{
uint8_t data;
/* Read the DS4432U+ WHO_AM_I register, on power up the register should have the value 0x00 */
esp_err_t register_result = i2c_bitaxe_register_read(ds4432u_dev_handle, DS4432U_OUT0_REG, &data, 1);
ESP_RETURN_ON_ERROR(i2c_bitaxe_register_read(ds4432u_dev_handle, DS4432U_OUT0_REG, &data, 1), TAG, "Failed to read DS4432U+ OUT0 register");
ESP_LOGI(TAG, "DS4432U+ OUT0 = 0x%02X", data);
return register_result == ESP_OK;
return ESP_OK;
}

View File

@ -6,7 +6,7 @@
#define DS4432_VRFS 0.997
bool DS4432U_test(void);
esp_err_t DS4432U_test(void);
esp_err_t DS4432U_init(void);
esp_err_t DS4432U_set_current_code(uint8_t output, uint8_t code);
esp_err_t DS4432U_get_current_code(uint8_t output, uint8_t *code);

View File

@ -20,6 +20,7 @@
#include <string.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "nvs_config.h"
#include "i2c_bitaxe.h"
@ -27,6 +28,8 @@
#define OLED_I2C_ADDR 0x3C
static const char * TAG = "oled";
extern unsigned char ucSmallFont[];
static int iScreenOffset; // current write offset of screen data
static unsigned char ucScreen[1024]; // local copy of the image buffer
@ -44,9 +47,7 @@ esp_err_t OLED_init(void)
{
//init the I2C device
if (i2c_bitaxe_add_device(OLED_I2C_ADDR, &ssd1306_dev_handle) != ESP_OK) {
return ESP_FAIL;
}
ESP_RETURN_ON_ERROR(i2c_bitaxe_add_device(OLED_I2C_ADDR, &ssd1306_dev_handle), TAG, "Failed to add display i2c device");
uint8_t oled32_initbuf[] = {0x00,
0xae, // cmd: display off
@ -115,7 +116,8 @@ esp_err_t OLED_init(void)
uc[1] = 0xc0;
write(uc, 2);
}
return true;
return ESP_OK;
}
// Sends a command to turn off the OLED display

View File

@ -1,26 +1,70 @@
#include <string.h>
// #include "freertos/event_groups.h"
// #include "freertos/timers.h"
// #include "driver/gpio.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "i2c_bitaxe.h"
#include "DS4432U.h"
#include "EMC2101.h"
#include "INA260.h"
#include "adc.h"
#include "esp_log.h"
#include "global_state.h"
#include "nvs_config.h"
#include "nvs_flash.h"
#include "oled.h"
#include "vcore.h"
#include "utils.h"
#include "string.h"
#include "TPS546.h"
#include "esp_timer.h"
#define BUTTON_BOOT GPIO_NUM_0
#define LONG_PRESS_DURATION_MS 2000 // Define what constitutes a long press
#define ESP_INTR_FLAG_DEFAULT 0 //wtf is this for esp-idf?
#define TESTS_FAILED 0
#define TESTS_PASSED 1
// Define event bits
#define EVENT_SHORT_PRESS 1
#define EVENT_LONG_PRESS 2
/////Test Constants/////
//Test Fan Speed
#define FAN_SPEED_TARGET_MIN 1000 //RPM
//Test Core Voltage
#define CORE_VOLTAGE_TARGET_MIN 1000 //mV
#define CORE_VOLTAGE_TARGET_MAX 1300 //mV
//Test Power Consumption
#define POWER_CONSUMPTION_TARGET_SUB_402 12 //watts
#define POWER_CONSUMPTION_TARGET_402 5 //watts
#define POWER_CONSUMPTION_TARGET_GAMMA 11 //watts
#define POWER_CONSUMPTION_MARGIN 3 //+/- watts
//test hashrate
#define HASHRATE_TARGET_GAMMA 900 //GH/s
#define HASHRATE_TARGET_SUPRA 500 //GH/s
// #define HASHRATE_TARGET_ULTRA 1000 //GH/s
// #define HASHRATE_TARGET_MAX 2000 //GH/s
static const char * TAG = "self_test";
// Create an event group
EventGroupHandle_t xTestsEventGroup;
TimerHandle_t xButtonTimer;
bool button_pressed = false;
//local function prototypes
static void tests_done(GlobalState * GLOBAL_STATE, bool test_result);
static void configure_button_boot_interrupt(void);
void vButtonTimerCallback(TimerHandle_t xTimer);
bool should_test(GlobalState * GLOBAL_STATE) {
bool is_max = GLOBAL_STATE->asic_model == ASIC_BM1397;
uint64_t best_diff = nvs_config_get_u64(NVS_CONFIG_BEST_DIFF, 0);
@ -42,32 +86,14 @@ static void display_msg(char * msg, GlobalState * GLOBAL_STATE) {
if (OLED_status()) {
memset(module->oled_buf, 0, 20);
snprintf(module->oled_buf, 20, msg);
OLED_writeString(0, 2, module->oled_buf);
OLED_writeString(0, 1, module->oled_buf);
}
break;
default:
}
}
static void display_end_screen(GlobalState * GLOBAL_STATE) {
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
case DEVICE_GAMMA:
if (OLED_status()) {
OLED_clearLine(2);
OLED_writeString(0, 2, "TESTS PASS!");
OLED_clearLine(3);
OLED_writeString(0, 3, " PRESS RESET");
}
break;
default:
}
}
static bool fan_sense_pass(GlobalState * GLOBAL_STATE)
static esp_err_t test_fan_sense(GlobalState * GLOBAL_STATE)
{
uint16_t fan_speed = 0;
switch (GLOBAL_STATE->device_model) {
@ -80,134 +106,141 @@ static bool fan_sense_pass(GlobalState * GLOBAL_STATE)
default:
}
ESP_LOGI(TAG, "fanSpeed: %d", fan_speed);
if (fan_speed > 1000) {
return true;
if (fan_speed > FAN_SPEED_TARGET_MIN) {
return ESP_OK;
}
return false;
//fan test failed
ESP_LOGE(TAG, "FAN test failed!");
display_msg("FAN:WARN", GLOBAL_STATE);
return ESP_FAIL;
}
static bool INA260_power_consumption_pass(int target_power, int margin)
static esp_err_t test_INA260_power_consumption(int target_power, int margin)
{
float power = INA260_read_power() / 1000;
ESP_LOGI(TAG, "Power: %f", power);
if (power > target_power -margin && power < target_power +margin) {
return true;
return ESP_OK;
}
return false;
return ESP_FAIL;
}
static bool TPS546_power_consumption_pass(int target_power, int margin)
static esp_err_t test_TPS546_power_consumption(int target_power, int margin)
{
float voltage = TPS546_get_vout();
float current = TPS546_get_iout();
float power = voltage * current;
ESP_LOGI(TAG, "Power: %f, Voltage: %f, Current %f", power, voltage, current);
if (power > target_power -margin && power < target_power +margin) {
return true;
return ESP_OK;
}
return false;
return ESP_FAIL;
}
static bool core_voltage_pass(GlobalState * GLOBAL_STATE)
static esp_err_t test_core_voltage(GlobalState * GLOBAL_STATE)
{
uint16_t core_voltage = VCORE_get_voltage_mv(GLOBAL_STATE);
ESP_LOGI(TAG, "Voltage: %u", core_voltage);
if (core_voltage > 1000 && core_voltage < 1300) {
return true;
if (core_voltage > CORE_VOLTAGE_TARGET_MIN && core_voltage < CORE_VOLTAGE_TARGET_MAX) {
return ESP_OK;
}
return false;
//tests failed
ESP_LOGE(TAG, "Core Voltage TEST FAIL, INCORRECT CORE VOLTAGE");
display_msg("VCORE:FAIL", GLOBAL_STATE);
return ESP_FAIL;
}
void self_test(void * pvParameters)
{
GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters;
ESP_LOGI(TAG, "Running Self Tests");
esp_err_t test_display(GlobalState * GLOBAL_STATE) {
// Display testing
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
case DEVICE_GAMMA:
if (!OLED_init()) {
ESP_LOGE(TAG, "OLED init failed!");
} else {
ESP_LOGI(TAG, "OLED init success!");
// clear the oled screen
OLED_fill(0);
OLED_writeString(0, 0, "BITAXE SELF TESTING");
}
ESP_RETURN_ON_ERROR(OLED_init(), TAG, "OLED init failed!");
ESP_LOGI(TAG, "OLED init success!");
// clear the oled screen
OLED_fill(0);
OLED_writeString(0, 0, "BITAXE SELF TESTING");
break;
default:
}
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128);
GLOBAL_STATE->valid_jobs = malloc(sizeof(uint8_t) * 128);
return ESP_OK;
}
for (int i = 0; i < 128; i++) {
esp_err_t init_voltage_regulator(GlobalState * GLOBAL_STATE) {
ESP_RETURN_ON_ERROR(VCORE_init(GLOBAL_STATE), TAG, "VCORE init failed!");
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[i] = NULL;
GLOBAL_STATE->valid_jobs[i] = 0;
}
ESP_RETURN_ON_ERROR(VCORE_set_voltage(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0, GLOBAL_STATE), TAG, "VCORE set voltage failed!");
return ESP_OK;
}
esp_err_t test_voltage_regulator(GlobalState * GLOBAL_STATE) {
//enable the voltage regulator GPIO on HW that supports it
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
case DEVICE_GAMMA:
// turn ASIC on
gpio_set_direction(GPIO_NUM_10, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_10, 0);
break;
default:
}
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
EMC2101_set_fan_speed(1);
break;
case DEVICE_GAMMA:
EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1));
EMC2101_set_fan_speed(1);
EMC2101_set_ideality_factor(EMC2101_IDEALITY_1_0319);
EMC2101_set_beta_compensation(EMC2101_BETA_11);
break;
default:
}
uint8_t result = VCORE_init(GLOBAL_STATE);
VCORE_set_voltage(nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE, CONFIG_ASIC_VOLTAGE) / 1000.0, GLOBAL_STATE);
if (init_voltage_regulator(GLOBAL_STATE) != ESP_OK) {
ESP_LOGE(TAG, "VCORE init failed!");
display_msg("VCORE:FAIL", GLOBAL_STATE);
//tests_done(GLOBAL_STATE, TESTS_FAILED);
return ESP_FAIL;
}
// VCore regulator testing
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
if (GLOBAL_STATE->board_version >= 402 && GLOBAL_STATE->board_version <= 499){
if (result != 0) {
ESP_LOGE(TAG, "TPS546 test failed!");
display_msg("TPS546:FAIL", GLOBAL_STATE);
return;
}
} else {
if(!DS4432U_test()) {
if (GLOBAL_STATE->board_version < 402){
if (DS4432U_test() != ESP_OK) {
ESP_LOGE(TAG, "DS4432 test failed!");
display_msg("DS4432U:FAIL", GLOBAL_STATE);
return;
//tests_done(GLOBAL_STATE, TESTS_FAILED);
return ESP_FAIL;
}
}
break;
case DEVICE_GAMMA:
if (result != 0) {
ESP_LOGE(TAG, "TPS546 test failed!");
display_msg("TPS546:FAIL", GLOBAL_STATE);
return;
}
break;
default:
}
ESP_LOGI(TAG, "Voltage Regulator test success!");
return ESP_OK;
}
esp_err_t test_init_peripherals(GlobalState * GLOBAL_STATE) {
//Init the EMC2101 fan and temperature monitoring
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
ESP_RETURN_ON_ERROR(EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1)), TAG, "EMC2101 init failed!");
EMC2101_set_fan_speed(1);
break;
case DEVICE_GAMMA:
ESP_RETURN_ON_ERROR(EMC2101_init(nvs_config_get_u16(NVS_CONFIG_INVERT_FAN_POLARITY, 1)), TAG, "EMC2101 init failed!");
EMC2101_set_fan_speed(1);
EMC2101_set_ideality_factor(EMC2101_IDEALITY_1_0319);
EMC2101_set_beta_compensation(EMC2101_BETA_11);
break;
default:
}
@ -219,29 +252,90 @@ void self_test(void * pvParameters)
case DEVICE_SUPRA:
if (GLOBAL_STATE->board_version < 402) {
// Initialize the LED controller
INA260_init();
ESP_RETURN_ON_ERROR(INA260_init(), TAG, "INA260 init failed!");
}
break;
case DEVICE_GAMMA:
default:
}
ESP_LOGI(TAG, "Peripherals init success!");
return ESP_OK;
}
/**
* @brief Perform a self-test of the system.
*
* This function is intended to be run as a task and will execute a series of
* diagnostic tests to ensure the system is functioning correctly.
*
* @param pvParameters Pointer to the parameters passed to the task (if any).
*/
void self_test(void * pvParameters)
{
GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters;
ESP_LOGI(TAG, "Running Self Tests");
//create the button timer for long press detection
xButtonTimer = xTimerCreate("ButtonTimer", pdMS_TO_TICKS(LONG_PRESS_DURATION_MS), pdFALSE, (void*)0, vButtonTimerCallback);
configure_button_boot_interrupt();
//Run display tests
if (test_display(GLOBAL_STATE) != ESP_OK) {
ESP_LOGE(TAG, "Display test failed!");
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
//Init peripherals EMC2101 and INA260 (if present)
if (test_init_peripherals(GLOBAL_STATE) != ESP_OK) {
ESP_LOGE(TAG, "Peripherals init failed!");
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
//Voltage Regulator Testing
if (test_voltage_regulator(GLOBAL_STATE) != ESP_OK) {
ESP_LOGE(TAG, "Voltage Regulator test failed!");
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
//test for number of ASICs
if (SERIAL_init() != ESP_OK) {
ESP_LOGE(TAG, "SERIAL init failed!");
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
SERIAL_init();
uint8_t chips_detected = (GLOBAL_STATE->ASIC_functions.init_fn)(GLOBAL_STATE->POWER_MANAGEMENT_MODULE.frequency_value, GLOBAL_STATE->asic_count);
ESP_LOGI(TAG, "%u chips detected, %u expected", chips_detected, GLOBAL_STATE->asic_count);
if (chips_detected < 1) {
ESP_LOGE(TAG, "SELF TEST FAIL, NO CHIPS DETECTED");
// ESP_LOGE(TAG, "SELF TEST FAIL, INCORRECT NONCE DIFF");
display_msg("ASIC:FAIL 0 CHIPS", GLOBAL_STATE);
return;
if (chips_detected != GLOBAL_STATE->asic_count) {
ESP_LOGE(TAG, "SELF TEST FAIL, %d of %d CHIPS DETECTED", chips_detected, GLOBAL_STATE->asic_count);
char error_buf[20];
snprintf(error_buf, 20, "ASIC:FAIL %d CHIPS", chips_detected);
display_msg(error_buf, GLOBAL_STATE);
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
//setup and test hashrate
int baud = (*GLOBAL_STATE->ASIC_functions.set_max_baud_fn)();
vTaskDelay(10 / portTICK_PERIOD_MS);
SERIAL_set_baud(baud);
if (SERIAL_set_baud(baud) != ESP_OK) {
ESP_LOGE(TAG, "SERIAL set baud failed!");
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128);
GLOBAL_STATE->valid_jobs = malloc(sizeof(uint8_t) * 128);
for (int i = 0; i < 128; i++) {
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[i] = NULL;
GLOBAL_STATE->valid_jobs[i] = 0;
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
@ -317,29 +411,25 @@ void self_test(void * pvParameters)
case DEVICE_ULTRA:
break;
case DEVICE_SUPRA:
if(hash_rate < 500){
if(hash_rate < HASHRATE_TARGET_SUPRA){
display_msg("HASHRATE:FAIL", GLOBAL_STATE);
return;
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
break;
case DEVICE_GAMMA:
if(hash_rate < 900){
if(hash_rate < HASHRATE_TARGET_GAMMA){
display_msg("HASHRATE:FAIL", GLOBAL_STATE);
return;
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
break;
default:
}
free(GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs);
free(GLOBAL_STATE->valid_jobs);
if (!core_voltage_pass(GLOBAL_STATE)) {
ESP_LOGE(TAG, "SELF TEST FAIL, INCORRECT CORE VOLTAGE");
display_msg("VCORE:FAIL", GLOBAL_STATE);
return;
if (test_core_voltage(GLOBAL_STATE) != ESP_OK) {
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
switch (GLOBAL_STATE->device_model) {
@ -347,65 +437,131 @@ void self_test(void * pvParameters)
case DEVICE_ULTRA:
case DEVICE_SUPRA:
if(GLOBAL_STATE->board_version >= 402 && GLOBAL_STATE->board_version <= 499){
if (!TPS546_power_consumption_pass(POWER_CONSUMPTION_TARGET_402, POWER_CONSUMPTION_MARGIN)) {
if (test_TPS546_power_consumption(POWER_CONSUMPTION_TARGET_402, POWER_CONSUMPTION_MARGIN) != ESP_OK) {
ESP_LOGE(TAG, "TPS546 Power Draw Failed, target %.2f", (float)POWER_CONSUMPTION_TARGET_402);
display_msg("POWER:FAIL", GLOBAL_STATE);
return;
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
} else {
if (!INA260_power_consumption_pass(POWER_CONSUMPTION_TARGET_SUB_402, POWER_CONSUMPTION_MARGIN)) {
if (test_INA260_power_consumption(POWER_CONSUMPTION_TARGET_SUB_402, POWER_CONSUMPTION_MARGIN) != ESP_OK) {
ESP_LOGE(TAG, "INA260 Power Draw Failed, target %.2f", (float)POWER_CONSUMPTION_TARGET_SUB_402);
display_msg("POWER:FAIL", GLOBAL_STATE);
return;
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
}
break;
case DEVICE_GAMMA:
if (!TPS546_power_consumption_pass(POWER_CONSUMPTION_TARGET_GAMMA, POWER_CONSUMPTION_MARGIN)) {
if (test_TPS546_power_consumption(POWER_CONSUMPTION_TARGET_GAMMA, POWER_CONSUMPTION_MARGIN) != ESP_OK) {
ESP_LOGE(TAG, "TPS546 Power Draw Failed, target %.2f", (float)POWER_CONSUMPTION_TARGET_GAMMA);
display_msg("POWER:FAIL", GLOBAL_STATE);
return;
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
break;
default:
}
if (!fan_sense_pass(GLOBAL_STATE)) {
ESP_LOGE(TAG, "FAN test failed!");
display_msg("FAN:WARN", GLOBAL_STATE);
if (test_fan_sense(GLOBAL_STATE) != ESP_OK) {
ESP_LOGE(TAG, "Fan test failed!");
tests_done(GLOBAL_STATE, TESTS_FAILED);
}
tests_done(GLOBAL_STATE, TESTS_PASSED);
ESP_LOGI(TAG, "Self Tests Passed!!!");
return;
}
ESP_LOGI(TAG, "SELF TESTS PASS -- Press RESET to continue");
display_end_screen(GLOBAL_STATE);
nvs_config_set_u16(NVS_CONFIG_SELF_TEST, 0);
static void tests_done(GlobalState * GLOBAL_STATE, bool test_result) {
//blink tests pass screen
// Create event group for the System task
xTestsEventGroup = xEventGroupCreate();
if (test_result == TESTS_PASSED) {
ESP_LOGI(TAG, "SELF TESTS PASS -- Press RESET to continue");
} else {
ESP_LOGI(TAG, "SELF TESTS FAIL -- Press RESET to continue");
}
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
case DEVICE_GAMMA:
if (OLED_status()) {
OLED_clearLine(2);
if (test_result == TESTS_PASSED) {
OLED_writeString(0, 2, "TESTS PASS!");
} else {
OLED_writeString(0, 2, "TESTS FAIL!");
}
OLED_clearLine(3);
OLED_writeString(0, 3, "LONG PRESS BOOT");
}
break;
default:
}
//wait here for a long press to reboot
while (1) {
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
case DEVICE_GAMMA:
if (OLED_status()) {
OLED_clearLine(3);
OLED_writeString(0, 3, " PRESS RESET");
}
break;
default:
EventBits_t uxBits = xEventGroupWaitBits(
xTestsEventGroup,
EVENT_LONG_PRESS,
pdTRUE, // Clear bits on exit
pdFALSE, // Wait for any bit
portMAX_DELAY //wait forever
);
if (uxBits & EVENT_LONG_PRESS) {
ESP_LOGI(TAG, "Long press detected, rebooting");
nvs_config_set_u16(NVS_CONFIG_SELF_TEST, 0);
esp_restart();
}
vTaskDelay(500 / portTICK_PERIOD_MS);
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
case DEVICE_GAMMA:
if (OLED_status()) {
OLED_clearLine(3);
}
break;
default:
}
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void vButtonTimerCallback(TimerHandle_t xTimer) {
// Timer callback, set the long press event bit
xEventGroupSetBits(xTestsEventGroup, EVENT_LONG_PRESS);
}
// Interrupt handler for BUTTON_BOOT
void IRAM_ATTR button_boot_isr_handler(void* arg) {
if (gpio_get_level(BUTTON_BOOT) == 0) {
// Button pressed, start the timer
if (!button_pressed) {
button_pressed = true;
xTimerStartFromISR(xButtonTimer, NULL);
}
} else {
// Button released, stop the timer and check the duration
if (button_pressed) {
button_pressed = false;
if (xTimerIsTimerActive(xButtonTimer)) {
xTimerStopFromISR(xButtonTimer, NULL);
//xEventGroupSetBitsFromISR(xTestsEventGroup, EVENT_SHORT_PRESS, NULL); //we don't care about a short press
}
}
}
}
static void configure_button_boot_interrupt(void) {
// Configure the GPIO pin as input
gpio_config_t io_conf = {
.intr_type = GPIO_INTR_ANYEDGE, // Interrupt on both edges
.mode = GPIO_MODE_INPUT, // Set as input mode
.pin_bit_mask = (1ULL << BUTTON_BOOT), // Bit mask of the pin to configure
.pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down mode
.pull_up_en = GPIO_PULLUP_ENABLE, // Enable pull-up mode
};
gpio_config(&io_conf);
// Install the ISR service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
// Attach the interrupt handler
gpio_isr_handler_add(BUTTON_BOOT, button_boot_isr_handler, NULL);
ESP_LOGI(TAG, "BUTTON_BOOT interrupt configured");
}

View File

@ -21,23 +21,30 @@
static const char *TAG = "vcore.c";
uint8_t VCORE_init(GlobalState * global_state) {
uint8_t result = 0;
esp_err_t VCORE_init(GlobalState * global_state) {
switch (global_state->device_model) {
case DEVICE_MAX:
case DEVICE_ULTRA:
case DEVICE_SUPRA:
if (global_state->board_version >= 402 && global_state->board_version <= 499) {
result = TPS546_init();
if (TPS546_init() != ESP_OK) {
ESP_LOGE(TAG, "TPS546 init failed!");
return ESP_FAIL;
}
} else {
ESP_RETURN_ON_ERROR(DS4432U_init(), TAG, "DS4432 init failed!");
}
break;
case DEVICE_GAMMA:
result = TPS546_init();
if (TPS546_init() != ESP_OK) {
ESP_LOGE(TAG, "TPS546 init failed!");
return ESP_FAIL;
}
break;
// case DEVICE_HEX:
default:
}
return result;
return ESP_OK;
}
/**
@ -68,7 +75,7 @@ static uint8_t ds4432_tps40305_bitaxe_voltage_to_reg(float vout)
return reg;
}
bool VCORE_set_voltage(float core_voltage, GlobalState * global_state)
esp_err_t VCORE_set_voltage(float core_voltage, GlobalState * global_state)
{
switch (global_state->device_model) {
case DEVICE_MAX:
@ -78,11 +85,9 @@ bool VCORE_set_voltage(float core_voltage, GlobalState * global_state)
ESP_LOGI(TAG, "Set ASIC voltage = %.3fV", core_voltage);
TPS546_set_vout(core_voltage * (float)global_state->voltage_domain);
} else {
DS4432U_init();
uint8_t reg_setting = ds4432_tps40305_bitaxe_voltage_to_reg(core_voltage * (float)global_state->voltage_domain);
ESP_LOGI(TAG, "Set ASIC voltage = %.3fV [0x%02X]", core_voltage, reg_setting);
DS4432U_set_current_code(0, reg_setting); /// eek!
ESP_RETURN_ON_ERROR(DS4432U_set_current_code(0, reg_setting), TAG, "DS4432U set current code failed!");
}
break;
case DEVICE_GAMMA:
@ -93,7 +98,7 @@ bool VCORE_set_voltage(float core_voltage, GlobalState * global_state)
default:
}
return true;
return ESP_OK;
}
uint16_t VCORE_get_voltage_mv(GlobalState * global_state) {

View File

@ -3,8 +3,8 @@
#include "global_state.h"
uint8_t VCORE_init(GlobalState * global_state);
bool VCORE_set_voltage(float core_voltage, GlobalState * global_state);
esp_err_t VCORE_init(GlobalState * global_state);
esp_err_t VCORE_set_voltage(float core_voltage, GlobalState * global_state);
uint16_t VCORE_get_voltage_mv(GlobalState * global_state);
#endif /* VCORE_H_ */