mirror of
https://github.com/pine64/blisp.git
synced 2024-12-22 14:30:28 +00:00
Compare commits
13 Commits
f0781f4862
...
9529ed5f93
Author | SHA1 | Date | |
---|---|---|---|
|
9529ed5f93 | ||
|
ffe2d0a48b | ||
|
aa79ad3601 | ||
|
04916cf5a4 | ||
|
80a0854f2c | ||
|
dddb316d91 | ||
|
c48950e07b | ||
|
14369675da | ||
|
f55975fe9b | ||
|
87174b7682 | ||
|
c30287e49d | ||
|
d278063472 | ||
|
738626e67e |
@ -10,9 +10,10 @@ option(BLISP_USE_SYSTEM_LIBRARIES "Use system-installed libraries" "${CMAKE_USE_
|
|||||||
option(COMPILE_TESTS "Compile the tests" OFF)
|
option(COMPILE_TESTS "Compile the tests" OFF)
|
||||||
|
|
||||||
add_library(libblisp_obj OBJECT
|
add_library(libblisp_obj OBJECT
|
||||||
lib/blisp.c
|
lib/blisp.c lib/blisp_easy.c
|
||||||
lib/chip/blisp_chip_bl60x.c
|
lib/chip/blisp_chip_bl60x.c
|
||||||
lib/chip/blisp_chip_bl70x.c lib/blisp_easy.c)
|
lib/chip/blisp_chip_bl70x.c
|
||||||
|
lib/chip/blisp_chip_bl808.c)
|
||||||
|
|
||||||
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/)
|
target_include_directories(libblisp_obj PRIVATE ${CMAKE_SOURCE_DIR}/include/)
|
||||||
|
|
||||||
|
@ -61,4 +61,8 @@ 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);
|
||||||
|
|
||||||
|
blisp_return_t bl808_load_clock_para(struct blisp_device* device,
|
||||||
|
bool irq_en, uint32_t baudrate);
|
||||||
|
blisp_return_t bl808_load_flash_para(struct blisp_device* device);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -28,4 +28,7 @@ extern struct blisp_chip blisp_chip_bl70x;
|
|||||||
extern struct blisp_chip blisp_chip_bl808;
|
extern struct blisp_chip blisp_chip_bl808;
|
||||||
extern struct blisp_chip blisp_chip_bl61x;
|
extern struct blisp_chip blisp_chip_bl61x;
|
||||||
|
|
||||||
|
extern struct bl808_bootheader_t bl808_header;
|
||||||
|
void fill_crcs(struct bl808_bootheader_t *bh);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -173,6 +173,212 @@ struct blflash_segment_header {
|
|||||||
static_assert(sizeof(struct blflash_segment_header) == 16,
|
static_assert(sizeof(struct blflash_segment_header) == 16,
|
||||||
"Segment header have wrong size");
|
"Segment header have wrong size");
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_spi_flash_cfg_t {
|
||||||
|
uint8_t ioMode; /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */
|
||||||
|
uint8_t cReadSupport; /*!< Support continuous read mode,bit0:continuous read mode support,bit1:read mode cfg */
|
||||||
|
uint8_t clkDelay; /*!< SPI clock delay,bit0-3:delay,bit4-6:pad delay */
|
||||||
|
uint8_t clkInvert; /*!< SPI clock phase invert,bit0:clck invert,bit1:rx invert,bit2-4:pad delay,bit5-7:pad delay */
|
||||||
|
uint8_t resetEnCmd; /*!< Flash enable reset command */
|
||||||
|
uint8_t resetCmd; /*!< Flash reset command */
|
||||||
|
uint8_t resetCreadCmd; /*!< Flash reset continuous read command */
|
||||||
|
uint8_t resetCreadCmdSize; /*!< Flash reset continuous read command size */
|
||||||
|
uint8_t jedecIdCmd; /*!< JEDEC ID command */
|
||||||
|
uint8_t jedecIdCmdDmyClk; /*!< JEDEC ID command dummy clock */
|
||||||
|
uint8_t enter32BitsAddrCmd; /*!< Enter 32-bits addr command */
|
||||||
|
uint8_t exit32BitsAddrCmd; /*!< Exit 32-bits addr command */
|
||||||
|
uint8_t sectorSize; /*!< *1024bytes */
|
||||||
|
uint8_t mid; /*!< Manufacturer ID */
|
||||||
|
uint16_t pageSize; /*!< Page size */
|
||||||
|
uint8_t chipEraseCmd; /*!< Chip erase cmd */
|
||||||
|
uint8_t sectorEraseCmd; /*!< Sector erase command */
|
||||||
|
uint8_t blk32EraseCmd; /*!< Block 32K erase command,some Micron not support */
|
||||||
|
uint8_t blk64EraseCmd; /*!< Block 64K erase command */
|
||||||
|
uint8_t writeEnableCmd; /*!< Need before every erase or program */
|
||||||
|
uint8_t pageProgramCmd; /*!< Page program cmd */
|
||||||
|
uint8_t qpageProgramCmd; /*!< QIO page program cmd */
|
||||||
|
uint8_t qppAddrMode; /*!< QIO page program address mode */
|
||||||
|
uint8_t fastReadCmd; /*!< Fast read command */
|
||||||
|
uint8_t frDmyClk; /*!< Fast read command dummy clock */
|
||||||
|
uint8_t qpiFastReadCmd; /*!< QPI fast read command */
|
||||||
|
uint8_t qpiFrDmyClk; /*!< QPI fast read command dummy clock */
|
||||||
|
uint8_t fastReadDoCmd; /*!< Fast read dual output command */
|
||||||
|
uint8_t frDoDmyClk; /*!< Fast read dual output command dummy clock */
|
||||||
|
uint8_t fastReadDioCmd; /*!< Fast read dual io comamnd */
|
||||||
|
uint8_t frDioDmyClk; /*!< Fast read dual io command dummy clock */
|
||||||
|
uint8_t fastReadQoCmd; /*!< Fast read quad output comamnd */
|
||||||
|
uint8_t frQoDmyClk; /*!< Fast read quad output comamnd dummy clock */
|
||||||
|
uint8_t fastReadQioCmd; /*!< Fast read quad io comamnd */
|
||||||
|
uint8_t frQioDmyClk; /*!< Fast read quad io comamnd dummy clock */
|
||||||
|
uint8_t qpiFastReadQioCmd; /*!< QPI fast read quad io comamnd */
|
||||||
|
uint8_t qpiFrQioDmyClk; /*!< QPI fast read QIO dummy clock */
|
||||||
|
uint8_t qpiPageProgramCmd; /*!< QPI program command */
|
||||||
|
uint8_t writeVregEnableCmd; /*!< Enable write reg */
|
||||||
|
uint8_t wrEnableIndex; /*!< Write enable register index */
|
||||||
|
uint8_t qeIndex; /*!< Quad mode enable register index */
|
||||||
|
uint8_t busyIndex; /*!< Busy status register index */
|
||||||
|
uint8_t wrEnableBit; /*!< Write enable bit pos */
|
||||||
|
uint8_t qeBit; /*!< Quad enable bit pos */
|
||||||
|
uint8_t busyBit; /*!< Busy status bit pos */
|
||||||
|
uint8_t wrEnableWriteRegLen; /*!< Register length of write enable */
|
||||||
|
uint8_t wrEnableReadRegLen; /*!< Register length of write enable status */
|
||||||
|
uint8_t qeWriteRegLen; /*!< Register length of contain quad enable */
|
||||||
|
uint8_t qeReadRegLen; /*!< Register length of contain quad enable status */
|
||||||
|
uint8_t releasePowerDown; /*!< Release power down command */
|
||||||
|
uint8_t busyReadRegLen; /*!< Register length of contain busy status */
|
||||||
|
uint8_t readRegCmd[4]; /*!< Read register command buffer */
|
||||||
|
uint8_t writeRegCmd[4]; /*!< Write register command buffer */
|
||||||
|
uint8_t enterQpi; /*!< Enter qpi command */
|
||||||
|
uint8_t exitQpi; /*!< Exit qpi command */
|
||||||
|
uint8_t cReadMode; /*!< Config data for continuous read mode */
|
||||||
|
uint8_t cRExit; /*!< Config data for exit continuous read mode */
|
||||||
|
uint8_t burstWrapCmd; /*!< Enable burst wrap command */
|
||||||
|
uint8_t burstWrapCmdDmyClk; /*!< Enable burst wrap command dummy clock */
|
||||||
|
uint8_t burstWrapDataMode; /*!< Data and address mode for this command */
|
||||||
|
uint8_t burstWrapData; /*!< Data to enable burst wrap */
|
||||||
|
uint8_t deBurstWrapCmd; /*!< Disable burst wrap command */
|
||||||
|
uint8_t deBurstWrapCmdDmyClk; /*!< Disable burst wrap command dummy clock */
|
||||||
|
uint8_t deBurstWrapDataMode; /*!< Data and address mode for this command */
|
||||||
|
uint8_t deBurstWrapData; /*!< Data to disable burst wrap */
|
||||||
|
uint16_t timeEsector; /*!< 4K erase time */
|
||||||
|
uint16_t timeE32k; /*!< 32K erase time */
|
||||||
|
uint16_t timeE64k; /*!< 64K erase time */
|
||||||
|
uint16_t timePagePgm; /*!< Page program time */
|
||||||
|
uint16_t timeCe; /*!< Chip erase time in ms */
|
||||||
|
uint8_t pdDelay; /*!< Release power down command delay time for wake up */
|
||||||
|
uint8_t qeData; /*!< QE set data */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_boot_flash_cfg_t {
|
||||||
|
uint32_t magiccode;
|
||||||
|
struct bl808_spi_flash_cfg_t cfg;
|
||||||
|
uint32_t crc32;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_sys_clk_cfg_t {
|
||||||
|
uint8_t xtal_type;
|
||||||
|
uint8_t mcu_clk;
|
||||||
|
uint8_t mcu_clk_div;
|
||||||
|
uint8_t mcu_bclk_div;
|
||||||
|
|
||||||
|
uint8_t mcu_pbclk_div;
|
||||||
|
uint8_t lp_div;
|
||||||
|
uint8_t dsp_clk;
|
||||||
|
uint8_t dsp_clk_div;
|
||||||
|
|
||||||
|
uint8_t dsp_bclk_div;
|
||||||
|
uint8_t dsp_pbclk;
|
||||||
|
uint8_t dsp_pbclk_div;
|
||||||
|
uint8_t emi_clk;
|
||||||
|
|
||||||
|
uint8_t emi_clk_div;
|
||||||
|
uint8_t flash_clk_type;
|
||||||
|
uint8_t flash_clk_div;
|
||||||
|
uint8_t wifipll_pu;
|
||||||
|
|
||||||
|
uint8_t aupll_pu;
|
||||||
|
uint8_t cpupll_pu;
|
||||||
|
uint8_t mipipll_pu;
|
||||||
|
uint8_t uhspll_pu;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_boot_clk_cfg_t {
|
||||||
|
uint32_t magiccode;
|
||||||
|
struct bl808_sys_clk_cfg_t cfg;
|
||||||
|
uint32_t crc32;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_boot_basic_cfg_t {
|
||||||
|
uint32_t sign_type : 2; /* [1: 0] for sign */
|
||||||
|
uint32_t encrypt_type : 2; /* [3: 2] for encrypt */
|
||||||
|
uint32_t key_sel : 2; /* [5: 4] key slot */
|
||||||
|
uint32_t xts_mode : 1; /* [6] for xts mode */
|
||||||
|
uint32_t aes_region_lock : 1; /* [7] rsvd */
|
||||||
|
uint32_t no_segment : 1; /* [8] no segment info */
|
||||||
|
uint32_t rsvd_0 : 1; /* [9] boot2 enable(rsvd_0) */
|
||||||
|
uint32_t rsvd_1 : 1; /* [10] boot2 rollback(rsvd_1) */
|
||||||
|
uint32_t cpu_master_id : 4; /* [14: 11] master id */
|
||||||
|
uint32_t notload_in_bootrom : 1; /* [15] notload in bootrom */
|
||||||
|
uint32_t crc_ignore : 1; /* [16] ignore crc */
|
||||||
|
uint32_t hash_ignore : 1; /* [17] hash ignore */
|
||||||
|
uint32_t power_on_mm : 1; /* [18] power on mm */
|
||||||
|
uint32_t em_sel : 3; /* [21: 19] em_sel */
|
||||||
|
uint32_t cmds_en : 1; /* [22] command spliter enable */
|
||||||
|
uint32_t cmds_wrap_mode : 2; /* [24: 23] cmds wrap mode */
|
||||||
|
uint32_t cmds_wrap_len : 4; /* [28: 25] cmds wrap len */
|
||||||
|
uint32_t icache_invalid : 1; /* [29] icache invalid */
|
||||||
|
uint32_t dcache_invalid : 1; /* [30] dcache invalid */
|
||||||
|
uint32_t rsvd_3 : 1; /* [31] rsvd_3 */
|
||||||
|
|
||||||
|
uint32_t group_image_offset; /* flash controller offset */
|
||||||
|
uint32_t aes_region_len; /* aes region length */
|
||||||
|
|
||||||
|
uint32_t img_len_cnt; /* image length or segment count */
|
||||||
|
uint32_t hash[32 / 4]; /* hash of the image */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_boot_cpu_cfg_t {
|
||||||
|
uint8_t config_enable; /* coinfig this cpu */
|
||||||
|
uint8_t halt_cpu; /* halt this cpu */
|
||||||
|
uint8_t cache_enable : 1; /* cache setting */
|
||||||
|
uint8_t cache_wa : 1; /* cache setting */
|
||||||
|
uint8_t cache_wb : 1; /* cache setting */
|
||||||
|
uint8_t cache_wt : 1; /* cache setting */
|
||||||
|
uint8_t cache_way_dis : 4; /* cache setting */
|
||||||
|
uint8_t rsvd;
|
||||||
|
|
||||||
|
uint32_t cache_range_h; /* cache range high */
|
||||||
|
uint32_t cache_range_l; /* cache range low */
|
||||||
|
|
||||||
|
uint32_t image_address_offset; /* image_address_offset */
|
||||||
|
uint32_t rsvd0; /* rsvd0 */
|
||||||
|
uint32_t msp_val; /* msp value */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_aesiv_cfg_t {
|
||||||
|
uint8_t aesiv[16];
|
||||||
|
uint32_t crc32;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_pkey_cfg_t {
|
||||||
|
uint8_t eckeyx[32]; /* ec key in boot header */
|
||||||
|
uint8_t eckeyy[32]; /* ec key in boot header */
|
||||||
|
uint32_t crc32;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_sign_cfg_t {
|
||||||
|
uint32_t sig_len;
|
||||||
|
uint8_t signature[32];
|
||||||
|
uint32_t crc32;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed, aligned(4))) bl808_bootheader_t {
|
||||||
|
uint32_t magiccode; /* 4 */
|
||||||
|
uint32_t rivison; /* 4 */
|
||||||
|
|
||||||
|
struct bl808_boot_flash_cfg_t flash_cfg; /* 4 + 84 + 4 */
|
||||||
|
struct bl808_boot_clk_cfg_t clk_cfg; /* 4 + 20 + 4 */
|
||||||
|
|
||||||
|
struct bl808_boot_basic_cfg_t basic_cfg; /* 4 + 4 + 4 + 4 + 4*8 */
|
||||||
|
|
||||||
|
struct bl808_boot_cpu_cfg_t cpu_cfg[3]; /*24*3 */
|
||||||
|
|
||||||
|
uint32_t boot2_pt_table_0_rsvd; /* address of partition table 0 */ /* 4 */
|
||||||
|
uint32_t boot2_pt_table_1_rsvd; /* address of partition table 1 */ /* 4 */
|
||||||
|
|
||||||
|
uint32_t flash_cfg_table_addr; /* address of flashcfg table list */ /* 4 */
|
||||||
|
uint32_t flash_cfg_table_len; /* flashcfg table list len */ /* 4 */
|
||||||
|
|
||||||
|
uint32_t rsvd0[8]; /* rsvd */
|
||||||
|
uint32_t rsvd1[8]; /* rsvd */
|
||||||
|
|
||||||
|
uint32_t rsvd3[5]; /* 20 */
|
||||||
|
|
||||||
|
uint32_t crc32; /* 4 */
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(struct bl808_bootheader_t) == 352,
|
||||||
|
"BL808 bootheader size mismatch");
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,6 +20,14 @@ static void blisp_dlog(const char* format, ...)
|
|||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void blisp_dlog_no_nl(const char* format, ...) {
|
||||||
|
fflush(stdout);
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void sleep_ms(int milliseconds) {
|
static void sleep_ms(int milliseconds) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
193
lib/blisp.c
193
lib/blisp.c
@ -11,6 +11,8 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <blisp_struct.h>
|
||||||
|
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
|
|
||||||
static void drain(struct sp_port* port) {
|
static void drain(struct sp_port* port) {
|
||||||
@ -23,6 +25,7 @@ blisp_return_t blisp_device_init(struct blisp_device* device,
|
|||||||
struct blisp_chip* chip) {
|
struct blisp_chip* chip) {
|
||||||
device->chip = chip;
|
device->chip = chip;
|
||||||
device->is_usb = false;
|
device->is_usb = false;
|
||||||
|
fill_crcs(&bl808_header);
|
||||||
return BLISP_OK;
|
return BLISP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,8 +148,16 @@ blisp_return_t blisp_receive_response(struct blisp_device* device,
|
|||||||
bool expect_payload) {
|
bool expect_payload) {
|
||||||
// TODO: Check checksum
|
// TODO: Check checksum
|
||||||
int ret;
|
int ret;
|
||||||
|
uint32_t read_timeout = 1000;
|
||||||
|
if (device->chip->type == BLISP_CHIP_BL808) {
|
||||||
|
// TODO: For some reason the BL808 does not send pending ('PD') responses
|
||||||
|
// during long (i.e. erase) operations, so we must disable response
|
||||||
|
// timeouts. Further investigation is necessary.
|
||||||
|
read_timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
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, read_timeout);
|
||||||
if (ret < 2) {
|
if (ret < 2) {
|
||||||
blisp_dlog("Failed to receive response, ret: %d", ret);
|
blisp_dlog("Failed to receive response, ret: %d", ret);
|
||||||
return BLISP_ERR_NO_RESPONSE;
|
return BLISP_ERR_NO_RESPONSE;
|
||||||
@ -177,6 +188,7 @@ blisp_return_t blisp_receive_response(struct blisp_device* device,
|
|||||||
blisp_return_t blisp_device_handshake(struct blisp_device* device,
|
blisp_return_t blisp_device_handshake(struct blisp_device* device,
|
||||||
bool in_ef_loader) {
|
bool in_ef_loader) {
|
||||||
int ret;
|
int ret;
|
||||||
|
bool ok = false;
|
||||||
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;
|
||||||
|
|
||||||
@ -216,15 +228,39 @@ blisp_return_t blisp_device_handshake(struct blisp_device* device,
|
|||||||
sp_flush(serial_port, SP_BUF_INPUT); // Flush garbage out of RX
|
sp_flush(serial_port, SP_BUF_INPUT); // Flush garbage out of RX
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 50);
|
if (device->chip->type == BLISP_CHIP_BL808) {
|
||||||
|
sleep_ms(300);
|
||||||
|
const static uint8_t second_handshake[] = { 0x50, 0x00, 0x08, 0x00, 0x38, 0xF0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18 };
|
||||||
|
ret = sp_blocking_write(serial_port, second_handshake, sizeof(second_handshake), 300);
|
||||||
|
if (ret < 0) {
|
||||||
|
blisp_dlog("Second handshake write failed, ret %d", ret);
|
||||||
|
return BLISP_ERR_API_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sp_blocking_read(serial_port, device->rx_buffer, 20, 50);
|
||||||
if (ret >= 2) {
|
if (ret >= 2) {
|
||||||
if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') {
|
for (uint8_t j = 0; j < (ret - 1); j++) {
|
||||||
|
if (device->rx_buffer[j] == 'O' && device->rx_buffer[j + 1] == 'K') {
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
blisp_dlog("Received incorrect handshake response from chip.");
|
||||||
|
blisp_dlog_no_nl("Could not find 0x%02X 0x%02X ('O', 'K') in: ", 'O', 'K');
|
||||||
|
if (ret) {
|
||||||
|
for (uint8_t j=0; j <= ret; j++) {
|
||||||
|
blisp_dlog_no_nl("0x%02X ", device->rx_buffer[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blisp_dlog("");
|
||||||
|
return BLISP_ERR_NO_RESPONSE;
|
||||||
|
}
|
||||||
|
|
||||||
return BLISP_OK;
|
return BLISP_OK;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
blisp_dlog("Received no response from chip.");
|
|
||||||
return BLISP_ERR_NO_RESPONSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blisp_return_t blisp_device_get_boot_info(struct blisp_device* device,
|
blisp_return_t blisp_device_get_boot_info(struct blisp_device* device,
|
||||||
@ -239,13 +275,15 @@ blisp_return_t blisp_device_get_boot_info(struct blisp_device* device,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
memcpy(boot_info->boot_rom_version, &device->rx_buffer[0],
|
// TODO: Endianess; this may break on big endian machines
|
||||||
4); // TODO: Endianess; this may break on big endian machines
|
memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], 4);
|
||||||
|
|
||||||
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);
|
||||||
|
} else {
|
||||||
|
memcpy(boot_info->chip_id, &device->rx_buffer[12], 6);
|
||||||
}
|
}
|
||||||
// TODO: BL60X
|
|
||||||
return BLISP_OK;
|
return BLISP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,13 +398,13 @@ blisp_return_t blisp_device_flash_erase(struct blisp_device* device,
|
|||||||
*(uint32_t*)(payload + 4) = end_address;
|
*(uint32_t*)(payload + 4) = end_address;
|
||||||
|
|
||||||
blisp_return_t ret = blisp_send_command(device, 0x30, payload, 8, true);
|
blisp_return_t ret = blisp_send_command(device, 0x30, payload, 8, true);
|
||||||
if (ret < 0)
|
if (ret != BLISP_OK)
|
||||||
return ret;
|
return ret;
|
||||||
do {
|
do {
|
||||||
ret = blisp_receive_response(device, false);
|
ret = blisp_receive_response(device, false);
|
||||||
} while (ret == BLISP_ERR_PENDING);
|
} while (ret == BLISP_ERR_PENDING);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
blisp_return_t blisp_device_flash_write(struct blisp_device* device,
|
blisp_return_t blisp_device_flash_write(struct blisp_device* device,
|
||||||
@ -415,3 +453,134 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blisp_return_t bl808_load_clock_para(struct blisp_device* device,
|
||||||
|
bool irq_en, uint32_t baudrate) {
|
||||||
|
// XXX: this may be a good place to increase the baudrate for subsequent comms
|
||||||
|
const uint32_t clock_para_size = sizeof(struct bl808_boot_clk_cfg_t);
|
||||||
|
const uint32_t payload_size = 8 + clock_para_size;
|
||||||
|
uint8_t payload[payload_size] = {};
|
||||||
|
|
||||||
|
uint32_t irq_enable = irq_en ? 1 : 0;
|
||||||
|
memcpy(&payload[0], &irq_enable, 4);
|
||||||
|
memcpy(&payload[4], &baudrate, 4);
|
||||||
|
memcpy(&payload[8], &bl808_header.clk_cfg, clock_para_size);
|
||||||
|
|
||||||
|
blisp_return_t ret = blisp_send_command(device, 0x22, payload, payload_size, true);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = blisp_receive_response(device, false);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return BLISP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
blisp_return_t bl808_load_flash_para(struct blisp_device* device) {
|
||||||
|
// TODO: I don't understand why these parameters are the way they are,
|
||||||
|
// but at least they are labeled. Also, flash_io_mode and flash_clk_delay
|
||||||
|
// seem to be duplicated in the main spi_flash_cfg_t struct?
|
||||||
|
const uint8_t flash_pin = 0x4;
|
||||||
|
const uint8_t flash_clk_cfg = 0x41;
|
||||||
|
const uint8_t flash_io_mode = 0x01;
|
||||||
|
const uint8_t flash_clk_delay = 0;
|
||||||
|
|
||||||
|
// Yes, these values are (slightly) different to the ones in blisp_chip_bl808.c
|
||||||
|
const static struct bl808_spi_flash_cfg_t cfg = {
|
||||||
|
.ioMode = 0x04,
|
||||||
|
.cReadSupport = 0x01,
|
||||||
|
.clkDelay = 0,
|
||||||
|
.clkInvert = 0,
|
||||||
|
.resetEnCmd = 0x66,
|
||||||
|
.resetCmd = 0x99,
|
||||||
|
.resetCreadCmd = 0xff,
|
||||||
|
.resetCreadCmdSize = 0x03,
|
||||||
|
.jedecIdCmd = 0x9f,
|
||||||
|
.jedecIdCmdDmyClk = 0,
|
||||||
|
.enter32BitsAddrCmd = 0xb7,
|
||||||
|
.exit32BitsAddrCmd = 0xe9,
|
||||||
|
.sectorSize = 0x04,
|
||||||
|
.mid = 0xef,
|
||||||
|
.pageSize = 0x100,
|
||||||
|
.chipEraseCmd = 0xc7,
|
||||||
|
.sectorEraseCmd = 0x20,
|
||||||
|
.blk32EraseCmd = 0x52,
|
||||||
|
.blk64EraseCmd = 0xd8,
|
||||||
|
.writeEnableCmd = 0x06,
|
||||||
|
.pageProgramCmd = 0x02,
|
||||||
|
.qpageProgramCmd = 0x32,
|
||||||
|
.qppAddrMode = 0,
|
||||||
|
.fastReadCmd = 0x0b,
|
||||||
|
.frDmyClk = 0x01,
|
||||||
|
.qpiFastReadCmd = 0x0b,
|
||||||
|
.qpiFrDmyClk = 0x01,
|
||||||
|
.fastReadDoCmd = 0x3b,
|
||||||
|
.frDoDmyClk = 0x01,
|
||||||
|
.fastReadDioCmd = 0xbb,
|
||||||
|
.frDioDmyClk = 0,
|
||||||
|
.fastReadQoCmd = 0x6b,
|
||||||
|
.frQoDmyClk = 0x01,
|
||||||
|
.fastReadQioCmd = 0xeb,
|
||||||
|
.frQioDmyClk = 0x02,
|
||||||
|
.qpiFastReadQioCmd = 0xeb,
|
||||||
|
.qpiFrQioDmyClk = 0x02,
|
||||||
|
.qpiPageProgramCmd = 0x02,
|
||||||
|
.writeVregEnableCmd = 0x50,
|
||||||
|
.wrEnableIndex = 0,
|
||||||
|
.qeIndex = 0x01,
|
||||||
|
.busyIndex = 0,
|
||||||
|
.wrEnableBit = 0x01,
|
||||||
|
.qeBit = 0x01,
|
||||||
|
.busyBit = 0,
|
||||||
|
.wrEnableWriteRegLen = 0x02,
|
||||||
|
.wrEnableReadRegLen = 0x01,
|
||||||
|
.qeWriteRegLen = 0x01,
|
||||||
|
.qeReadRegLen = 0x01,
|
||||||
|
.releasePowerDown = 0xab,
|
||||||
|
.busyReadRegLen = 0x01,
|
||||||
|
.readRegCmd[0] = 0x05,
|
||||||
|
.readRegCmd[1] = 0x35,
|
||||||
|
.readRegCmd[2] = 0,
|
||||||
|
.readRegCmd[3] = 0,
|
||||||
|
.writeRegCmd[0] = 0x01,
|
||||||
|
.writeRegCmd[1] = 0x31,
|
||||||
|
.writeRegCmd[2] = 0,
|
||||||
|
.writeRegCmd[3] = 0,
|
||||||
|
.enterQpi = 0x38,
|
||||||
|
.exitQpi = 0xff,
|
||||||
|
.cReadMode = 0xa0,
|
||||||
|
.cRExit = 0xff,
|
||||||
|
.burstWrapCmd = 0x77,
|
||||||
|
.burstWrapCmdDmyClk = 0x03,
|
||||||
|
.burstWrapDataMode = 0x02,
|
||||||
|
.burstWrapData = 0x40,
|
||||||
|
.deBurstWrapCmd = 0x77,
|
||||||
|
.deBurstWrapCmdDmyClk = 0x03,
|
||||||
|
.deBurstWrapDataMode = 0x02,
|
||||||
|
.deBurstWrapData = 0xf0,
|
||||||
|
.timeEsector = 0x12c,
|
||||||
|
.timeE32k = 0x4b0,
|
||||||
|
.timeE64k = 0x4b0,
|
||||||
|
.timePagePgm = 0x05,
|
||||||
|
.timeCe = 0x80e8,
|
||||||
|
.pdDelay = 0x03,
|
||||||
|
.qeData = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t payload_size = 4 + sizeof(struct bl808_spi_flash_cfg_t);
|
||||||
|
uint8_t payload[payload_size] = {};
|
||||||
|
payload[0] = flash_pin;
|
||||||
|
payload[1] = flash_clk_cfg;
|
||||||
|
payload[2] = flash_io_mode;
|
||||||
|
payload[3] = flash_clk_delay;
|
||||||
|
memcpy(&payload[4], &cfg, sizeof(struct bl808_spi_flash_cfg_t));
|
||||||
|
|
||||||
|
blisp_return_t ret = blisp_send_command(device, 0x3b, payload, payload_size, true);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = blisp_receive_response(device, false);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return BLISP_OK;
|
||||||
|
}
|
||||||
|
@ -1,11 +1,231 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
/*
|
||||||
|
* Some parts of this source code belongs to Bouffalo Labs
|
||||||
|
* COPYRIGHT(c) 2020 Bouffalo Lab , License: Apache
|
||||||
|
*/
|
||||||
|
|
||||||
#include "blisp.h"
|
#include "blisp.h"
|
||||||
|
#include "blisp_struct.h"
|
||||||
|
#include "blisp_util.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
struct blisp_chip blisp_chip_bl808 = {
|
struct blisp_chip blisp_chip_bl808 = {
|
||||||
.type = BLISP_CHIP_BL808,
|
.type = BLISP_CHIP_BL808,
|
||||||
.type_str = "bl808",
|
.type_str = "bl808",
|
||||||
.usb_isp_available = true, // TODO: Only for BL808D :-(
|
.usb_isp_available = true, // TODO: Only for BL808D :-(
|
||||||
.default_xtal = "-", // ?
|
.default_xtal = "-", // XXX: bfl software marks this as "Auto (0x07)"
|
||||||
.handshake_byte_multiplier = 0.003f,
|
.handshake_byte_multiplier = 0.006f,
|
||||||
.get_eflash_loader = NULL
|
.load_eflash_loader = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bl808_bootheader_t bl808_header = {
|
||||||
|
.magiccode = 0x504e4642,
|
||||||
|
.rivison = 0x00000001,
|
||||||
|
/*flash config */
|
||||||
|
.flash_cfg.magiccode = 0x47464346,
|
||||||
|
.flash_cfg.cfg.ioMode = 0x11, /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */
|
||||||
|
.flash_cfg.cfg.cReadSupport = 0x00, /*!< Support continuous read mode,bit0:continuous read mode support,bit1:read mode cfg */
|
||||||
|
.flash_cfg.cfg.clkDelay = 0x01, /*!< SPI clock delay,bit0-3:delay,bit4-6:pad delay */
|
||||||
|
.flash_cfg.cfg.clkInvert = 0x01, /*!< SPI clock phase invert,bit0:clck invert,bit1:rx invert,bit2-4:pad delay,bit5-7:pad delay */
|
||||||
|
.flash_cfg.cfg.resetEnCmd = 0x66, /*!< Flash enable reset command */
|
||||||
|
.flash_cfg.cfg.resetCmd = 0x99, /*!< Flash reset command */
|
||||||
|
.flash_cfg.cfg.resetCreadCmd = 0xff, /*!< Flash reset continuous read command */
|
||||||
|
.flash_cfg.cfg.resetCreadCmdSize = 0x03, /*!< Flash reset continuous read command size */
|
||||||
|
.flash_cfg.cfg.jedecIdCmd = 0x9f, /*!< JEDEC ID command */
|
||||||
|
.flash_cfg.cfg.jedecIdCmdDmyClk = 0x00, /*!< JEDEC ID command dummy clock */
|
||||||
|
.flash_cfg.cfg.enter32BitsAddrCmd = 0xb7, /*!< Enter 32-bits addr command */
|
||||||
|
.flash_cfg.cfg.exit32BitsAddrCmd = 0xe9, /*!< Exit 32-bits addr command */
|
||||||
|
.flash_cfg.cfg.sectorSize = 0x04, /*!< *1024bytes */
|
||||||
|
.flash_cfg.cfg.mid = 0x00, /*!< Manufacturer ID */
|
||||||
|
.flash_cfg.cfg.pageSize = 0x100, /*!< Page size */
|
||||||
|
.flash_cfg.cfg.chipEraseCmd = 0xc7, /*!< Chip erase cmd */
|
||||||
|
.flash_cfg.cfg.sectorEraseCmd = 0x20, /*!< Sector erase command */
|
||||||
|
.flash_cfg.cfg.blk32EraseCmd = 0x52, /*!< Block 32K erase command,some Micron not support */
|
||||||
|
.flash_cfg.cfg.blk64EraseCmd = 0xd8, /*!< Block 64K erase command */
|
||||||
|
.flash_cfg.cfg.writeEnableCmd = 0x06, /*!< Need before every erase or program */
|
||||||
|
.flash_cfg.cfg.pageProgramCmd = 0x02, /*!< Page program cmd */
|
||||||
|
.flash_cfg.cfg.qpageProgramCmd = 0x32, /*!< QIO page program cmd */
|
||||||
|
.flash_cfg.cfg.qppAddrMode = 0x00, /*!< QIO page program address mode */
|
||||||
|
.flash_cfg.cfg.fastReadCmd = 0x0b, /*!< Fast read command */
|
||||||
|
.flash_cfg.cfg.frDmyClk = 0x01, /*!< Fast read command dummy clock */
|
||||||
|
.flash_cfg.cfg.qpiFastReadCmd = 0x0b, /*!< QPI fast read command */
|
||||||
|
.flash_cfg.cfg.qpiFrDmyClk = 0x01, /*!< QPI fast read command dummy clock */
|
||||||
|
.flash_cfg.cfg.fastReadDoCmd = 0x3b, /*!< Fast read dual output command */
|
||||||
|
.flash_cfg.cfg.frDoDmyClk = 0x01, /*!< Fast read dual output command dummy clock */
|
||||||
|
.flash_cfg.cfg.fastReadDioCmd = 0xbb, /*!< Fast read dual io comamnd */
|
||||||
|
.flash_cfg.cfg.frDioDmyClk = 0x00, /*!< Fast read dual io command dummy clock */
|
||||||
|
.flash_cfg.cfg.fastReadQoCmd = 0x6b, /*!< Fast read quad output comamnd */
|
||||||
|
.flash_cfg.cfg.frQoDmyClk = 0x01, /*!< Fast read quad output comamnd dummy clock */
|
||||||
|
.flash_cfg.cfg.fastReadQioCmd = 0xeb, /*!< Fast read quad io comamnd */
|
||||||
|
.flash_cfg.cfg.frQioDmyClk = 0x02, /*!< Fast read quad io comamnd dummy clock */
|
||||||
|
.flash_cfg.cfg.qpiFastReadQioCmd = 0xeb, /*!< QPI fast read quad io comamnd */
|
||||||
|
.flash_cfg.cfg.qpiFrQioDmyClk = 0x02, /*!< QPI fast read QIO dummy clock */
|
||||||
|
.flash_cfg.cfg.qpiPageProgramCmd = 0x02, /*!< QPI program command */
|
||||||
|
.flash_cfg.cfg.writeVregEnableCmd = 0x50, /*!< Enable write reg */
|
||||||
|
.flash_cfg.cfg.wrEnableIndex = 0x00, /*!< Write enable register index */
|
||||||
|
.flash_cfg.cfg.qeIndex = 0x01, /*!< Quad mode enable register index */
|
||||||
|
.flash_cfg.cfg.busyIndex = 0x00, /*!< Busy status register index */
|
||||||
|
.flash_cfg.cfg.wrEnableBit = 0x01, /*!< Write enable bit pos */
|
||||||
|
.flash_cfg.cfg.qeBit = 0x01, /*!< Quad enable bit pos */
|
||||||
|
.flash_cfg.cfg.busyBit = 0x00, /*!< Busy status bit pos */
|
||||||
|
.flash_cfg.cfg.wrEnableWriteRegLen = 0x02, /*!< Register length of write enable */
|
||||||
|
.flash_cfg.cfg.wrEnableReadRegLen = 0x01, /*!< Register length of write enable status */
|
||||||
|
.flash_cfg.cfg.qeWriteRegLen = 0x02, /*!< Register length of contain quad enable */
|
||||||
|
.flash_cfg.cfg.qeReadRegLen = 0x01, /*!< Register length of contain quad enable status */
|
||||||
|
.flash_cfg.cfg.releasePowerDown = 0xab, /*!< Release power down command */
|
||||||
|
.flash_cfg.cfg.busyReadRegLen = 0x01, /*!< Register length of contain busy status */
|
||||||
|
.flash_cfg.cfg.readRegCmd[0] = 0x05, /*!< Read register command buffer */
|
||||||
|
.flash_cfg.cfg.readRegCmd[1] = 0x35, /*!< Read register command buffer */
|
||||||
|
.flash_cfg.cfg.readRegCmd[2] = 0x00, /*!< Read register command buffer */
|
||||||
|
.flash_cfg.cfg.readRegCmd[3] = 0x00, /*!< Read register command buffer */
|
||||||
|
.flash_cfg.cfg.writeRegCmd[0] = 0x01, /*!< Write register command buffer */
|
||||||
|
.flash_cfg.cfg.writeRegCmd[1] = 0x01, /*!< Write register command buffer */
|
||||||
|
.flash_cfg.cfg.writeRegCmd[2] = 0x00, /*!< Write register command buffer */
|
||||||
|
.flash_cfg.cfg.writeRegCmd[3] = 0x00, /*!< Write register command buffer */
|
||||||
|
.flash_cfg.cfg.enterQpi = 0x38, /*!< Enter qpi command */
|
||||||
|
.flash_cfg.cfg.exitQpi = 0xff, /*!< Exit qpi command */
|
||||||
|
.flash_cfg.cfg.cReadMode = 0x20, /*!< Config data for continuous read mode */
|
||||||
|
.flash_cfg.cfg.cRExit = 0xf0, /*!< Config data for exit continuous read mode */
|
||||||
|
.flash_cfg.cfg.burstWrapCmd = 0x77, /*!< Enable burst wrap command */
|
||||||
|
.flash_cfg.cfg.burstWrapCmdDmyClk = 0x03, /*!< Enable burst wrap command dummy clock */
|
||||||
|
.flash_cfg.cfg.burstWrapDataMode = 0x02, /*!< Data and address mode for this command */
|
||||||
|
.flash_cfg.cfg.burstWrapData = 0x40, /*!< Data to enable burst wrap */
|
||||||
|
.flash_cfg.cfg.deBurstWrapCmd = 0x77, /*!< Disable burst wrap command */
|
||||||
|
.flash_cfg.cfg.deBurstWrapCmdDmyClk = 0x03, /*!< Disable burst wrap command dummy clock */
|
||||||
|
.flash_cfg.cfg.deBurstWrapDataMode = 0x02, /*!< Data and address mode for this command */
|
||||||
|
.flash_cfg.cfg.deBurstWrapData = 0xf0, /*!< Data to disable burst wrap */
|
||||||
|
.flash_cfg.cfg.timeEsector = 300, /*!< 4K erase time */
|
||||||
|
.flash_cfg.cfg.timeE32k = 1200, /*!< 32K erase time */
|
||||||
|
.flash_cfg.cfg.timeE64k = 1200, /*!< 64K erase time */
|
||||||
|
.flash_cfg.cfg.timePagePgm = 50, /*!< Page program time */
|
||||||
|
.flash_cfg.cfg.timeCe = 30000, /*!< Chip erase time in ms */
|
||||||
|
.flash_cfg.cfg.pdDelay = 20, /*!< Release power down command delay time for wake up */
|
||||||
|
.flash_cfg.cfg.qeData = 0, /*!< QE set data */
|
||||||
|
.flash_cfg.crc32 = 0xdeadbeef,
|
||||||
|
/* clock cfg */
|
||||||
|
.clk_cfg.magiccode = 0x47464350,
|
||||||
|
.clk_cfg.cfg.xtal_type = 0x07, /*!< 0:None,1:24M,2:32M,3:38.4M,4:40M,5:26M,6:RC32M */
|
||||||
|
.clk_cfg.cfg.mcu_clk = 0x04, /*!< mcu_clk 0:RC32M,1:Xtal,2:cpupll 400M,3:wifipll 192M,4:wifipll 320M */
|
||||||
|
.clk_cfg.cfg.mcu_clk_div = 0x00,
|
||||||
|
.clk_cfg.cfg.mcu_bclk_div = 0x00,
|
||||||
|
|
||||||
|
.clk_cfg.cfg.mcu_pbclk_div = 0x03,
|
||||||
|
.clk_cfg.cfg.lp_div = 0x01,
|
||||||
|
.clk_cfg.cfg.dsp_clk = 0x03, /* 0:RC32M,1:Xtal,2:wifipll 240M,3:wifipll 320M,4:cpupll 400M */
|
||||||
|
.clk_cfg.cfg.dsp_clk_div = 0x00,
|
||||||
|
|
||||||
|
.clk_cfg.cfg.dsp_bclk_div = 0x01,
|
||||||
|
.clk_cfg.cfg.dsp_pbclk = 0x02, /* 0:RC32M,1:Xtal,2:wifipll 160M,3:cpupll 160M,4:wifipll 240M */
|
||||||
|
.clk_cfg.cfg.dsp_pbclk_div = 0x00,
|
||||||
|
.clk_cfg.cfg.emi_clk = 0x02, /*!< 0:mcu pbclk,1:cpupll 200M,2:wifipll 320M,3:cpupll 400M */
|
||||||
|
|
||||||
|
.clk_cfg.cfg.emi_clk_div = 0x01,
|
||||||
|
.clk_cfg.cfg.flash_clk_type = 0x01, /*!< 0:wifipll 120M,1:xtal,2:cpupll 100M,3:wifipll 80M,4:bclk,5:wifipll 96M */
|
||||||
|
.clk_cfg.cfg.flash_clk_div = 0x00,
|
||||||
|
.clk_cfg.cfg.wifipll_pu = 0x01,
|
||||||
|
|
||||||
|
.clk_cfg.cfg.aupll_pu = 0x01,
|
||||||
|
.clk_cfg.cfg.cpupll_pu = 0x01,
|
||||||
|
.clk_cfg.cfg.mipipll_pu = 0x01,
|
||||||
|
.clk_cfg.cfg.uhspll_pu = 0x01,
|
||||||
|
|
||||||
|
.clk_cfg.crc32 = 0xdeadbeef,
|
||||||
|
|
||||||
|
/* basic cfg */
|
||||||
|
.basic_cfg.sign_type = 0x0, /* [1: 0] for sign */
|
||||||
|
.basic_cfg.encrypt_type = 0x0, /* [3: 2] for encrypt */
|
||||||
|
.basic_cfg.key_sel = 0x0, /* [5: 4] key slot */
|
||||||
|
.basic_cfg.xts_mode = 0x0, /* [6] for xts mode */
|
||||||
|
.basic_cfg.aes_region_lock = 0x0, /* [7] rsvd */
|
||||||
|
.basic_cfg.no_segment = 0x1, /* [8] no segment info */
|
||||||
|
.basic_cfg.rsvd_0 = 0x0, /* [9] boot2 enable(rsvd_0) */
|
||||||
|
.basic_cfg.rsvd_1 = 0x0, /* [10] boot2 rollback(rsvd_1) */
|
||||||
|
.basic_cfg.cpu_master_id = 0x0, /* [14: 11] master id */
|
||||||
|
.basic_cfg.notload_in_bootrom = 0x0, /* [15] notload in bootrom */
|
||||||
|
.basic_cfg.crc_ignore = 0x1, /* [16] ignore crc */
|
||||||
|
.basic_cfg.hash_ignore = 0x1, /* [17] hash ignore */
|
||||||
|
.basic_cfg.power_on_mm = 0x1, /* [18] power on mm */
|
||||||
|
.basic_cfg.em_sel = 0x1, /* [21: 19] em_sel */
|
||||||
|
.basic_cfg.cmds_en = 0x1, /* [22] command spliter enable */
|
||||||
|
#if 0
|
||||||
|
# 0 : cmds bypass wrap commands to macro, original mode;
|
||||||
|
# 1 : cmds handle wrap commands, original mode;
|
||||||
|
# 2 : cmds bypass wrap commands to macro, cmds force wrap16 * 4 splitted into two wrap8 * 4;
|
||||||
|
# 3 : cmds handle wrap commands, cmds force wrap16 * 4 splitted into two wrap8 * 4
|
||||||
|
#endif
|
||||||
|
.basic_cfg.cmds_wrap_mode = 0x1, /* [24: 23] cmds wrap mode */
|
||||||
|
#if 0
|
||||||
|
# 0 : SF_CTRL_WRAP_LEN_8, 1 : SF_CTRL_WRAP_LEN_16, 2 : SF_CTRL_WRAP_LEN_32,
|
||||||
|
# 3 : SF_CTRL_WRAP_LEN_64, 9 : SF_CTRL_WRAP_LEN_4096
|
||||||
|
#endif
|
||||||
|
.basic_cfg.cmds_wrap_len = 0x9, /* [28: 25] cmds wrap len */
|
||||||
|
.basic_cfg.icache_invalid = 0x1, /* [29] icache invalid */
|
||||||
|
.basic_cfg.dcache_invalid = 0x1, /* [30] dcache invalid */
|
||||||
|
.basic_cfg.rsvd_3 = 0x0, /* [31] rsvd_3 */
|
||||||
|
|
||||||
|
#ifdef BFLB_BOOT2
|
||||||
|
.basic_cfg.group_image_offset = 0x00002000, /* flash controller offset */
|
||||||
|
#else
|
||||||
|
.basic_cfg.group_image_offset = 0x00001000, /* flash controller offset */
|
||||||
|
#endif
|
||||||
|
.basic_cfg.aes_region_len = 0x00000000, /* aes region length */
|
||||||
|
|
||||||
|
.basic_cfg.img_len_cnt = 0x00010000, /* image length or segment count */
|
||||||
|
.basic_cfg.hash = { 0xdeadbeef }, /* hash of the image */
|
||||||
|
|
||||||
|
/* cpu cfg */
|
||||||
|
.cpu_cfg[0].config_enable = 0x01, /* coinfig this cpu */
|
||||||
|
.cpu_cfg[0].halt_cpu = 0x0, /* halt this cpu */
|
||||||
|
.cpu_cfg[0].cache_enable = 0x0, /* cache setting :only for BL Cache */
|
||||||
|
.cpu_cfg[0].cache_wa = 0x0, /* cache setting :only for BL Cache*/
|
||||||
|
.cpu_cfg[0].cache_wb = 0x0, /* cache setting :only for BL Cache*/
|
||||||
|
.cpu_cfg[0].cache_wt = 0x0, /* cache setting :only for BL Cache*/
|
||||||
|
.cpu_cfg[0].cache_way_dis = 0x0, /* cache setting :only for BL Cache*/
|
||||||
|
.cpu_cfg[0].rsvd = 0x0,
|
||||||
|
|
||||||
|
.cpu_cfg[0].cache_range_h = 0x00000000,
|
||||||
|
.cpu_cfg[0].cache_range_l = 0x00000000,
|
||||||
|
/* image_address_offset */
|
||||||
|
.cpu_cfg[0].image_address_offset = 0x0,
|
||||||
|
.cpu_cfg[0].rsvd0 = 0x58000000, /* rsvd0 */
|
||||||
|
.cpu_cfg[0].msp_val = 0x00000000, /* msp value */
|
||||||
|
|
||||||
|
/* cpu cfg */
|
||||||
|
.cpu_cfg[1].config_enable = 0x0, /* coinfig this cpu */
|
||||||
|
.cpu_cfg[1].halt_cpu = 0x0, /* halt this cpu */
|
||||||
|
.cpu_cfg[1].cache_enable = 0x0, /* cache setting :only for BL Cache */
|
||||||
|
.cpu_cfg[1].cache_wa = 0x0, /* cache setting :only for BL Cache*/
|
||||||
|
.cpu_cfg[1].cache_wb = 0x0, /* cache setting :only for BL Cache*/
|
||||||
|
.cpu_cfg[1].cache_wt = 0x0, /* cache setting :only for BL Cache*/
|
||||||
|
.cpu_cfg[1].cache_way_dis = 0x0, /* cache setting :only for BL Cache*/
|
||||||
|
.cpu_cfg[1].rsvd = 0x0,
|
||||||
|
|
||||||
|
.cpu_cfg[1].cache_range_h = 0x00000000,
|
||||||
|
.cpu_cfg[1].cache_range_l = 0x00000000,
|
||||||
|
/* image_address_offset */
|
||||||
|
.cpu_cfg[1].image_address_offset = 0x0,
|
||||||
|
.cpu_cfg[1].rsvd0 = 0x58000000, /* rsvd0 */
|
||||||
|
.cpu_cfg[1].msp_val = 0x00000000, /* msp value */
|
||||||
|
|
||||||
|
/* address of partition table 0 */ /* 4 */
|
||||||
|
.boot2_pt_table_0_rsvd = 0x00000000,
|
||||||
|
/* address of partition table 1 */ /* 4 */
|
||||||
|
.boot2_pt_table_1_rsvd = 0x00000000,
|
||||||
|
|
||||||
|
/* address of flashcfg table list */ /* 4 */
|
||||||
|
.flash_cfg_table_addr = 0x00000000,
|
||||||
|
/* flashcfg table list len */ /* 4 */
|
||||||
|
.flash_cfg_table_len = 0x00000000,
|
||||||
|
|
||||||
|
.rsvd1[0] = 0x20000320,
|
||||||
|
.rsvd1[1] = 0x00000000,
|
||||||
|
.rsvd1[2] = 0x2000F038,
|
||||||
|
.rsvd1[3] = 0x18000000,
|
||||||
|
|
||||||
|
.crc32 = 0xdeadbeef /* 4 */
|
||||||
|
};
|
||||||
|
|
||||||
|
void fill_crcs(struct bl808_bootheader_t *bh) {
|
||||||
|
bh->flash_cfg.crc32 = crc32_calculate((unsigned char *) &bh->flash_cfg.cfg, sizeof(struct bl808_spi_flash_cfg_t));
|
||||||
|
bh->clk_cfg.crc32 = crc32_calculate((unsigned char *) &bh->clk_cfg.cfg, sizeof(struct bl808_sys_clk_cfg_t));
|
||||||
|
bh->crc32 = crc32_calculate((unsigned char *) bh, sizeof(struct bl808_bootheader_t) - 4);
|
||||||
|
}
|
||||||
|
@ -51,7 +51,7 @@ blisp_return_t blisp_single_download() {
|
|||||||
printf("Erasing the area, this might take a while...\n");
|
printf("Erasing the area, this might take a while...\n");
|
||||||
ret = blisp_device_flash_erase(
|
ret = blisp_device_flash_erase(
|
||||||
&device, *single_download_location->ival,
|
&device, *single_download_location->ival,
|
||||||
*single_download_location->ival + data_file_size + 1);
|
*single_download_location->ival + data_file_size - 1);
|
||||||
if (ret != BLISP_OK) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to erase.\n");
|
fprintf(stderr, "Failed to erase.\n");
|
||||||
goto exit2;
|
goto exit2;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "blisp_easy.h"
|
#include "blisp_easy.h"
|
||||||
|
#include "blisp_util.h"
|
||||||
#include "error_codes.h"
|
#include "error_codes.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
@ -31,6 +32,8 @@ blisp_return_t blisp_common_init_device(struct blisp_device* device,
|
|||||||
chip = &blisp_chip_bl70x;
|
chip = &blisp_chip_bl70x;
|
||||||
} else if (strcmp(chip_type->sval[0], "bl60x") == 0) {
|
} else if (strcmp(chip_type->sval[0], "bl60x") == 0) {
|
||||||
chip = &blisp_chip_bl60x;
|
chip = &blisp_chip_bl60x;
|
||||||
|
} else if (strcmp(chip_type->sval[0], "bl808") == 0) {
|
||||||
|
chip = &blisp_chip_bl808;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Chip type is invalid.\n");
|
fprintf(stderr, "Chip type is invalid.\n");
|
||||||
return BLISP_ERR_INVALID_CHIP_TYPE;
|
return BLISP_ERR_INVALID_CHIP_TYPE;
|
||||||
@ -39,15 +42,17 @@ blisp_return_t blisp_common_init_device(struct blisp_device* device,
|
|||||||
blisp_return_t ret;
|
blisp_return_t ret;
|
||||||
ret = blisp_device_init(device, chip);
|
ret = blisp_device_init(device, chip);
|
||||||
if (ret != BLISP_OK) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to init device.\n");
|
fprintf(stderr, "Failed to init device, ret: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = blisp_device_open(device,
|
ret = blisp_device_open(device,
|
||||||
port_name->count == 1 ? port_name->sval[0] : NULL);
|
port_name->count == 1 ? port_name->sval[0] : NULL);
|
||||||
if (ret != BLISP_OK) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, ret == BLISP_ERR_DEVICE_NOT_FOUND
|
if (ret == BLISP_ERR_DEVICE_NOT_FOUND) {
|
||||||
? "Device not found\n"
|
fprintf(stderr, "Device not found\n");
|
||||||
: "Failed to open device.\n");
|
} else {
|
||||||
|
fprintf(stderr, "Failed to open device, ret: %d\n", ret);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,17 +69,20 @@ blisp_return_t blisp_common_prepare_flash(struct blisp_device* device) {
|
|||||||
printf("Sending a handshake...\n");
|
printf("Sending a handshake...\n");
|
||||||
ret = blisp_device_handshake(device, false);
|
ret = blisp_device_handshake(device, false);
|
||||||
if (ret != BLISP_OK) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to handshake with device.\n");
|
fprintf(stderr, "Failed to handshake with device, ret: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
printf("Handshake successful!\nGetting chip info...\n");
|
printf("Handshake successful!\nGetting chip info...\n");
|
||||||
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 != BLISP_OK) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to get boot info.\n");
|
fprintf(stderr, "Failed to get boot info, ret: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Do we want this to print in big endian to match the output
|
||||||
|
// of Bouffalo's software?
|
||||||
|
if (device->chip->type == BLISP_CHIP_BL70X) {
|
||||||
printf(
|
printf(
|
||||||
"BootROM version %d.%d.%d.%d, ChipID: "
|
"BootROM version %d.%d.%d.%d, ChipID: "
|
||||||
"%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
"%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||||
@ -83,6 +91,30 @@ blisp_return_t blisp_common_prepare_flash(struct blisp_device* device) {
|
|||||||
boot_info.chip_id[0], boot_info.chip_id[1], boot_info.chip_id[2],
|
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[3], boot_info.chip_id[4], boot_info.chip_id[5],
|
||||||
boot_info.chip_id[6], boot_info.chip_id[7]);
|
boot_info.chip_id[6], boot_info.chip_id[7]);
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"BootROM version %d.%d.%d.%d, ChipID: "
|
||||||
|
"%02X%02X%02X%02X%02X%02X\n",
|
||||||
|
boot_info.boot_rom_version[0], boot_info.boot_rom_version[1],
|
||||||
|
boot_info.boot_rom_version[2], boot_info.boot_rom_version[3],
|
||||||
|
boot_info.chip_id[0], boot_info.chip_id[1], boot_info.chip_id[2],
|
||||||
|
boot_info.chip_id[3], boot_info.chip_id[4], boot_info.chip_id[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->chip->type == BLISP_CHIP_BL808) {
|
||||||
|
printf("Setting clock parameters ...\n");
|
||||||
|
ret = bl808_load_clock_para(device, true, device->current_baud_rate);
|
||||||
|
if (ret != BLISP_OK) {
|
||||||
|
fprintf(stderr, "Failed to set clock parameters, ret: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
printf("Setting flash parameters...\n");
|
||||||
|
ret = bl808_load_flash_para(device);
|
||||||
|
if (ret != BLISP_OK) {
|
||||||
|
fprintf(stderr, "Failed to set flash parameters, ret: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (device->chip->load_eflash_loader == NULL) {
|
if (device->chip->load_eflash_loader == NULL) {
|
||||||
return BLISP_OK;
|
return BLISP_OK;
|
||||||
@ -119,20 +151,20 @@ blisp_return_t blisp_common_prepare_flash(struct blisp_device* device) {
|
|||||||
|
|
||||||
ret = blisp_device_check_image(device);
|
ret = blisp_device_check_image(device);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf(stderr, "Failed to check image.\n");
|
fprintf(stderr, "Failed to check image, ret: %d\n", ret);
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = blisp_device_run_image(device);
|
ret = blisp_device_run_image(device);
|
||||||
if (ret != BLISP_OK) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to run image.\n");
|
fprintf(stderr, "Failed to run image, ret: %d\n", ret);
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Sending a handshake...\n");
|
printf("Sending a handshake...\n");
|
||||||
ret = blisp_device_handshake(device, true);
|
ret = blisp_device_handshake(device, true);
|
||||||
if (ret != BLISP_OK) {
|
if (ret != BLISP_OK) {
|
||||||
fprintf(stderr, "Failed to handshake with device.\n");
|
fprintf(stderr, "Failed to handshake with device, ret: %d\n", ret);
|
||||||
goto exit1;
|
goto exit1;
|
||||||
}
|
}
|
||||||
printf("Handshake with eflash_loader successful.\n");
|
printf("Handshake with eflash_loader successful.\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user