mirror of
https://github.com/pine64/blisp.git
synced 2025-04-17 07:47:18 +00:00
Add initial support for BL60X
This commit is contained in:
parent
d2f13de709
commit
8c3cc0b017
@ -7,6 +7,7 @@ option(BLISP_BUILD_CLI "Build CLI Tool" OFF)
|
|||||||
|
|
||||||
add_library(libblisp_obj OBJECT
|
add_library(libblisp_obj OBJECT
|
||||||
lib/blisp.c
|
lib/blisp.c
|
||||||
|
lib/chip/blisp_chip_bl60x.c
|
||||||
lib/chip/blisp_chip_bl70x.c)
|
lib/chip/blisp_chip_bl70x.c)
|
||||||
|
|
||||||
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/)
|
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/)
|
||||||
|
@ -6,7 +6,7 @@ Tool and library for flashing their RISC-V MCUs.
|
|||||||
|
|
||||||
# Supported MCUs
|
# Supported MCUs
|
||||||
|
|
||||||
- [ ] BL602 / BL604
|
- [X] BL602 / BL604
|
||||||
- [X] BL702 / BL704 / BL706
|
- [X] BL702 / BL704 / BL706
|
||||||
- [ ] BL606P
|
- [ ] BL606P
|
||||||
- [ ] BL616 / BL618
|
- [ ] BL616 / BL618
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
enum blisp_chip_type {
|
enum blisp_chip_type {
|
||||||
|
BLISP_CHIP_BL60X,
|
||||||
BLISP_CHIP_BL70X
|
BLISP_CHIP_BL70X
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -12,8 +13,11 @@ struct blisp_chip { // TODO: Move elsewhere?
|
|||||||
enum blisp_chip_type type;
|
enum blisp_chip_type type;
|
||||||
const char* type_str;
|
const char* type_str;
|
||||||
bool usb_isp_available;
|
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;
|
extern struct blisp_chip blisp_chip_bl70x;
|
||||||
|
|
||||||
#endif
|
#endif
|
26
lib/blisp.c
26
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_parity(serial_port, SP_PARITY_NONE);
|
||||||
sp_set_stopbits(serial_port, 1);
|
sp_set_stopbits(serial_port, 1);
|
||||||
sp_set_flowcontrol(serial_port, SP_FLOWCONTROL_NONE);
|
sp_set_flowcontrol(serial_port, SP_FLOWCONTROL_NONE);
|
||||||
|
|
||||||
uint32_t vid, pid;
|
uint32_t vid, pid;
|
||||||
sp_get_port_usb_vid_pid(serial_port, &vid, &pid);
|
sp_get_port_usb_vid_pid(serial_port, &vid, &pid);
|
||||||
device->is_usb = pid == 0xFFFF;
|
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);
|
sp_set_baudrate(serial_port, device->current_baud_rate);
|
||||||
device->serial_port = serial_port;
|
device->serial_port = serial_port;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +105,7 @@ int32_t blisp_receive_response(struct blisp_device* device, bool expect_payload)
|
|||||||
// TODO: Check checksum
|
// TODO: Check checksum
|
||||||
int ret;
|
int ret;
|
||||||
struct sp_port* serial_port = device->serial_port;
|
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) {
|
if (ret < 2) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "Failed to receive response. (ret = %d)\n", ret);
|
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
|
return -1; // TODO: Terrible
|
||||||
} else if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
|
} else if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
|
||||||
if (expect_payload) {
|
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]);
|
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);
|
sp_blocking_read(serial_port, &device->rx_buffer[0], data_length, 100);
|
||||||
return data_length;
|
return data_length;
|
||||||
@ -136,10 +138,12 @@ blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) {
|
|||||||
uint8_t handshake_buffer[600];
|
uint8_t handshake_buffer[600];
|
||||||
struct sp_port* serial_port = device->serial_port;
|
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;
|
if (bytes_count > 600) bytes_count = 600;
|
||||||
memset(handshake_buffer, 'U', bytes_count);
|
memset(handshake_buffer, 'U', bytes_count);
|
||||||
|
|
||||||
|
// sp_flush(serial_port, SP_BUF_BOTH);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 5; i++) {
|
for (uint8_t i = 0; i < 5; i++) {
|
||||||
if (!in_ef_loader) {
|
if (!in_ef_loader) {
|
||||||
if (device->is_usb) {
|
if (device->is_usb) {
|
||||||
@ -147,17 +151,20 @@ blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) {
|
|||||||
100);
|
100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count,
|
ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count,
|
||||||
100);
|
500);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 100);
|
ret = sp_blocking_read(serial_port, device->rx_buffer, 20, 1000);
|
||||||
if (ret == 2 && device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
|
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 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return -4; // didn't received response
|
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);
|
ret = blisp_receive_response(device, true);
|
||||||
if (ret < 0) return ret;
|
if (ret < 0) return ret;
|
||||||
|
|
||||||
if (device->chip->type == BLISP_CHIP_BL70X) {
|
|
||||||
memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], 4); // TODO: Endianess
|
memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], 4); // TODO: Endianess
|
||||||
|
if (device->chip->type == BLISP_CHIP_BL70X) {
|
||||||
memcpy(boot_info->chip_id, &device->rx_buffer[16], 8);
|
memcpy(boot_info->chip_id, &device->rx_buffer[16], 8);
|
||||||
}
|
}
|
||||||
|
// TODO: BL60X
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +214,7 @@ int32_t blisp_device_load_segment_data(struct blisp_device* device, uint8_t* seg
|
|||||||
int ret;
|
int ret;
|
||||||
ret = blisp_send_command(device, 0x18, segment_data, segment_data_length, false);
|
ret = blisp_send_command(device, 0x18, segment_data, segment_data_length, false);
|
||||||
if (ret < 0) return ret;
|
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;
|
if (ret < 0) return ret;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
9
lib/chip/blisp_chip_bl60x.c
Normal file
9
lib/chip/blisp_chip_bl60x.c
Normal file
@ -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,
|
||||||
|
};
|
@ -3,5 +3,7 @@
|
|||||||
struct blisp_chip blisp_chip_bl70x = {
|
struct blisp_chip blisp_chip_bl70x = {
|
||||||
.type = BLISP_CHIP_BL70X,
|
.type = BLISP_CHIP_BL70X,
|
||||||
.type_str = "bl70x",
|
.type_str = "bl70x",
|
||||||
.usb_isp_available = true
|
.usb_isp_available = true,
|
||||||
|
.default_eflash_loader_xtal = "32m",
|
||||||
|
.handshake_byte_multiplier = 0.003f,
|
||||||
};
|
};
|
||||||
|
@ -185,14 +185,25 @@ void fill_up_boot_header(struct bfl_boot_header* boot_header)
|
|||||||
void blisp_flash_firmware() {
|
void blisp_flash_firmware() {
|
||||||
FILE* eflash_loader_file = NULL;
|
FILE* eflash_loader_file = NULL;
|
||||||
|
|
||||||
// TODO: We support currently only BL70X
|
if (chip_type->count == 0) {
|
||||||
if (chip_type->count == 0 || strcmp(chip_type->sval[0], "bl70x") != 0) {
|
|
||||||
fprintf(stderr, "Chip type is invalid.\n");
|
fprintf(stderr, "Chip type is invalid.\n");
|
||||||
return;
|
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;
|
struct blisp_device device;
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
ret = blisp_device_init(&device, &blisp_chip_bl70x);
|
ret = blisp_device_init(&device, chip);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf(stderr, "Failed to init device.\n");
|
fprintf(stderr, "Failed to init device.\n");
|
||||||
return;
|
return;
|
||||||
@ -241,7 +252,7 @@ void blisp_flash_firmware() {
|
|||||||
char exe_path[PATH_MAX];
|
char exe_path[PATH_MAX];
|
||||||
char eflash_loader_path[PATH_MAX];
|
char eflash_loader_path[PATH_MAX];
|
||||||
get_binary_folder(exe_path, PATH_MAX); // TODO: Error handling
|
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
|
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
|
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;
|
buffer_size = 4092;
|
||||||
}
|
}
|
||||||
fread(buffer, buffer_size, 1, eflash_loader_file);
|
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
|
&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;
|
sent_data += buffer_size;
|
||||||
printf("%" PRIu32 "b / %" PRIu32 "b (%.2f%%)\n", sent_data,
|
printf("%" PRIu32 "b / %" PRIu32 "b (%.2f%%)\n", sent_data,
|
||||||
segment_header.length,
|
segment_header.length,
|
||||||
|
Loading…
Reference in New Issue
Block a user