Files
ESP-Miner/components/asic/common.c
mutatrum a5842a54b3 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>
2025-03-12 22:45:33 +01:00

128 lines
3.6 KiB
C

#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)
{
unsigned char reversed = 0;
int i;
for (i = 0; i < 8; i++) {
reversed <<= 1; // Left shift the reversed variable by 1
reversed |= num & 1; // Use bitwise OR to set the rightmost bit of reversed to the current bit of num
num >>= 1; // Right shift num by 1 to get the next bit
}
return reversed;
}
int _largest_power_of_two(int num)
{
int power = 0;
while (num > 1) {
num = num >> 1;
power++;
}
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;
}