108 Commits
Author SHA1 Message Date
Ben V. Brown ec078224bd Unify uploaded artefact names 2023-05-09 14:38:58 +10:00
Ben V. Brown 33c3f36b98 update upload artifact 2023-05-09 14:31:37 +10:00
Ben V. Brown f6f2013c8e Upload with specific names 2023-05-09 14:29:51 +10:00
Ben V. Brown 729609f2c0 Use Actions to recursively checkout 2023-05-09 14:29:51 +10:00
Ben V. Brown 491dd4f8c0 Draft test multi builder 2023-05-09 08:30:09 +10:00
river-mochi de4a9cd5e6 update install instructions 2023-04-10 18:26:06 -07:00
River M 0b363c620a Merge pull request #31 from River-Mochi/master
changed icon colors
2023-04-01 21:28:57 -07:00
River M e7eeef5f85 changed icon colors
Icons in black can not be seen well in dark screen. 
changed to color that matches badges and can be seen in dark mode.
2023-04-01 21:28:08 -07:00
Robert Lipe aaf07b7724 Update README.md
Updated from https://github.com/pine64/blisp/pull/1/files
2023-03-30 13:51:18 -05:00
Marek Kraus 8c3b93cbec Merge pull request #28 from River-Mochi/master
defind ISP
2023-03-30 20:04:35 +02:00
River M cc9ef81934 Update README.md 2023-03-30 10:57:23 -07:00
River M 9cb381d03e Update README.md 2023-03-19 15:49:38 -07:00
Robert Lipe f47bc9f948 Merge pull request #26 from River-Mochi/master
add table, icons, edit doc
2023-03-18 18:08:11 -05:00
River M 4b8713ecd4 Update README.md 2023-03-18 15:01:40 -07:00
River M 935ee4a12c Delete test 2023-03-18 14:55:03 -07:00
River M 55198e9612 Update README.md 2023-03-18 14:05:05 -07:00
River M 63dff45156 Update README.md 2023-03-18 14:03:44 -07:00
River M a98a5090b3 Update README.md 2023-03-18 13:43:53 -07:00
River M 55f40caa60 Update README.md 2023-03-18 13:10:41 -07:00
River M 7618f24c97 Update README.md 2023-03-18 12:41:33 -07:00
River M fb31f9a742 Add files via upload 2023-03-18 12:38:19 -07:00
River M 28d0743742 Create test 2023-03-18 12:37:52 -07:00
River M 042b9a72f0 Update README.md 2023-03-18 12:31:53 -07:00
River M eb55ab4702 Update README.md 2023-03-18 12:29:21 -07:00
River M ca4aca7219 Update README.md 2023-03-18 12:27:18 -07:00
River M 6f174eaffe Update README.md 2023-03-18 12:14:04 -07:00
River M a59d4f7a32 Merge branch 'pine64:master' into master 2023-03-17 04:53:04 -07:00
Marek Kraus 93703a7c2e Merge pull request #25 from porsolic/master
Enable building on FreeBSD hosts
2023-03-17 09:46:02 +01:00
porsolic 6f508d3db8 Enable building on FreeBSD hosts
FreeBSD has libusb built in.
Needs external libserialport.
2023-03-17 00:13:17 +01:00
River M 565c9ff913 Update README.md 2023-03-12 14:54:49 -07:00
River M e219e50efb Update README.md 2023-03-09 16:39:20 -08:00
River M 5a0ae8abc3 Update README.md 2023-03-09 14:15:12 -08:00
River M 0275fad1db Update README.md 2023-03-03 04:20:54 -08:00
River M e63ca04be5 Update README.md 2023-03-03 04:18:14 -08:00
River M 8c21c18b3a Merge branch 'pine64:master' into master 2023-03-03 04:11:38 -08:00
23ca06a336 add Badges (#23)
* Update README.md

syntax error in instructions. this command as written will not work because if flag --chip is used it needs to be --chip=bl70x with the "="
does not work: blisp write --chip bl70x --reset name_of_firmware.bin
or if "=" is not desired then "-c bl70x" could be used instead.

-c, --chip=<chip_type>    Chip Type

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

---------

Co-authored-by: River <97197236+River-b@users.noreply.github.com>
Co-authored-by: Marek Kraus <gamelaster@users.noreply.github.com>
2023-03-02 09:59:05 +01:00
Marek Kraus 5ebcf881b6 Merge branch 'master' into master 2023-03-02 09:58:34 +01:00
River M cda17f2713 Update README.md 2023-03-02 00:53:32 -08:00
River M 933851a775 Update README.md 2023-03-02 00:50:02 -08:00
River M 32e2a64390 Update README.md 2023-03-02 00:46:50 -08:00
River M c157261bf2 Update README.md 2023-03-02 09:44:16 +01:00
River M b54d820408 Update README.md 2023-03-02 09:44:16 +01:00
River M 9d4294f308 Update README.md 2023-03-02 09:44:16 +01:00
River M 44f5c12b40 Update README.md 2023-03-02 00:08:31 -08:00
River M f2605801a4 Update README.md 2023-03-01 22:04:18 -08:00
River M 670ec95507 Update README.md 2023-03-01 19:15:54 -08:00
River M f8acfa2ac1 Merge branch 'pine64:master' into master 2023-03-01 17:58:14 -08:00
Marek Kraus 3d4dfe8b81 Add BL602 branded MCUs 2023-02-28 11:23:18 +01:00
River 4afdfff4b7 Update README.md
syntax error in instructions. this command as written will not work because if flag --chip is used it needs to be --chip=bl70x with the "="
does not work: blisp write --chip bl70x --reset name_of_firmware.bin
or if "=" is not desired then "-c bl70x" could be used instead.

-c, --chip=<chip_type>    Chip Type
2023-02-19 15:48:48 +01:00
River 7669ebbbcb Update README.md
syntax error in instructions. this command as written will not work because if flag --chip is used it needs to be --chip=bl70x with the "="
does not work: blisp write --chip bl70x --reset name_of_firmware.bin
or if "=" is not desired then "-c bl70x" could be used instead.

-c, --chip=<chip_type>    Chip Type
2023-02-15 14:22:20 -08:00
porsolic 6424f9ddf8 Fix it to work under FreeBSD
Add sp_drain() where needed. Without it FreeBSD won't pass the handshake
phase.
Also decreate max buffer size.
Tested with Pinecil v2 and it can write and check new firmware.
2023-02-15 20:21:47 +01:00
porsolic 7fb2cc829c Fix UART baudrate
Set standard baudrate (460800) instead of non-standard (500000).
This enables opening of serial device under FreeBSD without error.
2023-02-15 20:21:47 +01:00
porsolic a67ab9d218 Fix build on FreeBSD 2023-02-15 20:21:47 +01:00
porsolic 3fff531334 Fix compiler warnings 2023-02-15 20:21:47 +01:00
porsolic 53b57c3158 Update README.md
Add missing part about git submodules.
Without it build system won't find dependencies.
2023-02-15 20:21:47 +01:00
Lee Lup Yuen 884142932d The "write" command is missing I think. Thanks :-) 2023-01-25 08:45:59 +01:00
Marek Kraus 5e09eca00d Fix Windows CI build 2023-01-21 15:17:17 +01:00
Marek Kraus 5a6cd281c3 Adds CI 2023-01-21 15:01:18 +01:00
Marek Kraus 2141e33c2b Version v0.0.3 2023-01-21 14:50:35 +01:00
Marek Kraus a7c69dbcee Add BL70XL into status matrix 2023-01-21 14:50:27 +01:00
Marek Kraus 10b150ee76 Update README that Apple is now supported 2023-01-21 14:48:31 +01:00
Marek Kraus cbac0733ee Final support of flashing on macOS
For some reason, macOS have issues with USB CDC,
surprisingly, CH340G convertor works just fine.
But FTDI and Bouffalo's USB CDC didn't worked.
Basically, without writing anything, we don't receive
response from board. This was fixed by adding drain
after writing BOUFALLOLABRESET handshake + adding
drains after every commmand write. Also, for some reason,
in USB CDC, the size of USB payload is limited, else
it will fail.
2023-01-21 14:34:46 +01:00
Marek Kraus 3325f3725e Make macOS build working again 2023-01-21 10:08:26 +01:00
Marek Kraus 626522e074 Version v0.0.2 2023-01-12 11:49:04 +01:00
Marek Kraus b941e60fbd [blisp] Disable compilation of argtable3 tests and other stuff 2023-01-12 11:46:40 +01:00
Marek Kraus 0e0ffb1d8c Change version to 0.0.1 2023-01-09 21:49:44 +01:00
Marek Kraus a6b9b4102b Fix Windows support 2023-01-09 21:38:06 +01:00
Marek Kraus 279f2433ea Integrated eflash_loader 2023-01-09 21:23:46 +01:00
Marek Kraus 59cf5fb038 Add blisp_easy, many improvements, adds iot single download feature 2023-01-07 23:25:42 +01:00
Marek Kraus ed2c9b80b8 Creating common functions: prepare flash 2023-01-07 19:57:23 +01:00
Marek Kraus a072ddb3f3 Move some stuff to new util file 2023-01-07 16:57:58 +01:00
Marek Kraus 2740d305ba Added initial BL61X and BL808 support, some chip changes 2023-01-07 16:57:45 +01:00
Marek Kraus 841a52177b Some improvements to readme and added blisp_dlog 2023-01-07 15:07:25 +01:00
Marek Kraus 8a00a63600 Make proper error handling 2023-01-07 13:34:33 +01:00
Marek Kraus da34daf69f Update code styly and reformat code 2023-01-07 11:50:51 +01:00
Marek Kraus 9fbaa05b64 Migrate Pinecil V2 instructions to Github Wiki 2023-01-07 10:38:06 +01:00
RiverandBen V. Brown 7601709a4c improved blisp instructions (#12)
* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

Co-authored-by: Ben V. Brown <5425387+Ralim@users.noreply.github.com>

* Update README.md

Co-authored-by: Ben V. Brown <5425387+Ralim@users.noreply.github.com>
2023-01-01 13:07:37 +11:00
River 4618e722ab Added instructions (#11)
* Update README.md

* Update README.md

* Update README.md

* Update README.md
2022-12-14 07:01:16 +01:00
Marek Kraus eb086f6fe3 Add initial MacOS support 2022-12-06 17:15:53 +01:00
Marek Kraus a68c54ed2b Fix indentation 2022-12-06 16:10:46 +01:00
Marek Kraus b9a2baae13 Merge pull request #3 from pine64/write
Modifications for MacOS to let it find data files in the same directory as the executable. This is totally wrong for a "normal" MacOS app bundle, but it follows the existing Linux convention.
2022-12-06 16:09:22 +01:00
Marek Kraus 4609916981 Merge branch 'master' into write 2022-12-06 16:08:54 +01:00
Marek KrausandRiver 6de3af46aa Update README.md
Co-authored-by: River <97197236+River-b@users.noreply.github.com>
2022-12-06 16:04:48 +01:00
Marek Kraus 6c0c857474 Drain TX and flush RX only in UART mode 2022-12-05 22:06:47 +01:00
Marek Kraus a4489c7cce Add license 2022-11-30 13:17:30 +01:00
Marek Kraus 8bb6d2a82d Adds LOW_LATENCY config, which is disabled by default
This helped with handshake on CH340, but FT232H don't like it.
Currently, it is not needed, as current code can work properly
both on CH340G but also on FT232H.
2022-11-22 14:01:27 +01:00
Marek Kraus 717d693d0b Wait a bit so BootROM can init after reset 2022-11-22 13:57:56 +01:00
Marek Kraus 115f1df0b3 Make handshake more reliable via UART
Added waiting for transmitting whole handshake, and then flushing
RX buffer in case we received 0xFF data in mean time.
2022-11-22 13:57:26 +01:00
Marek Kraus dd2801d6e9 Add termios support to libserialport and set_baudrate error handling
This fixes issues with flashing with FT232H
2022-11-22 13:55:38 +01:00
Marek Kraus 807c21bbef Merge pull request #8 from pine64/errors
Marginally improving error handling and rough corners
2022-11-20 18:10:28 +01:00
Ben V. Brown 236690b095 Handle failure finding current program path 2022-11-20 20:43:36 +11:00
Ben V. Brown 8334e583b6 Add note to use recursive clone 2022-11-20 17:22:47 +11:00
Ben V. Brown c419cc0cd9 Markdown styling 2022-11-20 17:22:36 +11:00
Ben V. Brown 20c4fa0163 Handle missing eflash loader in a nicer form
Print error rather than crashing
2022-11-20 17:20:46 +11:00
Ben V. Brown f60cfc02f9 Ignore build folder 2022-11-20 17:20:16 +11:00
Marek Kraus 2d7eb72e80 Increase timeout time, since erase command can take some time 2022-11-17 20:57:31 +01:00
Marek Kraus cae1bf0202 Don't wait too much on handshake response 2022-11-10 21:35:33 +01:00
Jean-François Milants 48ecd90f71 Fix handshake procedure :
- set RST and P8 low
 - wait
 - set P8 high
 - wait
 - set RST high

Also, do not reset again when sending the 2nd handshake.
2022-11-09 21:09:47 +01:00
Marek Kraus 6e036df085 Adding RTS & DTS mechanism (not working yet) 2022-11-09 20:16:08 +01:00
Marek Kraus 7f69a80f0e Add building and usage instructions 2022-11-08 22:17:40 +01:00
Marek Kraus 8c3cc0b017 Add initial support for BL60X 2022-11-08 22:06:14 +01:00
Marek Kraus d2f13de709 Working BL70X flashing 2022-11-08 19:35:51 +01:00
Marek Kraus c7bbb0a797 Fix unitialized variable 2022-11-08 16:21:13 +01:00
Marek Kraus 7795de96ff Add proper Windows support 2022-11-08 09:54:34 +01:00
Marek Kraus 6b97b239cb Update readme 2022-11-08 09:37:29 +01:00
Marek Kraus e3dea5b85d Windows fixes 2022-11-07 15:22:06 +01:00
Marek Kraus 17a6c2f4a1 Work in Progress 2022-11-07 10:20:38 +01:00
Robert Lipe e789cdf809 Modifications for MacOS to let it find data files in the same directory
as the executable.
This is totally wrong for a "normal" MacOS app bundle, but it follows
the existing Linux convention.
2022-10-23 02:26:06 -04:00
29 changed files with 10227 additions and 533 deletions
+2 -56
View File
@@ -1,58 +1,4 @@
--- ---
Language: Cpp BasedOnStyle: Chromium
BasedOnStyle: GNU
IndentWidth: 4
AllowShortBlocksOnASingleLine: Empty
AllowShortFunctionsOnASingleLine: None
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: false
AfterCaseLabel: false
AfterEnum: false
AfterControlStatement: Never
AfterStruct : false
AfterUnion : false
AfterExternBlock : false
BeforeElse : false
BeforeWhile : false
AlignAfterOpenBracket: Align
AlignArrayOfStructures: Left
AlignEscapedNewlines: Right
AlignOperands: Align
AllowShortEnumsOnASingleLine: False
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine : false
AlwaysBreakAfterReturnType: AllDefinitions
AlignTrailingComments : true
AlignConsecutiveMacros: AcrossEmptyLines
KeepEmptyLinesAtTheStartOfBlocks : false
PointerAlignment : Left
QualifierAlignment : Left
ReferenceAlignment : Left
RemoveBracesLLVM : false
SpaceAfterCStyleCast : false
SpaceAfterLogicalNot : false
SpaceAfterTemplateKeyword : false
SpaceAroundPointerQualifiers : Before
SpaceBeforeAssignmentOperators : true
SpaceBeforeCaseColon : false
SpaceBeforeCpp11BracedList : false
SpaceBeforeParens : ControlStatements
SpaceBeforeParensOptions :
AfterControlStatements : true
AfterFunctionDeclarationName : false
AfterFunctionDefinitionName : false
AfterOverloadedOperator : false
SpaceBeforeRangeBasedForLoopColon : false
SpaceBeforeSquareBrackets : false
SpaceInEmptyBlock : false
SpaceInEmptyParentheses : false
SpacesInCStyleCastParentheses : false
SpacesInConditionalStatement : false
SpacesInContainerLiterals : false
SpacesInParentheses: false
SpacesInSquareBrackets : false
UseTab : Never
BitFieldColonSpacing: None ...
BreakBeforeBinaryOperators: All
+141
View File
@@ -0,0 +1,141 @@
name: Build
on: [push, pull_request]
jobs:
build-windows:
runs-on: windows-2022
defaults:
run:
shell: cmd
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- uses: lukka/get-cmake@latest
- name: Build blisp tool
run: |
mkdir build
cd build
cmake .. -DBLISP_BUILD_CLI=ON -DCMAKE_BUILD_TYPE=Release
cmake --build . --config Release
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: blips-windows-x86_64.zip
path: |
build/tools/blisp/Release/blisp.exe
if-no-files-found: error
build-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- uses: lukka/get-cmake@latest
- name: Build blisp tool
run: |
mkdir build
cd build
cmake .. -DBLISP_BUILD_CLI=ON -DCMAKE_BUILD_TYPE=Release
cmake --build .
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: blips-apple-x86_64.zip
path: |
build/tools/blisp/blisp
if-no-files-found: error
build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- uses: lukka/get-cmake@latest
- name: Build blisp tool
run: |
mkdir build
cd build
cmake .. -DBLISP_BUILD_CLI=ON -DCMAKE_BUILD_TYPE=Release
cmake --build .
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: blips-linux-x86_64.zip
path: |
build/tools/blisp/blisp
if-no-files-found: error
build-linux-alternative-arch:
runs-on: ubuntu-latest
name: Build on ${{ matrix.distro }} ${{ matrix.arch }}
# Run steps on a matrix of 4 arch/distro combinations
strategy:
matrix:
include:
- arch: aarch64
distro: ubuntu_latest
- arch: armv7
distro: ubuntu_latest
- arch: riscv64
distro: ubuntu_latest
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- uses: uraimo/run-on-arch-action@v2
name: Build artifact
id: build
with:
arch: ${{ matrix.arch }}
distro: ${{ matrix.distro }}
# Create an artifacts directory
setup: |
mkdir -p "${PWD}/artifacts"
# Mount the artifacts directory as /artifacts in the container
dockerRunArgs: |
--volume "${PWD}/artifacts:/artifacts"
# Pass some environment variables to the container
env: | # YAML, but pipe character is necessary
artifact_name: blisp-linux-${{ matrix.arch }}
# The shell to run commands with in the container
shell: /bin/sh
# Install some dependencies in the container. This speeds up builds if
# you are also using githubToken. Any dependencies installed here will
# be part of the container image that gets cached, so subsequent
# builds don't have to re-install them. The image layer is cached
# publicly in your project's package repository, so it is vital that
# no secrets are present in the container state or logs.
install: |
case "${{ matrix.distro }}" in
ubuntu*|jessie|stretch|buster|bullseye)
apt-get update -q -y
apt-get install -q -y git cmake build-essential
;;
esac
# Produce a binary artifact and place it in the mounted volume
run: |
git config --global --add safe.directory /home/runner/work/blisp/blisp
mkdir build
cd build
cmake .. -DBLISP_BUILD_CLI=ON -DCMAKE_BUILD_TYPE=Release
cmake --build . -j2
cp ./tools/blisp/blisp "/artifacts/${artifact_name}"
echo "Produced artifact at /artifacts/${artifact_name}"
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: blisp-linux-${{ matrix.arch }}.zip
path: |
artifacts/blisp-*
if-no-files-found: error
+3
View File
@@ -75,3 +75,6 @@ fabric.properties
# Android studio 3.1+ serialized cache file # Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser .idea/caches/build_file_checksums.ser
build/
.DS_Store
+23 -8
View File
@@ -7,7 +7,8 @@ option(BLISP_BUILD_CLI "Build CLI Tool" OFF)
add_library(libblisp_obj OBJECT add_library(libblisp_obj OBJECT
lib/blisp.c lib/blisp.c
lib/chip/blisp_chip_bl70x.c) lib/chip/blisp_chip_bl60x.c
lib/chip/blisp_chip_bl70x.c lib/blisp_easy.c)
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/) target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/)
@@ -19,42 +20,56 @@ add_library(libblisp_static STATIC $<TARGET_OBJECTS:libblisp_obj>)
set_target_properties(libblisp PROPERTIES set_target_properties(libblisp PROPERTIES
PUBLIC_HEADER "include/blisp.h" PUBLIC_HEADER "include/blisp.h"
VERSION 1.0 VERSION 0.0.3
SOVERSION 1 SOVERSION 1
LIBRARY_OUTPUT_DIRECTORY "shared" LIBRARY_OUTPUT_DIRECTORY "shared"
OUTPUT_NAME "blisp") OUTPUT_NAME "blisp")
set_target_properties(libblisp_static PROPERTIES set_target_properties(libblisp_static PROPERTIES
PUBLIC_HEADER "include/blisp.h" PUBLIC_HEADER "include/blisp.h"
VERSION 1.0 VERSION 0.0.3
SOVERSION 1 SOVERSION 1
ARCHIVE_OUTPUT_DIRECTORY "static" ARCHIVE_OUTPUT_DIRECTORY "static"
OUTPUT_NAME "blisp") OUTPUT_NAME "blisp")
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
target_sources(libblisp_obj PRIVATE target_sources(libblisp_obj PRIVATE
${CMAKE_SOURCE_DIR}/vendor/libserialport/serialport.c ${CMAKE_SOURCE_DIR}/vendor/libserialport/serialport.c
${CMAKE_SOURCE_DIR}/vendor/libserialport/timing.c) ${CMAKE_SOURCE_DIR}/vendor/libserialport/timing.c)
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport)
endif()
if(WIN32) if(WIN32)
target_link_libraries(libblisp_obj PRIVATE Setupapi.lib) target_link_libraries(libblisp PRIVATE Setupapi.lib)
target_link_libraries(libblisp_static PRIVATE Setupapi.lib)
target_compile_definitions(libblisp_obj PRIVATE LIBSERIALPORT_MSBUILD) target_compile_definitions(libblisp_obj PRIVATE LIBSERIALPORT_MSBUILD)
target_sources(libblisp_obj PRIVATE target_sources(libblisp_obj PRIVATE
${CMAKE_SOURCE_DIR}/vendor/libserialport/windows.c) ${CMAKE_SOURCE_DIR}/vendor/libserialport/windows.c)
elseif(UNIX AND NOT APPLE) elseif(UNIX AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
target_sources(libblisp_obj PRIVATE target_sources(libblisp_obj PRIVATE
${CMAKE_SOURCE_DIR}/vendor/libserialport/linux.c ${CMAKE_SOURCE_DIR}/vendor/libserialport/linux.c
${CMAKE_SOURCE_DIR}/vendor/libserialport/linux_termios.c) ${CMAKE_SOURCE_DIR}/vendor/libserialport/linux_termios.c)
target_compile_definitions(libblisp_obj PRIVATE target_compile_definitions(libblisp_obj PRIVATE
LIBSERIALPORT_ATBUILD LIBSERIALPORT_ATBUILD
HAVE_TERMIOS2_SPEED
HAVE_STRUCT_TERMIOS2
HAVE_DECL_BOTHER
"SP_API=__attribute__((visibility(\"default\")))" "SP_API=__attribute__((visibility(\"default\")))"
"SP_PRIV=__attribute__((visibility(\"hidden\")))") "SP_PRIV=__attribute__((visibility(\"hidden\")))")
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport)
write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.") write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.")
elseif(UNIX AND ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
target_include_directories(libblisp_obj PRIVATE /usr/local/include/)
target_link_libraries(libblisp PRIVATE -L/usr/local/lib usb serialport)
target_link_libraries(libblisp_static PRIVATE -L/usr/local/lib usb serialport)
elseif(APPLE) elseif(APPLE)
target_sources(libblisp_obj PRIVATE target_sources(libblisp_obj PRIVATE
${CMAKE_SOURCE_DIR}/vendor/libserialport/macosx.c) ${CMAKE_SOURCE_DIR}/vendor/libserialport/macosx.c)
target_link_libraries(libblisp_obj PRIVATE "-framework IOKit" "-framework CoreFoundation") target_link_libraries(libblisp PRIVATE "-framework IOKit" "-framework CoreFoundation")
target_compile_definitions(libblisp_obj PRIVATE LIBSERIALPORT_ATBUILD "SP_API=__attribute__((visibility(\"default\")))") target_compile_definitions(libblisp_obj PRIVATE
LIBSERIALPORT_ATBUILD
"SP_PRIV=__attribute__((visibility(\"hidden\")))"
"SP_API=__attribute__((visibility(\"default\")))")
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport) target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/vendor/libserialport)
write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.") write_file(${CMAKE_SOURCE_DIR}/vendor/libserialport/config.h "// bypass errors.")
endif() endif()
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Marek Kraus <gamelaster@outlook.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+81 -12
View File
@@ -1,17 +1,86 @@
# Bouffalo Labs ISP tool & library [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fpine64%2Fblisp&count_bg=%235791AC&title_bg=%23555555&icon=airplayaudio.svg&icon_color=%23D2D9DD&title=hits&edge_flat=false)](https://github.com/pine64/blisp/wiki/Update-Pinecil-V2)
[![GitHub all downloads](https://img.shields.io/github/downloads/pine64/blisp/total?color=5791ac&logo=docusign&logoColor=white)](https://github.com/pine64/blisp/releases/tag/v0.0.3)
[![Discord](https://img.shields.io/discord/463237927984693259?color=5791ac&logo=discord&logoColor=white)](https://discord.com/invite/pine64)
[![GitHub release](https://img.shields.io/github/v/release/pine64/blisp?color=5791ac)](https://github.com/pine64/blisp/releases/tag/v0.0.3)
Tool and library for flashing their RISC-V MCUs. <img src="./img/Gradient-white-blue-03.png" align="left" width="60" > <br clear="left" />
# BLISP
# Supported MCUs Bouffalo Labs ISP (in-system-programming) tool & library: an open source tool to flash Bouffalo RISC-V MCUs.
- [ ] BL602 / BL604 **NOTE:** Library API and `blisp` tool cli arguments are not stable yet.
- [X] BL702 / BL704 / BL706 <br>
- [ ] BL606P
- [ ] BL616 / BL618
- [ ] BL808
# To Do ## Supported MCUs
- [x] `bl60x` - BL602 / BL604 / TG7100C / LF686 / LF688
- [x] `bl70x` - BL702 / BL704 / BL706
<br>
- [ ] Another code style ## Supported Devices
- [ ] Finalize API | 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 |
- [ ] SDIO and JTAG support | :-----: | :------: | :------: | :------: | :------: |
| 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/).
Check out the [wiki page](https://github.com/pine64/blisp/wiki/Update-Pinecil-V2) for install instructions.
<br><br>
## Building from code
### Clone repository
If you have not cloned this repository locally; clone the git repository locally by running
```bash
git clone --recursive https://github.com/pine64/blisp.git
cd blisp
git submodule update --init --recursive
```
If vendor/argtable3 and vendor/libserialport/ are empty, this last step has
failed and should be investigated.
### Build the library and command line utility
For building `blisp` command line tool, use following commands:
```bash
mkdir build && cd build
cmake -DBLISP_BUILD_CLI=ON ..
cmake --build .
```
#### Need more build details? [See here](https://github.com/pine64/blisp/wiki/Update-Pinecil-V2#build-blisp-flasher-from-code).
## Usage
For BL70X, BL61X, BL808 and BL606P, connected via USB, you can use following command, which will auto-detect serial port on Windows:
```bash
.\blisp.exe write --chip=bl70x --reset .\name_of_firmware.bin
or
.\blisp.exe write -c bl70x --reset .\name_of_firmware.bin
```
For BL60X, you need to specify also the serial port path:
```bash
blisp write --chip bl60x --reset -p /dev/ttyUSB0 name_of_firmware.bin
```
If you wish to see additional debugging, set the environmental
variable LIBSERIALPORT_DEBUG before running. You can either export this
in your shell or change it for a single run via
```bash
LIBSERIALPORT_DEBUG=y ./a.out write -c bl70x -p /dev/tty.usbmodem0000000200001
```
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.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

+40 -6
View File
@@ -1,3 +1,4 @@
// SPDX-License-Identifier: MIT
#ifndef _LIBBLISP_H #ifndef _LIBBLISP_H
#define _LIBBLISP_H #define _LIBBLISP_H
@@ -5,6 +6,18 @@
#include "blisp_chip.h" #include "blisp_chip.h"
enum blisp_return {
BLISP_OK = 0,
BLISP_ERR_UNKNOWN = -1,
BLISP_ERR_NO_RESPONSE = -2,
BLISP_ERR_DEVICE_NOT_FOUND = -3,
BLISP_ERR_CANT_OPEN_DEVICE = -4,
// Can't auto-find device due it doesn't have native USB
BLISP_ERR_NO_AUTO_FIND_AVAILABLE = -5,
BLISP_ERR_PENDING = -6,
BLISP_ERR_CHIP_ERR = -7
};
struct blisp_segment_header { struct blisp_segment_header {
uint32_t dest_addr; uint32_t dest_addr;
uint32_t length; uint32_t length;
@@ -27,16 +40,37 @@ struct blisp_boot_info {
uint8_t chip_id[8]; // TODO: BL60X only 6 bytes uint8_t chip_id[8]; // TODO: BL60X only 6 bytes
}; };
// TODO: Refactor variable names, so all will follow same semantic, like
// image_run, image_check etc.
int32_t blisp_device_init(struct blisp_device* device, struct blisp_chip* chip); int32_t blisp_device_init(struct blisp_device* device, struct blisp_chip* chip);
int32_t blisp_device_open(struct blisp_device* device, const char* port_name); int32_t blisp_device_open(struct blisp_device* device, const char* port_name);
int32_t blisp_device_handshake(struct blisp_device* device); 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_get_boot_info(struct blisp_device* device,
int32_t blisp_device_load_boot_header(struct blisp_device* device, uint8_t* boot_header); struct blisp_boot_info* boot_info);
int32_t blisp_device_load_segment_header(struct blisp_device* device, struct blisp_segment_header* segment_header); int32_t blisp_device_load_boot_header(struct blisp_device* device,
int32_t blisp_device_load_segment_data(struct blisp_device* device, uint8_t* segment_data, uint32_t segment_data_length); uint8_t* boot_header);
int32_t blisp_device_write_memory(struct blisp_device* device, uint32_t address, uint32_t value); int32_t blisp_device_load_segment_header(
struct blisp_device* device,
struct blisp_segment_header* segment_header);
int32_t blisp_device_load_segment_data(struct blisp_device* device,
uint8_t* segment_data,
uint32_t segment_data_length);
int32_t blisp_device_write_memory(struct blisp_device* device,
uint32_t address,
uint32_t value,
bool wait_for_res);
int32_t blisp_device_check_image(struct blisp_device* device); int32_t blisp_device_check_image(struct blisp_device* device);
int32_t blisp_device_run_image(struct blisp_device* device); int32_t blisp_device_run_image(struct blisp_device* device);
int32_t blisp_device_flash_erase(struct blisp_device* device,
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); void blisp_device_close(struct blisp_device* device);
#endif #endif
+14 -2
View File
@@ -1,19 +1,31 @@
// SPDX-License-Identifier: MIT
#ifndef _BLISP_CHIP_H #ifndef _BLISP_CHIP_H
#define _BLISP_CHIP_H #define _BLISP_CHIP_H
#include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
enum blisp_chip_type { enum blisp_chip_type {
BLISP_CHIP_BL70X BLISP_CHIP_BL60X,
BLISP_CHIP_BL70X,
BLISP_CHIP_BL606P,
BLISP_CHIP_BL808,
BLISP_CHIP_BL61X,
}; };
struct blisp_chip { // TODO: Move elsewhere? struct blisp_chip { // TODO: Move elsewhere?
enum blisp_chip_type type; enum blisp_chip_type type;
const char* type_str; const char* type_str;
bool usb_isp_available; bool usb_isp_available;
float handshake_byte_multiplier;
const char* default_xtal; // TODO: Make this selectable
int64_t (*load_eflash_loader)(uint8_t clk_type, uint8_t** firmware_buf_ptr);
uint32_t tcm_address;
}; };
extern struct blisp_chip blisp_chip_bl60x;
extern struct blisp_chip blisp_chip_bl70x; extern struct blisp_chip blisp_chip_bl70x;
extern struct blisp_chip blisp_chip_bl808;
extern struct blisp_chip blisp_chip_bl61x;
#endif #endif
+54
View File
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: MIT
#ifndef BLISP_BLISP_EASY_H
#define BLISP_BLISP_EASY_H
#include <stdio.h>
#include "blisp.h"
struct blisp_easy_transport {
uint8_t type; // 0 - memory, 1 - FILE file_handle
union {
FILE* file_handle;
struct {
void* data_location;
uint32_t data_size;
uint32_t current_position;
} memory;
} data;
};
enum blisp_easy_error {
BLISP_EASY_ERR_TRANSPORT_ERROR = -100,
BLISP_EASY_ERR_CHECK_IMAGE_FAILED = -101
};
typedef void (*blisp_easy_progress_callback)(uint32_t current_value,
uint32_t max_value);
struct blisp_easy_transport blisp_easy_transport_new_from_file(FILE* file);
struct blisp_easy_transport blisp_easy_transport_new_from_memory(
void* data_location,
uint32_t data_size);
int32_t blisp_easy_load_segment_data(
struct blisp_device* device,
uint32_t segment_size,
struct blisp_easy_transport* segment_transport,
blisp_easy_progress_callback progress_callback);
int32_t blisp_easy_load_ram_image(
struct blisp_device* device,
struct blisp_easy_transport* image_transport,
blisp_easy_progress_callback progress_callback);
int32_t blisp_easy_load_ram_app(struct blisp_device* device,
struct blisp_easy_transport* app_transport,
blisp_easy_progress_callback progress_callback);
int32_t blisp_easy_flash_write(struct blisp_device* device,
struct blisp_easy_transport* data_transport,
uint32_t flash_location,
uint32_t data_size,
blisp_easy_progress_callback progress_callback);
#endif // BLISP_BLISP_EASY_H
+172
View File
@@ -0,0 +1,172 @@
/*
* Some parts of this source code belongs to Bouffalo Labs
* COPYRIGHT(c) 2020 Bouffalo Lab , License: Apache
*/
#ifndef _LIBBLISP_STRUCT_H
#define _LIBBLISP_STRUCT_H
#include <assert.h>
#include <stdint.h>
#pragma pack(push, 1)
typedef struct {
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 qpiJedecIdCmd; /*!< QPI JEDEC ID comamnd */
uint8_t qpiJedecIdCmdDmyClk; /*!< QPI JEDEC ID command dummy clock */
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 */
} SPI_Flash_Cfg_Type;
#define BFLB_BOOTROM_HASH_SIZE 256 / 8
struct boot_flash_cfg_t {
char magiccode[4]; /*'FCFG'*/
SPI_Flash_Cfg_Type cfg;
uint32_t crc32;
};
struct sys_clk_cfg_t {
uint8_t xtal_type;
uint8_t pll_clk;
uint8_t hclk_div;
uint8_t bclk_div;
uint8_t flash_clk_type;
uint8_t flash_clk_div;
uint8_t rsvd[2];
};
struct boot_clk_cfg_t {
char magiccode[4]; /*'PCFG'*/
struct sys_clk_cfg_t cfg;
uint32_t crc32;
};
struct bfl_boot_header {
char magiccode[4]; /*'BFXP'*/
uint32_t revison;
struct boot_flash_cfg_t flashCfg;
struct boot_clk_cfg_t clkCfg;
union {
struct {
uint32_t sign : 2; /* [1: 0] for sign*/
uint32_t encrypt_type : 2; /* [3: 2] for encrypt */
uint32_t key_sel : 2; /* [5: 4] for key sel in boot interface*/
uint32_t rsvd6_7 : 2; /* [7: 6] for encrypt*/
uint32_t no_segment : 1; /* [8] no segment info */
uint32_t cache_enable : 1; /* [9] for cache */
uint32_t
notload_in_bootrom : 1; /* [10] not load this img in bootrom */
uint32_t aes_region_lock : 1; /* [11] aes region lock */
uint32_t cache_way_disable : 4; /* [15: 12] cache way disable info*/
uint32_t crc_ignore : 1; /* [16] ignore crc */
uint32_t hash_ignore : 1; /* [17] hash crc */
uint32_t halt_ap : 1; /* [18] halt ap */
uint32_t rsvd19_31 : 13; /* [31:19] rsvd */
} bval;
uint32_t wval;
} bootcfg;
union {
uint32_t segment_cnt;
uint32_t img_length;
} segment_info;
uint32_t bootentry; /* entry point of the image*/
uint32_t flashoffset;
uint8_t hash[BFLB_BOOTROM_HASH_SIZE]; /*hash of the image*/
uint32_t rsv1;
uint32_t rsv2;
uint32_t crc32;
};
static_assert(sizeof(struct bfl_boot_header) == 176,
"Bootheader have wrong size");
struct blflash_segment_header {
uint32_t destaddr;
uint32_t len;
uint32_t rsvd;
uint32_t crc32;
};
static_assert(sizeof(struct blflash_segment_header) == 16,
"Segment header have wrong size");
#pragma pack(pop)
#endif
+98
View File
@@ -0,0 +1,98 @@
// SPDX-License-Identifier: MIT
#ifndef _BLISP_UTIL_H
#define _BLISP_UTIL_H
#include <stdarg.h>
#include <stdio.h>
#ifdef WIN32
#include <windows.h>
#else
#include <time.h>
#endif
static void blisp_dlog(const char* format, ...)
{
fflush(stdout);
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fputc('\n', stderr);
}
static void sleep_ms(int milliseconds) {
#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
* by pycrc vunknown, https://pycrc.org
* using the configuration:
* - Width = 32
* - Poly = 0x04c11db7
* - XorIn = 0xffffffff
* - ReflectIn = True
* - XorOut = 0xffffffff
* - ReflectOut = True
* - Algorithm = table-driven
*/
static const uint32_t crc_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
static uint32_t crc32_calculate(const void *data, size_t data_len)
{
uint32_t crc = 0xffffffff;
const unsigned char *d = (const unsigned char *)data;
unsigned int tbl_idx;
while (data_len--) {
tbl_idx = (crc ^ *d) & 0xff;
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff;
d++;
}
return (crc & 0xffffffff) ^ 0xffffffff;
}
#endif
+256 -98
View File
@@ -1,33 +1,50 @@
// SPDX-License-Identifier: MIT
#include <blisp.h> #include <blisp.h>
#include <blisp_util.h>
#include <libserialport.h> #include <libserialport.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
int32_t blisp_device_init(struct blisp_device* device, struct blisp_chip* chip) #ifdef __linux__
{ #include <linux/serial.h>
#include <sys/ioctl.h>
#endif
#define DEBUG
static void drain(struct sp_port* port) {
#if defined(__APPLE__) || defined(__FreeBSD__)
sp_drain(port);
#endif
}
int32_t blisp_device_init(struct blisp_device* device,
struct blisp_chip* chip) {
device->chip = chip; device->chip = chip;
device->is_usb = false; device->is_usb = false;
return 0; return 0;
} }
int32_t blisp_device_open(struct blisp_device* device, const char* port_name) int32_t blisp_device_open(struct blisp_device* device, const char* port_name) {
{
int ret; int ret;
struct sp_port* serial_port = NULL; struct sp_port* serial_port = NULL;
if (port_name != NULL) { if (port_name != NULL) {
ret = sp_get_port_by_name(port_name, &serial_port); ret = sp_get_port_by_name(port_name, &serial_port);
if (ret != SP_OK) { if (ret != SP_OK) {
return -1; // TODO: Improve error codes blisp_dlog("Couldn't open device, err: %d", ret);
return BLISP_ERR_CANT_OPEN_DEVICE;
} }
} else { } else {
if (!device->chip->usb_isp_available) { if (!device->chip->usb_isp_available) {
return -2; // Can't auto-find device due it doesn't have native USB return BLISP_ERR_NO_AUTO_FIND_AVAILABLE;
} }
struct sp_port** port_list; struct sp_port** port_list;
ret = sp_list_ports(&port_list); ret = sp_list_ports(&port_list);
if (ret != SP_OK) { if (ret != SP_OK) {
return -1; // TODO: Improve error codes blisp_dlog("Couldn't list ports, err: %d", ret);
return BLISP_ERR_UNKNOWN;
} }
for (int i = 0; port_list[i] != NULL; i++) { for (int i = 0; port_list[i] != NULL; i++) {
struct sp_port* port = port_list[i]; struct sp_port* port = port_list[i];
@@ -37,40 +54,64 @@ int32_t blisp_device_open(struct blisp_device* device, const char* port_name)
if (vid == 0xFFFF && pid == 0xFFFF) { if (vid == 0xFFFF && pid == 0xFFFF) {
ret = sp_get_port_by_name(sp_get_port_name(port), &serial_port); ret = sp_get_port_by_name(sp_get_port_name(port), &serial_port);
if (ret != SP_OK) { if (ret != SP_OK) {
return -1; // TODO: Improve error codes blisp_dlog("Couldn't open device, err: %d", ret);
return BLISP_ERR_CANT_OPEN_DEVICE;
} }
break; break;
} }
} }
sp_free_port_list(port_list); sp_free_port_list(port_list);
if (serial_port == NULL) { if (serial_port == NULL) {
return -3; // Device not found return BLISP_ERR_DEVICE_NOT_FOUND;
} }
} }
ret = sp_open(serial_port, SP_MODE_READ_WRITE); ret = sp_open(serial_port, SP_MODE_READ_WRITE);
if (ret != SP_OK) { // TODO: Handle not found if (ret != SP_OK) {
return -1; blisp_dlog("SP open failed: %d", ret);
return BLISP_ERR_UNKNOWN; // TODO: Maybe this should be that it can't open
// device?
} }
// TODO: Handle errors in following functions, although, none of them *should*
// fail
sp_set_bits(serial_port, 8); sp_set_bits(serial_port, 8);
sp_set_parity(serial_port, SP_PARITY_NONE); sp_set_parity(serial_port, SP_PARITY_NONE);
sp_set_stopbits(serial_port, 1); sp_set_stopbits(serial_port, 1);
sp_set_flowcontrol(serial_port, SP_FLOWCONTROL_NONE); sp_set_flowcontrol(serial_port, SP_FLOWCONTROL_NONE);
uint32_t vid, pid;
int vid, pid;
sp_get_port_usb_vid_pid(serial_port, &vid, &pid); sp_get_port_usb_vid_pid(serial_port, &vid, &pid);
device->is_usb = pid == 0xFFFF; device->is_usb = pid == 0xFFFF;
// if (device->is_usb) { // if (device->is_usb) {
// device->current_baud_rate = 2000000; // device->current_baud_rate = 2000000;
// } else { // } else {
device->current_baud_rate = 500000; device->current_baud_rate = 460800;
// } // }
sp_set_baudrate(serial_port, device->current_baud_rate);
#if 0
int fd;
sp_get_port_handle(serial_port, &fd);
struct serial_struct serial;
ioctl(fd, TIOCGSERIAL, &serial);
// serial.flags &= ~(ASYNC_LOW_LATENCY);
serial.flags |= ASYNC_LOW_LATENCY;
ioctl(fd, TIOCSSERIAL, &serial);
#endif
ret = sp_set_baudrate(serial_port, device->current_baud_rate);
if (ret != SP_OK) {
blisp_dlog("Set baud rate failed: %d... Also hello macOS user :)", ret);
return BLISP_ERR_UNKNOWN;
}
device->serial_port = serial_port; device->serial_port = serial_port;
return 0;
return BLISP_OK;
} }
int32_t blisp_send_command(struct blisp_device* device, uint8_t command, void* payload, uint16_t payload_size, bool add_checksum) int32_t blisp_send_command(struct blisp_device* device,
{ uint8_t command,
void* payload,
uint16_t payload_size,
bool add_checksum) {
int ret; int ret;
struct sp_port* serial_port = device->serial_port; struct sp_port* serial_port = device->serial_port;
@@ -82,176 +123,293 @@ int32_t blisp_send_command(struct blisp_device* device, uint8_t command, void* p
uint32_t checksum = 0; uint32_t checksum = 0;
checksum += device->tx_buffer[2] + device->tx_buffer[3]; checksum += device->tx_buffer[2] + device->tx_buffer[3];
for (uint16_t i = 0; i < payload_size; i++) { for (uint16_t i = 0; i < payload_size; i++) {
checksum += *(uint8_t*)(payload + i); checksum += *(uint8_t*)((uint8_t*)payload + i);
} }
device->tx_buffer[1] = checksum & 0xFF; device->tx_buffer[1] = checksum & 0xFF;
} }
if (payload_size != 0) { if (payload_size != 0) {
memcpy(&device->tx_buffer[4], payload, payload_size); memcpy(&device->tx_buffer[4], payload, payload_size);
} }
ret = sp_blocking_write(serial_port, device->tx_buffer, 4 + payload_size, 1000); ret =
sp_blocking_write(serial_port, device->tx_buffer, 4 + payload_size, 1000);
if (ret != (4 + payload_size)) { if (ret != (4 + payload_size)) {
return -1; blisp_dlog("Received error or not written all data: %d", ret);
return BLISP_ERR_UNKNOWN;
} }
return 0; drain(serial_port);
return BLISP_OK;
} }
int32_t blisp_receive_response(struct blisp_device* device, bool expect_payload) { int32_t blisp_receive_response(struct blisp_device* device,
bool expect_payload) {
// TODO: Check checksum // TODO: Check checksum
int ret; int ret;
struct sp_port* serial_port = device->serial_port; struct sp_port* serial_port = device->serial_port;
ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 300); ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 1000);
if (ret < 2) { if (ret < 2) {
return -1; blisp_dlog("Failed to receive response, ret: %d", ret);
return BLISP_ERR_UNKNOWN; // TODO: Terrible
} else if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') { } else if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
if (expect_payload) { if (expect_payload) {
sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100); sp_blocking_read(serial_port, &device->rx_buffer[2], 2,
uint16_t data_length = (device->rx_buffer[3] << 8) | (device->rx_buffer[2]); 100); // TODO: Check if really we received the data.
uint16_t data_length =
(device->rx_buffer[3] << 8) | (device->rx_buffer[2]);
sp_blocking_read(serial_port, &device->rx_buffer[0], data_length, 100); sp_blocking_read(serial_port, &device->rx_buffer[0], data_length, 100);
return data_length; return data_length;
} }
return 0; return 0;
} else if (device->rx_buffer[0] == 'P' && device->rx_buffer[1] == 'D') { } else if (device->rx_buffer[0] == 'P' && device->rx_buffer[1] == 'D') {
return -1; return BLISP_ERR_PENDING; // TODO: This might be rather positive return
// number?
} else if (device->rx_buffer[0] == 'F' && device->rx_buffer[1] == 'L') { } else if (device->rx_buffer[0] == 'F' && device->rx_buffer[1] == 'L') {
sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100); sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100);
device->error_code = (device->rx_buffer[3] << 8) | (device->rx_buffer[2]); device->error_code = (device->rx_buffer[3] << 8) | (device->rx_buffer[2]);
return -4; // Failed blisp_dlog("Chip returned error: %d", device->error_code);
return BLISP_ERR_CHIP_ERR;
} }
return -1; blisp_dlog("Failed to receive any response (err: %d, %d - %d)", ret,
device->rx_buffer[0], device->rx_buffer[1]);
return BLISP_ERR_UNKNOWN;
} }
int32_t blisp_device_handshake(struct blisp_device* device) int32_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) {
{
int ret; int ret;
uint8_t handshake_buffer[600]; uint8_t handshake_buffer[600];
struct sp_port* serial_port = device->serial_port; struct sp_port* serial_port = device->serial_port;
uint32_t bytes_count = 0.003f * (float)device->current_baud_rate / 10.0f; // TODO: 0.003f is only for BL70X! if (!in_ef_loader && !device->is_usb) {
if (bytes_count > 600) bytes_count = 600; sp_set_rts(serial_port, SP_RTS_ON);
sp_set_dtr(serial_port, SP_DTR_ON);
sleep_ms(50);
sp_set_dtr(serial_port, SP_DTR_OFF);
sleep_ms(100);
sp_set_rts(serial_port, SP_RTS_OFF);
sleep_ms(50); // Wait a bit so BootROM can init
}
uint32_t bytes_count = device->chip->handshake_byte_multiplier *
(float)device->current_baud_rate / 10.0f;
if (bytes_count > 600)
bytes_count = 600;
memset(handshake_buffer, 'U', bytes_count); memset(handshake_buffer, 'U', bytes_count);
for (uint8_t i = 0; i < 5; i++) { for (uint8_t i = 0; i < 5; i++) {
if (!in_ef_loader) {
if (device->is_usb) { if (device->is_usb) {
sp_blocking_write(serial_port, "BOUFFALOLAB5555RESET\0\0", 22, sp_blocking_write(serial_port, "BOUFFALOLAB5555RESET\0\0", 22, 100);
100); drain(serial_port);
} }
}
ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count, ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count, 500);
100); // not sure about Apple part, but FreeBSD needs it
drain(serial_port);
if (ret < 0) { if (ret < 0) {
return -1; blisp_dlog("Handshake write failed, ret %d", ret);
} return BLISP_ERR_UNKNOWN;
ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 100);
if (ret == 2 && device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
return 0;
}
}
return -4; // didn't received response
} }
int32_t blisp_device_get_boot_info(struct blisp_device* device, struct blisp_boot_info* boot_info) if (!in_ef_loader && !device->is_usb) {
{ sp_drain(serial_port); // Wait for write to send all data
sp_flush(serial_port, SP_BUF_INPUT); // Flush garbage out of RX
}
ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 50);
if (ret >= 2) {
if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
return BLISP_OK;
}
}
}
blisp_dlog("Received no response from chip.");
return BLISP_ERR_NO_RESPONSE;
}
int32_t blisp_device_get_boot_info(struct blisp_device* device,
struct blisp_boot_info* boot_info) {
int ret; int ret;
ret = blisp_send_command(device, 0x10, NULL, 0, false); ret = blisp_send_command(device, 0x10, NULL, 0, false);
if (ret < 0) return ret; if (ret < 0)
return ret;
ret = blisp_receive_response(device, true); ret = blisp_receive_response(device, true);
if (ret < 0) return ret; if (ret < 0)
return ret;
memcpy(boot_info->boot_rom_version, &device->rx_buffer[0],
4); // TODO: Endianess
if (device->chip->type == BLISP_CHIP_BL70X) { if (device->chip->type == BLISP_CHIP_BL70X) {
memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], 4); // TODO: Endianess
memcpy(boot_info->chip_id, &device->rx_buffer[16], 8); memcpy(boot_info->chip_id, &device->rx_buffer[16], 8);
} }
return 0; // TODO: BL60X
return BLISP_OK;
} }
// TODO: Use struct instead of uint8_t* // TODO: Use struct instead of uint8_t*
int32_t blisp_device_load_boot_header(struct blisp_device* device, uint8_t* boot_header) int32_t blisp_device_load_boot_header(struct blisp_device* device,
{ uint8_t* boot_header) {
int ret; int ret;
ret = blisp_send_command(device, 0x11, boot_header, 176, false); ret = blisp_send_command(device, 0x11, boot_header, 176, false);
if (ret < 0) return ret; if (ret < 0)
return ret;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) return ret; if (ret < 0)
return ret;
return 0; return BLISP_OK;
} }
int32_t blisp_device_load_segment_header(struct blisp_device* device, struct blisp_segment_header* segment_header) int32_t blisp_device_load_segment_header(
{ struct blisp_device* device,
struct blisp_segment_header* segment_header) {
int ret; int ret;
ret = blisp_send_command(device, 0x17, segment_header, 16, false); ret = blisp_send_command(device, 0x17, segment_header, 16, false);
if (ret < 0) return ret; if (ret < 0)
ret = blisp_receive_response(device, false); return ret;
if (ret < 0) return ret;
return 0;
}
int32_t blisp_device_load_segment_data(struct blisp_device* device, uint8_t* segment_data, uint32_t segment_data_length)
{
int ret;
ret = blisp_send_command(device, 0x18, segment_data, segment_data_length, false);
if (ret < 0) return ret;
ret = blisp_receive_response(device, true); // TODO: Handle response ret = blisp_receive_response(device, true); // TODO: Handle response
if (ret < 0) return ret; if (ret < 0)
return ret;
return 0; return BLISP_OK;
} }
int32_t blisp_device_check_image(struct blisp_device* device) int32_t blisp_device_load_segment_data(struct blisp_device* device,
{ uint8_t* segment_data,
uint32_t segment_data_length) {
int ret;
ret = blisp_send_command(device, 0x18, segment_data, segment_data_length,
false);
if (ret < 0)
return ret;
ret = blisp_receive_response(device, false);
if (ret < 0)
return ret;
return BLISP_OK;
}
int32_t blisp_device_check_image(struct blisp_device* device) {
int ret; int ret;
ret = blisp_send_command(device, 0x19, NULL, 0, false); ret = blisp_send_command(device, 0x19, NULL, 0, false);
if (ret < 0) return ret; if (ret < 0)
return ret;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) return ret; if (ret < 0)
return ret;
return 0; return BLISP_OK;
} }
int32_t blisp_device_write_memory(struct blisp_device* device, uint32_t address, uint32_t value) int32_t blisp_device_write_memory(struct blisp_device* device,
{ uint32_t address,
uint32_t value,
bool wait_for_res) {
int ret; int ret;
uint8_t payload[8]; uint8_t payload[8];
*(uint32_t*)(payload) = address; *(uint32_t*)(payload) = address;
*(uint32_t*)(payload + 4) = value; // TODO: Endianness *(uint32_t*)(payload + 4) = value; // TODO: Endianness
ret = blisp_send_command(device, 0x50, payload, 8, false); ret = blisp_send_command(device, 0x50, payload, 8, true);
if (ret < 0) return ret; if (ret < 0)
return ret;
if (wait_for_res) {
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) return ret; if (ret < 0)
return ret;
return 0;
} }
int32_t blisp_device_run_image(struct blisp_device* device) return BLISP_OK;
{ }
int32_t blisp_device_run_image(struct blisp_device* device) {
int ret; int ret;
if (device->chip->type == BLISP_CHIP_BL70X) { // ERRATA if (device->chip->type == BLISP_CHIP_BL70X) { // ERRATA
ret = blisp_device_write_memory(device, 0x4000F100, 0x4E424845); ret = blisp_device_write_memory(device, 0x4000F100, 0x4E424845, true);
if (ret < 0) return ret; if (ret < 0)
ret = blisp_device_write_memory(device, 0x4000F104, 0x22010000); return ret;
if (ret < 0) return ret; ret = blisp_device_write_memory(device, 0x4000F104, 0x22010000, true);
if (ret < 0)
return ret;
// ret = blisp_device_write_memory(device, 0x40000018, 0x00000000); // ret = blisp_device_write_memory(device, 0x40000018, 0x00000000);
// if (ret < 0) return ret; // if (ret < 0) return ret;
ret = blisp_device_write_memory(device, 0x40000018, 0x00000002); ret = blisp_device_write_memory(device, 0x40000018, 0x00000002, false);
if (ret < 0) return ret; if (ret < 0)
return 0; return ret;
return BLISP_OK;
} }
ret = blisp_send_command(device, 0x1A, NULL, 0, false); ret = blisp_send_command(device, 0x1A, NULL, 0, false);
if (ret < 0) return ret; if (ret < 0)
return ret;
ret = blisp_receive_response(device, false); ret = blisp_receive_response(device, false);
if (ret < 0) return ret; if (ret < 0)
return ret;
return BLISP_OK;
}
int32_t blisp_device_flash_erase(struct blisp_device* device,
uint32_t start_address,
uint32_t end_address) {
uint8_t payload[8];
*(uint32_t*)(payload + 0) = start_address;
*(uint32_t*)(payload + 4) = end_address;
int ret = blisp_send_command(device, 0x30, payload, 8, true);
if (ret < 0)
return ret;
do {
ret = blisp_receive_response(device, false);
} while (ret == BLISP_ERR_PENDING);
return 0; return 0;
} }
void blisp_device_close(struct blisp_device* device) int32_t blisp_device_flash_write(struct blisp_device* device,
{ uint32_t start_address,
uint8_t* payload,
uint32_t payload_size) {
// TODO: Add max payload size (8184?)
// TODO: Don't use malloc + add check
uint8_t* buffer = malloc(4 + payload_size);
*((uint32_t*)(buffer)) = start_address;
memcpy(buffer + 4, payload, payload_size);
int ret = blisp_send_command(device, 0x31, buffer, payload_size + 4, true);
if (ret < 0)
goto exit1;
ret = blisp_receive_response(device, false);
exit1:
free(buffer);
return ret;
}
int32_t blisp_device_program_check(struct blisp_device* device) {
int ret = blisp_send_command(device, 0x3A, NULL, 0, true);
if (ret < 0)
return ret;
ret = blisp_receive_response(device, false);
if (ret < 0)
return ret;
return 0;
}
int32_t blisp_device_reset(struct blisp_device* device) {
int ret = blisp_send_command(device, 0x21, NULL, 0, true);
if (ret < 0)
return ret;
ret = blisp_receive_response(device, false);
if (ret < 0)
return ret;
return BLISP_OK;
}
void blisp_device_close(struct blisp_device* device) {
struct sp_port* serial_port = device->serial_port; struct sp_port* serial_port = device->serial_port;
sp_close(serial_port); sp_close(serial_port);
} }
+367
View File
@@ -0,0 +1,367 @@
// SPDX-License-Identifier: MIT
#include "blisp_easy.h"
#include "blisp_struct.h"
#include "blisp_util.h"
#include <inttypes.h>
#include <string.h>
static int64_t blisp_easy_transport_read(struct blisp_easy_transport* transport,
void* buffer,
uint32_t size) {
if (transport->type == 0) {
// TODO: Implement reading more than available
memcpy(buffer, (uint8_t*)transport->data.memory.data_location + transport->data.memory.current_position, size);
transport->data.memory.current_position += size;
return size;
} else {
return fread(buffer, size, 1, transport->data.file_handle);
}
}
static int64_t blisp_easy_transport_size(struct blisp_easy_transport* transport) {
if (transport->type == 0) {
return transport->data.memory.data_size;
} else {
// TODO: Implement
printf("%s() Warning: calling non-implemented function\n", __func__);
return -1;
}
}
static void blisp_easy_report_progress(blisp_easy_progress_callback callback,
uint32_t current_value,
uint32_t max_value) {
if (callback != NULL) {
callback(current_value, max_value);
}
}
struct blisp_easy_transport blisp_easy_transport_new_from_file(FILE* file) {
struct blisp_easy_transport transport = {.type = 1, .data.file_handle = file};
return transport;
}
struct blisp_easy_transport blisp_easy_transport_new_from_memory(
void* data_location,
uint32_t data_size) {
struct blisp_easy_transport transport = {
.type = 0,
.data.memory.data_location = data_location,
.data.memory.data_size = data_size,
.data.memory.current_position = 0};
return transport;
}
int32_t blisp_easy_load_segment_data(
struct blisp_device* device,
uint32_t segment_size,
struct blisp_easy_transport* segment_transport,
blisp_easy_progress_callback progress_callback) {
int32_t ret;
#ifdef __APPLE__
const uint16_t buffer_max_size = 252 * 16;
#else
const uint16_t buffer_max_size = 4092;
#endif
uint32_t sent_data = 0;
uint32_t buffer_size = 0;
#ifdef _WIN32
uint8_t buffer[4092];
#else
uint8_t buffer[buffer_max_size];
#endif
blisp_easy_report_progress(progress_callback, 0, segment_size);
while (sent_data < segment_size) {
buffer_size = segment_size - sent_data;
if (buffer_size > buffer_max_size) {
buffer_size = buffer_max_size;
}
blisp_easy_transport_read(segment_transport, buffer,
buffer_size); // TODO: Error Handling
ret = blisp_device_load_segment_data(device, buffer, buffer_size);
if (ret < BLISP_OK) {
// TODO: Error logging fprintf(stderr, "Failed to load segment data. (ret
// %d)\n", ret);
return ret;
}
sent_data += buffer_size;
blisp_easy_report_progress(progress_callback, sent_data, segment_size);
}
return 0;
}
int32_t blisp_easy_load_ram_image(
struct blisp_device* device,
struct blisp_easy_transport* image_transport,
blisp_easy_progress_callback progress_callback) {
int32_t ret;
struct bfl_boot_header image_boot_header;
// TODO: Error handling
blisp_easy_transport_read(image_transport, &image_boot_header, 176);
ret = blisp_device_load_boot_header(device, (uint8_t*)&image_boot_header);
if (ret != BLISP_OK) {
// TODO: Error printing: fprintf(stderr, "Failed to load boot header.\n");
return ret;
}
{
for (uint8_t seg_index = 0;
seg_index < image_boot_header.segment_info.segment_cnt; seg_index++) {
struct blisp_segment_header segment_header = {0};
blisp_easy_transport_read(image_transport, &segment_header,
16); // TODO: Error handling
ret = blisp_device_load_segment_header(device, &segment_header);
if (ret != 0) {
// TODO: Error printing: fprintf(stderr, "Failed to load segment
// header.");
return ret;
}
// TODO: Info printing: printf("Flashing %d. segment\n", seg_index + 1);
ret = blisp_easy_load_segment_data(device, segment_header.length,
image_transport, progress_callback);
if (ret != 0) {
return ret;
}
}
}
ret = blisp_device_check_image(device);
if (ret != BLISP_OK) {
// TODO: Error printing: fprintf(stderr, "Failed to check image.\n");
return BLISP_EASY_ERR_CHECK_IMAGE_FAILED;
}
return BLISP_OK;
}
int32_t blisp_easy_load_ram_app(struct blisp_device* device,
struct blisp_easy_transport* app_transport,
blisp_easy_progress_callback progress_callback)
{
int32_t ret;
// TODO: Rework
// region boot header fill
struct bfl_boot_header boot_header;
memcpy(boot_header.magiccode, "BFNP", 4);
memcpy(boot_header.flashCfg.magiccode, "FCFG", 4);
boot_header.revison = 0x01;
boot_header.flashCfg.cfg.ioMode = 0x04;
boot_header.flashCfg.cfg.cReadSupport = 0x01;
boot_header.flashCfg.cfg.clkDelay = 0x01;
boot_header.flashCfg.cfg.clkInvert = 0x01;
boot_header.flashCfg.cfg.resetEnCmd = 0x66;
boot_header.flashCfg.cfg.resetCmd = 0x99;
boot_header.flashCfg.cfg.resetCreadCmd = 0xFF;
boot_header.flashCfg.cfg.resetCreadCmdSize = 0x03;
boot_header.flashCfg.cfg.jedecIdCmd = 0x9F;
boot_header.flashCfg.cfg.jedecIdCmdDmyClk = 0x00;
boot_header.flashCfg.cfg.qpiJedecIdCmd = 0x9F;
boot_header.flashCfg.cfg.qpiJedecIdCmdDmyClk = 0x00;
boot_header.flashCfg.cfg.sectorSize = 0x04;
boot_header.flashCfg.cfg.mid = 0xEF;
boot_header.flashCfg.cfg.pageSize = 0x100;
boot_header.flashCfg.cfg.chipEraseCmd = 0xC7;
boot_header.flashCfg.cfg.sectorEraseCmd = 0x20;
boot_header.flashCfg.cfg.blk32EraseCmd = 0x52;
boot_header.flashCfg.cfg.blk64EraseCmd = 0xD8;
boot_header.flashCfg.cfg.writeEnableCmd = 0x06;
boot_header.flashCfg.cfg.pageProgramCmd = 0x02;
boot_header.flashCfg.cfg.qpageProgramCmd = 0x32;
boot_header.flashCfg.cfg.qppAddrMode = 0x00;
boot_header.flashCfg.cfg.fastReadCmd = 0x0B;
boot_header.flashCfg.cfg.frDmyClk = 0x01;
boot_header.flashCfg.cfg.qpiFastReadCmd = 0x0B;
boot_header.flashCfg.cfg.qpiFrDmyClk = 0x01;
boot_header.flashCfg.cfg.fastReadDoCmd = 0x3B;
boot_header.flashCfg.cfg.frDoDmyClk = 0x01;
boot_header.flashCfg.cfg.fastReadDioCmd = 0xBB;
boot_header.flashCfg.cfg.frDioDmyClk = 0x00;
boot_header.flashCfg.cfg.fastReadQoCmd = 0x6B;
boot_header.flashCfg.cfg.frQoDmyClk = 0x01;
boot_header.flashCfg.cfg.fastReadQioCmd = 0xEB;
boot_header.flashCfg.cfg.frQioDmyClk = 0x02;
boot_header.flashCfg.cfg.qpiFastReadQioCmd = 0xEB;
boot_header.flashCfg.cfg.qpiFrQioDmyClk = 0x02;
boot_header.flashCfg.cfg.qpiPageProgramCmd = 0x02;
boot_header.flashCfg.cfg.writeVregEnableCmd = 0x50;
boot_header.flashCfg.cfg.wrEnableIndex = 0x00;
boot_header.flashCfg.cfg.qeIndex = 0x01;
boot_header.flashCfg.cfg.busyIndex = 0x00;
boot_header.flashCfg.cfg.wrEnableBit = 0x01;
boot_header.flashCfg.cfg.qeBit = 0x01;
boot_header.flashCfg.cfg.busyBit = 0x00;
boot_header.flashCfg.cfg.wrEnableWriteRegLen = 0x02;
boot_header.flashCfg.cfg.wrEnableReadRegLen = 0x01;
boot_header.flashCfg.cfg.qeWriteRegLen = 0x01;
boot_header.flashCfg.cfg.qeReadRegLen = 0x01;
boot_header.flashCfg.cfg.releasePowerDown = 0xAB;
boot_header.flashCfg.cfg.busyReadRegLen = 0x01;
boot_header.flashCfg.cfg.readRegCmd[0] = 0x05;
boot_header.flashCfg.cfg.readRegCmd[1] = 0x35;
boot_header.flashCfg.cfg.readRegCmd[2] = 0x00;
boot_header.flashCfg.cfg.readRegCmd[3] = 0x00;
boot_header.flashCfg.cfg.writeRegCmd[0] = 0x01;
boot_header.flashCfg.cfg.writeRegCmd[1] = 0x31;
boot_header.flashCfg.cfg.writeRegCmd[2] = 0x00;
boot_header.flashCfg.cfg.writeRegCmd[3] = 0x00;
boot_header.flashCfg.cfg.enterQpi = 0x38;
boot_header.flashCfg.cfg.exitQpi = 0xFF;
boot_header.flashCfg.cfg.cReadMode = 0x20;
boot_header.flashCfg.cfg.cRExit = 0xFF;
boot_header.flashCfg.cfg.burstWrapCmd = 0x77;
boot_header.flashCfg.cfg.burstWrapCmdDmyClk = 0x03;
boot_header.flashCfg.cfg.burstWrapDataMode = 0x02;
boot_header.flashCfg.cfg.burstWrapData = 0x40;
boot_header.flashCfg.cfg.deBurstWrapCmd = 0x77;
boot_header.flashCfg.cfg.deBurstWrapCmdDmyClk = 0x03;
boot_header.flashCfg.cfg.deBurstWrapDataMode = 0x02;
boot_header.flashCfg.cfg.deBurstWrapData = 0xF0;
boot_header.flashCfg.cfg.timeEsector = 0x12C;
boot_header.flashCfg.cfg.timeE32k = 0x4B0;
boot_header.flashCfg.cfg.timeE64k = 0x4B0;
boot_header.flashCfg.cfg.timePagePgm = 0x05;
boot_header.flashCfg.cfg.timeCe = 0xD40;
boot_header.flashCfg.cfg.pdDelay = 0x03;
boot_header.flashCfg.cfg.qeData = 0x00;
boot_header.flashCfg.crc32 = 0xC4BDD748;
boot_header.clkCfg.cfg.xtal_type = 0x04;
boot_header.clkCfg.cfg.pll_clk = 0x04;
boot_header.clkCfg.cfg.hclk_div = 0x00;
boot_header.clkCfg.cfg.bclk_div = 0x01;
boot_header.clkCfg.cfg.flash_clk_type = 0x02;
boot_header.clkCfg.cfg.flash_clk_div = 0x00;
boot_header.clkCfg.crc32 = 0x824E14BB;
boot_header.bootcfg.bval.sign = 0x00;
boot_header.bootcfg.bval.encrypt_type = 0x00;
boot_header.bootcfg.bval.key_sel = 0x00;
boot_header.bootcfg.bval.rsvd6_7 = 0x00;
boot_header.bootcfg.bval.no_segment = 0x01;
boot_header.bootcfg.bval.cache_enable = 0x01;
boot_header.bootcfg.bval.notload_in_bootrom = 0x00;
boot_header.bootcfg.bval.aes_region_lock = 0x00;
boot_header.bootcfg.bval.cache_way_disable = 0x00;
boot_header.bootcfg.bval.crc_ignore = 0x01;
boot_header.bootcfg.bval.hash_ignore = 0x01;
boot_header.bootcfg.bval.halt_ap = 0x00;
boot_header.bootcfg.bval.rsvd19_31 = 0x00;
boot_header.segment_info.segment_cnt = 0x01;
boot_header.bootentry = 0x00;
boot_header.flashoffset = device->chip->tcm_address;
boot_header.hash[0x00] = 0xEF;
boot_header.hash[0x01] = 0xBE;
boot_header.hash[0x02] = 0xAD;
boot_header.hash[0x03] = 0xDE;
boot_header.hash[0x04] = 0x00;
boot_header.hash[0x05] = 0x00;
boot_header.hash[0x06] = 0x00;
boot_header.hash[0x07] = 0x00;
boot_header.hash[0x08] = 0x00;
boot_header.hash[0x09] = 0x00;
boot_header.hash[0x0a] = 0x00;
boot_header.hash[0x0b] = 0x00;
boot_header.hash[0x0c] = 0x00;
boot_header.hash[0x0d] = 0x00;
boot_header.hash[0x0e] = 0x00;
boot_header.hash[0x0f] = 0x00;
boot_header.hash[0x10] = 0x00;
boot_header.hash[0x11] = 0x00;
boot_header.hash[0x12] = 0x00;
boot_header.hash[0x13] = 0x00;
boot_header.hash[0x14] = 0x00;
boot_header.hash[0x15] = 0x00;
boot_header.hash[0x16] = 0x00;
boot_header.hash[0x17] = 0x00;
boot_header.hash[0x18] = 0x00;
boot_header.hash[0x19] = 0x00;
boot_header.hash[0x1a] = 0x00;
boot_header.hash[0x1b] = 0x00;
boot_header.hash[0x1c] = 0x00;
boot_header.hash[0x1d] = 0x00;
boot_header.hash[0x1e] = 0x00;
boot_header.hash[0x1f] = 0x00;
boot_header.rsv1 = 0x00;
boot_header.rsv2 = 0x00;
boot_header.crc32 = 0xDEADBEEF;
// endregion
ret = blisp_device_load_boot_header(device, (uint8_t*)&boot_header);
if (ret != BLISP_OK) {
blisp_dlog("Failed to load boot header, ret: %d.", ret);
return ret;
}
struct blisp_segment_header segment_header = {
.dest_addr = device->chip->tcm_address,
.length = blisp_easy_transport_size(app_transport),
.reserved = 0,
.crc32 = 0
};
segment_header.crc32 = crc32_calculate(&segment_header, 3 * sizeof(uint32_t)); // TODO: Make function
ret = blisp_device_load_segment_header(device, &segment_header);
if (ret != 0) {
blisp_dlog("Failed to load segment header, ret: %d.", ret);
return ret;
}
ret = blisp_easy_load_segment_data(device, blisp_easy_transport_size(app_transport),
app_transport, progress_callback);
if (ret != 0) {
// TODO: Error printing
return ret;
}
return BLISP_OK;
}
int32_t blisp_easy_flash_write(struct blisp_device* device,
struct blisp_easy_transport* data_transport,
uint32_t flash_location,
uint32_t data_size,
blisp_easy_progress_callback progress_callback) {
int32_t ret;
#if defined (__APPLE__) || defined (__FreeBSD__)
const uint16_t buffer_max_size = 372 * 1;
#else
const uint16_t buffer_max_size = 2052;
#endif
uint32_t sent_data = 0;
uint32_t buffer_size = 0;
#ifdef _WIN32
uint8_t buffer[2052];
#else
uint8_t buffer[buffer_max_size];
#endif
blisp_easy_report_progress(progress_callback, 0, data_size);
while (sent_data < data_size) {
buffer_size = data_size - sent_data;
if (buffer_size > buffer_max_size) {
buffer_size = buffer_max_size;
}
blisp_easy_transport_read(data_transport, buffer,
buffer_size); // TODO: Error Handling
ret = blisp_device_flash_write(device, flash_location + sent_data, buffer,
buffer_size);
if (ret < BLISP_OK) {
// TODO: Error logigng: fprintf(stderr, "Failed to write firmware! (ret:
// %d)\n", ret);
return ret;
}
sent_data += buffer_size;
blisp_easy_report_progress(progress_callback, sent_data, data_size);
}
return BLISP_OK;
}
+24
View File
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
#include <stdlib.h>
#include <string.h>
#include "../../data/bl60x_eflash_loader.h"
#include "blisp.h"
int64_t blisp_chip_bl60x_get_eflash_loader(uint8_t clk_type, uint8_t** firmware_buf_ptr)
{
uint8_t* firmware_buf = malloc(sizeof(bl60x_eflash_loader_bin));
memcpy(firmware_buf, bl60x_eflash_loader_bin, sizeof(bl60x_eflash_loader_bin));
*(firmware_buf + 0xE0) = 4; // TODO: 40 MHz clock
*firmware_buf_ptr = firmware_buf;
return sizeof(bl60x_eflash_loader_bin);
}
struct blisp_chip blisp_chip_bl60x = {
.type = BLISP_CHIP_BL60X,
.type_str = "bl60x",
.usb_isp_available = false,
.default_xtal = "40m",
.handshake_byte_multiplier = 0.006f,
.load_eflash_loader = blisp_chip_bl60x_get_eflash_loader,
.tcm_address = 0x22010000
};
+11
View File
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
#include "blisp.h"
struct blisp_chip blisp_chip_bl61x = {
.type = BLISP_CHIP_BL61X,
.type_str = "bl808",
.usb_isp_available = true,
.default_xtal = "-", // ?
.handshake_byte_multiplier = 0.003f,
.get_eflash_loader = NULL
};
+19 -1
View File
@@ -1,7 +1,25 @@
// SPDX-License-Identifier: MIT
#include <stdlib.h>
#include <string.h>
#include "../../data/bl70x_eflash_loader.h"
#include "blisp.h" #include "blisp.h"
int64_t blisp_chip_bl70x_get_eflash_loader(uint8_t clk_type, uint8_t** firmware_buf_ptr)
{
uint8_t* firmware_buf = malloc(sizeof(bl70x_eflash_loader_bin));
memcpy(firmware_buf, bl70x_eflash_loader_bin, sizeof(bl70x_eflash_loader_bin));
*(firmware_buf + 0xE0) = 1; // TODO: 32 MHz clock
*firmware_buf_ptr = firmware_buf;
return sizeof(bl70x_eflash_loader_bin);
}
struct blisp_chip blisp_chip_bl70x = { struct blisp_chip blisp_chip_bl70x = {
.type = BLISP_CHIP_BL70X, .type = BLISP_CHIP_BL70X,
.type_str = "bl70x", .type_str = "bl70x",
.usb_isp_available = true .usb_isp_available = true,
.default_xtal = "32m",
.handshake_byte_multiplier = 0.003f,
.load_eflash_loader = blisp_chip_bl70x_get_eflash_loader,
.tcm_address = 0x22010000
}; };
+11
View File
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
#include "blisp.h"
struct blisp_chip blisp_chip_bl808 = {
.type = BLISP_CHIP_BL808,
.type_str = "bl808",
.usb_isp_available = true, // TODO: Only for BL808D :-(
.default_xtal = "-", // ?
.handshake_byte_multiplier = 0.003f,
.get_eflash_loader = NULL
};
+9 -1
View File
@@ -1,6 +1,9 @@
set(ARGTABLE3_ENABLE_TESTS OFF CACHE BOOL "Enable unit tests")
set(ARGTABLE3_ENABLE_EXAMPLES OFF CACHE BOOL "Enable examples")
#set(ARGTABLE3_REPLACE_GETOPT OFF CACHE BOOL "Replace getopt in the system C library")
add_subdirectory(${CMAKE_SOURCE_DIR}/vendor/argtable3 ${CMAKE_CURRENT_BINARY_DIR}/argtable3) add_subdirectory(${CMAKE_SOURCE_DIR}/vendor/argtable3 ${CMAKE_CURRENT_BINARY_DIR}/argtable3)
add_executable(blisp src/main.c src/cmd/write.c) add_executable(blisp src/main.c src/cmd/write.c src/util.c src/common.c src/cmd/iot.c)
target_include_directories(blisp PRIVATE target_include_directories(blisp PRIVATE
"${CMAKE_SOURCE_DIR}/include" "${CMAKE_SOURCE_DIR}/include"
@@ -10,3 +13,8 @@ target_link_libraries(blisp PRIVATE
argtable3 argtable3
libblisp_static) libblisp_static)
if (WIN32)
target_link_libraries(blisp PRIVATE Setupapi.lib)
elseif (APPLE)
target_link_libraries(blisp PRIVATE "-framework IOKit" "-framework CoreFoundation")
endif ()
+2
View File
@@ -1,3 +1,4 @@
// SPDX-License-Identifier: MIT
#ifndef BLISP_CMD_H #ifndef BLISP_CMD_H
#define BLISP_CMD_H #define BLISP_CMD_H
@@ -12,5 +13,6 @@ struct cmd {
}; };
extern struct cmd cmd_write; extern struct cmd cmd_write;
extern struct cmd cmd_iot;
#endif // BLISP_CMD_H #endif // BLISP_CMD_H
+140
View File
@@ -0,0 +1,140 @@
#include <blisp_easy.h>
#include "../cmd.h"
#include "../common.h"
#include <argtable3.h>
#define REG_EXTENDED 1
#define REG_ICASE (REG_EXTENDED << 1)
static struct arg_rex* cmd;
static struct arg_file* single_download;
static struct arg_int* single_download_location;
static struct arg_str *port_name, *chip_type; // TODO: Make this common
static struct arg_lit* reset;
static struct arg_end* end;
static void* cmd_iot_argtable[7];
void blisp_single_download()
{
struct blisp_device device;
int32_t ret;
if (blisp_common_init_device(&device, port_name, chip_type) != 0) {
return;
}
if (blisp_common_prepare_flash(&device) != 0) {
// TODO: Error handling
goto exit1;
}
FILE* data_file = fopen(single_download->filename[0], "rb");
if (data_file == NULL) {
fprintf(stderr, "Failed to open data file \"%s\".\n",
single_download->filename[0]);
goto exit1;
}
fseek(data_file, 0, SEEK_END);
int64_t data_file_size = ftell(data_file);
rewind(data_file);
printf("Erasing the area, this might take a while...\n");
ret =
blisp_device_flash_erase(&device, *single_download_location->ival,
*single_download_location->ival + data_file_size + 1);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to erase.\n");
goto exit2;
}
printf("Writing the data...\n");
struct blisp_easy_transport data_transport =
blisp_easy_transport_new_from_file(data_file);
ret = blisp_easy_flash_write(&device, &data_transport, *single_download_location->ival,
data_file_size,
blisp_common_progress_callback);
if (ret < BLISP_OK) {
fprintf(stderr, "Failed to write data to flash.\n");
goto exit2;
}
printf("Checking program...\n");
ret = blisp_device_program_check(&device);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to check program.\n");
goto exit2;
}
printf("Program OK!\n");
if (reset->count > 0) { // TODO: could be common
blisp_device_reset(&device);
printf("Resetting the chip.\n");
}
printf("Download complete!\n");
exit2:
if (data_file != NULL)
fclose(data_file);
exit1:
blisp_device_close(&device);
}
int8_t cmd_iot_args_init() {
cmd_iot_argtable[0] = cmd =
arg_rex1(NULL, NULL, "iot", NULL, REG_ICASE, NULL);
cmd_iot_argtable[1] = chip_type =
arg_str1("c", "chip", "<chip_type>", "Chip Type");
cmd_iot_argtable[2] = port_name =
arg_str0("p", "port", "<port_name>",
"Name/Path to the Serial Port (empty for search)");
cmd_iot_argtable[3] = reset =
arg_lit0(NULL, "reset", "Reset chip after write");
cmd_iot_argtable[4] = single_download =
arg_file0("s", "single-down", "<file>", "Single download file");
cmd_iot_argtable[5] = single_download_location =
arg_int0("l", "single-down-loc", NULL, "Single download offset");
cmd_iot_argtable[6] = end = arg_end(10);
if (arg_nullcheck(cmd_iot_argtable) != 0) {
fprintf(stderr, "insufficient memory\n");
return -1;
}
return 0;
}
void cmd_iot_args_print_glossary() {
fputs("Usage: blisp", stdout);
arg_print_syntax(stdout, cmd_iot_argtable, "\n");
puts("Flashes firmware as Bouffalo's DevCube");
arg_print_glossary(stdout, cmd_iot_argtable, " %-25s %s\n");
}
uint8_t cmd_iot_parse_exec(int argc, char** argv) {
int errors = arg_parse(argc, argv, cmd_iot_argtable);
if (errors == 0) {
if (single_download->count == 1 && single_download_location->count == 1) {
blisp_single_download();
return 1;
} else {
return 0;
}
} else if (cmd->count == 1) {
cmd_iot_args_print_glossary();
return 1;
}
return 0;
}
void cmd_iot_args_print_syntax() {
arg_print_syntax(stdout, cmd_iot_argtable, "\n");
}
void cmd_iot_free() {
arg_freetable(cmd_iot_argtable,
sizeof(cmd_iot_argtable) / sizeof(cmd_iot_argtable[0]));
}
struct cmd cmd_iot = {"iot", cmd_iot_args_init, cmd_iot_parse_exec,
cmd_iot_args_print_syntax, cmd_iot_free};
+232 -122
View File
@@ -1,12 +1,14 @@
#include "../cmd.h" // SPDX-License-Identifier: MIT
#include "argtable3.h"
#include <blisp.h> #include <blisp.h>
#include <string.h>
#include <inttypes.h> #include <inttypes.h>
#ifdef __linux__ #include <stdlib.h>
#include <unistd.h> #include <string.h>
#include <linux/limits.h> #include "../cmd.h"
#endif #include "../common.h"
#include "../util.h"
#include <argtable3.h>
#include <blisp_easy.h>
#include <blisp_struct.h>
#define REG_EXTENDED 1 #define REG_EXTENDED 1
#define REG_ICASE (REG_EXTENDED << 1) #define REG_ICASE (REG_EXTENDED << 1)
@@ -14,141 +16,251 @@
static struct arg_rex* cmd; static struct arg_rex* cmd;
static struct arg_file* binary_to_write; static struct arg_file* binary_to_write;
static struct arg_str *port_name, *chip_type; static struct arg_str *port_name, *chip_type;
static struct arg_lit* reset;
static struct arg_end* end; static struct arg_end* end;
static void* cmd_write_argtable[5]; static void* cmd_write_argtable[6];
ssize_t void fill_up_boot_header(struct bfl_boot_header* boot_header) {
get_binary_folder(char* buffer, uint32_t buffer_size) { memcpy(boot_header->magiccode, "BFNP", 4);
#ifdef __linux__
readlink("/proc/self/exe", buffer, BUFSIZ); // TODO: Error handling boot_header->revison = 0x01;
char* pos = strrchr(buffer, '/'); memcpy(boot_header->flashCfg.magiccode, "FCFG", 4);
pos[0] = '\0'; boot_header->flashCfg.cfg.ioMode = 0x11;
return pos - buffer; boot_header->flashCfg.cfg.cReadSupport = 0x00;
#else boot_header->flashCfg.cfg.clkDelay = 0x01;
#error NOT IMPLEMENTED boot_header->flashCfg.cfg.clkInvert = 0x01;
WCHAR path[MAX_PATH]; boot_header->flashCfg.cfg.resetEnCmd = 0x66;
GetModuleFileName(NULL, path, ARRAYSIZE(path)); boot_header->flashCfg.cfg.resetCmd = 0x99;
#endif boot_header->flashCfg.cfg.resetCreadCmd = 0xFF;
boot_header->flashCfg.cfg.resetCreadCmdSize = 0x03;
boot_header->flashCfg.cfg.jedecIdCmd = 0x9F;
boot_header->flashCfg.cfg.jedecIdCmdDmyClk = 0x00;
boot_header->flashCfg.cfg.qpiJedecIdCmd = 0x9F;
boot_header->flashCfg.cfg.qpiJedecIdCmdDmyClk = 0x00;
boot_header->flashCfg.cfg.sectorSize = 0x04;
boot_header->flashCfg.cfg.mid = 0xC2;
boot_header->flashCfg.cfg.pageSize = 0x100;
boot_header->flashCfg.cfg.chipEraseCmd = 0xC7;
boot_header->flashCfg.cfg.sectorEraseCmd = 0x20;
boot_header->flashCfg.cfg.blk32EraseCmd = 0x52;
boot_header->flashCfg.cfg.blk64EraseCmd = 0xD8;
boot_header->flashCfg.cfg.writeEnableCmd = 0x06;
boot_header->flashCfg.cfg.pageProgramCmd = 0x02;
boot_header->flashCfg.cfg.qpageProgramCmd = 0x32;
boot_header->flashCfg.cfg.qppAddrMode = 0x00;
boot_header->flashCfg.cfg.fastReadCmd = 0x0B;
boot_header->flashCfg.cfg.frDmyClk = 0x01;
boot_header->flashCfg.cfg.qpiFastReadCmd = 0x0B;
boot_header->flashCfg.cfg.qpiFrDmyClk = 0x01;
boot_header->flashCfg.cfg.fastReadDoCmd = 0x3B;
boot_header->flashCfg.cfg.frDoDmyClk = 0x01;
boot_header->flashCfg.cfg.fastReadDioCmd = 0xBB;
boot_header->flashCfg.cfg.frDioDmyClk = 0x00;
boot_header->flashCfg.cfg.fastReadQoCmd = 0x6B;
boot_header->flashCfg.cfg.frQoDmyClk = 0x01;
boot_header->flashCfg.cfg.fastReadQioCmd = 0xEB;
boot_header->flashCfg.cfg.frQioDmyClk = 0x02;
boot_header->flashCfg.cfg.qpiFastReadQioCmd = 0xEB;
boot_header->flashCfg.cfg.qpiFrQioDmyClk = 0x02;
boot_header->flashCfg.cfg.qpiPageProgramCmd = 0x02;
boot_header->flashCfg.cfg.writeVregEnableCmd = 0x50;
boot_header->flashCfg.cfg.wrEnableIndex = 0x00;
boot_header->flashCfg.cfg.qeIndex = 0x01;
boot_header->flashCfg.cfg.busyIndex = 0x00;
boot_header->flashCfg.cfg.wrEnableBit = 0x01;
boot_header->flashCfg.cfg.qeBit = 0x01;
boot_header->flashCfg.cfg.busyBit = 0x00;
boot_header->flashCfg.cfg.wrEnableWriteRegLen = 0x02;
boot_header->flashCfg.cfg.wrEnableReadRegLen = 0x01;
boot_header->flashCfg.cfg.qeWriteRegLen = 0x02;
boot_header->flashCfg.cfg.qeReadRegLen = 0x01;
boot_header->flashCfg.cfg.releasePowerDown = 0xAB;
boot_header->flashCfg.cfg.busyReadRegLen = 0x01;
boot_header->flashCfg.cfg.readRegCmd[0] = 0x05;
boot_header->flashCfg.cfg.readRegCmd[1] = 0x00;
boot_header->flashCfg.cfg.readRegCmd[2] = 0x00;
boot_header->flashCfg.cfg.readRegCmd[3] = 0x00;
boot_header->flashCfg.cfg.writeRegCmd[0] = 0x01;
boot_header->flashCfg.cfg.writeRegCmd[1] = 0x00;
boot_header->flashCfg.cfg.writeRegCmd[2] = 0x00;
boot_header->flashCfg.cfg.writeRegCmd[3] = 0x00;
boot_header->flashCfg.cfg.enterQpi = 0x38;
boot_header->flashCfg.cfg.exitQpi = 0xFF;
boot_header->flashCfg.cfg.cReadMode = 0x00;
boot_header->flashCfg.cfg.cRExit = 0xFF;
boot_header->flashCfg.cfg.burstWrapCmd = 0x77;
boot_header->flashCfg.cfg.burstWrapCmdDmyClk = 0x03;
boot_header->flashCfg.cfg.burstWrapDataMode = 0x02;
boot_header->flashCfg.cfg.burstWrapData = 0x40;
boot_header->flashCfg.cfg.deBurstWrapCmd = 0x77;
boot_header->flashCfg.cfg.deBurstWrapCmdDmyClk = 0x03;
boot_header->flashCfg.cfg.deBurstWrapDataMode = 0x02;
boot_header->flashCfg.cfg.deBurstWrapData = 0xF0;
boot_header->flashCfg.cfg.timeEsector = 0x12C;
boot_header->flashCfg.cfg.timeE32k = 0x4B0;
boot_header->flashCfg.cfg.timeE64k = 0x4B0;
boot_header->flashCfg.cfg.timePagePgm = 0x05;
boot_header->flashCfg.cfg.timeCe = 0xFFFF;
boot_header->flashCfg.cfg.pdDelay = 0x14;
boot_header->flashCfg.cfg.qeData = 0x00;
boot_header->flashCfg.crc32 = 0xE43C762A;
boot_header->clkCfg.cfg.xtal_type = 0x01;
boot_header->clkCfg.cfg.pll_clk = 0x04;
boot_header->clkCfg.cfg.hclk_div = 0x00;
boot_header->clkCfg.cfg.bclk_div = 0x01;
boot_header->clkCfg.cfg.flash_clk_type = 0x03;
boot_header->clkCfg.cfg.flash_clk_div = 0x00;
boot_header->clkCfg.crc32 = 0x72127DBA;
boot_header->bootcfg.bval.sign = 0x00;
boot_header->bootcfg.bval.encrypt_type = 0x00;
boot_header->bootcfg.bval.key_sel = 0x00;
boot_header->bootcfg.bval.rsvd6_7 = 0x00;
boot_header->bootcfg.bval.no_segment = 0x01;
boot_header->bootcfg.bval.cache_enable = 0x01;
boot_header->bootcfg.bval.notload_in_bootrom = 0x00;
boot_header->bootcfg.bval.aes_region_lock = 0x00;
boot_header->bootcfg.bval.cache_way_disable = 0x00;
boot_header->bootcfg.bval.crc_ignore = 0x01;
boot_header->bootcfg.bval.hash_ignore = 0x01;
boot_header->bootcfg.bval.halt_ap = 0x00;
boot_header->bootcfg.bval.rsvd19_31 = 0x00;
boot_header->segment_info.segment_cnt = 0xCDA8;
boot_header->bootentry = 0x00;
boot_header->flashoffset = 0x2000;
boot_header->hash[0x00] = 0xEF;
boot_header->hash[0x01] = 0xBE;
boot_header->hash[0x02] = 0xAD;
boot_header->hash[0x03] = 0xDE;
boot_header->hash[0x04] = 0x00;
boot_header->hash[0x05] = 0x00;
boot_header->hash[0x06] = 0x00;
boot_header->hash[0x07] = 0x00;
boot_header->hash[0x08] = 0x00;
boot_header->hash[0x09] = 0x00;
boot_header->hash[0x0a] = 0x00;
boot_header->hash[0x0b] = 0x00;
boot_header->hash[0x0c] = 0x00;
boot_header->hash[0x0d] = 0x00;
boot_header->hash[0x0e] = 0x00;
boot_header->hash[0x0f] = 0x00;
boot_header->hash[0x10] = 0x00;
boot_header->hash[0x11] = 0x00;
boot_header->hash[0x12] = 0x00;
boot_header->hash[0x13] = 0x00;
boot_header->hash[0x14] = 0x00;
boot_header->hash[0x15] = 0x00;
boot_header->hash[0x16] = 0x00;
boot_header->hash[0x17] = 0x00;
boot_header->hash[0x18] = 0x00;
boot_header->hash[0x19] = 0x00;
boot_header->hash[0x1a] = 0x00;
boot_header->hash[0x1b] = 0x00;
boot_header->hash[0x1c] = 0x00;
boot_header->hash[0x1d] = 0x00;
boot_header->hash[0x1e] = 0x00;
boot_header->hash[0x1f] = 0x00;
boot_header->rsv1 = 0x1000;
boot_header->rsv2 = 0x2000;
boot_header->crc32 = 0xDEADBEEF;
} }
void blisp_flash_firmware() { void blisp_flash_firmware() {
// TODO: We support currently only BL70X
if (chip_type->count == 0 || strcmp(chip_type->sval[0], "bl70x") != 0) {
fprintf(stderr, "Chip type is invalid.\n");
return;
}
struct blisp_device device; struct blisp_device device;
uint32_t ret; int32_t ret;
ret = blisp_device_init(&device, &blisp_chip_bl70x);
if (ret != 0) { if (blisp_common_init_device(&device, port_name, chip_type) != 0) {
fprintf(stderr, "Failed to init device.\n");
return; return;
} }
ret = blisp_device_open(&device, port_name->count == 1 ? port_name->sval[0] : NULL);
if (ret != 0) {
fprintf(stderr, "Failed to open device.\n");
return;
}
printf("Sending a handshake...");
ret = blisp_device_handshake(&device);
if (ret != 0) {
fprintf(stderr, "\nFailed to handshake with device.\n");
goto exit1;
}
printf(" OK\nGetting chip info...");
struct blisp_boot_info boot_info;
ret = blisp_device_get_boot_info(&device, &boot_info);
if (ret != 0) {
fprintf(stderr, "\nFailed to get boot info.\n");
goto exit1;
}
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]);
char exe_path[PATH_MAX]; if (blisp_common_prepare_flash(&device) != 0) {
char eflash_loader_path[PATH_MAX]; // TODO: Error handling
get_binary_folder(exe_path, PATH_MAX); // TODO: Error handling
snprintf(eflash_loader_path, PATH_MAX, "%s/data/%s/eflash_loader_32m.bin", exe_path, device.chip->type_str);
FILE* eflash_loader_file = fopen(eflash_loader_path, "rb");
uint8_t eflash_loader_header[176];
fread(eflash_loader_header, 176, 1, eflash_loader_file); // TODO: Error handling
printf("Loading eflash_loader...\n");
ret = blisp_device_load_boot_header(&device, eflash_loader_header);
if (ret != 0) {
fprintf(stderr, "Failed to load boot header.\n");
goto exit1; goto exit1;
} }
uint32_t sent_data = 0; FILE* firmware_file = fopen(binary_to_write->filename[0], "rb");
uint32_t buffer_size = 0; if (firmware_file == NULL) {
uint8_t buffer[4092]; fprintf(stderr, "Failed to open firmware file \"%s\".\n",
binary_to_write->filename[0]);
// TODO: Real checking of segments count
for (uint8_t seg_index = 0; seg_index < 1; seg_index++) {
struct blisp_segment_header segment_header = {0};
fread(&segment_header, 16, 1, eflash_loader_file); // TODO: Error handling
ret = blisp_device_load_segment_header(&device, &segment_header);
if (ret != 0) {
fprintf(stderr, "Failed to load segment header.\n");
goto exit1; goto exit1;
} }
printf("Flashing %d. segment\n", seg_index + 1); fseek(firmware_file, 0, SEEK_END);
printf("0b / %" PRIu32 "b (0.00%%)\n", segment_header.length); int64_t firmware_file_size = ftell(firmware_file);
rewind(firmware_file);
while (sent_data < segment_header.length) { struct bfl_boot_header boot_header;
buffer_size = segment_header.length - sent_data; fill_up_boot_header(&boot_header);
if (buffer_size > 4092) {
buffer_size = 4092; const uint32_t firmware_base_address = 0x2000;
} printf("Erasing flash, this might take a while...\n");
fread(buffer, buffer_size, 1, eflash_loader_file); ret =
blisp_device_load_segment_data(&device, buffer, buffer_size); // TODO: Error handling blisp_device_flash_erase(&device, firmware_base_address,
sent_data += buffer_size; firmware_base_address + firmware_file_size + 1);
printf("%" PRIu32 "b / %" PRIu32 "b (%.2f%%)\n", sent_data, segment_header.length, if (ret != BLISP_OK) {
(((float)sent_data / (float)segment_header.length) * 100.0f)); fprintf(stderr, "Failed to erase flash.\n");
goto exit2;
} }
ret =
blisp_device_flash_erase(&device, 0x0000, sizeof(struct bfl_boot_header));
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to erase flash.\n");
goto exit2;
} }
ret = blisp_device_check_image(&device); printf("Flashing boot header...\n");
if (ret != 0) { ret = blisp_device_flash_write(&device, 0x0000, (uint8_t*)&boot_header,
fprintf(stderr, "Failed to check image.\n"); sizeof(struct bfl_boot_header));
goto exit1; if (ret != BLISP_OK) {
fprintf(stderr, "Failed to write boot header.\n");
goto exit2;
}
printf("Flashing the firmware...\n");
struct blisp_easy_transport data_transport =
blisp_easy_transport_new_from_file(firmware_file);
ret = blisp_easy_flash_write(&device, &data_transport, firmware_base_address,
firmware_file_size,
blisp_common_progress_callback);
if (ret < BLISP_OK) {
fprintf(stderr, "Failed to write app to flash.\n");
goto exit2;
} }
ret = blisp_device_run_image(&device); printf("Checking program...\n");
if (ret != 0) { ret = blisp_device_program_check(&device);
fprintf(stderr, "Failed to run image.\n"); if (ret != BLISP_OK) {
goto exit1; fprintf(stderr, "Failed to check program.\n");
goto exit2;
}
printf("Program OK!\n");
if (reset->count > 0) {
blisp_device_reset(&device);
printf("Resetting the chip.\n");
// TODO: It seems that GPIO peripheral is not reset after resetting the chip
} }
printf("Flash complete!\n");
exit2:
if (firmware_file != NULL)
fclose(firmware_file);
exit1: exit1:
if (eflash_loader_file != NULL) fclose(eflash_loader_file);
blisp_device_close(&device); blisp_device_close(&device);
} }
int8_t int8_t cmd_write_args_init() {
cmd_write_args_init() { cmd_write_argtable[0] = cmd =
cmd_write_argtable[0] = cmd arg_rex1(NULL, NULL, "write", NULL, REG_ICASE, NULL);
= arg_rex1(NULL, NULL, "write", NULL, REG_ICASE, NULL); cmd_write_argtable[1] = chip_type =
cmd_write_argtable[1] = chip_type = arg_str1("c", "chip", "<chip_type>", "Chip Type (bl70x)"); arg_str1("c", "chip", "<chip_type>", "Chip Type");
cmd_write_argtable[2] = port_name cmd_write_argtable[2] = port_name =
= arg_str0("p", "port", "<port_name>", "Name/Path to the Serial Port (empty for search)"); arg_str0("p", "port", "<port_name>",
cmd_write_argtable[3] = binary_to_write "Name/Path to the Serial Port (empty for search)");
= arg_file1(NULL, NULL, "<input>", "Binary to write"); cmd_write_argtable[3] = reset =
cmd_write_argtable[4] = end = arg_end(10); arg_lit0(NULL, "reset", "Reset chip after write");
cmd_write_argtable[4] = binary_to_write =
arg_file1(NULL, NULL, "<input>", "Binary to write");
cmd_write_argtable[5] = end = arg_end(10);
if (arg_nullcheck(cmd_write_argtable) != 0) { if (arg_nullcheck(cmd_write_argtable) != 0) {
fprintf(stderr, "insufficient memory\n"); fprintf(stderr, "insufficient memory\n");
@@ -164,8 +276,7 @@ void cmd_write_args_print_glossary() {
arg_print_glossary(stdout, cmd_write_argtable, " %-25s %s\n"); arg_print_glossary(stdout, cmd_write_argtable, " %-25s %s\n");
} }
uint8_t uint8_t cmd_write_parse_exec(int argc, char** argv) {
cmd_write_parse_exec(int argc, char** argv) {
int errors = arg_parse(argc, argv, cmd_write_argtable); int errors = arg_parse(argc, argv, cmd_write_argtable);
if (errors == 0) { if (errors == 0) {
blisp_flash_firmware(); // TODO: Error code? blisp_flash_firmware(); // TODO: Error code?
@@ -181,11 +292,10 @@ void cmd_write_args_print_syntax() {
arg_print_syntax(stdout, cmd_write_argtable, "\n"); arg_print_syntax(stdout, cmd_write_argtable, "\n");
} }
void void cmd_write_free() {
cmd_write_free() {
arg_freetable(cmd_write_argtable, arg_freetable(cmd_write_argtable,
sizeof(cmd_write_argtable) / sizeof(cmd_write_argtable[0])); sizeof(cmd_write_argtable) / sizeof(cmd_write_argtable[0]));
} }
struct cmd cmd_write struct cmd cmd_write = {"write", cmd_write_args_init, cmd_write_parse_exec,
= { "write", cmd_write_args_init, cmd_write_parse_exec, cmd_write_args_print_syntax, cmd_write_free }; cmd_write_args_print_syntax, cmd_write_free};
+138
View File
@@ -0,0 +1,138 @@
// SPDX-License-Identifier: MIT
#include "common.h"
#include <argtable3.h>
#include <blisp.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "blisp_easy.h"
#include "util.h"
void blisp_common_progress_callback(uint32_t current_value, uint32_t max_value) {
printf("%" PRIu32 "b / %u (%.2f%%)\n", current_value, max_value,
(((float)current_value / (float)max_value) * 100.0f));
}
int32_t blisp_common_init_device(struct blisp_device* device, struct arg_str* port_name, struct arg_str* chip_type)
{
if (chip_type->count == 0) {
fprintf(stderr, "Chip type is invalid.\n");
return -1;
}
struct blisp_chip* chip = NULL;
if (strcmp(chip_type->sval[0], "bl70x") == 0) {
chip = &blisp_chip_bl70x;
} else if (strcmp(chip_type->sval[0], "bl60x") == 0) {
chip = &blisp_chip_bl60x;
} else {
fprintf(stderr, "Chip type is invalid.\n");
return -1;
}
int32_t ret;
ret = blisp_device_init(device, chip);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to init device.\n");
return -1;
}
ret = blisp_device_open(device,
port_name->count == 1 ? port_name->sval[0] : NULL);
if (ret != BLISP_OK) {
fprintf(stderr, ret == BLISP_ERR_DEVICE_NOT_FOUND ? "Device not found\n" : "Failed to open device.\n");
return -1;
}
return 0;
}
/**
* Prepares chip to access flash
* this means performing handshake, and loading eflash_loader if needed.
*/
int32_t blisp_common_prepare_flash(struct blisp_device* device) {
int32_t ret = 0;
printf("Sending a handshake...\n");
ret = blisp_device_handshake(device, false);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to handshake with device.\n");
return -1;
}
printf("Handshake successful!\nGetting chip info...\n");
struct blisp_boot_info boot_info;
ret = blisp_device_get_boot_info(device, &boot_info);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to get boot info.\n");
return -1;
}
printf(
"BootROM version %d.%d.%d.%d, ChipID: "
"%02X%02X%02X%02X%02X%02X%02X%02X\n",
boot_info.boot_rom_version[0], boot_info.boot_rom_version[1],
boot_info.boot_rom_version[2], boot_info.boot_rom_version[3],
boot_info.chip_id[0], boot_info.chip_id[1], boot_info.chip_id[2],
boot_info.chip_id[3], boot_info.chip_id[4], boot_info.chip_id[5],
boot_info.chip_id[6], boot_info.chip_id[7]);
if (device->chip->load_eflash_loader == NULL) {
return 0;
}
if (boot_info.boot_rom_version[0] == 255 &&
boot_info.boot_rom_version[1] == 255 &&
boot_info.boot_rom_version[2] == 255 &&
boot_info.boot_rom_version[3] == 255) {
printf("Device already in eflash_loader.\n");
return 0;
}
uint8_t* eflash_loader_buffer = NULL;
// TODO: Error check
int64_t eflash_loader_buffer_length = device->chip->load_eflash_loader(0, &eflash_loader_buffer);
struct blisp_easy_transport eflash_loader_transport =
blisp_easy_transport_new_from_memory(eflash_loader_buffer, eflash_loader_buffer_length);
ret = blisp_easy_load_ram_app(device, &eflash_loader_transport, blisp_common_progress_callback);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to load eflash_loader, ret: %d\n", ret);
ret = -1;
goto exit1;
}
free(eflash_loader_buffer);
eflash_loader_buffer = NULL;
ret = blisp_device_check_image(device);
if (ret != 0) {
fprintf(stderr, "Failed to check image.\n");
ret = -1;
goto exit1;
}
ret = blisp_device_run_image(device);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to run image.\n");
ret = -1;
goto exit1;
}
printf("Sending a handshake...\n");
ret = blisp_device_handshake(device, true);
if (ret != BLISP_OK) {
fprintf(stderr, "Failed to handshake with device.\n");
ret = -1;
goto exit1;
}
printf("Handshake with eflash_loader successful.\n");
exit1:
if (eflash_loader_buffer != NULL)
free(eflash_loader_buffer);
return ret;
}
+13
View File
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
#ifndef BLISP_COMMON_H
#define BLISP_COMMON_H
#include <stdint.h>
#include <blisp.h>
#include <argtable3.h>
int32_t blisp_common_prepare_flash(struct blisp_device* device);
void blisp_common_progress_callback(uint32_t current_value, uint32_t max_value);
int32_t blisp_common_init_device(struct blisp_device* device, struct arg_str* port_name, struct arg_str* chip_type);
#endif // BLISP_COMMON_H
+9 -10
View File
@@ -1,12 +1,11 @@
#include "argtable3.h" // SPDX-License-Identifier: MIT
#include "cmd.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "argtable3.h"
#include "cmd.h"
struct cmd* cmds[] = { struct cmd* cmds[] = {&cmd_write, &cmd_iot};
&cmd_write
};
static uint8_t cmds_count = sizeof(cmds) / sizeof(cmds[0]); static uint8_t cmds_count = sizeof(cmds) / sizeof(cmds[0]);
@@ -17,7 +16,8 @@ static void* argtable[3];
int8_t args_init() { int8_t args_init() {
argtable[0] = help = arg_lit0(NULL, "help", "print this help and exit"); argtable[0] = help = arg_lit0(NULL, "help", "print this help and exit");
argtable[1] = version = arg_lit0(NULL, "version", "print version information and exit"); argtable[1] = version =
arg_lit0(NULL, "version", "print version information and exit");
argtable[2] = end = arg_end(20); argtable[2] = end = arg_end(20);
if (arg_nullcheck(argtable) != 0) { if (arg_nullcheck(argtable) != 0) {
@@ -45,8 +45,8 @@ int8_t args_parse_exec(int argc, char** argv) {
print_help(); print_help();
return 1; return 1;
} else if (version->count) { } else if (version->count) {
printf("blisp 1.0.0\n"); printf("blisp v0.0.3\n");
printf("Copyright (C) 2022 Marek Kraus and PINE64 Community\n"); printf("Copyright (C) 2023 Marek Kraus and PINE64 Community\n");
return 1; return 1;
} }
} }
@@ -57,8 +57,7 @@ void args_free() {
arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
} }
int int main(int argc, char** argv) {
main(int argc, char** argv) {
int exit_code = 0; int exit_code = 0;
if (args_init() != 0) { if (args_init() != 0) {
+51
View File
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: MIT
#include "util.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#ifdef __APPLE__
// Ugh. This stuff is just so messy without C++17 or Qt...
// These are not thread safe, but it doesn't place the responsibility
// to free an allocated buffer on the caller.nn
#include <stdlib.h>
static void util_get_executable_path(char* buffer_out, uint32_t max_size) {
assert(max_size >= PATH_MAX); // n.b. 1024 on MacOS. 4K on most Linux.
char raw_path_name[PATH_MAX]; // $HOME/../../var/tmp/x
char real_path_name[PATH_MAX]; // /var/tmp/x
uint32_t raw_path_size = sizeof(raw_path_name);
if (!_NSGetExecutablePath(raw_path_name, &raw_path_size)) {
realpath(raw_path_name, real_path_name);
}
// *real_path_name is appropriately sized and null terminated.
strcpy(buffer_out, real_path_name);
}
#endif
ssize_t util_get_binary_folder(char* buffer, uint32_t buffer_size) {
#ifdef __linux__
if (readlink("/proc/self/exe", buffer, buffer_size) <= 0) {
return -1;
}
char* pos = strrchr(buffer, '/');
#elif defined(__APPLE__)
util_get_executable_path(buffer, buffer_size);
char* pos = strrchr(buffer, '/');
#elif __FreeBSD__
if (readlink("/proc/curproc/file", buffer, buffer_size) <= 0) {
return -1;
}
char* pos = strrchr(buffer, '/');
#else
if (GetModuleFileName(NULL, buffer, buffer_size) <= 0) {
return -1;
}
char* pos = strrchr(buffer, '\\');
#endif
pos[0] = '\0';
return pos - buffer;
}
+23
View File
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
#ifndef BLISP_UTIL_H
#define BLISP_UTIL_H
#include <stdint.h>
#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#include <windows.h>
#define PATH_MAX MAX_PATH
#elif defined(__APPLE__)
#include <sys/syslimits.h>
#include <assert.h>
#include <sys/types.h>
#else
#include <unistd.h>
#endif
ssize_t util_get_binary_folder(char* buffer, uint32_t buffer_size);
#endif