Merge pull request #663 from BitMaker-hub/prerelease

hardware sha256 by evgenykz + new boards
This commit is contained in:
BitMaker
2025-09-07 09:07:19 +02:00
committed by GitHub
21 changed files with 2684 additions and 319 deletions

View File

@@ -25,17 +25,24 @@ jobs:
run: pip install --upgrade platformio
- name: Build PlatformIO Project
run: pio run
- name: Archive built binaries
- name: Debug - Check generated files
run: |
echo "=== All .bin files found ==="
find . -name "*.bin" -type f
echo "=== Directory structure ==="
ls -la
echo "=== .pio/build contents ==="
find .pio/build -name "*.bin" -type f 2>/dev/null || echo "No .pio/build files"
echo "=== firmware directory ==="
ls -la firmware/ 2>/dev/null || echo "No firmware directory"
find firmware -name "*.bin" -type f 2>/dev/null || echo "No firmware .bin files"
echo "=== Script check ==="
ls -la post_build_merge.py
- name: Archive firmware files
uses: actions/upload-artifact@v4
with:
name: built-binaries-${{ github.sha }}
path: .pio/build/*/*.bin
if-no-files-found: error
- name: Archive bootapp binary
uses: actions/upload-artifact@v4
with:
name: bootapp-binary-${{ github.sha }}
path: ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin
name: firmware-files-${{ github.sha }}
path: firmware/
if-no-files-found: error
- name: Get version
id: version_step
@@ -47,21 +54,23 @@ jobs:
contents: write
discussions: write
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/dev'
if: github.ref == 'refs/heads/prerelease'
steps:
- name: Download built binaries
- name: Download firmware files
uses: actions/download-artifact@v4
with:
path: ${{ github.workspace }}/binaries
name: built-binaries-${{ github.sha }}
- name: Download bootapp binary
uses: actions/download-artifact@v4
with:
path: ${{ github.workspace }}/binaries
name: bootapp-binary-${{ github.sha }}
- name: Rename built binaries
run: find ${{ github.workspace }}/binaries -mindepth 2 -maxdepth 3 -type f -name "*.bin" -exec sh -c 'cp "$0" "${{ github.workspace }}/binaries/$(basename $(dirname "$0"))_$(basename $0)"' {} \;
- name: Pre-release
path: ${{ github.workspace }}/
name: firmware-files-${{ github.sha }}
- name: Debug - Check downloaded files
run: |
echo "=== Working directory ==="
pwd
ls -la
echo "=== All .bin files after download ==="
find . -name "*.bin" -type f
echo "=== firmware directory after download ==="
find firmware -type f 2>/dev/null || echo "No firmware directory found"
- name: Prerelease
uses: softprops/action-gh-release@v2
with:
name: nerdminer-prerelease-${{ needs.build.outputs.version }}
@@ -70,5 +79,5 @@ jobs:
generate_release_notes: true
prerelease: true
fail_on_unmatched_files: true
files: ${{ github.workspace }}/binaries/*.bin
files: ${{ github.workspace }}/**/*.bin

View File

@@ -25,17 +25,11 @@ jobs:
run: pip install --upgrade platformio
- name: Build PlatformIO Project
run: pio run
- name: Archive built binaries
- name: Archive firmware files
uses: actions/upload-artifact@v4
with:
name: built-binaries-${{ github.sha }}
path: .pio/build/*/*.bin
if-no-files-found: error
- name: Archive bootapp binary
uses: actions/upload-artifact@v4
with:
name: bootapp-binary-${{ github.sha }}
path: ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin
name: firmware-files-${{ github.sha }}
path: firmware/
if-no-files-found: error
- name: Get version
id: version_step
@@ -48,7 +42,7 @@ jobs:
discussions: write
issues: write
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/main'
steps:
- uses: trstringer/manual-approval@v1
timeout-minutes: 120
@@ -59,18 +53,11 @@ jobs:
issue-title: "Releasing Nerdminer version ${{ needs.build.outputs.version }}"
issue-body: "Please approve or deny the release of ${{ needs.build.outputs.version }}."
exclude-workflow-initiator-as-approver: false
- name: Download built binaries
- name: Download firmware files
uses: actions/download-artifact@v4
with:
path: ${{ github.workspace }}/binaries
name: built-binaries-${{ github.sha }}
- name: Download bootapp binary
uses: actions/download-artifact@v4
with:
path: ${{ github.workspace }}/binaries
name: bootapp-binary-${{ github.sha }}
- name: Rename built binaries
run: find ${{ github.workspace }}/binaries -mindepth 2 -maxdepth 3 -type f -name "*.bin" -exec sh -c 'cp "$0" "${{ github.workspace }}/binaries/$(basename $(dirname "$0"))_$(basename $0)"' {} \;
path: ${{ github.workspace }}/
name: firmware-files-${{ github.sha }}
- name: Release
uses: softprops/action-gh-release@v2
with:
@@ -80,5 +67,5 @@ jobs:
generate_release_notes: true
make_latest: true
fail_on_unmatched_files: true
files: ${{ github.workspace }}/binaries/*.bin
files: ${{ github.workspace }}/firmware/*/*.bin

View File

@@ -11,12 +11,15 @@
[platformio]
globallib_dir = lib
default_envs = NerdminerV2-T-HMI, wt32-sc01, wt32-sc01-plus, han_m5stack, M5Stick-C, esp32cam, ESP32-2432S028R, ESP32_2432S028_2USB, NerdminerV2, Lilygo-T-Embed, ESP32-devKitv1, NerdminerV2-S3-DONGLE, NerdminerV2-S3-GEEK, NerdminerV2-S3-AMOLED, NerdminerV2-S3-AMOLED-TOUCH, NerdminerV2-T-QT, NerdminerV2-T-Display_V1, ESP32-2432S028R, M5-StampS3, ESP32-S3-devKitv1, ESP32-S3-mini-wemos, ESP32-S2-mini-wemos, ESP32-S3-mini-weact, ESP32-D0WD-V3-weact, ESP32-C3-devKitmv1, ESP32-C3-super-mini
default_envs = NerdminerV2, NerdminerV2-T-HMI, wt32-sc01, wt32-sc01-plus, han_m5stack, M5Stick-C, M5Stick-C-Plus2, M5Stick-CPlus, esp32cam, ESP32-2432S028R, ESP32_2432S028_2USB, Lilygo-T-Embed, ESP32-devKitv1, NerdminerV2-S3-DONGLE, NerdminerV2-S3-GEEK, NerdminerV2-S3-AMOLED, NerdminerV2-S3-AMOLED-TOUCH, NerdminerV2-T-QT, NerdminerV2-T-Display_V1, TTGO-T-Display, M5-StampS3, ESP32-S3-devKitv1, ESP32-S3-mini-wemos, ESP32-S2-mini-wemos, ESP32-S3-mini-weact, ESP32-D0WD-V3-weact, ESP32-C3-super-mini, ESP32-C3-devKitmv1, ESP32-C3-042-OLED, ESP32-S3-042-OLED, ESP32-C3-spotpear, esp32-s3-devkitc1-n32r8
[env:M5Stick-C-Plus2]
platform = espressif32@6.6.0
board = m5stick-c-plus2
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -51,6 +54,7 @@ board = m5stick-c
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -82,6 +86,9 @@ lib_ignore =
platform = espressif32@6.6.0
board = m5stick-c
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -116,6 +123,7 @@ board = esp-wrover-kit
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -150,6 +158,7 @@ board = esp32-s3-devkitc-1
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -187,6 +196,7 @@ board = lolin_s3_mini
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -221,6 +231,7 @@ board = m5stack-core-esp32
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -253,6 +264,7 @@ board = lolin_s2_mini
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -284,6 +296,7 @@ board = lolin_s3_mini
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -318,12 +331,13 @@ board = esp32dev
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
log2file
monitor_speed = 115200
upload_speed = 115200
upload_speed = 921600
board_build.partitions = huge_app.csv
build_flags =
-D DEVKITV1=1
@@ -349,6 +363,7 @@ board = seeed_xiao_esp32c3
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -381,6 +396,7 @@ board = esp32-c3-devkitm-1
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -412,6 +428,9 @@ lib_ignore =
platform = espressif32@6.6.0
board = esp32-c3-devkitm-1
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -441,6 +460,9 @@ lib_ignore =
platform = espressif32@6.6.0
board = esp32-s3-0.42oled
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -502,6 +524,7 @@ board = esp32-s3-devkitc-1
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -535,6 +558,7 @@ board = esp32-s3-devkitc1-n32r8
framework = arduino
extra_scripts = pre:auto_firmware_version.py
post:post_build_merge.py
monitor_speed = 115200
upload_speed = 115200
@@ -569,6 +593,8 @@ board = esp32-s3-devkitc-1
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -605,6 +631,7 @@ board = esp32-s3-devkitc-1
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -641,13 +668,14 @@ board = esp32dev
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
log2file
;board_build.arduino.memory_type = qio_opi
monitor_speed = 115200
upload_speed = 115200
upload_speed = 921600
# 2 x 4.5MB app, 6.875MB SPIFFS
board_build.partitions = huge_app.csv
build_flags =
@@ -670,6 +698,7 @@ board = esp32dev ;esp-wrover-kit
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -677,7 +706,7 @@ monitor_filters =
# Commenting out 'board_build.arduino.memory_type' fixes missing 'sdkconfig.h' errors:
;board_build.arduino.memory_type = qio_opi
monitor_speed = 115200
upload_speed = 115200
upload_speed = 921600
# 2 x 4.5MB app, 6.875MB SPIFFS
board_build.partitions = huge_app.csv
build_flags =
@@ -702,6 +731,7 @@ board = lilygo-t-amoled
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
board_build.partitions = huge_app.csv
build_flags =
-DNERDMINER_S3_AMOLED
@@ -726,6 +756,7 @@ board = lilygo-t-amoled
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
board_build.partitions = huge_app.csv
build_flags =
-DNERDMINER_S3_AMOLED
@@ -750,6 +781,7 @@ board = esp32-s3-devkitc-1
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
board_build.partitions = huge_app.csv
build_flags =
-DNERDMINER_S3_DONGLE
@@ -775,6 +807,7 @@ board = esp32-s3-devkitc-1
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
board_build.partitions = huge_app.csv
build_flags =
-DNERDMINER_S3_GEEK
@@ -803,6 +836,7 @@ board = esp32cam
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -834,6 +868,7 @@ board = esp32-s3-t-qt-pro
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time
@@ -865,6 +900,7 @@ board = esp32dev
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_speed = 115200
upload_speed = 921600
;build_type = debug
@@ -915,6 +951,7 @@ board = esp32dev
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_speed = 115200
monitor_filters =
esp32_exception_decoder
@@ -970,6 +1007,7 @@ board = lilygo-t-hmi
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
board_build.partitions = default_16MB.csv
monitor_filters =
esp32_exception_decoder
@@ -1009,6 +1047,7 @@ board = ttgo-lora32-v1
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_speed = 115200
upload_speed = 115200
board_build.partitions = huge_app.csv
@@ -1032,6 +1071,7 @@ board = m5stack-stamps3
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
monitor_filters =
esp32_exception_decoder
time

