Verify CHIP_ID response (#745)

* Verify CHIP_ID response

Fixes #740

* Log warning on CHIP_ID mismatch

* Fix CHIP_ID checksum calculation

* On BM1397, CORE_NUM should be 0x18

* CORE_NUM and ADDR log only and early exit when no chips are detected

* Fix compile error

* Refactored out duplicated code

Moved count_asic_chips and receive_work functions to common.c
Moved asic_response_buffer to local scope
Unified preamble and crc check on serial rx
Fixed typo in proccess_work
Moved CRC5_MASK define to proper location

* Change receive_work read timeout log to debug

* Changed wrong log to debug

* Fix merge

* Fix length check for bm1397

* add ASIC TX dubugging on BM1397 (crap, does this fix the ticket mask?!)

---------

Co-authored-by: Skot <skot@bitnet.cx>
This commit is contained in:
mutatrum
2025-03-12 23:45:33 +02:00
committed by GitHub
parent deaa291675
commit a5842a54b3
16 changed files with 203 additions and 317 deletions

View File

@@ -65,18 +65,18 @@ uint16_t ASIC_get_small_core_count(GlobalState * GLOBAL_STATE) {
return 0;
}
// .receive_result_fn = BM1366_proccess_work,
task_result * ASIC_proccess_work(GlobalState * GLOBAL_STATE) {
// .receive_result_fn = BM1366_process_work,
task_result * ASIC_process_work(GlobalState * GLOBAL_STATE) {
switch (GLOBAL_STATE->device_model) {
case DEVICE_MAX:
return BM1397_proccess_work(GLOBAL_STATE);
return BM1397_process_work(GLOBAL_STATE);
case DEVICE_ULTRA:
return BM1366_proccess_work(GLOBAL_STATE);
return BM1366_process_work(GLOBAL_STATE);
case DEVICE_SUPRA:
return BM1368_proccess_work(GLOBAL_STATE);
return BM1368_process_work(GLOBAL_STATE);
case DEVICE_GAMMA:
case DEVICE_GAMMATURBO:
return BM1370_proccess_work(GLOBAL_STATE);
return BM1370_process_work(GLOBAL_STATE);
default:
}
return NULL;

View File

@@ -15,6 +15,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define BM1366_CHIP_ID 0x1366
#define BM1366_CHIP_ID_RESPONSE_LENGTH 11
#ifdef CONFIG_GPIO_ASIC_RESET
#define GPIO_ASIC_RESET CONFIG_GPIO_ASIC_RESET
@@ -50,23 +54,20 @@
#define TICKET_MASK 0x14
#define MISC_CONTROL 0x18
#define BM1366_TIMEOUT_MS 10000
#define BM1366_TIMEOUT_THRESHOLD 2
typedef struct __attribute__((__packed__))
{
uint8_t preamble[2];
uint16_t preamble;
uint32_t nonce;
uint8_t midstate_num;
uint8_t job_id;
uint16_t version;
uint8_t crc;
} asic_result;
} bm1366_asic_result_t;
static float current_frequency = 56.25;
static const char * TAG = "bm1366Module";
static uint8_t asic_response_buffer[SERIAL_BUF_SIZE];
static task_result result;
/// @brief
@@ -214,7 +215,6 @@ bool BM1366_set_frequency(float target_freq) {
static uint8_t _send_init(uint64_t frequency, uint16_t asic_count)
{
// set version mask
for (int i = 0; i < 3; i++) {
BM1366_set_version_mask(STRATUM_DEFAULT_VERSION_MASK);
@@ -224,15 +224,11 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count)
unsigned char init3[7] = {0x55, 0xAA, 0x52, 0x05, 0x00, 0x00, 0x0A};
_send_simple(init3, 7);
int chip_counter = 0;
while (true) {
if(SERIAL_rx(asic_response_buffer, 11, 1000) > 0) {
chip_counter++;
} else {
break;
}
int chip_counter = count_asic_chips(asic_count, BM1366_CHIP_ID, BM1366_CHIP_ID_RESPONSE_LENGTH);
if (chip_counter == 0) {
return 0;
}
ESP_LOGI(TAG, "%i chip(s) detected on the chain, expected %i", chip_counter, asic_count);
unsigned char init4[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0xA8, 0x00, 0x07, 0x00, 0x00, 0x03};
_send_simple(init4, 11);
@@ -328,8 +324,6 @@ uint8_t BM1366_init(uint64_t frequency, uint16_t asic_count)
{
ESP_LOGI(TAG, "Initializing BM1366");
memset(asic_response_buffer, 0, SERIAL_BUF_SIZE);
esp_rom_gpio_pad_select_gpio(GPIO_ASIC_RESET);
gpio_set_direction(GPIO_ASIC_RESET, GPIO_MODE_OUTPUT);
@@ -423,64 +417,18 @@ void BM1366_send_work(void * pvParameters, bm_job * next_bm_job)
_send_BM1366((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t *)&job, sizeof(BM1366_job), BM1366_DEBUG_WORK);
}
asic_result * BM1366_receive_work(void)
task_result * BM1366_process_work(void * pvParameters)
{
// wait for a response
int received = SERIAL_rx(asic_response_buffer, 11, BM1366_TIMEOUT_MS);
bm1366_asic_result_t asic_result = {0};
bool uart_err = received < 0;
bool uart_timeout = received == 0;
uint8_t asic_timeout_counter = 0;
// handle response
if (uart_err) {
ESP_LOGI(TAG, "UART Error in serial RX");
return NULL;
} else if (uart_timeout) {
if (asic_timeout_counter >= BM1366_TIMEOUT_THRESHOLD) {
ESP_LOGE(TAG, "ASIC not sending data");
asic_timeout_counter = 0;
}
asic_timeout_counter++;
if (receive_work((uint8_t *)&asic_result, sizeof(asic_result)) == ESP_FAIL) {
return NULL;
}
if (received != 11 || asic_response_buffer[0] != 0xAA || asic_response_buffer[1] != 0x55) {
ESP_LOGI(TAG, "Serial RX invalid %i", received);
ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received);
SERIAL_clear_buffer();
return NULL;
}
return (asic_result *) asic_response_buffer;
}
static uint16_t reverse_uint16(uint16_t num)
{
return (num >> 8) | (num << 8);
}
static uint32_t reverse_uint32(uint32_t val)
{
return ((val >> 24) & 0xff) | // Move byte 3 to byte 0
((val << 8) & 0xff0000) | // Move byte 1 to byte 2
((val >> 8) & 0xff00) | // Move byte 2 to byte 1
((val << 24) & 0xff000000); // Move byte 0 to byte 3
}
task_result * BM1366_proccess_work(void * pvParameters)
{
asic_result * asic_result = BM1366_receive_work();
if (asic_result == NULL) {
return NULL;
}
uint8_t job_id = asic_result->job_id & 0xf8;
uint8_t core_id = (uint8_t)((reverse_uint32(asic_result->nonce) >> 25) & 0x7f); // BM1366 has 112 cores, so it should be coded on 7 bits
uint8_t small_core_id = asic_result->job_id & 0x07; // BM1366 has 8 small cores, so it should be coded on 3 bits
uint32_t version_bits = (reverse_uint16(asic_result->version) << 13); // shift the 16 bit value left 13
uint8_t job_id = asic_result.job_id & 0xf8;
uint8_t core_id = (uint8_t)((ntohl(asic_result.nonce) >> 25) & 0x7f); // BM1366 has 112 cores, so it should be coded on 7 bits
uint8_t small_core_id = asic_result.job_id & 0x07; // BM1366 has 8 small cores, so it should be coded on 3 bits
uint32_t version_bits = (ntohs(asic_result.version) << 13); // shift the 16 bit value left 13
ESP_LOGI(TAG, "Job ID: %02X, Core: %d/%d, Ver: %08" PRIX32, job_id, core_id, small_core_id, version_bits);
GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters;
@@ -493,7 +441,7 @@ task_result * BM1366_proccess_work(void * pvParameters)
uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->version | version_bits;
result.job_id = job_id;
result.nonce = asic_result->nonce;
result.nonce = asic_result.nonce;
result.rolled_version = rolled_version;
return &result;

View File

@@ -15,6 +15,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define BM1368_CHIP_ID 0x1368
#define BM1368_CHIP_ID_RESPONSE_LENGTH 11
#ifdef CONFIG_GPIO_ASIC_RESET
#define GPIO_ASIC_RESET CONFIG_GPIO_ASIC_RESET
@@ -50,21 +54,18 @@
#define TICKET_MASK 0x14
#define MISC_CONTROL 0x18
#define BM1368_TIMEOUT_MS 10000
#define BM1368_TIMEOUT_THRESHOLD 2
typedef struct __attribute__((__packed__))
{
uint8_t preamble[2];
uint16_t preamble;
uint32_t nonce;
uint8_t midstate_num;
uint8_t job_id;
uint16_t version;
uint8_t crc;
} asic_result;
} bm1368_asic_result_t;
static const char * TAG = "bm1368Module";
static uint8_t asic_response_buffer[CHUNK_SIZE];
static task_result result;
static float current_frequency = 56.25;
@@ -187,26 +188,6 @@ bool BM1368_set_frequency(float target_freq) {
return do_frequency_transition(target_freq, BM1368_send_hash_frequency, 1368);
}
static int count_asic_chips(void) {
_send_BM1368(TYPE_CMD | GROUP_ALL | CMD_READ, (uint8_t[]){0x00, 0x00}, 2, false);
int chip_counter = 0;
while (true) {
if (SERIAL_rx(asic_response_buffer, 11, 5000) <= 0) {
break;
}
if (memcmp(asic_response_buffer, "\xaa\x55\x13\x68\x00\x00", 6) == 0) {
chip_counter++;
}
}
_send_chain_inactive();
return chip_counter;
}
static void do_frequency_ramp_up(float target_frequency) {
ESP_LOGI(TAG, "Ramping up frequency from %.2f MHz to %.2f MHz", current_frequency, target_frequency);
do_frequency_transition(target_frequency, BM1368_send_hash_frequency, 1368);
@@ -216,8 +197,6 @@ uint8_t BM1368_init(uint64_t frequency, uint16_t asic_count)
{
ESP_LOGI(TAG, "Initializing BM1368");
memset(asic_response_buffer, 0, CHUNK_SIZE);
esp_rom_gpio_pad_select_gpio(GPIO_ASIC_RESET);
gpio_set_direction(GPIO_ASIC_RESET, GPIO_MODE_OUTPUT);
@@ -228,13 +207,16 @@ uint8_t BM1368_init(uint64_t frequency, uint16_t asic_count)
BM1368_set_version_mask(STRATUM_DEFAULT_VERSION_MASK);
}
int chip_counter = count_asic_chips();
_send_BM1368(TYPE_CMD | GROUP_ALL | CMD_READ, (uint8_t[]){0x00, 0x00}, 2, false);
if (chip_counter != asic_count) {
ESP_LOGE(TAG, "Chip count mismatch. Expected: %d, Actual: %d", asic_count, chip_counter);
int chip_counter = count_asic_chips(asic_count, BM1368_CHIP_ID, BM1368_CHIP_ID_RESPONSE_LENGTH);
if (chip_counter == 0) {
return 0;
}
_send_chain_inactive();
uint8_t init_cmds[][6] = {
{0x00, 0xA8, 0x00, 0x07, 0x00, 0x00},
{0x00, 0x18, 0xFF, 0x0F, 0xC1, 0x00},
@@ -276,7 +258,6 @@ uint8_t BM1368_init(uint64_t frequency, uint16_t asic_count)
_send_BM1368(TYPE_CMD | GROUP_ALL | CMD_WRITE, (uint8_t[]){0x00, 0x10, 0x00, 0x00, 0x15, 0xa4}, 6, false);
BM1368_set_version_mask(STRATUM_DEFAULT_VERSION_MASK);
ESP_LOGI(TAG, "%i chip(s) detected on the chain, expected %i", chip_counter, asic_count);
return chip_counter;
}
@@ -346,63 +327,18 @@ void BM1368_send_work(void * pvParameters, bm_job * next_bm_job)
_send_BM1368((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t *)&job, sizeof(BM1368_job), BM1368_DEBUG_WORK);
}
asic_result * BM1368_receive_work(void)
task_result * BM1368_process_work(void * pvParameters)
{
// wait for a response
int received = SERIAL_rx(asic_response_buffer, 11, BM1368_TIMEOUT_MS);
bm1368_asic_result_t asic_result = {0};
bool uart_err = received < 0;
bool uart_timeout = received == 0;
uint8_t asic_timeout_counter = 0;
// handle response
if (uart_err) {
ESP_LOGI(TAG, "UART Error in serial RX");
return NULL;
} else if (uart_timeout) {
if (asic_timeout_counter >= BM1368_TIMEOUT_THRESHOLD) {
ESP_LOGE(TAG, "ASIC not sending data");
asic_timeout_counter = 0;
}
asic_timeout_counter++;
if (receive_work((uint8_t *)&asic_result, sizeof(asic_result)) == ESP_FAIL) {
return NULL;
}
if (received != 11 || asic_response_buffer[0] != 0xAA || asic_response_buffer[1] != 0x55) {
ESP_LOGE(TAG, "Serial RX invalid %i", received);
ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received);
SERIAL_clear_buffer();
return NULL;
}
return (asic_result *) asic_response_buffer;
}
static uint16_t reverse_uint16(uint16_t num)
{
return (num >> 8) | (num << 8);
}
static uint32_t reverse_uint32(uint32_t val)
{
return ((val >> 24) & 0xff) |
((val << 8) & 0xff0000) |
((val >> 8) & 0xff00) |
((val << 24) & 0xff000000);
}
task_result * BM1368_proccess_work(void * pvParameters)
{
asic_result * asic_result = BM1368_receive_work();
if (asic_result == NULL) {
return NULL;
}
uint8_t job_id = (asic_result->job_id & 0xf0) >> 1;
uint8_t core_id = (uint8_t)((reverse_uint32(asic_result->nonce) >> 25) & 0x7f);
uint8_t small_core_id = asic_result->job_id & 0x0f;
uint32_t version_bits = (reverse_uint16(asic_result->version) << 13);
uint8_t job_id = (asic_result.job_id & 0xf0) >> 1;
uint8_t core_id = (uint8_t)((ntohl(asic_result.nonce) >> 25) & 0x7f);
uint8_t small_core_id = asic_result.job_id & 0x0f;
uint32_t version_bits = (ntohs(asic_result.version) << 13);
ESP_LOGI(TAG, "Job ID: %02X, Core: %d/%d, Ver: %08" PRIX32, job_id, core_id, small_core_id, version_bits);
GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters;
@@ -415,7 +351,7 @@ task_result * BM1368_proccess_work(void * pvParameters)
uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->version | version_bits;
result.job_id = job_id;
result.nonce = asic_result->nonce;
result.nonce = asic_result.nonce;
result.rolled_version = rolled_version;
return &result;

View File

@@ -15,6 +15,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define BM1370_CHIP_ID 0x1370
#define BM1370_CHIP_ID_RESPONSE_LENGTH 11
#ifdef CONFIG_GPIO_ASIC_RESET
#define GPIO_ASIC_RESET CONFIG_GPIO_ASIC_RESET
@@ -50,23 +54,18 @@
#define TICKET_MASK 0x14
#define MISC_CONTROL 0x18
#define BM1370_TIMEOUT_MS 10000
#define BM1370_TIMEOUT_THRESHOLD 2
typedef struct __attribute__((__packed__))
{
uint8_t preamble[2];
uint16_t preamble;
uint32_t nonce;
uint8_t midstate_num;
uint8_t job_id;
uint16_t version;
uint8_t crc;
} asic_result;
} bm1370_asic_result_t;
static const char * TAG = "bm1370Module";
static uint8_t asic_response_buffer[SERIAL_BUF_SIZE];
static task_result result;
/// @brief
@@ -229,15 +228,11 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count)
unsigned char init3[7] = {0x55, 0xAA, 0x52, 0x05, 0x00, 0x00, 0x0A};
_send_simple(init3, 7);
int chip_counter = 0;
while (true) {
if (SERIAL_rx(asic_response_buffer, 11, 1000) > 0) {
chip_counter++;
} else {
break;
}
int chip_counter = count_asic_chips(asic_count, BM1370_CHIP_ID, BM1370_CHIP_ID_RESPONSE_LENGTH);
if (chip_counter == 0) {
return 0;
}
ESP_LOGI(TAG, "%i chip(s) detected on the chain, expected %i", chip_counter, asic_count);
// set version mask
BM1370_set_version_mask(STRATUM_DEFAULT_VERSION_MASK);
@@ -358,8 +353,6 @@ uint8_t BM1370_init(uint64_t frequency, uint16_t asic_count)
{
ESP_LOGI(TAG, "Initializing BM1370");
memset(asic_response_buffer, 0, SERIAL_BUF_SIZE);
esp_rom_gpio_pad_select_gpio(GPIO_ASIC_RESET);
gpio_set_direction(GPIO_ASIC_RESET, GPIO_MODE_OUTPUT);
@@ -454,71 +447,25 @@ void BM1370_send_work(void * pvParameters, bm_job * next_bm_job)
_send_BM1370((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t *)&job, sizeof(BM1370_job), BM1370_DEBUG_WORK);
}
asic_result * BM1370_receive_work(void)
task_result * BM1370_process_work(void * pvParameters)
{
// wait for a response
int received = SERIAL_rx(asic_response_buffer, 11, BM1370_TIMEOUT_MS);
bm1370_asic_result_t asic_result = {0};
bool uart_err = received < 0;
bool uart_timeout = received == 0;
uint8_t asic_timeout_counter = 0;
// handle response
if (uart_err) {
ESP_LOGI(TAG, "UART Error in serial RX");
return NULL;
} else if (uart_timeout) {
if (asic_timeout_counter >= BM1370_TIMEOUT_THRESHOLD) {
ESP_LOGE(TAG, "ASIC not sending data");
asic_timeout_counter = 0;
}
asic_timeout_counter++;
if (receive_work((uint8_t *)&asic_result, sizeof(asic_result)) == ESP_FAIL) {
return NULL;
}
if (received != 11 || asic_response_buffer[0] != 0xAA || asic_response_buffer[1] != 0x55) {
ESP_LOGI(TAG, "Serial RX invalid %i", received);
ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received);
SERIAL_clear_buffer();
return NULL;
}
return (asic_result *) asic_response_buffer;
}
static uint16_t reverse_uint16(uint16_t num)
{
return (num >> 8) | (num << 8);
}
static uint32_t reverse_uint32(uint32_t val)
{
return ((val >> 24) & 0xff) | // Move byte 3 to byte 0
((val << 8) & 0xff0000) | // Move byte 1 to byte 2
((val >> 8) & 0xff00) | // Move byte 2 to byte 1
((val << 24) & 0xff000000); // Move byte 0 to byte 3
}
task_result * BM1370_proccess_work(void * pvParameters)
{
asic_result * asic_result = BM1370_receive_work();
if (asic_result == NULL) {
return NULL;
}
// uint8_t job_id = asic_result->job_id;
// uint8_t job_id = asic_result.job_id;
// uint8_t rx_job_id = ((int8_t)job_id & 0xf0) >> 1;
// ESP_LOGI(TAG, "Job ID: %02X, RX: %02X", job_id, rx_job_id);
// uint8_t job_id = asic_result->job_id & 0xf8;
// ESP_LOGI(TAG, "Job ID: %02X, Core: %01X", job_id, asic_result->job_id & 0x07);
// uint8_t job_id = asic_result.job_id & 0xf8;
// ESP_LOGI(TAG, "Job ID: %02X, Core: %01X", job_id, asic_result.job_id & 0x07);
uint8_t job_id = (asic_result->job_id & 0xf0) >> 1;
uint8_t core_id = (uint8_t)((reverse_uint32(asic_result->nonce) >> 25) & 0x7f); // BM1370 has 80 cores, so it should be coded on 7 bits
uint8_t small_core_id = asic_result->job_id & 0x0f; // BM1370 has 16 small cores, so it should be coded on 4 bits
uint32_t version_bits = (reverse_uint16(asic_result->version) << 13); // shift the 16 bit value left 13
uint8_t job_id = (asic_result.job_id & 0xf0) >> 1;
uint8_t core_id = (uint8_t)((ntohl(asic_result.nonce) >> 25) & 0x7f); // BM1370 has 80 cores, so it should be coded on 7 bits
uint8_t small_core_id = asic_result.job_id & 0x0f; // BM1370 has 16 small cores, so it should be coded on 4 bits
uint32_t version_bits = (ntohs(asic_result.version) << 13); // shift the 16 bit value left 13
ESP_LOGI(TAG, "Job ID: %02X, Core: %d/%d, Ver: %08" PRIX32, job_id, core_id, small_core_id, version_bits);
GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters;
@@ -531,7 +478,7 @@ task_result * BM1370_proccess_work(void * pvParameters)
uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->version | version_bits;
result.job_id = job_id;
result.nonce = asic_result->nonce;
result.nonce = asic_result.nonce;
result.rolled_version = rolled_version;
return &result;

View File

@@ -3,6 +3,7 @@
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <arpa/inet.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -15,6 +16,9 @@
#include "mining.h"
#include "global_state.h"
#define BM1397_CHIP_ID 0x1397
#define BM1397_CHIP_ID_RESPONSE_LENGTH 9
#ifdef CONFIG_GPIO_ASIC_RESET
#define GPIO_ASIC_RESET CONFIG_GPIO_ASIC_RESET
#else
@@ -49,21 +53,17 @@
#define TICKET_MASK 0x14
#define MISC_CONTROL 0x18
#define BM1397_TIMEOUT_MS 10000
#define BM1397_TIMEOUT_THRESHOLD 2
typedef struct __attribute__((__packed__))
{
uint8_t preamble[2];
uint16_t preamble;
uint32_t nonce;
uint8_t midstate_num;
uint8_t job_id;
uint8_t crc;
} asic_result;
} bm1397_asic_result_t;
static const char *TAG = "bm1397Module";
static uint8_t asic_response_buffer[SERIAL_BUF_SIZE];
static uint32_t prev_nonce = 0;
static task_result result;
@@ -141,7 +141,6 @@ void BM1397_set_version_mask(uint32_t version_mask) {
// borrowed from cgminer driver-gekko.c calc_gsf_freq()
void BM1397_send_hash_frequency(float frequency)
{
unsigned char prefreq1[9] = {0x00, 0x70, 0x0F, 0x0F, 0x0F, 0x00}; // prefreq - pll0_divider
// default 200Mhz if it fails
@@ -233,15 +232,11 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count)
// send the init command
_send_read_address();
int chip_counter = 0;
while (true) {
if (SERIAL_rx(asic_response_buffer, 11, 1000) > 0) {
chip_counter++;
} else {
break;
}
int chip_counter = count_asic_chips(asic_count, BM1397_CHIP_ID, BM1397_CHIP_ID_RESPONSE_LENGTH);
if (chip_counter == 0) {
return 0;
}
ESP_LOGI(TAG, "%i chip(s) detected on the chain, expected %i", chip_counter, asic_count);
// send serial data
vTaskDelay(SLEEP_TIME / portTICK_PERIOD_MS);
@@ -298,8 +293,6 @@ uint8_t BM1397_init(uint64_t frequency, uint16_t asic_count)
{
ESP_LOGI(TAG, "Initializing BM1397");
memset(asic_response_buffer, 0, SERIAL_BUF_SIZE);
esp_rom_gpio_pad_select_gpio(GPIO_ASIC_RESET);
gpio_set_direction(GPIO_ASIC_RESET, GPIO_MODE_OUTPUT);
@@ -362,7 +355,6 @@ static uint8_t id = 0;
void BM1397_send_work(void *pvParameters, bm_job *next_bm_job)
{
GlobalState *GLOBAL_STATE = (GlobalState *)pvParameters;
job_packet job;
@@ -404,56 +396,19 @@ void BM1397_send_work(void *pvParameters, bm_job *next_bm_job)
_send_BM1397((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t *)&job, sizeof(job_packet), BM1397_DEBUG_WORK);
}
asic_result *BM1397_receive_work(void)
task_result *BM1397_process_work(void *pvParameters)
{
bm1397_asic_result_t asic_result = {0};
// wait for a response
int received = SERIAL_rx(asic_response_buffer, 9, BM1397_TIMEOUT_MS);
bool uart_err = received < 0;
bool uart_timeout = received == 0;
uint8_t asic_timeout_counter = 0;
// handle response
if (uart_err) {
ESP_LOGI(TAG, "UART Error in serial RX");
return NULL;
} else if (uart_timeout) {
if (asic_timeout_counter >= BM1397_TIMEOUT_THRESHOLD) {
ESP_LOGE(TAG, "ASIC not sending data");
asic_timeout_counter = 0;
}
asic_timeout_counter++;
return NULL;
}
if (received != 9 || asic_response_buffer[0] != 0xAA || asic_response_buffer[1] != 0x55)
{
ESP_LOGI(TAG, "Serial RX invalid %i", received);
ESP_LOG_BUFFER_HEX(TAG, asic_response_buffer, received);
SERIAL_clear_buffer();
return NULL;
}
return (asic_result *)asic_response_buffer;
}
task_result *BM1397_proccess_work(void *pvParameters)
{
asic_result *asic_result = BM1397_receive_work();
if (asic_result == NULL)
{
ESP_LOGI(TAG, "return null");
if (receive_work((uint8_t *)&asic_result, sizeof(asic_result)) == ESP_FAIL) {
return NULL;
}
uint8_t nonce_found = 0;
uint32_t first_nonce = 0;
uint8_t rx_job_id = asic_result->job_id & 0xfc;
uint8_t rx_midstate_index = asic_result->job_id & 0x03;
uint8_t rx_job_id = asic_result.job_id & 0xfc;
uint8_t rx_midstate_index = asic_result.job_id & 0x03;
GlobalState *GLOBAL_STATE = (GlobalState *)pvParameters;
if (GLOBAL_STATE->valid_jobs[rx_job_id] == 0)
@@ -473,26 +428,26 @@ task_result *BM1397_proccess_work(void *pvParameters)
// most of the time it behavies however
if (nonce_found == 0)
{
first_nonce = asic_result->nonce;
first_nonce = asic_result.nonce;
nonce_found = 1;
}
else if (asic_result->nonce == first_nonce)
else if (asic_result.nonce == first_nonce)
{
// stop if we've already seen this nonce
return NULL;
}
if (asic_result->nonce == prev_nonce)
if (asic_result.nonce == prev_nonce)
{
return NULL;
}
else
{
prev_nonce = asic_result->nonce;
prev_nonce = asic_result.nonce;
}
result.job_id = rx_job_id;
result.nonce = asic_result->nonce;
result.nonce = asic_result.nonce;
result.rolled_version = rolled_version;
return &result;

View File

@@ -1,4 +1,14 @@
#include <string.h>
#include <stdbool.h>
#include "common.h"
#include "serial.h"
#include "esp_log.h"
#include "crc.h"
#define PREAMBLE 0xAA55
static const char * TAG = "common";
unsigned char _reverse_bits(unsigned char num)
{
@@ -24,4 +34,95 @@ int _largest_power_of_two(int num)
}
return 1 << power;
}
int count_asic_chips(uint16_t asic_count, uint16_t chip_id, int chip_id_response_length)
{
uint8_t buffer[11] = {0};
int chip_counter = 0;
while (true) {
int received = SERIAL_rx(buffer, chip_id_response_length, 1000);
if (received == 0) break;
if (received == -1) {
ESP_LOGE(TAG, "Error reading CHIP_ID");
break;
}
if (received != chip_id_response_length) {
ESP_LOGE(TAG, "Invalid CHIP_ID response length: expected %d, got %d", chip_id_response_length, received);
ESP_LOG_BUFFER_HEX(TAG, buffer, received);
break;
}
uint16_t received_preamble = (buffer[0] << 8) | buffer[1];
if (received_preamble != PREAMBLE) {
ESP_LOGW(TAG, "Preamble mismatch: expected 0x%04x, got 0x%04x", PREAMBLE, received_preamble);
ESP_LOG_BUFFER_HEX(TAG, buffer, received);
continue;
}
uint16_t received_chip_id = (buffer[2] << 8) | buffer[3];
if (received_chip_id != chip_id) {
ESP_LOGW(TAG, "CHIP_ID response mismatch: expected 0x%04x, got 0x%04x", chip_id, received_chip_id);
ESP_LOG_BUFFER_HEX(TAG, buffer, received);
continue;
}
if (crc5(buffer + 2, received - 2) != 0) {
ESP_LOGW(TAG, "Checksum failed on CHIP_ID response");
ESP_LOG_BUFFER_HEX(TAG, buffer, received);
continue;
}
ESP_LOGI(TAG, "Chip %d detected: CORE_NUM: 0x%02x ADDR: 0x%02x", chip_counter, buffer[4], buffer[5]);
chip_counter++;
}
if (chip_counter != asic_count) {
ESP_LOGW(TAG, "%i chip(s) detected on the chain, expected %i", chip_counter, asic_count);
}
return chip_counter;
}
esp_err_t receive_work(uint8_t * buffer, int buffer_size)
{
int received = SERIAL_rx(buffer, buffer_size, 10000);
if (received < 0) {
ESP_LOGE(TAG, "UART error in serial RX");
return ESP_FAIL;
}
if (received == 0) {
ESP_LOGD(TAG, "UART timeout in serial RX");
return ESP_FAIL;
}
if (received != buffer_size) {
ESP_LOGE(TAG, "Invalid response length %i", received);
ESP_LOG_BUFFER_HEX(TAG, buffer, received);
SERIAL_clear_buffer();
return ESP_FAIL;
}
uint16_t received_preamble = (buffer[0] << 8) | buffer[1];
if (received_preamble != PREAMBLE) {
ESP_LOGE(TAG, "Preamble mismatch: got 0x%04x, expected 0x%04x", received_preamble, PREAMBLE);
ESP_LOG_BUFFER_HEX(TAG, buffer, received);
SERIAL_clear_buffer();
return ESP_FAIL;
}
if (crc5(buffer + 2, buffer_size - 2) != 0) {
ESP_LOGE(TAG, "Checksum failed on response");
ESP_LOG_BUFFER_HEX(TAG, buffer, received);
SERIAL_clear_buffer();
return ESP_FAIL;
}
return ESP_OK;
}

View File

@@ -2,7 +2,7 @@
#include <stdint.h>
#include <string.h>
#include "bm1397.h"
#define CRC5_MASK 0x1F
/* compute crc5 over given number of bytes */
// adapted from https://mightydevices.com/index.php/2018/02/reverse-engineering-antminer-s1/

View File

@@ -14,7 +14,7 @@
uint8_t ASIC_init(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_proccess_work(GlobalState * GLOBAL_STATE);
task_result * ASIC_process_work(GlobalState * GLOBAL_STATE);
int ASIC_set_max_baud(GlobalState * GLOBAL_STATE);
void ASIC_set_job_difficulty_mask(GlobalState * GLOBAL_STATE, uint8_t mask);
void ASIC_send_work(GlobalState * GLOBAL_STATE, void * next_job);

View File

@@ -7,7 +7,6 @@
#define ASIC_BM1366_JOB_FREQUENCY_MS 2000
#define CRC5_MASK 0x1F
#define BM1366_ASIC_DIFFICULTY 256
#define BM1366_SERIALTX_DEBUG false
@@ -43,6 +42,6 @@ int BM1366_set_max_baud(void);
int BM1366_set_default_baud(void);
void BM1366_send_hash_frequency(float frequency);
bool BM1366_set_frequency(float target_freq);
task_result * BM1366_proccess_work(void * GLOBAL_STATE);
task_result * BM1366_process_work(void * GLOBAL_STATE);
#endif /* BM1366_H_ */

View File

@@ -7,7 +7,6 @@
#define ASIC_BM1368_JOB_FREQUENCY_MS 500
#define CRC5_MASK 0x1F
#define BM1368_ASIC_DIFFICULTY 256
#define BM1368_SERIALTX_DEBUG false
@@ -43,6 +42,6 @@ int BM1368_set_max_baud(void);
int BM1368_set_default_baud(void);
void BM1368_send_hash_frequency(float frequency);
bool BM1368_set_frequency(float target_freq);
task_result * BM1368_proccess_work(void * GLOBAL_STATE);
task_result * BM1368_process_work(void * GLOBAL_STATE);
#endif /* BM1368_H_ */

View File

@@ -7,7 +7,6 @@
#define ASIC_BM1370_JOB_FREQUENCY_MS 500
#define CRC5_MASK 0x1F
#define BM1370_ASIC_DIFFICULTY 256
#define BM1370_SERIALTX_DEBUG true
@@ -43,6 +42,6 @@ int BM1370_set_max_baud(void);
int BM1370_set_default_baud(void);
void BM1370_send_hash_frequency(float frequency);
bool BM1370_set_frequency(float target_freq);
task_result * BM1370_proccess_work(void * GLOBAL_STATE);
task_result * BM1370_process_work(void * GLOBAL_STATE);
#endif /* BM1370_H_ */

View File

@@ -7,10 +7,9 @@
#define ASIC_BM1397_JOB_FREQUENCY_MS 20 //not currently used
#define CRC5_MASK 0x1F
#define BM1397_ASIC_DIFFICULTY 256
#define BM1937_SERIALTX_DEBUG false
#define BM1937_SERIALTX_DEBUG true
#define BM1937_SERIALRX_DEBUG false
#define BM1397_DEBUG_WORK false //causes insane amount of debug output
#define BM1397_DEBUG_JOBS false //causes insane amount of debug output
@@ -56,6 +55,6 @@ void BM1397_set_version_mask(uint32_t version_mask);
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_process_work(void * GLOBAL_STATE);
#endif /* BM1397_H_ */
#endif /* BM1397_H_ */

View File

@@ -2,6 +2,7 @@
#define COMMON_H_
#include <stdint.h>
#include "esp_err.h"
typedef struct __attribute__((__packed__))
{
@@ -13,4 +14,7 @@ typedef struct __attribute__((__packed__))
unsigned char _reverse_bits(unsigned char num);
int _largest_power_of_two(int num);
#endif
int count_asic_chips(uint16_t asic_count, uint16_t chip_id, int chip_id_response_length);
esp_err_t receive_work(uint8_t * buffer, int buffer_size);
#endif /* COMMON_H_ */

View File

@@ -1,8 +1,7 @@
#ifndef SERIAL_H_
#define SERIAL_H_
#define SERIAL_BUF_SIZE 16
#define CHUNK_SIZE 1024
#include "esp_err.h"
int SERIAL_send(uint8_t *, int, bool);
esp_err_t SERIAL_init(void);
@@ -11,4 +10,4 @@ int16_t SERIAL_rx(uint8_t *, uint16_t, uint16_t);
void SERIAL_clear_buffer(void);
esp_err_t SERIAL_set_baud(int baud);
#endif /* SERIAL_H_ */
#endif /* SERIAL_H_ */

View File

@@ -454,7 +454,7 @@ void self_test(void * pvParameters)
double hash_rate = 0;
while(duration < 3){
task_result * asic_result = ASIC_proccess_work(GLOBAL_STATE);
task_result * asic_result = ASIC_process_work(GLOBAL_STATE);
if (asic_result != NULL) {
// check the nonce difficulty
double nonce_diff = test_nonce_value(&job, asic_result->nonce, asic_result->rolled_version);

View File

@@ -20,7 +20,7 @@ void ASIC_result_task(void *pvParameters)
while (1)
{
//task_result *asic_result = (*GLOBAL_STATE->ASIC_functions.receive_result_fn)(GLOBAL_STATE);
task_result *asic_result = ASIC_proccess_work(GLOBAL_STATE);
task_result *asic_result = ASIC_process_work(GLOBAL_STATE);
if (asic_result == NULL)
{