mirror of
https://github.com/skot/ESP-Miner.git
synced 2025-06-14 13:20:58 +02:00
parent
a3cdc67d19
commit
9bc0671563
@ -1,5 +1,6 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS
|
SRCS
|
||||||
|
"bm1366.c"
|
||||||
"bm1397.c"
|
"bm1397.c"
|
||||||
"serial.c"
|
"serial.c"
|
||||||
"crc.c"
|
"crc.c"
|
||||||
@ -10,3 +11,10 @@ REQUIRES
|
|||||||
driver
|
driver
|
||||||
stratum
|
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 "bm1397.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "crc.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 SLEEP_TIME 20
|
||||||
#define FREQ_MULT 25.0
|
#define FREQ_MULT 25.0
|
||||||
@ -25,8 +47,20 @@
|
|||||||
#define TICKET_MASK 0x14
|
#define TICKET_MASK 0x14
|
||||||
#define MISC_CONTROL 0x18
|
#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 const char *TAG = "bm1397Module";
|
||||||
|
|
||||||
|
static uint8_t asic_response_buffer[CHUNK_SIZE];
|
||||||
|
static uint32_t prev_nonce = 0;
|
||||||
|
static task_result result;
|
||||||
|
|
||||||
/// @brief
|
/// @brief
|
||||||
/// @param ftdi
|
/// @param ftdi
|
||||||
/// @param header
|
/// @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);
|
_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()
|
// borrowed from cgminer driver-gekko.c calc_gsf_freq()
|
||||||
void BM1397_send_hash_frequency(float frequency) {
|
void BM1397_send_hash_frequency(float frequency) {
|
||||||
@ -238,6 +249,8 @@ static void _send_read_address(void) {
|
|||||||
void BM1397_init(u_int64_t frequency) {
|
void BM1397_init(u_int64_t frequency) {
|
||||||
ESP_LOGI(TAG, "Initializing BM1397");
|
ESP_LOGI(TAG, "Initializing BM1397");
|
||||||
|
|
||||||
|
memset(asic_response_buffer, 0, sizeof(asic_response_buffer));
|
||||||
|
|
||||||
esp_rom_gpio_pad_select_gpio(BM1397_RST_PIN);
|
esp_rom_gpio_pad_select_gpio(BM1397_RST_PIN);
|
||||||
gpio_set_direction(BM1397_RST_PIN, GPIO_MODE_OUTPUT);
|
gpio_set_direction(BM1397_RST_PIN, GPIO_MODE_OUTPUT);
|
||||||
|
|
||||||
@ -249,7 +262,6 @@ void BM1397_init(u_int64_t frequency) {
|
|||||||
|
|
||||||
_send_init(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) {
|
if (job.num_midstates == 4)
|
||||||
_send_BM1397((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t*)job, sizeof(struct job_packet), false);
|
{
|
||||||
|
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_
|
#define BM1397_H_
|
||||||
|
|
||||||
#include "driver/gpio.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
|
#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_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
|
//2^32
|
||||||
static const u_int64_t NONCE_SPACE = 4294967296;
|
static const u_int64_t NONCE_SPACE = 4294967296;
|
||||||
static const double BM1397_FULLSCAN_MS = ((double)NONCE_SPACE / (double)BM1397_HASHRATE_S) * 1000;
|
static const double BM1397_FULLSCAN_MS = ((double)NONCE_SPACE / (double)BM1397_HASHRATE_S) * 1000;
|
||||||
@ -44,7 +29,7 @@ typedef enum {
|
|||||||
CMD_RESP = 1,
|
CMD_RESP = 1,
|
||||||
} response_type_t;
|
} response_type_t;
|
||||||
|
|
||||||
struct __attribute__((__packed__)) job_packet {
|
typedef struct __attribute__((__packed__)) {
|
||||||
uint8_t job_id;
|
uint8_t job_id;
|
||||||
uint8_t num_midstates;
|
uint8_t num_midstates;
|
||||||
uint8_t starting_nonce[4];
|
uint8_t starting_nonce[4];
|
||||||
@ -55,23 +40,19 @@ struct __attribute__((__packed__)) job_packet {
|
|||||||
uint8_t midstate1[32];
|
uint8_t midstate1[32];
|
||||||
uint8_t midstate2[32];
|
uint8_t midstate2[32];
|
||||||
uint8_t midstate3[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_init(u_int64_t frequency);
|
||||||
|
|
||||||
void BM1397_send_init(void);
|
void BM1397_send_work(void *GLOBAL_STATE, bm_job *next_bm_job);
|
||||||
void BM1397_send_work(struct job_packet *job);
|
|
||||||
void BM1397_set_job_difficulty_mask(int);
|
void BM1397_set_job_difficulty_mask(int);
|
||||||
int BM1397_set_max_baud(void);
|
int BM1397_set_max_baud(void);
|
||||||
int BM1397_set_default_baud(void);
|
int BM1397_set_default_baud(void);
|
||||||
void BM1397_send_hash_frequency(float frequency);
|
void BM1397_send_hash_frequency(float frequency);
|
||||||
|
task_result * BM1397_proccess_work(void *GLOBAL_STATE);
|
||||||
|
|
||||||
#endif /* BM1397_H_ */
|
#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,
|
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,
|
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);
|
memcpy((uint8_t *) &test_job, work1, 146);
|
||||||
|
|
||||||
uint8_t buf[1024];
|
uint8_t buf[1024];
|
||||||
@ -41,7 +41,7 @@ TEST_CASE("Check known working midstate + job command", "[bm1397]")
|
|||||||
|
|
||||||
BM1397_send_work(&test_job);
|
BM1397_send_work(&test_job);
|
||||||
uint16_t received = SERIAL_rx(buf, 9, 20);
|
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;
|
int i;
|
||||||
for (i = 0; i < received - 1; 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;
|
struct asic_result nonce;
|
||||||
memcpy((void *) &nonce, buf + i, sizeof(struct nonce_response));
|
memcpy((void *) &nonce, buf + i, sizeof(struct asic_result));
|
||||||
// expected nonce 9B 04 4C 0A
|
// expected nonce 9B 04 4C 0A
|
||||||
TEST_ASSERT_EQUAL_UINT32(0x0a4c049b, nonce.nonce);
|
TEST_ASSERT_EQUAL_UINT32(0x0a4c049b, nonce.nonce);
|
||||||
TEST_ASSERT_EQUAL_UINT8(0x18, nonce.job_id & 0xfc);
|
TEST_ASSERT_EQUAL_UINT8(0x18, nonce.job_id & 0xfc);
|
||||||
|
@ -8,7 +8,9 @@ typedef struct {
|
|||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t version_mask;
|
uint32_t version_mask;
|
||||||
uint8_t prev_block_hash[32];
|
uint8_t prev_block_hash[32];
|
||||||
|
uint8_t prev_block_hash_be[32];
|
||||||
uint8_t merkle_root[32];
|
uint8_t merkle_root[32];
|
||||||
|
uint8_t merkle_root_be[32];
|
||||||
uint32_t ntime;
|
uint32_t ntime;
|
||||||
uint32_t target; // aka difficulty, aka nbits
|
uint32_t target; // aka difficulty, aka nbits
|
||||||
uint32_t starting_nonce;
|
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);
|
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);
|
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;
|
new_job.pool_diff = params->difficulty;
|
||||||
|
|
||||||
hex2bin(merkle_root, new_job.merkle_root, 32);
|
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);
|
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
|
////make the midstate hash
|
||||||
uint8_t midstate_data[64];
|
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;
|
static const double truediffone = 26959535291011309493156476344723991336010898738574164086137773096960.0;
|
||||||
|
|
||||||
/* testing a nonce and return the diff - 0 means invalid */
|
/* 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;
|
double d64, s64, ds;
|
||||||
unsigned char header[80];
|
unsigned char header[80];
|
||||||
|
|
||||||
// TODO: use the midstate hash instead of hashing the whole header
|
// // TODO: use the midstate hash instead of hashing the whole header
|
||||||
uint32_t rolled_version = job->version;
|
// uint32_t rolled_version = job->version;
|
||||||
for (int i = 0; i < midstate_index; i++) {
|
// for (int i = 0; i < midstate_index; i++) {
|
||||||
rolled_version = increment_bitmask(rolled_version, job->version_mask);
|
// rolled_version = increment_bitmask(rolled_version, job->version_mask);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// copy data from job to header
|
// copy data from job to header
|
||||||
memcpy(header, &rolled_version, 4);
|
memcpy(header, &rolled_version, 4);
|
||||||
|
@ -254,7 +254,7 @@ int STRATUM_V1_subscribe(int socket, char ** extranonce, int * extranonce2_len)
|
|||||||
{
|
{
|
||||||
// Subscribe
|
// Subscribe
|
||||||
char subscribe_msg[BUFFER_SIZE];
|
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);
|
debug_stratum_tx(subscribe_msg);
|
||||||
write(socket, subscribe_msg, strlen(subscribe_msg));
|
write(socket, subscribe_msg, strlen(subscribe_msg));
|
||||||
char * line;
|
char * line;
|
||||||
|
@ -6,3 +6,5 @@ stratumurl,data,string,public-pool.io
|
|||||||
stratumport,data,u16,21496
|
stratumport,data,u16,21496
|
||||||
stratumuser,data,string,1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa.bitaxe
|
stratumuser,data,string,1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa.bitaxe
|
||||||
stratumpass,data,string,x
|
stratumpass,data,string,x
|
||||||
|
asicfrequency,data,u16,450
|
||||||
|
asicvoltage,data,u16,1400
|
@ -1,13 +1,19 @@
|
|||||||
menu "Bitaxe Configuration"
|
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)"
|
int "ASIC Core Voltage (mV)"
|
||||||
range 1000 1800
|
range 1000 1800
|
||||||
default 1400
|
default 1400
|
||||||
help
|
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)"
|
int "ASIC Hash Frequency (MHz)"
|
||||||
range 200 800
|
range 200 800
|
||||||
default 250
|
default 250
|
||||||
|
@ -3,16 +3,28 @@
|
|||||||
|
|
||||||
#include "work_queue.h"
|
#include "work_queue.h"
|
||||||
#include "bm1397.h"
|
#include "bm1397.h"
|
||||||
|
#include "bm1366.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "stratum_api.h"
|
#include "stratum_api.h"
|
||||||
#include "asic_task.h"
|
#include "asic_task.h"
|
||||||
#include "power_management_task.h"
|
#include "power_management_task.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#define STRATUM_USER CONFIG_STRATUM_USER
|
#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 {
|
typedef struct {
|
||||||
|
AsicFunctions ASIC_functions;
|
||||||
|
double asic_job_frequency_ms;
|
||||||
|
|
||||||
work_queue stratum_queue;
|
work_queue stratum_queue;
|
||||||
work_queue ASIC_jobs_queue;
|
work_queue ASIC_jobs_queue;
|
||||||
|
|
||||||
@ -22,6 +34,7 @@ typedef struct {
|
|||||||
PowerManagementModule POWER_MANAGEMENT_MODULE;
|
PowerManagementModule POWER_MANAGEMENT_MODULE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char * extranonce_str;
|
char * extranonce_str;
|
||||||
int extranonce_2_len;
|
int extranonce_2_len;
|
||||||
int abandon_work;
|
int abandon_work;
|
||||||
@ -34,7 +47,10 @@ typedef struct {
|
|||||||
|
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
|
|
||||||
} GlobalState;
|
} GlobalState;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* GLOBAL_STATE_H_ */
|
#endif /* GLOBAL_STATE_H_ */
|
41
main/miner.c
41
main/miner.c
@ -15,6 +15,10 @@
|
|||||||
#include "asic_result_task.h"
|
#include "asic_result_task.h"
|
||||||
#include "nvs_config.h"
|
#include "nvs_config.h"
|
||||||
|
|
||||||
|
#define ASIC_MODEL CONFIG_ASIC_MODEL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static GlobalState GLOBAL_STATE = {
|
static GlobalState GLOBAL_STATE = {
|
||||||
.extranonce_str = NULL,
|
.extranonce_str = NULL,
|
||||||
.extranonce_2_len = 0,
|
.extranonce_2_len = 0,
|
||||||
@ -22,7 +26,7 @@ static GlobalState GLOBAL_STATE = {
|
|||||||
.version_mask = 0,
|
.version_mask = 0,
|
||||||
.POWER_MANAGEMENT_MODULE = {
|
.POWER_MANAGEMENT_MODULE = {
|
||||||
.frequency_multiplier = 1,
|
.frequency_multiplier = 1,
|
||||||
.frequency_value = BM1397_FREQUENCY
|
.frequency_value = ASIC_FREQUENCY
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,6 +34,39 @@ static const char *TAG = "miner";
|
|||||||
|
|
||||||
void app_main(void)
|
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!");
|
ESP_LOGI(TAG, "Welcome to the bitaxe!");
|
||||||
//wait between 0 and 5 seconds for multiple units
|
//wait between 0 and 5 seconds for multiple units
|
||||||
vTaskDelay(rand() % 5001 / portTICK_PERIOD_MS);
|
vTaskDelay(rand() % 5001 / portTICK_PERIOD_MS);
|
||||||
@ -70,7 +107,7 @@ void app_main(void)
|
|||||||
|
|
||||||
SERIAL_init();
|
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
|
//set the startup_done flag
|
||||||
GLOBAL_STATE.SYSTEM_MODULE.startup_done = true;
|
GLOBAL_STATE.SYSTEM_MODULE.startup_done = true;
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
#define NVS_CONFIG_STRATUM_PORT "stratumport"
|
#define NVS_CONFIG_STRATUM_PORT "stratumport"
|
||||||
#define NVS_CONFIG_STRATUM_USER "stratumuser"
|
#define NVS_CONFIG_STRATUM_USER "stratumuser"
|
||||||
#define NVS_CONFIG_STRATUM_PASS "stratumpass"
|
#define NVS_CONFIG_STRATUM_PASS "stratumpass"
|
||||||
#define NVS_CONFIG_BM1397_FREQ "bm1397frequency"
|
#define NVS_CONFIG_ASIC_FREQ "asicfrequency"
|
||||||
#define NVS_CONFIG_BM1397_VOLTAGE "bm1397voltage"
|
#define NVS_CONFIG_ASIC_VOLTAGE "asicvoltage"
|
||||||
|
#define NVS_CONFIG_ASIC_MODEL "asicModel"
|
||||||
|
|
||||||
char * nvs_config_get_string(const char * key, const char * default_value);
|
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);
|
uint16_t nvs_config_get_u16(const char * key, const uint16_t default_value);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
static const char *TAG = "SystemModule";
|
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);
|
static void _suffix_string(uint64_t, char *, size_t, int);
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ static void _init_system(SystemModule* module) {
|
|||||||
ADC_init();
|
ADC_init();
|
||||||
|
|
||||||
//DS4432U tests
|
//DS4432U tests
|
||||||
DS4432U_set_vcore(BM1397_VOLTAGE / 1000.0);
|
DS4432U_set_vcore(ASIC_VOLTAGE / 1000.0);
|
||||||
|
|
||||||
//Fan Tests
|
//Fan Tests
|
||||||
EMC2101_init();
|
EMC2101_init();
|
||||||
|
@ -5,102 +5,58 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "nvs_config.h"
|
#include "nvs_config.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
const char * TAG = "asic_result";
|
const char * TAG = "asic_result";
|
||||||
|
|
||||||
void ASIC_result_task(void * pvParameters)
|
void ASIC_result_task(void * pvParameters)
|
||||||
{
|
{
|
||||||
|
|
||||||
GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters;
|
GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters;
|
||||||
|
|
||||||
uint8_t buf[CHUNK_SIZE];
|
|
||||||
memset(buf, 0, 1024);
|
|
||||||
SERIAL_clear_buffer();
|
SERIAL_clear_buffer();
|
||||||
uint32_t prev_nonce = 0;
|
|
||||||
|
|
||||||
|
|
||||||
char * user = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, STRATUM_USER);
|
char * user = nvs_config_get_string(NVS_CONFIG_STRATUM_USER, STRATUM_USER);
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
|
|
||||||
//wait for a response, wait time is pretty arbitrary
|
task_result *asic_result = (*GLOBAL_STATE->ASIC_functions.receive_result_fn)(GLOBAL_STATE);
|
||||||
int received = SERIAL_rx(buf, 9, 60000);
|
|
||||||
|
|
||||||
if (received < 0) {
|
if(asic_result == NULL){
|
||||||
ESP_LOGI(TAG, "Error in serial RX");
|
|
||||||
continue;
|
|
||||||
} else if(received == 0){
|
|
||||||
// Didn't find a solution, restart and try again
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(received != 9 || buf[0] != 0xAA || buf[1] != 0x55){
|
uint8_t job_id = asic_result->job_id;
|
||||||
ESP_LOGI(TAG, "Serial RX invalid %i", received);
|
|
||||||
ESP_LOG_BUFFER_HEX(TAG, buf, received);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t nonce_found = 0;
|
if (GLOBAL_STATE->valid_jobs[job_id] == 0) {
|
||||||
uint32_t first_nonce = 0;
|
ESP_LOGI(TAG, "Invalid job nonce found, id=%d", job_id);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the nonce difficulty
|
// check the nonce difficulty
|
||||||
double nonce_diff = test_nonce_value(
|
double nonce_diff = test_nonce_value(
|
||||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id],
|
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id],
|
||||||
nonce.nonce,
|
asic_result->nonce,
|
||||||
rx_midstate_index
|
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(
|
SYSTEM_notify_found_nonce(
|
||||||
&GLOBAL_STATE->SYSTEM_MODULE,
|
&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,
|
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(
|
STRATUM_V1_submit_share(
|
||||||
GLOBAL_STATE->sock,
|
GLOBAL_STATE->sock,
|
||||||
user,
|
user,
|
||||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->jobid,
|
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->jobid,
|
||||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->extranonce2,
|
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->extranonce2,
|
||||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->ntime,
|
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job_id]->ntime,
|
||||||
nonce.nonce,
|
asic_result->nonce,
|
||||||
rolled_version ^ GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[rx_job_id]->version
|
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;
|
GlobalState *GLOBAL_STATE = (GlobalState*) pvParameters;
|
||||||
|
|
||||||
|
|
||||||
uint8_t id = 0;
|
|
||||||
|
|
||||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128);
|
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs = malloc(sizeof(bm_job *) * 128);
|
||||||
GLOBAL_STATE->valid_jobs = malloc(sizeof(uint8_t) * 128);
|
GLOBAL_STATE->valid_jobs = malloc(sizeof(uint8_t) * 128);
|
||||||
for (int i = 0; i < 128; i++) {
|
for (int i = 0; i < 128; i++) {
|
||||||
|
|
||||||
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[i] = NULL;
|
GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[i] = NULL;
|
||||||
GLOBAL_STATE->valid_jobs[i] = 0;
|
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);
|
SERIAL_set_baud(baud);
|
||||||
|
|
||||||
SYSTEM_notify_mining_started(&GLOBAL_STATE->SYSTEM_MODULE);
|
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);
|
bm_job * next_bm_job = (bm_job *) queue_dequeue(&GLOBAL_STATE->ASIC_jobs_queue);
|
||||||
|
|
||||||
if(next_bm_job->pool_diff != GLOBAL_STATE->stratum_difficulty){
|
if(next_bm_job->pool_diff != GLOBAL_STATE->stratum_difficulty){
|
||||||
ESP_LOGI(TAG, "New difficulty %ld", next_bm_job->pool_diff);
|
//ESP_LOGI(TAG, "New difficulty %d", next_bm_job->pool_diff);
|
||||||
BM1397_set_job_difficulty_mask(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;
|
GLOBAL_STATE->stratum_difficulty = next_bm_job->pool_diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct job_packet job;
|
(*GLOBAL_STATE->ASIC_functions.send_work_fn)(GLOBAL_STATE, next_bm_job); //send the job to the ASIC
|
||||||
// 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
|
|
||||||
|
|
||||||
//Time to execute the above code is ~0.3ms
|
//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_START_THROTTLE 4900
|
||||||
#define VOLTAGE_MIN_THROTTLE 3500
|
#define VOLTAGE_MIN_THROTTLE 3500
|
||||||
#define VOLTAGE_RANGE (VOLTAGE_START_THROTTLE - VOLTAGE_MIN_THROTTLE)
|
#define VOLTAGE_RANGE (VOLTAGE_START_THROTTLE - VOLTAGE_MIN_THROTTLE)
|
||||||
|
#define ASIC_MODEL CONFIG_ASIC_MODEL
|
||||||
|
|
||||||
static const char * TAG = "power_management";
|
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){
|
// void _power_init(PowerManagementModule * power_management){
|
||||||
// power_management->frequency_multiplier = 1;
|
// power_management->frequency_multiplier = 1;
|
||||||
// power_management->frequency_value = BM1397_FREQUENCY;
|
// power_management->frequency_value = ASIC_FREQUENCY;
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -46,12 +47,14 @@ void POWER_MANAGEMENT_task(void * pvParameters){
|
|||||||
|
|
||||||
int last_frequency_increase = 0;
|
int last_frequency_increase = 0;
|
||||||
while(1){
|
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->voltage = INA260_read_voltage();
|
||||||
power_management->power = INA260_read_power() / 1000;
|
power_management->power = INA260_read_power() / 1000;
|
||||||
power_management->current = INA260_read_current();
|
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
|
// Voltage
|
||||||
// We'll throttle between 4.9v and 3.5v
|
// We'll throttle between 4.9v and 3.5v
|
||||||
@ -79,7 +82,7 @@ void POWER_MANAGEMENT_task(void * pvParameters){
|
|||||||
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){
|
if(target_frequency < 50){
|
||||||
// TODO: Turn the chip off
|
// TODO: Turn the chip off
|
||||||
@ -100,7 +103,7 @@ void POWER_MANAGEMENT_task(void * pvParameters){
|
|||||||
}else{
|
}else{
|
||||||
if(
|
if(
|
||||||
last_frequency_increase > 120 &&
|
last_frequency_increase > 120 &&
|
||||||
power_management->frequency_value != BM1397_FREQUENCY
|
power_management->frequency_value != ASIC_FREQUENCY
|
||||||
){
|
){
|
||||||
float add = (target_frequency + power_management->frequency_value) / 2;
|
float add = (target_frequency + power_management->frequency_value) / 2;
|
||||||
power_management->frequency_value += _fbound(add, 2 , 20);
|
power_management->frequency_value += _fbound(add, 2 , 20);
|
||||||
@ -111,8 +114,7 @@ void POWER_MANAGEMENT_task(void * pvParameters){
|
|||||||
last_frequency_increase++;
|
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);
|
//ESP_LOGI(TAG, "target %f, Freq %f, Volt %f, Power %f", target_frequency, power_management->frequency_value, power_management->voltage, power_management->power);
|
||||||
|
@ -16,6 +16,6 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
|||||||
|
|
||||||
set(IDF_TARGET "esp32s3")
|
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)
|
project(unit_test_stratum)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user