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

development of unit test to verify bm1366 is able to find a solution for a known block #167

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
639775f
add BM1366_set_chip_address (needed for unit test to work)
MoellerDi Apr 21, 2024
65800a7
add BM1366 unit test - Testing one single BM1366 chip against a known…
MoellerDi Apr 21, 2024
b922e3e
fix construct_bm_job - new_job.merkle_root instead of new_job.merkle_…
MoellerDi Apr 21, 2024
5295443
Revert "fix construct_bm_job - new_job.merkle_root instead of new_job…
MoellerDi Apr 21, 2024
dd7e0a1
the merkle_root copied from blockchain.info needs to be in reversed o…
MoellerDi Apr 21, 2024
e67c300
add rollover detection
MoellerDi Apr 26, 2024
802e0c8
update _set_chip_address
MoellerDi Apr 27, 2024
841bff4
update _send_init - static chip_counter
MoellerDi Apr 27, 2024
1aba19b
update _send_init - new address interval, utilize existing code and u…
MoellerDi Apr 27, 2024
186f979
add BM1366_set_nonce_scope and renaming of BM1366_set_chip_address
MoellerDi Apr 27, 2024
d9f26b1
update _send_init to use BM1366_set_nonce_space
MoellerDi Apr 27, 2024
5666d8c
update unit test
MoellerDi Apr 27, 2024
02c4b5f
Not ready for prime time - Revert "update _send_init to use BM1366_se…
MoellerDi Apr 27, 2024
0d92805
update unit test - new magic_number, call BM1366_set_nonce_scope in u…
MoellerDi Apr 27, 2024
f5ead64
update BM1366_set_nonce_scope
MoellerDi Apr 27, 2024
c012e05
add _calculate_chip_number, rev static chip_ccount and update BM1366_…
MoellerDi May 2, 2024
0b3eb9d
update unit test - add isDuplicated check
MoellerDi May 2, 2024
dba4eb6
update unit test - add time measurement
MoellerDi May 2, 2024
6cd0314
update unit test - minor updates
MoellerDi May 2, 2024
0cef4d6
update unit test - fix typo and remove option to show chip/core addre…
MoellerDi May 2, 2024
3f3da6f
fix typo
MoellerDi May 2, 2024
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
130 changes: 123 additions & 7 deletions components/bm1397/bm1366.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ static void _send_chain_inactive(void)
_send_BM1366((TYPE_CMD | GROUP_ALL | CMD_INACTIVE), read_address, 2, false);
}

static void _set_chip_address(uint8_t chipAddr)
static void _set_chip_address(uint8_t new_address)
{

unsigned char read_address[2] = {chipAddr, 0x00};
unsigned char send_address[2] = {new_address, 0x00};
// send serial data
_send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_SETADDRESS), read_address, 2, false);
_send_BM1366((TYPE_CMD | GROUP_SINGLE | CMD_SETADDRESS), send_address, 2, false);
}

void BM1366_send_hash_frequency(float target_freq)
Expand Down Expand Up @@ -456,51 +456,67 @@ static uint8_t _send_init(uint64_t frequency)
}
ESP_LOGI(TAG, "%i chip(s) detected on the chain", chip_counter);

//Reg_A8
unsigned char init4[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0xA8, 0x00, 0x07, 0x00, 0x00, 0x03};
_send_simple(init4, 11);

//Misc Control
unsigned char init5[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x18, 0xFF, 0x0F, 0xC1, 0x00, 0x00};
_send_simple(init5, 11);

unsigned char init6[7] = {0x55, 0xAA, 0x53, 0x05, 0x00, 0x00, 0x03};
_send_simple(init6, 7);
//chain inactive
_send_chain_inactive();

unsigned char init7[7] = {0x55, 0xAA, 0x40, 0x05, 0x00, 0x00, 0x1C};
_send_simple(init7, 7);
//set chip address
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this is exactly what I was talking about
it was the purpose of my "hex" branch from 9 month ago.
this have to be done also for other chip, not only BM1366. BM1397 and BM1368 may also be used in multi chip design in the furture

for (int i = 0; i < chip_counter; i++) {
_set_chip_address(i * (0x100 / chip_counter));
}

//Core Register Control
unsigned char init135[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x85, 0x40, 0x0C};
_send_simple(init135, 11);

//Core Register Control
unsigned char init136[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x80, 0x20, 0x19};
_send_simple(init136, 11);