202
post_build_merge.py Normal file
View File

@@ -0,0 +1,202 @@
#!/usr/bin/env python3
"""
Post-build script for NerdMiner_v2 firmware merging
Ported from merge_firmware_universal.js - detects ESP32 type from bootloader signature
Generates factory (0x0) and update (0x10000) files automatically after build
Usage: Add to platformio.ini environments:
extra_scripts =
pre:auto_firmware_version.py
post:post_build_merge.py
"""
import os
import subprocess
from pathlib import Path
Import("env")
def detect_esp32_type(bootloader_path):
"""Detect ESP32 type by analyzing bootloader signature - ported from JS version"""
try:
with open(bootloader_path, 'rb') as f:
bootloader_data = f.read()
if len(bootloader_data) < 13:
print("Warning: Bootloader too small, defaulting to ESP32")
return 'ESP32'
chip_id = bootloader_data[12] # Chip ID at byte 12
size = len(bootloader_data)
# Detect ESP32 type based on bootloader signature (from JS version)
if chip_id == 0x09 and size >= 15000:
return 'ESP32-S3'
elif chip_id == 0x05 and size >= 13000 and size < 14000:
return 'ESP32-C3'
elif chip_id == 0x02 and size >= 13000 and size < 15000:
return 'ESP32-S2'
elif chip_id == 0x00 and size >= 17000:
return 'ESP32'
else:
# Fallback: try to detect by size (from JS version)
if size >= 17000:
return 'ESP32'
elif size >= 15000:
return 'ESP32-S3'
elif size >= 13600:
return 'ESP32-S2'
elif size >= 13000:
return 'ESP32-C3'
else:
return 'ESP32' # Default fallback
except Exception as e:
print(f"Warning: Could not analyze bootloader ({e}), defaulting to ESP32")
return 'ESP32'
def get_memory_layout(esp_type):
"""Get memory addresses for each ESP32 variant - ported from JS version"""
if esp_type == 'ESP32-C3':
# ESP32-C3: Bootloader at 0x0000, no boot_app0
return {
'bootloader': 0x0000,
'partitions': 0x8000,
'firmware': 0x10000
}
elif esp_type == 'ESP32-S2':
# ESP32-S2: Bootloader at 0x1000, boot_app0 at 0xE000
return {
'bootloader': 0x1000,
'partitions': 0x8000,
'boot_app0': 0xE000,
'firmware': 0x10000
}
elif esp_type == 'ESP32-S3':
# ESP32-S3: Bootloader at 0x0000, no boot_app0
return {
'bootloader': 0x0000,
'partitions': 0x8000,
'firmware': 0x10000
}
else:
# ESP32 Classic: Bootloader at 0x1000, boot_app0 at 0xE000
return {
'bootloader': 0x1000,
'partitions': 0x8000,
'boot_app0': 0xE000,
'firmware': 0x10000
}
def get_firmware_version():
"""Get firmware version from git"""
try:
result = subprocess.run(["git", "describe", "--tags", "--dirty"],
stdout=subprocess.PIPE, text=True,
cwd=env.subst("$PROJECT_DIR"))
if result.returncode == 0:
version = result.stdout.strip()
# Clean up version string
version = version.replace('Release', '').replace('release', '')
return version
except:
pass
return "dev"
def create_merged_firmware(source, target, env):
"""Main function called after firmware build"""
# Get build info
project_dir = Path(env.subst("$PROJECT_DIR"))
build_dir = Path(env.subst("$BUILD_DIR"))
env_name = env.subst("$PIOENV")
version = get_firmware_version()
print(f"\n🔨 Building firmware files for {env_name}...")
# File paths in build directory
bootloader_file = build_dir / "bootloader.bin"
partitions_file = build_dir / "partitions.bin"
boot_app0_file = build_dir / "boot_app0.bin"
firmware_file = build_dir / "firmware.bin"
# Check if firmware exists
if not firmware_file.exists():
print(f"❌ Firmware file not found: {firmware_file}")
return
# Auto-detect ESP32 type
esp_type = detect_esp32_type(bootloader_file) if bootloader_file.exists() else 'ESP32'
addresses = get_memory_layout(esp_type)
print(f"📱 Detected: {esp_type} (bootloader at 0x{addresses['bootloader']:04X})")
# Output directory with version subfolder
version_dir = project_dir / "firmware" / version
version_dir.mkdir(parents=True, exist_ok=True)
# Output filenames (simplified names)
factory_file = version_dir / f"{env_name}_factory.bin"
update_file = version_dir / f"{env_name}_firmware.bin"
# 1. Create update file (just copy firmware.bin)
try:
import shutil
shutil.copy2(firmware_file, update_file)
print(f"✅ Firmware: {update_file.name}")
except Exception as e:
print(f"❌ Error creating firmware file: {e}")
return
# 2. Create factory file (merged)
try:
# Create merged binary - 4MB filled with 0xFF
merged_size = 0x400000 # 4MB
merged_data = bytearray([0xFF] * merged_size)
max_address = 0
# Files to merge
files_to_merge = {
'bootloader': bootloader_file,
'partitions': partitions_file,
'firmware': firmware_file
}
# Add boot_app0 for ESP32 Classic and S2
if 'boot_app0' in addresses:
files_to_merge['boot_app0'] = boot_app0_file
# Merge files at their respective addresses
for file_type, file_path in files_to_merge.items():
if file_path.exists():
address = addresses[file_type]
with open(file_path, 'rb') as f:
data = f.read()
print(f" 📄 {file_type} at 0x{address:06X}: {len(data)} bytes")
if address + len(data) <= merged_size:
merged_data[address:address+len(data)] = data
max_address = max(max_address, address + len(data))
else:
print(f"⚠️ Warning: {file_type} too large, truncating")
remaining = merged_size - address
merged_data[address:address+remaining] = data[:remaining]
max_address = merged_size
else:
print(f"⚠️ Warning: {file_type} not found: {file_path}")
# Find actual end of data (round up to 4K boundary)
actual_end = ((max_address + 4095) // 4096) * 4096
# Write factory file
with open(factory_file, 'wb') as f:
f.write(merged_data[:actual_end])
print(f"✅ Factory: {factory_file.name} ({actual_end} bytes)")
except Exception as e:
print(f"❌ Error creating factory file: {e}")
# Add post-build hook
env.AddPostAction("$BUILD_DIR/firmware.bin", create_merged_firmware)

View File

@@ -13,12 +13,16 @@
#include "monitor.h"
#include "drivers/displays/display.h"
#include "drivers/storage/SDCard.h"
#include "ShaTests/nerdSHA_HWTest.h"
#include "timeconst.h"
#ifdef TOUCH_ENABLE
#include "TouchHandler.h"
#endif
#include <soc/soc_caps.h>
//#define HW_SHA256_TEST
//3 seconds WDT
#define WDT_TIMEOUT 3
//15 minutes WDT for miner task
@@ -51,6 +55,7 @@ const char* ntpServer = "pool.ntp.org";
//void runMonitor(void *name);
/********* INIT *****/
void setup()
{
@@ -74,6 +79,10 @@ void setup()
disableCore0WDT();
//disableCore1WDT();
#ifdef HW_SHA256_TEST
while (1) HwShaTest();
#endif
// Setup the buttons
#if defined(PIN_BUTTON_1) && !defined(PIN_BUTTON_2) //One button device
button1.setPressMs(5*SECOND_MS);
@@ -123,15 +132,15 @@ void setup()
Serial.println("Initiating tasks...");
char *name = (char*) malloc(32);
sprintf(name, "(%s)", "Monitor");
BaseType_t res1 = xTaskCreatePinnedToCore(runMonitor, "Monitor", 10000, (void*)name, 4, NULL,1);
BaseType_t res1 = xTaskCreatePinnedToCore(runMonitor, "Monitor", 10000, (void*)name, 5, NULL,1);
/******** CREATE STRATUM TASK *****/
sprintf(name, "(%s)", "Stratum");
#if defined(ESP32_2432S028R) || defined(ESP32_2432S028_2USB)
// Free a little bit of the heap to the screen
BaseType_t res2 = xTaskCreatePinnedToCore(runStratumWorker, "Stratum", 13500, (void*)name, 3, NULL,1);
BaseType_t res2 = xTaskCreatePinnedToCore(runStratumWorker, "Stratum", 13500, (void*)name, 4, NULL,1);
#else
BaseType_t res2 = xTaskCreatePinnedToCore(runStratumWorker, "Stratum", 15000, (void*)name, 3, NULL,1);
BaseType_t res2 = xTaskCreatePinnedToCore(runStratumWorker, "Stratum", 15000, (void*)name, 4, NULL,1);
#endif
/******** CREATE MINER TASKS *****/
@@ -142,11 +151,19 @@ void setup()
// Start mining tasks
//BaseType_t res = xTaskCreate(runWorker, name, 35000, (void*)name, 1, NULL);
TaskHandle_t minerTask1, minerTask2 = NULL;
xTaskCreate(runMiner, "Miner0", 6000, (void*)0, 1, &minerTask1);
xTaskCreate(runMiner, "Miner1", 6000, (void*)1, 1, &minerTask2);
#ifdef HARDWARE_SHA265
xTaskCreate(minerWorkerHw, "MinerHw-0", 4096, (void*)0, 3, &minerTask1);
#else
xTaskCreate(minerWorkerSw, "MinerSw-0", 6000, (void*)0, 1, &minerTask1);
#endif
esp_task_wdt_add(minerTask1);
#if (SOC_CPU_CORES_NUM >= 2)
xTaskCreate(minerWorkerSw, "MinerSw-1", 6000, (void*)1, 1, &minerTask2);
esp_task_wdt_add(minerTask2);
#endif
vTaskPrioritySet(NULL, 4);
/******** MONITOR SETUP *****/
setup_monitor();

View File

@@ -24,6 +24,11 @@
#include <math.h>
#include <string.h>
//#pragma GCC optimize ("Ofast")
//#pragma GCC optimize ("jump-tables")
//#pragma GCC optimize ("tree-switch-conversion")
//#pragma GCC optimize ("no-stack-check")
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#ifndef PUT_UINT32_BE
@@ -101,7 +106,7 @@ void ByteReverseWords(uint32_t* out, const uint32_t* in, uint32_t byteCount)
}
IRAM_ATTR void nerd_mids(nerdSHA256_context* midstate, uint8_t* dataIn)
IRAM_ATTR void nerd_mids(uint32_t* digest, const uint8_t* dataIn)
{
uint32_t A[8] = { 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
@@ -190,26 +195,36 @@ IRAM_ATTR void nerd_mids(nerdSHA256_context* midstate, uint8_t* dataIn)
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
midstate->digest[0] = 0x6A09E667 + A[0];
midstate->digest[1] = 0xBB67AE85 + A[1];
midstate->digest[2] = 0x3C6EF372 + A[2];
midstate->digest[3] = 0xA54FF53A + A[3];
midstate->digest[4] = 0x510E527F + A[4];
midstate->digest[5] = 0x9B05688C + A[5];
midstate->digest[6] = 0x1F83D9AB + A[6];
midstate->digest[7] = 0x5BE0CD19 + A[7];
digest[0] = 0x6A09E667 + A[0];
digest[1] = 0xBB67AE85 + A[1];
digest[2] = 0x3C6EF372 + A[2];
digest[3] = 0xA54FF53A + A[3];
digest[4] = 0x510E527F + A[4];
digest[5] = 0x9B05688C + A[5];
digest[6] = 0x1F83D9AB + A[6];
digest[7] = 0x5BE0CD19 + A[7];
}
IRAM_ATTR bool nerd_sha256d(nerdSHA256_context* midstate, uint8_t* dataIn, uint8_t* doubleHash)
IRAM_ATTR bool nerd_sha256d(nerdSHA256_context* midstate, const uint8_t* dataIn, uint8_t* doubleHash)
{
uint32_t temp1, temp2;
uint8_t temp3, temp4;
uint32_t* buffer32;
//*********** Init 1rst SHA ***********
uint32_t W[16] = { GET_UINT32_BE(dataIn, 0), GET_UINT32_BE(dataIn, 4),
GET_UINT32_BE(dataIn, 8), GET_UINT32_BE(dataIn, 12), 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0,
uint32_t W[64] = {
#if 0
__builtin_bswap32(((const uint32_t*)dataIn)[0]),
__builtin_bswap32(((const uint32_t*)dataIn)[1]),
__builtin_bswap32(((const uint32_t*)dataIn)[2]),
__builtin_bswap32(((const uint32_t*)dataIn)[3]),
#else
GET_UINT32_BE(dataIn, 0),
GET_UINT32_BE(dataIn, 4),
GET_UINT32_BE(dataIn, 8),
GET_UINT32_BE(dataIn, 12),
#endif
0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 640};
uint32_t A[8] = { midstate->digest[0], midstate->digest[1], midstate->digest[2], midstate->digest[3],
@@ -380,12 +395,17 @@ IRAM_ATTR bool nerd_sha256d(nerdSHA256_context* midstate, uint8_t* dataIn, uint8
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(58), K[58]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(59), K[59]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(60), K[60]);
if ((uint32_t)(A[7] & 0xFFFF) != 0x32E7)
{
doubleHash[30] = 0xFF;
return false;
}
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(61), K[61]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
PUT_UINT32_BE(0x5BE0CD19 + A[7], doubleHash, 28);
if(doubleHash[31] !=0 || doubleHash[30] !=0) return false;
#if 1
//Best performance
PUT_UINT32_BE(0x6A09E667 + A[0], doubleHash, 0);
PUT_UINT32_BE(0xBB67AE85 + A[1], doubleHash, 4);
PUT_UINT32_BE(0x3C6EF372 + A[2], doubleHash, 8);
@@ -393,6 +413,332 @@ IRAM_ATTR bool nerd_sha256d(nerdSHA256_context* midstate, uint8_t* dataIn, uint8
PUT_UINT32_BE(0x510E527F + A[4], doubleHash, 16);
PUT_UINT32_BE(0x9B05688C + A[5], doubleHash, 20);
PUT_UINT32_BE(0x1F83D9AB + A[6], doubleHash, 24);
PUT_UINT32_BE(0x5BE0CD19 + A[7], doubleHash, 28);
#endif
#if 0
temp1 = 0x6A09E667 + A[0]; ((uint32_t*)doubleHash)[0] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0xBB67AE85 + A[1]; ((uint32_t*)doubleHash)[1] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x3C6EF372 + A[2]; ((uint32_t*)doubleHash)[2] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0xA54FF53A + A[3]; ((uint32_t*)doubleHash)[3] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x510E527F + A[4]; ((uint32_t*)doubleHash)[4] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x9B05688C + A[5]; ((uint32_t*)doubleHash)[5] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x1F83D9AB + A[6]; ((uint32_t*)doubleHash)[6] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x5BE0CD19 + A[7]; ((uint32_t*)doubleHash)[7] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
#endif
#if 0
temp1 = 0x6A09E667 + A[0]; ((uint32_t*)doubleHash)[0] = __builtin_bswap32(temp1);
temp1 = 0xBB67AE85 + A[1]; ((uint32_t*)doubleHash)[1] = __builtin_bswap32(temp1);
temp1 = 0x3C6EF372 + A[2]; ((uint32_t*)doubleHash)[2] = __builtin_bswap32(temp1);
temp1 = 0xA54FF53A + A[3]; ((uint32_t*)doubleHash)[3] = __builtin_bswap32(temp1);
temp1 = 0x510E527F + A[4]; ((uint32_t*)doubleHash)[4] = __builtin_bswap32(temp1);
temp1 = 0x9B05688C + A[5]; ((uint32_t*)doubleHash)[5] = __builtin_bswap32(temp1);
temp1 = 0x1F83D9AB + A[6]; ((uint32_t*)doubleHash)[6] = __builtin_bswap32(temp1);
temp1 = 0x5BE0CD19 + A[7]; ((uint32_t*)doubleHash)[7] = __builtin_bswap32(temp1);
#endif
#if 0
((uint32_t*)doubleHash)[0] = __builtin_bswap32( (0x6A09E667 + A[0]) );
((uint32_t*)doubleHash)[1] = __builtin_bswap32( (0xBB67AE85 + A[1]) );
((uint32_t*)doubleHash)[2] = __builtin_bswap32( (0x3C6EF372 + A[2]) );
((uint32_t*)doubleHash)[3] = __builtin_bswap32( (0xA54FF53A + A[3]) );
((uint32_t*)doubleHash)[4] = __builtin_bswap32( (0x510E527F + A[4]) );
((uint32_t*)doubleHash)[5] = __builtin_bswap32( (0x9B05688C + A[5]) );
((uint32_t*)doubleHash)[6] = __builtin_bswap32( (0x1F83D9AB + A[6]) );
((uint32_t*)doubleHash)[7] = __builtin_bswap32( (0x5BE0CD19 + A[7]) );
#endif
return true;
}
}
IRAM_ATTR void nerd_sha256_bake(const uint32_t* digest, const uint8_t* dataIn, uint32_t* bake) //15 words
{
bake[0] = GET_UINT32_BE(dataIn, 0);
bake[1] = GET_UINT32_BE(dataIn, 4);
bake[2] = GET_UINT32_BE(dataIn, 8);
//w[3] = GET_UINT32_BE(dataIn, 12);
bake[3] = S1( 0) + 0 + S0(bake[1]) + bake[0];
bake[4] = S1(640) + 0 + S0(bake[2]) + bake[1];
uint32_t* a = bake + 5;
a[0] = digest[0];
a[1] = digest[1];
a[2] = digest[2];
a[3] = digest[3];
a[4] = digest[4];
a[5] = digest[5];
a[6] = digest[6];
a[7] = digest[7];
uint32_t temp1, temp2;
P(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], bake[0], K[0]);
P(a[7], a[0], a[1], a[2], a[3], a[4], a[5], a[6], bake[1], K[1]);
P(a[6], a[7], a[0], a[1], a[2], a[3], a[4], a[5], bake[2], K[2]);
//P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[3], K[3]);
//P(a, b, c, d, e, f, g, h, x, K)
bake[13] = a[4] + S3(a[1]) + F1(a[1], a[2], a[3]) + K[3];// + x;
bake[14] = S2(a[5]) + F0(a[5], a[6], a[7]);
}
IRAM_ATTR bool nerd_sha256d_baked(const uint32_t* digest, const uint8_t* dataIn, const uint32_t* bake, uint8_t* doubleHash)
{
uint32_t temp1, temp2;
//*********** Init 1rst SHA ***********
//W0 W1 W2 is same !!
uint32_t W[64] = { bake[0], bake[1], bake[2], GET_UINT32_BE(dataIn, 12),
0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 640 };
W[16] = bake[3];
W[17] = bake[4];
const uint32_t* a = bake + 5;
uint32_t A[8] = { a[0], a[1], a[2], a[3],
a[4], a[5], a[6], a[7] };
//P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[0], K[0]);
//P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[1], K[1]);
//P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[2], K[2]);
//P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[3], K[3]);
//P(a, b, c, d, e, f, g, h, x, K)
temp1 = bake[13] + W[3];
temp2 = bake[14];
A[0] += temp1;
A[4] = temp1 + temp2;
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[4], K[4]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[5], K[5]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[6], K[6]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[7], K[7]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[8], K[8]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[9], K[9]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[10], K[10]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[11], K[11]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[12], K[12]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[13], K[13]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[14], K[14]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[15], K[15]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[16], K[16]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[17], K[17]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(18), K[18]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(19), K[19]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(20), K[20]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(21), K[21]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(22), K[22]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(23), K[23]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(24), K[24]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(25), K[25]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(26), K[26]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(27), K[27]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(28), K[28]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(29), K[29]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(30), K[30]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(31), K[31]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(32), K[32]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(33), K[33]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(34), K[34]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(35), K[35]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(36), K[36]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(37), K[37]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(38), K[38]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(39), K[39]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(40), K[40]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(41), K[41]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(42), K[42]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(43), K[43]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(44), K[44]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(45), K[45]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(46), K[46]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(47), K[47]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(48), K[48]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(49), K[49]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(50), K[50]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(51), K[51]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(52), K[52]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(53), K[53]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(54), K[54]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(55), K[55]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(56), K[56]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(57), K[57]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(58), K[58]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(59), K[59]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(60), K[60]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(61), K[61]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
//*********** end SHA_finish ***********
/* Calculate the second hash (double SHA-256) */
W[0] = A[0] + digest[0];
W[1] = A[1] + digest[1];
W[2] = A[2] + digest[2];
W[3] = A[3] + digest[3];
W[4] = A[4] + digest[4];
W[5] = A[5] + digest[5];
W[6] = A[6] + digest[6];
W[7] = A[7] + digest[7];
W[8] = 0x80000000;
W[9] = 0;
W[10] = 0;
W[11] = 0;
W[12] = 0;
W[13] = 0;
W[14] = 0;
W[15] = 256;
A[0] = 0x6A09E667;
A[1] = 0xBB67AE85;
A[2] = 0x3C6EF372;
A[3] = 0xA54FF53A;
A[4] = 0x510E527F;
A[5] = 0x9B05688C;
A[6] = 0x1F83D9AB;
A[7] = 0x5BE0CD19;
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[0], K[0]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[1], K[1]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[2], K[2]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[3], K[3]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[4], K[4]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[5], K[5]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[6], K[6]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[7], K[7]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[8], K[8]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[9], K[9]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[10], K[10]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[11], K[11]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[12], K[12]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[13], K[13]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[14], K[14]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[15], K[15]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(16), K[16]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(17), K[17]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(18), K[18]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(19), K[19]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(20), K[20]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(21), K[21]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(22), K[22]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(23), K[23]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(24), K[24]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(25), K[25]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(26), K[26]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(27), K[27]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(28), K[28]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(29), K[29]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(30), K[30]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(31), K[31]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(32), K[32]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(33), K[33]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(34), K[34]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(35), K[35]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(36), K[36]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(37), K[37]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(38), K[38]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(39), K[39]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(40), K[40]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(41), K[41]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(42), K[42]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(43), K[43]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(44), K[44]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(45), K[45]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(46), K[46]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(47), K[47]);
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(48), K[48]);
P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(49), K[49]);
P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(50), K[50]);
P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(51), K[51]);
P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(52), K[52]);
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(53), K[53]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(54), K[54]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(55), K[55]);
//Unroll 56 - worse performace
P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(56), K[56]);
//Unroll 57
//P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(57), K[57]);
//P(a, b, c, d, e, f, g, h, x, K)
uint32_t m1 = A[6] + S3(A[3]) + F1(A[3], A[4], A[5]) + K[57] + R(57);
//uint32_t m2 = S2(A[7]) + F0(A[7], A[0], A[1]);
A[2] += m1;
//A[6] = m1 + m2;
uint32_t d57_a1 = A[1];
//Unroll 58
//P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(58), K[58]);
//P(a, b, c, d, e, f, g, h, x, K)
uint32_t z1 = A[5] + S3(A[2]) + F1(A[2], A[3], A[4]) + K[58] + R(58);
//uint32_t z2 = S2(A[6]) + F0(A[6], A[7], A[0]);
uint32_t d58_a0 = A[0];
A[1] += z1;
//A[5] = z1 + z2;
//Unroll 59
//P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(59), K[59]);
//P(a, b, c, d, e, f, g, h, x, K)
uint32_t t1 = A[4] + S3(A[1]) + F1(A[1], A[2], A[3]) + K[59] + R(59);
//uint32_t t2 = S2(A[5]) + F0(A[5], A[6], A[7]);
A[0] += t1;
//A[4] = t1 + t2;
//Unroll 60
//P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(60), K[60]);
//P(a, b, c, d, e, f, g, h, x, K)
temp1 = A[3] + S3(A[0]) + F1(A[0], A[1], A[2]) + K[60] + R(60);
uint32_t a7 = A[7] + temp1;
if ((uint32_t)(a7 & 0xFFFF) != 0x32E7)
return false;
//Post 57
uint32_t m2 = S2(A[7]) + F0(A[7], d58_a0, d57_a1);
A[6] = m1 + m2;
//Post 58
uint32_t z2 = S2(A[6]) + F0(A[6], A[7], d58_a0);
A[5] = z1 + z2;
//Post 59
uint32_t t2 = S2(A[5]) + F0(A[5], A[6], A[7]);
//uint32_t t2 = S2(A[5]) + F0(A[5], A[6], a7);
A[4] = t1 + t2;
//Post 60
A[7] = a7;
temp2 = S2(A[4]) + F0(A[4], A[5], A[6]);
A[3] = temp1 + temp2;
P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(61), K[61]);
P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(62), K[62]);
P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(63), K[63]);
#if 1
temp1 = 0x6A09E667 + A[0]; ((uint32_t*)doubleHash)[0] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0xBB67AE85 + A[1]; ((uint32_t*)doubleHash)[1] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x3C6EF372 + A[2]; ((uint32_t*)doubleHash)[2] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0xA54FF53A + A[3]; ((uint32_t*)doubleHash)[3] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x510E527F + A[4]; ((uint32_t*)doubleHash)[4] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x9B05688C + A[5]; ((uint32_t*)doubleHash)[5] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x1F83D9AB + A[6]; ((uint32_t*)doubleHash)[6] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
temp1 = 0x5BE0CD19 + A[7]; ((uint32_t*)doubleHash)[7] = (temp1 << 24) | ((temp1 << 8) & 0x00FF0000) | ((temp1 >> 8) & 0x0000FF00) | (temp1 >> 24);
#else
PUT_UINT32_BE(0x6A09E667 + A[0], doubleHash, 0);
PUT_UINT32_BE(0xBB67AE85 + A[1], doubleHash, 4);
PUT_UINT32_BE(0x3C6EF372 + A[2], doubleHash, 8);
PUT_UINT32_BE(0xA54FF53A + A[3], doubleHash, 12);
PUT_UINT32_BE(0x510E527F + A[4], doubleHash, 16);
PUT_UINT32_BE(0x9B05688C + A[5], doubleHash, 20);
PUT_UINT32_BE(0x1F83D9AB + A[6], doubleHash, 24);
PUT_UINT32_BE(0x5BE0CD19 + A[7], doubleHash, 28);
#endif
return true;
}

