static vsf_err_t nuc100swj_init_iap(void) { uint32_t reg; uint8_t verify_buff[sizeof(iap_code)]; if (cm_dp_halt()) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "halt nuc100"); return ERRCODE_FAILURE_OPERATION; } // enable isp clock and ispen bit reg = NUC100_REG_AHBCLK_ISPEN; if (adi_memap_write_reg32(NUC100_REG_AHBCLK, ®, 0)) { return VSFERR_FAIL; } reg = NUC100_REG_ISPCON_ISPFF | NUC100_REG_ISPCON_LDUEN | NUC100_REG_ISPCON_CFGUEN | NUC100_REG_ISPCON_ISPEN; if (adi_memap_write_reg32(NUC100_REG_ISPCON, ®, 1)) { return VSFERR_FAIL; } // write iap_code if (adi_memap_write_buf32(NUC100_IAP_BASE, (uint8_t*)iap_code, sizeof(iap_code))) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "load iap_code to SRAM"); return ERRCODE_FAILURE_OPERATION; } // verify iap_code memset(verify_buff, 0, sizeof(iap_code)); if (adi_memap_read_buf32(NUC100_IAP_BASE, verify_buff, sizeof(iap_code))) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "read flash_loader"); return ERRCODE_FAILURE_OPERATION; } if (memcmp(verify_buff, iap_code, sizeof(iap_code))) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "verify flash_loader"); return ERRCODE_FAILURE_OPERATION; } // write pc reg = NUC100_IAP_BASE + 1; if (cm_write_core_register(CM_COREREG_PC, ®)) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "write PC"); return ERRCODE_FAILURE_OPERATION; } if (cm_dp_resume()) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "run iap"); return ERRCODE_FAILURE_OPERATION; } return VSFERR_NONE; }
static vsf_err_t nuc400swj_unlock(void) { uint32_t data[3] = {NUC400_REG_REGWRPROT_D0, NUC400_REG_REGWRPROT_D1, NUC400_REG_REGWRPROT_D2}; if (adi_memap_write_reg32(NUC400_REG_REGWRPROT, &data[0], 0) || adi_memap_write_reg32(NUC400_REG_REGWRPROT, &data[1], 0) || adi_memap_write_reg32(NUC400_REG_REGWRPROT, &data[2], 1)) { return VSFERR_FAIL; } return VSFERR_NONE; }
static vsf_err_t nuc400swj_fmc_enable(void) { uint32_t reg = NUC400_REG_AHBCLK_ISPEN; if (adi_memap_write_reg32(NUC400_REG_AHBCLK, ®, 0)) { return VSFERR_FAIL; } reg = NUC400_REG_ISPCON_ISPFF | NUC400_REG_ISPCON_LDUEN | NUC400_REG_ISPCON_CFGUEN | NUC400_REG_ISPCON_ISPEN; if (adi_memap_write_reg32(NUC400_REG_ISPCON, ®, 1)) { return VSFERR_FAIL; } return VSFERR_NONE; }
static vsf_err_t nuc400swj_reset_to_ldrom(void) { uint32_t reg = NUC400_REG_ISPCON_BS_LDROM; if (adi_memap_write_reg32(NUC400_REG_ISPCON, ®, 1) || nuc400swj_reset()) { return VSFERR_FAIL; } return VSFERR_NONE; }
static vsf_err_t nuc100swj_reset_to_aprom(void) { uint32_t ispcon = NUC100_REG_ISPCON_BS_APROM; if (adi_memap_write_reg32(NUC100_REG_ISPCON, &ispcon, 1) || nuc100swj_reset()) { return VSFERR_FAIL; } return VSFERR_NONE; }
static vsf_err_t at91sam3swj_iap_call(struct at91sam3swj_iap_command_t *cmd, struct at91sam3swj_iap_reply_t *reply) { uint32_t reg; uint32_t start, end; uint32_t i; reg = cmd->iap_command | AT91SAM3_EEFC_FKEY; if (adi_memap_write_reg32(cmd->eefc_base + AT91SAM3_EEFC_FCR_OFFSET, ®, 1)) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "write fcr"); return ERRCODE_FAILURE_OPERATION; } start = (uint32_t)(clock() / (CLOCKS_PER_SEC / 1000)); do { reg = 0; if (adi_memap_read_reg32(cmd->eefc_base + AT91SAM3_EEFC_FSR_OFFSET, ®, 1)) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "read fsr"); return ERRCODE_FAILURE_OPERATION; } reg = LE_TO_SYS_U32(reg); end = (uint32_t)(clock() / (CLOCKS_PER_SEC / 1000)); } while (!(reg & 1) && ((end - start) < 500)); if (!(reg & 1) || (reg & 0x60)) { return VSFERR_FAIL; } if ((reply != NULL) && (reply->data != NULL) && (reply->data_num > 0)) { for (i = 0; i < reply->data_num; i++) { if (adi_memap_read_reg32(cmd->eefc_base + AT91SAM3_EEFC_FRR_OFFSET, &reply->data[i], 1)) { LOG_ERROR(ERRMSG_FAILURE_OPERATION, "read frr"); return ERRCODE_FAILURE_OPERATION; } reply->data[i] = LE_TO_SYS_U32(reply->data[i]); } } return VSFERR_NONE; }
static vsf_err_t nuc400swj_isp_run(uint8_t cmd, uint32_t addr, uint32_t *data, uint32_t num, bool read) { vsf_err_t err = VSFERR_NONE; uint32_t reg, i; for (i = 0; i < num; i++) { if (!read && (data != NULL)) { if (adi_memap_write_reg32(NUC400_REG_ISPADR, &data[i], 0)) { err = ERRCODE_FAILURE_OPERATION; break; } } reg = addr; addr += 4; if (adi_memap_write_reg32(NUC400_REG_ISPADR, ®, 0)) { err = ERRCODE_FAILURE_OPERATION; break; } reg = cmd; if (adi_memap_write_reg32(NUC400_REG_ISPCMD, ®, 0)) { err = ERRCODE_FAILURE_OPERATION; break; } reg = NUC400_REG_ISPTRG_ISPGO; if (adi_memap_write_reg32(NUC400_REG_ISPTRG, ®, 0)) { err = ERRCODE_FAILURE_OPERATION; break; } while (1) { if (adi_memap_read_reg32(NUC400_REG_ISPTRG, ®, 1)) { err = ERRCODE_FAILURE_OPERATION; break; } if (!(reg & NUC400_REG_ISPTRG_ISPGO)) { break; } } if (adi_memap_read_reg32(NUC400_REG_ISPCON, ®, 1) || (reg & NUC400_REG_ISPCON_ISPFF)) { err = ERRCODE_FAILURE_OPERATION; break; } if (read && (data != NULL) && adi_memap_read_reg32(NUC400_REG_ISPDAT, &data[i], 1)) { err = ERRCODE_FAILURE_OPERATION; break; } } return err; }
static vsf_err_t nuc400swj_reset(void) { uint32_t reg = NUC400_REG_IPRSTC1_CUP_RST; return adi_memap_write_reg32(NUC400_REG_IPRSTC1, ®, 1); }
static vsf_err_t nuc100swj_reset(void) { uint32_t iprstc1 = NUC100_REG_IPRSTC1_CUP_RST; return adi_memap_write_reg32(NUC100_REG_IPRSTC1, &iprstc1, 1); }