mirror of
https://github.com/pine64/blisp.git
synced 2025-06-22 19:54:45 +00:00
Compare commits
3 Commits
7601709a4c
...
8a00a63600
Author | SHA1 | Date | |
---|---|---|---|
|
8a00a63600 | ||
|
da34daf69f | ||
|
9fbaa05b64 |
@ -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
|
|
||||||
|
100
README.md
100
README.md
@ -55,105 +55,9 @@ For BL60X, you need to specify also the serial port path:
|
|||||||
blisp --chip bl60x --reset -p /dev/ttyUSB0 name_of_firmware.bin
|
blisp --chip bl60x --reset -p /dev/ttyUSB0 name_of_firmware.bin
|
||||||
```
|
```
|
||||||
|
|
||||||
# Update Pinecil V2
|
# How to flash Pinecil V2
|
||||||
1. Windows or Linux: use the easy pre-made blisp executable.
|
|
||||||
2. Instructions on [Pinecil Wiki firmware](https://wiki.pine64.org/wiki/Pinecil#Update_Pinecil_V2)
|
|
||||||
3. For Troubleshooting the pre-made Blisp, [see down below](https://github.com/pine64/blisp#troubleshooting) or [Pinecil Wiki](https://wiki.pine64.org/wiki/Pinecil#Troubleshooting_V2_Flashing)
|
|
||||||
4. If you prefer to build the Blisp Flasher from Code, or have an ARM archietecture (i.e., Pinebook Pro laptop), see below.
|
|
||||||
|
|
||||||
|
|
||||||
# Build BLISP Flasher from code for BL70x
|
|
||||||
|
|
||||||
_Note: This has been tested on x86-64. The build process also works on aarch64 and armv7, and Pinebook Pro ARM._
|
|
||||||
|
|
||||||
## Linux Steps
|
|
||||||
|
|
||||||
1. **Linux set-up**
|
|
||||||
```
|
|
||||||
git clone --recursive https://github.com/pine64/blisp.git
|
|
||||||
cd blisp
|
|
||||||
mkdir build && cd build
|
|
||||||
cmake -DBLISP_BUILD_CLI=ON ..
|
|
||||||
cmake --build .
|
|
||||||
mkdir tools/blisp/data
|
|
||||||
mkdir -p tools/blisp/data/bl70x
|
|
||||||
```
|
|
||||||
Note: the blisp command will now be in `build/tools/blisp/` folder and could later be run with flags as ` ./tools/blisp/blisp` unless you cd into that folder.
|
|
||||||
|
|
||||||
2. Get the Bouffalo `eflash_loader_32m.bin`
|
|
||||||
|
|
||||||
a. Download [Bouffalo Lab Dev Cube here](https://dev.bouffalolab.com/download).
|
|
||||||
|
|
||||||
b. Extract the DevCube download and get the `eflash_loader_32m.bin` needed for the bl70x chip (the MCU in Pinecil V2).
|
|
||||||
|
|
||||||
Check this path for the file:
|
|
||||||
``` /BouffaloLabDevCube-v1.8.1/chips/bl702/eflash_loader/eflash_loader_32m.bin ```
|
|
||||||
|
|
||||||
c. cp or mv the `eflash_loader_32m.bin` to your `build/tools/data/bl70x` folder from step 1. The rest of the Dev Cube could be deleted.
|
|
||||||
|
|
||||||
`/build/tools/blisp/data/bl70x/eflash_loader_32m.bin`
|
|
||||||
|
|
||||||
### Continue with the next steps if building code to update Pinecil V2.
|
|
||||||
|
|
||||||
⛔ Do not use the Pinecil DC barrel jack while updating firmware or it may destroy your PC and pinecil. ⛔
|
|
||||||
|
|
||||||
3. **Get V2 firmware** from Github Ralim's IronOS
|
|
||||||
|
|
||||||
a. Download the newest stable [firmware release here](https://github.com/Ralim/IronOS/releases) (or a beta firmware). Hint: go to Assets section below the comments and get the Pinecilv2.zip file.
|
|
||||||
|
|
||||||
b. If it's in Zip form, then extract **Pinecilv2.zip** and select a language file (English = `Pinecilv2_EN.bin`).
|
|
||||||
|
|
||||||
c. Move the `Pinecilv2_EN.bin` (or selected language) into the same folder as the blisp command.
|
|
||||||
|
|
||||||
`build/tools/blisp/Pinecilv2_EN.bin`
|
|
||||||
|
|
||||||
d. Could delete the rest of Pinecilv2.zip, it is not needed.
|
|
||||||
|
|
||||||
4. Connect Pinecil to PC/laptop: long hold `[-]`, then connect cable. Can release the `[-]` after about 15-20second.
|
|
||||||
|
|
||||||
a. V2 screen should be Empty/black, if not, then repeat connection, or find another cable/port.
|
|
||||||
|
|
||||||
b. Pinecil connects as a serial port (Linux = /dev/ttyACM_x_, Windows = COM_x_).
|
|
||||||
|
|
||||||
c. use `dmesg -w` if you would like to watch the connection, Pinecil BL706 will connect as Manufacturer: BLIOT, ttyACM device.
|
|
||||||
|
|
||||||
5. If this fails, see [troubleshooting below](https://github.com/pine64/blisp#troubleshooting).
|
|
||||||
|
|
||||||
6. If you are in the folder `blisp/build/tools/blisp/` then execute
|
|
||||||
```
|
|
||||||
sudo ./blisp write -c bl70x --reset Pinecilv2_EN.bin
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: if a different language is selected, replace `Pinecilv2_EN.bin` above with the chosen file name.
|
|
||||||
|
|
||||||
7. Almost done: unplug from the PC and restart V2. Hold down the minus `[-]` button to see the new version number.
|
|
||||||
|
|
||||||
8. Before making menu changes, it is recommended to first [Restore Settings to Default](https://github.com/Ralim/IronOS/blob/dev/Documentation/GettingStarted.md#settings-menu).
|
|
||||||
Simply go to Advanced settings > Restore default settings, confirm using the `[+]` button. This sets all menu items to defaults, keeps the same firmware version, and does not affect any Boot-up logo art if applicable. Setting defaults first avoids unexpected behavior due to some changes in upgrades.
|
|
||||||
|
|
||||||
9. Congradulations, and [Stay Fluxey, my friends!](https://www.reddit.com/r/PINE64official/comments/xk9vxu/most_interesting_man_in_the_world_i_dont_always/?utm_source=share&utm_medium=web2x&context=3)
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
1. If the Pinecil V2 fails to connect to the PC, check the `dmesg` command output.
|
|
||||||
|
|
||||||
a. try different cable: usb-C to C is recommended over Usb-A, especially if you are having issues.
|
|
||||||
|
|
||||||
b. don't use a USB hub, directly connect to the USB port on the PC or laptop.
|
|
||||||
|
|
||||||
c. try different Usb ports (usb-c recommended). Sometimes the rear ports on a PC are better because they are directly connected to the motherboard.
|
|
||||||
|
|
||||||
d. try a different PC/laptop
|
|
||||||
|
|
||||||
2. It is important to hold down the `[-]` minus button _before_ plugging in the Usb-c cable, and do not release the button for another 15-20 seconds. Try to hold it a little longer before releasing if your computer is slow and it is not working. In rare circumstances on fussy USB ports, keep holding the `[-]` for the entire update.
|
|
||||||
|
|
||||||
3. If all of this fails, then join one of the [Live Community Chat channels linked](https://wiki.pine64.org/wiki/Pinecil#Community_links) in the Pinecil Wiki as volunteers there might be able to help.
|
|
||||||
|
|
||||||
4. Open a an new issue ticket in this Github/Blisp flasher at https://github.com/pine64/blisp/issues
|
|
||||||
|
|
||||||
5. See [Pinecil Wiki](https://wiki.pine64.org/wiki/Pinecil) for hardware information.
|
|
||||||
|
|
||||||
6. See [Github Ralim's IronOS](https://ralim.github.io/IronOS/#getting-started) for firmware/software information. This is only the Flasher that loads the firmware; all Pinecil firmware documents and menu instructions are in IronOS.
|
|
||||||
|
|
||||||
|
Check out the [wiki page](https://github.com/pine64/blisp/wiki/Update-Pinecil-V2).
|
||||||
|
|
||||||
# To Do
|
# To Do
|
||||||
|
|
||||||
|
@ -6,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;
|
||||||
@ -28,22 +40,35 @@ 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.
|
// 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, bool in_ef_loader);
|
int32_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader);
|
||||||
int32_t blisp_device_get_boot_info(struct blisp_device* device, 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_load_segment_header(
|
||||||
|
struct blisp_device* device,
|
||||||
|
struct blisp_segment_header* segment_header);
|
||||||
|
int32_t blisp_device_load_segment_data(struct blisp_device* device,
|
||||||
|
uint8_t* segment_data,
|
||||||
|
uint32_t segment_data_length);
|
||||||
int32_t blisp_device_write_memory(struct blisp_device* device,
|
int32_t blisp_device_write_memory(struct blisp_device* device,
|
||||||
uint32_t address, uint32_t value,
|
uint32_t address,
|
||||||
|
uint32_t value,
|
||||||
bool wait_for_res);
|
bool wait_for_res);
|
||||||
int32_t blisp_device_check_image(struct blisp_device* device);
|
int32_t blisp_device_check_image(struct blisp_device* device);
|
||||||
int32_t blisp_device_run_image(struct blisp_device* device);
|
int32_t blisp_device_run_image(struct blisp_device* device);
|
||||||
int32_t blisp_device_flash_erase(struct blisp_device* device, uint32_t start_address, uint32_t end_address);
|
int32_t blisp_device_flash_erase(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);
|
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_program_check(struct blisp_device* device);
|
||||||
int32_t blisp_device_reset(struct blisp_device* device);
|
int32_t blisp_device_reset(struct blisp_device* device);
|
||||||
void blisp_device_close(struct blisp_device* device);
|
void blisp_device_close(struct blisp_device* device);
|
||||||
|
@ -2,13 +2,10 @@
|
|||||||
#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_BL60X, BLISP_CHIP_BL70X };
|
||||||
BLISP_CHIP_BL60X,
|
|
||||||
BLISP_CHIP_BL70X
|
|
||||||
};
|
|
||||||
|
|
||||||
struct blisp_chip { // TODO: Move elsewhere?
|
struct blisp_chip { // TODO: Move elsewhere?
|
||||||
enum blisp_chip_type type;
|
enum blisp_chip_type type;
|
||||||
|
@ -6,16 +6,18 @@
|
|||||||
#ifndef _LIBBLISP_STRUCT_H
|
#ifndef _LIBBLISP_STRUCT_H
|
||||||
#define _LIBBLISP_STRUCT_H
|
#define _LIBBLISP_STRUCT_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t ioMode; /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */
|
uint8_t ioMode; /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */
|
||||||
uint8_t cReadSupport; /*!< Support continuous read mode,bit0:continuous read mode support,bit1:read mode cfg */
|
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 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 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 resetEnCmd; /*!< Flash enable reset command */
|
||||||
uint8_t resetCmd; /*!< Flash reset command */
|
uint8_t resetCmd; /*!< Flash reset command */
|
||||||
uint8_t resetCreadCmd; /*!< Flash reset continuous read command */
|
uint8_t resetCreadCmd; /*!< Flash reset continuous read command */
|
||||||
@ -88,15 +90,13 @@ typedef struct {
|
|||||||
|
|
||||||
#define BFLB_BOOTROM_HASH_SIZE 256 / 8
|
#define BFLB_BOOTROM_HASH_SIZE 256 / 8
|
||||||
|
|
||||||
struct boot_flash_cfg_t
|
struct boot_flash_cfg_t {
|
||||||
{
|
|
||||||
char magiccode[4]; /*'FCFG'*/
|
char magiccode[4]; /*'FCFG'*/
|
||||||
SPI_Flash_Cfg_Type cfg;
|
SPI_Flash_Cfg_Type cfg;
|
||||||
uint32_t crc32;
|
uint32_t crc32;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sys_clk_cfg_t
|
struct sys_clk_cfg_t {
|
||||||
{
|
|
||||||
uint8_t xtal_type;
|
uint8_t xtal_type;
|
||||||
uint8_t pll_clk;
|
uint8_t pll_clk;
|
||||||
uint8_t hclk_div;
|
uint8_t hclk_div;
|
||||||
@ -107,15 +107,13 @@ struct sys_clk_cfg_t
|
|||||||
uint8_t rsvd[2];
|
uint8_t rsvd[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct boot_clk_cfg_t
|
struct boot_clk_cfg_t {
|
||||||
{
|
|
||||||
char magiccode[4]; /*'PCFG'*/
|
char magiccode[4]; /*'PCFG'*/
|
||||||
struct sys_clk_cfg_t cfg;
|
struct sys_clk_cfg_t cfg;
|
||||||
uint32_t crc32;
|
uint32_t crc32;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bfl_boot_header
|
struct bfl_boot_header {
|
||||||
{
|
|
||||||
char magiccode[4]; /*'BFXP'*/
|
char magiccode[4]; /*'BFXP'*/
|
||||||
uint32_t revison;
|
uint32_t revison;
|
||||||
struct boot_flash_cfg_t flashCfg;
|
struct boot_flash_cfg_t flashCfg;
|
||||||
@ -128,7 +126,8 @@ struct bfl_boot_header
|
|||||||
uint32_t rsvd6_7 : 2; /* [7: 6] for encrypt*/
|
uint32_t rsvd6_7 : 2; /* [7: 6] for encrypt*/
|
||||||
uint32_t no_segment : 1; /* [8] no segment info */
|
uint32_t no_segment : 1; /* [8] no segment info */
|
||||||
uint32_t cache_enable : 1; /* [9] for cache */
|
uint32_t cache_enable : 1; /* [9] for cache */
|
||||||
uint32_t notload_in_bootrom : 1; /* [10] not load this img in bootrom */
|
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 aes_region_lock : 1; /* [11] aes region lock */
|
||||||
uint32_t cache_way_disable : 4; /* [15: 12] cache way disable info*/
|
uint32_t cache_way_disable : 4; /* [15: 12] cache way disable info*/
|
||||||
uint32_t crc_ignore : 1; /* [16] ignore crc */
|
uint32_t crc_ignore : 1; /* [16] ignore crc */
|
||||||
@ -137,12 +136,12 @@ struct bfl_boot_header
|
|||||||
uint32_t rsvd19_31 : 13; /* [31:19] rsvd */
|
uint32_t rsvd19_31 : 13; /* [31:19] rsvd */
|
||||||
} bval;
|
} bval;
|
||||||
uint32_t wval;
|
uint32_t wval;
|
||||||
}bootcfg ;
|
} bootcfg;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
uint32_t segment_cnt;
|
uint32_t segment_cnt;
|
||||||
uint32_t img_length;
|
uint32_t img_length;
|
||||||
}segment_info;
|
} segment_info;
|
||||||
|
|
||||||
uint32_t bootentry; /* entry point of the image*/
|
uint32_t bootentry; /* entry point of the image*/
|
||||||
|
|
||||||
@ -155,18 +154,18 @@ struct bfl_boot_header
|
|||||||
uint32_t crc32;
|
uint32_t crc32;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(struct bfl_boot_header) == 176, "Bootheader have wrong size");
|
static_assert(sizeof(struct bfl_boot_header) == 176,
|
||||||
|
"Bootheader have wrong size");
|
||||||
|
|
||||||
struct blflash_segment_header
|
struct blflash_segment_header {
|
||||||
{
|
|
||||||
uint32_t destaddr;
|
uint32_t destaddr;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t rsvd;
|
uint32_t rsvd;
|
||||||
uint32_t crc32;
|
uint32_t crc32;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(struct blflash_segment_header) == 16, "Segment header have wrong size");
|
static_assert(sizeof(struct blflash_segment_header) == 16,
|
||||||
|
"Segment header have wrong size");
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void sleep_ms(int milliseconds){
|
static void sleep_ms(int milliseconds) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
Sleep(milliseconds);
|
Sleep(milliseconds);
|
||||||
#else
|
#else
|
||||||
|
268
lib/blisp.c
268
lib/blisp.c
@ -2,8 +2,8 @@
|
|||||||
#include <blisp.h>
|
#include <blisp.h>
|
||||||
#include <blisp_util.h>
|
#include <blisp_util.h>
|
||||||
#include <libserialport.h>
|
#include <libserialport.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -13,55 +13,61 @@
|
|||||||
|
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
|
|
||||||
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) {
|
||||||
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];
|
||||||
|
|
||||||
int vid, pid;
|
int vid, pid;
|
||||||
sp_get_port_usb_vid_pid(port, &vid, &pid);
|
sp_get_port_usb_vid_pid(port, &vid, &pid);
|
||||||
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);
|
||||||
@ -70,11 +76,11 @@ int32_t blisp_device_open(struct blisp_device* device, const char* port_name)
|
|||||||
uint32_t vid, pid;
|
uint32_t vid, pid;
|
||||||
sp_get_port_usb_vid_pid(serial_port, &vid, &pid);
|
sp_get_port_usb_vid_pid(serial_port, &vid, &pid);
|
||||||
device->is_usb = pid == 0xFFFF;
|
device->is_usb = pid == 0xFFFF;
|
||||||
// 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 = 500000;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int fd;
|
int fd;
|
||||||
@ -87,15 +93,19 @@ int32_t blisp_device_open(struct blisp_device* device, const char* port_name)
|
|||||||
#endif
|
#endif
|
||||||
ret = sp_set_baudrate(serial_port, device->current_baud_rate);
|
ret = sp_set_baudrate(serial_port, device->current_baud_rate);
|
||||||
if (ret != SP_OK) {
|
if (ret != SP_OK) {
|
||||||
return -1; // TODO: Handle this
|
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;
|
||||||
|
|
||||||
@ -114,46 +124,49 @@ int32_t blisp_send_command(struct blisp_device* device, uint8_t command, void* p
|
|||||||
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;
|
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, 1000);
|
ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 1000);
|
||||||
if (ret < 2) {
|
if (ret < 2) {
|
||||||
#ifdef DEBUG
|
blisp_dlog("Failed to receive response, ret: %d", ret);
|
||||||
fprintf(stderr, "Failed to receive response. (ret = %d)\n", ret);
|
return BLISP_ERR_UNKNOWN; // TODO: Terrible
|
||||||
#endif
|
|
||||||
return -1; // TODO: Terrible
|
|
||||||
} else if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
|
} else if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
|
||||||
if (expect_payload) {
|
if (expect_payload) {
|
||||||
sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100); // TODO: Check if really we received the data.
|
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 -3; // TODO: Terrible
|
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;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
blisp_dlog("Failed to receive any response (err: %d, %d - %d)", ret,
|
||||||
fprintf(stderr, "Receive response failed... (err: %d, %d - %d)\n", ret, device->rx_buffer[0], device->rx_buffer[1]);
|
device->rx_buffer[0], device->rx_buffer[1]);
|
||||||
#endif
|
return BLISP_ERR_UNKNOWN;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) {
|
||||||
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;
|
||||||
@ -168,21 +181,22 @@ blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) {
|
|||||||
sleep_ms(50); // Wait a bit so BootROM can init
|
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;
|
uint32_t bytes_count = device->chip->handshake_byte_multiplier *
|
||||||
if (bytes_count > 600) bytes_count = 600;
|
(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 (!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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count,
|
ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count, 500);
|
||||||
500);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return -1;
|
blisp_dlog("Handshake write failed, ret %d", ret);
|
||||||
|
return BLISP_ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_ef_loader && !device->is_usb) {
|
if (!in_ef_loader && !device->is_usb) {
|
||||||
@ -193,171 +207,197 @@ blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) {
|
|||||||
ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 50);
|
ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 50);
|
||||||
if (ret >= 2) {
|
if (ret >= 2) {
|
||||||
if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
|
if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
|
||||||
return 0;
|
return BLISP_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -4; // didn't received response
|
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)
|
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
|
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->chip_id, &device->rx_buffer[16], 8);
|
memcpy(boot_info->chip_id, &device->rx_buffer[16], 8);
|
||||||
}
|
}
|
||||||
// TODO: BL60X
|
// TODO: BL60X
|
||||||
return 0;
|
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)
|
||||||
|
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_load_segment_data(struct blisp_device* device, uint8_t* segment_data, uint32_t segment_data_length)
|
int32_t blisp_device_load_segment_data(struct blisp_device* device,
|
||||||
{
|
uint8_t* segment_data,
|
||||||
|
uint32_t segment_data_length) {
|
||||||
int ret;
|
int ret;
|
||||||
ret = blisp_send_command(device, 0x18, segment_data, segment_data_length, false);
|
ret = blisp_send_command(device, 0x18, segment_data, segment_data_length,
|
||||||
if (ret < 0) return ret;
|
false);
|
||||||
|
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_check_image(struct blisp_device* device)
|
int32_t blisp_device_check_image(struct blisp_device* device) {
|
||||||
{
|
|
||||||
int ret;
|
int ret;
|
||||||
ret = blisp_send_command(device, 0x19, NULL, 0, false);
|
ret = blisp_send_command(device, 0x19, NULL, 0, false);
|
||||||
if (ret < 0) 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
|
int32_t blisp_device_write_memory(struct blisp_device* device,
|
||||||
blisp_device_write_memory(struct blisp_device* device, uint32_t address,
|
uint32_t address,
|
||||||
uint32_t value, bool wait_for_res) {
|
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, true);
|
ret = blisp_send_command(device, 0x50, payload, 8, true);
|
||||||
if (ret < 0) return ret;
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
if (wait_for_res) {
|
if (wait_for_res) {
|
||||||
ret = blisp_receive_response(device, false);
|
ret = blisp_receive_response(device, false);
|
||||||
if (ret < 0) return ret;
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return BLISP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t blisp_device_run_image(struct blisp_device* device)
|
int32_t blisp_device_run_image(struct blisp_device* device) {
|
||||||
{
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (device->chip->type == BLISP_CHIP_BL70X) { // ERRATA
|
if (device->chip->type == BLISP_CHIP_BL70X) { // ERRATA
|
||||||
ret = blisp_device_write_memory(device, 0x4000F100, 0x4E424845, true);
|
ret = blisp_device_write_memory(device, 0x4000F100, 0x4E424845, true);
|
||||||
if (ret < 0) return ret;
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
ret = blisp_device_write_memory(device, 0x4000F104, 0x22010000, true);
|
ret = blisp_device_write_memory(device, 0x4000F104, 0x22010000, true);
|
||||||
if (ret < 0) return ret;
|
if (ret < 0)
|
||||||
// ret = blisp_device_write_memory(device, 0x40000018, 0x00000000);
|
return ret;
|
||||||
// if (ret < 0) return ret;
|
// ret = blisp_device_write_memory(device, 0x40000018, 0x00000000);
|
||||||
|
// if (ret < 0) return ret;
|
||||||
ret = blisp_device_write_memory(device, 0x40000018, 0x00000002, false);
|
ret = blisp_device_write_memory(device, 0x40000018, 0x00000002, false);
|
||||||
if (ret < 0) 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 0;
|
return BLISP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t blisp_device_flash_erase(struct blisp_device* device,
|
||||||
blisp_device_flash_erase(struct blisp_device* device, uint32_t start_address, uint32_t end_address)
|
uint32_t start_address,
|
||||||
{
|
uint32_t end_address) {
|
||||||
uint8_t payload[8];
|
uint8_t payload[8];
|
||||||
*(uint32_t*)(payload + 0) = start_address;
|
*(uint32_t*)(payload + 0) = start_address;
|
||||||
*(uint32_t*)(payload + 4) = end_address;
|
*(uint32_t*)(payload + 4) = end_address;
|
||||||
|
|
||||||
int ret = blisp_send_command(device, 0x30, payload, 8, true);
|
int ret = blisp_send_command(device, 0x30, payload, 8, true);
|
||||||
if (ret < 0) return ret;
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
do {
|
do {
|
||||||
ret = blisp_receive_response(device, false);
|
ret = blisp_receive_response(device, false);
|
||||||
} while (ret == -3);
|
} while (ret == BLISP_ERR_PENDING);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t blisp_device_flash_write(struct blisp_device* device,
|
||||||
blisp_device_flash_write(struct blisp_device* device, uint32_t start_address, uint8_t* payload, uint32_t payload_size)
|
uint32_t start_address,
|
||||||
{
|
uint8_t* payload,
|
||||||
|
uint32_t payload_size) {
|
||||||
// TODO: Add max payload size (8184?)
|
// TODO: Add max payload size (8184?)
|
||||||
|
// TODO: Don't use malloc + add check
|
||||||
|
|
||||||
uint8_t* buffer = malloc(4 + payload_size); // TODO: Don't use malloc + add check
|
uint8_t* buffer = malloc(4 + payload_size);
|
||||||
*((uint32_t*)(buffer)) = start_address;
|
*((uint32_t*)(buffer)) = start_address;
|
||||||
memcpy(buffer + 4, payload, payload_size);
|
memcpy(buffer + 4, payload, payload_size);
|
||||||
int ret = blisp_send_command(device, 0x31, buffer, payload_size + 4, true);
|
int ret = blisp_send_command(device, 0x31, buffer, payload_size + 4, true);
|
||||||
if (ret < 0) goto exit1;
|
if (ret < 0)
|
||||||
|
goto exit1;
|
||||||
ret = blisp_receive_response(device, false);
|
ret = blisp_receive_response(device, false);
|
||||||
exit1:
|
exit1:
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t blisp_device_program_check(struct blisp_device* device)
|
int32_t blisp_device_program_check(struct blisp_device* device) {
|
||||||
{
|
|
||||||
int ret = blisp_send_command(device, 0x3A, NULL, 0, true);
|
int ret = blisp_send_command(device, 0x3A, NULL, 0, true);
|
||||||
if (ret < 0) 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 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t blisp_device_reset(struct blisp_device* device)
|
int32_t blisp_device_reset(struct blisp_device* device) {
|
||||||
{
|
|
||||||
int ret = blisp_send_command(device, 0x21, NULL, 0, true);
|
int ret = blisp_send_command(device, 0x21, NULL, 0, true);
|
||||||
if (ret < 0) 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void blisp_device_close(struct blisp_device* device)
|
void blisp_device_close(struct blisp_device* device) {
|
||||||
{
|
|
||||||
struct sp_port* serial_port = device->serial_port;
|
struct sp_port* serial_port = device->serial_port;
|
||||||
sp_close(serial_port);
|
sp_close(serial_port);
|
||||||
}
|
}
|
@ -10,8 +10,8 @@ target_link_libraries(blisp PRIVATE
|
|||||||
argtable3
|
argtable3
|
||||||
libblisp_static)
|
libblisp_static)
|
||||||
|
|
||||||
if(WIN32)
|
if (WIN32)
|
||||||
target_link_libraries(blisp PRIVATE Setupapi.lib)
|
target_link_libraries(blisp PRIVATE Setupapi.lib)
|
||||||
elseif(APPLE)
|
elseif (APPLE)
|
||||||
target_link_libraries(blisp PRIVATE "-framework IOKit" "-framework CoreFoundation")
|
target_link_libraries(blisp PRIVATE "-framework IOKit" "-framework CoreFoundation")
|
||||||
endif()
|
endif ()
|
@ -1,16 +1,16 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
#include <assert.h>
|
||||||
|
#include <blisp.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include "../cmd.h"
|
#include "../cmd.h"
|
||||||
#include "argtable3.h"
|
#include "argtable3.h"
|
||||||
#include <blisp.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include "blisp_struct.h"
|
#include "blisp_struct.h"
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <unistd.h>
|
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
#include <unistd.h>
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#include <BaseTsd.h>
|
#include <BaseTsd.h>
|
||||||
typedef SSIZE_T ssize_t;
|
typedef SSIZE_T ssize_t;
|
||||||
@ -25,7 +25,7 @@ typedef SSIZE_T ssize_t;
|
|||||||
|
|
||||||
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_lit* reset;
|
||||||
static struct arg_end* end;
|
static struct arg_end* end;
|
||||||
static void* cmd_write_argtable[6];
|
static void* cmd_write_argtable[6];
|
||||||
@ -36,13 +36,13 @@ static void* cmd_write_argtable[6];
|
|||||||
// to free an allocated buffer on the caller.nn
|
// to free an allocated buffer on the caller.nn
|
||||||
|
|
||||||
static void get_executable_path(char* buffer_out, uint32_t max_size) {
|
static void get_executable_path(char* buffer_out, uint32_t max_size) {
|
||||||
assert (max_size >= PATH_MAX); // n.b. 1024 on MacOS. 4K on most Linux.
|
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 raw_path_name[PATH_MAX]; // $HOME/../../var/tmp/x
|
||||||
char real_path_name[PATH_MAX]; // /var/tmp/x
|
char real_path_name[PATH_MAX]; // /var/tmp/x
|
||||||
uint32_t raw_path_size = sizeof(raw_path_name);
|
uint32_t raw_path_size = sizeof(raw_path_name);
|
||||||
|
|
||||||
if(!_NSGetExecutablePath(raw_path_name, &raw_path_size)) {
|
if (!_NSGetExecutablePath(raw_path_name, &raw_path_size)) {
|
||||||
realpath(raw_path_name, real_path_name);
|
realpath(raw_path_name, real_path_name);
|
||||||
}
|
}
|
||||||
// *real_path_name is appropriately sized and null terminated.
|
// *real_path_name is appropriately sized and null terminated.
|
||||||
@ -50,8 +50,7 @@ static void get_executable_path(char* buffer_out, uint32_t max_size) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ssize_t
|
ssize_t get_binary_folder(char* buffer, uint32_t buffer_size) {
|
||||||
get_binary_folder(char* buffer, uint32_t buffer_size) {
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (readlink("/proc/self/exe", buffer, buffer_size) <= 0) {
|
if (readlink("/proc/self/exe", buffer, buffer_size) <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -70,9 +69,9 @@ get_binary_folder(char* buffer, uint32_t buffer_size) {
|
|||||||
return pos - buffer;
|
return pos - buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_up_boot_header(struct bfl_boot_header* boot_header)
|
void fill_up_boot_header(struct bfl_boot_header* boot_header) {
|
||||||
{
|
memcpy(boot_header->magiccode, "BFNP", 4);
|
||||||
memcpy(boot_header->magiccode, "BFNP", 4);;
|
|
||||||
boot_header->revison = 0x01;
|
boot_header->revison = 0x01;
|
||||||
memcpy(boot_header->flashCfg.magiccode, "FCFG", 4);
|
memcpy(boot_header->flashCfg.magiccode, "FCFG", 4);
|
||||||
boot_header->flashCfg.cfg.ioMode = 0x11;
|
boot_header->flashCfg.cfg.ioMode = 0x11;
|
||||||
@ -236,25 +235,26 @@ void blisp_flash_firmware() {
|
|||||||
struct blisp_device device;
|
struct blisp_device device;
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
ret = blisp_device_init(&device, chip);
|
ret = blisp_device_init(&device, chip);
|
||||||
if (ret != 0) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to init device.\n");
|
fprintf(stderr, "Failed to init device.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ret = blisp_device_open(&device, port_name->count == 1 ? port_name->sval[0] : NULL);
|
ret = blisp_device_open(&device,
|
||||||
if (ret != 0) {
|
port_name->count == 1 ? port_name->sval[0] : NULL);
|
||||||
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to open device.\n");
|
fprintf(stderr, "Failed to open device.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("Sending a handshake...");
|
printf("Sending a handshake...");
|
||||||
ret = blisp_device_handshake(&device, false);
|
ret = blisp_device_handshake(&device, false);
|
||||||
if (ret != 0) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "\nFailed to handshake with device.\n");
|
fprintf(stderr, "\nFailed to handshake with device.\n");
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
printf(" OK\nGetting chip info...");
|
printf(" OK\nGetting chip info...");
|
||||||
struct blisp_boot_info boot_info;
|
struct blisp_boot_info boot_info;
|
||||||
ret = blisp_device_get_boot_info(&device, &boot_info);
|
ret = blisp_device_get_boot_info(&device, &boot_info);
|
||||||
if (ret != 0) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "\nFailed to get boot info.\n");
|
fprintf(stderr, "\nFailed to get boot info.\n");
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
@ -267,24 +267,20 @@ void blisp_flash_firmware() {
|
|||||||
goto eflash_loader;
|
goto eflash_loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" BootROM version %d.%d.%d.%d, ChipID: %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
printf(
|
||||||
boot_info.boot_rom_version[0],
|
" BootROM version %d.%d.%d.%d, ChipID: "
|
||||||
boot_info.boot_rom_version[1],
|
"%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||||
boot_info.boot_rom_version[2],
|
boot_info.boot_rom_version[0], boot_info.boot_rom_version[1],
|
||||||
boot_info.boot_rom_version[3],
|
boot_info.boot_rom_version[2], boot_info.boot_rom_version[3],
|
||||||
boot_info.chip_id[0],
|
boot_info.chip_id[0], boot_info.chip_id[1], boot_info.chip_id[2],
|
||||||
boot_info.chip_id[1],
|
boot_info.chip_id[3], boot_info.chip_id[4], boot_info.chip_id[5],
|
||||||
boot_info.chip_id[2],
|
boot_info.chip_id[6], boot_info.chip_id[7]);
|
||||||
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];
|
char exe_path[PATH_MAX];
|
||||||
char eflash_loader_path[PATH_MAX];
|
char eflash_loader_path[PATH_MAX];
|
||||||
if (get_binary_folder(exe_path, PATH_MAX) <= 0) {
|
if (get_binary_folder(exe_path, PATH_MAX) <= 0) {
|
||||||
fprintf(stderr, "Failed to find executable path to search for the "
|
fprintf(stderr,
|
||||||
|
"Failed to find executable path to search for the "
|
||||||
"eflash loader\n");
|
"eflash loader\n");
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
@ -292,8 +288,7 @@ void blisp_flash_firmware() {
|
|||||||
exe_path, device.chip->type_str,
|
exe_path, device.chip->type_str,
|
||||||
device.chip->default_eflash_loader_xtal);
|
device.chip->default_eflash_loader_xtal);
|
||||||
printf("Loading the eflash loader file from disk\n");
|
printf("Loading the eflash loader file from disk\n");
|
||||||
eflash_loader_file
|
eflash_loader_file = fopen(eflash_loader_path, "rb"); // TODO: Error handling
|
||||||
= fopen(eflash_loader_path, "rb"); // TODO: Error handling
|
|
||||||
if (eflash_loader_file == NULL) {
|
if (eflash_loader_file == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Could not open the eflash loader file from disk.\n"
|
"Could not open the eflash loader file from disk.\n"
|
||||||
@ -308,7 +303,7 @@ void blisp_flash_firmware() {
|
|||||||
|
|
||||||
printf("Loading eflash_loader...\n");
|
printf("Loading eflash_loader...\n");
|
||||||
ret = blisp_device_load_boot_header(&device, eflash_loader_header);
|
ret = blisp_device_load_boot_header(&device, eflash_loader_header);
|
||||||
if (ret != 0) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to load boot header.\n");
|
fprintf(stderr, "Failed to load boot header.\n");
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
@ -320,7 +315,7 @@ void blisp_flash_firmware() {
|
|||||||
|
|
||||||
// TODO: Real checking of segments count
|
// TODO: Real checking of segments count
|
||||||
for (uint8_t seg_index = 0; seg_index < 1; seg_index++) {
|
for (uint8_t seg_index = 0; seg_index < 1; seg_index++) {
|
||||||
struct blisp_segment_header segment_header = { 0 };
|
struct blisp_segment_header segment_header = {0};
|
||||||
fread(&segment_header, 16, 1,
|
fread(&segment_header, 16, 1,
|
||||||
eflash_loader_file); // TODO: Error handling
|
eflash_loader_file); // TODO: Error handling
|
||||||
|
|
||||||
@ -340,34 +335,33 @@ void blisp_flash_firmware() {
|
|||||||
fread(buffer, buffer_size, 1, eflash_loader_file);
|
fread(buffer, buffer_size, 1, eflash_loader_file);
|
||||||
ret = blisp_device_load_segment_data(
|
ret = blisp_device_load_segment_data(
|
||||||
&device, buffer, buffer_size); // TODO: Error handling
|
&device, buffer, buffer_size); // TODO: Error handling
|
||||||
if (ret < 0) {
|
if (ret < BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to load segment data. (ret %d)\n", ret);
|
fprintf(stderr, "Failed to load segment data. (ret %d)\n", ret);
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
sent_data += buffer_size;
|
sent_data += buffer_size;
|
||||||
printf("%" PRIu32 "b / %" PRIu32 "b (%.2f%%)\n", sent_data,
|
printf("%" PRIu32 "b / %" PRIu32 "b (%.2f%%)\n", sent_data,
|
||||||
segment_header.length,
|
segment_header.length,
|
||||||
(((float)sent_data / (float)segment_header.length)
|
(((float)sent_data / (float)segment_header.length) * 100.0f));
|
||||||
* 100.0f));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = blisp_device_check_image(&device);
|
ret = blisp_device_check_image(&device);
|
||||||
if (ret != 0) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to check image.\n");
|
fprintf(stderr, "Failed to check image.\n");
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = blisp_device_run_image(&device);
|
ret = blisp_device_run_image(&device);
|
||||||
if (ret != 0) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to run image.\n");
|
fprintf(stderr, "Failed to run image.\n");
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Sending a handshake...");
|
printf("Sending a handshake...");
|
||||||
ret = blisp_device_handshake(&device, true);
|
ret = blisp_device_handshake(&device, true);
|
||||||
if (ret != 0) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "\nFailed to handshake with device.\n");
|
fprintf(stderr, "\nFailed to handshake with device.\n");
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
@ -376,7 +370,8 @@ void blisp_flash_firmware() {
|
|||||||
eflash_loader:;
|
eflash_loader:;
|
||||||
FILE* firmware_file = fopen(binary_to_write->filename[0], "rb");
|
FILE* firmware_file = fopen(binary_to_write->filename[0], "rb");
|
||||||
if (firmware_file == NULL) {
|
if (firmware_file == NULL) {
|
||||||
fprintf(stderr,"Failed to open firmware file \"%s\".\n", binary_to_write->filename[0]);
|
fprintf(stderr, "Failed to open firmware file \"%s\".\n",
|
||||||
|
binary_to_write->filename[0]);
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
fseek(firmware_file, 0, SEEK_END);
|
fseek(firmware_file, 0, SEEK_END);
|
||||||
@ -388,22 +383,24 @@ eflash_loader:;
|
|||||||
|
|
||||||
const uint32_t firmware_base_address = 0x2000;
|
const uint32_t firmware_base_address = 0x2000;
|
||||||
printf("Erasing flash, this might take a while...");
|
printf("Erasing flash, this might take a while...");
|
||||||
ret = blisp_device_flash_erase(&device, firmware_base_address,
|
ret =
|
||||||
firmware_base_address + firmware_file_size
|
blisp_device_flash_erase(&device, firmware_base_address,
|
||||||
+ 1);
|
firmware_base_address + firmware_file_size + 1);
|
||||||
if (ret != 0) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "\nFailed to erase flash.\n");
|
fprintf(stderr, "\nFailed to erase flash.\n");
|
||||||
goto exit2;
|
goto exit2;
|
||||||
}
|
}
|
||||||
ret = blisp_device_flash_erase(&device, 0x0000, sizeof(struct bfl_boot_header));
|
ret =
|
||||||
if (ret != 0) {
|
blisp_device_flash_erase(&device, 0x0000, sizeof(struct bfl_boot_header));
|
||||||
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "\nFailed to erase flash.\n");
|
fprintf(stderr, "\nFailed to erase flash.\n");
|
||||||
goto exit2;
|
goto exit2;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" OK!\nFlashing boot header...");
|
printf(" OK!\nFlashing boot header...");
|
||||||
ret = blisp_device_flash_write(&device, 0x0000, (uint8_t*)&boot_header, sizeof(struct bfl_boot_header));
|
ret = blisp_device_flash_write(&device, 0x0000, (uint8_t*)&boot_header,
|
||||||
if (ret != 0) {
|
sizeof(struct bfl_boot_header));
|
||||||
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "\nFailed to write boot header.\n");
|
fprintf(stderr, "\nFailed to write boot header.\n");
|
||||||
goto exit2;
|
goto exit2;
|
||||||
}
|
}
|
||||||
@ -420,8 +417,10 @@ eflash_loader:;
|
|||||||
buffer_size = 2052;
|
buffer_size = 2052;
|
||||||
}
|
}
|
||||||
fread(buffer, buffer_size, 1, firmware_file);
|
fread(buffer, buffer_size, 1, firmware_file);
|
||||||
ret = blisp_device_flash_write(&device, firmware_base_address + sent_data, buffer, buffer_size); // TODO: Error handling
|
ret = blisp_device_flash_write(&device, firmware_base_address + sent_data,
|
||||||
if (ret < 0) {
|
buffer,
|
||||||
|
buffer_size); // TODO: Error handling
|
||||||
|
if (ret < BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to write firmware! (ret: %d)\n", ret);
|
fprintf(stderr, "Failed to write firmware! (ret: %d)\n", ret);
|
||||||
goto exit2;
|
goto exit2;
|
||||||
}
|
}
|
||||||
@ -433,7 +432,7 @@ eflash_loader:;
|
|||||||
|
|
||||||
printf("Checking program...");
|
printf("Checking program...");
|
||||||
ret = blisp_device_program_check(&device);
|
ret = blisp_device_program_check(&device);
|
||||||
if (ret != 0) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "\nFailed to check program.\n");
|
fprintf(stderr, "\nFailed to check program.\n");
|
||||||
goto exit2;
|
goto exit2;
|
||||||
}
|
}
|
||||||
@ -448,22 +447,26 @@ eflash_loader:;
|
|||||||
printf("Flash complete!\n");
|
printf("Flash complete!\n");
|
||||||
|
|
||||||
exit2:
|
exit2:
|
||||||
if (firmware_file != NULL) fclose(firmware_file);
|
if (firmware_file != NULL)
|
||||||
|
fclose(firmware_file);
|
||||||
exit1:
|
exit1:
|
||||||
if (eflash_loader_file != NULL) fclose(eflash_loader_file);
|
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 (bl70x)");
|
||||||
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] = reset = arg_lit0(NULL, "reset", "Reset chip after write");
|
"Name/Path to the Serial Port (empty for search)");
|
||||||
cmd_write_argtable[4] = binary_to_write
|
cmd_write_argtable[3] = reset =
|
||||||
= arg_file1(NULL, NULL, "<input>", "Binary to write");
|
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);
|
cmd_write_argtable[5] = end = arg_end(10);
|
||||||
|
|
||||||
if (arg_nullcheck(cmd_write_argtable) != 0) {
|
if (arg_nullcheck(cmd_write_argtable) != 0) {
|
||||||
@ -475,13 +478,12 @@ cmd_write_args_init() {
|
|||||||
|
|
||||||
void cmd_write_args_print_glossary() {
|
void cmd_write_args_print_glossary() {
|
||||||
fputs("Usage: blisp", stdout);
|
fputs("Usage: blisp", stdout);
|
||||||
arg_print_syntax(stdout,cmd_write_argtable,"\n");
|
arg_print_syntax(stdout, cmd_write_argtable, "\n");
|
||||||
puts("Writes firmware to SPI Flash");
|
puts("Writes firmware to SPI Flash");
|
||||||
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?
|
||||||
@ -494,14 +496,13 @@ cmd_write_parse_exec(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cmd_write_args_print_syntax() {
|
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};
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
#include "argtable3.h"
|
|
||||||
#include "cmd.h"
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "argtable3.h"
|
||||||
|
#include "cmd.h"
|
||||||
|
|
||||||
struct cmd* cmds[] = {
|
struct cmd* cmds[] = {&cmd_write};
|
||||||
&cmd_write
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t cmds_count = sizeof(cmds) / sizeof(cmds[0]);
|
static uint8_t cmds_count = sizeof(cmds) / sizeof(cmds[0]);
|
||||||
|
|
||||||
@ -18,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) {
|
||||||
@ -36,7 +35,7 @@ void print_help() {
|
|||||||
cmds[i]->args_print_syntax();
|
cmds[i]->args_print_syntax();
|
||||||
}
|
}
|
||||||
fputs(" blisp", stdout);
|
fputs(" blisp", stdout);
|
||||||
arg_print_syntax(stdout, argtable,"\n");
|
arg_print_syntax(stdout, argtable, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t args_parse_exec(int argc, char** argv) {
|
int8_t args_parse_exec(int argc, char** argv) {
|
||||||
@ -58,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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user