View File

@@ -25,9 +25,12 @@ struct nerdSHA256_context {
};
/* Calculate midstate */
IRAM_ATTR void nerd_mids(nerdSHA256_context* midstate, uint8_t* dataIn);
IRAM_ATTR void nerd_mids(uint32_t* digest, const uint8_t* dataIn);
IRAM_ATTR bool nerd_sha256d(nerdSHA256_context* midstate, uint8_t* dataIn, uint8_t* doubleHash);
IRAM_ATTR bool nerd_sha256d(nerdSHA256_context* midstate, const uint8_t* dataIn, uint8_t* doubleHash);
IRAM_ATTR void nerd_sha256_bake(const uint32_t* digest, const uint8_t* dataIn, uint32_t* bake); //15 words
IRAM_ATTR bool nerd_sha256d_baked(const uint32_t* digest, const uint8_t* dataIn, const uint32_t* bake, uint8_t* doubleHash);
void ByteReverseWords(uint32_t* out, const uint32_t* in, uint32_t byteCount);

View File

@@ -0,0 +1,531 @@
#ifdef HW_SHA256_TEST
#include <soc/soc.h>
#include "ShaTests/nerdSHA256plus.h"
#include "mbedtls/sha256.h"
#include <sha/sha_dma.h>
#include <sha/sha_parallel_engine.h>
#include <hal/sha_hal.h>
#include <hal/sha_ll.h>
#include <esp_heap_caps.h>
#include <hal/gdma_types.h>
#include <esp_crypto_shared_gdma.h>
#include <driver/periph_ctrl.h>
static const uint8_t s_test_buffer[128] =
{
0x00, 0x00, 0x00, 0x22, 0x99, 0x44, 0xbb, 0xff, 0xbb, 0x00, 0x00, 0x77, 0x44, 0xcc, 0x11, 0x77,
0x88, 0x55, 0xbb, 0x44, 0x55, 0x00, 0x77, 0x88, 0x99, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x66, 0x11, 0x88, 0x33, 0x44, 0x99, 0xcc, 0x33, 0xff, 0x22,
0x11, 0xaa, 0x77, 0xee, 0xbb, 0x66, 0xee, 0xcc, 0xee, 0x66, 0xee, 0xdd, 0x77, 0x55, 0x22, 0x22,
0xcc, 0xcc, 0x66, 0xee, 0x22, 0xdd, 0x99, 0x66, 0x66, 0x88, 0x00, 0x11, 0x2e, 0x33, 0x41, 0x19,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80
};
static const uint8_t s_test_buffer_aligned[128] __attribute__((aligned(256))) =
{
0x00, 0x00, 0x00, 0x22, 0x99, 0x44, 0xbb, 0xff, 0xbb, 0x00, 0x00, 0x77, 0x44, 0xcc, 0x11, 0x77,
0x88, 0x55, 0xbb, 0x44, 0x55, 0x00, 0x77, 0x88, 0x99, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0x66, 0x11, 0x88, 0x33, 0x44, 0x99, 0xcc, 0x33, 0xff, 0x22,
0x11, 0xaa, 0x77, 0xee, 0xbb, 0x66, 0xee, 0xcc, 0xee, 0x66, 0xee, 0xdd, 0x77, 0x55, 0x22, 0x22,
0xcc, 0xcc, 0x66, 0xee, 0x22, 0xdd, 0x99, 0x66, 0x66, 0x88, 0x00, 0x11, 0x2e, 0x33, 0x41, 0x19,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80
};
static uint8_t interResult_aligned[64] __attribute__((aligned(256)));
static uint8_t midstate_aligned[32] __attribute__((aligned(256)));
static uint8_t hash_aligned[64] __attribute__((aligned(256)));
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3)
static inline void nerd_sha_hal_wait_idle()
{
while (REG_READ(SHA_BUSY_REG))
{}
}
static inline void nerd_sha_ll_fill_text_block_sha256(const void *input_text)
{
uint32_t *data_words = (uint32_t *)input_text;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
REG_WRITE(&reg_addr_buf[0], data_words[0]);
REG_WRITE(&reg_addr_buf[1], data_words[1]);
REG_WRITE(&reg_addr_buf[2], data_words[2]);
REG_WRITE(&reg_addr_buf[3], data_words[3]);
REG_WRITE(&reg_addr_buf[4], data_words[4]);
REG_WRITE(&reg_addr_buf[5], data_words[5]);
REG_WRITE(&reg_addr_buf[6], data_words[6]);
REG_WRITE(&reg_addr_buf[7], data_words[7]);
REG_WRITE(&reg_addr_buf[8], data_words[8]);
REG_WRITE(&reg_addr_buf[9], data_words[9]);
REG_WRITE(&reg_addr_buf[10], data_words[10]);
REG_WRITE(&reg_addr_buf[11], data_words[11]);
REG_WRITE(&reg_addr_buf[12], data_words[12]);
REG_WRITE(&reg_addr_buf[13], data_words[13]);
REG_WRITE(&reg_addr_buf[14], data_words[14]);
REG_WRITE(&reg_addr_buf[15], data_words[15]);
}
static inline void nerd_sha_ll_write_digest_sha256(void *digest_state)
{
uint32_t *digest_state_words = (uint32_t *)digest_state;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
REG_WRITE(&reg_addr_buf[0], digest_state_words[0]);
REG_WRITE(&reg_addr_buf[1], digest_state_words[1]);
REG_WRITE(&reg_addr_buf[2], digest_state_words[2]);
REG_WRITE(&reg_addr_buf[3], digest_state_words[3]);
REG_WRITE(&reg_addr_buf[4], digest_state_words[4]);
REG_WRITE(&reg_addr_buf[5], digest_state_words[5]);
REG_WRITE(&reg_addr_buf[6], digest_state_words[6]);
REG_WRITE(&reg_addr_buf[7], digest_state_words[7]);
}
//void IRAM_ATTR esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address, uint32_t num_words)
static inline void nerd_sha_ll_read_digest(void* ptr)
{
DPORT_INTERRUPT_DISABLE();
#if 0
for (uint32_t i = 0; i < 256 / 32; ++i)
{
((uint32_t*)ptr)[i] = DPORT_SEQUENCE_REG_READ(SHA_H_BASE + i * 4);
}
#else
((uint32_t*)ptr)[0] = DPORT_SEQUENCE_REG_READ(SHA_H_BASE + 0 * 4);
((uint32_t*)ptr)[1] = DPORT_SEQUENCE_REG_READ(SHA_H_BASE + 1 * 4);
((uint32_t*)ptr)[2] = DPORT_SEQUENCE_REG_READ(SHA_H_BASE + 2 * 4);
((uint32_t*)ptr)[3] = DPORT_SEQUENCE_REG_READ(SHA_H_BASE + 3 * 4);
((uint32_t*)ptr)[4] = DPORT_SEQUENCE_REG_READ(SHA_H_BASE + 4 * 4);
((uint32_t*)ptr)[5] = DPORT_SEQUENCE_REG_READ(SHA_H_BASE + 5 * 4);
((uint32_t*)ptr)[6] = DPORT_SEQUENCE_REG_READ(SHA_H_BASE + 6 * 4);
((uint32_t*)ptr)[7] = DPORT_SEQUENCE_REG_READ(SHA_H_BASE + 7 * 4);
#endif
DPORT_INTERRUPT_RESTORE();
}
static IRAM_ATTR uint8_t dma_buffer[128] __attribute__((aligned(32)));
static IRAM_ATTR uint8_t dma_inter[64] __attribute__((aligned(32)));
static IRAM_ATTR uint8_t dma_hash[32] __attribute__((aligned(32)));
static DRAM_ATTR lldesc_t s_dma_descr_input;
static DRAM_ATTR lldesc_t s_dma_descr_buf;
static DRAM_ATTR lldesc_t s_dma_descr_inter;
#endif
#if defined(CONFIG_IDF_TARGET_ESP32)
static inline void nerd_sha_ll_read_digest_swap(void* ptr)
{
DPORT_INTERRUPT_DISABLE();
((uint32_t*)ptr)[0] = __builtin_bswap32(DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 0 * 4));
((uint32_t*)ptr)[1] = __builtin_bswap32(DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 1 * 4));
((uint32_t*)ptr)[2] = __builtin_bswap32(DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 2 * 4));
((uint32_t*)ptr)[3] = __builtin_bswap32(DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 3 * 4));
((uint32_t*)ptr)[4] = __builtin_bswap32(DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 4 * 4));
((uint32_t*)ptr)[5] = __builtin_bswap32(DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 5 * 4));
((uint32_t*)ptr)[6] = __builtin_bswap32(DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 6 * 4));
((uint32_t*)ptr)[7] = __builtin_bswap32(DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 7 * 4));
DPORT_INTERRUPT_RESTORE();
}
static inline void nerd_sha_ll_read_digest(void* ptr)
{
DPORT_INTERRUPT_DISABLE();
((uint32_t*)ptr)[0] = DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 0 * 4);
((uint32_t*)ptr)[1] = DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 1 * 4);
((uint32_t*)ptr)[2] = DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 2 * 4);
((uint32_t*)ptr)[3] = DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 3 * 4);
((uint32_t*)ptr)[4] = DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 4 * 4);
((uint32_t*)ptr)[5] = DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 5 * 4);
((uint32_t*)ptr)[6] = DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 6 * 4);
((uint32_t*)ptr)[7] = DPORT_SEQUENCE_REG_READ(SHA_TEXT_BASE + 7 * 4);
DPORT_INTERRUPT_RESTORE();
}
static inline void nerd_sha_hal_wait_idle()
{
while (DPORT_REG_READ(SHA_256_BUSY_REG))
{}
}
static inline void nerd_sha_ll_fill_text_block_sha256(const void *input_text)
{
uint32_t *data_words = (uint32_t *)input_text;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
reg_addr_buf[0] = data_words[0];
reg_addr_buf[1] = data_words[1];
reg_addr_buf[2] = data_words[2];
reg_addr_buf[3] = data_words[3];
reg_addr_buf[4] = data_words[4];
reg_addr_buf[5] = data_words[5];
reg_addr_buf[6] = data_words[6];
reg_addr_buf[7] = data_words[7];
reg_addr_buf[8] = data_words[8];
reg_addr_buf[9] = data_words[9];
reg_addr_buf[10] = data_words[10];
reg_addr_buf[11] = data_words[11];
reg_addr_buf[12] = data_words[12];
reg_addr_buf[13] = data_words[13];
reg_addr_buf[14] = data_words[14];
reg_addr_buf[15] = data_words[15];
}
static inline void nerd_sha_ll_fill_text_block_sha256_swap(const void *input_text)
{
uint32_t *data_words = (uint32_t *)input_text;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
reg_addr_buf[0] = __builtin_bswap32(data_words[0]);
reg_addr_buf[1] = __builtin_bswap32(data_words[1]);
reg_addr_buf[2] = __builtin_bswap32(data_words[2]);
reg_addr_buf[3] = __builtin_bswap32(data_words[3]);
reg_addr_buf[4] = __builtin_bswap32(data_words[4]);
reg_addr_buf[5] = __builtin_bswap32(data_words[5]);
reg_addr_buf[6] = __builtin_bswap32(data_words[6]);
reg_addr_buf[7] = __builtin_bswap32(data_words[7]);
reg_addr_buf[8] = __builtin_bswap32(data_words[8]);
reg_addr_buf[9] = __builtin_bswap32(data_words[9]);
reg_addr_buf[10] = __builtin_bswap32(data_words[10]);
reg_addr_buf[11] = __builtin_bswap32(data_words[11]);
reg_addr_buf[12] = __builtin_bswap32(data_words[12]);
reg_addr_buf[13] = __builtin_bswap32(data_words[13]);
reg_addr_buf[14] = __builtin_bswap32(data_words[14]);
reg_addr_buf[15] = __builtin_bswap32(data_words[15]);
}
static inline void nerd_sha_ll_fill_text_block_sha256_double(const void *input_text)
{
uint32_t *data_words = (uint32_t *)input_text;
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
#if 0
//No change
reg_addr_buf[0] = data_words[0];
reg_addr_buf[1] = data_words[1];
reg_addr_buf[2] = data_words[2];
reg_addr_buf[3] = data_words[3];
reg_addr_buf[4] = data_words[4];
reg_addr_buf[5] = data_words[5];
reg_addr_buf[6] = data_words[6];
reg_addr_buf[7] = data_words[7];
#endif
reg_addr_buf[8] = 0x80000000;
reg_addr_buf[9] = 0x00000000;
reg_addr_buf[10] = 0x00000000;
reg_addr_buf[11] = 0x00000000;
reg_addr_buf[12] = 0x00000000;
reg_addr_buf[13] = 0x00000000;
reg_addr_buf[14] = 0x00000000;
reg_addr_buf[15] = 0x00000100;
}
#endif
IRAM_ATTR void HwShaTest()
{
uint8_t interResult[64];
uint8_t midstate[32];
uint8_t hash[64];
memset(interResult, 0, sizeof(interResult));
interResult[32] = 0x80;
interResult[62] = 0x01;
interResult[63] = 0x00;
memset(interResult_aligned, 0, sizeof(interResult_aligned));
interResult_aligned[32] = 0x80;
interResult_aligned[62] = 0x01;
interResult_aligned[63] = 0x00;
uint32_t bake[16];
uint32_t time_start = micros();
int test_count = 1000000;
#if 0
//Generic software
//esp32s3 16KH/s
//esp32D 9.5KH/s
test_count = 20000;
mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx);
for (int i = 0; i < test_count; ++i)
{
mbedtls_sha256_starts_ret(&ctx,0);
mbedtls_sha256_update_ret(&ctx, s_test_buffer, 80);
mbedtls_sha256_finish_ret(&ctx, interResult);
mbedtls_sha256_starts_ret(&ctx,0);
mbedtls_sha256_update_ret(&ctx, interResult, 32);
mbedtls_sha256_finish_ret(&ctx, hash);
}
mbedtls_sha256_free(&ctx);
#endif
#if 1
//nerdSha256
//ESP32 39KH/s
//ESP32S3 39.01KH/s
test_count = 100000;
nerdSHA256_context ctx;
nerd_mids(ctx.digest, s_test_buffer);
for (int i = 0; i < test_count; ++i)
{
nerd_sha256d(&ctx, s_test_buffer+64, hash);
}
#endif
#if 0
//nerdSha256 bake
//ESP32 : 41KH/s
//ESP32S3 : 42.32KH/s
test_count = 100000;
nerdSHA256_context ctx;
nerd_mids(&ctx, s_test_buffer);
nerd_sha256_bake(ctx.digest, s_test_buffer+64, bake); //15 words
for (int i = 0; i < test_count; ++i)
{
nerd_sha256d_baked(ctx.digest, s_test_buffer+64, bake, hash);
}
#endif
#if 0
//Hardware high level 62KH/s
esp_sha_acquire_hardware();
for (int i = 0; i < test_count; ++i)
{
esp_sha_dma(SHA2_256, s_test_buffer+64, 64, s_test_buffer, 64, true);
esp_sha_read_digest_state(SHA2_256, interResult);
esp_sha_dma(SHA2_256, 0, 0, interResult, 64, true);
esp_sha_read_digest_state(SHA2_256, hash);
}
esp_sha_release_hardware();
#endif
#if 0
//ESP32D 5.50KH/s
test_count = 40000;
//esp_sha_lock_engine(SHA2_256);
for (int i = 0; i < test_count; ++i)
{
esp_sha(SHA2_256, s_test_buffer, 80, interResult);
esp_sha(SHA2_256, interResult, 32, hash);
}
//esp_sha_unlock_engine(SHA2_256);
#endif
#if 0
//ESP32D
//Invalid result!!
test_count = 100000;
esp_sha_lock_engine(SHA2_256);
for (int i = 0; i < test_count; ++i)
{
esp_sha_block(SHA2_256, s_test_buffer, true);
esp_sha_block(SHA2_256, s_test_buffer+64, false);
esp_sha_read_digest_state(SHA2_256, interResult);
esp_sha_block(SHA2_256, interResult, true);
esp_sha_read_digest_state(SHA2_256, hash);
}
esp_sha_unlock_engine(SHA2_256);
#endif
#if 0
//ESP32D Hardware SHA ~200KH/s
test_count = 50000;
periph_module_enable(PERIPH_SHA_MODULE);
uint8_t buffer_swap[128];
for (int i = 0; i < 32; ++i)
((uint32_t*)buffer_swap)[i] = __builtin_bswap32(((const uint32_t*)s_test_buffer)[i]);
uint8_t inter_swap[64];
for (int i = 0; i < 16; ++i)
((uint32_t*)inter_swap)[i] = __builtin_bswap32(((const uint32_t*)interResult)[i]);
for (int i = 0; i < test_count; ++i)
{
//sha_hal_hash_block(SHA2_256, s_test_buffer, 64/4, true);
nerd_sha_hal_wait_idle();
nerd_sha_ll_fill_text_block_sha256(buffer_swap);
sha_ll_start_block(SHA2_256);
//sha_hal_hash_block(SHA2_256, s_test_buffer+64, 64/4, false);
nerd_sha_hal_wait_idle();
nerd_sha_ll_fill_text_block_sha256(buffer_swap+64);
sha_ll_continue_block(SHA2_256);
nerd_sha_hal_wait_idle();
sha_ll_load(SHA2_256);
//nerd_sha_ll_read_digest_swap(interResult);
//sha_hal_hash_block(SHA2_256, interResult, 64/4, true);
nerd_sha_hal_wait_idle();
nerd_sha_ll_fill_text_block_sha256_double(inter_swap);
sha_ll_start_block(SHA2_256);
nerd_sha_hal_wait_idle();
sha_ll_load(SHA2_256);
nerd_sha_ll_read_digest_swap(hash);
}
#endif
#if 0
//Hardware low level + midstate 156KH/s
esp_sha_acquire_hardware();
sha_hal_hash_block(SHA2_256, s_test_buffer, 64/4, true);
sha_hal_read_digest(SHA2_256, midstate);
for (int i = 0; i < test_count; ++i)
{
sha_hal_write_digest(SHA2_256, midstate);
sha_hal_hash_block(SHA2_256, s_test_buffer+64, 64/4, false);
sha_hal_read_digest(SHA2_256, interResult);
sha_hal_hash_block(SHA2_256, interResult, 64/4, true);
sha_hal_read_digest(SHA2_256, hash);
}
esp_sha_release_hardware();
#endif
#if 0
//Hardware low level + midstate + aligned 156KH/s (No sense)
esp_sha_acquire_hardware();
sha_hal_hash_block(SHA2_256, s_test_buffer_aligned, 64/4, true);
sha_hal_read_digest(SHA2_256, midstate_aligned);
for (int i = 0; i < test_count; ++i)
{
sha_hal_write_digest(SHA2_256, midstate_aligned);
sha_hal_hash_block(SHA2_256, s_test_buffer_aligned+64, 64/4, false);
sha_hal_read_digest(SHA2_256, interResult_aligned);
sha_hal_hash_block(SHA2_256, interResult_aligned, 64/4, true);
sha_hal_read_digest(SHA2_256, hash_aligned);
}
esp_sha_release_hardware();
memcpy(hash, hash_aligned, sizeof(hash_aligned));
#endif
#if 0
//Hardware LL 162.43KH/s
esp_sha_acquire_hardware();
//sha_hal_hash_block(SHA2_256, s_test_buffer, 64/4, true);
sha_hal_wait_idle();
sha_ll_fill_text_block(s_test_buffer, 64/4);
sha_ll_start_block(SHA2_256);
//sha_hal_read_digest(SHA2_256, midstate);
sha_ll_load(SHA2_256);
sha_hal_wait_idle();
sha_ll_read_digest(SHA2_256, midstate, 256 / 32);
for (int i = 0; i < test_count; ++i)
{
//sha_hal_write_digest(SHA2_256, midstate);
sha_ll_write_digest(SHA2_256, midstate, 256 / 32);
//nerd_sha_ll_write_digest_sha256(midstate);
//sha_hal_hash_block(SHA2_256, s_test_buffer+64, 64/4, false);
//sha_hal_wait_idle();
nerd_sha_hal_wait_idle();
//sha_ll_fill_text_block(s_test_buffer+64, 64/4);
nerd_sha_ll_fill_text_block_sha256(s_test_buffer+64);
sha_ll_continue_block(SHA2_256);
//sha_hal_read_digest(SHA2_256, interResult);
sha_ll_load(SHA2_256);
//sha_hal_wait_idle();
nerd_sha_hal_wait_idle();
//sha_ll_read_digest(SHA2_256, interResult, 256 / 32);
nerd_sha_ll_read_digest(interResult);
//sha_hal_hash_block(SHA2_256, interResult, 64/4, true);
//sha_hal_wait_idle();
nerd_sha_hal_wait_idle();
//sha_ll_fill_text_block(interResult, 64/4);
nerd_sha_ll_fill_text_block_sha256(interResult);
sha_ll_start_block(SHA2_256);
//sha_hal_read_digest(SHA2_256, hash);
sha_ll_load(SHA2_256);
//sha_hal_wait_idle();
nerd_sha_hal_wait_idle();
//sha_ll_read_digest(SHA2_256, hash, 256 / 32);
nerd_sha_ll_read_digest(hash);
}
esp_sha_release_hardware();
#endif
#if 0
//DMA hash
uint8_t* dma_cap_buf = (uint8_t*)heap_caps_malloc(128, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
memcpy(dma_cap_buf, s_test_buffer, 128);
uint8_t* dma_cap_inter = (uint8_t*)heap_caps_malloc(64, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
memcpy(dma_cap_inter, interResult, 64);
uint8_t* dma_cap_hash = (uint8_t*)heap_caps_malloc(32, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
memset(&s_dma_descr_input, 0, sizeof(lldesc_t));
memset(&s_dma_descr_buf, 0, sizeof(lldesc_t));
memset(&s_dma_descr_inter, 0, sizeof(lldesc_t));
s_dma_descr_input.length = 64;
s_dma_descr_input.size = 64;
s_dma_descr_input.owner = 1;
s_dma_descr_input.eof = 1;
s_dma_descr_input.buf = dma_cap_buf+64;
s_dma_descr_buf.length = 64;
s_dma_descr_buf.size = 64;
s_dma_descr_buf.owner = 1;
s_dma_descr_buf.buf = dma_cap_buf;
s_dma_descr_buf.eof = 0;
s_dma_descr_buf.empty = (uint32_t)(&s_dma_descr_input);
s_dma_descr_inter.length = 64;
s_dma_descr_inter.size = 64;
s_dma_descr_inter.owner = 1;
s_dma_descr_inter.buf = dma_cap_inter;
s_dma_descr_inter.eof = 1;
//49.83KH/s
esp_sha_acquire_hardware();
for (int i = 0; i < test_count; ++i)
{
esp_crypto_shared_gdma_start(&s_dma_descr_buf, NULL, GDMA_TRIG_PERIPH_SHA);
sha_hal_hash_dma(SHA2_256, 2, true);
sha_hal_wait_idle();
esp_sha_read_digest_state(SHA2_256, dma_cap_inter);
esp_crypto_shared_gdma_start(&s_dma_descr_inter, NULL, GDMA_TRIG_PERIPH_SHA);
sha_hal_hash_dma(SHA2_256, 1, true);
sha_hal_wait_idle();
esp_sha_read_digest_state(SHA2_256, hash);
}
esp_sha_release_hardware();
#endif
uint32_t time_end = micros();
double hash_rate = ((double)test_count * 1000000) / (double)(time_end - time_start);
Serial.print("Hashrate=");
Serial.print(hash_rate/1000);
Serial.println("KH/s");
Serial.print("interResult: ");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", interResult[i]);
Serial.println("");
Serial.print("hash: ");
for (size_t i = 0; i < 32; i++)
Serial.printf("%02x", hash[i]);
Serial.println("");
//should be
//54cd9f1ebc3db9a626688e5bb91d808abbd4079b2cba7f43fa08bfced300ef19
//6fa464b007f2d577edfa5dfe9dfc3f9209f36d1a6711d314ea68ccdd03000000
}
#endif

View File

@@ -0,0 +1,5 @@
#ifdef HW_SHA256_TEST
IRAM_ATTR void HwShaTest();
#endif

184
src/i2c_master.cpp Normal file
View File

@@ -0,0 +1,184 @@
#include "i2c_master.h"
#include <Arduino.h>
#include <driver/i2c.h>
#define I2C_MASTER_NUM_PORT 0
#define PIN_I2C_SDA 21
#define PIN_I2C_SCL 22
#define I2C_MASTER_TX_BUF_LEN 1024
#define I2C_MASTER_RX_BUF_LEN 1024
static i2c_config_t s_i2c_config;
#define I2C_CMD_FEED 0xA1
#define I2C_CMD_REQUEST_RESULT 0xA9
#define I2C_CMD_SLAVE_RESULT 0xAA
struct __attribute__((__packed__)) JobI2cRequest
{
//84 bytes
uint8_t cmd;
uint8_t crc;
uint8_t id;
uint8_t nonce_start;
float difficulty;
uint8_t buffer[76];
};
struct __attribute__((__packed__)) JobI2cResult
{
//11 bytes
uint8_t cmd;
uint8_t crc;
uint8_t id;
uint32_t nonce;
uint32_t processed_nonce;
};
const uint8_t s_crc8_table[256] =
{
0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97,
0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E,
0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4,
0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D,
0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11,
0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8,
0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52,
0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB,
0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA,
0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13,
0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9,
0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50,
0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C,
0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95,
0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F,
0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6,
0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED,
0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54,
0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE,
0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17,
0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B,
0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2,
0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28,
0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91,
0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0,
0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69,
0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93,
0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A,
0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56,
0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF,
0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15,
0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC
};
static uint8_t CommandCrc8(const void* data, size_t len)
{
const uint8_t* ptr = (const uint8_t*)data;
uint8_t crc = 0xFF;
crc = s_crc8_table[crc ^ ptr[0]];
for (size_t n = 2; n < len; ++n)
crc = s_crc8_table[crc ^ ptr[n]];
return crc;
}
int i2c_master_start()
{
memset(&s_i2c_config, 0, sizeof(s_i2c_config));
s_i2c_config.mode = I2C_MODE_MASTER;
s_i2c_config.sda_io_num = PIN_I2C_SDA;
s_i2c_config.scl_io_num = PIN_I2C_SCL;
s_i2c_config.sda_pullup_en = GPIO_PULLUP_ENABLE;
s_i2c_config.scl_pullup_en = GPIO_PULLUP_ENABLE;
s_i2c_config.master.clk_speed = 50000;
esp_err_t err = i2c_param_config(I2C_MASTER_NUM_PORT, &s_i2c_config);
if (err != ESP_OK)
return err;
return i2c_driver_install(I2C_MASTER_NUM_PORT, s_i2c_config.mode, I2C_MASTER_TX_BUF_LEN, I2C_MASTER_RX_BUF_LEN, 0);
}
std::vector<uint8_t> i2c_master_scan(uint8_t start, uint8_t end)
{
std::vector<uint8_t> vec;
for (int addr = start; addr < end; ++addr)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, true);
//i2c_master_write(cmd, data_wr, size, true);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM_PORT, cmd, 50 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_OK)
vec.push_back(addr);
}
return vec;
}
void i2c_feed_slaves(const std::vector<uint8_t>& slaves, uint8_t id, uint8_t nonce_start, float difficulty, const uint8_t* buffer)
{
JobI2cRequest request;
request.cmd = I2C_CMD_FEED;
request.id = id;
request.difficulty = difficulty;
memcpy(request.buffer, buffer, sizeof(request.buffer));
for (size_t n = 0; n < slaves.size(); ++n)
{
request.nonce_start = nonce_start;
nonce_start += 0x10;
request.crc = CommandCrc8(&request, sizeof(request));
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (slaves[n] << 1) | I2C_MASTER_WRITE, true);
i2c_master_write(cmd, (const uint8_t*)&request, sizeof(request), true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_MASTER_NUM_PORT, cmd, 5 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
}
}
void i2c_hit_slaves(const std::vector<uint8_t>& slaves)
{
uint8_t request[2];
request[0] = I2C_CMD_REQUEST_RESULT;
request[1] = CommandCrc8(request, 2);
for (size_t n = 0; n < slaves.size(); ++n)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (slaves[n] << 1) | I2C_MASTER_WRITE, true);
i2c_master_write(cmd, request, sizeof(request), true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_MASTER_NUM_PORT, cmd, 5 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
}
}
std::vector<uint32_t> i2c_harvest_slaves(const std::vector<uint8_t>& slaves, uint8_t id, uint32_t &total_procesed_nonce)
{
std::vector<uint32_t> nonce_vector;
JobI2cResult result;
for (size_t n = 0; n < slaves.size(); ++n)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (slaves[n] << 1) | I2C_MASTER_READ, true);
i2c_master_read(cmd, (uint8_t*)&result, sizeof(result), I2C_MASTER_LAST_NACK);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_MASTER_NUM_PORT, cmd, 5 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
uint8_t crc = CommandCrc8(&result, sizeof(result));
if (crc != result.crc)
continue;
if (result.nonce != 0xFFFFFFFF)
nonce_vector.push_back(result.nonce);
total_procesed_nonce += result.processed_nonce;
}
return nonce_vector;
}