//set ticket mask
unsigned char init137[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x14, 0x00, 0x00, 0x00, 0xFF, 0x08};
_send_simple(init137, 11);

//Analog Mux Control
unsigned char init138[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x54, 0x00, 0x00, 0x00, 0x03, 0x1D};
_send_simple(init138, 11);

//Set the IO Driver Strength
unsigned char init139[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x58, 0x02, 0x11, 0x11, 0x11, 0x06};
_send_simple(init139, 11);

//UART Relay for each chip
unsigned char init171[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x2C, 0x00, 0x7C, 0x00, 0x03, 0x03};
_send_simple(init171, 11);

//FAST_UART_CONFIGURATION
unsigned char init173[11] = {0x55, 0xAA, 0x51, 0x09, 0x00, 0x28, 0x11, 0x30, 0x02, 0x00, 0x03};
_send_simple(init173, 11);

//Reg_A8 for each chip
unsigned char init174[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0xA8, 0x00, 0x07, 0x01, 0xF0, 0x15};
_send_simple(init174, 11);

//Misc Control for each chip
unsigned char init175[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x18, 0xF0, 0x00, 0xC1, 0x00, 0x0C};
_send_simple(init175, 11);

//Core Register Control for each chip
unsigned char init176[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x85, 0x40, 0x04};
_send_simple(init176, 11);

//Core Register Control for each chip
unsigned char init177[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x80, 0x20, 0x11};
_send_simple(init177, 11);

//Core Register Control for each chip
unsigned char init178[11] = {0x55, 0xAA, 0x41, 0x09, 0x00, 0x3C, 0x80, 0x00, 0x82, 0xAA, 0x05};
_send_simple(init178, 11);

Expand Down Expand Up @@ -540,6 +556,49 @@ static void _send_read_address(void)
_send_BM1366((TYPE_CMD | GROUP_ALL | CMD_READ), read_address, 2, false);
}

