Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for several boards #1850

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion AVR_Miner.py
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,13 @@ def mine_avr(com, threadid, fastest_pool, thread_rigid):
receiving the DTR signal
"""
sleep(2)

"""
Indicate to the device that the port
is open for receiving data after
reseting the board
"""
ser.setRTS(False)
break
except Exception as e:
pretty_print(
Expand Down Expand Up @@ -1099,7 +1106,7 @@ def mine_avr(com, threadid, fastest_pool, thread_rigid):
break

start_diff = "AVR"
if hashrate_test > 1000:
if hashrate_test > 3500:
start_diff = "DUE"
elif hashrate_test > 550:
start_diff = "ARM"
Expand Down
186 changes: 157 additions & 29 deletions Arduino_Code/Arduino_Code.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
(____/(______)(____)(_)\_)(_____) \___)(_____)(____)(_)\_)
Official code for Arduino boards (and relatives) version 4.3

Duino-Coin Team & Community 2019-2024 © MIT Licensed
Duino-Coin Team & Community 2019-2025 © MIT Licensed
https://duinocoin.com
https://github.com/revoxhere/duino-coin
If you don't know where to start, visit official website and navigate to
Expand All @@ -16,24 +16,49 @@
/* For microcontrollers with low memory change that to -Os in all files,
for default settings use -O0. -O may be a good tradeoff between both */
#pragma GCC optimize ("-Ofast")

/* For microcontrollers with custom LED pins, adjust the line below */
#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif

/* Uncomment if you want BBC Micro:bit LED Matrix support to display total shares
Requires Adafruit microbit library */
//#define MICROBIT_LED_MATRIX
//#define MICROBIT_LED_MATRIX_BUTTONS_CONTROL

/* Uncomment if you want the miner task on second core
Note that this may be slower than using just one core
Requires a board that has dual cores */
//#define USE_SECOND_CORE

/* Serial-related definitions */
#define SEP_TOKEN ","
#define END_TOKEN "\n"
/* For 8-bit microcontrollers we should use 16 bit variables since the
difficulty is low, for all the other cases should be 32 bits. */
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
typedef uint32_t uintDiff;
#else
typedef uint32_t uintDiff;
#endif

// Arduino identifier library - https://github.com/ricaun
#include "uniqueID.h"

#include "duco_hash.h"

#if defined(MICROBIT_LED_MATRIX)
#include <Adafruit_Microbit.h>

bool matrixEnabled = true;
byte minedDigitCount = 0;

Adafruit_Microbit_Matrix microbit;
#endif

struct duco_miner_job_t {
// Reserve 1 extra byte for comma separator (and later zero)
char lastBlockHash[40 + 1];
char newBlockHash[40 + 1];

uint32_t difficulty;
};
duco_miner_job_t *job;

String get_DUCOID() {
String ID = "DUCOID";
char buff[4];
Expand All @@ -50,6 +75,17 @@ void setup() {
// Prepare built-in led pin as output
pinMode(LED_BUILTIN, OUTPUT);
DUCOID = get_DUCOID();

// Prepare Microbit LED matrix
#if defined(MICROBIT_LED_MATRIX)
microbit.begin();

#if defined(MICROBIT_LED_MATRIX_BUTTONS_CONTROL)
pinMode(PIN_BUTTON_A, INPUT);
pinMode(PIN_BUTTON_B, INPUT);
#endif
#endif

// Open serial port
Serial.begin(115200);
Serial.setTimeout(10000);
Expand All @@ -71,27 +107,57 @@ void lowercase_hex_to_bytes(char const * hexDigest, uint8_t * rawDigest) {
}
}

char* citoa(uint32_t num, char* str) {
int i = 0;

/* Handle 0 explicitly, otherwise empty string is
* printed for 0 */
if (num == 0) {
str[i++] = '0';
str[i] = '\0';
return str;
}

// Process individual digits
while (num != 0) {
int rem = num % 10;
str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / 10;
}

str[i] = '\0'; // Append string terminator

// Reverse the string
int start = 0;
int end = i - 1;
while (start < end) {
char temp = str[start];
str[start] = str[end];
str[end] = temp;
end--;
start++;
}

return str;
}

// DUCO-S1A hasher
uintDiff ducos1a(char const * prevBlockHash, char const * targetBlockHash, uintDiff difficulty) {
uint32_t ducos1a() {
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
// If the difficulty is too high for AVR architecture then return 0
if (difficulty > 655) return 0;
if (job->difficulty > 655) return 0;
#endif

uint8_t target[SHA1_HASH_LEN];
lowercase_hex_to_bytes(targetBlockHash, target);

uintDiff const maxNonce = difficulty * 100 + 1;
return ducos1a_mine(prevBlockHash, target, maxNonce);
}
lowercase_hex_to_bytes(job->newBlockHash, target);

uintDiff ducos1a_mine(char const * prevBlockHash, uint8_t const * target, uintDiff maxNonce) {
static duco_hash_state_t hash;
duco_hash_init(&hash, prevBlockHash);
duco_hash_init(&hash, job->lastBlockHash);

uint32_t const maxNonce = job->difficulty * 100 + 1;
char nonceStr[10 + 1];
for (uintDiff nonce = 0; nonce < maxNonce; nonce++) {
ultoa(nonce, nonceStr, 10);
for (uint32_t nonce = 0; nonce < maxNonce; nonce++) {
citoa(nonce, nonceStr);

uint8_t const * hash_bytes = duco_hash_try_nonce(&hash, nonceStr);
if (memcmp(hash_bytes, target, SHA1_HASH_LEN) == 0) {
Expand All @@ -102,32 +168,44 @@ uintDiff ducos1a_mine(char const * prevBlockHash, uint8_t const * target, uintDi
return 0;
}

void loop() {
/* This is called by loop() at the end */
void serialEvent() {
// Wait for serial data
if (Serial.available() <= 0) {
return;
}

// Reserve 1 extra byte for comma separator (and later zero)
char lastBlockHash[40 + 1];
char newBlockHash[40 + 1];
// Create job object
duco_miner_job_t *newJob = new struct duco_miner_job_t;

// Read last block hash
if (Serial.readBytesUntil(',', lastBlockHash, 41) != 40) {
if (Serial.readBytesUntil(',', newJob->lastBlockHash, 41) != 40) {
return;
}
lastBlockHash[40] = 0;
newJob->lastBlockHash[40] = 0;

// Read expected hash
if (Serial.readBytesUntil(',', newBlockHash, 41) != 40) {
if (Serial.readBytesUntil(',', newJob->newBlockHash, 41) != 40) {
return;
}
newBlockHash[40] = 0;
newJob->newBlockHash[40] = 0;

// Read difficulty
uintDiff difficulty = strtoul(Serial.readStringUntil(',').c_str(), NULL, 10);
newJob->difficulty = strtoul(Serial.readStringUntil(',').c_str(), NULL, 10);

// Clearing the receive buffer reading one job.
while (Serial.available()) Serial.read();

// Send job object
job = newJob;
}

void hashEvent() {
// Ensure job is not empty
if (job == NULL) {
return;
}

// Turn off the built-in led
#if defined(ARDUINO_ARCH_AVR)
PORTB = PORTB | B00100000;
Expand All @@ -139,7 +217,7 @@ void loop() {
uint32_t startTime = micros();

// Call DUCO-S1A hasher
uintDiff ducos1result = ducos1a(lastBlockHash, newBlockHash, difficulty);
uint32_t ducos1result = ducos1a();

// Calculate elapsed time
uint32_t elapsedTime = micros() - startTime;
Expand All @@ -161,4 +239,54 @@ void loop() {
+ SEP_TOKEN
+ String(DUCOID)
+ END_TOKEN);

// Clear job object
delete job;
job = NULL;
}

#if defined(MICROBIT_LED_MATRIX)
void microbitMatrixEvent() {
// Draw Microbit matrix and handle button presses
#if defined(MICROBIT_LED_MATRIX_BUTTONS_CONTROL)
if (!digitalRead(PIN_BUTTON_A)) {
matrixEnabled = true;
minedDigitCount = 0;
}
if (!digitalRead(PIN_BUTTON_B)) {
matrixEnabled = false;
microbit.clear();
}
#endif

if (!digitDrawn && matrixEnabled) {
microbit.print(minedDigitCount);
}

// Count mined shares and clear Microbit matrix
if (matrixEnabled) {
minedDigitCount++;

// Cycle around 0-9 to prevent scrolling
if (minedDigitCount >= 10) {
minedDigitCount = 0;
}
}
}
#endif

void loop() {
#if defined(MICROBIT_LED_MATRIX)
microbitMatrixEvent();
#endif

#if ! defined(USE_SECOND_CORE)
hashEvent();
#endif
}

#if defined(USE_SECOND_CORE)
void loop1() {
hashEvent();
}
#endif
10 changes: 10 additions & 0 deletions Arduino_Code/uniqueID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,16 @@ ArduinoUniqueID::ArduinoUniqueID()
id[7] = SIGROW.SERNUM7;
id[8] = SIGROW.SERNUM8;
id[9] = SIGROW.SERNUM9;
#elif defined(NRF51_SERIES) || defined(NRF52_SERIES) || defined(NRF53_SERIES)
NRF_FICR_Type ficr = *NRF_FICR;
id[0] = ficr.DEVICEID[0] >> 24;
id[1] = ficr.DEVICEID[0] >> 16;
id[2] = ficr.DEVICEID[0] >> 8;
id[3] = ficr.DEVICEID[0];
id[4] = ficr.DEVICEID[1] >> 24;
id[5] = ficr.DEVICEID[1] >> 16;
id[6] = ficr.DEVICEID[1] >> 8;
id[7] = ficr.DEVICEID[1];
#endif
}

Expand Down
6 changes: 5 additions & 1 deletion Arduino_Code/uniqueID.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
#elif defined(ARDUINO_ARCH_MBED_RP2040) || defined(ARDUINO_ARCH_RP2040)
//#include <pico/unique_id.h>
#elif defined(ARDUINO_ARCH_MEGAAVR)
#elif defined(NRF51_SERIES) || defined(NRF52_SERIES) || defined(NRF53_SERIES)
#else
#error "ArduinoUniqueID only works on AVR, SAM, SAMD, STM32, Teensy, megaAVR and ESP Architecture"
#error "ArduinoUniqueID only works on AVR, SAM, SAMD, STM32, Teensy, megaAVR, nRF5 and ESP Architecture"
#endif

#if defined(ARDUINO_ARCH_AVR)
Expand Down Expand Up @@ -63,6 +64,9 @@
#elif defined(ARDUINO_ARCH_MEGAAVR)
#define UniqueIDsize 10
#define UniqueIDbuffer 10
#elif defined(NRF51_SERIES) || defined(NRF52_SERIES) || defined(NRF53_SERIES)
#define UniqueIDsize 8
#define UniqueIDbuffer 8
#endif

#define UniqueID8 (_UniqueID.id + UniqueIDbuffer - 8)
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,16 +167,24 @@ Please note the DUCO/day column has been removed since version 4.0 changed the r
| Libre Computers Tritium H5CC | 480 kH/s | 4 | 5 W |
| Libre Computers Le Potato | 410 kH/s | 4 | 5 W |
| Pine64 ROCK64 | 640 kH/s | 4 | 5 W |
| Qualcomm Snapdragon 425 **(fasthash)** | 6.4 MH/s | 4 | 3.5 W |
| Qualcomm Snapdragon 615 | 225 KH/s | 4 | 3.5 W |
| Qualcomm Snapdragon 8 Gen 1 **(fasthash)** | 27.6 MH/s | 8 | 5 W |
| MediaTek Helio A22 **(fasthash)** | 9.3 MH/s | 4 | 4.5 W |
| Intel Celeron G1840 | 1.25 MH/s | 2 | 53 W |
| Intel Celeron N2840 **(fasthash)** | 4.4 MH/s | 2 | 2.2 W |
| Intel Core m3-8100Y **(fasthash)** | 11.0 MH/s | 4 | 8.1 W |
| Intel Core i3-4130 | 1.45 MH/s | 4 | 54 W |
| Intel Core i5-2430M | 1.18 MH/s | 4 | 35 W |
| Intel Core i5-3230M | 1.52 MH/s | 4 | 35 W |
| Intel Core i5-5350U | 1.35 MH/s | 4 | 15 W |
| Intel Core i5-7200U | 1.62 MH/s | 4 | 15 W |
| Intel Core i5-8300H | 3.67 MH/s | 8 | 45 W |
| Intel Core i3-4130 | 1.45 MH/s | 4 | 54 W |
| Intel Core i7-11370H **(fasthash)** | 17.3 MH/s | 8 | 35 W |
| Intel Core i7-1260P **(fasthash)** | 73.5 MH/s | 16 | 25 W |
| Intel Core i9-13900K **(fasthash)** | 104.04 MH/s | 32 | 160 W |
| AMD Ryzen 5 2600 | 4.9 MH/s | 12 | 65 W |
| AMD Ryzen R1505G **(fasthash)** | 8.5 MH/s | 4 | 35 W |
| Intel Core i7-11370H **(fasthash)** | 17.3 MH/s | 8 | 35 W |
| Realtek RTD1295 | 490 kH/s | 4 | - |
| Realtek RTD1295 **(fasthash)** | 3.89 MH/s | 4 | - |

Expand Down
Loading