seems to be working
This commit is contained in:
parent
0931960ac1
commit
4b7a6d8146
@ -17,6 +17,9 @@
|
||||
#include "drivers/nerd-nos/bm1397.h"
|
||||
#include "drivers/nerd-nos/serial.h"
|
||||
|
||||
#ifdef NERD_NOS
|
||||
#include "mining_nerdnos.h"
|
||||
#endif
|
||||
|
||||
#ifdef TOUCH_ENABLE
|
||||
#include "TouchHandler.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "freertos/task.h"
|
||||
#include "../devices/device.h"
|
||||
#include "crc.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define TYPE_JOB 0x20
|
||||
#define TYPE_CMD 0x40
|
||||
@ -48,7 +49,6 @@ typedef struct __attribute__((__packed__))
|
||||
static const char *TAG = "bm1397Module";
|
||||
|
||||
static uint8_t asic_response_buffer[CHUNK_SIZE];
|
||||
static uint32_t prev_nonce = 0;
|
||||
static task_result result;
|
||||
|
||||
uint32_t increment_bitmask(const uint32_t value, const uint32_t mask);
|
||||
@ -101,7 +101,7 @@ static void _send_read_address(void)
|
||||
{
|
||||
unsigned char read_address[2] = {0x00, 0x00};
|
||||
// send serial data
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_READ), read_address, 2, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_READ), read_address, 2, BM1397_SERIALTX_DEBUG);
|
||||
}
|
||||
|
||||
static void _send_chain_inactive(void)
|
||||
@ -109,7 +109,7 @@ static void _send_chain_inactive(void)
|
||||
|
||||
unsigned char read_address[2] = {0x00, 0x00};
|
||||
// send serial data
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_INACTIVE), read_address, 2, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_INACTIVE), read_address, 2, BM1397_SERIALTX_DEBUG);
|
||||
}
|
||||
|
||||
static void _set_chip_address(uint8_t chipAddr)
|
||||
@ -117,7 +117,7 @@ static void _set_chip_address(uint8_t chipAddr)
|
||||
|
||||
unsigned char read_address[2] = {chipAddr, 0x00};
|
||||
// send serial data
|
||||
_send_BM1397((TYPE_CMD | GROUP_SINGLE | CMD_SETADDRESS), read_address, 2, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_SINGLE | CMD_SETADDRESS), read_address, 2, BM1397_SERIALTX_DEBUG);
|
||||
}
|
||||
|
||||
void BM1397_send_hash_frequency(float frequency)
|
||||
@ -187,12 +187,12 @@ void BM1397_send_hash_frequency(float frequency)
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), prefreqall, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), prefreqall, 6, BM1397_SERIALTX_DEBUG);
|
||||
}
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), freqbufall, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), freqbufall, 6, BM1397_SERIALTX_DEBUG);
|
||||
}
|
||||
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
@ -228,24 +228,24 @@ static uint8_t _send_init(uint64_t frequency, uint16_t asic_count)
|
||||
}
|
||||
|
||||
unsigned char init[6] = {0x00, CLOCK_ORDER_CONTROL_0, 0x00, 0x00, 0x00, 0x00}; // init1 - clock_order_control0
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init, 6, BM1397_SERIALTX_DEBUG);
|
||||
|
||||
unsigned char init2[6] = {0x00, CLOCK_ORDER_CONTROL_1, 0x00, 0x00, 0x00, 0x00}; // init2 - clock_order_control1
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init2, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init2, 6, BM1397_SERIALTX_DEBUG);
|
||||
|
||||
unsigned char init3[9] = {0x00, ORDERED_CLOCK_ENABLE, 0x00, 0x00, 0x00, 0x01}; // init3 - ordered_clock_enable
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init3, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init3, 6, BM1397_SERIALTX_DEBUG);
|
||||
|
||||
unsigned char init4[9] = {0x00, CORE_REGISTER_CONTROL, 0x80, 0x00, 0x80, 0x74}; // init4 - init_4_?
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init4, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init4, 6, BM1397_SERIALTX_DEBUG);
|
||||
|
||||
BM1397_set_job_difficulty_mask(BM1397_INITIAL_DIFFICULTY);
|
||||
|
||||
unsigned char init5[9] = {0x00, PLL3_PARAMETER, 0xC0, 0x70, 0x01, 0x11}; // init5 - pll3_parameter
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init5, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init5, 6, BM1397_SERIALTX_DEBUG);
|
||||
|
||||
unsigned char init6[9] = {0x00, FAST_UART_CONFIGURATION, 0x06, 0x00, 0x00, 0x0F}; // init6 - fast_uart_configuration
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init6, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), init6, 6, BM1397_SERIALTX_DEBUG);
|
||||
|
||||
BM1397_set_default_baud();
|
||||
|
||||
@ -294,7 +294,7 @@ int BM1397_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_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, BM1397_SERIALTX_DEBUG);
|
||||
return 115749;
|
||||
}
|
||||
|
||||
@ -304,7 +304,7 @@ int BM1397_set_max_baud(void)
|
||||
ESP_LOGI(TAG, "Setting max baud of 3125000");
|
||||
unsigned char baudrate[9] = {0x00, MISC_CONTROL, 0x00, 0x00, 0b01100000, 0b00110001};
|
||||
; // baudrate - misc_control
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), baudrate, 6, BM1397_SERIALTX_DEBUG);
|
||||
return 3125000;
|
||||
}
|
||||
|
||||
@ -317,7 +317,7 @@ void BM1397_set_job_difficulty_mask(int difficulty)
|
||||
// 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
|
||||
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}
|
||||
@ -329,18 +329,18 @@ void BM1397_set_job_difficulty_mask(int difficulty)
|
||||
// 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);
|
||||
job_difficulty_mask[5 - i] = reverse_bits(value);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Setting job ASIC mask to %d", difficulty);
|
||||
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), job_difficulty_mask, 6, BM1937_SERIALTX_DEBUG);
|
||||
_send_BM1397((TYPE_CMD | GROUP_ALL | CMD_WRITE), job_difficulty_mask, 6, BM1397_SERIALTX_DEBUG);
|
||||
}
|
||||
|
||||
|
||||
void BM1397_send_work(bm_job_t *next_bm_job, uint8_t job_id)
|
||||
{
|
||||
job_packet job;
|
||||
job_packet_t 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
|
||||
@ -360,7 +360,7 @@ void BM1397_send_work(bm_job_t *next_bm_job, uint8_t job_id)
|
||||
memcpy(job.midstate3, next_bm_job->midstate3, 32);
|
||||
}
|
||||
|
||||
_send_BM1397((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t*) &job, sizeof(job_packet), BM1397_DEBUG_WORK);
|
||||
_send_BM1397((TYPE_JOB | GROUP_SINGLE | CMD_WRITE), (uint8_t*) &job, sizeof(job_packet_t), BM1397_DEBUG_WORK);
|
||||
}
|
||||
|
||||
asic_result *BM1397_receive_work(uint16_t timeout)
|
||||
@ -392,7 +392,6 @@ asic_result *BM1397_receive_work(uint16_t timeout)
|
||||
|
||||
task_result *BM1397_proccess_work(uint32_t version, uint16_t timeout)
|
||||
{
|
||||
|
||||
asic_result *asic_result = BM1397_receive_work(timeout);
|
||||
|
||||
if (asic_result == NULL)
|
||||
@ -401,9 +400,6 @@ task_result *BM1397_proccess_work(uint32_t version, uint16_t timeout)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t nonce_found = 0;
|
||||
uint32_t first_nonce = 0;
|
||||
|
||||
uint8_t rx_job_id = (asic_result->job_id & 0xfc) >> 2;
|
||||
uint8_t rx_midstate_index = asic_result->job_id & 0x03;
|
||||
|
||||
@ -413,29 +409,6 @@ task_result *BM1397_proccess_work(uint32_t version, uint16_t timeout)
|
||||
rolled_version = increment_bitmask(rolled_version, 0x1fffe000);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
@ -1,49 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include "common.h"
|
||||
#include "mining.h"
|
||||
#include "nerdnos.h"
|
||||
#include "crc.h"
|
||||
|
||||
#define CRC5_MASK 0x1F
|
||||
#define BM1397_INITIAL_DIFFICULTY 64
|
||||
|
||||
#define BM1937_SERIALTX_DEBUG false
|
||||
#define BM1937_SERIALRX_DEBUG true //false
|
||||
#define BM1397_SERIALTX_DEBUG false
|
||||
#define BM1397_SERIALRX_DEBUG true //false
|
||||
#define BM1397_DEBUG_WORK false //causes insane amount of debug output
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float frequency;
|
||||
} bm1397Module;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
JOB_PACKET = 0,
|
||||
CMD_PACKET = 1,
|
||||
} packet_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
JOB_RESP = 0,
|
||||
CMD_RESP = 1,
|
||||
} response_type_t;
|
||||
|
||||
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 merkle4[4];
|
||||
uint8_t midstate[32];
|
||||
uint8_t midstate1[32];
|
||||
uint8_t midstate2[32];
|
||||
uint8_t midstate3[32];
|
||||
} job_packet;
|
||||
|
||||
uint8_t BM1397_init(uint64_t frequency, uint16_t asic_count);
|
||||
|
||||
void BM1397_send_work(bm_job_t * next_bm_job, uint8_t job_id);
|
||||
|
@ -1,41 +1,6 @@
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
#pragma once
|
||||
|
||||
#include <stdint.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;
|
||||
}
|
||||
#include <stddef.h>
|
||||
|
||||
void printBufferHex(const char *prefix, const uint8_t* buf, size_t len);
|
||||
|
||||
#endif
|
@ -1,18 +1,8 @@
|
||||
#ifndef CRC_H_
|
||||
#define CRC_H_
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint8_t crc5(uint8_t *buffer, uint16_t len);
|
||||
uint16_t crc16(uint8_t *buffer, uint16_t len);
|
||||
uint16_t crc16_false(uint8_t *buffer, uint16_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CRC_H_
|
@ -11,6 +11,7 @@
|
||||
#include "utils.h"
|
||||
#include "stratum.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "../../mining.h"
|
||||
|
||||
///////cgminer nonce testing
|
||||
/* truediffone == 0x00000000FFFF0000000000000000000000000000000000000000000000000000
|
||||
@ -18,7 +19,7 @@
|
||||
static const double truediffone = 26959535291011309493156476344723991336010898738574164086137773096960.0;
|
||||
|
||||
/* testing a nonce and return the diff - 0 means invalid */
|
||||
double asic_test_nonce_value(const bm_job_t *job, const uint32_t nonce, const uint32_t rolled_version)
|
||||
double nerdnos_test_nonce_value(const bm_job_t *job, const uint32_t nonce, const uint32_t rolled_version, uint8_t hash_result[32])
|
||||
{
|
||||
double d64, s64, ds;
|
||||
unsigned char header[80];
|
||||
@ -38,7 +39,6 @@ double asic_test_nonce_value(const bm_job_t *job, const uint32_t nonce, const ui
|
||||
memcpy(header + 76, &nonce, 4);
|
||||
|
||||
unsigned char hash_buffer[32];
|
||||
unsigned char hash_result[32];
|
||||
|
||||
// double hash the header
|
||||
mbedtls_sha256(header, 80, hash_buffer, 0);
|
||||
@ -51,29 +51,7 @@ double asic_test_nonce_value(const bm_job_t *job, const uint32_t nonce, const ui
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
||||
uint32_t increment_bitmask(const uint32_t value, const uint32_t mask)
|
||||
{
|
||||
// if mask is zero, just return the original value
|
||||
if (mask == 0)
|
||||
return value;
|
||||
|
||||
uint32_t carry = (value & mask) + (mask & -mask); // increment the least significant bit of the mask
|
||||
uint32_t overflow = carry & ~mask; // find overflowed bits that are not in the mask
|
||||
uint32_t new_value = (value & ~mask) | (carry & mask); // set bits according to the mask
|
||||
|
||||
// Handle carry propagation
|
||||
if (overflow > 0)
|
||||
{
|
||||
uint32_t carry_mask = (overflow << 1); // shift left to get the mask where carry should be propagated
|
||||
new_value = increment_bitmask(new_value, carry_mask); // recursively handle carry propagation
|
||||
}
|
||||
|
||||
return new_value;
|
||||
}
|
||||
|
||||
|
||||
void calculate_merkle_root_hash(const char *coinbase_tx, mining_job* job, char merkle_root_hash[65])
|
||||
static void calculate_merkle_root_hash(const char *coinbase_tx, mining_job* job, char merkle_root_hash[65])
|
||||
{
|
||||
size_t coinbase_tx_bin_len = strlen(coinbase_tx) / 2;
|
||||
uint8_t coinbase_tx_bin[coinbase_tx_bin_len];
|
||||
@ -93,7 +71,7 @@ void calculate_merkle_root_hash(const char *coinbase_tx, mining_job* job, char m
|
||||
}
|
||||
|
||||
// take a mining_notify struct with ascii hex strings and convert it to a bm_job struct
|
||||
void construct_bm_job(mining_job *job, const char *merkle_root, uint32_t version_mask, bm_job_t *new_job)
|
||||
static void construct_bm_job(mining_job *job, const char *merkle_root, uint32_t version_mask, bm_job_t *new_job)
|
||||
{
|
||||
new_job->version = strtoul(job->version.c_str(), NULL, 16);
|
||||
new_job->target = strtoul(job->nbits.c_str(), NULL, 16);
|
||||
@ -139,7 +117,7 @@ void construct_bm_job(mining_job *job, const char *merkle_root, uint32_t version
|
||||
new_job->num_midstates = 4;
|
||||
}
|
||||
|
||||
void asic_create_job(mining_subscribe *mWorker, mining_job *job, bm_job_t *next_job, uint32_t extranonce_2) {
|
||||
void nerdnos_create_job(mining_subscribe *mWorker, mining_job *job, bm_job_t *next_job, uint32_t extranonce_2, uint32_t stratum_difficulty) {
|
||||
char extranonce_2_str[mWorker->extranonce2_size * 2 + 1]; // +1 zero termination
|
||||
snprintf(extranonce_2_str, sizeof(extranonce_2_str), "%0*lx", (int) mWorker->extranonce2_size * 2, extranonce_2);
|
||||
|
||||
@ -156,20 +134,24 @@ void asic_create_job(mining_subscribe *mWorker, mining_job *job, bm_job_t *next_
|
||||
|
||||
next_job->jobid = strdup(job->job_id.c_str());
|
||||
next_job->extranonce2 = strdup(extranonce_2_str);
|
||||
//next_job->pool_diff = stratum_difficulty;
|
||||
next_job->pool_diff = stratum_difficulty;
|
||||
}
|
||||
|
||||
void asic_send_work(bm_job_t *next_bm_job, uint8_t job_id) {
|
||||
void nerdnos_send_work(bm_job_t *next_bm_job, uint8_t job_id) {
|
||||
BM1397_send_work(next_bm_job, job_id);
|
||||
}
|
||||
|
||||
task_result *asic_proccess_work(uint32_t version, uint16_t timeout) {
|
||||
task_result *nerdnos_proccess_work(uint32_t version, uint16_t timeout) {
|
||||
return BM1397_proccess_work(version, timeout);
|
||||
}
|
||||
|
||||
void asic_free_bm_job(bm_job_t *job) {
|
||||
void nerdnos_free_bm_job(bm_job_t *job) {
|
||||
free(job->jobid);
|
||||
free(job->extranonce2);
|
||||
// mark as free
|
||||
job->ntime = 0;
|
||||
}
|
||||
|
||||
void nerdnos_set_asic_difficulty(uint32_t difficulty) {
|
||||
BM1397_set_job_difficulty_mask(difficulty);
|
||||
}
|
@ -1,33 +1,25 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "common.h"
|
||||
//#include "stratum.h"
|
||||
#include "nerdnos.h"
|
||||
|
||||
// forward declaration to resolve circular inclusions
|
||||
typedef struct mining_subscribe mining_subscribe;
|
||||
typedef struct mining_job mining_job;
|
||||
|
||||
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;
|
||||
// set the asic hardware difficulty
|
||||
void nerdnos_set_asic_difficulty(uint32_t current_difficulty);
|
||||
|
||||
uint8_t num_midstates;
|
||||
uint8_t midstate[32];
|
||||
uint8_t midstate1[32];
|
||||
uint8_t midstate2[32];
|
||||
uint8_t midstate3[32];
|
||||
char *jobid;
|
||||
char *extranonce2;
|
||||
} bm_job_t;
|
||||
// create asic job
|
||||
void nerdnos_create_job(mining_subscribe *mWorker, mining_job *job, bm_job_t *next_job, uint32_t extranonce_2, uint32_t stratum_difficulty);
|
||||
|
||||
// send new work to the asic
|
||||
void nerdnos_send_work(bm_job_t *next_bm_job, uint8_t job_id);
|
||||
|
||||
void asic_send_work(bm_job_t *next_bm_job, uint8_t job_id);
|
||||
task_result *asic_proccess_work(uint32_t version, uint16_t timeout);
|
||||
// receive and process responses
|
||||
task_result *nerdnos_proccess_work(uint32_t version, uint16_t timeout);
|
||||
|
||||
double asic_test_nonce_value(const bm_job_t *job, const uint32_t nonce, const uint32_t rolled_version);
|
||||
void asic_free_bm_job(bm_job_t *job);
|
||||
// test difficulty
|
||||
double nerdnos_test_nonce_value(const bm_job_t *job, const uint32_t nonce, const uint32_t rolled_version, uint8_t hash_result[32]);
|
||||
|
||||
// free allocated RAM for strings on bm_job_t
|
||||
void nerdnos_free_bm_job(bm_job_t *job);
|
||||
|
66
src/drivers/nerd-nos/nerdnos.h
Normal file
66
src/drivers/nerd-nos/nerdnos.h
Normal file
@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define BM1397_INITIAL_DIFFICULTY 128
|
||||
|
||||
typedef struct __attribute__((__packed__))
|
||||
{
|
||||
uint8_t job_id;
|
||||
uint32_t nonce;
|
||||
uint32_t rolled_version;
|
||||
} task_result;
|
||||
|
||||
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;
|
||||
|
||||
uint8_t num_midstates;
|
||||
uint8_t midstate[32];
|
||||
uint8_t midstate1[32];
|
||||
uint8_t midstate2[32];
|
||||
uint8_t midstate3[32];
|
||||
char *jobid;
|
||||
char *extranonce2;
|
||||
uint32_t pool_diff;
|
||||
} bm_job_t;
|
||||
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
float frequency;
|
||||
} bm1397Module;
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JOB_PACKET = 0,
|
||||
CMD_PACKET = 1,
|
||||
} packet_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
JOB_RESP = 0,
|
||||
CMD_RESP = 1,
|
||||
} response_type_t;
|
||||
|
||||
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 merkle4[4];
|
||||
uint8_t midstate[32];
|
||||
uint8_t midstate1[32];
|
||||
uint8_t midstate2[32];
|
||||
uint8_t midstate3[32];
|
||||
} job_packet_t;
|
@ -51,12 +51,24 @@ int SERIAL_send(uint8_t *data, int len, bool debug)
|
||||
return uart_write_bytes(UART_NUM_1, (const char *)data, len);
|
||||
}
|
||||
|
||||
int SERIAL_check_for_data() {
|
||||
int length;
|
||||
uart_get_buffered_data_len(UART_NUM_1, (size_t*)&length);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/// @brief waits for a serial response from the device
|
||||
/// @param buf buffer to read data into
|
||||
/// @param buf number of ms to wait before timing out
|
||||
/// @return number of bytes read, or -1 on error
|
||||
int16_t SERIAL_rx(uint8_t *buf, uint16_t size, uint16_t timeout_ms)
|
||||
{
|
||||
// don't return incomplete data
|
||||
if (SERIAL_check_for_data() < size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t bytes_read = uart_read_bytes(UART_NUM_1, buf, size, timeout_ms / portTICK_PERIOD_MS);
|
||||
// if (bytes_read > 0) {
|
||||
// printf("rx: ");
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef SERIAL_H_
|
||||
#define SERIAL_H_
|
||||
#pragma once
|
||||
|
||||
#define CHUNK_SIZE 1024
|
||||
|
||||
@ -10,4 +9,3 @@ int16_t SERIAL_rx(uint8_t *, uint16_t, uint16_t);
|
||||
void SERIAL_clear_buffer(void);
|
||||
void SERIAL_set_baud(int baud);
|
||||
|
||||
#endif /* SERIAL_H_ */
|
@ -307,3 +307,51 @@ uint32_t flip32(uint32_t val)
|
||||
ret |= (val & 0xFF000000) >> 24;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int largest_power_of_two(int num)
|
||||
{
|
||||
int power = 0;
|
||||
|
||||
while (num > 1) {
|
||||
num = num >> 1;
|
||||
power++;
|
||||
}
|
||||
|
||||
return 1 << power;
|
||||
}
|
||||
|
||||
|
||||
uint32_t increment_bitmask(const uint32_t value, const uint32_t mask)
|
||||
{
|
||||
// if mask is zero, just return the original value
|
||||
if (mask == 0)
|
||||
return value;
|
||||
|
||||
uint32_t carry = (value & mask) + (mask & -mask); // increment the least significant bit of the mask
|
||||
uint32_t overflow = carry & ~mask; // find overflowed bits that are not in the mask
|
||||
uint32_t new_value = (value & ~mask) | (carry & mask); // set bits according to the mask
|
||||
|
||||
// Handle carry propagation
|
||||
if (overflow > 0)
|
||||
{
|
||||
uint32_t carry_mask = (overflow << 1); // shift left to get the mask where carry should be propagated
|
||||
new_value = increment_bitmask(new_value, carry_mask); // recursively handle carry propagation
|
||||
}
|
||||
|
||||
return new_value;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#pragma one
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@ -33,3 +33,8 @@ void prettyHex(unsigned char *buf, int len);
|
||||
|
||||
uint32_t flip32(uint32_t val);
|
||||
|
||||
unsigned char reverse_bits(unsigned char num);
|
||||
|
||||
int largest_power_of_two(int num);
|
||||
|
||||
uint32_t increment_bitmask(const uint32_t value, const uint32_t mask);
|
||||
|
126
src/mining.cpp
126
src/mining.cpp
@ -14,11 +14,6 @@
|
||||
#include "drivers/displays/display.h"
|
||||
#include "drivers/storage/storage.h"
|
||||
|
||||
#ifdef NERD_NOS
|
||||
#include "drivers/nerd-nos/mining.h"
|
||||
#endif
|
||||
|
||||
|
||||
nvs_handle_t stat_handle;
|
||||
|
||||
uint32_t templates = 0;
|
||||
@ -41,8 +36,8 @@ extern TSettings Settings;
|
||||
IPAddress serverIP(1, 1, 1, 1); //Temporally save poolIPaddres
|
||||
|
||||
//Global work data
|
||||
static WiFiClient client;
|
||||
static miner_data mMiner; //Global miner data (Create a miner class TODO)
|
||||
WiFiClient client;
|
||||
miner_data mMiner; //Global miner data (Create a miner class TODO)
|
||||
mining_subscribe mWorker;
|
||||
mining_job mJob;
|
||||
monitor_data mMonitor;
|
||||
@ -103,12 +98,14 @@ bool checkPoolInactivity(unsigned int keepAliveTime, unsigned long inactivityTim
|
||||
}*/
|
||||
}
|
||||
|
||||
#ifndef NERD_NOS
|
||||
if(elapsedKHs == 0){
|
||||
//Check if hashrate is 0 during inactivityTIme
|
||||
if(mStart0Hashrate == 0) mStart0Hashrate = millis();
|
||||
if((millis()-mStart0Hashrate) > inactivityTime) { mStart0Hashrate=0; return true;}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
mStart0Hashrate = 0;
|
||||
return false;
|
||||
@ -372,121 +369,6 @@ void runMiner(void * task_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void asic_create_job(mining_subscribe *mWorker, mining_job *job, bm_job_t *next_job, uint32_t extranonce_2);
|
||||
|
||||
// we can have 32 different job ids
|
||||
bm_job_t asic_jobs[32];
|
||||
|
||||
void runASIC(void * task_id) {
|
||||
Serial.printf("[MINER] Started runASIC Task!\n");
|
||||
|
||||
uint32_t extranonce_2 = 0;
|
||||
while(1) {
|
||||
// wait for new job
|
||||
while(1) {
|
||||
if (mMiner.newJob == true) {
|
||||
break;
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS); //Small delay
|
||||
}
|
||||
|
||||
if(mMiner.newJob) {
|
||||
mMiner.newJob = false; //Clear newJob flag
|
||||
}
|
||||
mMiner.inRun = true; //Set inRun flag
|
||||
|
||||
Serial.println(">>> STARTING TO HASH NONCES");
|
||||
uint32_t startT = micros();
|
||||
|
||||
memset(asic_jobs, 0, sizeof(asic_jobs));
|
||||
|
||||
// we are assuming the version doesn't change from job to job
|
||||
uint32_t version = strtoul(mJob.version.c_str(), NULL, 16);
|
||||
|
||||
mMonitor.NerdStatus = NM_hashing;
|
||||
|
||||
while (mMiner.inRun) {
|
||||
extranonce_2++;
|
||||
|
||||
// use extranonce2 as job id
|
||||
uint8_t asic_job_id = (uint8_t) (extranonce_2 % 32);
|
||||
|
||||
// if it was used before, we have to free the pointers
|
||||
if (asic_jobs[asic_job_id].ntime) {
|
||||
asic_free_bm_job(&asic_jobs[asic_job_id]);
|
||||
}
|
||||
|
||||
// create the next asic job
|
||||
asic_create_job(&mWorker, &mJob, &asic_jobs[asic_job_id], extranonce_2);
|
||||
|
||||
// send the job and
|
||||
asic_send_work(&asic_jobs[asic_job_id], asic_job_id);
|
||||
|
||||
// wait 30ms for the response
|
||||
// the pointer returned is the RS232 receive buffer :shushing-face:
|
||||
// but we only have a single thread so it should be okay
|
||||
task_result *result = asic_proccess_work(version, 30);
|
||||
|
||||
// if we haven't received anything in time, so send a new job
|
||||
if (!result) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we have received a job we don't know
|
||||
if (!asic_jobs[result->job_id].ntime) {
|
||||
Serial.printf("No Job found for received ID %02x\n", result->job_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
// check the nonce difficulty
|
||||
double diff_hash = asic_test_nonce_value(
|
||||
&asic_jobs[result->job_id],
|
||||
result->nonce,
|
||||
result->rolled_version);
|
||||
|
||||
Serial.print(" - Current diff share: "); Serial.println(diff_hash, 12);
|
||||
Serial.print(" - Current pool diff : "); Serial.println(mMiner.poolDifficulty, 12);
|
||||
|
||||
// update best diff
|
||||
if (diff_hash > best_diff)
|
||||
best_diff = diff_hash;
|
||||
|
||||
if(diff_hash > mMiner.poolDifficulty)
|
||||
{
|
||||
tx_mining_submit_asic(client, mWorker, &asic_jobs[result->job_id], result);
|
||||
Serial.println("valid share!");
|
||||
/*
|
||||
Serial.print(" - Current diff share: "); Serial.println(diff_hash,12);
|
||||
Serial.print(" - Current pool diff : "); Serial.println(mMiner.poolDifficulty,12);
|
||||
*/
|
||||
/*
|
||||
Serial.print(" - TX SHARE: ");
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
Serial.printf("%02x", hash[i]);
|
||||
*/
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.println("");
|
||||
Serial.print(" - Current nonce: "); Serial.println(nonce);
|
||||
Serial.print(" - Current block header: ");
|
||||
for (size_t i = 0; i < 80; i++) {
|
||||
Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
|
||||
}
|
||||
#endif
|
||||
Serial.println("");
|
||||
mLastTXtoPool = millis();
|
||||
}
|
||||
}
|
||||
Serial.println ("MINER WORK ABORTED >> waiting new job");
|
||||
mMiner.inRun = false;
|
||||
uint32_t duration = micros() - startT;
|
||||
/*
|
||||
if (esp_task_wdt_reset() == ESP_OK)
|
||||
Serial.print(">>> Resetting watchdog timer");
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define DELAY 100
|
||||
#define REDRAW_EVERY 10
|
||||
|
||||
|
232
src/mining_nerdnos.cpp
Normal file
232
src/mining_nerdnos.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <WiFi.h>
|
||||
#include <esp_task_wdt.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <nvs.h>
|
||||
//#include "ShaTests/nerdSHA256.h"
|
||||
#include "ShaTests/nerdSHA256plus.h"
|
||||
#include "stratum.h"
|
||||
#include "mining.h"
|
||||
#include "utils.h"
|
||||
#include "monitor.h"
|
||||
#include "timeconst.h"
|
||||
#include "drivers/displays/display.h"
|
||||
#include "drivers/storage/storage.h"
|
||||
|
||||
#include "drivers/nerd-nos/nerdnos.h"
|
||||
#include "mining_nerdnos.h"
|
||||
|
||||
extern WiFiClient client;
|
||||
extern mining_subscribe mWorker;
|
||||
extern mining_job mJob;
|
||||
extern miner_data mMiner;
|
||||
extern monitor_data mMonitor;
|
||||
|
||||
extern pthread_mutex_t job_mutex;
|
||||
extern double best_diff;
|
||||
extern unsigned long mLastTXtoPool;
|
||||
|
||||
// to track the jobs
|
||||
// we can have 32 different job ids
|
||||
static bm_job_t asic_jobs[32] = {0};
|
||||
|
||||
// to track hashrate
|
||||
#define ASIC_HISTORY_SIZE 128
|
||||
|
||||
typedef struct {
|
||||
uint32_t diffs[ASIC_HISTORY_SIZE];
|
||||
uint32_t timestamps[ASIC_HISTORY_SIZE];
|
||||
uint32_t newest;
|
||||
uint32_t oldest;
|
||||
uint64_t sum;
|
||||
double avg_gh;
|
||||
double duration;
|
||||
int shares;
|
||||
} history_t;
|
||||
|
||||
static pthread_mutex_t job_interval_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t job_interval_cond = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
history_t history = {0};
|
||||
|
||||
double nerdnos_get_avg_hashrate() {
|
||||
return history.avg_gh;
|
||||
}
|
||||
|
||||
// incremental ringbuffer based hashrate calculation
|
||||
static void calculate_hashrate(history_t *history, uint32_t diff) {
|
||||
// if we have wrapped around at least once our ringbuffer is full
|
||||
// and we have to remove the oldest element
|
||||
if (history->newest + 1 >= ASIC_HISTORY_SIZE) {
|
||||
history->sum -= history->diffs[history->oldest % ASIC_HISTORY_SIZE];
|
||||
history->oldest++;
|
||||
}
|
||||
// add and store the newest sample
|
||||
history->sum += diff;
|
||||
history->diffs[history->newest % ASIC_HISTORY_SIZE] = diff;
|
||||
history->timestamps[history->newest % ASIC_HISTORY_SIZE] = micros();
|
||||
|
||||
uint64_t oldest_timestamp = history->timestamps[history->oldest % ASIC_HISTORY_SIZE];
|
||||
uint64_t newest_timestamp = history->timestamps[history->newest % ASIC_HISTORY_SIZE];
|
||||
|
||||
history->duration = (double) (newest_timestamp - oldest_timestamp) / 1.0e6;
|
||||
history->shares = (int) history->newest - (int) history->oldest + 1;
|
||||
|
||||
if (history->duration) {
|
||||
double avg = (double) (history->sum << 32llu) / history->duration;
|
||||
history->avg_gh = avg / 1.0e9;
|
||||
}
|
||||
|
||||
history->newest++;
|
||||
}
|
||||
|
||||
// triggers the job creation
|
||||
static void create_job_timer(TimerHandle_t xTimer)
|
||||
{
|
||||
pthread_mutex_lock(&job_interval_mutex);
|
||||
pthread_cond_signal(&job_interval_cond);
|
||||
pthread_mutex_unlock(&job_interval_mutex);
|
||||
}
|
||||
|
||||
void runASIC(void * task_id) {
|
||||
Serial.printf("[MINER] Started runASIC Task!\n");
|
||||
|
||||
// Create the timer
|
||||
TimerHandle_t job_timer = xTimerCreate("NERDNOS_Job_Timer", NERDNOS_JOB_INTERVAL_MS / portTICK_PERIOD_MS, pdTRUE, NULL, create_job_timer);
|
||||
|
||||
if (job_timer == NULL) {
|
||||
Serial.println("Failed to create NERNOS timer");
|
||||
return;
|
||||
}
|
||||
|
||||
// Start the timer
|
||||
if (xTimerStart(job_timer, 0) != pdPASS) {
|
||||
Serial.println("Failed to start NERDNOS timer");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t extranonce_2 = 0;
|
||||
while(1) {
|
||||
// wait for new job
|
||||
while(1) {
|
||||
if (mMiner.newJob == true) {
|
||||
break;
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS); //Small delay
|
||||
}
|
||||
|
||||
if(mMiner.newJob) {
|
||||
mMiner.newJob = false; //Clear newJob flag
|
||||
}
|
||||
mMiner.inRun = true; //Set inRun flag
|
||||
|
||||
Serial.println(">>> STARTING TO HASH NONCES");
|
||||
uint32_t startT = micros();
|
||||
|
||||
memset(asic_jobs, 0, sizeof(asic_jobs));
|
||||
|
||||
// we are assuming the version doesn't change from job to job
|
||||
uint32_t version = strtoul(mJob.version.c_str(), NULL, 16);
|
||||
|
||||
mMonitor.NerdStatus = NM_hashing;
|
||||
|
||||
uint32_t current_difficulty = 0;
|
||||
|
||||
while (mMiner.inRun) {
|
||||
// wait for the timer to start a new job
|
||||
// also yields the CPU
|
||||
pthread_mutex_lock(&job_interval_mutex);
|
||||
pthread_cond_wait(&job_interval_cond, &job_interval_mutex);
|
||||
pthread_mutex_unlock(&job_interval_mutex);
|
||||
|
||||
// increment extranonce2
|
||||
extranonce_2++;
|
||||
|
||||
// use extranonce2 as job id
|
||||
uint8_t asic_job_id = (uint8_t) (extranonce_2 % 32);
|
||||
|
||||
// if it was used before, we have to free the pointers
|
||||
if (asic_jobs[asic_job_id].ntime) {
|
||||
nerdnos_free_bm_job(&asic_jobs[asic_job_id]);
|
||||
}
|
||||
|
||||
// create the next asic job
|
||||
// make sure that another task doesn't mess with the data while
|
||||
// we are using it
|
||||
pthread_mutex_lock(&job_mutex);
|
||||
if (current_difficulty != mMiner.poolDifficulty) {
|
||||
current_difficulty = mMiner.poolDifficulty;
|
||||
nerdnos_set_asic_difficulty(current_difficulty);
|
||||
Serial.printf("Set difficulty to %llu\n", current_difficulty);
|
||||
}
|
||||
nerdnos_create_job(&mWorker, &mJob, &asic_jobs[asic_job_id], extranonce_2, current_difficulty);
|
||||
pthread_mutex_unlock(&job_mutex);
|
||||
|
||||
// send the job and
|
||||
nerdnos_send_work(&asic_jobs[asic_job_id], asic_job_id);
|
||||
|
||||
// the pointer returned is the RS232 receive buffer :shushing-face:
|
||||
// but we only have a single thread so it should be okay
|
||||
// process all results if we have more than one
|
||||
// this is okay because serial uses a buffer and (most likely^^) DMA
|
||||
task_result *result = 0;
|
||||
while (result = nerdnos_proccess_work(version, 1), result != NULL) {
|
||||
// if we have received a job we don't know
|
||||
if (!asic_jobs[result->job_id].ntime) {
|
||||
Serial.printf("No Job found for received ID %02x\n", result->job_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t hash[32];
|
||||
|
||||
// check the nonce difficulty
|
||||
double diff_hash = nerdnos_test_nonce_value(
|
||||
&asic_jobs[result->job_id],
|
||||
result->nonce,
|
||||
result->rolled_version,
|
||||
hash);
|
||||
|
||||
// update best diff
|
||||
if (diff_hash > best_diff)
|
||||
best_diff = diff_hash;
|
||||
|
||||
// calculate the hashrate
|
||||
if (diff_hash >= asic_jobs[result->job_id].pool_diff) {
|
||||
calculate_hashrate(&history, asic_jobs[result->job_id].pool_diff);
|
||||
Serial.printf("avg hashrate: %.2fGH/s (history spans %2.fs, %d shares)\n", history.avg_gh, history.duration, history.shares);
|
||||
}
|
||||
|
||||
if(diff_hash > mMiner.poolDifficulty)
|
||||
{
|
||||
tx_mining_submit_asic(client, mWorker, &asic_jobs[result->job_id], result);
|
||||
Serial.println("valid share!");
|
||||
Serial.print(" - Current diff share: "); Serial.println(diff_hash,12);
|
||||
Serial.print(" - Current pool diff : "); Serial.println(mMiner.poolDifficulty,12);
|
||||
Serial.print(" - TX SHARE: ");
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
Serial.printf("%02x", hash[i]);
|
||||
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.println("");
|
||||
Serial.print(" - Current nonce: "); Serial.println(nonce);
|
||||
Serial.print(" - Current block header: ");
|
||||
for (size_t i = 0; i < 80; i++) {
|
||||
Serial.printf("%02x", mMiner.bytearray_blockheader[i]);
|
||||
}
|
||||
#endif
|
||||
Serial.println("");
|
||||
mLastTXtoPool = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
Serial.println ("MINER WORK ABORTED >> waiting new job");
|
||||
mMiner.inRun = false;
|
||||
uint32_t duration = micros() - startT;
|
||||
/*
|
||||
if (esp_task_wdt_reset() == ESP_OK)
|
||||
Serial.print(">>> Resetting watchdog timer");
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
6
src/mining_nerdnos.h
Normal file
6
src/mining_nerdnos.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define NERDNOS_JOB_INTERVAL_MS 30
|
||||
|
||||
void runASIC(void * task_id);
|
||||
double nerdnos_get_avg_hashrate();
|
@ -9,6 +9,10 @@
|
||||
#include "monitor.h"
|
||||
#include "drivers/storage/storage.h"
|
||||
|
||||
#ifdef NERD_NOS
|
||||
#include "mining_nerdnos.h"
|
||||
#endif
|
||||
|
||||
extern uint32_t templates;
|
||||
extern uint32_t hashes;
|
||||
extern uint32_t Mhashes;
|
||||
@ -234,10 +238,17 @@ String getTime(void){
|
||||
return LocalHour;
|
||||
}
|
||||
|
||||
#ifdef NERD_NOS
|
||||
String getCurrentHashRate(unsigned long mElapsed) {
|
||||
// we have too little space for 2 digits after the decimal point
|
||||
return String(nerdnos_get_avg_hashrate(), 1);
|
||||
}
|
||||
#else
|
||||
String getCurrentHashRate(unsigned long mElapsed)
|
||||
{
|
||||
return String((1.0 * (elapsedKHs * 1000)) / mElapsed, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
mining_data getMiningData(unsigned long mElapsed)
|
||||
{
|
||||
|
@ -10,7 +10,9 @@
|
||||
#include "utils.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
pthread_mutex_t job_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
StaticJsonDocument<BUFFER_JSON_DOC> doc;
|
||||
unsigned long id = 1;
|
||||
@ -99,9 +101,11 @@ bool parse_mining_subscribe(String line, mining_subscribe& mSubscribe)
|
||||
if (error || checkError(doc)) return false;
|
||||
if (!doc.containsKey("result")) return false;
|
||||
|
||||
pthread_mutex_lock(&job_mutex);
|
||||
mSubscribe.sub_details = String((const char*) doc["result"][0][0][1]);
|
||||
mSubscribe.extranonce1 = String((const char*) doc["result"][1]);
|
||||
mSubscribe.extranonce2_size = doc["result"][2];
|
||||
pthread_mutex_unlock(&job_mutex);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -179,6 +183,7 @@ bool parse_mining_notify(String line, mining_job& mJob)
|
||||
if (error) return false;
|
||||
if (!doc.containsKey("params")) return false;
|
||||
|
||||
pthread_mutex_lock(&job_mutex);
|
||||
mJob.job_id = String((const char*) doc["params"][0]);
|
||||
mJob.prev_block_hash = String((const char*) doc["params"][1]);
|
||||
mJob.coinb1 = String((const char*) doc["params"][2]);
|
||||
@ -188,6 +193,7 @@ bool parse_mining_notify(String line, mining_job& mJob)
|
||||
mJob.nbits = String((const char*) doc["params"][6]);
|
||||
mJob.ntime = String((const char*) doc["params"][7]);
|
||||
mJob.clean_jobs = doc["params"][8]; //bool
|
||||
pthread_mutex_unlock(&job_mutex);
|
||||
|
||||
#ifdef DEBUG_MINING
|
||||
Serial.print(" job_id: "); Serial.println(mJob.job_id);
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define BUFFER_JSON_DOC 4096
|
||||
#define BUFFER 1024
|
||||
|
||||
typedef struct {
|
||||
typedef struct mining_subscribe {
|
||||
String sub_details;
|
||||
String extranonce1;
|
||||
String extranonce2;
|
||||
@ -25,7 +25,7 @@ typedef struct {
|
||||
char wPass[20];
|
||||
} mining_subscribe;
|
||||
|
||||
typedef struct {
|
||||
typedef struct mining_job {
|
||||
String job_id;
|
||||
String prev_block_hash;
|
||||
String coinb1;
|
||||
|
Loading…
Reference in New Issue
Block a user