From 8c3cc0b017fa49855d00f38ccf965593415b2b5d Mon Sep 17 00:00:00 2001 From: Marek Kraus Date: Tue, 8 Nov 2022 22:06:14 +0100 Subject: [PATCH] Add initial support for BL60X --- CMakeLists.txt | 1 + README.md | 2 +- include/blisp_chip.h | 4 ++++ lib/blisp.c | 28 ++++++++++++++++++---------- lib/chip/blisp_chip_bl60x.c | 9 +++++++++ lib/chip/blisp_chip_bl70x.c | 4 +++- tools/blisp/src/cmd/write.c | 25 ++++++++++++++++++++----- 7 files changed, 56 insertions(+), 17 deletions(-) create mode 100644 lib/chip/blisp_chip_bl60x.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ab70d7c..124c4a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ option(BLISP_BUILD_CLI "Build CLI Tool" OFF) add_library(libblisp_obj OBJECT lib/blisp.c + lib/chip/blisp_chip_bl60x.c lib/chip/blisp_chip_bl70x.c) target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/) diff --git a/README.md b/README.md index ad2cc5d..6c860da 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Tool and library for flashing their RISC-V MCUs. # Supported MCUs -- [ ] BL602 / BL604 +- [X] BL602 / BL604 - [X] BL702 / BL704 / BL706 - [ ] BL606P - [ ] BL616 / BL618 diff --git a/include/blisp_chip.h b/include/blisp_chip.h index 4edee2b..c3d44f1 100644 --- a/include/blisp_chip.h +++ b/include/blisp_chip.h @@ -5,6 +5,7 @@ #include enum blisp_chip_type { + BLISP_CHIP_BL60X, BLISP_CHIP_BL70X }; @@ -12,8 +13,11 @@ struct blisp_chip { // TODO: Move elsewhere? enum blisp_chip_type type; const char* type_str; bool usb_isp_available; + float handshake_byte_multiplier; + const char* default_eflash_loader_xtal; // TODO: Make this selectable }; +extern struct blisp_chip blisp_chip_bl60x; extern struct blisp_chip blisp_chip_bl70x; #endif \ No newline at end of file diff --git a/lib/blisp.c b/lib/blisp.c index b53fb0e..4a2a3ef 100644 --- a/lib/blisp.c +++ b/lib/blisp.c @@ -59,6 +59,7 @@ int32_t blisp_device_open(struct blisp_device* device, const char* port_name) sp_set_parity(serial_port, SP_PARITY_NONE); sp_set_stopbits(serial_port, 1); sp_set_flowcontrol(serial_port, SP_FLOWCONTROL_NONE); + uint32_t vid, pid; sp_get_port_usb_vid_pid(serial_port, &vid, &pid); device->is_usb = pid == 0xFFFF; @@ -69,6 +70,7 @@ int32_t blisp_device_open(struct blisp_device* device, const char* port_name) // } sp_set_baudrate(serial_port, device->current_baud_rate); device->serial_port = serial_port; + return 0; } @@ -103,7 +105,7 @@ int32_t blisp_receive_response(struct blisp_device* device, bool expect_payload) // TODO: Check checksum int ret; struct sp_port* serial_port = device->serial_port; - ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 300); + ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 500); if (ret < 2) { #ifdef DEBUG fprintf(stderr, "Failed to receive response. (ret = %d)\n", ret); @@ -111,7 +113,7 @@ int32_t blisp_receive_response(struct blisp_device* device, bool expect_payload) return -1; // TODO: Terrible } else if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') { if (expect_payload) { - sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100); + sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100); // TODO: Check if really we received the data. uint16_t data_length = (device->rx_buffer[3] << 8) | (device->rx_buffer[2]); sp_blocking_read(serial_port, &device->rx_buffer[0], data_length, 100); return data_length; @@ -136,10 +138,12 @@ blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) { uint8_t handshake_buffer[600]; struct sp_port* serial_port = device->serial_port; - uint32_t bytes_count = 0.003f * (float)device->current_baud_rate / 10.0f; // TODO: 0.003f is only for BL70X! + uint32_t bytes_count = device->chip->handshake_byte_multiplier * (float)device->current_baud_rate / 10.0f; if (bytes_count > 600) bytes_count = 600; memset(handshake_buffer, 'U', bytes_count); +// sp_flush(serial_port, SP_BUF_BOTH); + for (uint8_t i = 0; i < 5; i++) { if (!in_ef_loader) { if (device->is_usb) { @@ -147,15 +151,18 @@ blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) { 100); } } - ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count, - 100); + 500); if (ret < 0) { return -1; } - ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 100); - if (ret == 2 && device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') { - return 0; + ret = sp_blocking_read(serial_port, device->rx_buffer, 20, 1000); + if (ret >= 2) { + for (uint8_t j = 0; j < (ret - 1); j++) { + if (device->rx_buffer[j] == 'O' && device->rx_buffer[j + 1] == 'K') { + return 0; + } + } } } return -4; // didn't received response @@ -171,10 +178,11 @@ int32_t blisp_device_get_boot_info(struct blisp_device* device, struct blisp_boo ret = blisp_receive_response(device, true); if (ret < 0) return ret; + memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], 4); // TODO: Endianess if (device->chip->type == BLISP_CHIP_BL70X) { - memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], 4); // TODO: Endianess memcpy(boot_info->chip_id, &device->rx_buffer[16], 8); } + // TODO: BL60X return 0; } @@ -206,7 +214,7 @@ int32_t blisp_device_load_segment_data(struct blisp_device* device, uint8_t* seg int ret; ret = blisp_send_command(device, 0x18, segment_data, segment_data_length, false); if (ret < 0) return ret; - ret = blisp_receive_response(device, true); // TODO: Handle response + ret = blisp_receive_response(device, false); if (ret < 0) return ret; return 0; diff --git a/lib/chip/blisp_chip_bl60x.c b/lib/chip/blisp_chip_bl60x.c new file mode 100644 index 0000000..7b5c59e --- /dev/null +++ b/lib/chip/blisp_chip_bl60x.c @@ -0,0 +1,9 @@ +#include "blisp.h" + +struct blisp_chip blisp_chip_bl60x = { + .type = BLISP_CHIP_BL60X, + .type_str = "bl60x", + .usb_isp_available = false, + .default_eflash_loader_xtal = "40m", + .handshake_byte_multiplier = 0.006f, +}; diff --git a/lib/chip/blisp_chip_bl70x.c b/lib/chip/blisp_chip_bl70x.c index 8104a24..19058d5 100644 --- a/lib/chip/blisp_chip_bl70x.c +++ b/lib/chip/blisp_chip_bl70x.c @@ -3,5 +3,7 @@ struct blisp_chip blisp_chip_bl70x = { .type = BLISP_CHIP_BL70X, .type_str = "bl70x", - .usb_isp_available = true + .usb_isp_available = true, + .default_eflash_loader_xtal = "32m", + .handshake_byte_multiplier = 0.003f, }; diff --git a/tools/blisp/src/cmd/write.c b/tools/blisp/src/cmd/write.c index 515bac6..51471ea 100644 --- a/tools/blisp/src/cmd/write.c +++ b/tools/blisp/src/cmd/write.c @@ -185,14 +185,25 @@ void fill_up_boot_header(struct bfl_boot_header* boot_header) void blisp_flash_firmware() { FILE* eflash_loader_file = NULL; - // TODO: We support currently only BL70X - if (chip_type->count == 0 || strcmp(chip_type->sval[0], "bl70x") != 0) { + if (chip_type->count == 0) { fprintf(stderr, "Chip type is invalid.\n"); return; } + + struct blisp_chip* chip = NULL; + + if (strcmp(chip_type->sval[0], "bl70x") == 0) { + chip = &blisp_chip_bl70x; + } else if (strcmp(chip_type->sval[0], "bl60x") == 0) { + chip = &blisp_chip_bl60x; + } else { + fprintf(stderr, "Chip type is invalid.\n"); + return; + } + struct blisp_device device; int32_t ret; - ret = blisp_device_init(&device, &blisp_chip_bl70x); + ret = blisp_device_init(&device, chip); if (ret != 0) { fprintf(stderr, "Failed to init device.\n"); return; @@ -241,7 +252,7 @@ void blisp_flash_firmware() { char exe_path[PATH_MAX]; char eflash_loader_path[PATH_MAX]; get_binary_folder(exe_path, PATH_MAX); // TODO: Error handling - snprintf(eflash_loader_path, PATH_MAX, "%s/data/%s/eflash_loader_32m.bin", exe_path, device.chip->type_str); + snprintf(eflash_loader_path, PATH_MAX, "%s/data/%s/eflash_loader_%s.bin", exe_path, device.chip->type_str, device.chip->default_eflash_loader_xtal); eflash_loader_file = fopen(eflash_loader_path, "rb"); // TODO: Error handling uint8_t eflash_loader_header[176]; // TODO: Remap it to the boot header struct @@ -279,8 +290,12 @@ void blisp_flash_firmware() { buffer_size = 4092; } fread(buffer, buffer_size, 1, eflash_loader_file); - blisp_device_load_segment_data( + ret = blisp_device_load_segment_data( &device, buffer, buffer_size); // TODO: Error handling + if (ret < 0) { + fprintf(stderr, "Failed to load segment data. (ret %d)\n", ret); + goto exit1; + } sent_data += buffer_size; printf("%" PRIu32 "b / %" PRIu32 "b (%.2f%%)\n", sent_data, segment_header.length,