static nxt_error_t nxt_flash_block(nxt_t *nxt, nxt_word_t block_num, char *buf) { // Set the target block number NXT_ERR(nxt_write_word(nxt, 0x202300, block_num)); // Send the block to flash NXT_ERR(nxt_send_file(nxt, 0x202100, buf, 256)); // Jump into the flash writing routine NXT_ERR(nxt_jump(nxt, 0x202000)); return NXT_OK; }
static nxt_error_t nxt_flash_prepare(nxt_t *nxt, int unlock) { // Put the clock in PLL/2 mode NXT_ERR(nxt_write_word(nxt, 0xFFFFFC30, 0x7)); // Unlock the flash chip if (unlock) NXT_ERR(nxt_flash_unlock_all_regions(nxt)); // Send the flash writing routine NXT_ERR(nxt_send_file(nxt, 0x202000, flash_bin, flash_len)); return NXT_OK; }
nxt_error_t nxt_flash_lock_all_regions(nxt_t *nxt) { int i; for (i = 0; i < 16; i++) NXT_ERR(nxt_flash_lock_region(nxt, i)); return NXT_OK; }
static nxt_error_t nxt_flash_alter_lock(nxt_t *nxt, int region_num, enum nxt_flash_commands cmd) { nxt_word_t w = 0x5A000000 | ((64 * region_num) << 8); w += cmd; NXT_ERR(nxt_flash_wait_ready(nxt)); /* Flash mode register: FCMN 0x5, FWS 0x1 * Flash command register: KEY 0x5A, FCMD = clear-lock-bit (0x4) * Flash mode register: FCMN 0x34, FWS 0x1 */ NXT_ERR(nxt_write_word(nxt, 0xFFFFFF60, 0x00050100)); NXT_ERR(nxt_write_word(nxt, 0xFFFFFF64, w)); NXT_ERR(nxt_write_word(nxt, 0xFFFFFF60, 0x00340100)); return NXT_OK; }
nxt_error_t nxt_flash_wait_ready(nxt_t *nxt) { nxt_word_t flash_status; do { NXT_ERR(nxt_read_word(nxt, 0xFFFFFF68, &flash_status)); /* Bit 0 is the FRDY field. Set to 1 if the flash controller is * ready to run a new command. */ } while (!(flash_status & 0x1)); return NXT_OK; }
nxt_error_t nxt_firmware_flash(nxt_t *nxt, char *fw_path, int start_page, int max_pages, int unlock, int write_len) { int fd, i, err, len = 0; char buf[256]; #if defined(_WIN32) || defined(__CYGWIN32__) fd = open(fw_path, O_RDONLY | O_BINARY); #else fd = open(fw_path, O_RDONLY); #endif if (fd < 0) return NXT_FILE_ERROR; err = nxt_firmware_validate_fd(fd, max_pages * 256); if (err != NXT_OK) { close(fd); return NXT_INVALID_FIRMWARE; } NXT_ERR(nxt_flash_prepare(nxt, unlock)); for (i = start_page; i < start_page + max_pages; i++) { int ret; memset(buf, 0, 256); ret = read(fd, buf, 256); if (ret != -1) { NXT_ERR(nxt_flash_block(nxt, i, buf)); len += ret; } if (ret < 256) { close(fd); if (ret != -1 && write_len) { ((unsigned *) buf)[63] = len; NXT_ERR(nxt_flash_block(nxt,start_page + max_pages -1, buf)); } NXT_ERR(nxt_flash_finish(nxt)); return ret == -1 ? NXT_FILE_ERROR : NXT_OK; } } close(fd); if (write_len) { ((unsigned *) buf)[63] = len; NXT_ERR(nxt_flash_block(nxt,start_page + max_pages -1, buf)); } NXT_ERR(nxt_flash_finish(nxt)); return NXT_OK; }