mirror of
https://github.com/skot/ESP-Miner.git
synced 2025-10-09 18:52:41 +02:00
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:
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
@@ -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/
|
||||
|
@@ -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);
|
||||
|
@@ -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_ */
|
||||
|
@@ -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_ */
|
||||
|
@@ -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_ */
|
||||
|
@@ -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_ */
|
||||
|
@@ -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_ */
|
||||
|
@@ -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_ */
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user