diff --git a/.clang-format b/.clang-format index 740bda5..86a15bf 100644 --- a/.clang-format +++ b/.clang-format @@ -1,58 +1,4 @@ --- -Language: Cpp -BasedOnStyle: GNU -IndentWidth: 4 -AllowShortBlocksOnASingleLine: Empty -AllowShortFunctionsOnASingleLine: None -BreakBeforeBraces: Custom -BraceWrapping: - AfterFunction: false - AfterCaseLabel: false - AfterEnum: false - AfterControlStatement: Never - AfterStruct : false - AfterUnion : false - AfterExternBlock : false - BeforeElse : false - BeforeWhile : false -AlignAfterOpenBracket: Align -AlignArrayOfStructures: Left -AlignEscapedNewlines: Right -AlignOperands: Align -AllowShortEnumsOnASingleLine: False -AllowShortIfStatementsOnASingleLine: Never -AllowShortLoopsOnASingleLine : false -AlwaysBreakAfterReturnType: AllDefinitions -AlignTrailingComments : true -AlignConsecutiveMacros: AcrossEmptyLines -KeepEmptyLinesAtTheStartOfBlocks : false -PointerAlignment : Left -QualifierAlignment : Left -ReferenceAlignment : Left -RemoveBracesLLVM : false -SpaceAfterCStyleCast : false -SpaceAfterLogicalNot : false -SpaceAfterTemplateKeyword : false -SpaceAroundPointerQualifiers : Before -SpaceBeforeAssignmentOperators : true -SpaceBeforeCaseColon : false -SpaceBeforeCpp11BracedList : false -SpaceBeforeParens : ControlStatements -SpaceBeforeParensOptions : - AfterControlStatements : true - AfterFunctionDeclarationName : false - AfterFunctionDefinitionName : false - AfterOverloadedOperator : false -SpaceBeforeRangeBasedForLoopColon : false -SpaceBeforeSquareBrackets : false -SpaceInEmptyBlock : false -SpaceInEmptyParentheses : false -SpacesInCStyleCastParentheses : false -SpacesInConditionalStatement : false -SpacesInContainerLiterals : false -SpacesInParentheses: false -SpacesInSquareBrackets : false -UseTab : Never +BasedOnStyle: Chromium -BitFieldColonSpacing: None -BreakBeforeBinaryOperators: All \ No newline at end of file +... diff --git a/include/blisp.h b/include/blisp.h index eaa8ddd..c45c1a7 100644 --- a/include/blisp.h +++ b/include/blisp.h @@ -7,43 +7,56 @@ #include "blisp_chip.h" struct blisp_segment_header { - uint32_t dest_addr; - uint32_t length; - uint32_t reserved; - uint32_t crc32; + uint32_t dest_addr; + uint32_t length; + uint32_t reserved; + uint32_t crc32; }; struct blisp_device { - struct blisp_chip* chip; - void* serial_port; - bool is_usb; - uint32_t current_baud_rate; - uint8_t rx_buffer[5000]; // TODO: - uint8_t tx_buffer[5000]; - uint16_t error_code; + struct blisp_chip* chip; + void* serial_port; + bool is_usb; + uint32_t current_baud_rate; + uint8_t rx_buffer[5000]; // TODO: + uint8_t tx_buffer[5000]; + uint16_t error_code; }; struct blisp_boot_info { - uint8_t boot_rom_version[4]; - uint8_t chip_id[8]; // TODO: BL60X only 6 bytes + uint8_t boot_rom_version[4]; + 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_open(struct blisp_device* device, const char* port_name); int32_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader); -int32_t blisp_device_get_boot_info(struct blisp_device* device, struct blisp_boot_info* boot_info); -int32_t blisp_device_load_boot_header(struct blisp_device* device, uint8_t* boot_header); -int32_t blisp_device_load_segment_header(struct blisp_device* device, struct blisp_segment_header* segment_header); -int32_t blisp_device_load_segment_data(struct blisp_device* device, uint8_t* segment_data, uint32_t segment_data_length); +int32_t blisp_device_get_boot_info(struct blisp_device* device, + struct blisp_boot_info* boot_info); +int32_t blisp_device_load_boot_header(struct blisp_device* device, + uint8_t* boot_header); +int32_t blisp_device_load_segment_header( + struct blisp_device* device, + struct blisp_segment_header* segment_header); +int32_t blisp_device_load_segment_data(struct blisp_device* device, + uint8_t* segment_data, + uint32_t segment_data_length); int32_t blisp_device_write_memory(struct blisp_device* device, - uint32_t address, uint32_t value, + uint32_t address, + uint32_t value, bool wait_for_res); int32_t blisp_device_check_image(struct blisp_device* device); int32_t blisp_device_run_image(struct blisp_device* device); -int32_t blisp_device_flash_erase(struct blisp_device* device, uint32_t start_address, uint32_t end_address); -int32_t blisp_device_flash_write(struct blisp_device* device, uint32_t start_address, uint8_t* payload, uint32_t payload_size); +int32_t blisp_device_flash_erase(struct blisp_device* device, + uint32_t start_address, + uint32_t end_address); +int32_t blisp_device_flash_write(struct blisp_device* device, + uint32_t start_address, + uint8_t* payload, + uint32_t payload_size); int32_t blisp_device_program_check(struct blisp_device* device); int32_t blisp_device_reset(struct blisp_device* device); void blisp_device_close(struct blisp_device* device); diff --git a/include/blisp_chip.h b/include/blisp_chip.h index d3ff789..4b3672b 100644 --- a/include/blisp_chip.h +++ b/include/blisp_chip.h @@ -2,20 +2,17 @@ #ifndef _BLISP_CHIP_H #define _BLISP_CHIP_H -#include #include +#include -enum blisp_chip_type { - BLISP_CHIP_BL60X, - BLISP_CHIP_BL70X -}; +enum blisp_chip_type { BLISP_CHIP_BL60X, BLISP_CHIP_BL70X }; -struct blisp_chip { // TODO: Move elsewhere? - enum blisp_chip_type type; - const char* type_str; - bool usb_isp_available; - float handshake_byte_multiplier; - const char* default_eflash_loader_xtal; // TODO: Make this selectable +struct blisp_chip { // TODO: Move elsewhere? + enum blisp_chip_type type; + const char* type_str; + bool usb_isp_available; + float handshake_byte_multiplier; + const char* default_eflash_loader_xtal; // TODO: Make this selectable }; extern struct blisp_chip blisp_chip_bl60x; diff --git a/include/blisp_struct.h b/include/blisp_struct.h index 5130e2c..73694b9 100644 --- a/include/blisp_struct.h +++ b/include/blisp_struct.h @@ -6,167 +6,166 @@ #ifndef _LIBBLISP_STRUCT_H #define _LIBBLISP_STRUCT_H -#include #include +#include #pragma pack(push, 1) typedef struct { - uint8_t ioMode; /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */ - uint8_t cReadSupport; /*!< Support continuous read mode,bit0:continuous read mode support,bit1:read mode cfg */ - uint8_t clkDelay; /*!< SPI clock delay,bit0-3:delay,bit4-6:pad delay */ - uint8_t clkInvert; /*!< SPI clock phase invert,bit0:clck invert,bit1:rx invert,bit2-4:pad delay,bit5-7:pad delay */ - uint8_t resetEnCmd; /*!< Flash enable reset command */ - uint8_t resetCmd; /*!< Flash reset command */ - uint8_t resetCreadCmd; /*!< Flash reset continuous read command */ - uint8_t resetCreadCmdSize; /*!< Flash reset continuous read command size */ - uint8_t jedecIdCmd; /*!< JEDEC ID command */ - uint8_t jedecIdCmdDmyClk; /*!< JEDEC ID command dummy clock */ - uint8_t qpiJedecIdCmd; /*!< QPI JEDEC ID comamnd */ - uint8_t qpiJedecIdCmdDmyClk; /*!< QPI JEDEC ID command dummy clock */ - uint8_t sectorSize; /*!< *1024bytes */ - uint8_t mid; /*!< Manufacturer ID */ - uint16_t pageSize; /*!< Page size */ - uint8_t chipEraseCmd; /*!< Chip erase cmd */ - uint8_t sectorEraseCmd; /*!< Sector erase command */ - uint8_t blk32EraseCmd; /*!< Block 32K erase command,some Micron not support */ - uint8_t blk64EraseCmd; /*!< Block 64K erase command */ - uint8_t writeEnableCmd; /*!< Need before every erase or program */ - uint8_t pageProgramCmd; /*!< Page program cmd */ - uint8_t qpageProgramCmd; /*!< QIO page program cmd */ - uint8_t qppAddrMode; /*!< QIO page program address mode */ - uint8_t fastReadCmd; /*!< Fast read command */ - uint8_t frDmyClk; /*!< Fast read command dummy clock */ - uint8_t qpiFastReadCmd; /*!< QPI fast read command */ - uint8_t qpiFrDmyClk; /*!< QPI fast read command dummy clock */ - uint8_t fastReadDoCmd; /*!< Fast read dual output command */ - uint8_t frDoDmyClk; /*!< Fast read dual output command dummy clock */ - uint8_t fastReadDioCmd; /*!< Fast read dual io comamnd */ - uint8_t frDioDmyClk; /*!< Fast read dual io command dummy clock */ - uint8_t fastReadQoCmd; /*!< Fast read quad output comamnd */ - uint8_t frQoDmyClk; /*!< Fast read quad output comamnd dummy clock */ - uint8_t fastReadQioCmd; /*!< Fast read quad io comamnd */ - uint8_t frQioDmyClk; /*!< Fast read quad io comamnd dummy clock */ - uint8_t qpiFastReadQioCmd; /*!< QPI fast read quad io comamnd */ - uint8_t qpiFrQioDmyClk; /*!< QPI fast read QIO dummy clock */ - uint8_t qpiPageProgramCmd; /*!< QPI program command */ - uint8_t writeVregEnableCmd; /*!< Enable write reg */ - uint8_t wrEnableIndex; /*!< Write enable register index */ - uint8_t qeIndex; /*!< Quad mode enable register index */ - uint8_t busyIndex; /*!< Busy status register index */ - uint8_t wrEnableBit; /*!< Write enable bit pos */ - uint8_t qeBit; /*!< Quad enable bit pos */ - uint8_t busyBit; /*!< Busy status bit pos */ - uint8_t wrEnableWriteRegLen; /*!< Register length of write enable */ - uint8_t wrEnableReadRegLen; /*!< Register length of write enable status */ - uint8_t qeWriteRegLen; /*!< Register length of contain quad enable */ - uint8_t qeReadRegLen; /*!< Register length of contain quad enable status */ - uint8_t releasePowerDown; /*!< Release power down command */ - uint8_t busyReadRegLen; /*!< Register length of contain busy status */ - uint8_t readRegCmd[4]; /*!< Read register command buffer */ - uint8_t writeRegCmd[4]; /*!< Write register command buffer */ - uint8_t enterQpi; /*!< Enter qpi command */ - uint8_t exitQpi; /*!< Exit qpi command */ - uint8_t cReadMode; /*!< Config data for continuous read mode */ - uint8_t cRExit; /*!< Config data for exit continuous read mode */ - uint8_t burstWrapCmd; /*!< Enable burst wrap command */ - uint8_t burstWrapCmdDmyClk; /*!< Enable burst wrap command dummy clock */ - uint8_t burstWrapDataMode; /*!< Data and address mode for this command */ - uint8_t burstWrapData; /*!< Data to enable burst wrap */ - uint8_t deBurstWrapCmd; /*!< Disable burst wrap command */ - uint8_t deBurstWrapCmdDmyClk; /*!< Disable burst wrap command dummy clock */ - uint8_t deBurstWrapDataMode; /*!< Data and address mode for this command */ - uint8_t deBurstWrapData; /*!< Data to disable burst wrap */ - uint16_t timeEsector; /*!< 4K erase time */ - uint16_t timeE32k; /*!< 32K erase time */ - uint16_t timeE64k; /*!< 64K erase time */ - uint16_t timePagePgm; /*!< Page program time */ - uint16_t timeCe; /*!< Chip erase time in ms */ - uint8_t pdDelay; /*!< Release power down command delay time for wake up */ - uint8_t qeData; /*!< QE set data */ + uint8_t ioMode; /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap */ + uint8_t cReadSupport; /*!< Support continuous read mode,bit0:continuous read + mode support,bit1:read mode cfg */ + uint8_t clkDelay; /*!< SPI clock delay,bit0-3:delay,bit4-6:pad delay */ + uint8_t clkInvert; /*!< SPI clock phase invert,bit0:clck invert,bit1:rx + invert,bit2-4:pad delay,bit5-7:pad delay */ + uint8_t resetEnCmd; /*!< Flash enable reset command */ + uint8_t resetCmd; /*!< Flash reset command */ + uint8_t resetCreadCmd; /*!< Flash reset continuous read command */ + uint8_t resetCreadCmdSize; /*!< Flash reset continuous read command size */ + uint8_t jedecIdCmd; /*!< JEDEC ID command */ + uint8_t jedecIdCmdDmyClk; /*!< JEDEC ID command dummy clock */ + uint8_t qpiJedecIdCmd; /*!< QPI JEDEC ID comamnd */ + uint8_t qpiJedecIdCmdDmyClk; /*!< QPI JEDEC ID command dummy clock */ + uint8_t sectorSize; /*!< *1024bytes */ + uint8_t mid; /*!< Manufacturer ID */ + uint16_t pageSize; /*!< Page size */ + uint8_t chipEraseCmd; /*!< Chip erase cmd */ + uint8_t sectorEraseCmd; /*!< Sector erase command */ + uint8_t blk32EraseCmd; /*!< Block 32K erase command,some Micron not support */ + uint8_t blk64EraseCmd; /*!< Block 64K erase command */ + uint8_t writeEnableCmd; /*!< Need before every erase or program */ + uint8_t pageProgramCmd; /*!< Page program cmd */ + uint8_t qpageProgramCmd; /*!< QIO page program cmd */ + uint8_t qppAddrMode; /*!< QIO page program address mode */ + uint8_t fastReadCmd; /*!< Fast read command */ + uint8_t frDmyClk; /*!< Fast read command dummy clock */ + uint8_t qpiFastReadCmd; /*!< QPI fast read command */ + uint8_t qpiFrDmyClk; /*!< QPI fast read command dummy clock */ + uint8_t fastReadDoCmd; /*!< Fast read dual output command */ + uint8_t frDoDmyClk; /*!< Fast read dual output command dummy clock */ + uint8_t fastReadDioCmd; /*!< Fast read dual io comamnd */ + uint8_t frDioDmyClk; /*!< Fast read dual io command dummy clock */ + uint8_t fastReadQoCmd; /*!< Fast read quad output comamnd */ + uint8_t frQoDmyClk; /*!< Fast read quad output comamnd dummy clock */ + uint8_t fastReadQioCmd; /*!< Fast read quad io comamnd */ + uint8_t frQioDmyClk; /*!< Fast read quad io comamnd dummy clock */ + uint8_t qpiFastReadQioCmd; /*!< QPI fast read quad io comamnd */ + uint8_t qpiFrQioDmyClk; /*!< QPI fast read QIO dummy clock */ + uint8_t qpiPageProgramCmd; /*!< QPI program command */ + uint8_t writeVregEnableCmd; /*!< Enable write reg */ + uint8_t wrEnableIndex; /*!< Write enable register index */ + uint8_t qeIndex; /*!< Quad mode enable register index */ + uint8_t busyIndex; /*!< Busy status register index */ + uint8_t wrEnableBit; /*!< Write enable bit pos */ + uint8_t qeBit; /*!< Quad enable bit pos */ + uint8_t busyBit; /*!< Busy status bit pos */ + uint8_t wrEnableWriteRegLen; /*!< Register length of write enable */ + uint8_t wrEnableReadRegLen; /*!< Register length of write enable status */ + uint8_t qeWriteRegLen; /*!< Register length of contain quad enable */ + uint8_t qeReadRegLen; /*!< Register length of contain quad enable status */ + uint8_t releasePowerDown; /*!< Release power down command */ + uint8_t busyReadRegLen; /*!< Register length of contain busy status */ + uint8_t readRegCmd[4]; /*!< Read register command buffer */ + uint8_t writeRegCmd[4]; /*!< Write register command buffer */ + uint8_t enterQpi; /*!< Enter qpi command */ + uint8_t exitQpi; /*!< Exit qpi command */ + uint8_t cReadMode; /*!< Config data for continuous read mode */ + uint8_t cRExit; /*!< Config data for exit continuous read mode */ + uint8_t burstWrapCmd; /*!< Enable burst wrap command */ + uint8_t burstWrapCmdDmyClk; /*!< Enable burst wrap command dummy clock */ + uint8_t burstWrapDataMode; /*!< Data and address mode for this command */ + uint8_t burstWrapData; /*!< Data to enable burst wrap */ + uint8_t deBurstWrapCmd; /*!< Disable burst wrap command */ + uint8_t deBurstWrapCmdDmyClk; /*!< Disable burst wrap command dummy clock */ + uint8_t deBurstWrapDataMode; /*!< Data and address mode for this command */ + uint8_t deBurstWrapData; /*!< Data to disable burst wrap */ + uint16_t timeEsector; /*!< 4K erase time */ + uint16_t timeE32k; /*!< 32K erase time */ + uint16_t timeE64k; /*!< 64K erase time */ + uint16_t timePagePgm; /*!< Page program time */ + uint16_t timeCe; /*!< Chip erase time in ms */ + uint8_t pdDelay; /*!< Release power down command delay time for wake up */ + uint8_t qeData; /*!< QE set data */ } SPI_Flash_Cfg_Type; #define BFLB_BOOTROM_HASH_SIZE 256 / 8 -struct boot_flash_cfg_t -{ - char magiccode[4]; /*'FCFG'*/ - SPI_Flash_Cfg_Type cfg; - uint32_t crc32; +struct boot_flash_cfg_t { + char magiccode[4]; /*'FCFG'*/ + SPI_Flash_Cfg_Type cfg; + uint32_t crc32; }; -struct sys_clk_cfg_t -{ - uint8_t xtal_type; - uint8_t pll_clk; - uint8_t hclk_div; - uint8_t bclk_div; +struct sys_clk_cfg_t { + uint8_t xtal_type; + uint8_t pll_clk; + uint8_t hclk_div; + uint8_t bclk_div; - uint8_t flash_clk_type; - uint8_t flash_clk_div; - uint8_t rsvd[2]; + uint8_t flash_clk_type; + uint8_t flash_clk_div; + uint8_t rsvd[2]; }; -struct boot_clk_cfg_t -{ - char magiccode[4]; /*'PCFG'*/ - struct sys_clk_cfg_t cfg; - uint32_t crc32; +struct boot_clk_cfg_t { + char magiccode[4]; /*'PCFG'*/ + struct sys_clk_cfg_t cfg; + uint32_t crc32; }; -struct bfl_boot_header -{ - char magiccode[4]; /*'BFXP'*/ - uint32_t revison; - struct boot_flash_cfg_t flashCfg; - struct boot_clk_cfg_t clkCfg; - union { - struct { - uint32_t sign : 2; /* [1: 0] for sign*/ - uint32_t encrypt_type : 2; /* [3: 2] for encrypt */ - uint32_t key_sel : 2; /* [5: 4] for key sel in boot interface*/ - uint32_t rsvd6_7 : 2; /* [7: 6] for encrypt*/ - uint32_t no_segment : 1; /* [8] no segment info */ - uint32_t cache_enable : 1; /* [9] for cache */ - uint32_t notload_in_bootrom : 1; /* [10] not load this img in bootrom */ - uint32_t aes_region_lock : 1; /* [11] aes region lock */ - uint32_t cache_way_disable : 4; /* [15: 12] cache way disable info*/ - uint32_t crc_ignore : 1; /* [16] ignore crc */ - uint32_t hash_ignore : 1; /* [17] hash crc */ - uint32_t halt_ap : 1; /* [18] halt ap */ - uint32_t rsvd19_31 : 13; /* [31:19] rsvd */ - } bval; - uint32_t wval; - }bootcfg ; +struct bfl_boot_header { + char magiccode[4]; /*'BFXP'*/ + uint32_t revison; + struct boot_flash_cfg_t flashCfg; + struct boot_clk_cfg_t clkCfg; + union { + struct { + uint32_t sign : 2; /* [1: 0] for sign*/ + uint32_t encrypt_type : 2; /* [3: 2] for encrypt */ + uint32_t key_sel : 2; /* [5: 4] for key sel in boot interface*/ + uint32_t rsvd6_7 : 2; /* [7: 6] for encrypt*/ + uint32_t no_segment : 1; /* [8] no segment info */ + uint32_t cache_enable : 1; /* [9] for cache */ + uint32_t + notload_in_bootrom : 1; /* [10] not load this img in bootrom */ + uint32_t aes_region_lock : 1; /* [11] aes region lock */ + uint32_t cache_way_disable : 4; /* [15: 12] cache way disable info*/ + uint32_t crc_ignore : 1; /* [16] ignore crc */ + uint32_t hash_ignore : 1; /* [17] hash crc */ + uint32_t halt_ap : 1; /* [18] halt ap */ + uint32_t rsvd19_31 : 13; /* [31:19] rsvd */ + } bval; + uint32_t wval; + } bootcfg; - union { - uint32_t segment_cnt; - uint32_t img_length; - }segment_info; + union { + uint32_t segment_cnt; + uint32_t img_length; + } segment_info; - uint32_t bootentry; /* entry point of the image*/ + uint32_t bootentry; /* entry point of the image*/ - uint32_t flashoffset; + uint32_t flashoffset; - uint8_t hash[BFLB_BOOTROM_HASH_SIZE]; /*hash of the image*/ + uint8_t hash[BFLB_BOOTROM_HASH_SIZE]; /*hash of the image*/ - uint32_t rsv1; - uint32_t rsv2; - uint32_t crc32; + uint32_t rsv1; + uint32_t rsv2; + 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 -{ - uint32_t destaddr; - uint32_t len; - uint32_t rsvd; - uint32_t crc32; +struct blflash_segment_header { + uint32_t destaddr; + uint32_t len; + uint32_t rsvd; + uint32_t crc32; }; -static_assert(sizeof(struct blflash_segment_header) == 16, "Segment header have wrong size"); - +static_assert(sizeof(struct blflash_segment_header) == 16, + "Segment header have wrong size"); #pragma pack(pop) diff --git a/include/blisp_util.h b/include/blisp_util.h index dd7bbcb..701041b 100644 --- a/include/blisp_util.h +++ b/include/blisp_util.h @@ -8,14 +8,14 @@ #include #endif -static void sleep_ms(int milliseconds){ +static void sleep_ms(int milliseconds) { #ifdef WIN32 - Sleep(milliseconds); + Sleep(milliseconds); #else - struct timespec ts; - ts.tv_sec = milliseconds / 1000; - ts.tv_nsec = (milliseconds % 1000) * 1000000; - nanosleep(&ts, NULL); + struct timespec ts; + ts.tv_sec = milliseconds / 1000; + ts.tv_nsec = (milliseconds % 1000) * 1000000; + nanosleep(&ts, NULL); #endif } diff --git a/lib/blisp.c b/lib/blisp.c index 5503841..0994bb7 100644 --- a/lib/blisp.c +++ b/lib/blisp.c @@ -2,8 +2,8 @@ #include #include #include -#include #include +#include #include #ifdef __linux__ @@ -13,68 +13,67 @@ #define DEBUG -int32_t blisp_device_init(struct blisp_device* device, struct blisp_chip* chip) -{ - device->chip = chip; - device->is_usb = false; - return 0; +int32_t blisp_device_init(struct blisp_device* device, + struct blisp_chip* chip) { + device->chip = chip; + device->is_usb = false; + return 0; } -int32_t blisp_device_open(struct blisp_device* device, const char* port_name) -{ - int ret; - struct sp_port* serial_port = NULL; +int32_t blisp_device_open(struct blisp_device* device, const char* port_name) { + int ret; + struct sp_port* serial_port = NULL; - if (port_name != NULL) { - ret = sp_get_port_by_name(port_name, &serial_port); - if (ret != SP_OK) { - return -1; // TODO: Improve error codes - } - } else { - if (!device->chip->usb_isp_available) { - return -2; // Can't auto-find device due it doesn't have native USB - } - struct sp_port **port_list; - ret = sp_list_ports(&port_list); - if (ret != SP_OK) { - return -1; // TODO: Improve error codes - } - for (int i = 0; port_list[i] != NULL; i++) { - struct sp_port *port = port_list[i]; - - int vid, pid; - sp_get_port_usb_vid_pid(port, &vid, &pid); - if (vid == 0xFFFF && pid == 0xFFFF) { - ret = sp_get_port_by_name(sp_get_port_name(port), &serial_port); - if (ret != SP_OK) { - return -1; // TODO: Improve error codes - } - break; - } - } - sp_free_port_list(port_list); - if (serial_port == NULL) { - return -3; // Device not found - } + if (port_name != NULL) { + ret = sp_get_port_by_name(port_name, &serial_port); + if (ret != SP_OK) { + return -1; // TODO: Improve error codes } - - ret = sp_open(serial_port, SP_MODE_READ_WRITE); - if (ret != SP_OK) { // TODO: Handle not found - return -1; + } else { + if (!device->chip->usb_isp_available) { + return -2; // Can't auto-find device due it doesn't have native USB } - sp_set_bits(serial_port, 8); - sp_set_parity(serial_port, SP_PARITY_NONE); - sp_set_stopbits(serial_port, 1); - sp_set_flowcontrol(serial_port, SP_FLOWCONTROL_NONE); + struct sp_port** port_list; + ret = sp_list_ports(&port_list); + if (ret != SP_OK) { + return -1; // TODO: Improve error codes + } + for (int i = 0; port_list[i] != NULL; i++) { + struct sp_port* port = port_list[i]; - uint32_t vid, pid; - sp_get_port_usb_vid_pid(serial_port, &vid, &pid); - device->is_usb = pid == 0xFFFF; -// if (device->is_usb) { -// device->current_baud_rate = 2000000; -// } else { - device->current_baud_rate = 500000; -// } + int vid, pid; + sp_get_port_usb_vid_pid(port, &vid, &pid); + if (vid == 0xFFFF && pid == 0xFFFF) { + ret = sp_get_port_by_name(sp_get_port_name(port), &serial_port); + if (ret != SP_OK) { + return -1; // TODO: Improve error codes + } + break; + } + } + sp_free_port_list(port_list); + if (serial_port == NULL) { + return -3; // Device not found + } + } + + ret = sp_open(serial_port, SP_MODE_READ_WRITE); + if (ret != SP_OK) { // TODO: Handle not found + return -1; + } + sp_set_bits(serial_port, 8); + sp_set_parity(serial_port, SP_PARITY_NONE); + sp_set_stopbits(serial_port, 1); + sp_set_flowcontrol(serial_port, SP_FLOWCONTROL_NONE); + + uint32_t vid, pid; + sp_get_port_usb_vid_pid(serial_port, &vid, &pid); + device->is_usb = pid == 0xFFFF; + // if (device->is_usb) { + // device->current_baud_rate = 2000000; + // } else { + device->current_baud_rate = 500000; + // } #if 0 int fd; @@ -85,279 +84,311 @@ int32_t blisp_device_open(struct blisp_device* device, const char* port_name) serial.flags |= ASYNC_LOW_LATENCY; ioctl(fd, TIOCSSERIAL, &serial); #endif - ret = sp_set_baudrate(serial_port, device->current_baud_rate); - if (ret != SP_OK) { - return -1; // TODO: Handle this - } - device->serial_port = serial_port; + ret = sp_set_baudrate(serial_port, device->current_baud_rate); + if (ret != SP_OK) { + return -1; // TODO: Handle this + } + device->serial_port = serial_port; - return 0; + return 0; } -int32_t blisp_send_command(struct blisp_device* device, uint8_t command, void* payload, uint16_t payload_size, bool add_checksum) -{ - int ret; - struct sp_port* serial_port = device->serial_port; +int32_t blisp_send_command(struct blisp_device* device, + uint8_t command, + void* payload, + uint16_t payload_size, + bool add_checksum) { + int ret; + struct sp_port* serial_port = device->serial_port; - device->tx_buffer[0] = command; - device->tx_buffer[1] = 0; - device->tx_buffer[2] = payload_size & 0xFF; - device->tx_buffer[3] = (payload_size >> 8) & 0xFF; - if (add_checksum) { - uint32_t checksum = 0; - checksum += device->tx_buffer[2] + device->tx_buffer[3]; - for (uint16_t i = 0; i < payload_size; i++) { - checksum += *(uint8_t*)((uint8_t*)payload + i); - } - device->tx_buffer[1] = checksum & 0xFF; + device->tx_buffer[0] = command; + device->tx_buffer[1] = 0; + device->tx_buffer[2] = payload_size & 0xFF; + device->tx_buffer[3] = (payload_size >> 8) & 0xFF; + if (add_checksum) { + uint32_t checksum = 0; + checksum += device->tx_buffer[2] + device->tx_buffer[3]; + for (uint16_t i = 0; i < payload_size; i++) { + checksum += *(uint8_t*)((uint8_t*)payload + i); } - if (payload_size != 0) { - memcpy(&device->tx_buffer[4], payload, payload_size); - } - ret = sp_blocking_write(serial_port, device->tx_buffer, 4 + payload_size, 1000); - if (ret != (4 + payload_size)) { - return -1; - } - return 0; -} - -int32_t blisp_receive_response(struct blisp_device* device, bool expect_payload) { - // TODO: Check checksum - int ret; - struct sp_port* serial_port = device->serial_port; - ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 1000); - if (ret < 2) { -#ifdef DEBUG - fprintf(stderr, "Failed to receive response. (ret = %d)\n", ret); -#endif - return -1; // TODO: Terrible - } else if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') { - if (expect_payload) { - sp_blocking_read(serial_port, &device->rx_buffer[2], 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); - return data_length; - } - return 0; - } else if (device->rx_buffer[0] == 'P' && device->rx_buffer[1] == 'D') { - return -3; // TODO: Terrible - } else if (device->rx_buffer[0] == 'F' && device->rx_buffer[1] == 'L') { - sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100); - device->error_code = (device->rx_buffer[3] << 8) | (device->rx_buffer[2]); - return -4; // Failed - } -#ifdef DEBUG - fprintf(stderr, "Receive response failed... (err: %d, %d - %d)\n", ret, device->rx_buffer[0], device->rx_buffer[1]); -#endif + device->tx_buffer[1] = checksum & 0xFF; + } + if (payload_size != 0) { + memcpy(&device->tx_buffer[4], payload, payload_size); + } + ret = + sp_blocking_write(serial_port, device->tx_buffer, 4 + payload_size, 1000); + if (ret != (4 + payload_size)) { return -1; + } + return 0; } -int32_t -blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) { - int ret; - uint8_t handshake_buffer[600]; - struct sp_port* serial_port = device->serial_port; +int32_t blisp_receive_response(struct blisp_device* device, + bool expect_payload) { + // TODO: Check checksum + int ret; + struct sp_port* serial_port = device->serial_port; + ret = sp_blocking_read(serial_port, &device->rx_buffer[0], 2, 1000); + if (ret < 2) { +#ifdef DEBUG + fprintf(stderr, "Failed to receive response. (ret = %d)\n", ret); +#endif + return -1; // TODO: Terrible + } else if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') { + if (expect_payload) { + sp_blocking_read(serial_port, &device->rx_buffer[2], 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); + return data_length; + } + return 0; + } else if (device->rx_buffer[0] == 'P' && device->rx_buffer[1] == 'D') { + return -3; // TODO: Terrible + } else if (device->rx_buffer[0] == 'F' && device->rx_buffer[1] == 'L') { + sp_blocking_read(serial_port, &device->rx_buffer[2], 2, 100); + device->error_code = (device->rx_buffer[3] << 8) | (device->rx_buffer[2]); + return -4; // Failed + } +#ifdef DEBUG + fprintf(stderr, "Receive response failed... (err: %d, %d - %d)\n", ret, + device->rx_buffer[0], device->rx_buffer[1]); +#endif + return -1; +} + +int32_t blisp_device_handshake(struct blisp_device* device, bool in_ef_loader) { + int ret; + uint8_t handshake_buffer[600]; + struct sp_port* serial_port = device->serial_port; + + if (!in_ef_loader && !device->is_usb) { + sp_set_rts(serial_port, SP_RTS_ON); + sp_set_dtr(serial_port, SP_DTR_ON); + sleep_ms(50); + sp_set_dtr(serial_port, SP_DTR_OFF); + sleep_ms(100); + sp_set_rts(serial_port, SP_RTS_OFF); + sleep_ms(50); // Wait a bit so BootROM can init + } + + uint32_t bytes_count = device->chip->handshake_byte_multiplier * + (float)device->current_baud_rate / 10.0f; + if (bytes_count > 600) + bytes_count = 600; + memset(handshake_buffer, 'U', bytes_count); + + for (uint8_t i = 0; i < 5; i++) { + if (!in_ef_loader) { + if (device->is_usb) { + sp_blocking_write(serial_port, "BOUFFALOLAB5555RESET\0\0", 22, 100); + } + } + ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count, 500); + if (ret < 0) { + return -1; + } if (!in_ef_loader && !device->is_usb) { - sp_set_rts(serial_port, SP_RTS_ON); - sp_set_dtr(serial_port, SP_DTR_ON); - sleep_ms(50); - sp_set_dtr(serial_port, SP_DTR_OFF); - sleep_ms(100); - sp_set_rts(serial_port, SP_RTS_OFF); - sleep_ms(50); // Wait a bit so BootROM can init + sp_drain(serial_port); // Wait for write to send all data + sp_flush(serial_port, SP_BUF_INPUT); // Flush garbage out of RX } - uint32_t bytes_count = device->chip->handshake_byte_multiplier * (float)device->current_baud_rate / 10.0f; - if (bytes_count > 600) bytes_count = 600; - memset(handshake_buffer, 'U', bytes_count); - - for (uint8_t i = 0; i < 5; i++) { - if (!in_ef_loader) { - if (device->is_usb) { - sp_blocking_write(serial_port, "BOUFFALOLAB5555RESET\0\0", 22, - 100); - } - } - ret = sp_blocking_write(serial_port, handshake_buffer, bytes_count, - 500); - if (ret < 0) { - return -1; - } - - if (!in_ef_loader && !device->is_usb) { - sp_drain(serial_port); // Wait for write to send all data - sp_flush(serial_port, SP_BUF_INPUT); // Flush garbage out of RX - } - - ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 50); - if (ret >= 2) { - if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') { - return 0; - } - } + ret = sp_blocking_read(serial_port, device->rx_buffer, 2, 50); + if (ret >= 2) { + if (device->rx_buffer[0] == 'O' && device->rx_buffer[1] == 'K') { + return 0; + } } - return -4; // didn't received response + } + return -4; // didn't received response } -int32_t blisp_device_get_boot_info(struct blisp_device* device, struct blisp_boot_info* boot_info) -{ - int ret; +int32_t blisp_device_get_boot_info(struct blisp_device* device, + struct blisp_boot_info* boot_info) { + int ret; - ret = blisp_send_command(device, 0x10, NULL, 0, false); - if (ret < 0) return ret; + ret = blisp_send_command(device, 0x10, NULL, 0, false); + if (ret < 0) + return ret; - ret = blisp_receive_response(device, true); - if (ret < 0) return ret; + ret = blisp_receive_response(device, true); + if (ret < 0) + return ret; - memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], 4); // TODO: Endianess - if (device->chip->type == BLISP_CHIP_BL70X) { - memcpy(boot_info->chip_id, &device->rx_buffer[16], 8); - } - // TODO: BL60X - return 0; + memcpy(boot_info->boot_rom_version, &device->rx_buffer[0], + 4); // TODO: Endianess + if (device->chip->type == BLISP_CHIP_BL70X) { + memcpy(boot_info->chip_id, &device->rx_buffer[16], 8); + } + // TODO: BL60X + return 0; } // TODO: Use struct instead of uint8_t* -int32_t blisp_device_load_boot_header(struct blisp_device* device, uint8_t* boot_header) -{ - int ret; - ret = blisp_send_command(device, 0x11, boot_header, 176, false); - if (ret < 0) return ret; - ret = blisp_receive_response(device, false); - if (ret < 0) return ret; - - return 0; -} - -int32_t blisp_device_load_segment_header(struct blisp_device* device, struct blisp_segment_header* segment_header) -{ - int ret; - ret = blisp_send_command(device, 0x17, segment_header, 16, false); - if (ret < 0) return ret; - ret = blisp_receive_response(device, true); // TODO: Handle response - if (ret < 0) return ret; - - return 0; -} - -int32_t blisp_device_load_segment_data(struct blisp_device* device, uint8_t* segment_data, uint32_t segment_data_length) -{ - int ret; - ret = blisp_send_command(device, 0x18, segment_data, segment_data_length, false); - if (ret < 0) return ret; - ret = blisp_receive_response(device, false); - if (ret < 0) return ret; - - return 0; -} - -int32_t blisp_device_check_image(struct blisp_device* device) -{ - int ret; - ret = blisp_send_command(device, 0x19, NULL, 0, false); - if (ret < 0) return ret; - ret = blisp_receive_response(device, false); - if (ret < 0) return ret; - - return 0; -} - -int32_t -blisp_device_write_memory(struct blisp_device* device, uint32_t address, - uint32_t value, bool wait_for_res) { - int ret; - uint8_t payload[8]; - *(uint32_t*)(payload) = address; - *(uint32_t*)(payload + 4) = value; // TODO: Endianness - ret = blisp_send_command(device, 0x50, payload, 8, true); - if (ret < 0) return ret; - if (wait_for_res) { - ret = blisp_receive_response(device, false); - if (ret < 0) return ret; - } - - return 0; -} - -int32_t blisp_device_run_image(struct blisp_device* device) -{ - int ret; - - if (device->chip->type == BLISP_CHIP_BL70X) { // ERRATA - ret = blisp_device_write_memory(device, 0x4000F100, 0x4E424845, true); - if (ret < 0) return ret; - ret = blisp_device_write_memory(device, 0x4000F104, 0x22010000, true); - if (ret < 0) return ret; -// ret = blisp_device_write_memory(device, 0x40000018, 0x00000000); -// if (ret < 0) return ret; - ret = blisp_device_write_memory(device, 0x40000018, 0x00000002, false); - if (ret < 0) return ret; - return 0; - } - - ret = blisp_send_command(device, 0x1A, NULL, 0, false); - if (ret < 0) return ret; - ret = blisp_receive_response(device, false); - if (ret < 0) return ret; - - return 0; -} - -int32_t -blisp_device_flash_erase(struct blisp_device* device, uint32_t start_address, uint32_t end_address) -{ - uint8_t payload[8]; - *(uint32_t*)(payload + 0) = start_address; - *(uint32_t*)(payload + 4) = end_address; - - int ret = blisp_send_command(device, 0x30, payload, 8, true); - if (ret < 0) return ret; - do { - ret = blisp_receive_response(device, false); - } while (ret == -3); - - return 0; -} - -int32_t -blisp_device_flash_write(struct blisp_device* device, uint32_t start_address, uint8_t* payload, uint32_t payload_size) -{ - // TODO: Add max payload size (8184?) - - uint8_t* buffer = malloc(4 + payload_size); // TODO: Don't use malloc + add check - *((uint32_t*)(buffer)) = start_address; - memcpy(buffer + 4, payload, payload_size); - int ret = blisp_send_command(device, 0x31, buffer, payload_size + 4, true); - if (ret < 0) goto exit1; - ret = blisp_receive_response(device, false); -exit1: - free(buffer); +int32_t blisp_device_load_boot_header(struct blisp_device* device, + uint8_t* boot_header) { + int ret; + ret = blisp_send_command(device, 0x11, boot_header, 176, false); + if (ret < 0) return ret; + ret = blisp_receive_response(device, false); + if (ret < 0) + return ret; + + return 0; } -int32_t blisp_device_program_check(struct blisp_device* device) -{ - int ret = blisp_send_command(device, 0x3A, NULL, 0, true); - if (ret < 0) return ret; +int32_t blisp_device_load_segment_header( + struct blisp_device* device, + struct blisp_segment_header* segment_header) { + int ret; + ret = blisp_send_command(device, 0x17, segment_header, 16, false); + if (ret < 0) + return ret; + ret = blisp_receive_response(device, true); // TODO: Handle response + if (ret < 0) + return ret; + + return 0; +} + +int32_t blisp_device_load_segment_data(struct blisp_device* device, + uint8_t* segment_data, + uint32_t segment_data_length) { + int ret; + ret = blisp_send_command(device, 0x18, segment_data, segment_data_length, + false); + if (ret < 0) + return ret; + ret = blisp_receive_response(device, false); + if (ret < 0) + return ret; + + return 0; +} + +int32_t blisp_device_check_image(struct blisp_device* device) { + int ret; + ret = blisp_send_command(device, 0x19, NULL, 0, false); + if (ret < 0) + return ret; + ret = blisp_receive_response(device, false); + if (ret < 0) + return ret; + + return 0; +} + +int32_t blisp_device_write_memory(struct blisp_device* device, + uint32_t address, + uint32_t value, + bool wait_for_res) { + int ret; + uint8_t payload[8]; + *(uint32_t*)(payload) = address; + *(uint32_t*)(payload + 4) = value; // TODO: Endianness + ret = blisp_send_command(device, 0x50, payload, 8, true); + if (ret < 0) + return ret; + if (wait_for_res) { 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) -{ - int ret = blisp_send_command(device, 0x21, NULL, 0, true); - if (ret < 0) return ret; +int32_t blisp_device_run_image(struct blisp_device* device) { + int ret; + + if (device->chip->type == BLISP_CHIP_BL70X) { // ERRATA + ret = blisp_device_write_memory(device, 0x4000F100, 0x4E424845, true); + if (ret < 0) + return ret; + ret = blisp_device_write_memory(device, 0x4000F104, 0x22010000, true); + if (ret < 0) + return ret; + // ret = blisp_device_write_memory(device, 0x40000018, 0x00000000); + // if (ret < 0) return ret; + ret = blisp_device_write_memory(device, 0x40000018, 0x00000002, false); + if (ret < 0) + return ret; + return 0; + } + + ret = blisp_send_command(device, 0x1A, NULL, 0, false); + if (ret < 0) + return ret; + ret = blisp_receive_response(device, false); + if (ret < 0) + return ret; + + return 0; +} + +int32_t blisp_device_flash_erase(struct blisp_device* device, + uint32_t start_address, + uint32_t end_address) { + uint8_t payload[8]; + *(uint32_t*)(payload + 0) = start_address; + *(uint32_t*)(payload + 4) = end_address; + + int ret = blisp_send_command(device, 0x30, payload, 8, true); + if (ret < 0) + return ret; + do { ret = blisp_receive_response(device, false); - if (ret < 0) return ret; + } while (ret == -3); - return 0; + return 0; } -void blisp_device_close(struct blisp_device* device) -{ - struct sp_port* serial_port = device->serial_port; - sp_close(serial_port); +int32_t blisp_device_flash_write(struct blisp_device* device, + uint32_t start_address, + uint8_t* payload, + uint32_t payload_size) { + // TODO: Add max payload size (8184?) + + uint8_t* buffer = + malloc(4 + payload_size); // TODO: Don't use malloc + add check + *((uint32_t*)(buffer)) = start_address; + memcpy(buffer + 4, payload, payload_size); + int ret = blisp_send_command(device, 0x31, buffer, payload_size + 4, true); + if (ret < 0) + goto exit1; + ret = blisp_receive_response(device, false); +exit1: + free(buffer); + return ret; +} + +int32_t blisp_device_program_check(struct blisp_device* device) { + int ret = blisp_send_command(device, 0x3A, NULL, 0, true); + if (ret < 0) + return ret; + ret = blisp_receive_response(device, false); + if (ret < 0) + return ret; + + return 0; +} + +int32_t blisp_device_reset(struct blisp_device* device) { + int ret = blisp_send_command(device, 0x21, NULL, 0, true); + if (ret < 0) + return ret; + ret = blisp_receive_response(device, false); + if (ret < 0) + return ret; + + return 0; +} + +void blisp_device_close(struct blisp_device* device) { + struct sp_port* serial_port = device->serial_port; + sp_close(serial_port); } \ No newline at end of file diff --git a/tools/blisp/CMakeLists.txt b/tools/blisp/CMakeLists.txt index 6cb53f4..f118db9 100644 --- a/tools/blisp/CMakeLists.txt +++ b/tools/blisp/CMakeLists.txt @@ -10,8 +10,8 @@ target_link_libraries(blisp PRIVATE argtable3 libblisp_static) -if(WIN32) +if (WIN32) target_link_libraries(blisp PRIVATE Setupapi.lib) -elseif(APPLE) +elseif (APPLE) target_link_libraries(blisp PRIVATE "-framework IOKit" "-framework CoreFoundation") -endif() \ No newline at end of file +endif () \ No newline at end of file diff --git a/tools/blisp/src/cmd.h b/tools/blisp/src/cmd.h index 20af7b4..b378b98 100644 --- a/tools/blisp/src/cmd.h +++ b/tools/blisp/src/cmd.h @@ -5,13 +5,13 @@ #include struct cmd { - const char* name; - int8_t (*args_init)(); - uint8_t (*args_parse_exec)(int argc, char** argv); - void (*args_print_syntax)(); - void (*args_free)(); + const char* name; + int8_t (*args_init)(); + uint8_t (*args_parse_exec)(int argc, char** argv); + void (*args_print_syntax)(); + void (*args_free)(); }; extern struct cmd cmd_write; -#endif // BLISP_CMD_H +#endif // BLISP_CMD_H diff --git a/tools/blisp/src/cmd/write.c b/tools/blisp/src/cmd/write.c index 658330a..0d43ffd 100644 --- a/tools/blisp/src/cmd/write.c +++ b/tools/blisp/src/cmd/write.c @@ -1,16 +1,16 @@ // SPDX-License-Identifier: MIT +#include +#include +#include +#include +#include #include "../cmd.h" #include "argtable3.h" -#include -#include -#include #include "blisp_struct.h" -#include -#include #ifdef __linux__ -#include #include +#include #elif defined(_MSC_VER) #include typedef SSIZE_T ssize_t; @@ -21,11 +21,11 @@ typedef SSIZE_T ssize_t; #endif #define REG_EXTENDED 1 -#define REG_ICASE (REG_EXTENDED << 1) +#define REG_ICASE (REG_EXTENDED << 1) static struct arg_rex* cmd; static struct arg_file* binary_to_write; -static struct arg_str* port_name, *chip_type; +static struct arg_str *port_name, *chip_type; static struct arg_lit* reset; static struct arg_end* end; static void* cmd_write_argtable[6]; @@ -36,472 +36,473 @@ static void* cmd_write_argtable[6]; // to free an allocated buffer on the caller.nn 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 real_path_name[PATH_MAX]; // /var/tmp/x - uint32_t raw_path_size = sizeof(raw_path_name); + char raw_path_name[PATH_MAX]; // $HOME/../../var/tmp/x + char real_path_name[PATH_MAX]; // /var/tmp/x + uint32_t raw_path_size = sizeof(raw_path_name); - if(!_NSGetExecutablePath(raw_path_name, &raw_path_size)) { - realpath(raw_path_name, real_path_name); - } - // *real_path_name is appropriately sized and null terminated. - strcpy(buffer_out, real_path_name); + if (!_NSGetExecutablePath(raw_path_name, &raw_path_size)) { + realpath(raw_path_name, real_path_name); + } + // *real_path_name is appropriately sized and null terminated. + strcpy(buffer_out, real_path_name); } #endif -ssize_t -get_binary_folder(char* buffer, uint32_t buffer_size) { +ssize_t get_binary_folder(char* buffer, uint32_t buffer_size) { #ifdef __linux__ - if (readlink("/proc/self/exe", buffer, buffer_size) <= 0) { - return -1; - } - char* pos = strrchr(buffer, '/'); + if (readlink("/proc/self/exe", buffer, buffer_size) <= 0) { + return -1; + } + char* pos = strrchr(buffer, '/'); #elif defined(__APPLE__) - get_executable_path(buffer, buffer_size); - char* pos = strrchr(buffer, '/'); + get_executable_path(buffer, buffer_size); + char* pos = strrchr(buffer, '/'); #else - if (GetModuleFileName(NULL, buffer, buffer_size) <= 0) { - return -1; - } - char* pos = strrchr(buffer, '\\'); + if (GetModuleFileName(NULL, buffer, buffer_size) <= 0) { + return -1; + } + char* pos = strrchr(buffer, '\\'); #endif - pos[0] = '\0'; - return pos - buffer; + pos[0] = '\0'; + return pos - buffer; } -void fill_up_boot_header(struct bfl_boot_header* boot_header) -{ - memcpy(boot_header->magiccode, "BFNP", 4);; - boot_header->revison = 0x01; - memcpy(boot_header->flashCfg.magiccode, "FCFG", 4); - boot_header->flashCfg.cfg.ioMode = 0x11; - boot_header->flashCfg.cfg.cReadSupport = 0x00; - boot_header->flashCfg.cfg.clkDelay = 0x01; - boot_header->flashCfg.cfg.clkInvert = 0x01; - boot_header->flashCfg.cfg.resetEnCmd = 0x66; - boot_header->flashCfg.cfg.resetCmd = 0x99; - boot_header->flashCfg.cfg.resetCreadCmd = 0xFF; - boot_header->flashCfg.cfg.resetCreadCmdSize = 0x03; - boot_header->flashCfg.cfg.jedecIdCmd = 0x9F; - boot_header->flashCfg.cfg.jedecIdCmdDmyClk = 0x00; - boot_header->flashCfg.cfg.qpiJedecIdCmd = 0x9F; - boot_header->flashCfg.cfg.qpiJedecIdCmdDmyClk = 0x00; - boot_header->flashCfg.cfg.sectorSize = 0x04; - boot_header->flashCfg.cfg.mid = 0xC2; - boot_header->flashCfg.cfg.pageSize = 0x100; - boot_header->flashCfg.cfg.chipEraseCmd = 0xC7; - boot_header->flashCfg.cfg.sectorEraseCmd = 0x20; - boot_header->flashCfg.cfg.blk32EraseCmd = 0x52; - boot_header->flashCfg.cfg.blk64EraseCmd = 0xD8; - boot_header->flashCfg.cfg.writeEnableCmd = 0x06; - boot_header->flashCfg.cfg.pageProgramCmd = 0x02; - boot_header->flashCfg.cfg.qpageProgramCmd = 0x32; - boot_header->flashCfg.cfg.qppAddrMode = 0x00; - boot_header->flashCfg.cfg.fastReadCmd = 0x0B; - boot_header->flashCfg.cfg.frDmyClk = 0x01; - boot_header->flashCfg.cfg.qpiFastReadCmd = 0x0B; - boot_header->flashCfg.cfg.qpiFrDmyClk = 0x01; - boot_header->flashCfg.cfg.fastReadDoCmd = 0x3B; - boot_header->flashCfg.cfg.frDoDmyClk = 0x01; - boot_header->flashCfg.cfg.fastReadDioCmd = 0xBB; - boot_header->flashCfg.cfg.frDioDmyClk = 0x00; - boot_header->flashCfg.cfg.fastReadQoCmd = 0x6B; - boot_header->flashCfg.cfg.frQoDmyClk = 0x01; - boot_header->flashCfg.cfg.fastReadQioCmd = 0xEB; - boot_header->flashCfg.cfg.frQioDmyClk = 0x02; - boot_header->flashCfg.cfg.qpiFastReadQioCmd = 0xEB; - boot_header->flashCfg.cfg.qpiFrQioDmyClk = 0x02; - boot_header->flashCfg.cfg.qpiPageProgramCmd = 0x02; - boot_header->flashCfg.cfg.writeVregEnableCmd = 0x50; - boot_header->flashCfg.cfg.wrEnableIndex = 0x00; - boot_header->flashCfg.cfg.qeIndex = 0x01; - boot_header->flashCfg.cfg.busyIndex = 0x00; - boot_header->flashCfg.cfg.wrEnableBit = 0x01; - boot_header->flashCfg.cfg.qeBit = 0x01; - boot_header->flashCfg.cfg.busyBit = 0x00; - boot_header->flashCfg.cfg.wrEnableWriteRegLen = 0x02; - boot_header->flashCfg.cfg.wrEnableReadRegLen = 0x01; - boot_header->flashCfg.cfg.qeWriteRegLen = 0x02; - boot_header->flashCfg.cfg.qeReadRegLen = 0x01; - boot_header->flashCfg.cfg.releasePowerDown = 0xAB; - boot_header->flashCfg.cfg.busyReadRegLen = 0x01; - boot_header->flashCfg.cfg.readRegCmd[0] = 0x05; - boot_header->flashCfg.cfg.readRegCmd[1] = 0x00; - boot_header->flashCfg.cfg.readRegCmd[2] = 0x00; - boot_header->flashCfg.cfg.readRegCmd[3] = 0x00; - boot_header->flashCfg.cfg.writeRegCmd[0] = 0x01; - boot_header->flashCfg.cfg.writeRegCmd[1] = 0x00; - boot_header->flashCfg.cfg.writeRegCmd[2] = 0x00; - boot_header->flashCfg.cfg.writeRegCmd[3] = 0x00; - boot_header->flashCfg.cfg.enterQpi = 0x38; - boot_header->flashCfg.cfg.exitQpi = 0xFF; - boot_header->flashCfg.cfg.cReadMode = 0x00; - boot_header->flashCfg.cfg.cRExit = 0xFF; - boot_header->flashCfg.cfg.burstWrapCmd = 0x77; - boot_header->flashCfg.cfg.burstWrapCmdDmyClk = 0x03; - boot_header->flashCfg.cfg.burstWrapDataMode = 0x02; - boot_header->flashCfg.cfg.burstWrapData = 0x40; - boot_header->flashCfg.cfg.deBurstWrapCmd = 0x77; - boot_header->flashCfg.cfg.deBurstWrapCmdDmyClk = 0x03; - boot_header->flashCfg.cfg.deBurstWrapDataMode = 0x02; - boot_header->flashCfg.cfg.deBurstWrapData = 0xF0; - boot_header->flashCfg.cfg.timeEsector = 0x12C; - boot_header->flashCfg.cfg.timeE32k = 0x4B0; - boot_header->flashCfg.cfg.timeE64k = 0x4B0; - boot_header->flashCfg.cfg.timePagePgm = 0x05; - boot_header->flashCfg.cfg.timeCe = 0xFFFF; - boot_header->flashCfg.cfg.pdDelay = 0x14; - boot_header->flashCfg.cfg.qeData = 0x00; - boot_header->flashCfg.crc32 = 0xE43C762A; - boot_header->clkCfg.cfg.xtal_type = 0x01; - boot_header->clkCfg.cfg.pll_clk = 0x04; - boot_header->clkCfg.cfg.hclk_div = 0x00; - boot_header->clkCfg.cfg.bclk_div = 0x01; - boot_header->clkCfg.cfg.flash_clk_type = 0x03; - boot_header->clkCfg.cfg.flash_clk_div = 0x00; - boot_header->clkCfg.crc32 = 0x72127DBA; - boot_header->bootcfg.bval.sign = 0x00; - boot_header->bootcfg.bval.encrypt_type = 0x00; - boot_header->bootcfg.bval.key_sel = 0x00; - boot_header->bootcfg.bval.rsvd6_7 = 0x00; - boot_header->bootcfg.bval.no_segment = 0x01; - boot_header->bootcfg.bval.cache_enable = 0x01; - boot_header->bootcfg.bval.notload_in_bootrom = 0x00; - boot_header->bootcfg.bval.aes_region_lock = 0x00; - boot_header->bootcfg.bval.cache_way_disable = 0x00; - boot_header->bootcfg.bval.crc_ignore = 0x01; - boot_header->bootcfg.bval.hash_ignore = 0x01; - boot_header->bootcfg.bval.halt_ap = 0x00; - boot_header->bootcfg.bval.rsvd19_31 = 0x00; - boot_header->segment_info.segment_cnt = 0xCDA8; - boot_header->bootentry = 0x00; - boot_header->flashoffset = 0x2000; - boot_header->hash[0x00] = 0xEF; - boot_header->hash[0x01] = 0xBE; - boot_header->hash[0x02] = 0xAD; - boot_header->hash[0x03] = 0xDE; - boot_header->hash[0x04] = 0x00; - boot_header->hash[0x05] = 0x00; - boot_header->hash[0x06] = 0x00; - boot_header->hash[0x07] = 0x00; - boot_header->hash[0x08] = 0x00; - boot_header->hash[0x09] = 0x00; - boot_header->hash[0x0a] = 0x00; - boot_header->hash[0x0b] = 0x00; - boot_header->hash[0x0c] = 0x00; - boot_header->hash[0x0d] = 0x00; - boot_header->hash[0x0e] = 0x00; - boot_header->hash[0x0f] = 0x00; - boot_header->hash[0x10] = 0x00; - boot_header->hash[0x11] = 0x00; - boot_header->hash[0x12] = 0x00; - boot_header->hash[0x13] = 0x00; - boot_header->hash[0x14] = 0x00; - boot_header->hash[0x15] = 0x00; - boot_header->hash[0x16] = 0x00; - boot_header->hash[0x17] = 0x00; - boot_header->hash[0x18] = 0x00; - boot_header->hash[0x19] = 0x00; - boot_header->hash[0x1a] = 0x00; - boot_header->hash[0x1b] = 0x00; - boot_header->hash[0x1c] = 0x00; - boot_header->hash[0x1d] = 0x00; - boot_header->hash[0x1e] = 0x00; - boot_header->hash[0x1f] = 0x00; - boot_header->rsv1 = 0x1000; - boot_header->rsv2 = 0x2000; - boot_header->crc32 = 0xDEADBEEF; +void fill_up_boot_header(struct bfl_boot_header* boot_header) { + memcpy(boot_header->magiccode, "BFNP", 4); + ; + boot_header->revison = 0x01; + memcpy(boot_header->flashCfg.magiccode, "FCFG", 4); + boot_header->flashCfg.cfg.ioMode = 0x11; + boot_header->flashCfg.cfg.cReadSupport = 0x00; + boot_header->flashCfg.cfg.clkDelay = 0x01; + boot_header->flashCfg.cfg.clkInvert = 0x01; + boot_header->flashCfg.cfg.resetEnCmd = 0x66; + boot_header->flashCfg.cfg.resetCmd = 0x99; + boot_header->flashCfg.cfg.resetCreadCmd = 0xFF; + boot_header->flashCfg.cfg.resetCreadCmdSize = 0x03; + boot_header->flashCfg.cfg.jedecIdCmd = 0x9F; + boot_header->flashCfg.cfg.jedecIdCmdDmyClk = 0x00; + boot_header->flashCfg.cfg.qpiJedecIdCmd = 0x9F; + boot_header->flashCfg.cfg.qpiJedecIdCmdDmyClk = 0x00; + boot_header->flashCfg.cfg.sectorSize = 0x04; + boot_header->flashCfg.cfg.mid = 0xC2; + boot_header->flashCfg.cfg.pageSize = 0x100; + boot_header->flashCfg.cfg.chipEraseCmd = 0xC7; + boot_header->flashCfg.cfg.sectorEraseCmd = 0x20; + boot_header->flashCfg.cfg.blk32EraseCmd = 0x52; + boot_header->flashCfg.cfg.blk64EraseCmd = 0xD8; + boot_header->flashCfg.cfg.writeEnableCmd = 0x06; + boot_header->flashCfg.cfg.pageProgramCmd = 0x02; + boot_header->flashCfg.cfg.qpageProgramCmd = 0x32; + boot_header->flashCfg.cfg.qppAddrMode = 0x00; + boot_header->flashCfg.cfg.fastReadCmd = 0x0B; + boot_header->flashCfg.cfg.frDmyClk = 0x01; + boot_header->flashCfg.cfg.qpiFastReadCmd = 0x0B; + boot_header->flashCfg.cfg.qpiFrDmyClk = 0x01; + boot_header->flashCfg.cfg.fastReadDoCmd = 0x3B; + boot_header->flashCfg.cfg.frDoDmyClk = 0x01; + boot_header->flashCfg.cfg.fastReadDioCmd = 0xBB; + boot_header->flashCfg.cfg.frDioDmyClk = 0x00; + boot_header->flashCfg.cfg.fastReadQoCmd = 0x6B; + boot_header->flashCfg.cfg.frQoDmyClk = 0x01; + boot_header->flashCfg.cfg.fastReadQioCmd = 0xEB; + boot_header->flashCfg.cfg.frQioDmyClk = 0x02; + boot_header->flashCfg.cfg.qpiFastReadQioCmd = 0xEB; + boot_header->flashCfg.cfg.qpiFrQioDmyClk = 0x02; + boot_header->flashCfg.cfg.qpiPageProgramCmd = 0x02; + boot_header->flashCfg.cfg.writeVregEnableCmd = 0x50; + boot_header->flashCfg.cfg.wrEnableIndex = 0x00; + boot_header->flashCfg.cfg.qeIndex = 0x01; + boot_header->flashCfg.cfg.busyIndex = 0x00; + boot_header->flashCfg.cfg.wrEnableBit = 0x01; + boot_header->flashCfg.cfg.qeBit = 0x01; + boot_header->flashCfg.cfg.busyBit = 0x00; + boot_header->flashCfg.cfg.wrEnableWriteRegLen = 0x02; + boot_header->flashCfg.cfg.wrEnableReadRegLen = 0x01; + boot_header->flashCfg.cfg.qeWriteRegLen = 0x02; + boot_header->flashCfg.cfg.qeReadRegLen = 0x01; + boot_header->flashCfg.cfg.releasePowerDown = 0xAB; + boot_header->flashCfg.cfg.busyReadRegLen = 0x01; + boot_header->flashCfg.cfg.readRegCmd[0] = 0x05; + boot_header->flashCfg.cfg.readRegCmd[1] = 0x00; + boot_header->flashCfg.cfg.readRegCmd[2] = 0x00; + boot_header->flashCfg.cfg.readRegCmd[3] = 0x00; + boot_header->flashCfg.cfg.writeRegCmd[0] = 0x01; + boot_header->flashCfg.cfg.writeRegCmd[1] = 0x00; + boot_header->flashCfg.cfg.writeRegCmd[2] = 0x00; + boot_header->flashCfg.cfg.writeRegCmd[3] = 0x00; + boot_header->flashCfg.cfg.enterQpi = 0x38; + boot_header->flashCfg.cfg.exitQpi = 0xFF; + boot_header->flashCfg.cfg.cReadMode = 0x00; + boot_header->flashCfg.cfg.cRExit = 0xFF; + boot_header->flashCfg.cfg.burstWrapCmd = 0x77; + boot_header->flashCfg.cfg.burstWrapCmdDmyClk = 0x03; + boot_header->flashCfg.cfg.burstWrapDataMode = 0x02; + boot_header->flashCfg.cfg.burstWrapData = 0x40; + boot_header->flashCfg.cfg.deBurstWrapCmd = 0x77; + boot_header->flashCfg.cfg.deBurstWrapCmdDmyClk = 0x03; + boot_header->flashCfg.cfg.deBurstWrapDataMode = 0x02; + boot_header->flashCfg.cfg.deBurstWrapData = 0xF0; + boot_header->flashCfg.cfg.timeEsector = 0x12C; + boot_header->flashCfg.cfg.timeE32k = 0x4B0; + boot_header->flashCfg.cfg.timeE64k = 0x4B0; + boot_header->flashCfg.cfg.timePagePgm = 0x05; + boot_header->flashCfg.cfg.timeCe = 0xFFFF; + boot_header->flashCfg.cfg.pdDelay = 0x14; + boot_header->flashCfg.cfg.qeData = 0x00; + boot_header->flashCfg.crc32 = 0xE43C762A; + boot_header->clkCfg.cfg.xtal_type = 0x01; + boot_header->clkCfg.cfg.pll_clk = 0x04; + boot_header->clkCfg.cfg.hclk_div = 0x00; + boot_header->clkCfg.cfg.bclk_div = 0x01; + boot_header->clkCfg.cfg.flash_clk_type = 0x03; + boot_header->clkCfg.cfg.flash_clk_div = 0x00; + boot_header->clkCfg.crc32 = 0x72127DBA; + boot_header->bootcfg.bval.sign = 0x00; + boot_header->bootcfg.bval.encrypt_type = 0x00; + boot_header->bootcfg.bval.key_sel = 0x00; + boot_header->bootcfg.bval.rsvd6_7 = 0x00; + boot_header->bootcfg.bval.no_segment = 0x01; + boot_header->bootcfg.bval.cache_enable = 0x01; + boot_header->bootcfg.bval.notload_in_bootrom = 0x00; + boot_header->bootcfg.bval.aes_region_lock = 0x00; + boot_header->bootcfg.bval.cache_way_disable = 0x00; + boot_header->bootcfg.bval.crc_ignore = 0x01; + boot_header->bootcfg.bval.hash_ignore = 0x01; + boot_header->bootcfg.bval.halt_ap = 0x00; + boot_header->bootcfg.bval.rsvd19_31 = 0x00; + boot_header->segment_info.segment_cnt = 0xCDA8; + boot_header->bootentry = 0x00; + boot_header->flashoffset = 0x2000; + boot_header->hash[0x00] = 0xEF; + boot_header->hash[0x01] = 0xBE; + boot_header->hash[0x02] = 0xAD; + boot_header->hash[0x03] = 0xDE; + boot_header->hash[0x04] = 0x00; + boot_header->hash[0x05] = 0x00; + boot_header->hash[0x06] = 0x00; + boot_header->hash[0x07] = 0x00; + boot_header->hash[0x08] = 0x00; + boot_header->hash[0x09] = 0x00; + boot_header->hash[0x0a] = 0x00; + boot_header->hash[0x0b] = 0x00; + boot_header->hash[0x0c] = 0x00; + boot_header->hash[0x0d] = 0x00; + boot_header->hash[0x0e] = 0x00; + boot_header->hash[0x0f] = 0x00; + boot_header->hash[0x10] = 0x00; + boot_header->hash[0x11] = 0x00; + boot_header->hash[0x12] = 0x00; + boot_header->hash[0x13] = 0x00; + boot_header->hash[0x14] = 0x00; + boot_header->hash[0x15] = 0x00; + boot_header->hash[0x16] = 0x00; + boot_header->hash[0x17] = 0x00; + boot_header->hash[0x18] = 0x00; + boot_header->hash[0x19] = 0x00; + boot_header->hash[0x1a] = 0x00; + boot_header->hash[0x1b] = 0x00; + boot_header->hash[0x1c] = 0x00; + boot_header->hash[0x1d] = 0x00; + boot_header->hash[0x1e] = 0x00; + boot_header->hash[0x1f] = 0x00; + boot_header->rsv1 = 0x1000; + boot_header->rsv2 = 0x2000; + boot_header->crc32 = 0xDEADBEEF; } void blisp_flash_firmware() { - FILE* eflash_loader_file = NULL; + FILE* eflash_loader_file = NULL; - if (chip_type->count == 0) { - fprintf(stderr, "Chip type is invalid.\n"); - return; - } + if (chip_type->count == 0) { + fprintf(stderr, "Chip type is invalid.\n"); + return; + } - struct blisp_chip* chip = NULL; + struct blisp_chip* chip = NULL; - if (strcmp(chip_type->sval[0], "bl70x") == 0) { - chip = &blisp_chip_bl70x; - } else if (strcmp(chip_type->sval[0], "bl60x") == 0) { - chip = &blisp_chip_bl60x; - } else { - fprintf(stderr, "Chip type is invalid.\n"); - return; - } + if (strcmp(chip_type->sval[0], "bl70x") == 0) { + chip = &blisp_chip_bl70x; + } else if (strcmp(chip_type->sval[0], "bl60x") == 0) { + chip = &blisp_chip_bl60x; + } else { + fprintf(stderr, "Chip type is invalid.\n"); + return; + } - struct blisp_device device; - int32_t ret; - ret = blisp_device_init(&device, chip); - if (ret != 0) { - fprintf(stderr, "Failed to init device.\n"); - return; - } - ret = blisp_device_open(&device, port_name->count == 1 ? port_name->sval[0] : NULL); - if (ret != 0) { - fprintf(stderr, "Failed to open device.\n"); - return; - } - printf("Sending a handshake..."); - ret = blisp_device_handshake(&device, false); - if (ret != 0) { - fprintf(stderr, "\nFailed to handshake with device.\n"); + struct blisp_device device; + int32_t ret; + ret = blisp_device_init(&device, chip); + if (ret != 0) { + fprintf(stderr, "Failed to init device.\n"); + return; + } + ret = blisp_device_open(&device, + port_name->count == 1 ? port_name->sval[0] : NULL); + if (ret != 0) { + fprintf(stderr, "Failed to open device.\n"); + return; + } + printf("Sending a handshake..."); + ret = blisp_device_handshake(&device, false); + if (ret != 0) { + fprintf(stderr, "\nFailed to handshake with device.\n"); + goto exit1; + } + printf(" OK\nGetting chip info..."); + struct blisp_boot_info boot_info; + ret = blisp_device_get_boot_info(&device, &boot_info); + if (ret != 0) { + fprintf(stderr, "\nFailed to get boot info.\n"); + goto exit1; + } + + if (boot_info.boot_rom_version[0] == 255 && + boot_info.boot_rom_version[1] == 255 && + boot_info.boot_rom_version[2] == 255 && + boot_info.boot_rom_version[3] == 255) { + printf(" OK\nDevice already in eflash_loader.\n"); + goto eflash_loader; + } + + printf( + " BootROM version %d.%d.%d.%d, ChipID: " + "%02X%02X%02X%02X%02X%02X%02X%02X\n", + boot_info.boot_rom_version[0], boot_info.boot_rom_version[1], + boot_info.boot_rom_version[2], boot_info.boot_rom_version[3], + boot_info.chip_id[0], boot_info.chip_id[1], boot_info.chip_id[2], + boot_info.chip_id[3], boot_info.chip_id[4], boot_info.chip_id[5], + boot_info.chip_id[6], boot_info.chip_id[7]); + + char exe_path[PATH_MAX]; + char eflash_loader_path[PATH_MAX]; + if (get_binary_folder(exe_path, PATH_MAX) <= 0) { + fprintf(stderr, + "Failed to find executable path to search for the " + "eflash loader\n"); + goto exit1; + } + snprintf(eflash_loader_path, PATH_MAX, "%s/data/%s/eflash_loader_%s.bin", + exe_path, device.chip->type_str, + device.chip->default_eflash_loader_xtal); + printf("Loading the eflash loader file from disk\n"); + eflash_loader_file = fopen(eflash_loader_path, "rb"); // TODO: Error handling + if (eflash_loader_file == NULL) { + fprintf(stderr, + "Could not open the eflash loader file from disk.\n" + "Does \"%s\" exist?\n", + eflash_loader_path); + goto exit1; + } + uint8_t + eflash_loader_header[176]; // TODO: Remap it to the boot header struct + fread(eflash_loader_header, 176, 1, + eflash_loader_file); // TODO: Error handling + + printf("Loading eflash_loader...\n"); + ret = blisp_device_load_boot_header(&device, eflash_loader_header); + if (ret != 0) { + fprintf(stderr, "Failed to load boot header.\n"); + goto exit1; + } + + { + uint32_t sent_data = 0; + uint32_t buffer_size = 0; + uint8_t buffer[4092]; + + // TODO: Real checking of segments count + for (uint8_t seg_index = 0; seg_index < 1; seg_index++) { + struct blisp_segment_header segment_header = {0}; + fread(&segment_header, 16, 1, + eflash_loader_file); // TODO: Error handling + + ret = blisp_device_load_segment_header(&device, &segment_header); + if (ret != 0) { + fprintf(stderr, "Failed to load segment header.\n"); goto exit1; - } - printf(" OK\nGetting chip info..."); - struct blisp_boot_info boot_info; - ret = blisp_device_get_boot_info(&device, &boot_info); - if (ret != 0) { - fprintf(stderr, "\nFailed to get boot info.\n"); - goto exit1; - } + } + printf("Flashing %d. segment\n", seg_index + 1); + printf("0b / %" PRIu32 "b (0.00%%)\n", segment_header.length); - if (boot_info.boot_rom_version[0] == 255 && - boot_info.boot_rom_version[1] == 255 && - boot_info.boot_rom_version[2] == 255 && - boot_info.boot_rom_version[3] == 255) { - printf(" OK\nDevice already in eflash_loader.\n"); - goto eflash_loader; - } - - printf(" BootROM version %d.%d.%d.%d, ChipID: %02X%02X%02X%02X%02X%02X%02X%02X\n", - boot_info.boot_rom_version[0], - boot_info.boot_rom_version[1], - boot_info.boot_rom_version[2], - boot_info.boot_rom_version[3], - boot_info.chip_id[0], - boot_info.chip_id[1], - boot_info.chip_id[2], - boot_info.chip_id[3], - boot_info.chip_id[4], - boot_info.chip_id[5], - boot_info.chip_id[6], - boot_info.chip_id[7]); - - char exe_path[PATH_MAX]; - char eflash_loader_path[PATH_MAX]; - if (get_binary_folder(exe_path, PATH_MAX) <= 0) { - fprintf(stderr, "Failed to find executable path to search for the " - "eflash loader\n"); - goto exit1; - } - snprintf(eflash_loader_path, PATH_MAX, "%s/data/%s/eflash_loader_%s.bin", - exe_path, device.chip->type_str, - device.chip->default_eflash_loader_xtal); - printf("Loading the eflash loader file from disk\n"); - eflash_loader_file - = fopen(eflash_loader_path, "rb"); // TODO: Error handling - if (eflash_loader_file == NULL) { - fprintf(stderr, - "Could not open the eflash loader file from disk.\n" - "Does \"%s\" exist?\n", - eflash_loader_path); - goto exit1; - } - uint8_t - eflash_loader_header[176]; // TODO: Remap it to the boot header struct - fread(eflash_loader_header, 176, 1, - eflash_loader_file); // TODO: Error handling - - printf("Loading eflash_loader...\n"); - ret = blisp_device_load_boot_header(&device, eflash_loader_header); - if (ret != 0) { - fprintf(stderr, "Failed to load boot header.\n"); - goto exit1; - } - - { - uint32_t sent_data = 0; - uint32_t buffer_size = 0; - uint8_t buffer[4092]; - - // TODO: Real checking of segments count - for (uint8_t seg_index = 0; seg_index < 1; seg_index++) { - struct blisp_segment_header segment_header = { 0 }; - fread(&segment_header, 16, 1, - eflash_loader_file); // TODO: Error handling - - ret = blisp_device_load_segment_header(&device, &segment_header); - if (ret != 0) { - fprintf(stderr, "Failed to load segment header.\n"); - goto exit1; - } - printf("Flashing %d. segment\n", seg_index + 1); - printf("0b / %" PRIu32 "b (0.00%%)\n", segment_header.length); - - while (sent_data < segment_header.length) { - buffer_size = segment_header.length - sent_data; - if (buffer_size > 4092) { - buffer_size = 4092; - } - fread(buffer, buffer_size, 1, eflash_loader_file); - ret = blisp_device_load_segment_data( - &device, buffer, buffer_size); // TODO: Error handling - if (ret < 0) { - fprintf(stderr, "Failed to load segment data. (ret %d)\n", ret); - goto exit1; - } - sent_data += buffer_size; - printf("%" PRIu32 "b / %" PRIu32 "b (%.2f%%)\n", sent_data, - segment_header.length, - (((float)sent_data / (float)segment_header.length) - * 100.0f)); - } + while (sent_data < segment_header.length) { + buffer_size = segment_header.length - sent_data; + if (buffer_size > 4092) { + buffer_size = 4092; } + fread(buffer, buffer_size, 1, eflash_loader_file); + ret = blisp_device_load_segment_data( + &device, buffer, buffer_size); // TODO: Error handling + if (ret < 0) { + fprintf(stderr, "Failed to load segment data. (ret %d)\n", ret); + goto exit1; + } + sent_data += buffer_size; + printf("%" PRIu32 "b / %" PRIu32 "b (%.2f%%)\n", sent_data, + segment_header.length, + (((float)sent_data / (float)segment_header.length) * 100.0f)); + } } + } - ret = blisp_device_check_image(&device); - if (ret != 0) { - fprintf(stderr, "Failed to check image.\n"); - goto exit1; - } + ret = blisp_device_check_image(&device); + if (ret != 0) { + fprintf(stderr, "Failed to check image.\n"); + goto exit1; + } - ret = blisp_device_run_image(&device); - if (ret != 0) { - fprintf(stderr, "Failed to run image.\n"); - goto exit1; - } + ret = blisp_device_run_image(&device); + if (ret != 0) { + fprintf(stderr, "Failed to run image.\n"); + goto exit1; + } - printf("Sending a handshake..."); - ret = blisp_device_handshake(&device, true); - if (ret != 0) { - fprintf(stderr, "\nFailed to handshake with device.\n"); - goto exit1; - } - printf(" OK\n"); + printf("Sending a handshake..."); + ret = blisp_device_handshake(&device, true); + if (ret != 0) { + fprintf(stderr, "\nFailed to handshake with device.\n"); + goto exit1; + } + printf(" OK\n"); eflash_loader:; - FILE* firmware_file = fopen(binary_to_write->filename[0], "rb"); - if (firmware_file == NULL) { - fprintf(stderr,"Failed to open firmware file \"%s\".\n", binary_to_write->filename[0]); - goto exit1; - } - fseek(firmware_file, 0, SEEK_END); - int64_t firmware_file_size = ftell(firmware_file); - rewind(firmware_file); + FILE* firmware_file = fopen(binary_to_write->filename[0], "rb"); + if (firmware_file == NULL) { + fprintf(stderr, "Failed to open firmware file \"%s\".\n", + binary_to_write->filename[0]); + goto exit1; + } + fseek(firmware_file, 0, SEEK_END); + int64_t firmware_file_size = ftell(firmware_file); + rewind(firmware_file); - struct bfl_boot_header boot_header; - fill_up_boot_header(&boot_header); + struct bfl_boot_header boot_header; + fill_up_boot_header(&boot_header); - const uint32_t firmware_base_address = 0x2000; - printf("Erasing flash, this might take a while..."); - ret = blisp_device_flash_erase(&device, firmware_base_address, - firmware_base_address + firmware_file_size - + 1); - if (ret != 0) { - fprintf(stderr, "\nFailed to erase flash.\n"); - goto exit2; - } - ret = blisp_device_flash_erase(&device, 0x0000, sizeof(struct bfl_boot_header)); - if (ret != 0) { - fprintf(stderr, "\nFailed to erase flash.\n"); + const uint32_t firmware_base_address = 0x2000; + printf("Erasing flash, this might take a while..."); + ret = + blisp_device_flash_erase(&device, firmware_base_address, + firmware_base_address + firmware_file_size + 1); + if (ret != 0) { + fprintf(stderr, "\nFailed to erase flash.\n"); + goto exit2; + } + ret = + blisp_device_flash_erase(&device, 0x0000, sizeof(struct bfl_boot_header)); + if (ret != 0) { + fprintf(stderr, "\nFailed to erase flash.\n"); + goto exit2; + } + + printf(" OK!\nFlashing boot header..."); + ret = blisp_device_flash_write(&device, 0x0000, (uint8_t*)&boot_header, + sizeof(struct bfl_boot_header)); + if (ret != 0) { + fprintf(stderr, "\nFailed to write boot header.\n"); + goto exit2; + } + printf(" OK!\nFlashing the firmware...\n"); + { + uint32_t sent_data = 0; + uint32_t buffer_size = 0; + uint8_t buffer[8184]; + printf("0b / %ldb (0.00%%)\n", firmware_file_size); + + while (sent_data < firmware_file_size) { + buffer_size = firmware_file_size - sent_data; + if (buffer_size > 2052) { + buffer_size = 2052; + } + fread(buffer, buffer_size, 1, firmware_file); + ret = blisp_device_flash_write(&device, firmware_base_address + sent_data, + buffer, + buffer_size); // TODO: Error handling + if (ret < 0) { + fprintf(stderr, "Failed to write firmware! (ret: %d)\n", ret); goto exit2; + } + sent_data += buffer_size; + printf("%" PRIu32 "b / %ldb (%.2f%%)\n", sent_data, firmware_file_size, + (((float)sent_data / (float)firmware_file_size) * 100.0f)); } + } - printf(" OK!\nFlashing boot header..."); - ret = blisp_device_flash_write(&device, 0x0000, (uint8_t*)&boot_header, sizeof(struct bfl_boot_header)); - if (ret != 0) { - fprintf(stderr, "\nFailed to write boot header.\n"); - goto exit2; - } - printf(" OK!\nFlashing the firmware...\n"); - { - uint32_t sent_data = 0; - uint32_t buffer_size = 0; - uint8_t buffer[8184]; - printf("0b / %ldb (0.00%%)\n", firmware_file_size); + printf("Checking program..."); + ret = blisp_device_program_check(&device); + if (ret != 0) { + fprintf(stderr, "\nFailed to check program.\n"); + goto exit2; + } + printf("OK\n"); - while (sent_data < firmware_file_size) { - buffer_size = firmware_file_size - sent_data; - if (buffer_size > 2052) { - buffer_size = 2052; - } - fread(buffer, buffer_size, 1, firmware_file); - ret = blisp_device_flash_write(&device, firmware_base_address + sent_data, buffer, buffer_size); // TODO: Error handling - if (ret < 0) { - fprintf(stderr, "Failed to write firmware! (ret: %d)\n", ret); - goto exit2; - } - sent_data += buffer_size; - printf("%" PRIu32 "b / %ldb (%.2f%%)\n", sent_data, firmware_file_size, - (((float)sent_data / (float)firmware_file_size) * 100.0f)); - } - } + if (reset->count > 0) { + blisp_device_reset(&device); + printf("Resetting the chip.\n"); + // TODO: It seems that GPIO peripheral is not reset after resetting the chip + } - printf("Checking program..."); - ret = blisp_device_program_check(&device); - if (ret != 0) { - fprintf(stderr, "\nFailed to check program.\n"); - goto exit2; - } - printf("OK\n"); - - if (reset->count > 0) { - blisp_device_reset(&device); - printf("Resetting the chip.\n"); - // TODO: It seems that GPIO peripheral is not reset after resetting the chip - } - - printf("Flash complete!\n"); + printf("Flash complete!\n"); exit2: - if (firmware_file != NULL) fclose(firmware_file); + if (firmware_file != NULL) + fclose(firmware_file); exit1: - if (eflash_loader_file != NULL) fclose(eflash_loader_file); - blisp_device_close(&device); + if (eflash_loader_file != NULL) + fclose(eflash_loader_file); + blisp_device_close(&device); } -int8_t -cmd_write_args_init() { - cmd_write_argtable[0] = cmd - = arg_rex1(NULL, NULL, "write", NULL, REG_ICASE, NULL); - cmd_write_argtable[1] = chip_type = arg_str1("c", "chip", "", "Chip Type (bl70x)"); - cmd_write_argtable[2] = port_name - = arg_str0("p", "port", "", "Name/Path to the Serial Port (empty for search)"); - cmd_write_argtable[3] = reset = arg_lit0(NULL, "reset", "Reset chip after write"); - cmd_write_argtable[4] = binary_to_write - = arg_file1(NULL, NULL, "", "Binary to write"); - cmd_write_argtable[5] = end = arg_end(10); +int8_t cmd_write_args_init() { + cmd_write_argtable[0] = cmd = + arg_rex1(NULL, NULL, "write", NULL, REG_ICASE, NULL); + cmd_write_argtable[1] = chip_type = + arg_str1("c", "chip", "", "Chip Type (bl70x)"); + cmd_write_argtable[2] = port_name = + arg_str0("p", "port", "", + "Name/Path to the Serial Port (empty for search)"); + cmd_write_argtable[3] = reset = + arg_lit0(NULL, "reset", "Reset chip after write"); + cmd_write_argtable[4] = binary_to_write = + arg_file1(NULL, NULL, "", "Binary to write"); + cmd_write_argtable[5] = end = arg_end(10); - if (arg_nullcheck(cmd_write_argtable) != 0) { - fprintf(stderr, "insufficient memory\n"); - return -1; - } - return 0; + if (arg_nullcheck(cmd_write_argtable) != 0) { + fprintf(stderr, "insufficient memory\n"); + return -1; + } + return 0; } void cmd_write_args_print_glossary() { - fputs("Usage: blisp", stdout); - arg_print_syntax(stdout,cmd_write_argtable,"\n"); - puts("Writes firmware to SPI Flash"); - arg_print_glossary(stdout,cmd_write_argtable," %-25s %s\n"); + fputs("Usage: blisp", stdout); + arg_print_syntax(stdout, cmd_write_argtable, "\n"); + puts("Writes firmware to SPI Flash"); + arg_print_glossary(stdout, cmd_write_argtable, " %-25s %s\n"); } -uint8_t -cmd_write_parse_exec(int argc, char** argv) { - int errors = arg_parse(argc, argv, cmd_write_argtable); - if (errors == 0) { - blisp_flash_firmware(); // TODO: Error code? - return 1; - } else if (cmd->count == 1) { - cmd_write_args_print_glossary(); - return 1; - } - return 0; +uint8_t cmd_write_parse_exec(int argc, char** argv) { + int errors = arg_parse(argc, argv, cmd_write_argtable); + if (errors == 0) { + blisp_flash_firmware(); // TODO: Error code? + return 1; + } else if (cmd->count == 1) { + cmd_write_args_print_glossary(); + return 1; + } + return 0; } void cmd_write_args_print_syntax() { - arg_print_syntax(stdout,cmd_write_argtable,"\n"); + arg_print_syntax(stdout, cmd_write_argtable, "\n"); } -void -cmd_write_free() { - arg_freetable(cmd_write_argtable, - sizeof(cmd_write_argtable) / sizeof(cmd_write_argtable[0])); +void cmd_write_free() { + arg_freetable(cmd_write_argtable, + sizeof(cmd_write_argtable) / sizeof(cmd_write_argtable[0])); } -struct cmd cmd_write - = { "write", cmd_write_args_init, cmd_write_parse_exec, cmd_write_args_print_syntax, cmd_write_free }; +struct cmd cmd_write = {"write", cmd_write_args_init, cmd_write_parse_exec, + cmd_write_args_print_syntax, cmd_write_free}; diff --git a/tools/blisp/src/main.c b/tools/blisp/src/main.c index 87ae4ac..646cebb 100644 --- a/tools/blisp/src/main.c +++ b/tools/blisp/src/main.c @@ -1,13 +1,11 @@ // SPDX-License-Identifier: MIT -#include "argtable3.h" -#include "cmd.h" #include #include #include +#include "argtable3.h" +#include "cmd.h" -struct cmd* cmds[] = { - &cmd_write -}; +struct cmd* cmds[] = {&cmd_write}; static uint8_t cmds_count = sizeof(cmds) / sizeof(cmds[0]); @@ -17,83 +15,83 @@ static struct arg_end* end; static void* argtable[3]; int8_t args_init() { - 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[2] = end = arg_end(20); + 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[2] = end = arg_end(20); - if (arg_nullcheck(argtable) != 0) { - fprintf(stderr, "insufficient memory\n"); - return -1; - } + if (arg_nullcheck(argtable) != 0) { + fprintf(stderr, "insufficient memory\n"); + return -1; + } - return 0; + return 0; } void print_help() { - puts("Usage:"); - for (uint8_t i = 0; i < cmds_count; i++) { - fputs(" blisp", stdout); - cmds[i]->args_print_syntax(); - } + puts("Usage:"); + for (uint8_t i = 0; i < cmds_count; i++) { fputs(" blisp", stdout); - arg_print_syntax(stdout, argtable,"\n"); + cmds[i]->args_print_syntax(); + } + fputs(" blisp", stdout); + arg_print_syntax(stdout, argtable, "\n"); } int8_t args_parse_exec(int argc, char** argv) { - int error = arg_parse(argc, argv, argtable); - if (error == 0) { - if (help->count) { - print_help(); - return 1; - } else if (version->count) { - printf("blisp 1.0.0\n"); - printf("Copyright (C) 2022 Marek Kraus and PINE64 Community\n"); - return 1; - } + int error = arg_parse(argc, argv, argtable); + if (error == 0) { + if (help->count) { + print_help(); + return 1; + } else if (version->count) { + printf("blisp 1.0.0\n"); + printf("Copyright (C) 2022 Marek Kraus and PINE64 Community\n"); + return 1; } - return 0; + } + return 0; } void args_free() { - arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); + arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); } -int -main(int argc, char** argv) { - int exit_code = 0; +int main(int argc, char** argv) { + int exit_code = 0; - if (args_init() != 0) { - exit_code = -1; - goto exit; - } + if (args_init() != 0) { + exit_code = -1; + goto exit; + } - for (uint8_t i = 0; i < cmds_count; i++) { - if (cmds[i]->args_init() != 0) { - exit_code = -1; - goto exit; - } + for (uint8_t i = 0; i < cmds_count; i++) { + if (cmds[i]->args_init() != 0) { + exit_code = -1; + goto exit; } + } - if (args_parse_exec(argc, argv)) { - goto exit; - } + if (args_parse_exec(argc, argv)) { + goto exit; + } - uint8_t command_found = false; - for (uint8_t i = 0; i < cmds_count; i++) { - if (cmds[i]->args_parse_exec(argc, argv)) { - command_found = true; - break; - } + uint8_t command_found = false; + for (uint8_t i = 0; i < cmds_count; i++) { + if (cmds[i]->args_parse_exec(argc, argv)) { + command_found = true; + break; } + } - if (!command_found) { - print_help(); - } + if (!command_found) { + print_help(); + } exit: - for (uint8_t i = 0; i < cmds_count; i++) { - cmds[i]->args_free(); - } - args_free(); - return exit_code; + for (uint8_t i = 0; i < cmds_count; i++) { + cmds[i]->args_free(); + } + args_free(); + return exit_code; }