diff --git a/.vscode/settings.json b/.vscode/settings.json index 078d6c503..272d80d7c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,6 +22,6 @@ "cSpell.words": [ "ssid" ], - "idf.port": "/dev/cu.usbmodem1434301", + "idf.port": "/dev/cu.usbmodem1434401", "C_Cpp.intelliSenseEngine": "Tag Parser" } \ No newline at end of file diff --git a/components/bm1397/CMakeLists.txt b/components/bm1397/CMakeLists.txt index 6ff1865f5..b68955cb6 100644 --- a/components/bm1397/CMakeLists.txt +++ b/components/bm1397/CMakeLists.txt @@ -1,5 +1,6 @@ idf_component_register( SRCS + "bm1368.c" "bm1366.c" "bm1397.c" "serial.c" diff --git a/components/bm1397/bm1366.c b/components/bm1397/bm1366.c index daec02128..e56ff075e 100644 --- a/components/bm1397/bm1366.c +++ b/components/bm1397/bm1366.c @@ -105,7 +105,7 @@ 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); + SERIAL_send(buf, total_length, true); free(buf); } @@ -653,7 +653,7 @@ asic_result * BM1366_receive_work(void) return (asic_result *) asic_response_buffer; } -uint16_t reverse_uint16(uint16_t num) +static uint16_t reverse_uint16(uint16_t num) { return (num >> 8) | (num << 8); } diff --git a/components/bm1397/bm1368.c b/components/bm1397/bm1368.c new file mode 100644 index 000000000..4b33b987f --- /dev/null +++ b/components/bm1397/bm1368.c @@ -0,0 +1,698 @@ +#include "bm1368.h" + +#include "crc.h" +#include "global_state.h" +#include "serial.h" +#include "utils.h" + +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include +#include +#include +#include +#include + +#define BM1368_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 = "bm1368Module"; + +static uint8_t asic_response_buffer[CHUNK_SIZE]; +static task_result result; + +/// @brief +/// @param ftdi +/// @param header +/// @param data +/// @param len +static void _send_BM1368(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, true); + + free(buf); +} + +static void _send_chain_inactive(void) +{ + + unsigned char read_address[2] = {0x00, 0x00}; + // send serial data + _send_BM1368((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_BM1368((TYPE_CMD | GROUP_SINGLE | CMD_SETADDRESS), read_address, 2, false); +} + +void BM1368_send_hash_frequency(float target_freq) +{ + // default 200Mhz if it fails + unsigned char freqbuf[9] = {0x00, 0x08, 0x40, 0xA0, 0x02, 0x41}; // freqbuf - pll0_parameter + float newf = 200.0; + + uint8_t fb_divider = 0; + uint8_t post_divider1 = 0, post_divider2 = 0; + uint8_t ref_divider = 0; + float min_difference = 10; + + // refdiver is 2 or 1 + // postdivider 2 is 1 to 7 + // postdivider 1 is 1 to 7 and less than postdivider 2 + // fbdiv is 144 to 235 + for (uint8_t refdiv_loop = 2; refdiv_loop > 0 && fb_divider == 0; refdiv_loop--) { + for (uint8_t postdiv1_loop = 7; postdiv1_loop > 0 && fb_divider == 0; postdiv1_loop--) { + for (uint8_t postdiv2_loop = 1; postdiv2_loop < postdiv1_loop && fb_divider == 0; postdiv2_loop++) { + int temp_fb_divider = round(((float) (postdiv1_loop * postdiv2_loop * target_freq * refdiv_loop) / 25.0)); + + if (temp_fb_divider >= 144 && temp_fb_divider <= 235) { + float temp_freq = 25.0 * (float) temp_fb_divider / (float) (refdiv_loop * postdiv2_loop * postdiv1_loop); + float freq_diff = fabs(target_freq - temp_freq); + + if (freq_diff < min_difference) { + fb_divider = temp_fb_divider; + post_divider1 = postdiv1_loop; + post_divider2 = postdiv2_loop; + ref_divider = refdiv_loop; + min_difference = freq_diff; + break; + } + } + } + } + } + + if (fb_divider == 0) { + puts("Finding dividers failed, using default value (200Mhz)"); + } else { + newf = 25.0 / (float) (ref_divider * fb_divider) / (float) (post_divider1 * post_divider2); + printf("final refdiv: %d, fbdiv: %d, postdiv1: %d, postdiv2: %d, min diff value: %f\n", ref_divider, fb_divider, + post_divider1, post_divider2, min_difference); + + freqbuf[3] = fb_divider; + freqbuf[4] = ref_divider; + freqbuf[5] = (((post_divider1 - 1) & 0xf) << 4) + ((post_divider2 - 1) & 0xf); + + if (fb_divider * 25 / (float) ref_divider >= 2400) { + freqbuf[2] = 0x50; + } + } + + _send_BM1368((TYPE_CMD | GROUP_ALL | CMD_WRITE), freqbuf, 6, true); + + ESP_LOGI(TAG, "Setting Frequency to %.2fMHz (%.2f)", target_freq, newf); +} + +static void do_frequency_ramp_up() +{ + // TODO: figure out how to replicate this ramp up. + // bm1368 doesn't get going until after this sequence + 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); +} + +static void _send_init(uint64_t frequency) +{ + + // //send serial data + // vTaskDelay(SLEEP_TIME / portTICK_PERIOD_MS); + + // unsigned char init[6] = { 0x00, 0xA4, 0x90, 0x00, 0xFF, 0xFF}; + + // _send_BM1368((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_BM1368((TYPE_CMD | GROUP_ALL | CMD_WRITE), init2, 6, true); + + // unsigned char init3[6] = { 0x00, 0x18, 0xFF, 0x0F, 0xC1, 0x00 }; + // _send_BM1368((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_BM1368((TYPE_CMD | GROUP_ALL | CMD_WRITE), init6, 6, true); + + // unsigned char init7[6] = { 0x00, 0x3C, 0x80, 0x00, 0x80, 0x20}; + // _send_BM1368((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); + + do_frequency_ramp_up(); + + BM1368_send_hash_frequency(frequency); + + 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 BM1368 via the RTS line +static void _reset(void) +{ + gpio_set_level(BM1368_RST_PIN, 0); + + // delay for 100ms + vTaskDelay(100 / portTICK_PERIOD_MS); + + // set the gpio pin high + gpio_set_level(BM1368_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_BM1368((TYPE_CMD | GROUP_ALL | CMD_READ), read_address, 2, false); +} + +void BM1368_init(uint64_t frequency) +{ + ESP_LOGI(TAG, "Initializing BM1368"); + + memset(asic_response_buffer, 0, 1024); + + esp_rom_gpio_pad_select_gpio(BM1368_RST_PIN); + gpio_set_direction(BM1368_RST_PIN, GPIO_MODE_OUTPUT); + + // reset the bm1368 + _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 BM1368_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_BM1368((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, false); + return 115749; +} + +int BM1368_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 BM1368_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 - 1) if it is a pow 2 then step down to second largest for more hashrate sampling + difficulty = _largest_power_of_two(difficulty) - 1; + + // 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_BM1368((TYPE_CMD | GROUP_ALL | CMD_WRITE), job_difficulty_mask, 6, false); +} + +static uint8_t id = 0; + +void BM1368_send_work(void * pvParameters, bm_job * next_bm_job) +{ + + GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; + + BM1368_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_BM1368((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), &job, sizeof(BM1368_job), false); +} + +asic_result * BM1368_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; +} + +static uint16_t reverse_uint16(uint16_t num) +{ + return (num >> 8) | (num << 8); +} + +task_result * BM1368_proccess_work(void * pvParameters) +{ + + asic_result * asic_result = BM1368_receive_work(); + + if (asic_result == NULL) { + return NULL; + } + + uint8_t job_id = asic_result->job_id; + uint8_t rx_job_id = ((int8_t)job_id & 0xf8) >> 1; + ESP_LOGI(TAG, "RX Job ID: %02X", rx_job_id); + + GlobalState * GLOBAL_STATE = (GlobalState *) pvParameters; + + //print the size of the active jobs array + ESP_LOGI(TAG, "Active Jobs: %i", sizeof(GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs)); + + if (GLOBAL_STATE->valid_jobs[rx_job_id] == 0) { + if (GLOBAL_STATE->valid_jobs[rx_job_id | 0x80] == 0) { + ESP_LOGE(TAG, "Invalid job nonce found, 0x%02X", rx_job_id); + return NULL; + } else { + rx_job_id |= 0x80; + } + } + + 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/include/bm1368.h b/components/bm1397/include/bm1368.h new file mode 100644 index 000000000..ea06c53d0 --- /dev/null +++ b/components/bm1397/include/bm1368.h @@ -0,0 +1,44 @@ +#ifndef BM1368_H_ +#define BM1368_H_ + +#include "common.h" +#include "driver/gpio.h" +#include "mining.h" + +#define CRC5_MASK 0x1F + +// static const u_int64_t BM1368_FREQUENCY = CONFIG_ASIC_FREQUENCY; +static const u_int64_t BM1368_CORE_COUNT = 672; +// static const u_int64_t BM1368_HASHRATE_S = BM1368_FREQUENCY * BM1368_CORE_COUNT * 1000000; +// 2^32 +// static const u_int64_t NONCE_SPACE = 4294967296; +static const double BM1368_FULLSCAN_MS = 2140; + +typedef struct +{ + float frequency; +} bm1368Module; + +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]; +} BM1368_job; + +void BM1368_init(u_int64_t frequency); + +void BM1368_send_init(void); +void BM1368_send_work(void * GLOBAL_STATE, bm_job * next_bm_job); +void BM1368_set_job_difficulty_mask(int); +int BM1368_set_max_baud(void); +int BM1368_set_default_baud(void); +void BM1368_send_hash_frequency(float frequency); +task_result * BM1368_proccess_work(void * GLOBAL_STATE); + +#endif /* BM1368_H_ */ \ No newline at end of file diff --git a/components/bm1397/serial.c b/components/bm1397/serial.c index dcc1b9a6c..c46b6cbef 100644 --- a/components/bm1397/serial.c +++ b/components/bm1397/serial.c @@ -67,11 +67,11 @@ int SERIAL_send(uint8_t *data, int len, bool debug) int16_t SERIAL_rx(uint8_t *buf, uint16_t size, uint16_t timeout_ms) { int16_t bytes_read = uart_read_bytes(UART_NUM_1, buf, size, timeout_ms / portTICK_PERIOD_MS); - // if (bytes_read > 0) { - // printf("rx: "); - // prettyHex((unsigned char*) buf, bytes_read); - // printf("\n"); - // } + if (bytes_read > 0) { + printf("rx: "); + prettyHex((unsigned char*) buf, bytes_read); + printf("\n"); + } return bytes_read; } diff --git a/main/global_state.h b/main/global_state.h index 51184fb0d..51323a75f 100644 --- a/main/global_state.h +++ b/main/global_state.h @@ -2,6 +2,7 @@ #define GLOBAL_STATE_H_ #include "asic_task.h" +#include "bm1368.h" #include "bm1366.h" #include "bm1397.h" #include "common.h" diff --git a/main/main.c b/main/main.c index a05b909c0..f53c34c43 100644 --- a/main/main.c +++ b/main/main.c @@ -38,6 +38,18 @@ void app_main(void) .send_work_fn = BM1366_send_work}; GLOBAL_STATE.asic_job_frequency_ms = BM1366_FULLSCAN_MS; + GLOBAL_STATE.ASIC_functions = ASIC_functions; + } else if (strcmp(GLOBAL_STATE.asic_model, "BM1368") == 0) { + ESP_LOGI(TAG, "ASIC: BM1368"); + AsicFunctions ASIC_functions = {.init_fn = BM1368_init, + .receive_result_fn = BM1368_proccess_work, + .set_max_baud_fn = BM1368_set_max_baud, + .set_difficulty_mask_fn = BM1368_set_job_difficulty_mask, + .send_work_fn = BM1368_send_work}; + + uint64_t bm1368_hashrate = GLOBAL_STATE.POWER_MANAGEMENT_MODULE.frequency_value * BM1368_CORE_COUNT * 1000000; + GLOBAL_STATE.asic_job_frequency_ms = ((double) NONCE_SPACE / (double) bm1368_hashrate) * 1000; + GLOBAL_STATE.ASIC_functions = ASIC_functions; } else if (strcmp(GLOBAL_STATE.asic_model, "BM1397") == 0) { ESP_LOGI(TAG, "ASIC: BM1397"); diff --git a/main/tasks/power_management_task.c b/main/tasks/power_management_task.c index 4f74873e7..2cb222b2b 100644 --- a/main/tasks/power_management_task.c +++ b/main/tasks/power_management_task.c @@ -141,7 +141,7 @@ void POWER_MANAGEMENT_task(void * pvParameters) last_frequency_increase++; } } - } else if (strcmp(GLOBAL_STATE->asic_model, "BM1366") == 0) { + } else if ((strcmp(GLOBAL_STATE->asic_model, "BM1366") == 0) || (strcmp(GLOBAL_STATE->asic_model, "BM1368") == 0)) { power_management->chip_temp = EMC2101_get_internal_temp() + 5; if (power_management->chip_temp > THROTTLE_TEMP && diff --git a/merge_bin_with_config.sh b/merge_bin_with_config.sh old mode 100644 new mode 100755