/** * Get boot region information * \return 0 or 1. */ static uint32_t _app_boot_get(void) { uint32_t gpmvm_status = flash_is_gpnvm_set(2); if (gpmvm_status == FLASH_RC_YES) { return 1; } else { return 0; } }
/** * \brief Clear the given GPNVM bit. * * \param ul_gpnvm GPNVM bit index. * * \return 0 if successful; otherwise returns an error code. */ uint32_t flash_clear_gpnvm(uint32_t ul_gpnvm) { if (ul_gpnvm >= GPNVM_NUM_MAX) { return FLASH_RC_INVALID; } if (FLASH_RC_NO == flash_is_gpnvm_set(ul_gpnvm)) { return FLASH_RC_OK; } if (EFC_RC_OK == efc_perform_command(EFC, EFC_FCMD_CGPB, ul_gpnvm)) { return FLASH_RC_OK; } return FLASH_RC_ERROR; }
/** * \brief Compute the address of a flash by the given page and offset. * * \param p_efc Pointer to an EFC instance. * \param us_page Page number. * \param us_offset Byte offset inside page. * \param pul_addr Computed address (optional). */ static void compute_address(Efc *p_efc, uint16_t us_page, uint16_t us_offset, uint32_t *pul_addr) { uint32_t ul_addr; /* Dual bank flash */ #ifdef EFC1 /* Compute address */ #if (SAM4SD16 || SAM4SD32 || SAM4C32) uint32_t uc_gpnvm2; uc_gpnvm2 = flash_is_gpnvm_set(2); if (p_efc == EFC0) { if(uc_gpnvm2 == FLASH_RC_YES) { ul_addr = IFLASH1_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset; } else { ul_addr = IFLASH0_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset; } } else { if(uc_gpnvm2 == FLASH_RC_YES) { ul_addr = IFLASH0_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset; } else { ul_addr = IFLASH1_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset; } } #else ul_addr = (p_efc == EFC0) ? IFLASH0_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset : IFLASH1_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset; #endif /* One bank flash */ #else /* avoid Cppcheck Warning */ UNUSED(p_efc); /* Compute address */ ul_addr = IFLASH_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset; #endif /* Store result */ if (pul_addr != NULL) { *pul_addr = ul_addr; } }
/** * \brief Check if the security bit is set or not. * * \retval 1 If the security bit is currently set. * \retval 0 If the security bit is currently cleared. */ uint32_t flash_is_security_bit_enabled(void) { return flash_is_gpnvm_set(0); }
//False = Currently set to boot from FLASH0, True = Set to boot from FLASH1 instead bool DueFlashStorage::getGPNVMBootMode() { if (flash_is_gpnvm_set(2) == 0) return false; return true; }
/** * \brief Translate the given flash address to page and offset values. * \note pus_page and pus_offset must not be null in order to store the * corresponding values. * * \param pp_efc Pointer to an EFC pointer. * \param ul_addr Address to translate. * \param pus_page The first page accessed. * \param pus_offset Byte offset in the first page. */ static void translate_address(Efc **pp_efc, uint32_t ul_addr, uint16_t *pus_page, uint16_t *pus_offset) { Efc *p_efc; uint16_t us_page; uint16_t us_offset; #if (SAM3XA || SAM3U4) if (ul_addr >= IFLASH1_ADDR) { p_efc = EFC1; us_page = (ul_addr - IFLASH1_ADDR) / IFLASH1_PAGE_SIZE; us_offset = (ul_addr - IFLASH1_ADDR) % IFLASH1_PAGE_SIZE; } else { p_efc = EFC0; us_page = (ul_addr - IFLASH0_ADDR) / IFLASH0_PAGE_SIZE; us_offset = (ul_addr - IFLASH0_ADDR) % IFLASH0_PAGE_SIZE; } #elif (SAM4SD16 || SAM4SD32 || SAM4C32) uint32_t uc_gpnvm2; uc_gpnvm2 = flash_is_gpnvm_set(2); if (ul_addr >= IFLASH1_ADDR) { if(uc_gpnvm2 == FLASH_RC_YES) { p_efc = EFC0; } else { p_efc = EFC1; } us_page = (ul_addr - IFLASH1_ADDR) / IFLASH1_PAGE_SIZE; us_offset = (ul_addr - IFLASH1_ADDR) % IFLASH1_PAGE_SIZE; } else { if(uc_gpnvm2 == FLASH_RC_YES) { p_efc = EFC1; } else { p_efc = EFC0; } us_page = (ul_addr - IFLASH0_ADDR) / IFLASH0_PAGE_SIZE; us_offset = (ul_addr - IFLASH0_ADDR) % IFLASH0_PAGE_SIZE; } #elif (SAM3SD8) p_efc = EFC; us_page = (ul_addr - IFLASH0_ADDR) / IFLASH0_PAGE_SIZE; us_offset = (ul_addr - IFLASH0_ADDR) % IFLASH0_PAGE_SIZE; #else Assert(ul_addr >= IFLASH_ADDR); Assert(ul_addr <= (IFLASH_ADDR + IFLASH_SIZE)); p_efc = EFC; us_page = (ul_addr - IFLASH_ADDR) / IFLASH_PAGE_SIZE; us_offset = (ul_addr - IFLASH_ADDR) % IFLASH_PAGE_SIZE; #endif /* Store values */ if (pp_efc) { *pp_efc = p_efc; } if (pus_page) { *pus_page = us_page; } if (pus_offset) { *pus_offset = us_offset; } }