9
src/i2c_master.h Normal file
View File

@@ -0,0 +1,9 @@
#include <stdint.h>
#include <vector>
#pragma once
int i2c_master_start();
std::vector<uint8_t> i2c_master_scan(uint8_t start, uint8_t end);
void i2c_feed_slaves(const std::vector<uint8_t>& slaves, uint8_t id, uint8_t nonce_start, float difficulty, const uint8_t* buffer);
void i2c_hit_slaves(const std::vector<uint8_t>& slaves);
std::vector<uint32_t> i2c_harvest_slaves(const std::vector<uint8_t>& slaves, uint8_t id, uint32_t &total_procesed_nonce);

File diff suppressed because it is too large Load Diff

View File

@@ -6,15 +6,24 @@
#define MAX_NONCE_STEP 5000000U
#define MAX_NONCE 25000000U
#define TARGET_NONCE 471136297U
#define DEFAULT_DIFFICULTY 1e-4
#define DEFAULT_DIFFICULTY 0.00015
#define KEEPALIVE_TIME_ms 30000
#define POOLINACTIVITY_TIME_ms 60000
//#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3)
#define HARDWARE_SHA265
//#endif
#define TARGET_BUFFER_SIZE 64
void runMonitor(void *name);
void runStratumWorker(void *name);
void runMiner(void *name);
void minerWorkerSw(void * task_id);
void minerWorkerHw(void * task_id);
String printLocalTime(void);
void resetStat();
@@ -23,13 +32,8 @@ typedef struct{
uint8_t bytearray_target[32];
uint8_t bytearray_pooltarget[32];
uint8_t merkle_result[32];
uint8_t bytearray_blockheader[80];
uint8_t bytearray_blockheader2[80];
double poolDifficulty;
bool inRun;
bool newJob;
bool newJob2;
}miner_data;
uint8_t bytearray_blockheader[128];
} miner_data;
#endif // UTILS_API_H

