mirror of
https://github.com/skot/ESP-Miner.git
synced 2025-03-17 13:22:53 +01:00
parent
a3cdc67d19
commit
9bc0671563
@ -1,5 +1,6 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"bm1366.c"
|
||||
"bm1397.c"
|
||||
"serial.c"
|
||||
"crc.c"
|
||||
@ -9,4 +10,11 @@ REQUIRES
|
||||
freertos
|
||||
driver
|
||||
stratum
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# Include the header files from "main" directory
|
||||
target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../main")
|
||||
|
||||
# Include the header files from "main/tasks" directory
|
||||
target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../main/tasks")
|
712
components/bm1397/bm1366.c
Normal file
712
components/bm1397/bm1366.c
Normal file
@ -0,0 +1,712 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "serial.h"
|
||||
#include "bm1366.h"
|
||||
#include "utils.h"
|
||||
#include "crc.h"
|
||||
#include "global_state.h"
|
||||
|
||||
#define BM1366_RST_PIN GPIO_NUM_1
|
||||
|
||||
|
||||
#define TYPE_JOB 0x20
|
||||
#define TYPE_CMD 0x40
|
||||
|
||||
#define GROUP_SINGLE 0x00
|
||||
#define GROUP_ALL 0x10
|
||||
|
||||
#define CMD_JOB 0x01
|
||||
|
||||
#define CMD_SETADDRESS 0x00
|
||||
#define CMD_WRITE 0x01
|
||||
#define CMD_READ 0x02
|
||||
#define CMD_INACTIVE 0x03
|
||||
|
||||
#define RESPONSE_CMD 0x00
|
||||
#define RESPONSE_JOB 0x80
|
||||
|
||||
|
||||
|
||||
#define SLEEP_TIME 20
|
||||
#define FREQ_MULT 25.0
|
||||
|
||||
#define CLOCK_ORDER_CONTROL_0 0x80
|
||||
#define CLOCK_ORDER_CONTROL_1 0x84
|
||||
#define ORDERED_CLOCK_ENABLE 0x20
|
||||
#define CORE_REGISTER_CONTROL 0x3C
|
||||
#define PLL3_PARAMETER 0x68
|
||||
#define FAST_UART_CONFIGURATION 0x28
|
||||
#define TICKET_MASK 0x14
|
||||
#define MISC_CONTROL 0x18
|
||||
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t preamble[2];
|
||||
uint32_t nonce;
|
||||
uint8_t midstate_num;
|
||||
uint8_t job_id;
|
||||
uint16_t version;
|
||||
uint8_t crc;
|
||||
} asic_result;
|
||||
|
||||
static const char *TAG = "bm1366Module";
|
||||
|
||||
static uint8_t asic_response_buffer[CHUNK_SIZE];
|
||||
static task_result result;
|
||||
|
||||
/// @brief
|
||||
/// @param ftdi
|
||||
/// @param header
|
||||
/// @param data
|
||||
/// @param len
|
||||
static void _send_BM1366(uint8_t header, uint8_t * data, uint8_t data_len, bool debug) {
|
||||
packet_type_t packet_type = (header & TYPE_JOB) ? JOB_PACKET : CMD_PACKET;
|
||||
uint8_t total_length = (packet_type == JOB_PACKET) ? (data_len+6) : (data_len+5);
|
||||
|
||||
//allocate memory for buffer
|
||||
unsigned char *buf = malloc(total_length);
|
||||
|
||||
//add the preamble
|
||||
buf[0] = 0x55;
|
||||
buf[1] = 0xAA;
|
||||
|
||||
//add the header field
|
||||
buf[2] = header;
|
||||
|
||||
//add the length field
|
||||
buf[3] = (packet_type == JOB_PACKET) ? (data_len+4) : (data_len+3);
|
||||
|
||||
//add the data
|
||||
memcpy(buf+4, data, data_len);
|
||||
|
||||
//add the correct crc type
|
||||
if (packet_type == JOB_PACKET) {
|
||||
uint16_t crc16_total = crc16_false(buf+2, data_len+2);
|
||||
buf[4+data_len] = (crc16_total >> 8) & 0xFF;
|
||||
buf[5+data_len] = crc16_total & 0xFF;
|
||||
} else {
|
||||
buf[4+data_len] = crc5(buf+2, data_len+2);
|
||||
}
|
||||
|
||||
//send serial data
|
||||
SERIAL_send(buf, total_length, debug);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void _send_simple(uint8_t * data, uint8_t total_length){
|
||||
unsigned char *buf = malloc(total_length);
|
||||
memcpy(buf, data, total_length);
|
||||
SERIAL_send(buf, total_length, false);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void _send_chain_inactive(void) {
|
||||
|
||||
unsigned char read_address[2] = {0x00, 0x00};
|
||||
//send serial data
|
||||
_send_BM1366((TYPE_CMD | GROUP_ALL | CMD_INACTIVE), read_address, 2, false);
|
||||
}
|
||||
|
||||
static void _set_chip_address(uint8_t chipAddr) {
|
||||
|
||||
unsigned char read_address[2] = {chipAddr, 0x00};
|
||||
//send serial data
|
||||
_send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_SETADDRESS), read_address, 2, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// borrowed from cgminer driver-gekko.c calc_gsf_freq()
|
||||
void BM1366_send_hash_frequency(float frequency) {
|
||||
|
||||
unsigned char prefreq1[9] = {0x00, 0x70, 0x0F, 0x0F, 0x0F, 0x00}; //prefreq - pll0_divider
|
||||
|
||||
// default 200Mhz if it fails
|
||||
unsigned char freqbuf[9] = {0x00, 0x08, 0x40, 0xA0, 0x02, 0x25}; //freqbuf - pll0_parameter
|
||||
|
||||
float deffreq = 200.0;
|
||||
|
||||
float fa, fb, fc1, fc2, newf;
|
||||
float f1, basef, famax = 0xf0, famin = 0x10;
|
||||
int i;
|
||||
|
||||
//bound the frequency setting
|
||||
// You can go as low as 13 but it doesn't really scale or
|
||||
// produce any nonces
|
||||
if (frequency < 50) {
|
||||
f1 = 50;
|
||||
} else if (frequency > 500) {
|
||||
f1 = 500;
|
||||
} else {
|
||||
f1 = frequency;
|
||||
}
|
||||
|
||||
|
||||
fb = 2; fc1 = 1; fc2 = 5; // initial multiplier of 10
|
||||
if (f1 >= 500) {
|
||||
// halve down to '250-400'
|
||||
fb = 1;
|
||||
} else if (f1 <= 150) {
|
||||
// triple up to '300-450'
|
||||
fc1 = 3;
|
||||
} else if (f1 <= 250) {
|
||||
// double up to '300-500'
|
||||
fc1 = 2;
|
||||
}
|
||||
// else f1 is 250-500
|
||||
|
||||
// f1 * fb * fc1 * fc2 is between 2500 and 5000
|
||||
// - so round up to the next 25 (freq_mult)
|
||||
basef = FREQ_MULT * ceil(f1 * fb * fc1 * fc2 / FREQ_MULT);
|
||||
|
||||
// fa should be between 100 (0x64) and 200 (0xC8)
|
||||
fa = basef / FREQ_MULT;
|
||||
|
||||
// code failure ... basef isn't 400 to 6000
|
||||
if (fa < famin || fa > famax) {
|
||||
newf = deffreq;
|
||||
} else {
|
||||
freqbuf[3] = (int)fa;
|
||||
freqbuf[4] = (int)fb;
|
||||
// fc1, fc2 'should' already be 1..15
|
||||
freqbuf[5] = (((int)fc1 & 0xf) << 4) + ((int)fc2 & 0xf);
|
||||
|
||||
newf = basef / ((float)fb * (float)fc1 * (float)fc2);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
_send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), prefreq1, 6, false);
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
_send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), freqbuf, 6, false);
|
||||
}
|
||||
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
ESP_LOGI(TAG, "Setting Frequency to %.2fMHz (%.2f)", frequency, newf);
|
||||
|
||||
}
|
||||
|
||||
static void _send_init(u_int64_t frequency) {
|
||||
|
||||
// //send serial data
|
||||
// vTaskDelay(SLEEP_TIME / portTICK_PERIOD_MS);
|
||||
|
||||
// unsigned char init[6] = { 0x00, 0xA4, 0x90, 0x00, 0xFF, 0xFF};
|
||||
|
||||
|
||||
// _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), init, 6, true);
|
||||
|
||||
// unsigned char init18[7] = { 0x55, 0xAA, 0x52, 0x05, 0x00, 0x00, 0x0A };
|
||||
// _send_simple(init18, 7);
|
||||
|
||||
|
||||
// unsigned char init2[6] = { 0x00, 0xA8, 0x00, 0x07, 0x00, 0x00};
|
||||
// _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), init2, 6, true);
|
||||
|
||||
// unsigned char init3[6] = { 0x00, 0x18, 0xFF, 0x0F, 0xC1, 0x00 };
|
||||
// _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), init3, 6, true);
|
||||
|
||||
// unsigned char init4[7] = { 0x55, 0xAA, 0x53, 0x05, 0x00, 0x00, 0x03 };
|
||||
// _send_simple(init4, 7);
|
||||
|
||||
// unsigned char init5[7] = { 0x55, 0xAA, 0x40, 0x05, 0x00, 0x00, 0x1C };
|
||||
// _send_simple(init5, 7);
|
||||
|
||||
// unsigned char init6[6] = { 0x00, 0x3C, 0x80, 0x00, 0x85, 0x40 };
|
||||
// _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), init6, 6, true);
|
||||
|
||||
// unsigned char init7[6] = { 0x00, 0x3C, 0x80, 0x00, 0x80, 0x20};
|
||||
// _send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), init7, 6, true);
|
||||
|
||||
|
||||
// unsigned char init17[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0xA4, 0x90, 0x00, 0xFF, 0xFF, 0x1C};
|
||||
// _send_simple(init17, 11);
|
||||
|
||||
unsigned char init0[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0xA4, 0x90, 0x00, 0xFF, 0xFF, 0x1C };
|
||||
_send_simple(init0, 11);
|
||||
|
||||
unsigned char init1[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0xA4, 0x90, 0x00, 0xFF, 0xFF, 0x1C };
|
||||
_send_simple(init1, 11);
|
||||
|
||||
unsigned char init2[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0xA4, 0x90, 0x00, 0xFF, 0xFF, 0x1C };
|
||||
_send_simple(init2, 11);
|
||||
|
||||
unsigned char init3[7] = { 0x55, 0xAA, 0x52, 0x05, 0x00, 0x00, 0x0A };
|
||||
_send_simple(init3, 7);
|
||||
|
||||
unsigned char init4[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0xA8, 0x00, 0x07, 0x00, 0x00, 0x03 };
|
||||
_send_simple(init4, 11);
|
||||
|
||||
unsigned char init5[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x18, 0xFF, 0x0F, 0xC1, 0x00, 0x00 };
|
||||
_send_simple(init5, 11);
|
||||
|
||||
unsigned char init6[7] = { 0x55, 0xAA, 0x53, 0x05, 0x00, 0x00, 0x03 };
|
||||
_send_simple(init6, 7);
|
||||
|
||||
unsigned char init7[7] = { 0x55, 0xAA, 0x40, 0x05, 0x00, 0x00, 0x1C };
|
||||
_send_simple(init7, 7);
|
||||
|
||||
|
||||
unsigned char init135[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x85, 0x40, 0x0C };
|
||||
_send_simple(init135, 11);
|
||||
|
||||
unsigned char init136[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x80, 0x20, 0x19 };
|
||||
_send_simple(init136, 11);
|
||||
|
||||
unsigned char init137[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x14, 0x00, 0x00, 0x00, 0xFF, 0x08 };
|
||||
_send_simple(init137, 11);
|
||||
|
||||
unsigned char init138[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x54, 0x00, 0x00, 0x00, 0x03, 0x1D };
|
||||
_send_simple(init138, 11);
|
||||
|
||||
unsigned char init139[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x58, 0x02, 0x11, 0x11, 0x11, 0x06 };
|
||||
_send_simple(init139, 11);
|
||||
|
||||
|
||||
|
||||
unsigned char init171[11] = { 0x55, 0xAA, 0x41, 0x09, 0x00, 0x2C, 0x00, 0x7C, 0x00, 0x03, 0x03 };
|
||||
_send_simple(init171, 11);
|
||||
|
||||
|
||||
|
||||
unsigned char init173[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x28, 0x11, 0x30, 0x02, 0x00, 0x03 };
|
||||
_send_simple(init173, 11);
|
||||
|
||||
unsigned char init174[11] = { 0x55, 0xAA, 0x41, 0x09, 0x00, 0xA8, 0x00, 0x07, 0x01, 0xF0, 0x15 };
|
||||
_send_simple(init174, 11);
|
||||
|
||||
unsigned char init175[11] = { 0x55, 0xAA, 0x41, 0x09, 0x00, 0x18, 0xF0, 0x00, 0xC1, 0x00, 0x0C };
|
||||
_send_simple(init175, 11);
|
||||
|
||||
unsigned char init176[11] = { 0x55, 0xAA, 0x41, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x85, 0x40, 0x04 };
|
||||
_send_simple(init176, 11);
|
||||
|
||||
unsigned char init177[11] = { 0x55, 0xAA, 0x41, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x80, 0x20, 0x11 };
|
||||
_send_simple(init177, 11);
|
||||
|
||||
unsigned char init178[11] = { 0x55, 0xAA, 0x41, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x82, 0xAA, 0x05 };
|
||||
_send_simple(init178, 11);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
unsigned char init724[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA2, 0x02, 0x55, 0x0F };
|
||||
_send_simple(init724, 11);
|
||||
|
||||
unsigned char init725[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAF, 0x02, 0x64, 0x08 };
|
||||
_send_simple(init725, 11);
|
||||
|
||||
unsigned char init726[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA5, 0x02, 0x54, 0x08 };
|
||||
_send_simple(init726, 11);
|
||||
|
||||
unsigned char init727[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA8, 0x02, 0x63, 0x11 };
|
||||
_send_simple(init727, 11);
|
||||
|
||||
unsigned char init728[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB6, 0x02, 0x63, 0x0C };
|
||||
_send_simple(init728, 11);
|
||||
|
||||
unsigned char init729[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA8, 0x02, 0x53, 0x1A };
|
||||
_send_simple(init729, 11);
|
||||
|
||||
unsigned char init730[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB4, 0x02, 0x53, 0x12 };
|
||||
_send_simple(init730, 11);
|
||||
|
||||
unsigned char init731[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA8, 0x02, 0x62, 0x14 };
|
||||
_send_simple(init731, 11);
|
||||
|
||||
unsigned char init732[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAA, 0x02, 0x43, 0x15 };
|
||||
_send_simple(init732, 11);
|
||||
|
||||
unsigned char init733[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA2, 0x02, 0x52, 0x14 };
|
||||
_send_simple(init733, 11);
|
||||
|
||||
unsigned char init734[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAB, 0x02, 0x52, 0x12 };
|
||||
_send_simple(init734, 11);
|
||||
|
||||
unsigned char init735[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB4, 0x02, 0x52, 0x17 };
|
||||
_send_simple(init735, 11);
|
||||
|
||||
unsigned char init736[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xBD, 0x02, 0x52, 0x11 };
|
||||
_send_simple(init736, 11);
|
||||
|
||||
unsigned char init737[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA5, 0x02, 0x42, 0x0C };
|
||||
_send_simple(init737, 11);
|
||||
|
||||
unsigned char init738[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA1, 0x02, 0x61, 0x1D };
|
||||
_send_simple(init738, 11);
|
||||
|
||||
unsigned char init739[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA8, 0x02, 0x61, 0x1B };
|
||||
_send_simple(init739, 11);
|
||||
|
||||
unsigned char init740[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAF, 0x02, 0x61, 0x19 };
|
||||
_send_simple(init740, 11);
|
||||
|
||||
unsigned char init741[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB6, 0x02, 0x61, 0x06 };
|
||||
_send_simple(init741, 11);
|
||||
|
||||
unsigned char init742[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA2, 0x02, 0x51, 0x1B };
|
||||
_send_simple(init742, 11);
|
||||
|
||||
unsigned char init743[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA8, 0x02, 0x51, 0x10 };
|
||||
_send_simple(init743, 11);
|
||||
|
||||
unsigned char init744[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAE, 0x02, 0x51, 0x0A };
|
||||
_send_simple(init744, 11);
|
||||
|
||||
unsigned char init745[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB4, 0x02, 0x51, 0x18 };
|
||||
_send_simple(init745, 11);
|
||||
|
||||
unsigned char init746[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xBA, 0x02, 0x51, 0x1C };
|
||||
_send_simple(init746, 11);
|
||||
|
||||
unsigned char init747[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA0, 0x02, 0x41, 0x14 };
|
||||
_send_simple(init747, 11);
|
||||
|
||||
unsigned char init748[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA5, 0x02, 0x41, 0x03 };
|
||||
_send_simple(init748, 11);
|
||||
|
||||
unsigned char init749[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAA, 0x02, 0x41, 0x1F };
|
||||
_send_simple(init749, 11);
|
||||
|
||||
unsigned char init750[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAF, 0x02, 0x41, 0x08 };
|
||||
_send_simple(init750, 11);
|
||||
|
||||
unsigned char init751[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB4, 0x02, 0x41, 0x02 };
|
||||
_send_simple(init751, 11);
|
||||
|
||||
unsigned char init752[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB9, 0x02, 0x41, 0x0B };
|
||||
_send_simple(init752, 11);
|
||||
|
||||
unsigned char init753[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xBE, 0x02, 0x41, 0x09 };
|
||||
_send_simple(init753, 11);
|
||||
|
||||
unsigned char init754[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xC3, 0x02, 0x41, 0x01 };
|
||||
_send_simple(init754, 11);
|
||||
|
||||
unsigned char init755[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA0, 0x02, 0x31, 0x18 };
|
||||
_send_simple(init755, 11);
|
||||
|
||||
unsigned char init756[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA4, 0x02, 0x31, 0x17 };
|
||||
_send_simple(init756, 11);
|
||||
|
||||
unsigned char init757[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA8, 0x02, 0x31, 0x06 };
|
||||
_send_simple(init757, 11);
|
||||
|
||||
unsigned char init758[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAC, 0x02, 0x31, 0x09 };
|
||||
_send_simple(init758, 11);
|
||||
|
||||
unsigned char init759[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB0, 0x02, 0x31, 0x01 };
|
||||
_send_simple(init759, 11);
|
||||
|
||||
unsigned char init760[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB4, 0x02, 0x31, 0x0E };
|
||||
_send_simple(init760, 11);
|
||||
|
||||
unsigned char init761[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA1, 0x02, 0x60, 0x18 };
|
||||
_send_simple(init761, 11);
|
||||
|
||||
unsigned char init762[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xBC, 0x02, 0x31, 0x10 };
|
||||
_send_simple(init762, 11);
|
||||
|
||||
unsigned char init763[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA8, 0x02, 0x60, 0x1E };
|
||||
_send_simple(init763, 11);
|
||||
|
||||
unsigned char init764[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xC4, 0x02, 0x31, 0x0F };
|
||||
_send_simple(init764, 11);
|
||||
|
||||
unsigned char init765[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAF, 0x02, 0x60, 0x1C };
|
||||
_send_simple(init765, 11);
|
||||
|
||||
unsigned char init766[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xCC, 0x02, 0x31, 0x11 };
|
||||
_send_simple(init766, 11);
|
||||
|
||||
unsigned char init767[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB6, 0x02, 0x60, 0x03 };
|
||||
_send_simple(init767, 11);
|
||||
|
||||
unsigned char init768[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xD4, 0x02, 0x31, 0x16 };
|
||||
_send_simple(init768, 11);
|
||||
|
||||
unsigned char init769[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA2, 0x02, 0x50, 0x1E };
|
||||
_send_simple(init769, 11);
|
||||
|
||||
unsigned char init770[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA5, 0x02, 0x50, 0x1C };
|
||||
_send_simple(init770, 11);
|
||||
|
||||
unsigned char init771[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA8, 0x02, 0x50, 0x15 };
|
||||
_send_simple(init771, 11);
|
||||
|
||||
unsigned char init772[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAB, 0x02, 0x50, 0x18 };
|
||||
_send_simple(init772, 11);
|
||||
|
||||
unsigned char init773[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAE, 0x02, 0x50, 0x0F };
|
||||
_send_simple(init773, 11);
|
||||
|
||||
unsigned char init774[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB1, 0x02, 0x50, 0x0A };
|
||||
_send_simple(init774, 11);
|
||||
|
||||
unsigned char init775[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB4, 0x02, 0x50, 0x1D };
|
||||
_send_simple(init775, 11);
|
||||
|
||||
unsigned char init776[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB7, 0x02, 0x50, 0x10 };
|
||||
_send_simple(init776, 11);
|
||||
|
||||
unsigned char init777[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xBA, 0x02, 0x50, 0x19 };
|
||||
_send_simple(init777, 11);
|
||||
|
||||
unsigned char init778[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xBD, 0x02, 0x50, 0x1B };
|
||||
_send_simple(init778, 11);
|
||||
|
||||
unsigned char init779[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA0, 0x02, 0x40, 0x11 };
|
||||
_send_simple(init779, 11);
|
||||
|
||||
unsigned char init780[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xC3, 0x02, 0x50, 0x1E };
|
||||
_send_simple(init780, 11);
|
||||
|
||||
unsigned char init781[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xA5, 0x02, 0x40, 0x06 };
|
||||
_send_simple(init781, 11);
|
||||
|
||||
unsigned char init782[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xC9, 0x02, 0x50, 0x15 };
|
||||
_send_simple(init782, 11);
|
||||
|
||||
unsigned char init783[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAA, 0x02, 0x40, 0x1A };
|
||||
_send_simple(init783, 11);
|
||||
|
||||
unsigned char init784[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xCF, 0x02, 0x50, 0x0F };
|
||||
_send_simple(init784, 11);
|
||||
|
||||
unsigned char init785[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xAF, 0x02, 0x40, 0x0D };
|
||||
_send_simple(init785, 11);
|
||||
|
||||
unsigned char init786[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xD5, 0x02, 0x50, 0x1D };
|
||||
_send_simple(init786, 11);
|
||||
|
||||
unsigned char init787[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB4, 0x02, 0x40, 0x07 };
|
||||
_send_simple(init787, 11);
|
||||
|
||||
unsigned char init788[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xDB, 0x02, 0x50, 0x19 };
|
||||
_send_simple(init788, 11);
|
||||
|
||||
unsigned char init789[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xB9, 0x02, 0x40, 0x0E };
|
||||
_send_simple(init789, 11);
|
||||
|
||||
unsigned char init790[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xE1, 0x02, 0x50, 0x1C };
|
||||
_send_simple(init790, 11);
|
||||
|
||||
unsigned char init791[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x40, 0xBE, 0x02, 0x40, 0x0C };
|
||||
_send_simple(init791, 11);
|
||||
|
||||
unsigned char init792[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xE7, 0x02, 0x50, 0x06 };
|
||||
_send_simple(init792, 11);
|
||||
|
||||
unsigned char init793[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x08, 0x50, 0xC2, 0x02, 0x40, 0x1C };
|
||||
_send_simple(init793, 11);
|
||||
|
||||
unsigned char init794[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x10, 0x00, 0x00, 0x15, 0x1C, 0x02 };
|
||||
_send_simple(init794, 11);
|
||||
|
||||
unsigned char init795[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0xA4, 0x90, 0x00, 0xFF, 0xFF, 0x1C };
|
||||
_send_simple(init795, 11);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//reset the BM1366 via the RTS line
|
||||
static void _reset(void) {
|
||||
gpio_set_level(BM1366_RST_PIN, 0);
|
||||
|
||||
//delay for 100ms
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
|
||||
//set the gpio pin high
|
||||
gpio_set_level(BM1366_RST_PIN, 1);
|
||||
|
||||
//delay for 100ms
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void _send_read_address(void) {
|
||||
|
||||
unsigned char read_address[2] = {0x00, 0x00};
|
||||
//send serial data
|
||||
_send_BM1366((TYPE_CMD | GROUP_ALL | CMD_READ), read_address, 2, false);
|
||||
}
|
||||
|
||||
|
||||
void BM1366_init(u_int64_t frequency) {
|
||||
ESP_LOGI(TAG, "Initializing BM1366");
|
||||
|
||||
memset(asic_response_buffer, 0, 1024);
|
||||
|
||||
esp_rom_gpio_pad_select_gpio(BM1366_RST_PIN);
|
||||
gpio_set_direction(BM1366_RST_PIN, GPIO_MODE_OUTPUT);
|
||||
|
||||
//reset the bm1366
|
||||
_reset();
|
||||
|
||||
//send the init command
|
||||
//_send_read_address();
|
||||
|
||||
_send_init(frequency);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Baud formula = 25M/((denominator+1)*8)
|
||||
// The denominator is 5 bits found in the misc_control (bits 9-13)
|
||||
int BM1366_set_default_baud(void){
|
||||
//default divider of 26 (11010) for 115,749
|
||||
unsigned char baudrate[9] = {0x00, MISC_CONTROL, 0x00, 0x00, 0b01111010, 0b00110001}; //baudrate - misc_control
|
||||
_send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, false);
|
||||
return 115749;
|
||||
}
|
||||
|
||||
int BM1366_set_max_baud(void){
|
||||
|
||||
///return 115749;
|
||||
|
||||
// divider of 0 for 3,125,000
|
||||
ESP_LOGI(TAG, "Setting max baud of 1000000 ");
|
||||
|
||||
unsigned char init8[11] = { 0x55, 0xAA, 0x51, 0x09, 0x00, 0x28, 0x11, 0x30, 0x02, 0x00, 0x03 };
|
||||
_send_simple(init8, 11);
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
void BM1366_set_job_difficulty_mask(int difficulty){
|
||||
|
||||
return;
|
||||
|
||||
// Default mask of 256 diff
|
||||
unsigned char job_difficulty_mask[9] = {0x00, TICKET_MASK, 0b00000000, 0b00000000, 0b00000000, 0b11111111};
|
||||
|
||||
// The mask must be a power of 2 so there are no holes
|
||||
// Correct: {0b00000000, 0b00000000, 0b11111111, 0b11111111}
|
||||
// Incorrect: {0b00000000, 0b00000000, 0b11100111, 0b11111111}
|
||||
difficulty = _largest_power_of_two(difficulty) -1; // (difficulty - 1) if it is a pow 2 then step down to second largest for more hashrate sampling
|
||||
|
||||
// convert difficulty into char array
|
||||
// Ex: 256 = {0b00000000, 0b00000000, 0b00000000, 0b11111111}, {0x00, 0x00, 0x00, 0xff}
|
||||
// Ex: 512 = {0b00000000, 0b00000000, 0b00000001, 0b11111111}, {0x00, 0x00, 0x01, 0xff}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
char value = (difficulty >> (8 * i)) & 0xFF;
|
||||
//The char is read in backwards to the register so we need to reverse them
|
||||
//So a mask of 512 looks like 0b00000000 00000000 00000001 1111111
|
||||
//and not 0b00000000 00000000 10000000 1111111
|
||||
|
||||
job_difficulty_mask[5 - i] = _reverse_bits(value);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Setting job ASIC mask to %d", difficulty);
|
||||
|
||||
_send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), job_difficulty_mask, 6, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint8_t id = 0;
|
||||
|
||||
void BM1366_send_work(void *pvParameters, bm_job *next_bm_job) {
|
||||
|
||||
GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters;
|
||||
|
||||
BM1366_job job;
|
||||
id = (id + 8) % 128;
|
||||
job.job_id = id;
|
||||
job.num_midstates = 0x01;
|
||||
memcpy(&job.starting_nonce, &next_bm_job->starting_nonce, 4);
|
||||
memcpy(&job.nbits, &next_bm_job->target, 4);
|
||||
memcpy(&job.ntime, &next_bm_job->ntime, 4);
|
||||
memcpy(job.merkle_root, next_bm_job->merkle_root_be, 32);
|
||||
memcpy(job.prev_block_hash, next_bm_job->prev_block_hash_be, 32);
|
||||
memcpy(&job.version, &next_bm_job->version, 4);
|
||||
|
||||
if (GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) {
|
||||
free_bm_job(GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id]);
|
||||
}
|
||||
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] = next_bm_job;
|
||||
|
||||
pthread_mutex_lock(&GLOBAL_STATE->valid_jobs_lock);
|
||||
GLOBAL_STATE-> valid_jobs[job.job_id] = 1;
|
||||
//ESP_LOGI(TAG, "Added Job: %i", job.job_id);
|
||||
pthread_mutex_unlock(&GLOBAL_STATE->valid_jobs_lock);
|
||||
|
||||
_send_BM1366((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), &job, sizeof(BM1366_job), false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
asic_result * BM1366_receive_work(void){
|
||||
//wait for a response, wait time is pretty arbitrary
|
||||
int received = SERIAL_rx(asic_response_buffer, 11, 60000);
|
||||
|
||||
|
||||
if (received < 0) {
|
||||
ESP_LOGI(TAG, "Error in serial RX");
|
||||
return NULL;
|
||||
} else if(received == 0){
|
||||
// Didn't find a solution, restart and try again
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (asic_result*) asic_response_buffer;
|
||||
|
||||
|
||||
}
|
||||
|
||||
uint16_t reverse_uint16(uint16_t num) {
|
||||
return (num >> 8) | (num << 8);
|
||||
}
|
||||
|
||||
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;
|
||||
uint8_t rx_job_id = job_id & 0xf8;
|
||||
|
||||
GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters;
|
||||
|
||||
uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version;
|
||||
|
||||
// // // shift the 16 bit value left 13
|
||||
rolled_version = (reverse_uint16(asic_result->version) << 13) | rolled_version;
|
||||
|
||||
result.job_id = rx_job_id;
|
||||
result.nonce = asic_result->nonce;
|
||||
result.rolled_version = rolled_version;
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,28 @@
|
||||
#include "bm1397.h"
|
||||
#include "utils.h"
|
||||
#include "crc.h"
|
||||
#include "mining.h"
|
||||
#include "global_state.h"
|
||||
|
||||
#define BM1397_RST_PIN GPIO_NUM_1
|
||||
|
||||
|
||||
#define TYPE_JOB 0x20
|
||||
#define TYPE_CMD 0x40
|
||||
|
||||
#define GROUP_SINGLE 0x00
|
||||
#define GROUP_ALL 0x10
|
||||
|
||||
#define CMD_JOB 0x01
|
||||
|
||||
#define CMD_SETADDRESS 0x00
|
||||
#define CMD_WRITE 0x01
|
||||
#define CMD_READ 0x02
|
||||
#define CMD_INACTIVE 0x03
|
||||
|
||||
#define RESPONSE_CMD 0x00
|
||||
#define RESPONSE_JOB 0x80
|
||||
|
||||
|
||||
#define SLEEP_TIME 20
|
||||
#define FREQ_MULT 25.0
|
||||
@ -25,8 +47,20 @@
|
||||
#define TICKET_MASK 0x14
|
||||
#define MISC_CONTROL 0x18
|
||||
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t preamble[2];
|
||||
uint32_t nonce;
|
||||
uint8_t midstate_num;
|
||||
uint8_t job_id;
|
||||
uint8_t crc;
|
||||
} asic_result;
|
||||
|
||||
static const char *TAG = "bm1397Module";
|
||||
|
||||
static uint8_t asic_response_buffer[CHUNK_SIZE];
|
||||
static uint32_t prev_nonce = 0;
|
||||
static task_result result;
|
||||
|
||||
/// @brief
|
||||
/// @param ftdi
|
||||
/// @param header
|
||||
@ -81,29 +115,6 @@ static void _set_chip_address(uint8_t chipAddr) {
|
||||
_send_BM1397((TYPE_CMD | GROUP_SINGLE | CMD_SETADDRESS), read_address, 2, false);
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static int _largest_power_of_two(int num) {
|
||||
int power = 0;
|
||||
|
||||
while (num > 1) {
|
||||
num = num >> 1;
|
||||
power++;
|
||||
}
|
||||
|
||||
return 1 << power;
|
||||
}
|
||||
|
||||
// borrowed from cgminer driver-gekko.c calc_gsf_freq()
|
||||
void BM1397_send_hash_frequency(float frequency) {
|
||||
@ -238,6 +249,8 @@ static void _send_read_address(void) {
|
||||
void BM1397_init(u_int64_t frequency) {
|
||||
ESP_LOGI(TAG, "Initializing BM1397");
|
||||
|
||||
memset(asic_response_buffer, 0, sizeof(asic_response_buffer));
|
||||
|
||||
esp_rom_gpio_pad_select_gpio(BM1397_RST_PIN);
|
||||
gpio_set_direction(BM1397_RST_PIN, GPIO_MODE_OUTPUT);
|
||||
|
||||
@ -249,7 +262,6 @@ void BM1397_init(u_int64_t frequency) {
|
||||
|
||||
_send_init(frequency);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -301,10 +313,127 @@ void BM1397_set_job_difficulty_mask(int difficulty){
|
||||
}
|
||||
|
||||
|
||||
static uint8_t id = 0;
|
||||
|
||||
void BM1397_send_work(void *pvParameters, bm_job *next_bm_job) {
|
||||
|
||||
GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters;
|
||||
|
||||
job_packet job;
|
||||
// max job number is 128
|
||||
// there is still some really weird logic with the job id bits for the asic to sort out
|
||||
// so we have it limited to 128 and it has to increment by 4
|
||||
id = (id + 4) % 128;
|
||||
|
||||
job.job_id = id;
|
||||
job.num_midstates = next_bm_job->num_midstates;
|
||||
memcpy(&job.starting_nonce, &next_bm_job->starting_nonce, 4);
|
||||
memcpy(&job.nbits, &next_bm_job->target, 4);
|
||||
memcpy(&job.ntime, &next_bm_job->ntime, 4);
|
||||
memcpy(&job.merkle4, next_bm_job->merkle_root + 28, 4);
|
||||
memcpy(job.midstate, next_bm_job->midstate, 32);
|
||||
|
||||
|
||||
void BM1397_send_work(struct job_packet *job) {
|
||||
_send_BM1397((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t*)job, sizeof(struct job_packet), false);
|
||||
if (job.num_midstates == 4)
|
||||
{
|
||||
memcpy(job.midstate1, next_bm_job->midstate1, 32);
|
||||
memcpy(job.midstate2, next_bm_job->midstate2, 32);
|
||||
memcpy(job.midstate3, next_bm_job->midstate3, 32);
|
||||
}
|
||||
|
||||
if (GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) {
|
||||
free_bm_job(GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id]);
|
||||
}
|
||||
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] = next_bm_job;
|
||||
|
||||
pthread_mutex_lock(&GLOBAL_STATE->valid_jobs_lock);
|
||||
GLOBAL_STATE-> valid_jobs[job.job_id] = 1;
|
||||
//ESP_LOGI(TAG, "Added Job: %i", job.job_id);
|
||||
pthread_mutex_unlock(&GLOBAL_STATE->valid_jobs_lock);
|
||||
|
||||
_send_BM1397((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), &job, sizeof(job_packet), false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
asic_result * BM1397_receive_work(void){
|
||||
|
||||
//wait for a response, wait time is pretty arbitrary
|
||||
int received = SERIAL_rx(asic_response_buffer, 9, 60000);
|
||||
|
||||
if (received < 0) {
|
||||
ESP_LOGI(TAG, "Error in serial RX");
|
||||
return NULL;
|
||||
} else if(received == 0){
|
||||
// Didn't find a solution, restart and try again
|
||||
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);
|
||||
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");
|
||||
return NULL;
|
||||
}
|
||||
ESP_LOGI(TAG, "return not 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;
|
||||
|
||||
|
||||
GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters;
|
||||
if (GLOBAL_STATE->valid_jobs[rx_job_id] == 0) {
|
||||
ESP_LOGI(TAG, "Invalid job nonce found, id=%d", rx_job_id);
|
||||
}
|
||||
|
||||
uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version;
|
||||
for (int i = 0; i < rx_midstate_index; i++) {
|
||||
rolled_version = increment_bitmask(rolled_version, GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version_mask);
|
||||
}
|
||||
|
||||
|
||||
// ASIC may return the same nonce multiple times
|
||||
// or one that was already found
|
||||
// most of the time it behavies however
|
||||
if (nonce_found == 0) {
|
||||
first_nonce = asic_result->nonce;
|
||||
nonce_found = 1;
|
||||
} else if (asic_result->nonce == first_nonce) {
|
||||
// stop if we've already seen this nonce
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (asic_result->nonce == prev_nonce) {
|
||||
return NULL;
|
||||
} else {
|
||||
prev_nonce = asic_result->nonce;
|
||||
}
|
||||
|
||||
|
||||
result.job_id = rx_job_id;
|
||||
result.nonce = asic_result->nonce;
|
||||
result.rolled_version = rolled_version;
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
|
46
components/bm1397/include/bm1366.h
Normal file
46
components/bm1397/include/bm1366.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef BM1366_H_
|
||||
#define BM1366_H_
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "mining.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
|
||||
#define CRC5_MASK 0x1F
|
||||
|
||||
static const u_int64_t BM1366_FREQUENCY = CONFIG_ASIC_FREQUENCY;
|
||||
static const u_int64_t BM1366_CORE_COUNT = 672;
|
||||
static const u_int64_t BM1366_HASHRATE_S = BM1366_FREQUENCY * BM1366_CORE_COUNT * 1000000;
|
||||
//2^32
|
||||
//static const u_int64_t NONCE_SPACE = 4294967296;
|
||||
static const double BM1366_FULLSCAN_MS = 2140;
|
||||
|
||||
typedef struct {
|
||||
float frequency;
|
||||
} bm1366Module;
|
||||
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t job_id;
|
||||
uint8_t num_midstates;
|
||||
uint8_t starting_nonce[4];
|
||||
uint8_t nbits[4];
|
||||
uint8_t ntime[4];
|
||||
uint8_t merkle_root[32];
|
||||
uint8_t prev_block_hash[32];
|
||||
uint8_t version[4];
|
||||
} BM1366_job;
|
||||
|
||||
|
||||
|
||||
void BM1366_init(u_int64_t frequency);
|
||||
|
||||
void BM1366_send_init(void);
|
||||
void BM1366_send_work(void *GLOBAL_STATE, bm_job *next_bm_job);
|
||||
void BM1366_set_job_difficulty_mask(int);
|
||||
int BM1366_set_max_baud(void);
|
||||
int BM1366_set_default_baud(void);
|
||||
void BM1366_send_hash_frequency(float frequency);
|
||||
task_result * BM1366_proccess_work(void *GLOBAL_STATE);
|
||||
|
||||
#endif /* BM1366_H_ */
|
@ -2,30 +2,15 @@
|
||||
#define BM1397_H_
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "mining.h"
|
||||
#include "common.h"
|
||||
|
||||
#define BM1397_RST_PIN GPIO_NUM_1
|
||||
|
||||
|
||||
#define TYPE_JOB 0x20
|
||||
#define TYPE_CMD 0x40
|
||||
|
||||
#define GROUP_SINGLE 0x00
|
||||
#define GROUP_ALL 0x10
|
||||
|
||||
#define CMD_JOB 0x01
|
||||
|
||||
#define CMD_SETADDRESS 0x00
|
||||
#define CMD_WRITE 0x01
|
||||
#define CMD_READ 0x02
|
||||
#define CMD_INACTIVE 0x03
|
||||
|
||||
#define RESPONSE_CMD 0x00
|
||||
#define RESPONSE_JOB 0x80
|
||||
#define CRC5_MASK 0x1F
|
||||
|
||||
static const u_int64_t BM1397_FREQUENCY = CONFIG_BM1397_FREQUENCY;
|
||||
|
||||
static const u_int64_t ASIC_FREQUENCY = CONFIG_ASIC_FREQUENCY;
|
||||
static const u_int64_t BM1397_CORE_COUNT = 672;
|
||||
static const u_int64_t BM1397_HASHRATE_S = BM1397_FREQUENCY * BM1397_CORE_COUNT * 1000000;
|
||||
static const u_int64_t BM1397_HASHRATE_S = ASIC_FREQUENCY * BM1397_CORE_COUNT * 1000000;
|
||||
//2^32
|
||||
static const u_int64_t NONCE_SPACE = 4294967296;
|
||||
static const double BM1397_FULLSCAN_MS = ((double)NONCE_SPACE / (double)BM1397_HASHRATE_S) * 1000;
|
||||
@ -44,7 +29,7 @@ typedef enum {
|
||||
CMD_RESP = 1,
|
||||
} response_type_t;
|
||||
|
||||
struct __attribute__((__packed__)) job_packet {
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t job_id;
|
||||
uint8_t num_midstates;
|
||||
uint8_t starting_nonce[4];
|
||||
@ -55,23 +40,19 @@ struct __attribute__((__packed__)) job_packet {
|
||||
uint8_t midstate1[32];
|
||||
uint8_t midstate2[32];
|
||||
uint8_t midstate3[32];
|
||||
};
|
||||
} job_packet;
|
||||
|
||||
|
||||
|
||||
|
||||
struct __attribute__((__packed__)) nonce_response {
|
||||
uint8_t preamble[2];
|
||||
uint32_t nonce;
|
||||
uint8_t midstate_num;
|
||||
uint8_t job_id;
|
||||
uint8_t crc;
|
||||
};
|
||||
|
||||
void BM1397_init(u_int64_t frequency);
|
||||
|
||||
void BM1397_send_init(void);
|
||||
void BM1397_send_work(struct job_packet *job);
|
||||
void BM1397_send_work(void *GLOBAL_STATE, bm_job *next_bm_job);
|
||||
void BM1397_set_job_difficulty_mask(int);
|
||||
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);
|
||||
|
||||
#endif /* BM1397_H_ */
|
34
components/bm1397/include/common.h
Normal file
34
components/bm1397/include/common.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t job_id;
|
||||
uint32_t nonce;
|
||||
uint32_t rolled_version;
|
||||
} task_result;
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static int _largest_power_of_two(int num) {
|
||||
int power = 0;
|
||||
|
||||
while (num > 1) {
|
||||
num = num >> 1;
|
||||
power++;
|
||||
}
|
||||
|
||||
return 1 << power;
|
||||
}
|
||||
|
||||
#endif
|
@ -33,7 +33,7 @@ TEST_CASE("Check known working midstate + job command", "[bm1397]")
|
||||
0x7E, 0x02, 0x70, 0x35, 0xB1, 0xAC, 0xBA, 0xF2, 0x3E, 0xA0, 0x1A, 0x52, 0x73, 0x44, 0xFA, 0xF7, 0x6A, 0xB4, 0x76, 0xD3, 0x28, 0x21, 0x61, 0x18, 0xB7, 0x76, 0x0F, 0x7B, 0x1B, 0x22, 0xD2, 0x29,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
struct job_packet test_job;
|
||||
job_packet test_job;
|
||||
memcpy((uint8_t *) &test_job, work1, 146);
|
||||
|
||||
uint8_t buf[1024];
|
||||
@ -41,7 +41,7 @@ TEST_CASE("Check known working midstate + job command", "[bm1397]")
|
||||
|
||||
BM1397_send_work(&test_job);
|
||||
uint16_t received = SERIAL_rx(buf, 9, 20);
|
||||
TEST_ASSERT_GREATER_OR_EQUAL_UINT16(sizeof(struct nonce_response), received);
|
||||
TEST_ASSERT_GREATER_OR_EQUAL_UINT16(sizeof(struct asic_result), received);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < received - 1; i++) {
|
||||
@ -50,8 +50,8 @@ TEST_CASE("Check known working midstate + job command", "[bm1397]")
|
||||
}
|
||||
}
|
||||
|
||||
struct nonce_response nonce;
|
||||
memcpy((void *) &nonce, buf + i, sizeof(struct nonce_response));
|
||||
struct asic_result nonce;
|
||||
memcpy((void *) &nonce, buf + i, sizeof(struct asic_result));
|
||||
// expected nonce 9B 04 4C 0A
|
||||
TEST_ASSERT_EQUAL_UINT32(0x0a4c049b, nonce.nonce);
|
||||
TEST_ASSERT_EQUAL_UINT8(0x18, nonce.job_id & 0xfc);
|
||||
|
@ -8,7 +8,9 @@ typedef struct {
|
||||
uint32_t version;
|
||||
uint32_t version_mask;
|
||||
uint8_t prev_block_hash[32];
|
||||
uint8_t prev_block_hash_be[32];
|
||||
uint8_t merkle_root[32];
|
||||
uint8_t merkle_root_be[32];
|
||||
uint32_t ntime;
|
||||
uint32_t target; // aka difficulty, aka nbits
|
||||
uint32_t starting_nonce;
|
||||
@ -32,7 +34,7 @@ char * calculate_merkle_root_hash(const char * coinbase_tx, const uint8_t merkle
|
||||
|
||||
bm_job construct_bm_job(mining_notify * params, const char * merkle_root, const uint32_t version_mask);
|
||||
|
||||
double test_nonce_value(const bm_job * job, const uint32_t nonce, const uint8_t midstate_index);
|
||||
double test_nonce_value(const bm_job * job, const uint32_t nonce, const uint32_t rolled_version);
|
||||
|
||||
char * extranonce_2_generate(uint32_t extranonce_2, uint32_t length);
|
||||
|
||||
|
@ -63,8 +63,16 @@ bm_job construct_bm_job(mining_notify * params, const char * merkle_root, const
|
||||
new_job.pool_diff = params->difficulty;
|
||||
|
||||
hex2bin(merkle_root, new_job.merkle_root, 32);
|
||||
|
||||
//hex2bin(merkle_root, new_job.merkle_root_be, 32);
|
||||
swap_endian_words(merkle_root, new_job.merkle_root_be);
|
||||
reverse_bytes(new_job.merkle_root_be, 32);
|
||||
|
||||
swap_endian_words(params->prev_block_hash, new_job.prev_block_hash);
|
||||
|
||||
hex2bin(params->prev_block_hash, new_job.prev_block_hash_be, 32);
|
||||
reverse_bytes(new_job.prev_block_hash_be, 32);
|
||||
|
||||
////make the midstate hash
|
||||
uint8_t midstate_data[64];
|
||||
|
||||
@ -117,15 +125,15 @@ char * extranonce_2_generate(uint32_t extranonce_2, uint32_t length)
|
||||
static const double truediffone = 26959535291011309493156476344723991336010898738574164086137773096960.0;
|
||||
|
||||
/* testing a nonce and return the diff - 0 means invalid */
|
||||
double test_nonce_value(const bm_job * job, const uint32_t nonce, const uint8_t midstate_index) {
|
||||
double test_nonce_value(const bm_job * job, const uint32_t nonce, const uint32_t rolled_version) {
|
||||
double d64, s64, ds;
|
||||
unsigned char header[80];
|
||||
|
||||
// TODO: use the midstate hash instead of hashing the whole header
|
||||
uint32_t rolled_version = job->version;
|
||||
for (int i = 0; i < midstate_index; i++) {
|
||||
rolled_version = increment_bitmask(rolled_version, job->version_mask);
|
||||
}
|
||||
// // TODO: use the midstate hash instead of hashing the whole header
|
||||
// uint32_t rolled_version = job->version;
|
||||
// for (int i = 0; i < midstate_index; i++) {
|
||||
// rolled_version = increment_bitmask(rolled_version, job->version_mask);
|
||||
// }
|
||||
|
||||
// copy data from job to header
|
||||
memcpy(header, &rolled_version, 4);
|
||||
|
@ -254,7 +254,7 @@ int STRATUM_V1_subscribe(int socket, char ** extranonce, int * extranonce2_len)
|
||||
{
|
||||
// Subscribe
|
||||
char subscribe_msg[BUFFER_SIZE];
|
||||
sprintf(subscribe_msg, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": [\"bitaxe v2.2\"]}\n", send_uid++);
|
||||
sprintf(subscribe_msg, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": [\"bitaxe %s\"]}\n", send_uid++, CONFIG_ASIC_MODEL);
|
||||
debug_stratum_tx(subscribe_msg);
|
||||
write(socket, subscribe_msg, strlen(subscribe_msg));
|
||||
char * line;
|
||||
|
@ -6,3 +6,5 @@ stratumurl,data,string,public-pool.io
|
||||
stratumport,data,u16,21496
|
||||
stratumuser,data,string,1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa.bitaxe
|
||||
stratumpass,data,string,x
|
||||
asicfrequency,data,u16,450
|
||||
asicvoltage,data,u16,1400
|
@ -1,13 +1,19 @@
|
||||
menu "Bitaxe Configuration"
|
||||
|
||||
config BM1397_VOLTAGE
|
||||
config ASIC_MODEL
|
||||
string "ASIC Model"
|
||||
default "BM1397"
|
||||
help
|
||||
BM1397 or BM1366
|
||||
|
||||
config ASIC_VOLTAGE
|
||||
int "ASIC Core Voltage (mV)"
|
||||
range 1000 1800
|
||||
default 1400
|
||||
help
|
||||
The core voltage to set the BM1397 ASIC to.
|
||||
The core voltage to set the ASIC to. 1200 for BM1366 or 1400 for BM1397 is typical.
|
||||
|
||||
config BM1397_FREQUENCY
|
||||
config ASIC_FREQUENCY
|
||||
int "ASIC Hash Frequency (MHz)"
|
||||
range 200 800
|
||||
default 250
|
||||
|
@ -3,16 +3,28 @@
|
||||
|
||||
#include "work_queue.h"
|
||||
#include "bm1397.h"
|
||||
#include "bm1366.h"
|
||||
#include "system.h"
|
||||
#include "stratum_api.h"
|
||||
#include "asic_task.h"
|
||||
#include "power_management_task.h"
|
||||
|
||||
#include "serial.h"
|
||||
#include "common.h"
|
||||
|
||||
#define STRATUM_USER CONFIG_STRATUM_USER
|
||||
|
||||
typedef struct {
|
||||
void (*init_fn)(u_int64_t);
|
||||
task_result * (*receive_result_fn)(void *GLOBAL_STATE);
|
||||
int (*set_max_baud_fn)(void);
|
||||
void (*set_difficulty_mask_fn)(int);
|
||||
void (*send_work_fn)(void *GLOBAL_STATE, bm_job *next_bm_job);
|
||||
} AsicFunctions;
|
||||
|
||||
typedef struct {
|
||||
AsicFunctions ASIC_functions;
|
||||
double asic_job_frequency_ms;
|
||||
|
||||
work_queue stratum_queue;
|
||||
work_queue ASIC_jobs_queue;
|
||||
|
||||
@ -22,6 +34,7 @@ typedef struct {
|
||||
PowerManagementModule POWER_MANAGEMENT_MODULE;
|
||||
|
||||
|
||||
|
||||
char * extranonce_str;
|
||||
int extranonce_2_len;
|
||||
int abandon_work;
|
||||
@ -34,7 +47,10 @@ typedef struct {
|
||||
|
||||
int sock;
|
||||
|
||||
|
||||
} GlobalState;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* GLOBAL_STATE_H_ */
|
41
main/miner.c
41
main/miner.c
@ -15,6 +15,10 @@
|
||||
#include "asic_result_task.h"
|
||||
#include "nvs_config.h"
|
||||
|
||||
#define ASIC_MODEL CONFIG_ASIC_MODEL
|
||||
|
||||
|
||||
|
||||
static GlobalState GLOBAL_STATE = {
|
||||
.extranonce_str = NULL,
|
||||
.extranonce_2_len = 0,
|
||||
@ -22,7 +26,7 @@ static GlobalState GLOBAL_STATE = {
|
||||
.version_mask = 0,
|
||||
.POWER_MANAGEMENT_MODULE = {
|
||||
.frequency_multiplier = 1,
|
||||
.frequency_value = BM1397_FREQUENCY
|
||||
.frequency_value = ASIC_FREQUENCY
|
||||
}
|
||||
};
|
||||
|
||||
@ -30,6 +34,39 @@ static const char *TAG = "miner";
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
|
||||
if(strcmp(ASIC_MODEL, "BM1366") == 0){
|
||||
ESP_LOGI(TAG, "ASIC: BM1366");
|
||||
AsicFunctions ASIC_functions = {
|
||||
.init_fn = BM1366_init,
|
||||
.receive_result_fn = BM1366_proccess_work,
|
||||
.set_max_baud_fn = BM1366_set_max_baud,
|
||||
.set_difficulty_mask_fn = BM1366_set_job_difficulty_mask,
|
||||
.send_work_fn = BM1366_send_work
|
||||
};
|
||||
GLOBAL_STATE.asic_job_frequency_ms = BM1366_FULLSCAN_MS;
|
||||
|
||||
GLOBAL_STATE.ASIC_functions = ASIC_functions;
|
||||
}else if(strcmp(ASIC_MODEL, "BM1397") == 0){
|
||||
ESP_LOGI(TAG, "ASIC: BM1397");
|
||||
AsicFunctions ASIC_functions = {
|
||||
.init_fn = BM1397_init,
|
||||
.receive_result_fn = BM1397_proccess_work,
|
||||
.set_max_baud_fn = BM1397_set_max_baud,
|
||||
.set_difficulty_mask_fn = BM1397_set_job_difficulty_mask,
|
||||
.send_work_fn = BM1397_send_work
|
||||
};
|
||||
GLOBAL_STATE.asic_job_frequency_ms = BM1397_FULLSCAN_MS;
|
||||
|
||||
GLOBAL_STATE.ASIC_functions = ASIC_functions;
|
||||
}else{
|
||||
ESP_LOGI(TAG, "Invalid ASIC model");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ESP_LOGI(TAG, "Welcome to the bitaxe!");
|
||||
//wait between 0 and 5 seconds for multiple units
|
||||
vTaskDelay(rand() % 5001 / portTICK_PERIOD_MS);
|
||||
@ -70,7 +107,7 @@ void app_main(void)
|
||||
|
||||
SERIAL_init();
|
||||
|
||||
BM1397_init(GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value);
|
||||
(*GLOBAL_STATE.ASIC_functions.init_fn)(GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value);
|
||||
|
||||
//set the startup_done flag
|
||||
GLOBAL_STATE.SYSTEM_MODULE.startup_done = true;
|
||||
|
@ -9,8 +9,9 @@
|
||||
#define NVS_CONFIG_STRATUM_PORT "stratumport"
|
||||
#define NVS_CONFIG_STRATUM_USER "stratumuser"
|
||||
#define NVS_CONFIG_STRATUM_PASS "stratumpass"
|
||||
#define NVS_CONFIG_BM1397_FREQ "bm1397frequency"
|
||||
#define NVS_CONFIG_BM1397_VOLTAGE "bm1397voltage"
|
||||
#define NVS_CONFIG_ASIC_FREQ "asicfrequency"
|
||||
#define NVS_CONFIG_ASIC_VOLTAGE "asicvoltage"
|
||||
#define NVS_CONFIG_ASIC_MODEL "asicModel"
|
||||
|
||||
char * nvs_config_get_string(const char * key, const char * default_value);
|
||||
uint16_t nvs_config_get_u16(const char * key, const uint16_t default_value);
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
static const char *TAG = "SystemModule";
|
||||
|
||||
#define BM1397_VOLTAGE CONFIG_BM1397_VOLTAGE
|
||||
#define ASIC_VOLTAGE CONFIG_ASIC_VOLTAGE
|
||||
|
||||
static void _suffix_string(uint64_t, char *, size_t, int);
|
||||
|
||||
@ -66,7 +66,7 @@ static void _init_system(SystemModule* module) {
|
||||
ADC_init();
|
||||
|
||||
//DS4432U tests
|
||||
DS4432U_set_vcore(BM1397_VOLTAGE / 1000.0);
|
||||
DS4432U_set_vcore(ASIC_VOLTAGE / 1000.0);
|
||||
|
||||
//Fan Tests
|
||||
EMC2101_init();
|
||||
|
@ -5,102 +5,58 @@
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "nvs_config.h"
|
||||
#include "utils.h"
|
||||
|
||||
const char * TAG = "asic_result";
|
||||
|
||||
void ASIC_result_task(void * pvParameters)
|
||||
{
|
||||
|
||||
GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters;
|
||||
|
||||
uint8_t buf[CHUNK_SIZE];
|
||||
memset(buf, 0, 1024);
|
||||
SERIAL_clear_buffer();
|
||||
uint32_t prev_nonce = 0;
|
||||
|
||||
|
||||
char * user = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, STRATUM_USER);
|
||||
|
||||
while(1){
|
||||
|
||||
//wait for a response, wait time is pretty arbitrary
|
||||
int received = SERIAL_rx(buf, 9, 60000);
|
||||
task_result *asic_result = (*GLOBAL_STATE->ASIC_functions.receive_result_fn)(GLOBAL_STATE);
|
||||
|
||||
if (received < 0) {
|
||||
ESP_LOGI(TAG, "Error in serial RX");
|
||||
continue;
|
||||
} else if(received == 0){
|
||||
// Didn't find a solution, restart and try again
|
||||
if(asic_result == NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(received != 9 || buf[0] != 0xAA || buf[1] != 0x55){
|
||||
ESP_LOGI(TAG, "Serial RX invalid %i", received);
|
||||
ESP_LOG_BUFFER_HEX(TAG, buf, received);
|
||||
continue;
|
||||
}
|
||||
uint8_t job_id = asic_result->job_id;
|
||||
|
||||
uint8_t nonce_found = 0;
|
||||
uint32_t first_nonce = 0;
|
||||
|
||||
struct nonce_response nonce;
|
||||
memcpy((void *) &nonce, buf, sizeof(struct nonce_response));
|
||||
|
||||
uint8_t rx_job_id = nonce.job_id & 0xfc;
|
||||
uint8_t rx_midstate_index = nonce.job_id & 0x03;
|
||||
|
||||
if (GLOBAL_STATE->valid_jobs[rx_job_id] == 0) {
|
||||
ESP_LOGI(TAG, "Invalid job nonce found, id=%d", nonce.job_id);
|
||||
}
|
||||
|
||||
// ASIC may return the same nonce multiple times
|
||||
// or one that was already found
|
||||
// most of the time it behavies however
|
||||
if (nonce_found == 0) {
|
||||
first_nonce = nonce.nonce;
|
||||
nonce_found = 1;
|
||||
} else if (nonce.nonce == first_nonce) {
|
||||
// stop if we've already seen this nonce
|
||||
break;
|
||||
}
|
||||
|
||||
if (nonce.nonce == prev_nonce) {
|
||||
continue;
|
||||
} else {
|
||||
prev_nonce = nonce.nonce;
|
||||
if (GLOBAL_STATE->valid_jobs[job_id] == 0) {
|
||||
ESP_LOGI(TAG, "Invalid job nonce found, id=%d", job_id);
|
||||
}
|
||||
|
||||
// check the nonce difficulty
|
||||
double nonce_diff = test_nonce_value(
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id],
|
||||
nonce.nonce,
|
||||
rx_midstate_index
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id],
|
||||
asic_result->nonce,
|
||||
asic_result->rolled_version
|
||||
);
|
||||
|
||||
ESP_LOGI(TAG, "Nonce difficulty %.2f of %ld.", nonce_diff, GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->pool_diff);
|
||||
ESP_LOGI(TAG, "Nonce difficulty %.2f of %ld.", nonce_diff, GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->pool_diff);
|
||||
|
||||
if (nonce_diff > GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->pool_diff)
|
||||
if (nonce_diff > GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->pool_diff)
|
||||
{
|
||||
SYSTEM_notify_found_nonce(
|
||||
&GLOBAL_STATE->SYSTEM_MODULE,
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->pool_diff,
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->pool_diff,
|
||||
nonce_diff,
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->target
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->target
|
||||
);
|
||||
|
||||
uint32_t rolled_version = GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version;
|
||||
for (int i = 0; i < rx_midstate_index; i++) {
|
||||
rolled_version = increment_bitmask(rolled_version, GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version_mask);
|
||||
}
|
||||
|
||||
STRATUM_V1_submit_share(
|
||||
GLOBAL_STATE->sock,
|
||||
user,
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->jobid,
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->extranonce2,
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->ntime,
|
||||
nonce.nonce,
|
||||
rolled_version ^ GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->jobid,
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->extranonce2,
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->ntime,
|
||||
asic_result->nonce,
|
||||
asic_result->rolled_version ^ GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->version
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -19,18 +19,17 @@ void ASIC_task(void * pvParameters)
|
||||
GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters;
|
||||
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int baud = BM1397_set_max_baud();
|
||||
int baud = (*GLOBAL_STATE->ASIC_functions.set_max_baud_fn)();
|
||||
SERIAL_set_baud(baud);
|
||||
|
||||
SYSTEM_notify_mining_started(&GLOBAL_STATE->SYSTEM_MODULE);
|
||||
@ -40,50 +39,17 @@ void ASIC_task(void * pvParameters)
|
||||
bm_job * next_bm_job = (bm_job *) queue_dequeue(&GLOBAL_STATE->ASIC_jobs_queue);
|
||||
|
||||
if(next_bm_job->pool_diff != GLOBAL_STATE->stratum_difficulty){
|
||||
ESP_LOGI(TAG, "New difficulty %ld", next_bm_job->pool_diff);
|
||||
BM1397_set_job_difficulty_mask(next_bm_job->pool_diff);
|
||||
//ESP_LOGI(TAG, "New difficulty %d", next_bm_job->pool_diff);
|
||||
(*GLOBAL_STATE->ASIC_functions.set_difficulty_mask_fn)(next_bm_job->pool_diff);
|
||||
GLOBAL_STATE->stratum_difficulty = next_bm_job->pool_diff;
|
||||
}
|
||||
|
||||
|
||||
struct job_packet job;
|
||||
// max job number is 128
|
||||
// there is still some really weird logic with the job id bits for the asic to sort out
|
||||
// so we have it limited to 128 and it has to increment by 4
|
||||
id = (id + 4) % 128;
|
||||
|
||||
job.job_id = id;
|
||||
job.num_midstates = next_bm_job->num_midstates;
|
||||
memcpy(&job.starting_nonce, &next_bm_job->starting_nonce, 4);
|
||||
memcpy(&job.nbits, &next_bm_job->target, 4);
|
||||
memcpy(&job.ntime, &next_bm_job->ntime, 4);
|
||||
memcpy(&job.merkle4, next_bm_job->merkle_root + 28, 4);
|
||||
memcpy(job.midstate, next_bm_job->midstate, 32);
|
||||
|
||||
if (job.num_midstates == 4)
|
||||
{
|
||||
memcpy(job.midstate1, next_bm_job->midstate1, 32);
|
||||
memcpy(job.midstate2, next_bm_job->midstate2, 32);
|
||||
memcpy(job.midstate3, next_bm_job->midstate3, 32);
|
||||
}
|
||||
|
||||
if (GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) {
|
||||
free_bm_job(GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id]);
|
||||
}
|
||||
|
||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] = next_bm_job;
|
||||
|
||||
pthread_mutex_lock(&GLOBAL_STATE->valid_jobs_lock);
|
||||
GLOBAL_STATE-> valid_jobs[job.job_id] = 1;
|
||||
pthread_mutex_unlock(&GLOBAL_STATE->valid_jobs_lock);
|
||||
|
||||
|
||||
|
||||
|
||||
BM1397_send_work(&job); //send the job to the ASIC
|
||||
(*GLOBAL_STATE->ASIC_functions.send_work_fn)(GLOBAL_STATE, next_bm_job); //send the job to the ASIC
|
||||
|
||||
//Time to execute the above code is ~0.3ms
|
||||
vTaskDelay((BM1397_FULLSCAN_MS - 0.3 ) / portTICK_PERIOD_MS);
|
||||
//vTaskDelay((BM1397_FULLSCAN_MS - 0.3 ) / portTICK_PERIOD_MS);
|
||||
vTaskDelay((GLOBAL_STATE->asic_job_frequency_ms - 0.3) / portTICK_PERIOD_MS);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define VOLTAGE_START_THROTTLE 4900
|
||||
#define VOLTAGE_MIN_THROTTLE 3500
|
||||
#define VOLTAGE_RANGE (VOLTAGE_START_THROTTLE - VOLTAGE_MIN_THROTTLE)
|
||||
#define ASIC_MODEL CONFIG_ASIC_MODEL
|
||||
|
||||
static const char * TAG = "power_management";
|
||||
|
||||
@ -33,7 +34,7 @@ static float _fbound(float value, float lower_bound, float upper_bound)
|
||||
|
||||
// void _power_init(PowerManagementModule * power_management){
|
||||
// power_management->frequency_multiplier = 1;
|
||||
// power_management->frequency_value = BM1397_FREQUENCY;
|
||||
// power_management->frequency_value = ASIC_FREQUENCY;
|
||||
|
||||
// }
|
||||
|
||||
@ -46,75 +47,76 @@ void POWER_MANAGEMENT_task(void * pvParameters){
|
||||
|
||||
int last_frequency_increase = 0;
|
||||
while(1){
|
||||
power_management->fan_speed = EMC2101_get_fan_speed();
|
||||
power_management->chip_temp = EMC2101_get_chip_temp();
|
||||
|
||||
power_management->voltage = INA260_read_voltage();
|
||||
power_management->power = INA260_read_power() / 1000;
|
||||
power_management->current = INA260_read_current();
|
||||
|
||||
if(strcmp(ASIC_MODEL, "BM1397") == 0){
|
||||
power_management->fan_speed = EMC2101_get_fan_speed();
|
||||
power_management->chip_temp = EMC2101_get_chip_temp();
|
||||
|
||||
// Voltage
|
||||
// We'll throttle between 4.9v and 3.5v
|
||||
float voltage_multiplier = _fbound((power_management->voltage - VOLTAGE_MIN_THROTTLE) * (1/(float)VOLTAGE_RANGE), 0, 1);
|
||||
// Voltage
|
||||
// We'll throttle between 4.9v and 3.5v
|
||||
float voltage_multiplier = _fbound((power_management->voltage - VOLTAGE_MIN_THROTTLE) * (1/(float)VOLTAGE_RANGE), 0, 1);
|
||||
|
||||
|
||||
// Temperature
|
||||
float temperature_multiplier = 1;
|
||||
float over_temp = -(THROTTLE_TEMP - power_management->chip_temp);
|
||||
if(over_temp > 0){
|
||||
temperature_multiplier = (THROTTLE_TEMP_RANGE - over_temp)/THROTTLE_TEMP_RANGE;
|
||||
}
|
||||
|
||||
float lowest_multiplier = 1;
|
||||
float multipliers[2] = {voltage_multiplier, temperature_multiplier};
|
||||
|
||||
for(int i = 0; i < 2; i++){
|
||||
if(multipliers[i] < lowest_multiplier){
|
||||
lowest_multiplier = multipliers[i];
|
||||
// Temperature
|
||||
float temperature_multiplier = 1;
|
||||
float over_temp = -(THROTTLE_TEMP - power_management->chip_temp);
|
||||
if(over_temp > 0){
|
||||
temperature_multiplier = (THROTTLE_TEMP_RANGE - over_temp)/THROTTLE_TEMP_RANGE;
|
||||
}
|
||||
|
||||
float lowest_multiplier = 1;
|
||||
float multipliers[2] = {voltage_multiplier, temperature_multiplier};
|
||||
|
||||
for(int i = 0; i < 2; i++){
|
||||
if(multipliers[i] < lowest_multiplier){
|
||||
lowest_multiplier = multipliers[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
power_management->frequency_multiplier = lowest_multiplier;
|
||||
power_management->frequency_multiplier = lowest_multiplier;
|
||||
|
||||
|
||||
float target_frequency = _fbound(power_management->frequency_multiplier * BM1397_FREQUENCY, 0, BM1397_FREQUENCY);
|
||||
float target_frequency = _fbound(power_management->frequency_multiplier * ASIC_FREQUENCY, 0, ASIC_FREQUENCY);
|
||||
|
||||
if(target_frequency < 50){
|
||||
// TODO: Turn the chip off
|
||||
}
|
||||
if(target_frequency < 50){
|
||||
// TODO: Turn the chip off
|
||||
}
|
||||
|
||||
// chip is coming back from a low/no voltage event
|
||||
if(power_management->frequency_value < 50 && target_frequency > 50){
|
||||
// TODO recover gracefully?
|
||||
esp_restart();
|
||||
}
|
||||
// chip is coming back from a low/no voltage event
|
||||
if(power_management->frequency_value < 50 && target_frequency > 50){
|
||||
// TODO recover gracefully?
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
|
||||
if(power_management->frequency_value > target_frequency){
|
||||
power_management->frequency_value = target_frequency;
|
||||
last_frequency_increase = 0;
|
||||
BM1397_send_hash_frequency(power_management->frequency_value);
|
||||
ESP_LOGI(TAG, "target %f, Freq %f, Temp %f, Power %f", target_frequency, power_management->frequency_value, power_management->chip_temp, power_management->power);
|
||||
}else{
|
||||
if(
|
||||
last_frequency_increase > 120 &&
|
||||
power_management->frequency_value != BM1397_FREQUENCY
|
||||
){
|
||||
float add = (target_frequency + power_management->frequency_value) / 2;
|
||||
power_management->frequency_value += _fbound(add, 2 , 20);
|
||||
if(power_management->frequency_value > target_frequency){
|
||||
power_management->frequency_value = target_frequency;
|
||||
last_frequency_increase = 0;
|
||||
BM1397_send_hash_frequency(power_management->frequency_value);
|
||||
ESP_LOGI(TAG, "target %f, Freq %f, Temp %f, Power %f", target_frequency, power_management->frequency_value, power_management->chip_temp, power_management->power);
|
||||
last_frequency_increase = 60;
|
||||
}else{
|
||||
last_frequency_increase++;
|
||||
if(
|
||||
last_frequency_increase > 120 &&
|
||||
power_management->frequency_value != ASIC_FREQUENCY
|
||||
){
|
||||
float add = (target_frequency + power_management->frequency_value) / 2;
|
||||
power_management->frequency_value += _fbound(add, 2 , 20);
|
||||
BM1397_send_hash_frequency(power_management->frequency_value);
|
||||
ESP_LOGI(TAG, "target %f, Freq %f, Temp %f, Power %f", target_frequency, power_management->frequency_value, power_management->chip_temp, power_management->power);
|
||||
last_frequency_increase = 60;
|
||||
}else{
|
||||
last_frequency_increase++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//ESP_LOGI(TAG, "target %f, Freq %f, Volt %f, Power %f", target_frequency, power_management->frequency_value, power_management->voltage, power_management->power);
|
||||
vTaskDelay(POLL_RATE / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
@ -16,6 +16,6 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
set(IDF_TARGET "esp32s3")
|
||||
|
||||
idf_build_set_property(COMPILE_DEFINITIONS "-DCONFIG_BM1397_FREQUENCY=100" APPEND)
|
||||
idf_build_set_property(COMPILE_DEFINITIONS "-DCONFIG_ASIC_FREQUENCY=100" APPEND)
|
||||
|
||||
project(unit_test_stratum)
|
||||
|
Loading…
x
Reference in New Issue
Block a user