diff --git a/components/bm1397/CMakeLists.txt b/components/bm1397/CMakeLists.txt index f613350..6ff1865 100644 --- a/components/bm1397/CMakeLists.txt +++ b/components/bm1397/CMakeLists.txt @@ -1,5 +1,6 @@ idf_component_register( SRCS + "bm1366.c" "bm1397.c" "serial.c" "crc.c" @@ -9,4 +10,11 @@ REQUIRES freertos driver stratum -) \ No newline at end of file +) + + +# 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") \ No newline at end of file diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c new file mode 100644 index 0000000..63e1441 --- /dev/null +++ b/components/bm1397/bm1366.c @@ -0,0 +1,712 @@ +#include +#include +#include +#include +#include + +#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; +} + + diff --git a/components/bm1397/bm1397.c b/components/bm1397/bm1397.c index a4249cc..684fff2 100644 --- a/components/bm1397/bm1397.c +++ b/components/bm1397/bm1397.c @@ -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; +} + diff --git a/components/bm1397/include/bm1366.h b/components/bm1397/include/bm1366.h new file mode 100644 index 0000000..827da52 --- /dev/null +++ b/components/bm1397/include/bm1366.h @@ -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_ */ \ No newline at end of file diff --git a/components/bm1397/include/bm1397.h b/components/bm1397/include/bm1397.h index bfe30a9..eb3614e 100644 --- a/components/bm1397/include/bm1397.h +++ b/components/bm1397/include/bm1397.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_ */ \ No newline at end of file diff --git a/components/bm1397/include/common.h b/components/bm1397/include/common.h new file mode 100644 index 0000000..f9e686e --- /dev/null +++ b/components/bm1397/include/common.h @@ -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 \ No newline at end of file diff --git a/components/bm1397/test/test_job_command.c b/components/bm1397/test/test_job_command.c index 4bbf348..ab5e5c4 100644 --- a/components/bm1397/test/test_job_command.c +++ b/components/bm1397/test/test_job_command.c @@ -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); diff --git a/components/stratum/include/mining.h b/components/stratum/include/mining.h index 787afb7..4215b01 100644 --- a/components/stratum/include/mining.h +++ b/components/stratum/include/mining.h @@ -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); diff --git a/components/stratum/mining.c b/components/stratum/mining.c index 92e9fb8..0397cb2 100644 --- a/components/stratum/mining.c +++ b/components/stratum/mining.c @@ -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); diff --git a/components/stratum/stratum_api.c b/components/stratum/stratum_api.c index 1bcc583..dc7e755 100644 --- a/components/stratum/stratum_api.c +++ b/components/stratum/stratum_api.c @@ -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; diff --git a/config.cvs.example b/config.cvs.example index 0c61b77..d2c849f 100644 --- a/config.cvs.example +++ b/config.cvs.example @@ -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 \ No newline at end of file diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index eafc703..2b059b4 100755 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -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 diff --git a/main/global_state.h b/main/global_state.h index c15be9c..cd15bc0 100644 --- a/main/global_state.h +++ b/main/global_state.h @@ -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_ */ \ No newline at end of file diff --git a/main/miner.c b/main/miner.c index bf16e4b..337a8b0 100755 --- a/main/miner.c +++ b/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; diff --git a/main/nvs_config.h b/main/nvs_config.h index c71fb9b..3a1d99b 100644 --- a/main/nvs_config.h +++ b/main/nvs_config.h @@ -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); diff --git a/main/system.c b/main/system.c index 4c19d12..4ba49de 100644 --- a/main/system.c +++ b/main/system.c @@ -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(); diff --git a/main/tasks/asic_result_task.c b/main/tasks/asic_result_task.c index 19c9e86..3434114 100644 --- a/main/tasks/asic_result_task.c +++ b/main/tasks/asic_result_task.c @@ -5,102 +5,58 @@ #include #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 ); } diff --git a/main/tasks/asic_task.c b/main/tasks/asic_task.c index a1bb794..df46ed6 100644 --- a/main/tasks/asic_task.c +++ b/main/tasks/asic_task.c @@ -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); } } diff --git a/main/tasks/power_management_task.c b/main/tasks/power_management_task.c index 354836c..0011a2c 100644 --- a/main/tasks/power_management_task.c +++ b/main/tasks/power_management_task.c @@ -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); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9d5538e..1989724 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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)