diff --git a/components/bm1397/bm1397.c b/components/bm1397/bm1397.c index 3350def5..b178d200 100644 --- a/components/bm1397/bm1397.c +++ b/components/bm1397/bm1397.c @@ -126,8 +126,9 @@ void send_init(void) { unsigned char init4[9] = {0x00, 0x3C, 0x80, 0x00, 0x80, 0x74}; //init4 - init_4_? send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init4, 6, false); - unsigned char set_ticket[9] = {0x00, 0x14, 0x00, 0x00, 0x00, 0xff}; //set_ticket - ticket_mask - send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), set_ticket, 6, false); + // Stratum will set this + // unsigned char ticket_mask[9] = {0x00, 0x14, 0x00, 0x00, 0x00, 0xff}; //set_ticket - ticket_mask + // send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), ticket_mask, 6, false); unsigned char init5[9] = {0x00, 0x68, 0xC0, 0x70, 0x01, 0x11}; //init5 - pll3_parameter send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init5, 6, false); @@ -139,11 +140,66 @@ void send_init(void) { send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init6, 6, false); unsigned char baudrate[9] = {0x00, 0x18, 0x00, 0x00, 0x7A, 0x31}; //baudrate - misc_control + //unsigned char baudrate[9] = {0x00, 0x18, 0x00, 0x00, 0x70, 0x30}; //baudrate - misc_control send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, false); send_hash_frequency(BM1397_FREQUENCY); } +void set_bm1397_max_baud(void){ + unsigned char baudrate[9] = {0x00, 0x18, 0x00, 0x00, 0x70, 0x30}; //baudrate - misc_control + send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, false); +} + +void set_job_difficulty_mask(int difficulty){ + + // Default mask of 256 diff + unsigned char job_difficulty_mask[9] = {0x00, 0x14, 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 = largestPowerOfTwo(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] = reverseBits(value); + } + + send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), job_difficulty_mask, 6, false); +} + +unsigned char reverseBits(unsigned char num) { + unsigned char reversed = 0; + int i; + + for (i = 0; i < 8; i++) { + reversed <<= 1; // Left shift the reversed variable by 1 + reversed |= num & 1; // Use bitwise OR to set the rightmost bit of reversed to the current bit of num + num >>= 1; // Right shift num by 1 to get the next bit + } + + return reversed; +} + +int largestPowerOfTwo(int num) { + int power = 0; + + while (num > 1) { + num = num >> 1; + power++; + } + + return 1 << power; +} + + void send_work(struct job_packet *job) { send_BM1397((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t*)job, sizeof(struct job_packet), false); } diff --git a/components/bm1397/include/bm1397.h b/components/bm1397/include/bm1397.h index 95b1a89d..bb61933b 100644 --- a/components/bm1397/include/bm1397.h +++ b/components/bm1397/include/bm1397.h @@ -66,6 +66,9 @@ void send_init(void); void send_work(struct job_packet *job); void reset_BM1397(void); void init_BM1397(void); - +void set_job_difficulty_mask(int); +unsigned char reverseBits(unsigned char num); +int largestPowerOfTwo(int num); +void set_bm1397_max_baud(void); #endif /* BM1397_H_ */ \ No newline at end of file diff --git a/components/bm1397/include/serial.h b/components/bm1397/include/serial.h index 18e9c6f8..0a04c5a0 100644 --- a/components/bm1397/include/serial.h +++ b/components/bm1397/include/serial.h @@ -9,5 +9,6 @@ void init_serial(void); void debug_serial_rx(void); int16_t serial_rx(uint8_t *, uint16_t, uint16_t); void clear_serial_buffer(void); +void set_max_baud(void); #endif /* SERIAL_H_ */ \ No newline at end of file diff --git a/components/bm1397/serial.c b/components/bm1397/serial.c index 25a52c67..21752a2c 100644 --- a/components/bm1397/serial.c +++ b/components/bm1397/serial.c @@ -40,6 +40,13 @@ void init_serial(void) { uart_driver_install(UART_NUM_1, BUF_SIZE * 2, 0, 0, NULL, 0); } +void set_max_baud(void){ + ESP_LOGI("SERIAL", "SETTING CHIP MAX BAUD"); + set_bm1397_max_baud(); + ESP_LOGI("SERIAL", "SETTING UART MAX BAUD"); + uart_set_baudrate(UART_NUM_1, 3125000); +} + int send_serial(uint8_t *data, int len, bool debug) { if (debug) { printf("->"); diff --git a/components/stratum/include/mining.h b/components/stratum/include/mining.h index 97909e40..46d3061c 100644 --- a/components/stratum/include/mining.h +++ b/components/stratum/include/mining.h @@ -2,6 +2,8 @@ #define MINING_H #include "stratum_api.h" +#include + typedef struct { uint32_t version; @@ -13,6 +15,8 @@ typedef struct { uint8_t midstate[32]; uint32_t pool_diff; + // is the pool diff a power of 2? + bool pool_diff_pow2; char * jobid; char * extranonce2; } bm_job; diff --git a/main/miner.c b/main/miner.c index 1de910a6..f76225cd 100755 --- a/main/miner.c +++ b/main/miner.c @@ -61,6 +61,8 @@ static void ASIC_task(void * pvParameters) init_BM1397(); + ESP_LOGI(TAG, "Job wait time:%f", BM1397_FULLSCAN_MS); + //reset the bm1397 reset_BM1397(); @@ -86,6 +88,9 @@ static void ASIC_task(void * pvParameters) } uint32_t prev_nonce = 0; + + + set_max_baud(); while (1) { bm_job * next_bm_job = (bm_job *) queue_dequeue(&ASIC_jobs_queue); struct job_packet job; @@ -112,7 +117,7 @@ static void ASIC_task(void * pvParameters) send_work(&job); //send the job to the ASIC //wait for a response - int received = serial_rx(buf, 9, BM1397_FULLSCAN_MS); //TODO: this timeout should be 2^32/hashrate + int received = serial_rx(buf, 9, BM1397_FULLSCAN_MS); if (received < 0) { ESP_LOGI(TAG, "Error in serial RX"); @@ -153,6 +158,15 @@ static void ASIC_task(void * pvParameters) prev_nonce = nonce.nonce; } + // If the pool diff is a power of 2, the ASIC won't return nonces lower than the diff + // hence we can skip all the checking + if(active_jobs[nonce.job_id]->pool_diff_pow2){ + submit_share(sock, STRATUM_USER, active_jobs[nonce.job_id]->jobid, active_jobs[nonce.job_id]->ntime, + active_jobs[nonce.job_id]->extranonce2, nonce.nonce); + notify_system_submitted_share(); + continue; + } + // check the nonce difficulty double nonce_diff = test_nonce_value(active_jobs[nonce.job_id], nonce.nonce); @@ -163,6 +177,7 @@ static void ASIC_task(void * pvParameters) //print_hex((uint8_t *)&job, sizeof(struct job_packet), sizeof(struct job_packet), "job: "); submit_share(sock, STRATUM_USER, active_jobs[nonce.job_id]->jobid, active_jobs[nonce.job_id]->ntime, active_jobs[nonce.job_id]->extranonce2, nonce.nonce); + notify_system_submitted_share(); } } } @@ -191,6 +206,7 @@ static void create_jobs_task(void * pvParameters) bm_job next_job = construct_bm_job(¶ms, merkle_root); next_job.pool_diff = stratum_difficulty; //each job is tied to the _current_ difficulty + next_job.pool_diff_pow2 = (stratum_difficulty != 0 && (stratum_difficulty & (stratum_difficulty - 1)) == 0); //ESP_LOGI(TAG, "bm_job: "); // print_hex((uint8_t *) &next_job.target, 4, 4, "nbits: "); @@ -314,6 +330,8 @@ static void stratum_task(void * pvParameters) } else if (method == MINING_SET_DIFFICULTY) { stratum_difficulty = parse_mining_set_difficulty_message(line); ESP_LOGI(TAG, "Set stratum difficulty: %d", stratum_difficulty); + set_job_difficulty_mask(stratum_difficulty); + } else if (method == MINING_SET_VERSION_MASK) { version_mask = parse_mining_set_version_mask_message(line); ESP_LOGI(TAG, "Set version mask: %08x", version_mask); @@ -339,7 +357,7 @@ void app_main(void) ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); - xTaskCreate(SysTask, "System_Task", 4096, NULL, 10, &sysTaskHandle); + xTaskCreate(system_task, "System_Task", 4096, NULL, 10, &sysTaskHandle); /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. * Read "Establishing Wi-Fi or Ethernet Connection" section in diff --git a/main/system.c b/main/system.c index 871c3313..43fd41e7 100644 --- a/main/system.c +++ b/main/system.c @@ -11,13 +11,24 @@ #include "INA260.h" #include "adc.h" #include "oled.h" +#include + static const char *TAG = "system"; #define BM1397_VOLTAGE CONFIG_BM1397_VOLTAGE +static int shares_submitted = 0; +static time_t start_time, current_time; + +void notify_system_submitted_share(void){ + shares_submitted++; +} + void init_system(void) { + start_time = time(NULL); + //test the LEDs // ESP_LOGI(TAG, "Init LEDs!"); // ledc_init(); @@ -51,7 +62,7 @@ void init_system(void) { } } -void get_stats(void) { +void update_system_info(void) { char oled_buf[20]; uint16_t fan_speed = EMC2101_get_fan_speed(); @@ -61,42 +72,63 @@ void get_stats(void) { float power = INA260_read_power() / 1000; //uint16_t vcore = ADC_get_vcore(); - // ESP_LOGI(TAG, "Fan Speed: %d RPM", fan_speed); - // ESP_LOGI(TAG, "Chip Temp: %.2f C", chip_temp); - - // //Current Sensor tests - // ESP_LOGI(TAG, "Current: %.2f mA", current); - // ESP_LOGI(TAG, "Voltage: %.2f mV", voltage); - // ESP_LOGI(TAG, "Power: %.2f mW", power); - - // //ESP32 ADC tests - // ESP_LOGI(TAG, "Vcore: %d mV\n", vcore); - if (OLED_status()) { + OLED_clearLine(1); + OLED_clearLine(2); + OLED_clearLine(3); + memset(oled_buf, 0, 20); snprintf(oled_buf, 20, "Fan: %d RPM", fan_speed); - OLED_clearLine(1); OLED_writeString(0, 1, oled_buf); memset(oled_buf, 0, 20); snprintf(oled_buf, 20, "Temp: %.2f C", chip_temp); - OLED_clearLine(2); OLED_writeString(0, 2, oled_buf); memset(oled_buf, 0, 20); snprintf(oled_buf, 20, "Pwr: %.2f W", power); - OLED_clearLine(3); OLED_writeString(0, 3, oled_buf); } } -void SysTask(void *arg) { +void update_system_performance(){ + char oled_buf[20]; + + // Get the current system time as the current time + current_time = time(NULL); + + // Calculate the uptime in seconds + double uptime_in_seconds = difftime(current_time, start_time); + + // Calculate the uptime in days and hours + int uptime_in_days = uptime_in_seconds / (3600 * 24); + int remaining_seconds = (int)uptime_in_seconds % (3600 * 24); + double uptime_in_hours = (double)remaining_seconds / 3600; + + if (OLED_status()) { + OLED_clearLine(1); + OLED_clearLine(2); + OLED_clearLine(3); + + memset(oled_buf, 0, 20); + snprintf(oled_buf, 20, "Shares: %i", shares_submitted); + OLED_writeString(0, 1, oled_buf); + + memset(oled_buf, 0, 20); + snprintf(oled_buf, 20, "Uptime: %dd %.2fh", uptime_in_days, uptime_in_hours); + OLED_writeString(0, 2, oled_buf); + } +} + +void system_task(void *arg) { init_system(); while(1){ - get_stats(); + update_system_info(); + vTaskDelay(5000 / portTICK_RATE_MS); + update_system_performance(); vTaskDelay(5000 / portTICK_RATE_MS); } } \ No newline at end of file diff --git a/main/system.h b/main/system.h index d8eef90e..eba76c8b 100644 --- a/main/system.h +++ b/main/system.h @@ -1,8 +1,9 @@ #ifndef SYSTEM_H_ #define SYSTEM_H_ -void SysTask(void *arg); +void system_task(void *arg); void init_system(void); void get_stats(void); +void notify_system_submitted_share(void); #endif /* SYSTEM_H_ */ \ No newline at end of file