mirror of
https://github.com/pine64/blisp.git
synced 2026-09-19 23:21:29 +00:00
Compare commits
4
Commits
v0.0.5
..
196d7d0170
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
196d7d0170 | ||
|
|
5634b678f3 | ||
|
|
8dbb58353b | ||
|
|
f1fcdb9587 |
@@ -26,7 +26,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
submodules: 'recursive'
|
||||
- uses: lukka/get-cmake@latest
|
||||
- name: Build blisp tool
|
||||
run: |
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: blips-windows-x86_64
|
||||
name: blips-windows-x86_64.zip
|
||||
path: |
|
||||
build/tools/blisp/Release/blisp.exe
|
||||
if-no-files-found: error
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
submodules: 'recursive'
|
||||
- uses: lukka/get-cmake@latest
|
||||
- name: Build blisp tool
|
||||
run: |
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: blips-apple-universal
|
||||
name: blips-apple-universal.zip
|
||||
path: |
|
||||
build/tools/blisp/blisp
|
||||
if-no-files-found: error
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
submodules: 'recursive'
|
||||
- uses: lukka/get-cmake@latest
|
||||
- name: Build blisp tool
|
||||
run: |
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: blips-linux-x86_64
|
||||
name: blips-linux-x86_64.zip
|
||||
path: |
|
||||
build/tools/blisp/blisp
|
||||
if-no-files-found: error
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
submodules: 'recursive'
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
name: Build artifact
|
||||
id: build
|
||||
@@ -151,33 +151,7 @@ jobs:
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: blisp-linux-${{ matrix.arch }}
|
||||
name: blisp-linux-${{ matrix.arch }}.zip
|
||||
path: |
|
||||
artifacts/blisp-*
|
||||
if-no-files-found: error
|
||||
|
||||
test-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: "recursive"
|
||||
- uses: lukka/get-cmake@latest
|
||||
- name: Build blisp tool & unit tests
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DBLISP_BUILD_CLI=ON -DCOMPILE_TESTS=ON
|
||||
cmake --build .
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
cd build
|
||||
for f in $(find . -type f -executable -iname "*_test"); do
|
||||
echo "Running test file $f"
|
||||
"$f"
|
||||
status=$?
|
||||
if [ $status -ne 0 ]; then
|
||||
echo "Test $f failed with exit code $status"
|
||||
exit $status
|
||||
fi
|
||||
done
|
||||
|
||||
+1
-2
@@ -77,5 +77,4 @@ fabric.properties
|
||||
.idea/caches/build_file_checksums.ser
|
||||
build/
|
||||
|
||||
.DS_Store
|
||||
.cache/
|
||||
.DS_Store
|
||||
+9
-37
@@ -11,22 +11,10 @@ option(COMPILE_TESTS "Compile the tests" OFF)
|
||||
|
||||
add_library(libblisp_obj OBJECT
|
||||
lib/blisp.c
|
||||
lib/blisp_easy.c
|
||||
lib/blisp_util.c
|
||||
lib/chip/blisp_chip_bl60x.c
|
||||
lib/chip/blisp_chip_bl70x.c
|
||||
lib/chip/blisp_chip_bl808.c)
|
||||
lib/chip/blisp_chip_bl70x.c lib/blisp_easy.c)
|
||||
|
||||
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/)
|
||||
if (NOT CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
||||
target_compile_options(libblisp_obj PRIVATE -Wall -Wextra -Wpedantic)
|
||||
else()
|
||||
# MSVC does not support 'extra' and 'pedantic' levels to warnings.
|
||||
# `/Wall` seems to generate way too many non-actionable output marked as warnings.
|
||||
# We settle for `/W4`.
|
||||
# https://learn.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level?view=msvc-170
|
||||
target_compile_options(libblisp_obj PRIVATE -W4)
|
||||
endif()
|
||||
|
||||
set_property(TARGET libblisp_obj PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||
|
||||
@@ -42,14 +30,14 @@ set(BLISP_PUBLIC_HEADERS
|
||||
|
||||
set_target_properties(libblisp PROPERTIES
|
||||
PUBLIC_HEADER "${BLISP_PUBLIC_HEADERS}"
|
||||
VERSION 0.0.5
|
||||
VERSION 0.0.4
|
||||
SOVERSION 1
|
||||
LIBRARY_OUTPUT_DIRECTORY "shared"
|
||||
OUTPUT_NAME "blisp")
|
||||
|
||||
set_target_properties(libblisp_static PROPERTIES
|
||||
PUBLIC_HEADER "${BLISP_PUBLIC_HEADERS}"
|
||||
VERSION 0.0.5
|
||||
VERSION 0.0.4
|
||||
SOVERSION 1
|
||||
ARCHIVE_OUTPUT_DIRECTORY "static"
|
||||
OUTPUT_NAME "blisp")
|
||||
@@ -60,13 +48,13 @@ if(BLISP_USE_SYSTEM_LIBRARIES)
|
||||
target_link_libraries(libblisp_static PUBLIC Libserialport::Libserialport)
|
||||
target_include_directories(libblisp_obj PUBLIC ${Libserialport_INCLUDE_DIRS})
|
||||
else()
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
target_sources(libblisp_obj PRIVATE
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
target_sources(libblisp_obj PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/vendor/libserialport/serialport.c
|
||||
${CMAKE_SOURCE_DIR}/vendor/libserialport/timing.c)
|
||||
|
||||
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport)
|
||||
endif()
|
||||
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(libblisp PRIVATE Setupapi.lib)
|
||||
@@ -104,7 +92,7 @@ else()
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS libblisp libblisp_static
|
||||
install(TARGETS libblisp libblisp_static
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
@@ -117,21 +105,5 @@ endif()
|
||||
|
||||
|
||||
if(COMPILE_TESTS)
|
||||
# Bring in googletest & C++
|
||||
enable_language(CXX)
|
||||
enable_testing()
|
||||
include(FetchContent)
|
||||
|
||||
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG v1.17.0
|
||||
)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
add_library(GTest::GTest INTERFACE IMPORTED)
|
||||
target_link_libraries(GTest::GTest INTERFACE gtest_main)
|
||||
|
||||
add_subdirectory(tools/blisp/src/file_parsers/dfu/tests)
|
||||
add_subdirectory(tools/blisp/src/file_parsers/hex/tests)
|
||||
add_subdirectory(tools/blisp/src/cmd/dfu/tests)
|
||||
endif(COMPILE_TESTS)
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env make -f
|
||||
|
||||
### global variables section
|
||||
|
||||
# static vars
|
||||
BUILD_DIR:="build"
|
||||
BUILD_BIN:="$(BUILD_DIR)/tools/blisp/blisp"
|
||||
|
||||
# dynamic vars
|
||||
FILES_CMAKE:=$(shell find . -path ./$(BUILD_DIR) -prune -false -o -type f -name '*.cmake' -o -type f -name 'CMakeLists.txt')
|
||||
FILES_SRC:=$(shell find . -path ./$(BUILD_DIR) -prune -false -o -type f -name '*.c' -o -type f -name '*.h')
|
||||
|
||||
### main targets section
|
||||
|
||||
# simplify build
|
||||
build: $(FILES_CMAKE) $(FILES_SRC) Makefile
|
||||
@echo "\n>>>> Generating build files in: $(BUILD_DIR) ...\n"
|
||||
@cmake -S . -B $(BUILD_DIR) -DBLISP_BUILD_CLI=ON
|
||||
@echo "\n>>>> Building...\n"
|
||||
@cmake --build $(BUILD_DIR)
|
||||
@echo "\n>>>> DONE: $(BUILD_BIN)\n"
|
||||
|
||||
# deleting output build directory with its content
|
||||
clean:
|
||||
-@rm -rf $(BUILD_DIR)/
|
||||
|
||||
# printf-like debug target
|
||||
vars:
|
||||
@echo "\n>>>> FILES_CMAKE:"
|
||||
@echo "$(FILES_CMAKE)" | sed 's, ,\n,g'
|
||||
@echo "\n>>>> FILES_SRC:"
|
||||
@echo "$(FILES_SRC)" | sed 's, ,\n,g'
|
||||
|
||||
.PHONY: clean vars
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
[](https://github.com/pine64/blisp/wiki/Update-Pinecil-V2)
|
||||
[](https://github.com/pine64/blisp/releases/tag/v0.0.5)
|
||||
[](https://github.com/pine64/blisp/releases/tag/v0.0.4)
|
||||
[](https://discord.com/invite/pine64)
|
||||
[](https://github.com/pine64/blisp/releases/tag/v0.0.5)
|
||||
[](https://github.com/pine64/blisp/releases/tag/v0.0.4)
|
||||
|
||||
<img src="./img/Gradient-white-blue-03.png" align="left" width="60" > <br clear="left" />
|
||||
# BLISP
|
||||
# BLISP
|
||||
|
||||
Bouffalo Labs ISP (in-system-programming) tool & library: an open source tool to flash Bouffalo RISC-V MCUs.
|
||||
|
||||
@@ -16,13 +16,13 @@ Bouffalo Labs ISP (in-system-programming) tool & library: an open source tool to
|
||||
- [x] `bl70x` - BL702 / BL704 / BL706
|
||||
<br>
|
||||
|
||||
## Supported Devices
|
||||
| System | <img width="15" src="img/win32.png" /> Windows | <img width="15" src="https://cdn.simpleicons.org/Apple/5791ac" /> MacOS| <img width="17" src="https://cdn.simpleicons.org/Linux/5791ac" /> Linux| <img width="15" src="https://cdn.simpleicons.org/Freebsd/5791ac" /> FreeBSD |
|
||||
## Supported Devices
|
||||
| System | <img width="15" src="https://cdn.simpleicons.org/Windows11/5791ac" /> Windows | <img width="15" src="https://cdn.simpleicons.org/Apple/5791ac" /> MacOS| <img width="17" src="https://cdn.simpleicons.org/Linux/5791ac" /> Linux| <img width="15" src="https://cdn.simpleicons.org/Freebsd/5791ac" /> FreeBSD |
|
||||
| :-----: | :------: | :------: | :------: | :------: |
|
||||
| Pinecil V2 |<img width="22" src="https://cdn.simpleicons.org/cachet/5791ac" />|<img width="22" src="https://cdn.simpleicons.org/cachet/5791ac" />| <img width="22" src="https://cdn.simpleicons.org/cachet/5791ac" />| <img width="22" src="https://cdn.simpleicons.org/cachet/5791ac" /> |
|
||||
| Pinecone |<img width="22" src="https://cdn.simpleicons.org/cachet/5791ac" />|<img width="22" src="https://cdn.simpleicons.org/cachet/5791ac" />|<img width="22" src="https://cdn.simpleicons.org/cachet/5791ac" />| <img width="22" src="https://cdn.simpleicons.org/cachet/5791ac" /> |
|
||||
<br>
|
||||
|
||||
|
||||
## How to update Pinecil V2
|
||||
|
||||
Download the newest release of [Blisp updater here](https://github.com/pine64/blisp/releases/).
|
||||
@@ -94,15 +94,6 @@ Because this is done at the lowest level of serial communication, the
|
||||
displays aren't packet-aware or know about the chip's command set or such.
|
||||
This is really only useful for debugging systems-level issues withing
|
||||
the device or blisp itself.
|
||||
## Running unit tests
|
||||
|
||||
```shell
|
||||
mkdir build && cd build
|
||||
cmake -DBLISP_BUILD_CLI=ON -DCOMPILE_TESTS=ON ..
|
||||
cmake --build .
|
||||
# Find all compiled unit test files; you can now run these directly
|
||||
find . -type f -executable -iname "*_test" -print
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "blisp";
|
||||
version = "0.0.5-unstable";
|
||||
version = "0.0.4-unstable";
|
||||
src = self;
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 598 B |
+27
-36
@@ -16,7 +16,6 @@ struct blisp_segment_header {
|
||||
struct blisp_device {
|
||||
struct blisp_chip* chip;
|
||||
void* serial_port;
|
||||
uint32_t serial_timeout; // in ms
|
||||
bool is_usb;
|
||||
uint32_t current_baud_rate;
|
||||
uint8_t rx_buffer[5000]; // TODO:
|
||||
@@ -32,42 +31,34 @@ struct blisp_boot_info {
|
||||
// TODO: Refactor variable names, so all will follow same semantic, like
|
||||
// image_run, image_check etc.
|
||||
|
||||
blisp_return_t blisp_device_init(struct blisp_device* device, struct blisp_chip* chip);
|
||||
blisp_return_t blisp_device_open(struct blisp_device* device, const char* port_name,
|
||||
uint32_t baudrate);
|
||||
blisp_return_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader);
|
||||
blisp_return_t blisp_device_get_boot_info(struct blisp_device* device,
|
||||
struct blisp_boot_info* boot_info);
|
||||
blisp_return_t blisp_device_load_boot_header(struct blisp_device* device,
|
||||
uint8_t* boot_header);
|
||||
|
||||
blisp_return_t blisp_device_load_segment_header(
|
||||
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, bool in_ef_loader);
|
||||
int32_t blisp_device_get_boot_info(struct blisp_device* device,
|
||||
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_segment_header(
|
||||
struct blisp_device* device,
|
||||
struct blisp_segment_header* segment_header);
|
||||
blisp_return_t blisp_device_load_segment_data(struct blisp_device* device,
|
||||
uint8_t* segment_data,
|
||||
uint32_t segment_data_length);
|
||||
blisp_return_t blisp_device_write_memory(struct blisp_device* device,
|
||||
uint32_t address,
|
||||
uint32_t value,
|
||||
bool wait_for_res);
|
||||
blisp_return_t blisp_device_check_image(struct blisp_device* device);
|
||||
blisp_return_t blisp_device_run_image(struct blisp_device* device);
|
||||
blisp_return_t blisp_device_flash_erase(struct blisp_device* device,
|
||||
uint32_t start_address,
|
||||
uint32_t end_address);
|
||||
blisp_return_t blisp_device_chip_erase(struct blisp_device* device);
|
||||
blisp_return_t blisp_device_flash_write(struct blisp_device* device,
|
||||
uint32_t start_address,
|
||||
uint8_t* payload,
|
||||
uint32_t payload_size);
|
||||
|
||||
blisp_return_t blisp_device_program_check(struct blisp_device* device);
|
||||
blisp_return_t blisp_device_reset(struct blisp_device* device);
|
||||
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,
|
||||
uint32_t address,
|
||||
uint32_t value,
|
||||
bool wait_for_res);
|
||||
int32_t blisp_device_check_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,
|
||||
uint32_t start_address,
|
||||
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_reset(struct blisp_device* device);
|
||||
void blisp_device_close(struct blisp_device* device);
|
||||
|
||||
blisp_return_t bl808_load_clock_para(struct blisp_device* device,
|
||||
bool irq_en, uint32_t baudrate);
|
||||
blisp_return_t bl808_load_flash_para(struct blisp_device* device);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -28,7 +28,4 @@ extern struct blisp_chip blisp_chip_bl70x;
|
||||
extern struct blisp_chip blisp_chip_bl808;
|
||||
extern struct blisp_chip blisp_chip_bl61x;
|
||||
|
||||
extern struct bl808_bootheader_t bl808_header;
|
||||
void fill_crcs(struct bl808_bootheader_t *bh);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -173,212 +173,6 @@ struct blflash_segment_header {
|
||||
static_assert(sizeof(struct blflash_segment_header) == 16,
|
||||
"Segment header have wrong size");
|
||||
|
||||
struct bl808_spi_flash_cfg_t {
|
||||
uint8_t ioMode; /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */
|
||||
uint8_t cReadSupport; /*!< Support continuous read mode,bit0:continuous read mode support,bit1:read mode cfg */
|
||||
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 invert,bit2-4:pad delay,bit5-7:pad delay */
|
||||
uint8_t resetEnCmd; /*!< Flash enable reset command */
|
||||
uint8_t resetCmd; /*!< Flash reset command */
|
||||
uint8_t resetCreadCmd; /*!< Flash reset continuous read command */
|
||||
uint8_t resetCreadCmdSize; /*!< Flash reset continuous read command size */
|
||||
uint8_t jedecIdCmd; /*!< JEDEC ID command */
|
||||
uint8_t jedecIdCmdDmyClk; /*!< JEDEC ID command dummy clock */
|
||||
uint8_t enter32BitsAddrCmd; /*!< Enter 32-bits addr command */
|
||||
uint8_t exit32BitsAddrCmd; /*!< Exit 32-bits addr command */
|
||||
uint8_t sectorSize; /*!< *1024bytes */
|
||||
uint8_t mid; /*!< Manufacturer ID */
|
||||
uint16_t pageSize; /*!< Page size */
|
||||
uint8_t chipEraseCmd; /*!< Chip erase cmd */
|
||||
uint8_t sectorEraseCmd; /*!< Sector erase command */
|
||||
uint8_t blk32EraseCmd; /*!< Block 32K erase command,some Micron not support */
|
||||
uint8_t blk64EraseCmd; /*!< Block 64K erase command */
|
||||
uint8_t writeEnableCmd; /*!< Need before every erase or program */
|
||||
uint8_t pageProgramCmd; /*!< Page program cmd */
|
||||
uint8_t qpageProgramCmd; /*!< QIO page program cmd */
|
||||
uint8_t qppAddrMode; /*!< QIO page program address mode */
|
||||
uint8_t fastReadCmd; /*!< Fast read command */
|
||||
uint8_t frDmyClk; /*!< Fast read command dummy clock */
|
||||
uint8_t qpiFastReadCmd; /*!< QPI fast read command */
|
||||
uint8_t qpiFrDmyClk; /*!< QPI fast read command dummy clock */
|
||||
uint8_t fastReadDoCmd; /*!< Fast read dual output command */
|
||||
uint8_t frDoDmyClk; /*!< Fast read dual output command dummy clock */
|
||||
uint8_t fastReadDioCmd; /*!< Fast read dual io comamnd */
|
||||
uint8_t frDioDmyClk; /*!< Fast read dual io command dummy clock */
|
||||
uint8_t fastReadQoCmd; /*!< Fast read quad output comamnd */
|
||||
uint8_t frQoDmyClk; /*!< Fast read quad output comamnd dummy clock */
|
||||
uint8_t fastReadQioCmd; /*!< Fast read quad io comamnd */
|
||||
uint8_t frQioDmyClk; /*!< Fast read quad io comamnd dummy clock */
|
||||
uint8_t qpiFastReadQioCmd; /*!< QPI fast read quad io comamnd */
|
||||
uint8_t qpiFrQioDmyClk; /*!< QPI fast read QIO dummy clock */
|
||||
uint8_t qpiPageProgramCmd; /*!< QPI program command */
|
||||
uint8_t writeVregEnableCmd; /*!< Enable write reg */
|
||||
uint8_t wrEnableIndex; /*!< Write enable register index */
|
||||
uint8_t qeIndex; /*!< Quad mode enable register index */
|
||||
uint8_t busyIndex; /*!< Busy status register index */
|
||||
uint8_t wrEnableBit; /*!< Write enable bit pos */
|
||||
uint8_t qeBit; /*!< Quad enable bit pos */
|
||||
uint8_t busyBit; /*!< Busy status bit pos */
|
||||
uint8_t wrEnableWriteRegLen; /*!< Register length of write enable */
|
||||
uint8_t wrEnableReadRegLen; /*!< Register length of write enable status */
|
||||
uint8_t qeWriteRegLen; /*!< Register length of contain quad enable */
|
||||
uint8_t qeReadRegLen; /*!< Register length of contain quad enable status */
|
||||
uint8_t releasePowerDown; /*!< Release power down command */
|
||||
uint8_t busyReadRegLen; /*!< Register length of contain busy status */
|
||||
uint8_t readRegCmd[4]; /*!< Read register command buffer */
|
||||
uint8_t writeRegCmd[4]; /*!< Write register command buffer */
|
||||
uint8_t enterQpi; /*!< Enter qpi command */
|
||||
uint8_t exitQpi; /*!< Exit qpi command */
|
||||
uint8_t cReadMode; /*!< Config data for continuous read mode */
|
||||
uint8_t cRExit; /*!< Config data for exit continuous read mode */
|
||||
uint8_t burstWrapCmd; /*!< Enable burst wrap command */
|
||||
uint8_t burstWrapCmdDmyClk; /*!< Enable burst wrap command dummy clock */
|
||||
uint8_t burstWrapDataMode; /*!< Data and address mode for this command */
|
||||
uint8_t burstWrapData; /*!< Data to enable burst wrap */
|
||||
uint8_t deBurstWrapCmd; /*!< Disable burst wrap command */
|
||||
uint8_t deBurstWrapCmdDmyClk; /*!< Disable burst wrap command dummy clock */
|
||||
uint8_t deBurstWrapDataMode; /*!< Data and address mode for this command */
|
||||
uint8_t deBurstWrapData; /*!< Data to disable burst wrap */
|
||||
uint16_t timeEsector; /*!< 4K erase time */
|
||||
uint16_t timeE32k; /*!< 32K erase time */
|
||||
uint16_t timeE64k; /*!< 64K erase time */
|
||||
uint16_t timePagePgm; /*!< Page program time */
|
||||
uint16_t timeCe; /*!< Chip erase time in ms */
|
||||
uint8_t pdDelay; /*!< Release power down command delay time for wake up */
|
||||
uint8_t qeData; /*!< QE set data */
|
||||
};
|
||||
|
||||
struct bl808_boot_flash_cfg_t {
|
||||
uint32_t magiccode;
|
||||
struct bl808_spi_flash_cfg_t cfg;
|
||||
uint32_t crc32;
|
||||
};
|
||||
|
||||
struct bl808_sys_clk_cfg_t {
|
||||
uint8_t xtal_type;
|
||||
uint8_t mcu_clk;
|
||||
uint8_t mcu_clk_div;
|
||||
uint8_t mcu_bclk_div;
|
||||
|
||||
uint8_t mcu_pbclk_div;
|
||||
uint8_t lp_div;
|
||||
uint8_t dsp_clk;
|
||||
uint8_t dsp_clk_div;
|
||||
|
||||
uint8_t dsp_bclk_div;
|
||||
uint8_t dsp_pbclk;
|
||||
uint8_t dsp_pbclk_div;
|
||||
uint8_t emi_clk;
|
||||
|
||||
uint8_t emi_clk_div;
|
||||
uint8_t flash_clk_type;
|
||||
uint8_t flash_clk_div;
|
||||
uint8_t wifipll_pu;
|
||||
|
||||
uint8_t aupll_pu;
|
||||
uint8_t cpupll_pu;
|
||||
uint8_t mipipll_pu;
|
||||
uint8_t uhspll_pu;
|
||||
};
|
||||
|
||||
struct bl808_boot_clk_cfg_t {
|
||||
uint32_t magiccode;
|
||||
struct bl808_sys_clk_cfg_t cfg;
|
||||
uint32_t crc32;
|
||||
};
|
||||
|
||||
struct bl808_boot_basic_cfg_t {
|
||||
uint32_t sign_type : 2; /* [1: 0] for sign */
|
||||
uint32_t encrypt_type : 2; /* [3: 2] for encrypt */
|
||||
uint32_t key_sel : 2; /* [5: 4] key slot */
|
||||
uint32_t xts_mode : 1; /* [6] for xts mode */
|
||||
uint32_t aes_region_lock : 1; /* [7] rsvd */
|
||||
uint32_t no_segment : 1; /* [8] no segment info */
|
||||
uint32_t rsvd_0 : 1; /* [9] boot2 enable(rsvd_0) */
|
||||
uint32_t rsvd_1 : 1; /* [10] boot2 rollback(rsvd_1) */
|
||||
uint32_t cpu_master_id : 4; /* [14: 11] master id */
|
||||
uint32_t notload_in_bootrom : 1; /* [15] notload in bootrom */
|
||||
uint32_t crc_ignore : 1; /* [16] ignore crc */
|
||||
uint32_t hash_ignore : 1; /* [17] hash ignore */
|
||||
uint32_t power_on_mm : 1; /* [18] power on mm */
|
||||
uint32_t em_sel : 3; /* [21: 19] em_sel */
|
||||
uint32_t cmds_en : 1; /* [22] command spliter enable */
|
||||
uint32_t cmds_wrap_mode : 2; /* [24: 23] cmds wrap mode */
|
||||
uint32_t cmds_wrap_len : 4; /* [28: 25] cmds wrap len */
|
||||
uint32_t icache_invalid : 1; /* [29] icache invalid */
|
||||
uint32_t dcache_invalid : 1; /* [30] dcache invalid */
|
||||
uint32_t rsvd_3 : 1; /* [31] rsvd_3 */
|
||||
|
||||
uint32_t group_image_offset; /* flash controller offset */
|
||||
uint32_t aes_region_len; /* aes region length */
|
||||
|
||||
uint32_t img_len_cnt; /* image length or segment count */
|
||||
uint32_t hash[32 / 4]; /* hash of the image */
|
||||
};
|
||||
|
||||
struct bl808_boot_cpu_cfg_t {
|
||||
uint8_t config_enable; /* coinfig this cpu */
|
||||
uint8_t halt_cpu; /* halt this cpu */
|
||||
uint8_t cache_enable : 1; /* cache setting */
|
||||
uint8_t cache_wa : 1; /* cache setting */
|
||||
uint8_t cache_wb : 1; /* cache setting */
|
||||
uint8_t cache_wt : 1; /* cache setting */
|
||||
uint8_t cache_way_dis : 4; /* cache setting */
|
||||
uint8_t rsvd;
|
||||
|
||||
uint32_t cache_range_h; /* cache range high */
|
||||
uint32_t cache_range_l; /* cache range low */
|
||||
|
||||
uint32_t image_address_offset; /* image_address_offset */
|
||||
uint32_t rsvd0; /* rsvd0 */
|
||||
uint32_t msp_val; /* msp value */
|
||||
};
|
||||
|
||||
struct bl808_aesiv_cfg_t {
|
||||
uint8_t aesiv[16];
|
||||
uint32_t crc32;
|
||||
};
|
||||
|
||||
struct bl808_pkey_cfg_t {
|
||||
uint8_t eckeyx[32]; /* ec key in boot header */
|
||||
uint8_t eckeyy[32]; /* ec key in boot header */
|
||||
uint32_t crc32;
|
||||
};
|
||||
|
||||
struct bl808_sign_cfg_t {
|
||||
uint32_t sig_len;
|
||||
uint8_t signature[32];
|
||||
uint32_t crc32;
|
||||
};
|
||||
|
||||
struct bl808_bootheader_t {
|
||||
uint32_t magiccode; /* 4 */
|
||||
uint32_t rivison; /* 4 */
|
||||
|
||||
struct bl808_boot_flash_cfg_t flash_cfg; /* 4 + 84 + 4 */
|
||||
struct bl808_boot_clk_cfg_t clk_cfg; /* 4 + 20 + 4 */
|
||||
|
||||
struct bl808_boot_basic_cfg_t basic_cfg; /* 4 + 4 + 4 + 4 + 4*8 */
|
||||
|
||||
struct bl808_boot_cpu_cfg_t cpu_cfg[3]; /*24*3 */
|
||||
|
||||
uint32_t boot2_pt_table_0_rsvd; /* address of partition table 0 */ /* 4 */
|
||||
uint32_t boot2_pt_table_1_rsvd; /* address of partition table 1 */ /* 4 */
|
||||
|
||||
uint32_t flash_cfg_table_addr; /* address of flashcfg table list */ /* 4 */
|
||||
uint32_t flash_cfg_table_len; /* flashcfg table list len */ /* 4 */
|
||||
|
||||
uint32_t rsvd0[8]; /* rsvd */
|
||||
uint32_t rsvd1[8]; /* rsvd */
|
||||
|
||||
uint32_t rsvd3[5]; /* 20 */
|
||||
|
||||
uint32_t crc32; /* 4 */
|
||||
};
|
||||
|
||||
static_assert(sizeof(struct bl808_bootheader_t) == 352,
|
||||
"BL808 bootheader size mismatch");
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
||||
+39
-9
@@ -2,20 +2,35 @@
|
||||
#ifndef _BLISP_UTIL_H
|
||||
#define _BLISP_UTIL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#ifdef WIN32
|
||||
# include <windows.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
# include <time.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
void blisp_dlog(const char* format, ...);
|
||||
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);
|
||||
}
|
||||
|
||||
void blisp_dlog_no_nl(const char* format, ...);
|
||||
|
||||
void sleep_ms(int milliseconds);
|
||||
|
||||
uint32_t crc32_calculate(const void *data, size_t data_len);
|
||||
static void sleep_ms(int milliseconds) {
|
||||
#ifdef WIN32
|
||||
Sleep(milliseconds);
|
||||
#else
|
||||
struct timespec ts;
|
||||
ts.tv_sec = milliseconds / 1000;
|
||||
ts.tv_nsec = (milliseconds % 1000) * 1000000;
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* * Generated on Mon Jan 9 19:56:36 2023
|
||||
@@ -65,4 +80,19 @@ static const uint32_t crc_table[256] = {
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
#endif
|
||||
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
|
||||
+20
-212
@@ -11,15 +11,11 @@
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <blisp_struct.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
static void drain(struct sp_port* port) {
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
sp_drain(port);
|
||||
#else
|
||||
(void)port; // unused
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -27,24 +23,12 @@ blisp_return_t blisp_device_init(struct blisp_device* device,
|
||||
struct blisp_chip* chip) {
|
||||
device->chip = chip;
|
||||
device->is_usb = false;
|
||||
fill_crcs(&bl808_header);
|
||||
|
||||
if (device->chip->type == BLISP_CHIP_BL808) {
|
||||
// TODO: For some reason the BL808 does not send pending ('PD') responses
|
||||
// during long (i.e. erase) operations, so we must disable response
|
||||
// timeouts. Further investigation is necessary.
|
||||
device->serial_timeout = 0;
|
||||
} else {
|
||||
device->serial_timeout = 1000;
|
||||
}
|
||||
|
||||
return BLISP_OK;
|
||||
}
|
||||
|
||||
blisp_return_t blisp_device_open(struct blisp_device* device,
|
||||
const char* port_name,
|
||||
uint32_t baudrate) {
|
||||
enum sp_return ret;
|
||||
const char* port_name) {
|
||||
blisp_return_t ret;
|
||||
struct sp_port* serial_port = NULL;
|
||||
|
||||
if (port_name != NULL) {
|
||||
@@ -98,7 +82,11 @@ blisp_return_t blisp_device_open(struct blisp_device* device,
|
||||
int vid, pid;
|
||||
sp_get_port_usb_vid_pid(serial_port, &vid, &pid);
|
||||
device->is_usb = pid == 0xFFFF;
|
||||
device->current_baud_rate = baudrate;
|
||||
// if (device->is_usb) {
|
||||
// device->current_baud_rate = 2000000;
|
||||
// } else {
|
||||
device->current_baud_rate = 460800;
|
||||
// }
|
||||
|
||||
#if 0
|
||||
int fd;
|
||||
@@ -157,9 +145,8 @@ blisp_return_t blisp_receive_response(struct blisp_device* device,
|
||||
bool expect_payload) {
|
||||
// TODO: Check checksum
|
||||
int ret;
|
||||
|
||||
struct sp_port* serial_port = device->serial_port;
|
||||
ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, device->serial_timeout);
|
||||
ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 1000);
|
||||
if (ret < 2) {
|
||||
blisp_dlog("Failed to receive response, ret: %d", ret);
|
||||
return BLISP_ERR_NO_RESPONSE;
|
||||
@@ -190,7 +177,6 @@ blisp_return_t blisp_receive_response(struct blisp_device* device,
|
||||
blisp_return_t blisp_device_handshake(struct blisp_device* device,
|
||||
bool in_ef_loader) {
|
||||
int ret;
|
||||
bool ok = false;
|
||||
uint8_t handshake_buffer[600];
|
||||
struct sp_port* serial_port = device->serial_port;
|
||||
|
||||
@@ -204,8 +190,8 @@ blisp_return_t blisp_device_handshake(struct blisp_device* device,
|
||||
sleep_ms(50); // Wait a bit so BootROM can init
|
||||
}
|
||||
|
||||
uint32_t bytes_count = (uint32_t)(device->chip->handshake_byte_multiplier *
|
||||
(float)device->current_baud_rate / 10.0f);
|
||||
uint32_t bytes_count = device->chip->handshake_byte_multiplier *
|
||||
(float)device->current_baud_rate / 10.0f;
|
||||
if (bytes_count > 600)
|
||||
bytes_count = 600;
|
||||
memset(handshake_buffer, 'U', bytes_count);
|
||||
@@ -230,40 +216,14 @@ blisp_return_t blisp_device_handshake(struct blisp_device* device,
|
||||
sp_flush(serial_port, SP_BUF_INPUT); // Flush garbage out of RX
|
||||
}
|
||||
|
||||
if (device->chip->type == BLISP_CHIP_BL808) {
|
||||
sleep_ms(300);
|
||||
static const uint8_t second_handshake[] = { 0x50, 0x00, 0x08, 0x00, 0x38, 0xF0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18 };
|
||||
ret = sp_blocking_write(serial_port, second_handshake, sizeof(second_handshake), 300);
|
||||
if (ret < 0) {
|
||||
blisp_dlog("Second handshake write failed, ret %d", ret);
|
||||
return BLISP_ERR_API_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
for (uint8_t j = 0; j < (ret - 1); j++) {
|
||||
if (device->rx_buffer[j] == 'O' && device->rx_buffer[j + 1] == 'K') {
|
||||
ok = true;
|
||||
}
|
||||
if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
|
||||
return BLISP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
return BLISP_OK;
|
||||
} else {
|
||||
blisp_dlog("Received incorrect handshake response from chip (attempt %d/5).", i+1);
|
||||
blisp_dlog_no_nl("Could not find 0x%02X 0x%02X ('O', 'K') in: ", 'O', 'K');
|
||||
if (ret) {
|
||||
for (uint8_t j=0; j <= ret; j++) {
|
||||
blisp_dlog_no_nl("0x%02X ", device->rx_buffer[j]);
|
||||
}
|
||||
}
|
||||
blisp_dlog("");
|
||||
}
|
||||
}
|
||||
|
||||
blisp_dlog("Did not receive correct response from chip after 5 attempts.");
|
||||
blisp_dlog("Received no response from chip.");
|
||||
return BLISP_ERR_NO_RESPONSE;
|
||||
}
|
||||
|
||||
@@ -279,15 +239,13 @@ blisp_return_t blisp_device_get_boot_info(struct blisp_device* device,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
// TODO: Endianess; this may break on big endian machines
|
||||
memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], 4);
|
||||
memcpy(boot_info->boot_rom_version, &device->rx_buffer[0],
|
||||
4); // TODO: Endianess; this may break on big endian machines
|
||||
|
||||
if (device->chip->type == BLISP_CHIP_BL70X) {
|
||||
memcpy(boot_info->chip_id, &device->rx_buffer[16], 8);
|
||||
} else {
|
||||
memcpy(boot_info->chip_id, &device->rx_buffer[12], 6);
|
||||
}
|
||||
|
||||
// TODO: BL60X
|
||||
return BLISP_OK;
|
||||
}
|
||||
|
||||
@@ -402,24 +360,13 @@ blisp_return_t blisp_device_flash_erase(struct blisp_device* device,
|
||||
*(uint32_t*)(payload + 4) = end_address;
|
||||
|
||||
blisp_return_t ret = blisp_send_command(device, 0x30, payload, 8, true);
|
||||
if (ret != BLISP_OK)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
do {
|
||||
ret = blisp_receive_response(device, false);
|
||||
} while (ret == BLISP_ERR_PENDING);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
blisp_return_t blisp_device_chip_erase(struct blisp_device* device) {
|
||||
blisp_return_t ret = blisp_send_command(device, 0x3C, NULL, 0, true);
|
||||
if (ret != BLISP_OK)
|
||||
return ret;
|
||||
do {
|
||||
ret = blisp_receive_response(device, false);
|
||||
} while (ret == BLISP_ERR_PENDING);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
blisp_return_t blisp_device_flash_write(struct blisp_device* device,
|
||||
@@ -467,143 +414,4 @@ blisp_return_t blisp_device_reset(struct blisp_device* device) {
|
||||
void blisp_device_close(struct blisp_device* device) {
|
||||
struct sp_port* serial_port = device->serial_port;
|
||||
sp_close(serial_port);
|
||||
}
|
||||
|
||||
blisp_return_t bl808_load_clock_para(struct blisp_device* device,
|
||||
bool irq_en, uint32_t baudrate) {
|
||||
#define bl808_load_clock_para_payload_size 36
|
||||
static_assert(bl808_load_clock_para_payload_size == sizeof(struct bl808_boot_clk_cfg_t) + 8,
|
||||
"BL808 clock parameter struct size mismatch");
|
||||
uint8_t payload[bl808_load_clock_para_payload_size] = { 0 };
|
||||
|
||||
uint32_t irq_enable = irq_en ? 1 : 0;
|
||||
memcpy(&payload[0], &irq_enable, 4);
|
||||
memcpy(&payload[4], &baudrate, 4);
|
||||
memcpy(&payload[8], &bl808_header.clk_cfg, sizeof(struct bl808_boot_clk_cfg_t));
|
||||
|
||||
blisp_return_t ret = blisp_send_command(device, 0x22, payload,
|
||||
bl808_load_clock_para_payload_size, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = blisp_receive_response(device, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return BLISP_OK;
|
||||
}
|
||||
|
||||
blisp_return_t bl808_load_flash_para(struct blisp_device* device) {
|
||||
// TODO: I don't understand why these parameters are the way they are,
|
||||
// but at least they are labeled. Also, flash_io_mode and flash_clk_delay
|
||||
// seem to be duplicated in the main spi_flash_cfg_t struct?
|
||||
const uint8_t flash_pin = 0x4;
|
||||
const uint8_t flash_clk_cfg = 0x41;
|
||||
const uint8_t flash_io_mode = 0x01;
|
||||
const uint8_t flash_clk_delay = 0;
|
||||
|
||||
// Yes, these values are (slightly) different to the ones in blisp_chip_bl808.c
|
||||
// These values were obtained by observing the raw bytes sent by Bouffalo's
|
||||
// own flashing software. So for whatever reason, the flash configuration needs
|
||||
// to be different when flashing the chip vs. when the chip is running normally.
|
||||
static const struct bl808_spi_flash_cfg_t cfg = {
|
||||
.ioMode = 0x04,
|
||||
.cReadSupport = 0x01,
|
||||
.clkDelay = 0,
|
||||
.clkInvert = 0,
|
||||
.resetEnCmd = 0x66,
|
||||
.resetCmd = 0x99,
|
||||
.resetCreadCmd = 0xff,
|
||||
.resetCreadCmdSize = 0x03,
|
||||
.jedecIdCmd = 0x9f,
|
||||
.jedecIdCmdDmyClk = 0,
|
||||
.enter32BitsAddrCmd = 0xb7,
|
||||
.exit32BitsAddrCmd = 0xe9,
|
||||
.sectorSize = 0x04,
|
||||
.mid = 0xef,
|
||||
.pageSize = 0x100,
|
||||
.chipEraseCmd = 0xc7,
|
||||
.sectorEraseCmd = 0x20,
|
||||
.blk32EraseCmd = 0x52,
|
||||
.blk64EraseCmd = 0xd8,
|
||||
.writeEnableCmd = 0x06,
|
||||
.pageProgramCmd = 0x02,
|
||||
.qpageProgramCmd = 0x32,
|
||||
.qppAddrMode = 0,
|
||||
.fastReadCmd = 0x0b,
|
||||
.frDmyClk = 0x01,
|
||||
.qpiFastReadCmd = 0x0b,
|
||||
.qpiFrDmyClk = 0x01,
|
||||
.fastReadDoCmd = 0x3b,
|
||||
.frDoDmyClk = 0x01,
|
||||
.fastReadDioCmd = 0xbb,
|
||||
.frDioDmyClk = 0,
|
||||
.fastReadQoCmd = 0x6b,
|
||||
.frQoDmyClk = 0x01,
|
||||
.fastReadQioCmd = 0xeb,
|
||||
.frQioDmyClk = 0x02,
|
||||
.qpiFastReadQioCmd = 0xeb,
|
||||
.qpiFrQioDmyClk = 0x02,
|
||||
.qpiPageProgramCmd = 0x02,
|
||||
.writeVregEnableCmd = 0x50,
|
||||
.wrEnableIndex = 0,
|
||||
.qeIndex = 0x01,
|
||||
.busyIndex = 0,
|
||||
.wrEnableBit = 0x01,
|
||||
.qeBit = 0x01,
|
||||
.busyBit = 0,
|
||||
.wrEnableWriteRegLen = 0x02,
|
||||
.wrEnableReadRegLen = 0x01,
|
||||
.qeWriteRegLen = 0x01,
|
||||
.qeReadRegLen = 0x01,
|
||||
.releasePowerDown = 0xab,
|
||||
.busyReadRegLen = 0x01,
|
||||
.readRegCmd[0] = 0x05,
|
||||
.readRegCmd[1] = 0x35,
|
||||
.readRegCmd[2] = 0,
|
||||
.readRegCmd[3] = 0,
|
||||
.writeRegCmd[0] = 0x01,
|
||||
.writeRegCmd[1] = 0x31,
|
||||
.writeRegCmd[2] = 0,
|
||||
.writeRegCmd[3] = 0,
|
||||
.enterQpi = 0x38,
|
||||
.exitQpi = 0xff,
|
||||
.cReadMode = 0xa0,
|
||||
.cRExit = 0xff,
|
||||
.burstWrapCmd = 0x77,
|
||||
.burstWrapCmdDmyClk = 0x03,
|
||||
.burstWrapDataMode = 0x02,
|
||||
.burstWrapData = 0x40,
|
||||
.deBurstWrapCmd = 0x77,
|
||||
.deBurstWrapCmdDmyClk = 0x03,
|
||||
.deBurstWrapDataMode = 0x02,
|
||||
.deBurstWrapData = 0xf0,
|
||||
.timeEsector = 0x12c,
|
||||
.timeE32k = 0x4b0,
|
||||
.timeE64k = 0x4b0,
|
||||
.timePagePgm = 0x05,
|
||||
.timeCe = 0x80e8,
|
||||
.pdDelay = 0x03,
|
||||
.qeData = 0,
|
||||
};
|
||||
|
||||
#define bl808_load_flash_para_payload_size 88
|
||||
static_assert(bl808_load_flash_para_payload_size == sizeof(struct bl808_spi_flash_cfg_t) + 4,
|
||||
"BL808 flash parameter struct size mismatch");
|
||||
uint8_t payload[bl808_load_flash_para_payload_size] = { 0 };
|
||||
|
||||
payload[0] = flash_pin;
|
||||
payload[1] = flash_clk_cfg;
|
||||
payload[2] = flash_io_mode;
|
||||
payload[3] = flash_clk_delay;
|
||||
memcpy(&payload[4], &cfg, sizeof(struct bl808_spi_flash_cfg_t));
|
||||
|
||||
blisp_return_t ret = blisp_send_command(device, 0x3b, payload,
|
||||
bl808_load_flash_para_payload_size, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = blisp_receive_response(device, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return BLISP_OK;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
#include "blisp_util.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void blisp_dlog_no_nl(const char* format, ...) {
|
||||
fflush(stdout);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(stderr, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void sleep_ms(int milliseconds) {
|
||||
#ifdef WIN32
|
||||
Sleep(milliseconds);
|
||||
#else
|
||||
struct timespec ts;
|
||||
ts.tv_sec = milliseconds / 1000;
|
||||
ts.tv_nsec = (milliseconds % 1000) * 1000000;
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
int64_t blisp_chip_bl60x_get_eflash_loader(uint8_t clk_type, uint8_t** firmware_buf_ptr)
|
||||
{
|
||||
(void)clk_type; // unused
|
||||
|
||||
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
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
int64_t blisp_chip_bl70x_get_eflash_loader(uint8_t clk_type, uint8_t** firmware_buf_ptr)
|
||||
{
|
||||
(void) clk_type; // ununsed
|
||||
|
||||
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
|
||||
|
||||
+4
-224
@@ -1,231 +1,11 @@
|
||||
/*
|
||||
* Some parts of this source code belongs to Bouffalo Labs
|
||||
* COPYRIGHT(c) 2020 Bouffalo Lab , License: Apache
|
||||
*/
|
||||
|
||||
// SPDX-License-Identifier: MIT
|
||||
#include "blisp.h"
|
||||
#include "blisp_struct.h"
|
||||
#include "blisp_util.h"
|
||||
#include <stddef.h>
|
||||
|
||||
struct blisp_chip blisp_chip_bl808 = {
|
||||
.type = BLISP_CHIP_BL808,
|
||||
.type_str = "bl808",
|
||||
.usb_isp_available = true, // TODO: Only for BL808D :-(
|
||||
.default_xtal = "-", // XXX: bfl software marks this as "Auto (0x07)"
|
||||
.handshake_byte_multiplier = 0.006f,
|
||||
.load_eflash_loader = NULL
|
||||
.default_xtal = "-", // ?
|
||||
.handshake_byte_multiplier = 0.003f,
|
||||
.get_eflash_loader = NULL
|
||||
};
|
||||
|
||||
struct bl808_bootheader_t bl808_header = {
|
||||
.magiccode = 0x504e4642,
|
||||
.rivison = 0x00000001,
|
||||
/*flash config */
|
||||
.flash_cfg.magiccode = 0x47464346,
|
||||
.flash_cfg.cfg.ioMode = 0x11, /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */
|
||||
.flash_cfg.cfg.cReadSupport = 0x00, /*!< Support continuous read mode,bit0:continuous read mode support,bit1:read mode cfg */
|
||||
.flash_cfg.cfg.clkDelay = 0x01, /*!< SPI clock delay,bit0-3:delay,bit4-6:pad delay */
|
||||
.flash_cfg.cfg.clkInvert = 0x01, /*!< SPI clock phase invert,bit0:clck invert,bit1:rx invert,bit2-4:pad delay,bit5-7:pad delay */
|
||||
.flash_cfg.cfg.resetEnCmd = 0x66, /*!< Flash enable reset command */
|
||||
.flash_cfg.cfg.resetCmd = 0x99, /*!< Flash reset command */
|
||||
.flash_cfg.cfg.resetCreadCmd = 0xff, /*!< Flash reset continuous read command */
|
||||
.flash_cfg.cfg.resetCreadCmdSize = 0x03, /*!< Flash reset continuous read command size */
|
||||
.flash_cfg.cfg.jedecIdCmd = 0x9f, /*!< JEDEC ID command */
|
||||
.flash_cfg.cfg.jedecIdCmdDmyClk = 0x00, /*!< JEDEC ID command dummy clock */
|
||||
.flash_cfg.cfg.enter32BitsAddrCmd = 0xb7, /*!< Enter 32-bits addr command */
|
||||
.flash_cfg.cfg.exit32BitsAddrCmd = 0xe9, /*!< Exit 32-bits addr command */
|
||||
.flash_cfg.cfg.sectorSize = 0x04, /*!< *1024bytes */
|
||||
.flash_cfg.cfg.mid = 0x00, /*!< Manufacturer ID */
|
||||
.flash_cfg.cfg.pageSize = 0x100, /*!< Page size */
|
||||
.flash_cfg.cfg.chipEraseCmd = 0xc7, /*!< Chip erase cmd */
|
||||
.flash_cfg.cfg.sectorEraseCmd = 0x20, /*!< Sector erase command */
|
||||
.flash_cfg.cfg.blk32EraseCmd = 0x52, /*!< Block 32K erase command,some Micron not support */
|
||||
.flash_cfg.cfg.blk64EraseCmd = 0xd8, /*!< Block 64K erase command */
|
||||
.flash_cfg.cfg.writeEnableCmd = 0x06, /*!< Need before every erase or program */
|
||||
.flash_cfg.cfg.pageProgramCmd = 0x02, /*!< Page program cmd */
|
||||
.flash_cfg.cfg.qpageProgramCmd = 0x32, /*!< QIO page program cmd */
|
||||
.flash_cfg.cfg.qppAddrMode = 0x00, /*!< QIO page program address mode */
|
||||
.flash_cfg.cfg.fastReadCmd = 0x0b, /*!< Fast read command */
|
||||
.flash_cfg.cfg.frDmyClk = 0x01, /*!< Fast read command dummy clock */
|
||||
.flash_cfg.cfg.qpiFastReadCmd = 0x0b, /*!< QPI fast read command */
|
||||
.flash_cfg.cfg.qpiFrDmyClk = 0x01, /*!< QPI fast read command dummy clock */
|
||||
.flash_cfg.cfg.fastReadDoCmd = 0x3b, /*!< Fast read dual output command */
|
||||
.flash_cfg.cfg.frDoDmyClk = 0x01, /*!< Fast read dual output command dummy clock */
|
||||
.flash_cfg.cfg.fastReadDioCmd = 0xbb, /*!< Fast read dual io comamnd */
|
||||
.flash_cfg.cfg.frDioDmyClk = 0x00, /*!< Fast read dual io command dummy clock */
|
||||
.flash_cfg.cfg.fastReadQoCmd = 0x6b, /*!< Fast read quad output comamnd */
|
||||
.flash_cfg.cfg.frQoDmyClk = 0x01, /*!< Fast read quad output comamnd dummy clock */
|
||||
.flash_cfg.cfg.fastReadQioCmd = 0xeb, /*!< Fast read quad io comamnd */
|
||||
.flash_cfg.cfg.frQioDmyClk = 0x02, /*!< Fast read quad io comamnd dummy clock */
|
||||
.flash_cfg.cfg.qpiFastReadQioCmd = 0xeb, /*!< QPI fast read quad io comamnd */
|
||||
.flash_cfg.cfg.qpiFrQioDmyClk = 0x02, /*!< QPI fast read QIO dummy clock */
|
||||
.flash_cfg.cfg.qpiPageProgramCmd = 0x02, /*!< QPI program command */
|
||||
.flash_cfg.cfg.writeVregEnableCmd = 0x50, /*!< Enable write reg */
|
||||
.flash_cfg.cfg.wrEnableIndex = 0x00, /*!< Write enable register index */
|
||||
.flash_cfg.cfg.qeIndex = 0x01, /*!< Quad mode enable register index */
|
||||
.flash_cfg.cfg.busyIndex = 0x00, /*!< Busy status register index */
|
||||
.flash_cfg.cfg.wrEnableBit = 0x01, /*!< Write enable bit pos */
|
||||
.flash_cfg.cfg.qeBit = 0x01, /*!< Quad enable bit pos */
|
||||
.flash_cfg.cfg.busyBit = 0x00, /*!< Busy status bit pos */
|
||||
.flash_cfg.cfg.wrEnableWriteRegLen = 0x02, /*!< Register length of write enable */
|
||||
.flash_cfg.cfg.wrEnableReadRegLen = 0x01, /*!< Register length of write enable status */
|
||||
.flash_cfg.cfg.qeWriteRegLen = 0x02, /*!< Register length of contain quad enable */
|
||||
.flash_cfg.cfg.qeReadRegLen = 0x01, /*!< Register length of contain quad enable status */
|
||||
.flash_cfg.cfg.releasePowerDown = 0xab, /*!< Release power down command */
|
||||
.flash_cfg.cfg.busyReadRegLen = 0x01, /*!< Register length of contain busy status */
|
||||
.flash_cfg.cfg.readRegCmd[0] = 0x05, /*!< Read register command buffer */
|
||||
.flash_cfg.cfg.readRegCmd[1] = 0x35, /*!< Read register command buffer */
|
||||
.flash_cfg.cfg.readRegCmd[2] = 0x00, /*!< Read register command buffer */
|
||||
.flash_cfg.cfg.readRegCmd[3] = 0x00, /*!< Read register command buffer */
|
||||
.flash_cfg.cfg.writeRegCmd[0] = 0x01, /*!< Write register command buffer */
|
||||
.flash_cfg.cfg.writeRegCmd[1] = 0x01, /*!< Write register command buffer */
|
||||
.flash_cfg.cfg.writeRegCmd[2] = 0x00, /*!< Write register command buffer */
|
||||
.flash_cfg.cfg.writeRegCmd[3] = 0x00, /*!< Write register command buffer */
|
||||
.flash_cfg.cfg.enterQpi = 0x38, /*!< Enter qpi command */
|
||||
.flash_cfg.cfg.exitQpi = 0xff, /*!< Exit qpi command */
|
||||
.flash_cfg.cfg.cReadMode = 0x20, /*!< Config data for continuous read mode */
|
||||
.flash_cfg.cfg.cRExit = 0xf0, /*!< Config data for exit continuous read mode */
|
||||
.flash_cfg.cfg.burstWrapCmd = 0x77, /*!< Enable burst wrap command */
|
||||
.flash_cfg.cfg.burstWrapCmdDmyClk = 0x03, /*!< Enable burst wrap command dummy clock */
|
||||
.flash_cfg.cfg.burstWrapDataMode = 0x02, /*!< Data and address mode for this command */
|
||||
.flash_cfg.cfg.burstWrapData = 0x40, /*!< Data to enable burst wrap */
|
||||
.flash_cfg.cfg.deBurstWrapCmd = 0x77, /*!< Disable burst wrap command */
|
||||
.flash_cfg.cfg.deBurstWrapCmdDmyClk = 0x03, /*!< Disable burst wrap command dummy clock */
|
||||
.flash_cfg.cfg.deBurstWrapDataMode = 0x02, /*!< Data and address mode for this command */
|
||||
.flash_cfg.cfg.deBurstWrapData = 0xf0, /*!< Data to disable burst wrap */
|
||||
.flash_cfg.cfg.timeEsector = 300, /*!< 4K erase time */
|
||||
.flash_cfg.cfg.timeE32k = 1200, /*!< 32K erase time */
|
||||
.flash_cfg.cfg.timeE64k = 1200, /*!< 64K erase time */
|
||||
.flash_cfg.cfg.timePagePgm = 50, /*!< Page program time */
|
||||
.flash_cfg.cfg.timeCe = 30000, /*!< Chip erase time in ms */
|
||||
.flash_cfg.cfg.pdDelay = 20, /*!< Release power down command delay time for wake up */
|
||||
.flash_cfg.cfg.qeData = 0, /*!< QE set data */
|
||||
.flash_cfg.crc32 = 0xdeadbeef,
|
||||
/* clock cfg */
|
||||
.clk_cfg.magiccode = 0x47464350,
|
||||
.clk_cfg.cfg.xtal_type = 0x07, /*!< 0:None,1:24M,2:32M,3:38.4M,4:40M,5:26M,6:RC32M */
|
||||
.clk_cfg.cfg.mcu_clk = 0x04, /*!< mcu_clk 0:RC32M,1:Xtal,2:cpupll 400M,3:wifipll 192M,4:wifipll 320M */
|
||||
.clk_cfg.cfg.mcu_clk_div = 0x00,
|
||||
.clk_cfg.cfg.mcu_bclk_div = 0x00,
|
||||
|
||||
.clk_cfg.cfg.mcu_pbclk_div = 0x03,
|
||||
.clk_cfg.cfg.lp_div = 0x01,
|
||||
.clk_cfg.cfg.dsp_clk = 0x03, /* 0:RC32M,1:Xtal,2:wifipll 240M,3:wifipll 320M,4:cpupll 400M */
|
||||
.clk_cfg.cfg.dsp_clk_div = 0x00,
|
||||
|
||||
.clk_cfg.cfg.dsp_bclk_div = 0x01,
|
||||
.clk_cfg.cfg.dsp_pbclk = 0x02, /* 0:RC32M,1:Xtal,2:wifipll 160M,3:cpupll 160M,4:wifipll 240M */
|
||||
.clk_cfg.cfg.dsp_pbclk_div = 0x00,
|
||||
.clk_cfg.cfg.emi_clk = 0x02, /*!< 0:mcu pbclk,1:cpupll 200M,2:wifipll 320M,3:cpupll 400M */
|
||||
|
||||
.clk_cfg.cfg.emi_clk_div = 0x01,
|
||||
.clk_cfg.cfg.flash_clk_type = 0x01, /*!< 0:wifipll 120M,1:xtal,2:cpupll 100M,3:wifipll 80M,4:bclk,5:wifipll 96M */
|
||||
.clk_cfg.cfg.flash_clk_div = 0x00,
|
||||
.clk_cfg.cfg.wifipll_pu = 0x01,
|
||||
|
||||
.clk_cfg.cfg.aupll_pu = 0x01,
|
||||
.clk_cfg.cfg.cpupll_pu = 0x01,
|
||||
.clk_cfg.cfg.mipipll_pu = 0x01,
|
||||
.clk_cfg.cfg.uhspll_pu = 0x01,
|
||||
|
||||
.clk_cfg.crc32 = 0xdeadbeef,
|
||||
|
||||
/* basic cfg */
|
||||
.basic_cfg.sign_type = 0x0, /* [1: 0] for sign */
|
||||
.basic_cfg.encrypt_type = 0x0, /* [3: 2] for encrypt */
|
||||
.basic_cfg.key_sel = 0x0, /* [5: 4] key slot */
|
||||
.basic_cfg.xts_mode = 0x0, /* [6] for xts mode */
|
||||
.basic_cfg.aes_region_lock = 0x0, /* [7] rsvd */
|
||||
.basic_cfg.no_segment = 0x1, /* [8] no segment info */
|
||||
.basic_cfg.rsvd_0 = 0x0, /* [9] boot2 enable(rsvd_0) */
|
||||
.basic_cfg.rsvd_1 = 0x0, /* [10] boot2 rollback(rsvd_1) */
|
||||
.basic_cfg.cpu_master_id = 0x0, /* [14: 11] master id */
|
||||
.basic_cfg.notload_in_bootrom = 0x0, /* [15] notload in bootrom */
|
||||
.basic_cfg.crc_ignore = 0x1, /* [16] ignore crc */
|
||||
.basic_cfg.hash_ignore = 0x1, /* [17] hash ignore */
|
||||
.basic_cfg.power_on_mm = 0x1, /* [18] power on mm */
|
||||
.basic_cfg.em_sel = 0x1, /* [21: 19] em_sel */
|
||||
.basic_cfg.cmds_en = 0x1, /* [22] command spliter enable */
|
||||
#if 0
|
||||
# 0 : cmds bypass wrap commands to macro, original mode;
|
||||
# 1 : cmds handle wrap commands, original mode;
|
||||
# 2 : cmds bypass wrap commands to macro, cmds force wrap16 * 4 splitted into two wrap8 * 4;
|
||||
# 3 : cmds handle wrap commands, cmds force wrap16 * 4 splitted into two wrap8 * 4
|
||||
#endif
|
||||
.basic_cfg.cmds_wrap_mode = 0x1, /* [24: 23] cmds wrap mode */
|
||||
#if 0
|
||||
# 0 : SF_CTRL_WRAP_LEN_8, 1 : SF_CTRL_WRAP_LEN_16, 2 : SF_CTRL_WRAP_LEN_32,
|
||||
# 3 : SF_CTRL_WRAP_LEN_64, 9 : SF_CTRL_WRAP_LEN_4096
|
||||
#endif
|
||||
.basic_cfg.cmds_wrap_len = 0x9, /* [28: 25] cmds wrap len */
|
||||
.basic_cfg.icache_invalid = 0x1, /* [29] icache invalid */
|
||||
.basic_cfg.dcache_invalid = 0x1, /* [30] dcache invalid */
|
||||
.basic_cfg.rsvd_3 = 0x0, /* [31] rsvd_3 */
|
||||
|
||||
#ifdef BFLB_BOOT2
|
||||
.basic_cfg.group_image_offset = 0x00002000, /* flash controller offset */
|
||||
#else
|
||||
.basic_cfg.group_image_offset = 0x00001000, /* flash controller offset */
|
||||
#endif
|
||||
.basic_cfg.aes_region_len = 0x00000000, /* aes region length */
|
||||
|
||||
.basic_cfg.img_len_cnt = 0x00010000, /* image length or segment count */
|
||||
.basic_cfg.hash = { 0xdeadbeef }, /* hash of the image */
|
||||
|
||||
/* cpu cfg */
|
||||
.cpu_cfg[0].config_enable = 0x01, /* coinfig this cpu */
|
||||
.cpu_cfg[0].halt_cpu = 0x0, /* halt this cpu */
|
||||
.cpu_cfg[0].cache_enable = 0x0, /* cache setting :only for BL Cache */
|
||||
.cpu_cfg[0].cache_wa = 0x0, /* cache setting :only for BL Cache*/
|
||||
.cpu_cfg[0].cache_wb = 0x0, /* cache setting :only for BL Cache*/
|
||||
.cpu_cfg[0].cache_wt = 0x0, /* cache setting :only for BL Cache*/
|
||||
.cpu_cfg[0].cache_way_dis = 0x0, /* cache setting :only for BL Cache*/
|
||||
.cpu_cfg[0].rsvd = 0x0,
|
||||
|
||||
.cpu_cfg[0].cache_range_h = 0x00000000,
|
||||
.cpu_cfg[0].cache_range_l = 0x00000000,
|
||||
/* image_address_offset */
|
||||
.cpu_cfg[0].image_address_offset = 0x0,
|
||||
.cpu_cfg[0].rsvd0 = 0x58000000, /* rsvd0 */
|
||||
.cpu_cfg[0].msp_val = 0x00000000, /* msp value */
|
||||
|
||||
/* cpu cfg */
|
||||
.cpu_cfg[1].config_enable = 0x0, /* coinfig this cpu */
|
||||
.cpu_cfg[1].halt_cpu = 0x0, /* halt this cpu */
|
||||
.cpu_cfg[1].cache_enable = 0x0, /* cache setting :only for BL Cache */
|
||||
.cpu_cfg[1].cache_wa = 0x0, /* cache setting :only for BL Cache*/
|
||||
.cpu_cfg[1].cache_wb = 0x0, /* cache setting :only for BL Cache*/
|
||||
.cpu_cfg[1].cache_wt = 0x0, /* cache setting :only for BL Cache*/
|
||||
.cpu_cfg[1].cache_way_dis = 0x0, /* cache setting :only for BL Cache*/
|
||||
.cpu_cfg[1].rsvd = 0x0,
|
||||
|
||||
.cpu_cfg[1].cache_range_h = 0x00000000,
|
||||
.cpu_cfg[1].cache_range_l = 0x00000000,
|
||||
/* image_address_offset */
|
||||
.cpu_cfg[1].image_address_offset = 0x0,
|
||||
.cpu_cfg[1].rsvd0 = 0x58000000, /* rsvd0 */
|
||||
.cpu_cfg[1].msp_val = 0x00000000, /* msp value */
|
||||
|
||||
/* address of partition table 0 */ /* 4 */
|
||||
.boot2_pt_table_0_rsvd = 0x00000000,
|
||||
/* address of partition table 1 */ /* 4 */
|
||||
.boot2_pt_table_1_rsvd = 0x00000000,
|
||||
|
||||
/* address of flashcfg table list */ /* 4 */
|
||||
.flash_cfg_table_addr = 0x00000000,
|
||||
/* flashcfg table list len */ /* 4 */
|
||||
.flash_cfg_table_len = 0x00000000,
|
||||
|
||||
.rsvd1[0] = 0x20000320,
|
||||
.rsvd1[1] = 0x00000000,
|
||||
.rsvd1[2] = 0x2000F038,
|
||||
.rsvd1[3] = 0x18000000,
|
||||
|
||||
.crc32 = 0xdeadbeef /* 4 */
|
||||
};
|
||||
|
||||
void fill_crcs(struct bl808_bootheader_t *bh) {
|
||||
bh->flash_cfg.crc32 = crc32_calculate((unsigned char *) &bh->flash_cfg.cfg, sizeof(struct bl808_spi_flash_cfg_t));
|
||||
bh->clk_cfg.crc32 = crc32_calculate((unsigned char *) &bh->clk_cfg.cfg, sizeof(struct bl808_sys_clk_cfg_t));
|
||||
bh->crc32 = crc32_calculate((unsigned char *) bh, sizeof(struct bl808_bootheader_t) - 4);
|
||||
}
|
||||
|
||||
@@ -23,16 +23,6 @@ target_link_libraries(blisp PRIVATE
|
||||
argtable3::argtable3
|
||||
libblisp_static file_parsers)
|
||||
|
||||
if (NOT CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
||||
target_compile_options(libblisp_obj PRIVATE -Wall -Wextra -Wpedantic)
|
||||
else()
|
||||
# MSVC does not support 'extra' and 'pedantic' levels to warnings.
|
||||
# `/Wall` seems to generate way too many non-actionable output marked as warnings.
|
||||
# We settle for `/W4`.
|
||||
# https://learn.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level?view=msvc-170
|
||||
target_compile_options(libblisp_obj PRIVATE -W4)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(blisp PRIVATE Setupapi.lib)
|
||||
elseif (APPLE)
|
||||
|
||||
+22
-54
@@ -1,6 +1,5 @@
|
||||
#include <argtable3.h>
|
||||
#include <blisp_easy.h>
|
||||
|
||||
#include "../cmd.h"
|
||||
#include "../common.h"
|
||||
|
||||
@@ -11,27 +10,15 @@ 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_int *baudrate;
|
||||
static struct arg_lit* reset;
|
||||
static struct arg_lit* chiperase;
|
||||
static struct arg_end* end;
|
||||
static void* cmd_iot_argtable[9];
|
||||
static void* cmd_iot_argtable[7];
|
||||
static void cmd_iot_args_print_glossary();
|
||||
|
||||
blisp_return_t blisp_single_download(void) {
|
||||
blisp_return_t blisp_single_download() {
|
||||
struct blisp_device device;
|
||||
blisp_return_t ret;
|
||||
|
||||
uint32_t baud = DEFAULT_BAUDRATE;
|
||||
if (baudrate->count == 1) {
|
||||
if (*baudrate->ival < 0) {
|
||||
fprintf(stderr, "Baud rate cannot be negative!\n");
|
||||
return BLISP_ERR_INVALID_COMMAND;
|
||||
} else {
|
||||
baud = *baudrate->ival;
|
||||
}
|
||||
}
|
||||
|
||||
if (access(single_download->filename[0], R_OK) != 0) {
|
||||
// File not accessible, error out.
|
||||
fprintf(stderr, "Input firmware not found: %s\n", single_download->filename[0]);
|
||||
@@ -40,25 +27,13 @@ blisp_return_t blisp_single_download(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = blisp_common_init_device(&device, port_name, chip_type, baud);
|
||||
ret = blisp_common_init_device(&device, port_name, chip_type);
|
||||
if (ret != BLISP_OK) {
|
||||
return ret;
|
||||
}
|
||||
ret = blisp_common_prepare_flash(&device);
|
||||
if (ret != BLISP_OK) {
|
||||
// TODO: user-friendly error messages
|
||||
fprintf(stderr, "Failed to initialize device, ret: %d\n", ret);
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
if (chiperase->count) {
|
||||
printf("Performing a chip erase, this might take a while...\n");
|
||||
ret = blisp_device_chip_erase(&device);
|
||||
if (ret == BLISP_OK) {
|
||||
printf("Erase complete!\n");
|
||||
} else {
|
||||
fprintf(stderr, "Failed to erase, ret: %d\n", ret);
|
||||
}
|
||||
// TODO: Error handling
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
@@ -76,9 +51,9 @@ blisp_return_t blisp_single_download(void) {
|
||||
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);
|
||||
*single_download_location->ival + data_file_size + 1);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to erase, ret: %d\n", ret);
|
||||
fprintf(stderr, "Failed to erase.\n");
|
||||
goto exit2;
|
||||
}
|
||||
|
||||
@@ -89,15 +64,15 @@ blisp_return_t blisp_single_download(void) {
|
||||
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, ret: %d\n", ret);
|
||||
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, ret: %d\n", ret);
|
||||
fprintf(stderr, "Failed to check program.\n");
|
||||
goto exit2;
|
||||
}
|
||||
printf("Program OK!\n");
|
||||
@@ -106,7 +81,7 @@ blisp_return_t blisp_single_download(void) {
|
||||
printf("Resetting the chip.\n");
|
||||
ret = blisp_device_reset(&device);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to reset chip, ret: %d\n", ret);
|
||||
fprintf(stderr, "Failed to reset chip.\n");
|
||||
goto exit2;
|
||||
}
|
||||
}
|
||||
@@ -123,28 +98,21 @@ exit1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
blisp_return_t cmd_iot_args_init(void) {
|
||||
size_t index = 0;
|
||||
|
||||
cmd_iot_argtable[index++] = cmd =
|
||||
blisp_return_t cmd_iot_args_init() {
|
||||
cmd_iot_argtable[0] = cmd =
|
||||
arg_rex1(NULL, NULL, "iot", NULL, REG_ICASE, NULL);
|
||||
cmd_iot_argtable[index++] = chip_type =
|
||||
cmd_iot_argtable[1] = chip_type =
|
||||
arg_str1("c", "chip", "<chip_type>", "Chip Type");
|
||||
cmd_iot_argtable[index++] = port_name =
|
||||
cmd_iot_argtable[2] = port_name =
|
||||
arg_str0("p", "port", "<port_name>",
|
||||
"Name/Path to the Serial Port (empty for search)");
|
||||
cmd_iot_argtable[index++] = baudrate =
|
||||
arg_int0("b", "baudrate", "<baud rate>",
|
||||
"Serial baud rate (default: " XSTR(DEFAULT_BAUDRATE) ")");
|
||||
cmd_iot_argtable[index++] = reset =
|
||||
cmd_iot_argtable[3] = reset =
|
||||
arg_lit0(NULL, "reset", "Reset chip after write");
|
||||
cmd_iot_argtable[index++] = chiperase =
|
||||
arg_lit0(NULL, "chiperase", "Do not write any data; erase the entire chip instead");
|
||||
cmd_iot_argtable[index++] = single_download =
|
||||
cmd_iot_argtable[4] = single_download =
|
||||
arg_file0("s", "single-down", "<file>", "Single download file");
|
||||
cmd_iot_argtable[index++] = single_download_location =
|
||||
cmd_iot_argtable[5] = single_download_location =
|
||||
arg_int0("l", "single-down-loc", NULL, "Single download offset");
|
||||
cmd_iot_argtable[index++] = end = arg_end(10);
|
||||
cmd_iot_argtable[6] = end = arg_end(10);
|
||||
|
||||
if (arg_nullcheck(cmd_iot_argtable) != 0) {
|
||||
fprintf(stderr, "insufficient memory\n");
|
||||
@@ -153,7 +121,7 @@ blisp_return_t cmd_iot_args_init(void) {
|
||||
return BLISP_OK;
|
||||
}
|
||||
|
||||
void cmd_iot_args_print_glossary(void) {
|
||||
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");
|
||||
@@ -163,7 +131,7 @@ void cmd_iot_args_print_glossary(void) {
|
||||
blisp_return_t cmd_iot_parse_exec(int argc, char** argv) {
|
||||
int errors = arg_parse(argc, argv, cmd_iot_argtable);
|
||||
if (errors == 0) {
|
||||
if (chiperase->count || (single_download->count == 1 && single_download_location->count == 1)) {
|
||||
if (single_download->count == 1 && single_download_location->count == 1) {
|
||||
return blisp_single_download();
|
||||
} else {
|
||||
return BLISP_ERR_INVALID_COMMAND;
|
||||
@@ -175,11 +143,11 @@ blisp_return_t cmd_iot_parse_exec(int argc, char** argv) {
|
||||
return BLISP_ERR_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
void cmd_iot_args_print_syntax(void) {
|
||||
void cmd_iot_args_print_syntax() {
|
||||
arg_print_syntax(stdout, cmd_iot_argtable, "\n");
|
||||
}
|
||||
|
||||
void cmd_iot_free(void) {
|
||||
void cmd_iot_free() {
|
||||
arg_freetable(cmd_iot_argtable,
|
||||
sizeof(cmd_iot_argtable) / sizeof(cmd_iot_argtable[0]));
|
||||
}
|
||||
|
||||
+23
-45
@@ -17,10 +17,9 @@
|
||||
static struct arg_rex* cmd;
|
||||
static struct arg_file* binary_to_write;
|
||||
static struct arg_str *port_name, *chip_type;
|
||||
static struct arg_int *baudrate;
|
||||
static struct arg_lit* reset;
|
||||
static struct arg_end* end;
|
||||
static void* cmd_write_argtable[7];
|
||||
static void* cmd_write_argtable[6];
|
||||
static void cmd_write_args_print_glossary();
|
||||
|
||||
void fill_up_boot_header(struct bfl_boot_header* boot_header) {
|
||||
@@ -167,47 +166,33 @@ void fill_up_boot_header(struct bfl_boot_header* boot_header) {
|
||||
boot_header->crc32 = 0xDEADBEEF;
|
||||
}
|
||||
|
||||
blisp_return_t blisp_flash_firmware(void) {
|
||||
blisp_return_t blisp_flash_firmware() {
|
||||
struct blisp_device device;
|
||||
blisp_return_t ret = BLISP_OK;
|
||||
|
||||
uint32_t baud = DEFAULT_BAUDRATE;
|
||||
if (baudrate->count == 1) {
|
||||
if (*baudrate->ival < 0) {
|
||||
fprintf(stderr, "Baud rate cannot be negative!\n");
|
||||
return BLISP_ERR_INVALID_COMMAND;
|
||||
} else {
|
||||
baud = *baudrate->ival;
|
||||
}
|
||||
}
|
||||
blisp_return_t ret;
|
||||
|
||||
if (access(binary_to_write->filename[0], R_OK) != 0) {
|
||||
// File not accessible, error out.
|
||||
fprintf(stderr, "Input firmware not found: %s\n", binary_to_write->filename[0]);
|
||||
cmd_write_args_print_glossary(); /* Print help to assist user */
|
||||
/* No need to free memory, will now exit with ret code 1 */
|
||||
return BLISP_ERR_CANT_OPEN_FILE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = blisp_common_init_device(&device, port_name, chip_type, baud);
|
||||
if (ret != BLISP_OK) {
|
||||
ret = blisp_common_init_device(&device, port_name, chip_type);
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = blisp_common_prepare_flash(&device);
|
||||
if (ret != BLISP_OK) {
|
||||
if (blisp_common_prepare_flash(&device) != 0) {
|
||||
// TODO: Error handling
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
parsed_firmware_file_t parsed_file;
|
||||
memset(&parsed_file, 0, sizeof(parsed_file));
|
||||
if (parse_firmware_file(binary_to_write->filename[0], &parsed_file) < 0) {
|
||||
// `parse_firmware_file` doesn't return `blisp_return_t`
|
||||
// so we default to the generic error.
|
||||
ret = BLISP_ERR_UNKNOWN;
|
||||
goto exit1;
|
||||
}
|
||||
int parsed_result =
|
||||
parse_firmware_file(binary_to_write->filename[0], &parsed_file);
|
||||
|
||||
// If we are injecting a bootloader section, make it, erase flash, and flash
|
||||
// it. Then when we do firmware later on; it will be located afterwards
|
||||
@@ -248,13 +233,13 @@ blisp_return_t blisp_flash_firmware(void) {
|
||||
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr,
|
||||
"Failed to erase flash. Tried to erase from 0x%08zx to 0x%08zx\n",
|
||||
"Failed to erase flash. Tried to erase from 0x%08lu to 0x%08lu\n",
|
||||
parsed_file.payload_address,
|
||||
parsed_file.payload_address + parsed_file.payload_length + 1);
|
||||
goto exit2;
|
||||
}
|
||||
|
||||
printf("Flashing the firmware %zu bytes @ 0x%08zx...\n",
|
||||
printf("Flashing the firmware %lu bytes @ 0x%08lu...\n",
|
||||
parsed_file.payload_length, parsed_file.payload_address);
|
||||
struct blisp_easy_transport data_transport =
|
||||
blisp_easy_transport_new_from_memory(parsed_file.payload,
|
||||
@@ -264,7 +249,7 @@ blisp_return_t blisp_flash_firmware(void) {
|
||||
&device, &data_transport, parsed_file.payload_address,
|
||||
parsed_file.payload_length, blisp_common_progress_callback);
|
||||
|
||||
if (ret != BLISP_OK) {
|
||||
if (ret < BLISP_OK) {
|
||||
fprintf(stderr, "Failed to write app to flash.\n");
|
||||
goto exit2;
|
||||
}
|
||||
@@ -290,28 +275,21 @@ exit2:
|
||||
free(parsed_file.payload);
|
||||
exit1:
|
||||
blisp_device_close(&device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
blisp_return_t cmd_write_args_init(void) {
|
||||
size_t index = 0;
|
||||
|
||||
cmd_write_argtable[index++] = cmd =
|
||||
blisp_return_t cmd_write_args_init() {
|
||||
cmd_write_argtable[0] = cmd =
|
||||
arg_rex1(NULL, NULL, "write", NULL, REG_ICASE, NULL);
|
||||
cmd_write_argtable[index++] = chip_type =
|
||||
cmd_write_argtable[1] = chip_type =
|
||||
arg_str1("c", "chip", "<chip_type>", "Chip Type");
|
||||
cmd_write_argtable[index++] = port_name =
|
||||
cmd_write_argtable[2] = port_name =
|
||||
arg_str0("p", "port", "<port_name>",
|
||||
"Name/Path to the Serial Port (empty for search)");
|
||||
cmd_write_argtable[index++] = baudrate =
|
||||
arg_int0("b", "baudrate", "<baud rate>",
|
||||
"Serial baud rate (default: " XSTR(DEFAULT_BAUDRATE) ")");
|
||||
cmd_write_argtable[index++] = reset =
|
||||
cmd_write_argtable[3] = reset =
|
||||
arg_lit0(NULL, "reset", "Reset chip after write");
|
||||
cmd_write_argtable[index++] = binary_to_write =
|
||||
cmd_write_argtable[4] = binary_to_write =
|
||||
arg_file1(NULL, NULL, "<input>", "Binary to write");
|
||||
cmd_write_argtable[index++] = end = arg_end(10);
|
||||
cmd_write_argtable[5] = end = arg_end(10);
|
||||
|
||||
if (arg_nullcheck(cmd_write_argtable) != 0) {
|
||||
fprintf(stderr, "insufficient memory\n");
|
||||
@@ -320,7 +298,7 @@ blisp_return_t cmd_write_args_init(void) {
|
||||
return BLISP_OK;
|
||||
}
|
||||
|
||||
void cmd_write_args_print_glossary(void) {
|
||||
void cmd_write_args_print_glossary() {
|
||||
fputs("Usage: blisp", stdout);
|
||||
arg_print_syntax(stdout, cmd_write_argtable, "\n");
|
||||
puts("Writes firmware to SPI Flash");
|
||||
@@ -339,11 +317,11 @@ blisp_return_t cmd_write_parse_exec(int argc, char** argv) {
|
||||
return BLISP_ERR_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
void cmd_write_args_print_syntax(void) {
|
||||
void cmd_write_args_print_syntax() {
|
||||
arg_print_syntax(stdout, cmd_write_argtable, "\n");
|
||||
}
|
||||
|
||||
void cmd_write_free(void) {
|
||||
void cmd_write_free() {
|
||||
arg_freetable(cmd_write_argtable,
|
||||
sizeof(cmd_write_argtable) / sizeof(cmd_write_argtable[0]));
|
||||
}
|
||||
|
||||
+29
-85
@@ -8,7 +8,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "blisp_easy.h"
|
||||
#include "blisp_util.h"
|
||||
#include "error_codes.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -20,8 +19,7 @@ void blisp_common_progress_callback(uint32_t current_value,
|
||||
|
||||
blisp_return_t blisp_common_init_device(struct blisp_device* device,
|
||||
struct arg_str* port_name,
|
||||
struct arg_str* chip_type,
|
||||
uint32_t baudrate) {
|
||||
struct arg_str* chip_type) {
|
||||
if (chip_type->count == 0) {
|
||||
fprintf(stderr, "Chip type is invalid.\n");
|
||||
return BLISP_ERR_INVALID_CHIP_TYPE;
|
||||
@@ -33,8 +31,6 @@ blisp_return_t blisp_common_init_device(struct blisp_device* device,
|
||||
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 BLISP_ERR_INVALID_CHIP_TYPE;
|
||||
@@ -43,18 +39,15 @@ blisp_return_t blisp_common_init_device(struct blisp_device* device,
|
||||
blisp_return_t ret;
|
||||
ret = blisp_device_init(device, chip);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to init device, ret: %d\n", ret);
|
||||
fprintf(stderr, "Failed to init device.\n");
|
||||
return ret;
|
||||
}
|
||||
ret = blisp_device_open(device,
|
||||
port_name->count == 1 ? port_name->sval[0] : NULL,
|
||||
baudrate);
|
||||
port_name->count == 1 ? port_name->sval[0] : NULL);
|
||||
if (ret != BLISP_OK) {
|
||||
if (ret == BLISP_ERR_DEVICE_NOT_FOUND) {
|
||||
fprintf(stderr, "Device not found\n");
|
||||
} else {
|
||||
fprintf(stderr, "Failed to open device, ret: %d\n", ret);
|
||||
}
|
||||
fprintf(stderr, ret == BLISP_ERR_DEVICE_NOT_FOUND
|
||||
? "Device not found\n"
|
||||
: "Failed to open device.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -67,78 +60,29 @@ blisp_return_t blisp_common_init_device(struct blisp_device* device,
|
||||
*/
|
||||
blisp_return_t blisp_common_prepare_flash(struct blisp_device* device) {
|
||||
blisp_return_t ret = 0;
|
||||
uint32_t previous_timeout;
|
||||
|
||||
printf("Sending a handshake...\n");
|
||||
ret = blisp_device_handshake(device, false);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to handshake with device.\n");
|
||||
return ret;
|
||||
}
|
||||
printf("Handshake successful!\nGetting chip info...\n");
|
||||
struct blisp_boot_info boot_info;
|
||||
|
||||
// We may already be in communication with the chip from a previous
|
||||
// invocation of this command. In that case, it will not respond to our
|
||||
// handshake. We detect this by trying to send a command to it, using a
|
||||
// (relatively) short timeout.
|
||||
//
|
||||
// NOTE: This appears to be how BouffaloLab software does it as well.
|
||||
//
|
||||
// NOTE: Modifying the timeout is mandatory for BL808;
|
||||
// see blisp.c:blisp_device_init()
|
||||
previous_timeout = device->serial_timeout;
|
||||
device->serial_timeout = 500;
|
||||
printf("Testing if we can skip the handshake...\n");
|
||||
ret = blisp_device_get_boot_info(device, &boot_info);
|
||||
device->serial_timeout = previous_timeout;
|
||||
|
||||
if (ret == BLISP_OK) {
|
||||
printf("Skipping handshake!\n");
|
||||
} else {
|
||||
printf("We can't; ignore the previous error.\n");
|
||||
printf("Sending a handshake...\n");
|
||||
ret = blisp_device_handshake(device, false);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to handshake with device, ret: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
printf("Handshake successful!\nGetting chip info...\n");
|
||||
ret = blisp_device_get_boot_info(device, &boot_info);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to get boot info, ret: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to get boot info.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: Do we want this to print in big endian to match the output
|
||||
// of Bouffalo's software?
|
||||
if (device->chip->type == BLISP_CHIP_BL70X) {
|
||||
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]);
|
||||
} else {
|
||||
printf(
|
||||
"BootROM version %d.%d.%d.%d, ChipID: "
|
||||
"%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]);
|
||||
}
|
||||
|
||||
if (device->chip->type == BLISP_CHIP_BL808) {
|
||||
printf("Setting clock parameters ...\n");
|
||||
ret = bl808_load_clock_para(device, true, device->current_baud_rate);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to set clock parameters, ret: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
printf("Setting flash parameters ...\n");
|
||||
ret = bl808_load_flash_para(device);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to set flash parameters, ret: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
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 BLISP_OK;
|
||||
@@ -175,20 +119,20 @@ blisp_return_t blisp_common_prepare_flash(struct blisp_device* device) {
|
||||
|
||||
ret = blisp_device_check_image(device);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to check image, ret: %d\n", ret);
|
||||
fprintf(stderr, "Failed to check image.\n");
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
ret = blisp_device_run_image(device);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to run image, ret: %d\n", ret);
|
||||
fprintf(stderr, "Failed to run image.\n");
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
printf("Sending a handshake...\n");
|
||||
ret = blisp_device_handshake(device, true);
|
||||
if (ret != BLISP_OK) {
|
||||
fprintf(stderr, "Failed to handshake with device, ret: %d\n", ret);
|
||||
fprintf(stderr, "Failed to handshake with device.\n");
|
||||
goto exit1;
|
||||
}
|
||||
printf("Handshake with eflash_loader successful.\n");
|
||||
@@ -197,4 +141,4 @@ exit1:
|
||||
free(eflash_loader_buffer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,8 @@
|
||||
#include <blisp.h>
|
||||
#include <argtable3.h>
|
||||
|
||||
// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
||||
#define DEFAULT_BAUDRATE 460800
|
||||
#define STR(x) #x
|
||||
#define XSTR(x) STR(x)
|
||||
|
||||
blisp_return_t blisp_common_prepare_flash(struct blisp_device* device);
|
||||
int32_t blisp_common_prepare_flash(struct blisp_device* device);
|
||||
void blisp_common_progress_callback(uint32_t current_value, uint32_t max_value);
|
||||
blisp_return_t blisp_common_init_device(struct blisp_device* device, struct arg_str* port_name, struct arg_str* chip_type, uint32_t baudrate);
|
||||
int32_t blisp_common_init_device(struct blisp_device* device, struct arg_str* port_name, struct arg_str* chip_type);
|
||||
|
||||
#endif // BLISP_COMMON_H
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
list(APPEND ADD_INCLUDE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/bin"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dfu"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/hex"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
@@ -13,7 +12,6 @@ add_library(file_parsers STATIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/bin/bin_file.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dfu/dfu_file.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dfu/dfu_crc.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/hex/hex_file.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/parse_file.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/get_file_contents.c"
|
||||
)
|
||||
@@ -21,7 +19,6 @@ add_library(file_parsers STATIC
|
||||
target_include_directories(file_parsers PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bin
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/dfu
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hex
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
|
||||
)
|
||||
|
||||
@@ -78,7 +78,6 @@ int dfu_file_parse(const char* file_path_on_disk,
|
||||
size_t* payload_address) {
|
||||
uint8_t* dfu_file_contents = NULL;
|
||||
ssize_t file_size = get_file_contents(file_path_on_disk, &dfu_file_contents);
|
||||
// Bubble up the result if it was an error instead of size (a negative value)
|
||||
if (file_size < 0) {
|
||||
return file_size;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,31 @@
|
||||
add_executable(dfu_file_test test_dfu_file.cpp ../dfu_file.c ../dfu_crc.c ../../get_file_contents.c)
|
||||
enable_language(CXX)
|
||||
|
||||
enable_testing()
|
||||
include(FetchContent)
|
||||
|
||||
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG release-1.11.0
|
||||
)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
add_library(GTest::GTest INTERFACE IMPORTED)
|
||||
target_link_libraries(GTest::GTest INTERFACE gtest_main)
|
||||
|
||||
|
||||
add_executable(dfu_file_test test_dfu_file.cpp ../dfu_file.c ../dfu_crc.c)
|
||||
|
||||
target_link_libraries(dfu_file_test
|
||||
PRIVATE
|
||||
GTest::GTest
|
||||
)
|
||||
include(GoogleTest)
|
||||
include_directories(dfu_file_test PRIVATE ../ ../../)
|
||||
target_compile_definitions(dfu_file_test PUBLIC "SOURCE_DIR=\"${CMAKE_SOURCE_DIR}\"")
|
||||
gtest_discover_tests(dfu_file_test)
|
||||
include_directories(dfu_file_test PRIVATE ../)
|
||||
add_test(dfu_file_test_gtests dfu_file_test)
|
||||
|
||||
configure_file(Config.h.in ${CMAKE_BINARY_DIR}/Config.h)
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
|
||||
set(TEST_APP_NAME dfu_file_tests)
|
||||
|
||||
#add_custom_command(TARGET ${TEST_APP_NAME} COMMAND ./${TEST_APP_NAME} POST_BUILD)
|
||||
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by ralim on 26/09/22.
|
||||
//
|
||||
|
||||
#ifndef BLISP_CONFIG_H_IN_H
|
||||
#define BLISP_CONFIG_H_IN_H
|
||||
|
||||
#define SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
|
||||
#endif // BLISP_CONFIG_H_IN_H
|
||||
@@ -2,16 +2,16 @@
|
||||
// Created by ralim on 26/09/22.
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "Config.h"
|
||||
#include "dfu_file.h"
|
||||
#include <gtest/gtest.h>
|
||||
TEST(DFU_FILE_PARSER, ParseTestFile) {
|
||||
uint8_t* payload = nullptr;
|
||||
size_t payload_size = 0;
|
||||
size_t payload_address = 0;
|
||||
int res = dfu_file_parse(SOURCE_DIR
|
||||
"/tools/blisp/src/file_parsers/dfu/tests/test.dfu",
|
||||
&payload, &payload_size, &payload_address);
|
||||
ASSERT_EQ(res, 1);
|
||||
ASSERT_EQ(payload_size, 1337);
|
||||
ASSERT_EQ(payload_address, 0x11223344);
|
||||
}
|
||||
uint8_t* payload = nullptr;
|
||||
size_t payload_size = 0;
|
||||
size_t payload_address = 0;
|
||||
int res = dfu_file_parse(SOURCE_DIR "/test.dfu", &payload, &payload_size,
|
||||
&payload_address);
|
||||
ASSERT_EQ(res, 1);
|
||||
ASSERT_EQ(payload_size, 1337);
|
||||
ASSERT_EQ(payload_address, 0x11223344);
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
#include "hex_file.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "parse_file.h"
|
||||
|
||||
// Convert ASCII hex character to integer
|
||||
static int hex_to_int(char c) {
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Convert 2 ASCII hex characters to a byte
|
||||
static int hex_byte_to_int(const char* str) {
|
||||
int high = hex_to_int(str[0]);
|
||||
int low = hex_to_int(str[1]);
|
||||
if (high < 0 || low < 0)
|
||||
return -1;
|
||||
return (high << 4) | low;
|
||||
}
|
||||
|
||||
// Parse a single Intel HEX line into the record type and data
|
||||
// Returns: Record Type on success, negative error code on failure
|
||||
static int parse_hex_line(const char* line,
|
||||
uint8_t* data_buffer,
|
||||
uint32_t* address,
|
||||
uint32_t* base_address,
|
||||
uint32_t* max_address,
|
||||
uint32_t min_address) {
|
||||
size_t len = strlen(line);
|
||||
|
||||
// Line must start with ':' and have at least 11 characters (:BBAAAATTCC)
|
||||
if (line[0] != ':' || len < 11) {
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
// Extract record fields
|
||||
int byte_count = hex_byte_to_int(line + 1);
|
||||
if (byte_count < 0)
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
|
||||
// Make sure line is long enough
|
||||
if (len < (size_t)(11 + byte_count * 2)) {
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
int addr_high = hex_byte_to_int(line + 3);
|
||||
int addr_low = hex_byte_to_int(line + 5);
|
||||
if (addr_high < 0 || addr_low < 0)
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
|
||||
uint16_t record_address = (addr_high << 8) | addr_low;
|
||||
|
||||
int record_type = hex_byte_to_int(line + 7);
|
||||
if (record_type < 0)
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
|
||||
// Verify checksum
|
||||
uint8_t checksum = 0;
|
||||
for (int i = 1; i < 9 + byte_count * 2; i += 2) {
|
||||
int value = hex_byte_to_int(line + i);
|
||||
if (value < 0) {
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
checksum += value;
|
||||
}
|
||||
|
||||
int file_checksum = hex_byte_to_int(line + 9 + byte_count * 2);
|
||||
if (file_checksum < 0) {
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
checksum = ~checksum + 1; // Two's complement
|
||||
// Verify checksum
|
||||
if (checksum != file_checksum) {
|
||||
return HEX_PARSE_ERROR_CHECKSUM;
|
||||
}
|
||||
|
||||
// Process the record based on record type
|
||||
switch (record_type) {
|
||||
case HEX_RECORD_DATA: {
|
||||
uint32_t absolute_address = *base_address + record_address;
|
||||
*address = absolute_address;
|
||||
|
||||
// Update max address if this data extends beyond current max
|
||||
if (absolute_address + byte_count > *max_address) {
|
||||
*max_address = absolute_address + byte_count;
|
||||
}
|
||||
|
||||
// Parse data bytes
|
||||
for (int i = 0; i < byte_count; i++) {
|
||||
int value = hex_byte_to_int(line + 9 + i * 2);
|
||||
if (value < 0)
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
|
||||
// Make sure we don't write outside our buffer
|
||||
if (data_buffer != NULL) {
|
||||
size_t buf_offset = absolute_address - min_address + i;
|
||||
data_buffer[buf_offset] = value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case HEX_RECORD_EOF:
|
||||
// End of file, nothing to do
|
||||
break;
|
||||
|
||||
case HEX_RECORD_EXTENDED_SEGMENT:
|
||||
// Set segment base address (offset = value * 16)
|
||||
if (byte_count != 2)
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
int value_high = hex_byte_to_int(line + 9);
|
||||
int value_low = hex_byte_to_int(line + 11);
|
||||
if (value_high < 0 || value_low < 0)
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
*base_address = ((value_high << 8) | value_low) << 4;
|
||||
break;
|
||||
|
||||
case HEX_RECORD_EXTENDED_LINEAR:
|
||||
// Set high-order 16 bits of address
|
||||
if (byte_count != 2)
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
value_high = hex_byte_to_int(line + 9);
|
||||
value_low = hex_byte_to_int(line + 11);
|
||||
if (value_high < 0 || value_low < 0)
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
*base_address = ((value_high << 8) | value_low) << 16;
|
||||
break;
|
||||
|
||||
case HEX_RECORD_START_LINEAR:
|
||||
// Start linear address - store as a potential entry point
|
||||
// but not crucial for firmware extraction
|
||||
break;
|
||||
|
||||
case HEX_RECORD_START_SEGMENT:
|
||||
// Start segment address - similar to above
|
||||
break;
|
||||
|
||||
default:
|
||||
return HEX_PARSE_ERROR_UNSUPPORTED_RECORD;
|
||||
}
|
||||
|
||||
return record_type;
|
||||
}
|
||||
|
||||
int hex_file_parse(const char* file_path_on_disk,
|
||||
uint8_t** payload,
|
||||
size_t* payload_length,
|
||||
size_t* payload_address) {
|
||||
FILE* file = fopen(file_path_on_disk, "r");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Could not open file %s for reading\n", file_path_on_disk);
|
||||
return PARSED_ERROR_CANT_OPEN_FILE;
|
||||
}
|
||||
|
||||
// First pass: Find start and end addresses, and thus size of the payload
|
||||
char line[512];
|
||||
uint32_t base_address = 0;
|
||||
uint32_t address = 0;
|
||||
uint32_t min_address = 0xFFFFFFFF;
|
||||
uint32_t max_address = 0;
|
||||
bool found_data = false;
|
||||
|
||||
// First pass to determine memory range
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
size_t len = strlen(line);
|
||||
// Trim trailing newline and carriage return
|
||||
while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
|
||||
line[--len] = 0;
|
||||
}
|
||||
if (len == 0 || line[0] != ':')
|
||||
continue;
|
||||
|
||||
int result =
|
||||
parse_hex_line(line, NULL, &address, &base_address, &max_address, 0);
|
||||
if (result < 0) {
|
||||
fclose(file);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if this is a data record (type 0)
|
||||
if (result == HEX_RECORD_DATA) {
|
||||
found_data = true;
|
||||
if (address < min_address) {
|
||||
min_address = address;
|
||||
}
|
||||
}
|
||||
|
||||
// If we hit EOF record, we're done
|
||||
if (result == HEX_RECORD_EOF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no data was found, return error
|
||||
if (!found_data) {
|
||||
fclose(file);
|
||||
return HEX_PARSE_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
// Calculate payload size
|
||||
size_t size = max_address - min_address;
|
||||
if (size > (1024 * 1024 * 128)) { // Limit to 128 MB
|
||||
fclose(file);
|
||||
return HEX_PARSE_ERROR_TOO_LARGE;
|
||||
}
|
||||
// Allocate memory for the payload
|
||||
*payload = (uint8_t*)calloc(size, sizeof(uint8_t));
|
||||
if (!*payload) {
|
||||
fclose(file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Clear the memory to ensure all bytes are initialized
|
||||
memset(*payload, 0, size);
|
||||
|
||||
// Second pass: actually parse the data and fill out the buffer with the data
|
||||
rewind(file);
|
||||
base_address = 0;
|
||||
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
size_t len = strlen(line);
|
||||
// Trim trailing newline and carriage return
|
||||
while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) {
|
||||
line[--len] = 0;
|
||||
}
|
||||
if (len == 0 || line[0] != ':')
|
||||
continue;
|
||||
|
||||
// When parsing for real, data is written to the payload buffer
|
||||
// with addresses relative to min_address
|
||||
uint32_t dummy_max = 0;
|
||||
|
||||
int result = parse_hex_line(line, *payload, &address, &base_address,
|
||||
&dummy_max, min_address);
|
||||
if (result < 0) {
|
||||
free(*payload);
|
||||
*payload = NULL;
|
||||
fclose(file);
|
||||
return result;
|
||||
}
|
||||
|
||||
// If we hit EOF record, we're done
|
||||
if (result == HEX_RECORD_EOF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
// Set output parameters
|
||||
*payload_length = size;
|
||||
*payload_address = min_address;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
//
|
||||
// Created for Intel HEX file parsing
|
||||
//
|
||||
|
||||
#ifndef BLISP_HEX_FILE_H
|
||||
#define BLISP_HEX_FILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Error codes specific to hex parsing
|
||||
#define HEX_PARSE_ERROR_INVALID_FORMAT -0x2001
|
||||
#define HEX_PARSE_ERROR_CHECKSUM -0x2002
|
||||
#define HEX_PARSE_ERROR_UNSUPPORTED_RECORD -0x2003
|
||||
#define HEX_PARSE_ERROR_TOO_LARGE -0x2004
|
||||
|
||||
// Intel HEX record types
|
||||
typedef enum {
|
||||
HEX_RECORD_DATA = 0x00, // Data record
|
||||
HEX_RECORD_EOF = 0x01, // End of file record
|
||||
HEX_RECORD_EXTENDED_SEGMENT = 0x02, // Extended segment address record
|
||||
HEX_RECORD_START_SEGMENT = 0x03, // Start segment address record
|
||||
HEX_RECORD_EXTENDED_LINEAR = 0x04, // Extended linear address record
|
||||
HEX_RECORD_START_LINEAR = 0x05 // Start linear address record
|
||||
} hex_record_type_t;
|
||||
|
||||
// Parse an Intel HEX file and return a contiguous memory block
|
||||
// Parameters:
|
||||
// file_path_on_disk: Path to the Intel HEX file
|
||||
// payload: Pointer to the buffer that will hold the parsed data
|
||||
// payload_length: Size of the payload
|
||||
// payload_address: Start address of the payload
|
||||
// Returns:
|
||||
// 0 on success, negative value on error
|
||||
int hex_file_parse(const char* file_path_on_disk,
|
||||
uint8_t** payload,
|
||||
size_t* payload_length,
|
||||
size_t* payload_address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // BLISP_HEX_FILE_H
|
||||
@@ -1,10 +0,0 @@
|
||||
add_executable(hex_file_test test_hex_file.cpp ../hex_file.c )
|
||||
|
||||
target_link_libraries(hex_file_test
|
||||
PRIVATE
|
||||
GTest::GTest
|
||||
)
|
||||
include(GoogleTest)
|
||||
include_directories(hex_file_test PRIVATE ../ ../../)
|
||||
target_compile_definitions(hex_file_test PUBLIC "SOURCE_DIR=\"${CMAKE_SOURCE_DIR}\"")
|
||||
gtest_discover_tests(hex_file_test)
|
||||
@@ -1,9 +0,0 @@
|
||||
:02000004230FC8
|
||||
:10FC0000400196000500000021005A000200070094
|
||||
:10FC10000100000000001E000000000000000000C5
|
||||
:10FC2000000000000000040001007602A40184032B
|
||||
:10FC3000000000000A0001000700000000000000B2
|
||||
:10FC4000140000001A000100000000000000040081
|
||||
:10FC50005A00010082005A008C001E00A5001E0000
|
||||
:10FC60008C001E005A001E00020000000000000070
|
||||
:00000001FF
|
||||
@@ -1,47 +0,0 @@
|
||||
// Intel hex file parser test
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "hex_file.h"
|
||||
#include "parse_file.h"
|
||||
|
||||
TEST(HEX_FILE_PARSER, ParseTestFile) {
|
||||
uint8_t* payload = nullptr;
|
||||
size_t payload_size = 0;
|
||||
size_t payload_address = 0;
|
||||
int res = hex_file_parse(SOURCE_DIR
|
||||
"/tools/blisp/src/file_parsers/hex/tests/test.hex",
|
||||
&payload, &payload_size, &payload_address);
|
||||
// Shall return 0 on success
|
||||
ASSERT_EQ(res, 0);
|
||||
// The expected base address is 0x230F0000 + 0xFC00 = 0x230FFC00
|
||||
ASSERT_EQ(payload_address, 0x230FFC00);
|
||||
// There are 7 data records of 16 bytes each, so payload size should be 0x70
|
||||
// (112 bytes)
|
||||
ASSERT_EQ(payload_size, 0x70);
|
||||
|
||||
// Optionally, check the first few bytes for expected values
|
||||
ASSERT_EQ(payload[0], 0x40);
|
||||
ASSERT_EQ(payload[1], 0x01);
|
||||
ASSERT_EQ(payload[2], 0x96);
|
||||
ASSERT_EQ(payload[3], 0x00);
|
||||
|
||||
// Clean up
|
||||
free(payload);
|
||||
}
|
||||
|
||||
TEST(HEX_FILE_PARSER, ParseNonExistentFile) {
|
||||
uint8_t* payload = nullptr;
|
||||
size_t payload_size = 0;
|
||||
size_t payload_address = 0;
|
||||
int res = hex_file_parse(SOURCE_DIR "/non_existent_file.hex", &payload,
|
||||
&payload_size, &payload_address);
|
||||
|
||||
ASSERT_EQ(res, PARSED_ERROR_CANT_OPEN_FILE);
|
||||
}
|
||||
|
||||
TEST(HEX_FILE_PARSER, ParseInvalidFormat) {
|
||||
// This test would require creating an invalid hex file
|
||||
// For simplicity, we'll skip actual implementation
|
||||
// but in a real test suite we would create a file with invalid format
|
||||
// and verify that it returns HEX_PARSE_ERROR_INVALID_FORMAT
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <string.h>
|
||||
#include "bin_file.h"
|
||||
#include "dfu_file.h"
|
||||
#include "hex_file.h"
|
||||
|
||||
const char* get_filename_ext(const char* filename) {
|
||||
const char* dot = strrchr(filename, '.');
|
||||
@@ -28,13 +27,8 @@ int parse_firmware_file(const char* file_path_on_disk,
|
||||
res = bin_file_parse(file_path_on_disk, &parsed_results->payload,
|
||||
&parsed_results->payload_length,
|
||||
&parsed_results->payload_address);
|
||||
} else if (strncmp(ext, "hex", 3) == 0 || strncmp(ext, "HEX", 3) == 0) {
|
||||
printf("Input file identified as a .hex file\n");
|
||||
// Intel HEX file
|
||||
res = hex_file_parse(file_path_on_disk, &parsed_results->payload,
|
||||
&parsed_results->payload_length,
|
||||
&parsed_results->payload_address);
|
||||
}
|
||||
// If we wanted to support hex files, here would be where
|
||||
|
||||
// Normalise address, some builds will base the firmware at flash start but
|
||||
// for the flasher we use 0 base (i.e. offsets into flash)
|
||||
@@ -46,4 +40,4 @@ int parse_firmware_file(const char* file_path_on_disk,
|
||||
parsed_results->needs_boot_struct = parsed_results->payload_address == 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ int8_t args_parse_exec(int argc, char** argv) {
|
||||
print_help();
|
||||
return BLISP_OK;
|
||||
} else if (version->count) {
|
||||
printf("blisp v0.0.5\n");
|
||||
printf("blisp v0.0.4\n");
|
||||
printf("Copyright (C) 2023 Marek Kraus and PINE64 Community\n");
|
||||
return BLISP_OK;
|
||||
}
|
||||
|
||||
Vendored
+1
-1
Submodule vendor/argtable3 updated: b50c6c81f2...6f0e40bc44
Reference in New Issue
Block a user