View File

@@ -4,6 +4,7 @@
#include "HTTPClient.h"
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <list>
#include "mining.h"
#include "utils.h"
#include "monitor.h"
@@ -156,6 +157,8 @@ String getBTCprice(void){
if (WiFi.status() != WL_CONNECTED) return "$" + String(bitcoin_price);
HTTPClient http;
bool priceUpdated = false;
try {
http.begin(getBTCAPI);
int httpCode = http.GET();
@@ -166,9 +169,7 @@ String getBTCprice(void){
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
if (doc.containsKey("bpi") && doc["bpi"].containsKey("USD")) {
bitcoin_price = doc["bpi"]["USD"]["rate_float"].as<unsigned int>();
}
if (doc.containsKey("last_trade_price")) bitcoin_price = doc["last_trade_price"];
doc.clear();
@@ -238,9 +239,69 @@ String getTime(void){
return LocalHour;
}
enum EHashRateScale
{
HashRateScale_99KH,
HashRateScale_999KH,
HashRateScale_9MH
};
static EHashRateScale s_hashrate_scale = HashRateScale_99KH;
static uint32_t s_skip_first = 3;
static double s_top_hashrate = 0.0;
static std::list<double> s_hashrate_avg_list;
static double s_hashrate_summ = 0.0;
static uint8_t s_hashrate_recalc = 0;
String getCurrentHashRate(unsigned long mElapsed)
{
return String((1.0 * (elapsedKHs * 1000)) / mElapsed, 2);
double hashrate = (double)elapsedKHs * 1000.0 / (double)mElapsed;
s_hashrate_summ += hashrate;
s_hashrate_avg_list.push_back(hashrate);
if (s_hashrate_avg_list.size() > 10)
{
s_hashrate_summ -= s_hashrate_avg_list.front();
s_hashrate_avg_list.pop_front();
}
++s_hashrate_recalc;
if (s_hashrate_recalc == 0)
{
s_hashrate_summ = 0.0;
for (auto itt = s_hashrate_avg_list.begin(); itt != s_hashrate_avg_list.end(); ++itt)
s_hashrate_summ += *itt;
}
double avg_hashrate = s_hashrate_summ / (double)s_hashrate_avg_list.size();
if (avg_hashrate < 0.0)
avg_hashrate = 0.0;
if (s_skip_first > 0)
{
s_skip_first--;
} else
{
if (avg_hashrate > s_top_hashrate)
{
s_top_hashrate = avg_hashrate;
if (avg_hashrate > 999.9)
s_hashrate_scale = HashRateScale_9MH;
else if (avg_hashrate > 99.9)
s_hashrate_scale = HashRateScale_999KH;
}
}
switch (s_hashrate_scale)
{
case HashRateScale_99KH:
return String(avg_hashrate, 2);
case HashRateScale_999KH:
return String(avg_hashrate, 1);
default:
return String((int)avg_hashrate );
}
}
mining_data getMiningData(unsigned long mElapsed)
@@ -251,11 +312,13 @@ mining_data getMiningData(unsigned long mElapsed)
suffix_string(best_diff, best_diff_string, 16, 0);
char timeMining[15] = {0};
uint64_t secElapsed = upTime + (esp_timer_get_time() / 1000000);
int days = secElapsed / 86400;
int hours = (secElapsed - (days * 86400)) / 3600; // Number of seconds in an hour
int mins = (secElapsed - (days * 86400) - (hours * 3600)) / 60; // Remove the number of hours and calculate the minutes.
int secs = secElapsed - (days * 86400) - (hours * 3600) - (mins * 60);
uint64_t tm = upTime;
int secs = tm % 60;
tm /= 60;
int mins = tm % 60;
tm /= 60;
int hours = tm % 24;
int days = tm / 24;
sprintf(timeMining, "%01d %02d:%02d:%02d", days, hours, mins, secs);
data.completedShares = shares;

View File

@@ -14,7 +14,8 @@
//API BTC price (Update to USDT cus it's more liquidity and flow price updade)
#define getBTCAPI "https://api.coindesk.com/v1/bpi/currentprice.json"
//#define getBTCAPI "https://api.coindesk.com/v1/bpi/currentprice.json" -- doesn't work anymore
#define getBTCAPI "https://api.blockchain.com/v3/exchange/tickers/BTC-USDT"
#define UPDATE_BTC_min 1

View File

@@ -205,13 +205,14 @@ bool parse_mining_notify(String line, mining_job& mJob)
}
bool tx_mining_submit(WiFiClient& client, mining_subscribe mWorker, mining_job mJob, unsigned long nonce)
bool tx_mining_submit(WiFiClient& client, mining_subscribe mWorker, mining_job mJob, unsigned long nonce, unsigned long &submit_id)
{
char payload[BUFFER] = {0};
// Submit
id = getNextId(id);
sprintf(payload, "{\"id\": %u, \"method\": \"mining.submit\", \"params\": [\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"]}\n",
submit_id = id;
sprintf(payload, "{\"id\":%u,\"method\":\"mining.submit\",\"params\":[\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"]}\n",
id,
mWorker.wName,//"bc1qvv469gmw4zz6qa4u4dsezvrlmqcqszwyfzhgwj", //mWorker.name,
mJob.job_id.c_str(),
@@ -247,9 +248,24 @@ bool tx_suggest_difficulty(WiFiClient& client, double difficulty)
char payload[BUFFER] = {0};
id = getNextId(id);
sprintf(payload, "{\"id\": %d, \"method\": \"mining.suggest_difficulty\", \"params\": [%.10g]}\n", id, difficulty);
sprintf(payload, "{\"id\":%d,\"method\":\"mining.suggest_difficulty\",\"params\":[%.10g]}\n", id, difficulty);
Serial.print(" Sending : "); Serial.print(payload);
return client.print(payload);
}
unsigned long parse_extract_id(const String &line)
{
DeserializationError error = deserializeJson(doc, line);
if (error)
return 0;
if (!doc.containsKey("id"))
return 0;
unsigned long id = doc["id"];
return id;
}

