1 Commits
Author SHA1 Message Date
Marek Kraus 738626e67e Initial support for BL808
Not working yet
2022-11-10 21:36:00 +01:00
27 changed files with 1036 additions and 9882 deletions
+56 -2
View File
@@ -1,4 +1,58 @@
--- ---
BasedOnStyle: Chromium Language: Cpp
BasedOnStyle: GNU
IndentWidth: 4
AllowShortBlocksOnASingleLine: Empty
AllowShortFunctionsOnASingleLine: None
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: false
AfterCaseLabel: false
AfterEnum: false
AfterControlStatement: Never
AfterStruct : false
AfterUnion : false
AfterExternBlock : false
BeforeElse : false
BeforeWhile : false
AlignAfterOpenBracket: Align
AlignArrayOfStructures: Left
AlignEscapedNewlines: Right
AlignOperands: Align
AllowShortEnumsOnASingleLine: False
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine : false
AlwaysBreakAfterReturnType: AllDefinitions
AlignTrailingComments : true
AlignConsecutiveMacros: AcrossEmptyLines
KeepEmptyLinesAtTheStartOfBlocks : false
PointerAlignment : Left
QualifierAlignment : Left
ReferenceAlignment : Left
RemoveBracesLLVM : false
SpaceAfterCStyleCast : false
SpaceAfterLogicalNot : false
SpaceAfterTemplateKeyword : false
SpaceAroundPointerQualifiers : Before
SpaceBeforeAssignmentOperators : true
SpaceBeforeCaseColon : false
SpaceBeforeCpp11BracedList : false
SpaceBeforeParens : ControlStatements
SpaceBeforeParensOptions :
AfterControlStatements : true
AfterFunctionDeclarationName : false
AfterFunctionDefinitionName : false
AfterOverloadedOperator : false
SpaceBeforeRangeBasedForLoopColon : false
SpaceBeforeSquareBrackets : false
SpaceInEmptyBlock : false
SpaceInEmptyParentheses : false
SpacesInCStyleCastParentheses : false
SpacesInConditionalStatement : false
SpacesInContainerLiterals : false
SpacesInParentheses: false
SpacesInSquareBrackets : false
UseTab : Never
... BitFieldColonSpacing: None
BreakBeforeBinaryOperators: All
-3
View File
@@ -75,6 +75,3 @@ fabric.properties
# Android studio 3.1+ serialized cache file # Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser .idea/caches/build_file_checksums.ser
build/
.DS_Store
+7 -12
View File
@@ -8,7 +8,8 @@ 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_bl60x.c
lib/chip/blisp_chip_bl70x.c lib/blisp_easy.c) lib/chip/blisp_chip_bl70x.c
lib/chip/blisp_chip_bl808.c)
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/) target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/)
@@ -20,15 +21,15 @@ add_library(libblisp_static STATIC $<TARGET_OBJECTS:libblisp_obj>)
set_target_properties(libblisp PROPERTIES set_target_properties(libblisp PROPERTIES
PUBLIC_HEADER "include/blisp.h" PUBLIC_HEADER "include/blisp.h"
VERSION 0.0.1 VERSION 1.0
SOVERSION 1 SOVERSION 1
LIBRARY_OUTPUT_DIRECTORY "shared" LIBRARY_OUTPUT_DIRECTORY "shared"
OUTPUT_NAME "blisp") OUTPUT_NAME "blisp")
set_target_properties(libblisp_static PROPERTIES set_target_properties(libblisp_static PROPERTIES
PUBLIC_HEADER "include/blisp.h" PUBLIC_HEADER "include/blisp.h"
VERSION 0.0.1 VERSION 1.0
SOVERSION 2 SOVERSION 1
ARCHIVE_OUTPUT_DIRECTORY "static" ARCHIVE_OUTPUT_DIRECTORY "static"
OUTPUT_NAME "blisp") OUTPUT_NAME "blisp")
@@ -49,20 +50,14 @@ elseif(UNIX AND NOT APPLE)
${CMAKE_SOURCE_DIR}/vendor/libserialport/linux_termios.c) ${CMAKE_SOURCE_DIR}/vendor/libserialport/linux_termios.c)
target_compile_definitions(libblisp_obj PRIVATE target_compile_definitions(libblisp_obj PRIVATE
LIBSERIALPORT_ATBUILD LIBSERIALPORT_ATBUILD
HAVE_TERMIOS2_SPEED
HAVE_STRUCT_TERMIOS2
HAVE_DECL_BOTHER
"SP_API=__attribute__((visibility(\"default\")))" "SP_API=__attribute__((visibility(\"default\")))"
"SP_PRIV=__attribute__((visibility(\"hidden\")))") "SP_PRIV=__attribute__((visibility(\"hidden\")))")
write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.") write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.")
elseif(APPLE) elseif(APPLE)
target_sources(libblisp_obj PRIVATE target_sources(libblisp_obj PRIVATE
${CMAKE_SOURCE_DIR}/vendor/libserialport/macosx.c) ${CMAKE_SOURCE_DIR}/vendor/libserialport/macosx.c)
target_link_libraries(libblisp PRIVATE "-framework IOKit" "-framework CoreFoundation") target_link_libraries(libblisp_obj PRIVATE "-framework IOKit" "-framework CoreFoundation")
target_compile_definitions(libblisp_obj PRIVATE target_compile_definitions(libblisp_obj PRIVATE LIBSERIALPORT_ATBUILD "SP_API=__attribute__((visibility(\"default\")))")
LIBSERIALPORT_ATBUILD
"SP_PRIV=__attribute__((visibility(\"hidden\")))"
"SP_API=__attribute__((visibility(\"default\")))")
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport) target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport)
write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.") write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.")
endif() endif()
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 Marek Kraus <gamelaster@outlook.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+8 -22
View File
@@ -1,35 +1,19 @@
# Bouffalo Labs ISP tool & library # Bouffalo Labs ISP tool & library
Open source tool and library for flashing Bouffalo RISC-V MCUs. Tool and library for flashing their RISC-V MCUs.
**NOTE:** Library API and `blisp` tool cli arguments are not stable yet. **NOTE:** Library API and `blisp` tool cli arguments are not stable yet.
# Supported MCUs # Supported MCUs
- [x] `bl60x` - BL602 / BL604 - [X] `bl60x` - BL602 / BL604
- [x] `bl70x` - BL702 / BL704 / BL706 - [X] `bl70x` - BL702 / BL704 / BL706
- [ ] `bl606p` - BL606P - [ ] `bl606p` - BL606P
- [ ] `bl61x` - BL616 / BL618 - [ ] `bl61x` - BL616 / BL618
- [ ] `bl808` - BL808 - [ ] `bl808` - BL808
# Supported OS
- [x] Windows
- [x] Linux
- [ ] Apple (WIP: work-in-progress)
# Building # Building
## Clone repository
If you have not cloned this repository locally; clone the git repository locally by running
```bash
git clone --recursive https://github.com/pine64/blisp.git
cd blisp
```
## Build the library and command line utility
For building `blisp` command line tool, use following commands: For building `blisp` command line tool, use following commands:
```bash ```bash
@@ -43,7 +27,7 @@ cmake --build .
For BL70X, BL61X, BL808 and BL606P, connected via USB, you can use following command, which will auto-detect serial port: For BL70X, BL61X, BL808 and BL606P, connected via USB, you can use following command, which will auto-detect serial port:
```bash ```bash
blisp write --chip bl70x --reset name_of_firmware.bin blisp --chip bl70x --reset name_of_firmware.bin
``` ```
For BL60X, you need to specify also the serial port path: For BL60X, you need to specify also the serial port path:
@@ -52,6 +36,8 @@ For BL60X, you need to specify also the serial port path:
blisp --chip bl60x --reset -p /dev/ttyUSB0 name_of_firmware.bin blisp --chip bl60x --reset -p /dev/ttyUSB0 name_of_firmware.bin
``` ```
# How to flash Pinecil V2 # To Do
Check out the [wiki page](https://github.com/pine64/blisp/wiki/Update-Pinecil-V2). - [ ] Another code style
- [ ] Finalize API
- [ ] SDIO and JTAG support
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+8 -34
View File
@@ -1,4 +1,3 @@
// SPDX-License-Identifier: MIT
#ifndef _LIBBLISP_H #ifndef _LIBBLISP_H
#define _LIBBLISP_H #define _LIBBLISP_H
@@ -6,18 +5,6 @@
#include "blisp_chip.h" #include "blisp_chip.h"
enum blisp_return {
BLISP_OK = 0,
BLISP_ERR_UNKNOWN = -1,
BLISP_ERR_NO_RESPONSE = -2,
BLISP_ERR_DEVICE_NOT_FOUND = -3,
BLISP_ERR_CANT_OPEN_DEVICE = -4,
// Can't auto-find device due it doesn't have native USB
BLISP_ERR_NO_AUTO_FIND_AVAILABLE = -5,
BLISP_ERR_PENDING = -6,
BLISP_ERR_CHIP_ERR = -7
};
struct blisp_segment_header { struct blisp_segment_header {
uint32_t dest_addr; uint32_t dest_addr;
uint32_t length; uint32_t length;
@@ -40,35 +27,22 @@ struct blisp_boot_info {
uint8_t chip_id[8]; // TODO: BL60X only 6 bytes uint8_t chip_id[8]; // TODO: BL60X only 6 bytes
}; };
// TODO: Refactor variable names, so all will follow same semantic, like // TODO: Refactor variable names, so all will follow same semantic, like image_run, image_check etc.
// image_run, image_check etc.
int32_t blisp_device_init(struct blisp_device* device, struct blisp_chip* chip); 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_open(struct blisp_device* device, const char* port_name);
int32_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader); int32_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader);
int32_t blisp_device_get_boot_info(struct blisp_device* device, int32_t blisp_device_get_boot_info(struct blisp_device* device, struct blisp_boot_info* boot_info);
struct blisp_boot_info* boot_info); int32_t blisp_device_load_boot_header(struct blisp_device* device, uint8_t* boot_header);
int32_t blisp_device_load_boot_header(struct blisp_device* device, int32_t blisp_device_load_segment_header(struct blisp_device* device, struct blisp_segment_header* segment_header);
uint8_t* boot_header); int32_t blisp_device_load_segment_data(struct blisp_device* device, uint8_t* segment_data, uint32_t segment_data_length);
int32_t blisp_device_load_segment_header(
struct blisp_device* device,
struct blisp_segment_header* segment_header);
int32_t blisp_device_load_segment_data(struct blisp_device* device,
uint8_t* segment_data,
uint32_t segment_data_length);
int32_t blisp_device_write_memory(struct blisp_device* device, int32_t blisp_device_write_memory(struct blisp_device* device,
uint32_t address, uint32_t address, uint32_t value,
uint32_t value,
bool wait_for_res); bool wait_for_res);
int32_t blisp_device_check_image(struct blisp_device* device); int32_t blisp_device_check_image(struct blisp_device* device);
int32_t blisp_device_run_image(struct blisp_device* device); int32_t blisp_device_run_image(struct blisp_device* device);
int32_t blisp_device_flash_erase(struct blisp_device* device, int32_t blisp_device_flash_erase(struct blisp_device* device, uint32_t start_address, uint32_t end_address);
uint32_t start_address, int32_t blisp_device_flash_write(struct blisp_device* device, uint32_t start_address, uint8_t* payload, uint32_t payload_size);
uint32_t end_address);
int32_t blisp_device_flash_write(struct blisp_device* device,
uint32_t start_address,
uint8_t* payload,
uint32_t payload_size);
int32_t blisp_device_program_check(struct blisp_device* device); int32_t blisp_device_program_check(struct blisp_device* device);
int32_t blisp_device_reset(struct blisp_device* device); int32_t blisp_device_reset(struct blisp_device* device);
void blisp_device_close(struct blisp_device* device); void blisp_device_close(struct blisp_device* device);
+3 -9
View File
@@ -1,16 +1,13 @@
// SPDX-License-Identifier: MIT
#ifndef _BLISP_CHIP_H #ifndef _BLISP_CHIP_H
#define _BLISP_CHIP_H #define _BLISP_CHIP_H
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
enum blisp_chip_type { enum blisp_chip_type {
BLISP_CHIP_BL60X, BLISP_CHIP_BL60X,
BLISP_CHIP_BL70X, BLISP_CHIP_BL70X,
BLISP_CHIP_BL606P, BLISP_CHIP_BL808
BLISP_CHIP_BL808,
BLISP_CHIP_BL61X,
}; };
struct blisp_chip { // TODO: Move elsewhere? struct blisp_chip { // TODO: Move elsewhere?
@@ -18,14 +15,11 @@ struct blisp_chip { // TODO: Move elsewhere?
const char* type_str; const char* type_str;
bool usb_isp_available; bool usb_isp_available;
float handshake_byte_multiplier; float handshake_byte_multiplier;
const char* default_xtal; // TODO: Make this selectable const char* default_eflash_loader_xtal; // TODO: Make this selectable
int64_t (*load_eflash_loader)(uint8_t clk_type, uint8_t** firmware_buf_ptr);
uint32_t tcm_address;
}; };
extern struct blisp_chip blisp_chip_bl60x; extern struct blisp_chip blisp_chip_bl60x;
extern struct blisp_chip blisp_chip_bl70x; extern struct blisp_chip blisp_chip_bl70x;
extern struct blisp_chip blisp_chip_bl808; extern struct blisp_chip blisp_chip_bl808;
extern struct blisp_chip blisp_chip_bl61x;
#endif #endif
-54
View File
@@ -1,54 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef BLISP_BLISP_EASY_H
#define BLISP_BLISP_EASY_H
#include <stdio.h>
#include "blisp.h"
struct blisp_easy_transport {
uint8_t type; // 0 - memory, 1 - FILE file_handle
union {
FILE* file_handle;
struct {
void* data_location;
uint32_t data_size;
uint32_t current_position;
} memory;
} data;
};
enum blisp_easy_error {
BLISP_EASY_ERR_TRANSPORT_ERROR = -100,
BLISP_EASY_ERR_CHECK_IMAGE_FAILED = -101
};
typedef void (*blisp_easy_progress_callback)(uint32_t current_value,
uint32_t max_value);
struct blisp_easy_transport blisp_easy_transport_new_from_file(FILE* file);
struct blisp_easy_transport blisp_easy_transport_new_from_memory(
void* data_location,
uint32_t data_size);
int32_t blisp_easy_load_segment_data(
struct blisp_device* device,
uint32_t segment_size,
struct blisp_easy_transport* segment_transport,
blisp_easy_progress_callback progress_callback);
int32_t blisp_easy_load_ram_image(
struct blisp_device* device,
struct blisp_easy_transport* image_transport,
blisp_easy_progress_callback progress_callback);
int32_t blisp_easy_load_ram_app(struct blisp_device* device,
struct blisp_easy_transport* app_transport,
blisp_easy_progress_callback progress_callback);
int32_t blisp_easy_flash_write(struct blisp_device* device,
struct blisp_easy_transport* data_transport,
uint32_t flash_location,
uint32_t data_size,
blisp_easy_progress_callback progress_callback);
#endif // BLISP_BLISP_EASY_H
+17 -16
View File
@@ -6,18 +6,16 @@
#ifndef _LIBBLISP_STRUCT_H #ifndef _LIBBLISP_STRUCT_H
#define _LIBBLISP_STRUCT_H #define _LIBBLISP_STRUCT_H
#include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h>
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct { typedef struct {
uint8_t ioMode; /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */ uint8_t ioMode; /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */
uint8_t cReadSupport; /*!< Support continuous read mode,bit0:continuous read uint8_t cReadSupport; /*!< Support continuous read mode,bit0:continuous read mode support,bit1:read mode cfg */
mode support,bit1:read mode cfg */
uint8_t clkDelay; /*!< SPI clock delay,bit0-3:delay,bit4-6:pad delay */ uint8_t clkDelay; /*!< SPI clock delay,bit0-3:delay,bit4-6:pad delay */
uint8_t clkInvert; /*!< SPI clock phase invert,bit0:clck invert,bit1:rx uint8_t clkInvert; /*!< SPI clock phase invert,bit0:clck invert,bit1:rx invert,bit2-4:pad delay,bit5-7:pad delay */
invert,bit2-4:pad delay,bit5-7:pad delay */
uint8_t resetEnCmd; /*!< Flash enable reset command */ uint8_t resetEnCmd; /*!< Flash enable reset command */
uint8_t resetCmd; /*!< Flash reset command */ uint8_t resetCmd; /*!< Flash reset command */
uint8_t resetCreadCmd; /*!< Flash reset continuous read command */ uint8_t resetCreadCmd; /*!< Flash reset continuous read command */
@@ -90,13 +88,15 @@ typedef struct {
#define BFLB_BOOTROM_HASH_SIZE 256 / 8 #define BFLB_BOOTROM_HASH_SIZE 256 / 8
struct boot_flash_cfg_t { struct boot_flash_cfg_t
{
char magiccode[4]; /*'FCFG'*/ char magiccode[4]; /*'FCFG'*/
SPI_Flash_Cfg_Type cfg; SPI_Flash_Cfg_Type cfg;
uint32_t crc32; uint32_t crc32;
}; };
struct sys_clk_cfg_t { struct sys_clk_cfg_t
{
uint8_t xtal_type; uint8_t xtal_type;
uint8_t pll_clk; uint8_t pll_clk;
uint8_t hclk_div; uint8_t hclk_div;
@@ -107,13 +107,15 @@ struct sys_clk_cfg_t {
uint8_t rsvd[2]; uint8_t rsvd[2];
}; };
struct boot_clk_cfg_t { struct boot_clk_cfg_t
{
char magiccode[4]; /*'PCFG'*/ char magiccode[4]; /*'PCFG'*/
struct sys_clk_cfg_t cfg; struct sys_clk_cfg_t cfg;
uint32_t crc32; uint32_t crc32;
}; };
struct bfl_boot_header { struct bfl_boot_header
{
char magiccode[4]; /*'BFXP'*/ char magiccode[4]; /*'BFXP'*/
uint32_t revison; uint32_t revison;
struct boot_flash_cfg_t flashCfg; struct boot_flash_cfg_t flashCfg;
@@ -126,8 +128,7 @@ struct bfl_boot_header {
uint32_t rsvd6_7 : 2; /* [7: 6] for encrypt*/ uint32_t rsvd6_7 : 2; /* [7: 6] for encrypt*/
uint32_t no_segment : 1; /* [8] no segment info */ uint32_t no_segment : 1; /* [8] no segment info */
uint32_t cache_enable : 1; /* [9] for cache */ uint32_t cache_enable : 1; /* [9] for cache */
uint32_t uint32_t notload_in_bootrom : 1; /* [10] not load this img in bootrom */
notload_in_bootrom : 1; /* [10] not load this img in bootrom */
uint32_t aes_region_lock : 1; /* [11] aes region lock */ uint32_t aes_region_lock : 1; /* [11] aes region lock */
uint32_t cache_way_disable : 4; /* [15: 12] cache way disable info*/ uint32_t cache_way_disable : 4; /* [15: 12] cache way disable info*/
uint32_t crc_ignore : 1; /* [16] ignore crc */ uint32_t crc_ignore : 1; /* [16] ignore crc */
@@ -154,18 +155,18 @@ struct bfl_boot_header {
uint32_t crc32; uint32_t crc32;
}; };
static_assert(sizeof(struct bfl_boot_header) == 176, static_assert(sizeof(struct bfl_boot_header) == 176, "Bootheader have wrong size");
"Bootheader have wrong size");
struct blflash_segment_header { struct blflash_segment_header
{
uint32_t destaddr; uint32_t destaddr;
uint32_t len; uint32_t len;
uint32_t rsvd; uint32_t rsvd;
uint32_t crc32; uint32_t crc32;
}; };
static_assert(sizeof(struct blflash_segment_header) == 16, static_assert(sizeof(struct blflash_segment_header) == 16, "Segment header have wrong size");
"Segment header have wrong size");
#pragma pack(pop) #pragma pack(pop)
-77
View File
@@ -1,26 +1,12 @@
// SPDX-License-Identifier: MIT
#ifndef _BLISP_UTIL_H #ifndef _BLISP_UTIL_H
#define _BLISP_UTIL_H #define _BLISP_UTIL_H
#include <stdarg.h>
#include <stdio.h>
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
#else #else
#include <time.h> #include <time.h>
#endif #endif
static void blisp_dlog(const char* format, ...)
{
fflush(stdout);
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fputc('\n', stderr);
}
static void sleep_ms(int milliseconds){ static void sleep_ms(int milliseconds){
#ifdef WIN32 #ifdef WIN32
Sleep(milliseconds); Sleep(milliseconds);
@@ -32,67 +18,4 @@ static void sleep_ms(int milliseconds) {
#endif #endif
} }
/**
* * Generated on Mon Jan 9 19:56:36 2023
* by pycrc vunknown, https://pycrc.org
* using the configuration:
* - Width = 32
* - Poly = 0x04c11db7
* - XorIn = 0xffffffff
* - ReflectIn = True
* - XorOut = 0xffffffff
* - ReflectOut = True
* - Algorithm = table-driven
*/
static const uint32_t crc_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
};
static uint32_t crc32_calculate(const void *data, size_t data_len)
{
uint32_t crc = 0xffffffff;
const unsigned char *d = (const unsigned char *)data;
unsigned int tbl_idx;
while (data_len--) {
tbl_idx = (crc ^ *d) & 0xff;
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff;
d++;
}
return (crc & 0xffffffff) ^ 0xffffffff;
}
#endif #endif
+120 -176
View File
@@ -1,44 +1,37 @@
// SPDX-License-Identifier: MIT
#include <blisp.h> #include <blisp.h>
#include <blisp_util.h>
#include <libserialport.h> #include <libserialport.h>
#include <malloc.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <blisp_util.h>
#ifdef __linux__
#include <linux/serial.h>
#include <sys/ioctl.h>
#endif
#define DEBUG #define DEBUG
int32_t blisp_device_init(struct blisp_device* device, int32_t blisp_device_init(struct blisp_device* device, struct blisp_chip* chip)
struct blisp_chip* chip) { {
device->chip = chip; device->chip = chip;
device->is_usb = false; device->is_usb = false;
return 0; return 0;
} }
int32_t blisp_device_open(struct blisp_device* device, const char* port_name) { int32_t blisp_device_open(struct blisp_device* device, const char* port_name)
{
int ret; int ret;
struct sp_port* serial_port = NULL; struct sp_port* serial_port = NULL;
if (port_name != NULL) { if (port_name != NULL) {
ret = sp_get_port_by_name(port_name, &serial_port); ret = sp_get_port_by_name(port_name, &serial_port);
if (ret != SP_OK) { if (ret != SP_OK) {
blisp_dlog("Couldn't open device, err: %d", ret); return -1; // TODO: Improve error codes
return BLISP_ERR_CANT_OPEN_DEVICE;
} }
} else { } else {
if (!device->chip->usb_isp_available) { if (!device->chip->usb_isp_available) {
return BLISP_ERR_NO_AUTO_FIND_AVAILABLE; return -2; // Can't auto-find device due it doesn't have native USB
} }
struct sp_port **port_list; struct sp_port **port_list;
ret = sp_list_ports(&port_list); ret = sp_list_ports(&port_list);
if (ret != SP_OK) { if (ret != SP_OK) {
blisp_dlog("Couldn't list ports, err: %d", ret); return -1; // TODO: Improve error codes
return BLISP_ERR_UNKNOWN;
} }
for (int i = 0; port_list[i] != NULL; i++) { for (int i = 0; port_list[i] != NULL; i++) {
struct sp_port *port = port_list[i]; struct sp_port *port = port_list[i];
@@ -48,26 +41,21 @@ int32_t blisp_device_open(struct blisp_device* device, const char* port_name) {
if (vid == 0xFFFF && pid == 0xFFFF) { if (vid == 0xFFFF && pid == 0xFFFF) {
ret = sp_get_port_by_name(sp_get_port_name(port), &serial_port); ret = sp_get_port_by_name(sp_get_port_name(port), &serial_port);
if (ret != SP_OK) { if (ret != SP_OK) {
blisp_dlog("Couldn't open device, err: %d", ret); return -1; // TODO: Improve error codes
return BLISP_ERR_CANT_OPEN_DEVICE;
} }
break; break;
} }
} }
sp_free_port_list(port_list); sp_free_port_list(port_list);
if (serial_port == NULL) { if (serial_port == NULL) {
return BLISP_ERR_DEVICE_NOT_FOUND; return -3; // Device not found
} }
} }
ret = sp_open(serial_port, SP_MODE_READ_WRITE); ret = sp_open(serial_port, SP_MODE_READ_WRITE);
if (ret != SP_OK) { if (ret != SP_OK) { // TODO: Handle not found
blisp_dlog("SP open failed: %d", ret); return -1;
return BLISP_ERR_UNKNOWN; // TODO: Maybe this should be that it can't open
// device?
} }
// TODO: Handle errors in following functions, although, none of them *should*
// fail
sp_set_bits(serial_port, 8); sp_set_bits(serial_port, 8);
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);
@@ -81,31 +69,14 @@ int32_t blisp_device_open(struct blisp_device* device, const char* port_name) {
// } else { // } else {
device->current_baud_rate = 500000; device->current_baud_rate = 500000;
// } // }
sp_set_baudrate(serial_port, device->current_baud_rate);
#if 0
int fd;
sp_get_port_handle(serial_port, &fd);
struct serial_struct serial;
ioctl(fd, TIOCGSERIAL, &serial);
// serial.flags &= ~(ASYNC_LOW_LATENCY);
serial.flags |= ASYNC_LOW_LATENCY;
ioctl(fd, TIOCSSERIAL, &serial);
#endif
ret = sp_set_baudrate(serial_port, device->current_baud_rate);
if (ret != SP_OK) {
blisp_dlog("Set baud rate failed: %d... Also hello macOS user :)", ret);
return BLISP_ERR_UNKNOWN;
}
device->serial_port = serial_port; device->serial_port = serial_port;
return BLISP_OK; return 0;
} }
int32_t blisp_send_command(struct blisp_device* device, int32_t blisp_send_command(struct blisp_device* device, uint8_t command, void* payload, uint16_t payload_size, bool add_checksum)
uint8_t command, {
void* payload,
uint16_t payload_size,
bool add_checksum) {
int ret; int ret;
struct sp_port* serial_port = device->serial_port; struct sp_port* serial_port = device->serial_port;
@@ -124,49 +95,46 @@ int32_t blisp_send_command(struct blisp_device* device,
if (payload_size != 0) { if (payload_size != 0) {
memcpy(&device->tx_buffer[4], payload, payload_size); memcpy(&device->tx_buffer[4], payload, payload_size);
} }
ret = ret = sp_blocking_write(serial_port, device->tx_buffer, 4 + payload_size, 1000);
sp_blocking_write(serial_port, device->tx_buffer, 4 + payload_size, 1000);
if (ret != (4 + payload_size)) { if (ret != (4 + payload_size)) {
blisp_dlog("Received error or not written all data: %d", ret); return -1;
return BLISP_ERR_UNKNOWN;
} }
return BLISP_OK; return 0;
} }
int32_t blisp_receive_response(struct blisp_device* device, int32_t blisp_receive_response(struct blisp_device* device, bool expect_payload) {
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, 1000); ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 500);
if (ret < 2) { if (ret < 2) {
blisp_dlog("Failed to receive response, ret: %d", ret); #ifdef DEBUG
return BLISP_ERR_UNKNOWN; // TODO: Terrible fprintf(stderr, "Failed to receive response. (ret = %d)\n", ret);
#endif
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, sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100); // TODO: Check if really we received the data.
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;
} }
return 0; return 0;
} else if (device->rx_buffer[0] == 'P' && device->rx_buffer[1] == 'D') { } else if (device->rx_buffer[0] == 'P' && device->rx_buffer[1] == 'D') {
return BLISP_ERR_PENDING; // TODO: This might be rather positive return return -3; // TODO: Terrible
// number?
} else if (device->rx_buffer[0] == 'F' && device->rx_buffer[1] == 'L') { } else if (device->rx_buffer[0] == 'F' && device->rx_buffer[1] == 'L') {
sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100); sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100);
device->error_code = (device->rx_buffer[3] << 8) | (device->rx_buffer[2]); device->error_code = (device->rx_buffer[3] << 8) | (device->rx_buffer[2]);
blisp_dlog("Chip returned error: %d", device->error_code); return -4; // Failed
return BLISP_ERR_CHIP_ERR;
} }
blisp_dlog("Failed to receive any response (err: %d, %d - %d)", ret, #ifdef DEBUG
device->rx_buffer[0], device->rx_buffer[1]); fprintf(stderr, "Receive response failed... (err: %d, %d - %d)\n", ret, device->rx_buffer[0], device->rx_buffer[1]);
return BLISP_ERR_UNKNOWN; #endif
return -1;
} }
int32_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) { int32_t
blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) {
int ret; int ret;
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;
@@ -178,226 +146,202 @@ int32_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) {
sp_set_dtr(serial_port, SP_DTR_OFF); sp_set_dtr(serial_port, SP_DTR_OFF);
sleep_ms(100); sleep_ms(100);
sp_set_rts(serial_port, SP_RTS_OFF); sp_set_rts(serial_port, SP_RTS_OFF);
sleep_ms(50); // Wait a bit so BootROM can init
} }
uint32_t bytes_count = device->chip->handshake_byte_multiplier * uint32_t bytes_count = device->chip->handshake_byte_multiplier * (float)device->current_baud_rate / 10.0f;
(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) {
sp_blocking_write(serial_port, "BOUFFALOLAB5555RESET\0\0", 22, 100); sp_blocking_write(serial_port, "BOUFFALOLAB5555RESET\0\0", 22,
100); // TODO: Error handling
} }
} }
ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count, 500); ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count,
500);
if (ret < 0) { if (ret < 0) {
blisp_dlog("Handshake write failed, ret %d", ret); return -1;
return BLISP_ERR_UNKNOWN;
} }
if (!in_ef_loader && !device->is_usb) { if (device->chip->type == BLISP_CHIP_BL808) {
sp_drain(serial_port); // Wait for write to send all data sleep_ms(300);
sp_flush(serial_port, SP_BUF_INPUT); // Flush garbage out of RX const uint8_t second_handshake[] = { 0x50, 0x00, 0x08, 0x00, 0x38, 0xF0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18 };
sp_blocking_write(serial_port, second_handshake, sizeof(second_handshake), 300); // TODO: Error handling
} }
ret = sp_blocking_read(serial_port, device->rx_buffer, 20, 50);
ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 50);
if (ret >= 2) { if (ret >= 2) {
if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') { for (uint8_t j = 0; j < (ret - 1); j++) {
return BLISP_OK; if (device->rx_buffer[j] == 'O' && device->rx_buffer[j + 1] == 'K') {
return 0;
} }
} }
} }
blisp_dlog("Received no response from chip."); }
return BLISP_ERR_NO_RESPONSE; return -4; // didn't received response
} }
int32_t blisp_device_get_boot_info(struct blisp_device* device, int32_t blisp_device_get_boot_info(struct blisp_device* device, struct blisp_boot_info* boot_info)
struct blisp_boot_info* boot_info) { {
int ret; int ret;
ret = blisp_send_command(device, 0x10, NULL, 0, false); ret = blisp_send_command(device, 0x10, NULL, 0, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
ret = blisp_receive_response(device, true); ret = blisp_receive_response(device, true);
if (ret < 0) if (ret < 0) return ret;
return ret;
memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], 4); // TODO: Endianess
4); // TODO: Endianess if (device->chip->type == BLISP_CHIP_BL70X || device->chip->type == BLISP_CHIP_BL808) { // TODO: This is only 70X related
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 // TODO: BL60X, BL808
return BLISP_OK; return 0;
} }
// TODO: Use struct instead of uint8_t* // TODO: Use struct instead of uint8_t*
int32_t blisp_device_load_boot_header(struct blisp_device* device, int32_t blisp_device_load_boot_header(struct blisp_device* device, uint8_t* boot_header)
uint8_t* boot_header) { {
int ret; int ret;
ret = blisp_send_command(device, 0x11, boot_header, 176, false); ret = blisp_send_command(device, 0x11, boot_header, 176, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
return BLISP_OK; return 0;
} }
int32_t blisp_device_load_segment_header( int32_t blisp_device_load_segment_header(struct blisp_device* device, struct blisp_segment_header* segment_header)
struct blisp_device* device, {
struct blisp_segment_header* segment_header) {
int ret; int ret;
ret = blisp_send_command(device, 0x17, segment_header, 16, false); ret = blisp_send_command(device, 0x17, segment_header, 16, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
ret = blisp_receive_response(device, true); // TODO: Handle response ret = blisp_receive_response(device, true); // TODO: Handle response
if (ret < 0) if (ret < 0) return ret;
return ret;
return BLISP_OK; return 0;
} }
int32_t blisp_device_load_segment_data(struct blisp_device* device, int32_t blisp_device_load_segment_data(struct blisp_device* device, uint8_t* segment_data, uint32_t segment_data_length)
uint8_t* segment_data, {
uint32_t segment_data_length) {
int ret; int ret;
ret = blisp_send_command(device, 0x18, segment_data, segment_data_length, ret = blisp_send_command(device, 0x18, segment_data, segment_data_length, false);
false); if (ret < 0) return ret;
if (ret < 0)
return ret;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
return BLISP_OK; return 0;
} }
int32_t blisp_device_check_image(struct blisp_device* device) { int32_t blisp_device_check_image(struct blisp_device* device)
{
int ret; int ret;
ret = blisp_send_command(device, 0x19, NULL, 0, false); ret = blisp_send_command(device, 0x19, NULL, 0, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
return BLISP_OK; return 0;
} }
int32_t blisp_device_write_memory(struct blisp_device* device, int32_t
uint32_t address, blisp_device_write_memory(struct blisp_device* device, uint32_t address,
uint32_t value, uint32_t value, bool wait_for_res) {
bool wait_for_res) {
int ret; int ret;
uint8_t payload[8]; uint8_t payload[8];
*(uint32_t*)(payload) = address; *(uint32_t*)(payload) = address;
*(uint32_t*)(payload + 4) = value; // TODO: Endianness *(uint32_t*)(payload + 4) = value; // TODO: Endianness
ret = blisp_send_command(device, 0x50, payload, 8, true); ret = blisp_send_command(device, 0x50, payload, 8, true);
if (ret < 0) if (ret < 0) return ret;
return ret;
if (wait_for_res) { if (wait_for_res) {
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
} }
return BLISP_OK; return 0;
} }
int32_t blisp_device_run_image(struct blisp_device* device) { int32_t blisp_device_run_image(struct blisp_device* device)
{
int ret; int ret;
if (device->chip->type == BLISP_CHIP_BL70X) { // ERRATA if (device->chip->type == BLISP_CHIP_BL70X) { // ERRATA
ret = blisp_device_write_memory(device, 0x4000F100, 0x4E424845, true); ret = blisp_device_write_memory(device, 0x4000F100, 0x4E424845, true);
if (ret < 0) if (ret < 0) return ret;
return ret;
ret = blisp_device_write_memory(device, 0x4000F104, 0x22010000, true); ret = blisp_device_write_memory(device, 0x4000F104, 0x22010000, true);
if (ret < 0) if (ret < 0) return ret;
return ret;
// ret = blisp_device_write_memory(device, 0x40000018, 0x00000000); // ret = blisp_device_write_memory(device, 0x40000018, 0x00000000);
// if (ret < 0) return ret; // if (ret < 0) return ret;
ret = blisp_device_write_memory(device, 0x40000018, 0x00000002, false); ret = blisp_device_write_memory(device, 0x40000018, 0x00000002, false);
if (ret < 0) if (ret < 0) return ret;
return ret; return 0;
return BLISP_OK;
} }
ret = blisp_send_command(device, 0x1A, NULL, 0, false); ret = blisp_send_command(device, 0x1A, NULL, 0, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
return BLISP_OK; return 0;
} }
int32_t blisp_device_flash_erase(struct blisp_device* device, int32_t
uint32_t start_address, blisp_device_flash_erase(struct blisp_device* device, uint32_t start_address, uint32_t end_address)
uint32_t end_address) { {
uint8_t payload[8]; uint8_t payload[8];
*(uint32_t*)(payload + 0) = start_address; *(uint32_t*)(payload + 0) = start_address;
*(uint32_t*)(payload + 4) = end_address; *(uint32_t*)(payload + 4) = end_address;
int ret = blisp_send_command(device, 0x30, payload, 8, true); int ret = blisp_send_command(device, 0x30, payload, 8, true);
if (ret < 0) if (ret < 0) return ret;
return ret;
do { do {
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
} while (ret == BLISP_ERR_PENDING); } while (ret == -3);
return 0; return 0;
} }
int32_t blisp_device_flash_write(struct blisp_device* device, int32_t
uint32_t start_address, blisp_device_flash_write(struct blisp_device* device, uint32_t start_address, uint8_t* payload, uint32_t payload_size)
uint8_t* payload, {
uint32_t payload_size) {
// TODO: Add max payload size (8184?) // TODO: Add max payload size (8184?)
// TODO: Don't use malloc + add check
uint8_t* buffer = malloc(4 + payload_size); uint8_t* buffer = malloc(4 + payload_size); // TODO: Don't use malloc + add check
*((uint32_t*)(buffer)) = start_address; *((uint32_t*)(buffer)) = start_address;
memcpy(buffer + 4, payload, payload_size); memcpy(buffer + 4, payload, payload_size);
int ret = blisp_send_command(device, 0x31, buffer, payload_size + 4, true); int ret = blisp_send_command(device, 0x31, buffer, payload_size + 4, true);
if (ret < 0) if (ret < 0) goto exit1;
goto exit1;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
exit1: exit1:
free(buffer); free(buffer);
return ret; return ret;
} }
int32_t blisp_device_program_check(struct blisp_device* device) { int32_t blisp_device_program_check(struct blisp_device* device)
{
int ret = blisp_send_command(device, 0x3A, NULL, 0, true); int ret = blisp_send_command(device, 0x3A, NULL, 0, true);
if (ret < 0) if (ret < 0) return ret;
return ret;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
return 0; return 0;
} }
int32_t blisp_device_reset(struct blisp_device* device) { int32_t blisp_device_reset(struct blisp_device* device)
{
int ret = blisp_send_command(device, 0x21, NULL, 0, true); int ret = blisp_send_command(device, 0x21, NULL, 0, true);
if (ret < 0) if (ret < 0) return ret;
return ret;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) if (ret < 0) return ret;
return ret;
return BLISP_OK; return 0;
} }
void blisp_device_close(struct blisp_device* device) { void blisp_device_close(struct blisp_device* device)
{
struct sp_port* serial_port = device->serial_port; struct sp_port* serial_port = device->serial_port;
sp_close(serial_port); sp_close(serial_port);
} }
-345
View File
@@ -1,345 +0,0 @@
// SPDX-License-Identifier: MIT
#include "blisp_easy.h"
#include "blisp_struct.h"
#include "blisp_util.h"
#include <inttypes.h>
#include <string.h>
static int64_t blisp_easy_transport_read(struct blisp_easy_transport* transport,
void* buffer,
uint32_t size) {
if (transport->type == 0) {
// TODO: Implement reading more than available
memcpy(buffer, (uint8_t*)transport->data.memory.data_location + transport->data.memory.current_position, size);
transport->data.memory.current_position += size;
return size;
} else {
return fread(buffer, size, 1, transport->data.file_handle);
}
}
static int64_t blisp_easy_transport_size(struct blisp_easy_transport* transport) {
if (transport->type == 0) {
return transport->data.memory.data_size;
} else {
// TODO: Implement
}
}
static void blisp_easy_report_progress(blisp_easy_progress_callback callback,
uint32_t current_value,
uint32_t max_value) {
if (callback != NULL) {
callback(current_value, max_value);
}
}
struct blisp_easy_transport blisp_easy_transport_new_from_file(FILE* file) {
struct blisp_easy_transport transport = {.type = 1, .data.file_handle = file};
return transport;
}
struct blisp_easy_transport blisp_easy_transport_new_from_memory(
void* data_location,
uint32_t data_size) {
struct blisp_easy_transport transport = {
.type = 0,
.data.memory.data_location = data_location,
.data.memory.data_size = data_size,
.data.memory.current_position = 0};
return transport;
}
int32_t blisp_easy_load_segment_data(
struct blisp_device* device,
uint32_t segment_size,
struct blisp_easy_transport* segment_transport,
blisp_easy_progress_callback progress_callback) {
int32_t ret;
uint32_t sent_data = 0;
uint32_t buffer_size = 0;
uint8_t buffer[4092];
blisp_easy_report_progress(progress_callback, 0, segment_size);
while (sent_data < segment_size) {
buffer_size = segment_size - sent_data;
if (buffer_size > 4092) {
buffer_size = 4092;
}
blisp_easy_transport_read(segment_transport, buffer,
buffer_size); // TODO: Error Handling
ret = blisp_device_load_segment_data(device, buffer, buffer_size);
if (ret < BLISP_OK) {
// TODO: Error logging fprintf(stderr, "Failed to load segment data. (ret
// %d)\n", ret);
return ret;
}
sent_data += buffer_size;
blisp_easy_report_progress(progress_callback, sent_data, segment_size);
}
return 0;
}
int32_t blisp_easy_load_ram_image(
struct blisp_device* device,
struct blisp_easy_transport* image_transport,
blisp_easy_progress_callback progress_callback) {
int32_t ret;
struct bfl_boot_header image_boot_header;
// TODO: Error handling
blisp_easy_transport_read(image_transport, &image_boot_header, 176);
ret = blisp_device_load_boot_header(device, (uint8_t*)&image_boot_header);
if (ret != BLISP_OK) {
// TODO: Error printing: fprintf(stderr, "Failed to load boot header.\n");
return ret;
}
{
for (uint8_t seg_index = 0;
seg_index < image_boot_header.segment_info.segment_cnt; seg_index++) {
struct blisp_segment_header segment_header = {0};
blisp_easy_transport_read(image_transport, &segment_header,
16); // TODO: Error handling
ret = blisp_device_load_segment_header(device, &segment_header);
if (ret != 0) {
// TODO: Error printing: fprintf(stderr, "Failed to load segment
// header.");
return ret;
}
// TODO: Info printing: printf("Flashing %d. segment\n", seg_index + 1);
ret = blisp_easy_load_segment_data(device, segment_header.length,
image_transport, progress_callback);
if (ret != 0) {
return ret;
}
}
}
ret = blisp_device_check_image(device);
if (ret != BLISP_OK) {
// TODO: Error printing: fprintf(stderr, "Failed to check image.\n");
return BLISP_EASY_ERR_CHECK_IMAGE_FAILED;
}
return BLISP_OK;
}
int32_t blisp_easy_load_ram_app(struct blisp_device* device,
struct blisp_easy_transport* app_transport,
blisp_easy_progress_callback progress_callback)
{
int32_t ret;
// TODO: Rework
// region boot header fill
struct bfl_boot_header boot_header;
memcpy(boot_header.magiccode, "BFNP", 4);
memcpy(boot_header.flashCfg.magiccode, "FCFG", 4);
boot_header.revison = 0x01;
boot_header.flashCfg.cfg.ioMode = 0x04;
boot_header.flashCfg.cfg.cReadSupport = 0x01;
boot_header.flashCfg.cfg.clkDelay = 0x01;
boot_header.flashCfg.cfg.clkInvert = 0x01;
boot_header.flashCfg.cfg.resetEnCmd = 0x66;
boot_header.flashCfg.cfg.resetCmd = 0x99;
boot_header.flashCfg.cfg.resetCreadCmd = 0xFF;
boot_header.flashCfg.cfg.resetCreadCmdSize = 0x03;
boot_header.flashCfg.cfg.jedecIdCmd = 0x9F;
boot_header.flashCfg.cfg.jedecIdCmdDmyClk = 0x00;
boot_header.flashCfg.cfg.qpiJedecIdCmd = 0x9F;
boot_header.flashCfg.cfg.qpiJedecIdCmdDmyClk = 0x00;
boot_header.flashCfg.cfg.sectorSize = 0x04;
boot_header.flashCfg.cfg.mid = 0xEF;
boot_header.flashCfg.cfg.pageSize = 0x100;
boot_header.flashCfg.cfg.chipEraseCmd = 0xC7;
boot_header.flashCfg.cfg.sectorEraseCmd = 0x20;
boot_header.flashCfg.cfg.blk32EraseCmd = 0x52;
boot_header.flashCfg.cfg.blk64EraseCmd = 0xD8;
boot_header.flashCfg.cfg.writeEnableCmd = 0x06;
boot_header.flashCfg.cfg.pageProgramCmd = 0x02;
boot_header.flashCfg.cfg.qpageProgramCmd = 0x32;
boot_header.flashCfg.cfg.qppAddrMode = 0x00;
boot_header.flashCfg.cfg.fastReadCmd = 0x0B;
boot_header.flashCfg.cfg.frDmyClk = 0x01;
boot_header.flashCfg.cfg.qpiFastReadCmd = 0x0B;
boot_header.flashCfg.cfg.qpiFrDmyClk = 0x01;
boot_header.flashCfg.cfg.fastReadDoCmd = 0x3B;
boot_header.flashCfg.cfg.frDoDmyClk = 0x01;
boot_header.flashCfg.cfg.fastReadDioCmd = 0xBB;
boot_header.flashCfg.cfg.frDioDmyClk = 0x00;
boot_header.flashCfg.cfg.fastReadQoCmd = 0x6B;
boot_header.flashCfg.cfg.frQoDmyClk = 0x01;
boot_header.flashCfg.cfg.fastReadQioCmd = 0xEB;
boot_header.flashCfg.cfg.frQioDmyClk = 0x02;
boot_header.flashCfg.cfg.qpiFastReadQioCmd = 0xEB;
boot_header.flashCfg.cfg.qpiFrQioDmyClk = 0x02;
boot_header.flashCfg.cfg.qpiPageProgramCmd = 0x02;
boot_header.flashCfg.cfg.writeVregEnableCmd = 0x50;
boot_header.flashCfg.cfg.wrEnableIndex = 0x00;
boot_header.flashCfg.cfg.qeIndex = 0x01;
boot_header.flashCfg.cfg.busyIndex = 0x00;
boot_header.flashCfg.cfg.wrEnableBit = 0x01;
boot_header.flashCfg.cfg.qeBit = 0x01;
boot_header.flashCfg.cfg.busyBit = 0x00;
boot_header.flashCfg.cfg.wrEnableWriteRegLen = 0x02;
boot_header.flashCfg.cfg.wrEnableReadRegLen = 0x01;
boot_header.flashCfg.cfg.qeWriteRegLen = 0x01;
boot_header.flashCfg.cfg.qeReadRegLen = 0x01;
boot_header.flashCfg.cfg.releasePowerDown = 0xAB;
boot_header.flashCfg.cfg.busyReadRegLen = 0x01;
boot_header.flashCfg.cfg.readRegCmd[0] = 0x05;
boot_header.flashCfg.cfg.readRegCmd[1] = 0x35;
boot_header.flashCfg.cfg.readRegCmd[2] = 0x00;
boot_header.flashCfg.cfg.readRegCmd[3] = 0x00;
boot_header.flashCfg.cfg.writeRegCmd[0] = 0x01;
boot_header.flashCfg.cfg.writeRegCmd[1] = 0x31;
boot_header.flashCfg.cfg.writeRegCmd[2] = 0x00;
boot_header.flashCfg.cfg.writeRegCmd[3] = 0x00;
boot_header.flashCfg.cfg.enterQpi = 0x38;
boot_header.flashCfg.cfg.exitQpi = 0xFF;
boot_header.flashCfg.cfg.cReadMode = 0x20;
boot_header.flashCfg.cfg.cRExit = 0xFF;
boot_header.flashCfg.cfg.burstWrapCmd = 0x77;
boot_header.flashCfg.cfg.burstWrapCmdDmyClk = 0x03;
boot_header.flashCfg.cfg.burstWrapDataMode = 0x02;
boot_header.flashCfg.cfg.burstWrapData = 0x40;
boot_header.flashCfg.cfg.deBurstWrapCmd = 0x77;
boot_header.flashCfg.cfg.deBurstWrapCmdDmyClk = 0x03;
boot_header.flashCfg.cfg.deBurstWrapDataMode = 0x02;
boot_header.flashCfg.cfg.deBurstWrapData = 0xF0;
boot_header.flashCfg.cfg.timeEsector = 0x12C;
boot_header.flashCfg.cfg.timeE32k = 0x4B0;
boot_header.flashCfg.cfg.timeE64k = 0x4B0;
boot_header.flashCfg.cfg.timePagePgm = 0x05;
boot_header.flashCfg.cfg.timeCe = 0xD40;
boot_header.flashCfg.cfg.pdDelay = 0x03;
boot_header.flashCfg.cfg.qeData = 0x00;
boot_header.flashCfg.crc32 = 0xC4BDD748;
boot_header.clkCfg.cfg.xtal_type = 0x04;
boot_header.clkCfg.cfg.pll_clk = 0x04;
boot_header.clkCfg.cfg.hclk_div = 0x00;
boot_header.clkCfg.cfg.bclk_div = 0x01;
boot_header.clkCfg.cfg.flash_clk_type = 0x02;
boot_header.clkCfg.cfg.flash_clk_div = 0x00;
boot_header.clkCfg.crc32 = 0x824E14BB;
boot_header.bootcfg.bval.sign = 0x00;
boot_header.bootcfg.bval.encrypt_type = 0x00;
boot_header.bootcfg.bval.key_sel = 0x00;
boot_header.bootcfg.bval.rsvd6_7 = 0x00;
boot_header.bootcfg.bval.no_segment = 0x01;
boot_header.bootcfg.bval.cache_enable = 0x01;
boot_header.bootcfg.bval.notload_in_bootrom = 0x00;
boot_header.bootcfg.bval.aes_region_lock = 0x00;
boot_header.bootcfg.bval.cache_way_disable = 0x00;
boot_header.bootcfg.bval.crc_ignore = 0x01;
boot_header.bootcfg.bval.hash_ignore = 0x01;
boot_header.bootcfg.bval.halt_ap = 0x00;
boot_header.bootcfg.bval.rsvd19_31 = 0x00;
boot_header.segment_info.segment_cnt = 0x01;
boot_header.bootentry = 0x00;
boot_header.flashoffset = device->chip->tcm_address;
boot_header.hash[0x00] = 0xEF;
boot_header.hash[0x01] = 0xBE;
boot_header.hash[0x02] = 0xAD;
boot_header.hash[0x03] = 0xDE;
boot_header.hash[0x04] = 0x00;
boot_header.hash[0x05] = 0x00;
boot_header.hash[0x06] = 0x00;
boot_header.hash[0x07] = 0x00;
boot_header.hash[0x08] = 0x00;
boot_header.hash[0x09] = 0x00;
boot_header.hash[0x0a] = 0x00;
boot_header.hash[0x0b] = 0x00;
boot_header.hash[0x0c] = 0x00;
boot_header.hash[0x0d] = 0x00;
boot_header.hash[0x0e] = 0x00;
boot_header.hash[0x0f] = 0x00;
boot_header.hash[0x10] = 0x00;
boot_header.hash[0x11] = 0x00;
boot_header.hash[0x12] = 0x00;
boot_header.hash[0x13] = 0x00;
boot_header.hash[0x14] = 0x00;
boot_header.hash[0x15] = 0x00;
boot_header.hash[0x16] = 0x00;
boot_header.hash[0x17] = 0x00;
boot_header.hash[0x18] = 0x00;
boot_header.hash[0x19] = 0x00;
boot_header.hash[0x1a] = 0x00;
boot_header.hash[0x1b] = 0x00;
boot_header.hash[0x1c] = 0x00;
boot_header.hash[0x1d] = 0x00;
boot_header.hash[0x1e] = 0x00;
boot_header.hash[0x1f] = 0x00;
boot_header.rsv1 = 0x00;
boot_header.rsv2 = 0x00;
boot_header.crc32 = 0xDEADBEEF;
// endregion
ret = blisp_device_load_boot_header(device, (uint8_t*)&boot_header);
if (ret != BLISP_OK) {
blisp_dlog("Failed to load boot header, ret: %d.", ret);
return ret;
}
struct blisp_segment_header segment_header = {
.dest_addr = device->chip->tcm_address,
.length = blisp_easy_transport_size(app_transport),
.reserved = 0,
.crc32 = 0
};
segment_header.crc32 = crc32_calculate(&segment_header, 3 * sizeof(uint32_t)); // TODO: Make function
ret = blisp_device_load_segment_header(device, &segment_header);
if (ret != 0) {
blisp_dlog("Failed to load segment header, ret: %d.", ret);
return ret;
}
ret = blisp_easy_load_segment_data(device, blisp_easy_transport_size(app_transport),
app_transport, progress_callback);
if (ret != 0) {
// TODO: Error printing
return ret;
}
return BLISP_OK;
}
int32_t blisp_easy_flash_write(struct blisp_device* device,
struct blisp_easy_transport* data_transport,
uint32_t flash_location,
uint32_t data_size,
blisp_easy_progress_callback progress_callback) {
int32_t ret;
uint32_t sent_data = 0;
uint32_t buffer_size = 0;
uint8_t buffer[8184];
blisp_easy_report_progress(progress_callback, 0, data_size);
while (sent_data < data_size) {
buffer_size = data_size - sent_data;
if (buffer_size > 2052) {
buffer_size = 2052;
}
blisp_easy_transport_read(data_transport, buffer,
buffer_size); // TODO: Error Handling
ret = blisp_device_flash_write(device, flash_location + sent_data, buffer,
buffer_size);
if (ret < BLISP_OK) {
// TODO: Error logigng: fprintf(stderr, "Failed to write firmware! (ret:
// %d)\n", ret);
return ret;
}
sent_data += buffer_size;
blisp_easy_report_progress(progress_callback, sent_data, data_size);
}
return BLISP_OK;
}
+1 -16
View File
@@ -1,24 +1,9 @@
// SPDX-License-Identifier: MIT
#include <malloc.h>
#include <string.h>
#include "../../data/bl60x_eflash_loader.h"
#include "blisp.h" #include "blisp.h"
int64_t blisp_chip_bl60x_get_eflash_loader(uint8_t clk_type, uint8_t** firmware_buf_ptr)
{
uint8_t* firmware_buf = malloc(sizeof(bl60x_eflash_loader_bin));
memcpy(firmware_buf, bl60x_eflash_loader_bin, sizeof(bl60x_eflash_loader_bin));
*(firmware_buf + 0xE0) = 4; // TODO: 40 MHz clock
*firmware_buf_ptr = firmware_buf;
return sizeof(bl60x_eflash_loader_bin);
}
struct blisp_chip blisp_chip_bl60x = { struct blisp_chip blisp_chip_bl60x = {
.type = BLISP_CHIP_BL60X, .type = BLISP_CHIP_BL60X,
.type_str = "bl60x", .type_str = "bl60x",
.usb_isp_available = false, .usb_isp_available = false,
.default_xtal = "40m", .default_eflash_loader_xtal = "40m",
.handshake_byte_multiplier = 0.006f, .handshake_byte_multiplier = 0.006f,
.load_eflash_loader = blisp_chip_bl60x_get_eflash_loader,
.tcm_address = 0x22010000
}; };
-11
View File
@@ -1,11 +0,0 @@
// SPDX-License-Identifier: MIT
#include "blisp.h"
struct blisp_chip blisp_chip_bl61x = {
.type = BLISP_CHIP_BL61X,
.type_str = "bl808",
.usb_isp_available = true,
.default_xtal = "-", // ?
.handshake_byte_multiplier = 0.003f,
.get_eflash_loader = NULL
};
+1 -17
View File
@@ -1,25 +1,9 @@
// SPDX-License-Identifier: MIT
#include <malloc.h>
#include <string.h>
#include "../../data/bl70x_eflash_loader.h"
#include "blisp.h" #include "blisp.h"
int64_t blisp_chip_bl70x_get_eflash_loader(uint8_t clk_type, uint8_t** firmware_buf_ptr)
{
uint8_t* firmware_buf = malloc(sizeof(bl70x_eflash_loader_bin));
memcpy(firmware_buf, bl70x_eflash_loader_bin, sizeof(bl70x_eflash_loader_bin));
*(firmware_buf + 0xE0) = 1; // TODO: 32 MHz clock
*firmware_buf_ptr = firmware_buf;
return sizeof(bl70x_eflash_loader_bin);
}
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_xtal = "32m", .default_eflash_loader_xtal = "32m",
.handshake_byte_multiplier = 0.003f, .handshake_byte_multiplier = 0.003f,
.load_eflash_loader = blisp_chip_bl70x_get_eflash_loader,
.tcm_address = 0x22010000
}; };
+2 -5
View File
@@ -1,11 +1,8 @@
// SPDX-License-Identifier: MIT
#include "blisp.h" #include "blisp.h"
struct blisp_chip blisp_chip_bl808 = { struct blisp_chip blisp_chip_bl808 = {
.type = BLISP_CHIP_BL808, .type = BLISP_CHIP_BL808,
.type_str = "bl808", .type_str = "bl808",
.usb_isp_available = true, // TODO: Only for BL808D :-( .usb_isp_available = true,
.default_xtal = "-", // ? .handshake_byte_multiplier = 0.006f,
.handshake_byte_multiplier = 0.003f,
.get_eflash_loader = NULL
}; };
+1 -3
View File
@@ -1,6 +1,6 @@
add_subdirectory(${CMAKE_SOURCE_DIR}/vendor/argtable3 ${CMAKE_CURRENT_BINARY_DIR}/argtable3) add_subdirectory(${CMAKE_SOURCE_DIR}/vendor/argtable3 ${CMAKE_CURRENT_BINARY_DIR}/argtable3)
add_executable(blisp src/main.c src/cmd/write.c src/util.c src/common.c src/cmd/iot.c) add_executable(blisp src/main.c src/cmd/write.c)
target_include_directories(blisp PRIVATE target_include_directories(blisp PRIVATE
"${CMAKE_SOURCE_DIR}/include" "${CMAKE_SOURCE_DIR}/include"
@@ -12,6 +12,4 @@ target_link_libraries(blisp PRIVATE
if(WIN32) if(WIN32)
target_link_libraries(blisp PRIVATE Setupapi.lib) target_link_libraries(blisp PRIVATE Setupapi.lib)
elseif (APPLE)
target_link_libraries(blisp PRIVATE "-framework IOKit" "-framework CoreFoundation")
endif() endif()
-2
View File
@@ -1,4 +1,3 @@
// SPDX-License-Identifier: MIT
#ifndef BLISP_CMD_H #ifndef BLISP_CMD_H
#define BLISP_CMD_H #define BLISP_CMD_H
@@ -13,6 +12,5 @@ struct cmd {
}; };
extern struct cmd cmd_write; extern struct cmd cmd_write;
extern struct cmd cmd_iot;
#endif // BLISP_CMD_H #endif // BLISP_CMD_H
-140
View File
@@ -1,140 +0,0 @@
#include <blisp_easy.h>
#include "../cmd.h"
#include "../common.h"
#include <argtable3.h>
#define REG_EXTENDED 1
#define REG_ICASE (REG_EXTENDED << 1)
static struct arg_rex* cmd;
static struct arg_file* single_download;
static struct arg_int* single_download_location;
static struct arg_str *port_name, *chip_type; // TODO: Make this common
static struct arg_lit* reset;
static struct arg_end* end;
static void* cmd_iot_argtable[7];
void blisp_single_download()
{
struct blisp_device device;
int32_t ret;
if (blisp_common_init_device(&device, port_name, chip_type) != 0) {
return;
}
if (blisp_common_prepare_flash(&device) != 0) {
// TODO: Error handling
goto exit1;
}
FILE* data_file = fopen(single_download->filename[0], "rb");
if (data_file == NULL) {
fprintf(stderr, "Failed to open data file \"%s\".\n",
single_download->filename[0]);
goto exit1;
}
fseek(data_file, 0, SEEK_END);
int64_t data_file_size = ftell(data_file);
rewind(data_file);
printf("Erasing the area, this might take a while...\n");
ret =
blisp_device_flash_erase(&device, *single_download_location->ival,
*single_download_location->ival + data_file_size + 1);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to erase.\n");
goto exit2;
}
printf("Writing the data...\n");
struct blisp_easy_transport data_transport =
blisp_easy_transport_new_from_file(data_file);
ret = blisp_easy_flash_write(&device, &data_transport, *single_download_location->ival,
data_file_size,
blisp_common_progress_callback);
if (ret < BLISP_OK) {
fprintf(stderr, "Failed to write data to flash.\n");
goto exit2;
}
printf("Checking program...\n");
ret = blisp_device_program_check(&device);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to check program.\n");
goto exit2;
}
printf("Program OK!\n");
if (reset->count > 0) { // TODO: could be common
blisp_device_reset(&device);
printf("Resetting the chip.\n");
}
printf("Download complete!\n");
exit2:
if (data_file != NULL)
fclose(data_file);
exit1:
blisp_device_close(&device);
}
int8_t cmd_iot_args_init() {
cmd_iot_argtable[0] = cmd =
arg_rex1(NULL, NULL, "iot", NULL, REG_ICASE, NULL);
cmd_iot_argtable[1] = chip_type =
arg_str1("c", "chip", "<chip_type>", "Chip Type");
cmd_iot_argtable[2] = port_name =
arg_str0("p", "port", "<port_name>",
"Name/Path to the Serial Port (empty for search)");
cmd_iot_argtable[3] = reset =
arg_lit0(NULL, "reset", "Reset chip after write");
cmd_iot_argtable[4] = single_download =
arg_file0("s", "single-down", "<file>", "Single download file");
cmd_iot_argtable[5] = single_download_location =
arg_int0("l", "single-down-loc", NULL, "Single download offset");
cmd_iot_argtable[6] = end = arg_end(10);
if (arg_nullcheck(cmd_iot_argtable) != 0) {
fprintf(stderr, "insufficient memory\n");
return -1;
}
return 0;
}
void cmd_iot_args_print_glossary() {
fputs("Usage: blisp", stdout);
arg_print_syntax(stdout, cmd_iot_argtable, "\n");
puts("Flashes firmware as Bouffalo's DevCube");
arg_print_glossary(stdout, cmd_iot_argtable, " %-25s %s\n");
}
uint8_t cmd_iot_parse_exec(int argc, char** argv) {
int errors = arg_parse(argc, argv, cmd_iot_argtable);
if (errors == 0) {
if (single_download->count == 1 && single_download_location->count == 1) {
blisp_single_download();
return 1;
} else {
return 0;
}
} else if (cmd->count == 1) {
cmd_iot_args_print_glossary();
return 1;
}
return 0;
}
void cmd_iot_args_print_syntax() {
arg_print_syntax(stdout, cmd_iot_argtable, "\n");
}
void cmd_iot_free() {
arg_freetable(cmd_iot_argtable,
sizeof(cmd_iot_argtable) / sizeof(cmd_iot_argtable[0]));
}
struct cmd cmd_iot = {"iot", cmd_iot_args_init, cmd_iot_parse_exec,
cmd_iot_args_print_syntax, cmd_iot_free};
+235 -64
View File
@@ -1,14 +1,19 @@
// SPDX-License-Identifier: MIT
#include <blisp.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include "../cmd.h" #include "../cmd.h"
#include "../common.h" #include "argtable3.h"
#include "../util.h" #include <blisp.h>
#include <argtable3.h> #include <string.h>
#include <blisp_easy.h> #include <inttypes.h>
#include <blisp_struct.h> #include "blisp_struct.h"
#ifdef __linux__
#include <unistd.h>
#include <linux/limits.h>
#elif defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#include <windows.h>
#define PATH_MAX MAX_PATH
#endif
#define REG_EXTENDED 1 #define REG_EXTENDED 1
#define REG_ICASE (REG_EXTENDED << 1) #define REG_ICASE (REG_EXTENDED << 1)
@@ -20,9 +25,22 @@ static struct arg_lit* reset;
static struct arg_end* end; static struct arg_end* end;
static void* cmd_write_argtable[6]; static void* cmd_write_argtable[6];
void fill_up_boot_header(struct bfl_boot_header* boot_header) { ssize_t
memcpy(boot_header->magiccode, "BFNP", 4); get_binary_folder(char* buffer, uint32_t buffer_size) {
#ifdef __linux__
readlink("/proc/self/exe", buffer, buffer_size); // TODO: Error handling
char* pos = strrchr(buffer, '/');
#else
GetModuleFileName(NULL, buffer, buffer_size);
char* pos = strrchr(buffer, '\\');
#endif
pos[0] = '\0';
return pos - buffer;
}
void fill_up_boot_header(struct bfl_boot_header* boot_header)
{
memcpy(boot_header->magiccode, "BFNP", 4);;
boot_header->revison = 0x01; boot_header->revison = 0x01;
memcpy(boot_header->flashCfg.magiccode, "FCFG", 4); memcpy(boot_header->flashCfg.magiccode, "FCFG", 4);
boot_header->flashCfg.cfg.ioMode = 0x11; boot_header->flashCfg.cfg.ioMode = 0x11;
@@ -165,22 +183,165 @@ void fill_up_boot_header(struct bfl_boot_header* boot_header) {
} }
void blisp_flash_firmware() { void blisp_flash_firmware() {
struct blisp_device device; FILE* eflash_loader_file = NULL;
int32_t ret;
if (blisp_common_init_device(&device, port_name, chip_type) != 0) { if (chip_type->count == 0) {
fprintf(stderr, "Chip type is invalid.\n");
return; return;
} }
if (blisp_common_prepare_flash(&device) != 0) { struct blisp_chip* chip = NULL;
// TODO: Error handling
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 if (strcmp(chip_type->sval[0], "bl808") == 0) {
chip = &blisp_chip_bl808;
} else {
fprintf(stderr, "Chip type is invalid.\n");
return;
}
struct blisp_device device;
int32_t ret;
ret = blisp_device_init(&device, chip);
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, false);
if (ret != 0) {
fprintf(stderr, "\nFailed to handshake with device.\n");
goto exit1; goto exit1;
} }
printf(" OK\nGetting chip info...");
struct blisp_boot_info boot_info;
ret = blisp_device_get_boot_info(&device, &boot_info);
if (ret != 0) {
fprintf(stderr, "\nFailed to get boot info.\n");
goto exit1;
}
if (boot_info.boot_rom_version[0] == 255 &&
boot_info.boot_rom_version[1] == 255 &&
boot_info.boot_rom_version[2] == 255 &&
boot_info.boot_rom_version[3] == 255) {
printf(" OK\nDevice already in eflash_loader.\n");
goto eflash_loader;
}
printf(" BootROM version %d.%d.%d.%d, ChipID: %02X%02X%02X%02X%02X%02X%02X%02X\n",
boot_info.boot_rom_version[0],
boot_info.boot_rom_version[1],
boot_info.boot_rom_version[2],
boot_info.boot_rom_version[3],
boot_info.chip_id[0],
boot_info.chip_id[1],
boot_info.chip_id[2],
boot_info.chip_id[3],
boot_info.chip_id[4],
boot_info.chip_id[5],
boot_info.chip_id[6],
boot_info.chip_id[7]);
if (device.chip->type == BLISP_CHIP_BL808) {
// Since eflash_loader is not needed in BL808, we can jump to flashing.
goto eflash_loader; // TODO: Rework
}
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_%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
fread(eflash_loader_header, 176, 1, eflash_loader_file); // TODO: Error handling
printf("Loading eflash_loader...\n");
ret = blisp_device_load_boot_header(&device, eflash_loader_header);
if (ret != 0) {
fprintf(stderr, "Failed to load boot header.\n");
goto exit1;
}
{
uint32_t sent_data = 0;
uint32_t buffer_size = 0;
uint8_t buffer[4092];
// TODO: Real checking of segments count
for (uint8_t seg_index = 0; seg_index < 1; seg_index++) {
struct blisp_segment_header segment_header = { 0 };
fread(&segment_header, 16, 1,
eflash_loader_file); // TODO: Error handling
ret = blisp_device_load_segment_header(&device, &segment_header);
if (ret != 0) {
fprintf(stderr, "Failed to load segment header.\n");
goto exit1;
}
printf("Flashing %d. segment\n", seg_index + 1);
printf("0b / %" PRIu32 "b (0.00%%)\n", segment_header.length);
while (sent_data < segment_header.length) {
buffer_size = segment_header.length - sent_data;
if (buffer_size > 4092) {
buffer_size = 4092;
}
fread(buffer, buffer_size, 1, eflash_loader_file);
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,
(((float)sent_data / (float)segment_header.length)
* 100.0f));
}
}
}
ret = blisp_device_check_image(&device);
if (ret != 0) {
fprintf(stderr, "Failed to check image.\n");
goto exit1;
}
ret = blisp_device_run_image(&device);
if (ret != 0) {
fprintf(stderr, "Failed to run image.\n");
goto exit1;
}
printf("Sending a handshake...");
ret = blisp_device_handshake(&device, true);
if (ret != 0) {
fprintf(stderr, "\nFailed to handshake with device.\n");
goto exit1;
}
printf(" OK\n");
eflash_loader:
if (device.chip->type == BLISP_CHIP_BL808) {
// Setting CLK configuration
// Setting Flash Config
// Setting Flash Parameter
}
FILE* firmware_file = fopen(binary_to_write->filename[0], "rb"); FILE* firmware_file = fopen(binary_to_write->filename[0], "rb");
if (firmware_file == NULL) { if (firmware_file == NULL) {
fprintf(stderr, "Failed to open firmware file \"%s\".\n", fprintf(stderr,"Failed to open firmware file \"%s\".\n", binary_to_write->filename[0]);
binary_to_write->filename[0]);
goto exit1; goto exit1;
} }
fseek(firmware_file, 0, SEEK_END); fseek(firmware_file, 0, SEEK_END);
@@ -191,47 +352,57 @@ void blisp_flash_firmware() {
fill_up_boot_header(&boot_header); fill_up_boot_header(&boot_header);
const uint32_t firmware_base_address = 0x2000; const uint32_t firmware_base_address = 0x2000;
printf("Erasing flash, this might take a while...\n"); printf("Erasing flash, this might take a while...");
ret = ret = blisp_device_flash_erase(&device, firmware_base_address,
blisp_device_flash_erase(&device, firmware_base_address, firmware_base_address + firmware_file_size
firmware_base_address + firmware_file_size + 1); + 1);
if (ret != BLISP_OK) { if (ret != 0) {
fprintf(stderr, "Failed to erase flash.\n"); fprintf(stderr, "\nFailed to erase flash.\n");
goto exit2; goto exit2;
} }
ret = ret = blisp_device_flash_erase(&device, 0x0000, sizeof(struct bfl_boot_header));
blisp_device_flash_erase(&device, 0x0000, sizeof(struct bfl_boot_header)); if (ret != 0) {
if (ret != BLISP_OK) { fprintf(stderr, "\nFailed to erase flash.\n");
fprintf(stderr, "Failed to erase flash.\n");
goto exit2; goto exit2;
} }
printf("Flashing boot header...\n"); printf(" OK!\nFlashing boot header...");
ret = blisp_device_flash_write(&device, 0x0000, (uint8_t*)&boot_header, ret = blisp_device_flash_write(&device, 0x0000, (uint8_t*)&boot_header, sizeof(struct bfl_boot_header));
sizeof(struct bfl_boot_header)); if (ret != 0) {
if (ret != BLISP_OK) { fprintf(stderr, "\nFailed to write boot header.\n");
fprintf(stderr, "Failed to write boot header.\n");
goto exit2; goto exit2;
} }
printf("Flashing the firmware...\n"); printf(" OK!\nFlashing the firmware...\n");
struct blisp_easy_transport data_transport = {
blisp_easy_transport_new_from_file(firmware_file); uint32_t sent_data = 0;
uint32_t buffer_size = 0;
uint8_t buffer[8184];
printf("0b / %ldb (0.00%%)\n", firmware_file_size);
ret = blisp_easy_flash_write(&device, &data_transport, firmware_base_address, while (sent_data < firmware_file_size) {
firmware_file_size, buffer_size = firmware_file_size - sent_data;
blisp_common_progress_callback); if (buffer_size > 2052) {
if (ret < BLISP_OK) { buffer_size = 2052;
fprintf(stderr, "Failed to write app to flash.\n"); }
fread(buffer, buffer_size, 1, firmware_file);
ret = blisp_device_flash_write(&device, firmware_base_address + sent_data, buffer, buffer_size); // TODO: Error handling
if (ret < 0) {
fprintf(stderr, "Failed to write firmware! (ret: %d)\n", ret);
goto exit2; goto exit2;
} }
sent_data += buffer_size;
printf("%" PRIu32 "b / %ldb (%.2f%%)\n", sent_data, firmware_file_size,
(((float)sent_data / (float)firmware_file_size) * 100.0f));
}
}
printf("Checking program...\n"); printf("Checking program...");
ret = blisp_device_program_check(&device); ret = blisp_device_program_check(&device);
if (ret != BLISP_OK) { if (ret != 0) {
fprintf(stderr, "Failed to check program.\n"); fprintf(stderr, "\nFailed to check program.\n");
goto exit2; goto exit2;
} }
printf("Program OK!\n"); printf("OK\n");
if (reset->count > 0) { if (reset->count > 0) {
blisp_device_reset(&device); blisp_device_reset(&device);
@@ -242,24 +413,22 @@ void blisp_flash_firmware() {
printf("Flash complete!\n"); printf("Flash complete!\n");
exit2: exit2:
if (firmware_file != NULL) if (firmware_file != NULL) fclose(firmware_file);
fclose(firmware_file);
exit1: exit1:
if (eflash_loader_file != NULL) fclose(eflash_loader_file);
blisp_device_close(&device); blisp_device_close(&device);
} }
int8_t cmd_write_args_init() { int8_t
cmd_write_argtable[0] = cmd = cmd_write_args_init() {
arg_rex1(NULL, NULL, "write", NULL, REG_ICASE, NULL); cmd_write_argtable[0] = cmd
cmd_write_argtable[1] = chip_type = = arg_rex1(NULL, NULL, "write", NULL, REG_ICASE, NULL);
arg_str1("c", "chip", "<chip_type>", "Chip Type"); cmd_write_argtable[1] = chip_type = arg_str1("c", "chip", "<chip_type>", "Chip Type (bl70x)");
cmd_write_argtable[2] = port_name = cmd_write_argtable[2] = port_name
arg_str0("p", "port", "<port_name>", = arg_str0("p", "port", "<port_name>", "Name/Path to the Serial Port (empty for search)");
"Name/Path to the Serial Port (empty for search)"); cmd_write_argtable[3] = reset = arg_lit0(NULL, "reset", "Reset chip after write");
cmd_write_argtable[3] = reset = cmd_write_argtable[4] = binary_to_write
arg_lit0(NULL, "reset", "Reset chip after write"); = arg_file1(NULL, NULL, "<input>", "Binary to write");
cmd_write_argtable[4] = binary_to_write =
arg_file1(NULL, NULL, "<input>", "Binary to write");
cmd_write_argtable[5] = end = arg_end(10); cmd_write_argtable[5] = end = arg_end(10);
if (arg_nullcheck(cmd_write_argtable) != 0) { if (arg_nullcheck(cmd_write_argtable) != 0) {
@@ -276,7 +445,8 @@ void cmd_write_args_print_glossary() {
arg_print_glossary(stdout,cmd_write_argtable," %-25s %s\n"); arg_print_glossary(stdout,cmd_write_argtable," %-25s %s\n");
} }
uint8_t cmd_write_parse_exec(int argc, char** argv) { uint8_t
cmd_write_parse_exec(int argc, char** argv) {
int errors = arg_parse(argc, argv, cmd_write_argtable); int errors = arg_parse(argc, argv, cmd_write_argtable);
if (errors == 0) { if (errors == 0) {
blisp_flash_firmware(); // TODO: Error code? blisp_flash_firmware(); // TODO: Error code?
@@ -292,10 +462,11 @@ void cmd_write_args_print_syntax() {
arg_print_syntax(stdout,cmd_write_argtable,"\n"); arg_print_syntax(stdout,cmd_write_argtable,"\n");
} }
void cmd_write_free() { void
cmd_write_free() {
arg_freetable(cmd_write_argtable, arg_freetable(cmd_write_argtable,
sizeof(cmd_write_argtable) / sizeof(cmd_write_argtable[0])); sizeof(cmd_write_argtable) / sizeof(cmd_write_argtable[0]));
} }
struct cmd cmd_write = {"write", cmd_write_args_init, cmd_write_parse_exec, struct cmd cmd_write
cmd_write_args_print_syntax, cmd_write_free}; = { "write", cmd_write_args_init, cmd_write_parse_exec, cmd_write_args_print_syntax, cmd_write_free };
-138
View File
@@ -1,138 +0,0 @@
// SPDX-License-Identifier: MIT
#include "common.h"
#include <argtable3.h>
#include <blisp.h>
#include <inttypes.h>
#include <malloc.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "blisp_easy.h"
#include "util.h"
void blisp_common_progress_callback(uint32_t current_value, uint32_t max_value) {
printf("%" PRIu32 "b / %ldb (%.2f%%)\n", current_value, max_value,
(((float)current_value / (float)max_value) * 100.0f));
}
int32_t blisp_common_init_device(struct blisp_device* device, struct arg_str* port_name, struct arg_str* chip_type)
{
if (chip_type->count == 0) {
fprintf(stderr, "Chip type is invalid.\n");
return -1;
}
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 -1;
}
int32_t ret;
ret = blisp_device_init(device, chip);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to init device.\n");
return -1;
}
ret = blisp_device_open(device,
port_name->count == 1 ? port_name->sval[0] : NULL);
if (ret != BLISP_OK) {
fprintf(stderr, ret == BLISP_ERR_DEVICE_NOT_FOUND ? "Device not found\n" : "Failed to open device.\n");
return -1;
}
return 0;
}
/**
* Prepares chip to access flash
* this means performing handshake, and loading eflash_loader if needed.
*/
int32_t blisp_common_prepare_flash(struct blisp_device* device) {
int32_t ret = 0;
printf("Sending a handshake...\n");
ret = blisp_device_handshake(device, false);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to handshake with device.\n");
return -1;
}
printf("Handshake successful!\nGetting chip info...\n");
struct blisp_boot_info boot_info;
ret = blisp_device_get_boot_info(device, &boot_info);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to get boot info.\n");
return -1;
}
printf(
"BootROM version %d.%d.%d.%d, ChipID: "
"%02X%02X%02X%02X%02X%02X%02X%02X\n",
boot_info.boot_rom_version[0], boot_info.boot_rom_version[1],
boot_info.boot_rom_version[2], boot_info.boot_rom_version[3],
boot_info.chip_id[0], boot_info.chip_id[1], boot_info.chip_id[2],
boot_info.chip_id[3], boot_info.chip_id[4], boot_info.chip_id[5],
boot_info.chip_id[6], boot_info.chip_id[7]);
if (device->chip->load_eflash_loader == NULL) {
return 0;
}
if (boot_info.boot_rom_version[0] == 255 &&
boot_info.boot_rom_version[1] == 255 &&
boot_info.boot_rom_version[2] == 255 &&
boot_info.boot_rom_version[3] == 255) {
printf("Device already in eflash_loader.\n");
return 0;
}
uint8_t* eflash_loader_buffer = NULL;
// TODO: Error check
int64_t eflash_loader_buffer_length = device->chip->load_eflash_loader(0, &eflash_loader_buffer);
struct blisp_easy_transport eflash_loader_transport =
blisp_easy_transport_new_from_memory(eflash_loader_buffer, eflash_loader_buffer_length);
ret = blisp_easy_load_ram_app(device, &eflash_loader_transport, blisp_common_progress_callback);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to load eflash_loader, ret: %d\n", ret);
ret = -1;
goto exit1;
}
free(eflash_loader_buffer);
eflash_loader_buffer = NULL;
ret = blisp_device_check_image(device);
if (ret != 0) {
fprintf(stderr, "Failed to check image.\n");
ret = -1;
goto exit1;
}
ret = blisp_device_run_image(device);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to run image.\n");
ret = -1;
goto exit1;
}
printf("Sending a handshake...\n");
ret = blisp_device_handshake(device, true);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to handshake with device.\n");
ret = -1;
goto exit1;
}
printf("Handshake with eflash_loader successful.\n");
exit1:
if (eflash_loader_buffer != NULL)
free(eflash_loader_buffer);
return ret;
}
-13
View File
@@ -1,13 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef BLISP_COMMON_H
#define BLISP_COMMON_H
#include <stdint.h>
#include <blisp.h>
#include <argtable3.h>
int32_t blisp_common_prepare_flash(struct blisp_device* device);
void blisp_common_progress_callback(uint32_t current_value, uint32_t max_value);
int32_t blisp_common_init_device(struct blisp_device* device, struct arg_str* port_name, struct arg_str* chip_type);
#endif // BLISP_COMMON_H
+10 -9
View File
@@ -1,11 +1,12 @@
// SPDX-License-Identifier: MIT #include "argtable3.h"
#include "cmd.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "argtable3.h"
#include "cmd.h"
struct cmd* cmds[] = {&cmd_write, &cmd_iot}; struct cmd* cmds[] = {
&cmd_write
};
static uint8_t cmds_count = sizeof(cmds) / sizeof(cmds[0]); static uint8_t cmds_count = sizeof(cmds) / sizeof(cmds[0]);
@@ -16,8 +17,7 @@ static void* argtable[3];
int8_t args_init() { int8_t args_init() {
argtable[0] = help = arg_lit0(NULL, "help", "print this help and exit"); argtable[0] = help = arg_lit0(NULL, "help", "print this help and exit");
argtable[1] = version = argtable[1] = version = arg_lit0(NULL, "version", "print version information and exit");
arg_lit0(NULL, "version", "print version information and exit");
argtable[2] = end = arg_end(20); argtable[2] = end = arg_end(20);
if (arg_nullcheck(argtable) != 0) { if (arg_nullcheck(argtable) != 0) {
@@ -45,8 +45,8 @@ int8_t args_parse_exec(int argc, char** argv) {
print_help(); print_help();
return 1; return 1;
} else if (version->count) { } else if (version->count) {
printf("blisp 0.0.1\n"); printf("blisp 1.0.0\n");
printf("Copyright (C) 2023 Marek Kraus and PINE64 Community\n"); printf("Copyright (C) 2022 Marek Kraus and PINE64 Community\n");
return 1; return 1;
} }
} }
@@ -57,7 +57,8 @@ void args_free() {
arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
} }
int main(int argc, char** argv) { int
main(int argc, char** argv) {
int exit_code = 0; int exit_code = 0;
if (args_init() != 0) { if (args_init() != 0) {
-44
View File
@@ -1,44 +0,0 @@
// SPDX-License-Identifier: MIT
#include "util.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#ifdef __APPLE__
// Ugh. This stuff is just so messy without C++17 or Qt...
// These are not thread safe, but it doesn't place the responsibility
// to free an allocated buffer on the caller.nn
static void util_get_executable_path(char* buffer_out, uint32_t max_size) {
assert(max_size >= PATH_MAX); // n.b. 1024 on MacOS. 4K on most Linux.
char raw_path_name[PATH_MAX]; // $HOME/../../var/tmp/x
char real_path_name[PATH_MAX]; // /var/tmp/x
uint32_t raw_path_size = sizeof(raw_path_name);
if (!_NSGetExecutablePath(raw_path_name, &raw_path_size)) {
realpath(raw_path_name, real_path_name);
}
// *real_path_name is appropriately sized and null terminated.
strcpy(buffer_out, real_path_name);
}
#endif
ssize_t util_get_binary_folder(char* buffer, uint32_t buffer_size) {
#ifdef __linux__
if (readlink("/proc/self/exe", buffer, buffer_size) <= 0) {
return -1;
}
char* pos = strrchr(buffer, '/');
#elif defined(__APPLE__)
util_get_executable_path(buffer, buffer_size);
char* pos = strrchr(buffer, '/');
#else
if (GetModuleFileName(NULL, buffer, buffer_size) <= 0) {
return -1;
}
char* pos = strrchr(buffer, '\\');
#endif
pos[0] = '\0';
return pos - buffer;
}
-26
View File
@@ -1,26 +0,0 @@
// SPDX-License-Identifier: MIT
#ifndef BLISP_UTIL_H
#define BLISP_UTIL_H
#include <stdint.h>
#ifdef __linux__
#include <unistd.h>
#elif defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#include <windows.h>
#define PATH_MAX MAX_PATH
#elif defined(__APPLE__)
#include <sys/syslimits.h>
#include <assert.h>
#endif
#ifdef __linux__
#include <linux/limits.h>
#endif
ssize_t util_get_binary_folder(char* buffer, uint32_t buffer_size);
#endif