static int _calculate_chip_number(unsigned int actual_chip_count)
{
int i = 0;
if(actual_chip_count == 1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the algo for this function may be written using interger algebra instead of this if else if else if structure.

I don't really understand the final usage of it, but as it is only for the added test (will not be used by actual mining), why not.

{
i = 1;
}
else if(actual_chip_count == 2)
{
i = 2;
}
else if((actual_chip_count > 2) && (actual_chip_count <= 4))
{
i = 4;
}
else if((actual_chip_count > 4) && (actual_chip_count <= 8))
{
i = 8;
}
else if((actual_chip_count > 8) && (actual_chip_count <= 16))
{
i = 16;
}
else if((actual_chip_count > 16) && (actual_chip_count <= 32))
{
i = 32;
}
else if((actual_chip_count > 32) && (actual_chip_count <= 64))
{
i = 64;
}
else if((actual_chip_count > 64) && (actual_chip_count <= 128))
{
i = 128;
}
else
{
ESP_LOGE(TAG,"actual_chip_count = %d, but it is error\n", actual_chip_count);
return -1;
}
return i;
}

uint8_t BM1366_init(uint64_t frequency)
{
ESP_LOGI(TAG, "Initializing BM1366");
Expand All @@ -558,6 +617,63 @@ uint8_t BM1366_init(uint64_t frequency)
return _send_init(frequency);
}

void BM1366_set_single_chip_address(uint8_t new_address)
{
// set all chips to chain_inactive mode
_send_chain_inactive();

// set new chip address to first chip in chain_inactive mode.
_set_chip_address(new_address);
}

void BM1366_set_nonce_mask(int chip_count)
{
if (chip_count < 1) { chip_count = 1; }
if (chip_count > 128) { chip_count = 128; }

chip_count = _calculate_chip_number(chip_count); // Because of the way the nonce ranges calculated, we need to use a fixed chip address interval (for now)

// Every nonce returned by chip (except those sent by opencore) encodes address of the
// chip and core that computed it, because of the way they divide the search space.

// uint8_t chip_address = (asic_result->nonce >> 9) & 0x7f; // Range 0x00-0xFF. Chip address seems to be 8 bits in size. However the first bit should always be 0 because the chip address is increment by 2. The last bit is always low for addresses < 0x80 and always high for addresses >= 0x80
// uint8_t core_small_core_address = (asic_result->nonce >> 29) & 0x7; // Range 0x0-0x7. Helps to identify if the nonce was calculated by what small_core but not really important for now.

// It seems the nonces calculation use the following structure:
// 31.................16 15..................0
// 0byyy00000 0b0000000x 0bxxxxxxx0 0b00000000 // nonce calculated, one can compute the chip address and small core address from the nonce as outlines above
// 0b00000000 0b0000mmmm 0bmmmmmmm0 0b00000000 // nonce mask
// x = chip address (0x00 - 0xFF)
// y = small_core address (0x0 - 0x7)
// m = nonce mask used for nonce calculation.

// The following are known configurations:
// 55 AA 51 09 00 10 00 00 11 5A 04 //s19kPro (77 chips) -> 0x115a
// unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010001, 0b01011010};
// 55 AA 51 09 00 10 00 00 14 46 04 //s19xp_luxos (110 chips) -> 0x1446
// unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010100, 0b01000110};
// 55 AA 51 09 00 10 00 00 15 1C 02 //s19xp-stock / BitaxeUltra -> 0x151c
// unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010101, 0b00011100};
// 55 AA 51 09 00 10 00 00 15 A4 0A //s21 (bm1368 - 108 chips)
// unsigned char command[9] = {0x00, 0x10, 0b00000000, 0b00000000, 0b00010101, 0b10100100};

// command template
unsigned char command[9] = {0x00, 0x10, 0x00, 0x00, 0x00, 0x00};

// This nonce_mask is used in combination with the chip address to calculate the nonce ranges for the chip.
uint32_t offset = (0x15FF / 2); // found by try-and-error. 15FF seems to be max value. Any higher number result in duplicated nonces because the way (using addr interval) I'm moving bits to the left.
uint32_t nonce_mask = offset * (0x100 / chip_count);

// convert into char array and mix with command template
for (int i = 0; i < 4; i++) {
char value = (nonce_mask >> (8 * i)) & 0xFF;
command[5 - i] = command[5 - i] | value;
}

ESP_LOGI(TAG, "Setting Nonce mask to %08lX", nonce_mask);
_send_BM1366((TYPE_CMD | GROUP_ALL | CMD_WRITE), command, 6, false);
}

// Baud formula = 25M/((denominator+1)*8)
// The denominator is 5 bits found in the misc_control (bits 9-13)
int BM1366_set_default_baud(void)
Expand Down
2 changes: 2 additions & 0 deletions components/bm1397/include/bm1366.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,7 @@ int BM1366_set_max_baud(void);
int BM1366_set_default_baud(void);
void BM1366_send_hash_frequency(float frequency);
task_result * BM1366_proccess_work(void * GLOBAL_STATE);
void BM1366_set_single_chip_address(uint8_t chipAddr);
void BM1366_set_nonce_mask(int chip_count);

#endif /* BM1366_H_ */
24 changes: 21 additions & 3 deletions components/bm1397/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
idf_component_register(SRC_DIRS "."
INCLUDE_DIRS "."
REQUIRES cmock stratum bm1397)
idf_component_register(
SRCS
"test_bm1366.c"
"../../../main/adc.c"
"../../../main/nvs_config.c"
"../../../main/EMC2101.c"
"../../../main/DS4432U.c"
INCLUDE_DIRS
"."
"../include"
"../../../main"
"../../../main/tasks"

REQUIRES unity cmock stratum bm1397 nvs_flash esp_adc esp_event connect
)

# Include the header files from "main" directory
target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../main")

# Include the header files from "main/tasks" directory
target_include_directories(${COMPONENT_LIB} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../main/tasks")
147 changes: 147 additions & 0 deletions components/bm1397/test/log/test_bm1366_output.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
export IDF_PATH=/opt/esp/idf
/opt/esp/python_env/idf5.3_py3.10_env/bin/python /opt/esp/idf/tools/idf_monitor.py -p /dev/ttyACM0 -b 115200 --toolchain-prefix xtensa-esp32s3-elf- --target esp32s3 /workspaces/build/esp-miner.elf
root@31cc35ad06b6:/workspaces# export IDF_PATH=/opt/esp/idf
root@31cc35ad06b6:/workspaces# /opt/esp/python_env/idf5.3_py3.10_env/bin/python /opt/esp/idf/tools/idf_monitor.py -p /dev/ttyACM0 -b 115200 --toolchain-prefix xtensa-esp32s3-elf- --target esp32s3 /workspaces/build/esp-miner.elf
--- esp-idf-monitor 1.4.0 on /dev/ttyACM0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
I (115) esp_image: segment 1: paddr=00023ec4 vaddr=3fc93cESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x15 (USB_UART_CHIP_RESET),boot:0x28 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40378db6
0x40378db6: esp_random at /opt/esp/idf/components/esp_hw_support/hw_random.c:84 (discriminator 1)

SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2810,len:0x178c
load:0x403c8700,len:0x4
load:0x403c8704,len:0xcb8
load:0x403cb700,len:0x2d9c
entry 0x403c8914
I (26) boot: ESP-IDF v5.3-dev-3225-g5a40bb8746 2nd stage bootloader
I (27) boot: compile time Apr 18 2024 07:48:00
I (27) boot: Multicore bootloader
I (31) boot: chip revision: v0.2
I (35) boot.esp32s3: Boot SPI Speed : 80MHz
I (40) boot.esp32s3: SPI Mode : DIO
I (45) boot.esp32s3: SPI Flash Size : 2MB
I (49) boot: Enabling RNG early entropy source...
I (55) boot: Partition Table:
I (58) boot: ## Label Usage Type ST Offset Length
I (66) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (73) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (81) boot: 2 factory factory app 00 00 00010000 00100000
I (88) boot: End of partition table
I (92) esp_image: segment 0: paddr=00010020 vaddr=3c040020 size=13e9ch ( 81564) map
I (115) esp_image: segment 1: paddr=00023ec4 vaddr=3fc93c00 size=03228h ( 12840) load
I (119) esp_image: segment 2: paddr=000270f4 vaddr=40374000 size=08f24h ( 36644) load
I (129) esp_image: segment 3: paddr=00030020 vaddr=42000020 size=32d80h (208256) map
I (167) esp_image: segment 4: paddr=00062da8 vaddr=4037cf24 size=06c94h ( 27796) load
I (180) boot: Loaded app from partition at offset 0x10000
I (180) boot: Disabling RNG early entropy source...
I (183) cpu_start: Multicore app
I (192) cpu_start: Pro cpu start user code
I (192) cpu_start: cpu freq: 160000000 Hz
I (192) app_init: Application information:
I (195) app_init: Project name: unit_test_stratum
I (201) app_init: App version: 07e7d41
I (206) app_init: Compile time: Apr 21 2024 12:19:07
I (212) app_init: ELF file SHA256: 0c91dab32...
I (217) app_init: ESP-IDF: v5.3-dev-3225-g5a40bb8746
I (223) efuse_init: Min chip rev: v0.0
I (228) efuse_init: Max chip rev: v0.99
I (233) efuse_init: Chip rev: v0.2
I (238) heap_init: Initializing. RAM available for dynamic allocation:
I (245) heap_init: At 3FC98C00 len 00050B10 (322 KiB): RAM
I (251) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
I (257) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (263) heap_init: At 600FE100 len 00001EE8 (7 KiB): RTCRAM
I (271) spi_flash: detected chip: gd
I (274) spi_flash: flash io: dio
I (310) sleep: Configure to isolate all GPIO pins in sleep state
I (317) sleep: Enable automatic switching of GPIO sleep configuration
I (324) main_task: Started on CPU0
I (334) main_task: Calling app_main()

#### Running all the registered tests #####

Running Testing single BM1366 chip against a known valid block...
I (384) test_bm1366: ASIC: BM1366
I (384) test_bm1366: I2C initialized successfully
I (384) DS4432U.c: Set ASIC voltage = 1.250V [0xB9]
I (384) DS4432U.c: Writing 0xB9
I (394) serial: Initializing serial
I (394) bm1366Module: Initializing BM1366
I (1594) bm1366Module: 1 chip(s) detected on the chain
final refdiv: 2, fbdiv: 220, postdiv1: 5, postdiv2: 1, min diff value: 0.000000
I (1624) bm1366Module: Setting Frequency to 550.00MHz (0.01)
I (1624) bm1366Module: Setting max baud of 1000000
I (1634) serial: Changing UART baud to 1000000
I (1634) test_bm1366: BM1366 is ready and waiting for work
I (1644) test_bm1366: Preparing job
I (1644) bm1366Module: Setting job ASIC mask to 511
I (1654) test_bm1366: Changing chip address and sending job; new chip address: 0xc0
I (1664) test_bm1366: Waiting for result ... (might take a while due to 60s timeout)
I (2114) test_bm1366: Result[1]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000
I (3974) test_bm1366: Result[2]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000
I (5704) test_bm1366: Result[3]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000
I (7554) test_bm1366: Result[4]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000
I (9294) test_bm1366: Result[5]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000
I (11144) test_bm1366: Result[6]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000
I (12874) test_bm1366: Result[7]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000
I (14724) test_bm1366: Result[8]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000
I (16464) test_bm1366: Result[9]: Nonce 3818226259 Nonce difficulty 8452.86377870396427169907838106155396. rolled-version 0x24148000
I (18314) test_bm1366: Result[10]: Nonce 504135883 Nonce difficulty 816.88959549147682537295622751116753. rolled-version 0x349cc000
I (20044) test_bm1366: Changing chip address and sending job; new chip address: 0xc2
I (20044) test_bm1366: Waiting for result ... (might take a while due to 60s timeout)
I (21064) test_bm1366: Result[1]: Nonce 3118696143 Nonce difficulty 1007.71313585765790321602253243327141. rolled-version 0x2915a000
I (21234) test_bm1366: Result[2]: Nonce 3529540887 Nonce difficulty 125538251293054.07812500000000000000000000000000. rolled-version 0x2a966000
I (21234) test_bm1366: Expected nonce and version match. Solution found!
/workspaces/components/bm1397/test/test_bm1366.c:23:Testing single BM1366 chip against a known valid block:PASS
Running Check coinbase tx construction...
/workspaces/components/stratum/test/test_mining.c:7:Check coinbase tx construction:PASS
Running Validate merkle root calculation...
/workspaces/components/stratum/test/test_mining.c:19:Validate merkle root calculation:PASS
Running Validate another merkle root calculation...
/workspaces/components/stratum/test/test_mining.c:43:Validate another merkle root calculation:PASS
Running Validate bm job construction...
/workspaces/components/stratum/test/test_mining.c:75:Validate bm job construction:FAIL: Element 0 Expected 77 Was 214. Function [mining]
Running Validate version mask incrementing...
/workspaces/components/stratum/test/test_mining.c:78:Validate version mask incrementing:PASS
Running Test extranonce 2 generation...
/workspaces/components/stratum/test/test_mining.c:118:Test extranonce 2 generation:PASS
Running Test nonce diff checking...
/workspaces/components/stratum/test/test_mining.c:153:Test nonce diff checking:FAIL: Expected 18 Was 0. Function [mining test_nonce]
Running Test nonce diff checking 2...
/workspaces/components/stratum/test/test_mining.c:189:Test nonce diff checking 2:FAIL: Expected 683 Was 0. Function [mining test_nonce]
Running Parse stratum method...
/workspaces/components/stratum/test/test_stratum_json.c:4:Parse stratum method:PASS
Running Parse stratum mining.notify abandon work...
/workspaces/components/stratum/test/test_stratum_json.c:21:Parse stratum mining.notify abandon work:PASS
Running Parse stratum set_difficulty params...
/workspaces/components/stratum/test/test_stratum_json.c:62:Parse stratum set_difficulty params:PASS
Running Parse stratum notify params...
/workspaces/components/stratum/test/test_stratum_json.c:71:Parse stratum notify params:PASS
Running Parse stratum mining.set_version_mask params...
/workspaces/components/stratum/test/test_stratum_json.c:108:Parse stratum mining.set_version_mask params:PASS
Running Parse stratum result success...
/workspaces/components/stratum/test/test_stratum_json.c:118:Parse stratum result success:PASS
Running Parse stratum result error...
/workspaces/components/stratum/test/test_stratum_json.c:128:Parse stratum result error:PASS
Running Test double sha...
/workspaces/components/stratum/test/test_utils.c:5:Test double sha:PASS
Running Test hex2bin...
/workspaces/components/stratum/test/test_utils.c:12:Test hex2bin:PASS
Running Test bin2hex...
/workspaces/components/stratum/test/test_utils.c:25:Test bin2hex:PASS
Running Test hex2char...
/workspaces/components/stratum/test/test_utils.c:33:Test hex2char:PASS

-----------------------
20 Tests 3 Failures 0 Ignored
FAIL

#### Starting interactive test menu #####



Press ENTER to see the list of tests.
Loading
Loading