View File

@@ -60,11 +60,12 @@ stratum_method parse_mining_method(String line);
bool parse_mining_notify(String line, mining_job& mJob);
//Method Mining.submit
bool tx_mining_submit(WiFiClient& client, mining_subscribe mWorker, mining_job mJob, unsigned long nonce);
bool tx_mining_submit(WiFiClient& client, mining_subscribe mWorker, mining_job mJob, unsigned long nonce, unsigned long &submit_id);
//Difficulty Methods
bool tx_suggest_difficulty(WiFiClient& client, double difficulty);
bool parse_mining_set_difficulty(String line, double& difficulty);
unsigned long parse_extract_id(const String &line);
#endif // STRATUM_API_H

View File

@@ -79,23 +79,23 @@ static const double truediffone = 2695953529101130949315647634472399133601089873
/* Converts a little endian 256 bit value to a double */
double le256todouble(const void *target)
{
const uint8_t *byte_target = static_cast<const uint8_t*>(target); // Convert to byte pointer
uint64_t *data64;
double dcut64;
data64 = (uint64_t *)(byte_target + 24);
dcut64 = *data64 * 6277101735386680763835789423207666416102355444464034512896.0;
const uint64_t *data64;
double dcut64;
data64 = (uint64_t *)(byte_target + 16);
dcut64 += *data64 * 340282366920938463463374607431768211456.0;
data64 = (const uint64_t *)((const uint8_t*)target + 24);
dcut64 = *data64 * 6277101735386680763835789423207666416102355444464034512896.0;
data64 = (uint64_t *)(byte_target + 8);
dcut64 += *data64 * 18446744073709551616.0;
data64 = (const uint64_t *)((const uint8_t*)target + 16);
dcut64 += *data64 * 340282366920938463463374607431768211456.0;
data64 = (uint64_t *)(byte_target);
dcut64 += *data64;
data64 = (const uint64_t *)((const uint8_t*)target + 8);
dcut64 += *data64 * 18446744073709551616.0;
return dcut64;
data64 = (const uint64_t *)(target);
dcut64 += *data64;
return dcut64;
}
double diff_from_target(void *target)
@@ -109,6 +109,16 @@ double diff_from_target(void *target)
return d64 / dcut64;
}
bool isSha256Valid(const void* sha256)
{
for(uint8_t i=0; i < 8; ++i)
{
if ( ((const uint32_t*)sha256)[i] != 0 )
return true;
}
return false;
}
/****************** PREMINING CALCULATIONS ********************/
@@ -172,12 +182,7 @@ void getNextExtranonce2(int extranonce2_size, char *extranonce2) {
miner_data init_miner_data(void){
miner_data newMinerData;
newMinerData.poolDifficulty = DEFAULT_DIFFICULTY;
newMinerData.inRun = false;
newMinerData.newJob = false;
miner_data newMinerData;
return newMinerData;
}
@@ -205,10 +210,20 @@ miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob){
// get extranonce2 - extranonce2 = hex(random.randint(0,2**32-1))[2:].zfill(2*extranonce2_size)
//To review
char extranonce2_char[2 * mWorker.extranonce2_size+1];
mWorker.extranonce2.toCharArray(extranonce2_char, 2 * mWorker.extranonce2_size + 1);
getNextExtranonce2(mWorker.extranonce2_size, extranonce2_char);
mWorker.extranonce2 = String(extranonce2_char);
//char extranonce2_char[2 * mWorker.extranonce2_size+1];
//mWorker.extranonce2.toCharArray(extranonce2_char, 2 * mWorker.extranonce2_size + 1);
//getNextExtranonce2(mWorker.extranonce2_size, extranonce2_char);
if (mWorker.extranonce2_size == 2)
mWorker.extranonce2 = "0001";
else if (mWorker.extranonce2_size == 4)
mWorker.extranonce2 = "00000001";
else if (mWorker.extranonce2_size == 8)
mWorker.extranonce2 = "0000000000000001";
else
{
Serial.println("Unknown extranonce2");
mWorker.extranonce2 = "00000001";
}
//mWorker.extranonce2 = "00000002";
//get coinbase - coinbase_hash_bin = hashlib.sha256(hashlib.sha256(binascii.unhexlify(coinbase)).digest()).digest()
@@ -426,43 +441,70 @@ void suffix_string(double val, char *buf, size_t bufsiz, int sigdigits)
// minimum diff value to display
const double min_diff = 0.001;
const byte maxNdigits = 2;
char suffix[2] = "";
char suffix[2] = {0,0};
bool decimal = true;
double dval;
if (val >= exa) {
val /= peta;
dval = val / kilo;
strcpy(suffix, "E");
suffix[0] = 'E';
if (dval > 999.99)
dval = 999.99;
} else if (val >= peta) {
val /= tera;
dval = val / kilo;
strcpy(suffix, "P");
suffix[0] = 'P';
} else if (val >= tera) {
val /= giga;
dval = val / kilo;
strcpy(suffix, "T");
suffix[0] = 'T';
} else if (val >= giga) {
val /= mega;
dval = val / kilo;
strcpy(suffix, "G");
suffix[0] = 'G';
} else if (val >= mega) {
val /= kilo;
dval = val / kilo;
strcpy(suffix, "M");
suffix[0] = 'M';
} else if (val >= kilo) {
dval = val / kilo;
strcpy(suffix, "K");
suffix[0] = 'K';
} else {
dval = val;
if (dval < min_diff)
dval = 0.0;
}
int frac = 3;
if (suffix[0] != 0)
{
if (dval > 99.999)
frac = 1;
else if (dval > 9.999)
frac = 2;
} else
{
if (dval > 99.999)
frac = 2;
else if (dval > 9.999)
frac = 3;
else
frac = 4;
}
if (!sigdigits) {
if (decimal)
snprintf(buf, bufsiz, "%.3f%s", dval, suffix);
else
{
if (frac == 4)
snprintf(buf, bufsiz, "%.4f%s", dval, suffix);
else if (frac == 3)
snprintf(buf, bufsiz, "%.3f%s", dval, suffix);
else if (frac == 2)
snprintf(buf, bufsiz, "%.2f%s", dval, suffix);
else
snprintf(buf, bufsiz, "%.1f%s", dval, suffix);
} else
snprintf(buf, bufsiz, "%d%s", (unsigned int)dval, suffix);
} else {
/* Always show sigdigits + 1, padded on right with zeroes
@@ -472,3 +514,91 @@ void suffix_string(double val, char *buf, size_t bufsiz, int sigdigits)
snprintf(buf, bufsiz, "%*.*f%s", sigdigits + 1, ndigits, dval, suffix);
}
}
static const uint32_t s_crc32_table[256] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
uint32_t crc32_reset()
{
return 0xFFFFFFFF;
}
uint32_t crc32_add(uint32_t crc32, const void* data, size_t size)
{
for (size_t n = 0; n < size; ++n)
crc32 = (crc32 >> 8) ^ s_crc32_table[(crc32 ^ ((const uint8_t*)data)[n]) & 0xFF];
return crc32;
}
uint32_t crc32_finish(uint32_t crc32)
{
return crc32 ^ 0xFFFFFFFF;
}

View File

@@ -20,10 +20,15 @@ uint8_t hex(char ch);
int to_byte_array(const char *in, size_t in_size, uint8_t *out);
double le256todouble(const void *target);
double diff_from_target(void *target);
bool isSha256Valid(const void* sha256);
miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob);
bool checkValid(unsigned char* hash, unsigned char* target);
void suffix_string(double val, char *buf, size_t bufsiz, int sigdigits);
uint32_t crc32_reset();
uint32_t crc32_add(uint32_t crc32, const void* data, size_t size);
uint32_t crc32_finish(uint32_t crc32);
#endif // UTILS_API_H

View File

@@ -1,6 +1,6 @@
#ifndef VERSION_H
#define VERSION_H
#define CURRENT_VERSION "V1.7.0"
#define CURRENT_VERSION "V1.8.0"
#endif // VERSION_H

View File

@@ -204,7 +204,9 @@ void init_WifiManager()
wm.setConfigPortalBlocking(true); //Hacemos que el portal SI bloquee el firmware
drawSetupScreen();
mMonitor.NerdStatus = NM_Connecting;
if (!wm.startConfigPortal(DEFAULT_SSID, DEFAULT_WIFIPW))
wm.startConfigPortal(DEFAULT_SSID, DEFAULT_WIFIPW);
if (shouldSaveConfig)
{
//Could be break forced after edditing, so save new config
Serial.println("failed to connect and hit timeout");