mirror of
https://github.com/pine64/blisp.git
synced 2025-01-03 04:10:31 +00:00
WIP
This commit is contained in:
parent
9d8738cb85
commit
29a36a2d7b
@ -4,47 +4,54 @@ project(blisp C)
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
|
||||
option(BLISP_BUILD_CLI "Build CLI Tool" OFF)
|
||||
option(BLISP_DYNAMIC_LIBRARY "Build dynamic library" OFF)
|
||||
|
||||
if(BLISP_DYNAMIC_LIBRARY)
|
||||
add_library(libblisp SHARED)
|
||||
else()
|
||||
add_library(libblisp STATIC)
|
||||
endif()
|
||||
add_library(libblisp_obj OBJECT
|
||||
lib/blisp.c
|
||||
lib/chip/blisp_chip_bl70x.c)
|
||||
|
||||
target_sources(libblisp PRIVATE lib/blisp_easy.c)
|
||||
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/)
|
||||
|
||||
set_property(TARGET libblisp_obj PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||
|
||||
add_library(libblisp SHARED $<TARGET_OBJECTS:libblisp_obj>)
|
||||
add_library(libblisp_static STATIC $<TARGET_OBJECTS:libblisp_obj>)
|
||||
|
||||
target_include_directories(libblisp PRIVATE ${CMAKE_SOURCE_DIR}/include/)
|
||||
|
||||
set_target_properties(libblisp PROPERTIES
|
||||
PUBLIC_HEADER "include/blisp_easy.h"
|
||||
PUBLIC_HEADER "include/blisp.h"
|
||||
VERSION 1.0
|
||||
SOVERSION 1
|
||||
OUTPUT_NAME "blisp"
|
||||
)
|
||||
LIBRARY_OUTPUT_DIRECTORY "shared"
|
||||
OUTPUT_NAME "blisp")
|
||||
|
||||
set_target_properties(libblisp_static PROPERTIES
|
||||
PUBLIC_HEADER "include/blisp.h"
|
||||
VERSION 1.0
|
||||
SOVERSION 1
|
||||
ARCHIVE_OUTPUT_DIRECTORY "static"
|
||||
OUTPUT_NAME "blisp")
|
||||
|
||||
target_sources(libblisp_obj PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/vendor/libserialport/serialport.c
|
||||
${CMAKE_SOURCE_DIR}/vendor/libserialport/timing.c)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(libblisp_obj PRIVATE Setupapi.lib)
|
||||
target_compile_definitions(libblisp_obj PRIVATE LIBSERIALPORT_MSBUILD)
|
||||
target_sources(libblisp_obj PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/vendor/libserialport/windows.c)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
target_sources(libblisp_obj PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/vendor/libserialport/linux.c
|
||||
${CMAKE_SOURCE_DIR}/vendor/libserialport/linux_termios.c)
|
||||
target_compile_definitions(libblisp_obj PRIVATE
|
||||
LIBSERIALPORT_ATBUILD
|
||||
"SP_API=__attribute__((visibility(\"default\")))"
|
||||
"SP_PRIV=__attribute__((visibility(\"hidden\")))")
|
||||
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport)
|
||||
write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.")
|
||||
endif()
|
||||
|
||||
if(BLISP_BUILD_CLI)
|
||||
add_subdirectory(tools/blisp)
|
||||
endif()
|
||||
|
||||
|
||||
#target_sources(blisp PRIVATE
|
||||
# ${CMAKE_SOURCE_DIR}/vendor/libserialport/serialport.c
|
||||
# ${CMAKE_SOURCE_DIR}/vendor/libserialport/timing.c)
|
||||
#
|
||||
#if(WIN32)
|
||||
# target_link_libraries(blisp PRIVATE Setupapi.lib)
|
||||
# target_compile_definitions(blisp PRIVATE LIBSERIALPORT_MSBUILD)
|
||||
# target_sources(blisp PRIVATE
|
||||
# ${CMAKE_SOURCE_DIR}/vendor/libserialport/windows.c)
|
||||
#elseif(UNIX AND NOT APPLE)
|
||||
# target_sources(blisp PRIVATE
|
||||
# ${CMAKE_SOURCE_DIR}/vendor/libserialport/linux.c
|
||||
# ${CMAKE_SOURCE_DIR}/vendor/libserialport/linux_termios.c)
|
||||
# target_compile_definitions(blisp PRIVATE
|
||||
# LIBSERIALPORT_ATBUILD
|
||||
# "SP_API=__attribute__((visibility(\"default\")))"
|
||||
# "SP_PRIV=__attribute__((visibility(\"hidden\")))")
|
||||
# target_include_directories(blisp PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport)
|
||||
# write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.")
|
||||
#endif()
|
@ -13,4 +13,5 @@ Tool and library for flashing their RISC-V MCUs.
|
||||
# To Do
|
||||
|
||||
- [ ] Another code style
|
||||
- [ ] Separate `blisp` flashing to library
|
||||
- [ ] Finalize API
|
||||
- [ ] SDIO and JTAG support
|
29
include/blisp.h
Normal file
29
include/blisp.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef _LIBBLISP_H
|
||||
#define _LIBBLISP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "blisp_chip.h"
|
||||
|
||||
struct blisp_device {
|
||||
struct blisp_chip* chip;
|
||||
void* serial_port;
|
||||
bool is_usb;
|
||||
uint32_t current_baud_rate;
|
||||
uint8_t rx_buffer[5000]; // TODO:
|
||||
uint8_t tx_buffer[5000];
|
||||
uint16_t error_code;
|
||||
};
|
||||
|
||||
struct blisp_boot_info {
|
||||
uint8_t boot_rom_version[4];
|
||||
uint8_t chip_id[8]; // TODO: BL60X only 6 bytes
|
||||
};
|
||||
|
||||
int32_t blisp_device_init(struct blisp_device* device, struct blisp_chip* chip);
|
||||
int32_t blisp_device_open(struct blisp_device* device, const char* port_name);
|
||||
int32_t blisp_device_handshake(struct blisp_device* device);
|
||||
int32_t blisp_device_get_boot_info(struct blisp_device* device, struct blisp_boot_info* boot_info);
|
||||
void blisp_device_close(struct blisp_device* device);
|
||||
|
||||
#endif
|
18
include/blisp_chip.h
Normal file
18
include/blisp_chip.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _BLISP_CHIP_H
|
||||
#define _BLISP_CHIP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
enum blisp_chip_type {
|
||||
BLISP_CHIP_BL70X
|
||||
};
|
||||
|
||||
struct blisp_chip { // TODO: Move elsewhere?
|
||||
enum blisp_chip_type type;
|
||||
bool usb_isp_available;
|
||||
};
|
||||
|
||||
extern struct blisp_chip blisp_chip_bl70x;
|
||||
|
||||
#endif
|
@ -1,6 +0,0 @@
|
||||
#ifndef _LIBBLISP_EASY_H
|
||||
#define _LIBBLISP_EASY_H
|
||||
|
||||
|
||||
|
||||
#endif
|
148
lib/blisp.c
Normal file
148
lib/blisp.c
Normal file
@ -0,0 +1,148 @@
|
||||
#include <blisp.h>
|
||||
#include <libserialport.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int32_t blisp_device_init(struct blisp_device* device, struct blisp_chip* chip)
|
||||
{
|
||||
device->chip = chip;
|
||||
device->is_usb = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t blisp_device_open(struct blisp_device* device, const char* port_name)
|
||||
{
|
||||
int ret;
|
||||
struct sp_port* serial_port = NULL;
|
||||
|
||||
if (port_name != NULL) {
|
||||
ret = sp_get_port_by_name(port_name, &serial_port);
|
||||
if (ret != SP_OK) {
|
||||
return -1; // TODO: Improve error codes
|
||||
}
|
||||
} else {
|
||||
if (!device->chip->usb_isp_available) {
|
||||
return -2; // Can't auto-find device due it doesn't have native USB
|
||||
}
|
||||
struct sp_port **port_list;
|
||||
ret = sp_list_ports(&port_list);
|
||||
if (ret != SP_OK) {
|
||||
return -1; // TODO: Improve error codes
|
||||
}
|
||||
for (int i = 0; port_list[i] != NULL; i++) {
|
||||
struct sp_port *port = port_list[i];
|
||||
|
||||
int vid, pid;
|
||||
sp_get_port_usb_vid_pid(port, &vid, &pid);
|
||||
if (vid == 0xFFFF && pid == 0xFFFF) {
|
||||
ret = sp_get_port_by_name(sp_get_port_name(port), &serial_port);
|
||||
if (ret != SP_OK) {
|
||||
return -1; // TODO: Improve error codes
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
sp_free_port_list(port_list);
|
||||
if (serial_port == NULL) {
|
||||
return -3; // Device not found
|
||||
}
|
||||
}
|
||||
|
||||
ret = sp_open(serial_port, SP_MODE_READ_WRITE);
|
||||
if (ret != SP_OK) { // TODO: Handle not found
|
||||
return -1;
|
||||
}
|
||||
sp_set_bits(serial_port, 8);
|
||||
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;
|
||||
if (device->is_usb) {
|
||||
device->current_baud_rate = 2000000;
|
||||
} else {
|
||||
device->current_baud_rate = 500000;
|
||||
}
|
||||
sp_set_baudrate(serial_port, device->current_baud_rate);
|
||||
device->serial_port = serial_port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t blisp_send_command(struct blisp_device* device, uint8_t command, void* payload, uint16_t payload_size, bool add_checksum)
|
||||
{
|
||||
int ret;
|
||||
struct sp_port* serial_port = device->serial_port;
|
||||
|
||||
device->tx_buffer[0] = command;
|
||||
device->tx_buffer[1] = 0;
|
||||
device->tx_buffer[2] = (payload_size >> 8) & 0xFF;
|
||||
device->tx_buffer[3] = payload_size & 0xFF;
|
||||
if (add_checksum) {
|
||||
uint32_t checksum = 0;
|
||||
checksum += device->tx_buffer[2] + device->tx_buffer[3];
|
||||
for (uint16_t i = 0; i < payload_size; i++) {
|
||||
checksum += *(uint8_t*)(payload + i);
|
||||
}
|
||||
device->tx_buffer[1] = checksum & 0xFF;
|
||||
}
|
||||
if (payload_size != 0) {
|
||||
memcpy(&device->tx_buffer[4], payload, payload_size);
|
||||
}
|
||||
ret = sp_blocking_write(serial_port, device->tx_buffer, 4 + payload_size, 1000);
|
||||
if (ret != (4 + payload_size)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t blisp_receive_response(struct blisp_device* device, bool expect_payload) {
|
||||
int ret;
|
||||
struct sp_port* serial_port = device->serial_port;
|
||||
ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 300);
|
||||
if (ret < 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int32_t blisp_device_handshake(struct blisp_device* device)
|
||||
{
|
||||
int ret;
|
||||
uint8_t handshake_buffer[600];
|
||||
struct sp_port* serial_port = device->serial_port;
|
||||
|
||||
if (device->is_usb) {
|
||||
sp_blocking_write(serial_port, "BOUFFALOLAB5555RESET\0\0", 22, 100);
|
||||
}
|
||||
uint32_t bytes_count = 0.003f * (float)device->current_baud_rate / 10.0f; // TODO: 0.003f is only for BL70X!
|
||||
if (bytes_count > 600) bytes_count = 600;
|
||||
memset(handshake_buffer, 'U', bytes_count);
|
||||
ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count, 100);
|
||||
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 -4; // didn't received response
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t blisp_device_get_boot_info(struct blisp_device* device, struct blisp_boot_info* boot_info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = blisp_send_command(device, 0x10, NULL, 0, false);
|
||||
if (ret < 0) return ret;
|
||||
|
||||
ret = blisp_receive_response(device, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void blisp_device_close(struct blisp_device* device)
|
||||
{
|
||||
struct sp_port* serial_port = device->serial_port;
|
||||
sp_close(serial_port);
|
||||
}
|
@ -1 +0,0 @@
|
||||
#include <blisp_easy.h>
|
6
lib/chip/blisp_chip_bl70x.c
Normal file
6
lib/chip/blisp_chip_bl70x.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "blisp.h"
|
||||
|
||||
struct blisp_chip blisp_chip_bl70x = {
|
||||
.type = BLISP_CHIP_BL70X,
|
||||
.usb_isp_available = true
|
||||
};
|
@ -5,6 +5,8 @@ add_executable(blisp src/main.c src/cmd/write.c)
|
||||
target_include_directories(blisp PRIVATE
|
||||
"${CMAKE_SOURCE_DIR}/include"
|
||||
"${CMAKE_SOURCE_DIR}/vendor/argtable3/src")
|
||||
|
||||
target_link_libraries(blisp PRIVATE
|
||||
libblisp
|
||||
argtable3)
|
||||
argtable3
|
||||
libblisp_static)
|
||||
|
||||
|
@ -1,18 +1,38 @@
|
||||
#include "../cmd.h"
|
||||
#include "argtable3.h"
|
||||
|
||||
void blisp_flash_firmware(const char* firmware_path) {
|
||||
printf("");
|
||||
}
|
||||
|
||||
#include <blisp.h>
|
||||
|
||||
#define REG_EXTENDED 1
|
||||
#define REG_ICASE (REG_EXTENDED << 1)
|
||||
|
||||
static struct arg_rex* cmd;
|
||||
static struct arg_file* binary_to_write;
|
||||
static struct arg_str* port_name;
|
||||
static struct arg_end* end;
|
||||
static void* cmd_write_argtable[3];
|
||||
static void* cmd_write_argtable[4];
|
||||
|
||||
void blisp_flash_firmware() {
|
||||
struct blisp_device device;
|
||||
uint32_t ret;
|
||||
ret = blisp_device_init(&device, &blisp_chip_bl70x);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to init device.\n");
|
||||
return;
|
||||
}
|
||||
ret = blisp_device_open(&device, port_name->count == 1 ? port_name->sval[0] : NULL);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to open device.\n");
|
||||
return;
|
||||
}
|
||||
printf("Sending a handshake...");
|
||||
ret = blisp_device_handshake(&device);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "\nFailed to handshake with device.\n");
|
||||
return;
|
||||
}
|
||||
printf(" OK\n");
|
||||
blisp_device_close(&device);
|
||||
}
|
||||
|
||||
int8_t
|
||||
cmd_write_args_init() {
|
||||
@ -20,7 +40,9 @@ cmd_write_args_init() {
|
||||
= arg_rex1(NULL, NULL, "write", NULL, REG_ICASE, NULL);
|
||||
cmd_write_argtable[1] = binary_to_write
|
||||
= arg_file1(NULL, NULL, "<input>", "Binary to write");
|
||||
cmd_write_argtable[2] = end = arg_end(10);
|
||||
cmd_write_argtable[2] = port_name
|
||||
= arg_str0("p", "port", "<port_name>", "Name/Path to the Serial Port (empty for search)");
|
||||
cmd_write_argtable[3] = end = arg_end(10);
|
||||
|
||||
if (arg_nullcheck(cmd_write_argtable) != 0) {
|
||||
fprintf(stderr, "insufficient memory\n");
|
||||
@ -40,7 +62,7 @@ uint8_t
|
||||
cmd_write_parse_exec(int argc, char** argv) {
|
||||
int errors = arg_parse(argc, argv, cmd_write_argtable);
|
||||
if (errors == 0) {
|
||||
blisp_flash_firmware(binary_to_write->filename[0]); // TODO: Error code?
|
||||
blisp_flash_firmware(); // TODO: Error code?
|
||||
return 1;
|
||||
} else if (cmd->count == 1) {
|
||||
cmd_write_args_print_glossary();
|
||||
|
Loading…
Reference in New Issue
Block a user