/** * \brief Test NVM initialization * * This function will write the default configuration to NVM * and returns an error in case of failure. * * \param test Current test case. */ static void run_nvm_init_test(const struct test_case *test) { struct nvm_config config; enum status_code status; /* Get the default configuration */ nvm_get_config_defaults(&config); /* Set wait state to 1 */ config.wait_states = 1; /* Enable automatic page write mode */ config.manual_page_write = false; /* Set the NVM configuration */ status = nvm_set_config(&config); /* Validate the initialization */ test_assert_true(test, status == STATUS_OK, "NVM Initialization error"); if (status == STATUS_OK) { nvm_init_success = true; } }
static int samd21_flash_init(void) { int rc; struct nvm_config cfg; struct nvm_parameters params; nvm_get_config_defaults(&cfg); cfg.manual_page_write = false; rc = nvm_set_config(&cfg); if(rc != STATUS_OK) { return -1; } nvm_get_parameters(¶ms); /* the samd21 flash doesn't use sector terminology. They use Row and * page. A row contains 4 pages. Each pages is a fixed size. You can * only erase based on row. Here I will map the rows to sectors and * deal with pages inside this driver. */ samd21_flash_dev.hf_itf = &samd21_flash_funcs; samd21_flash_dev.hf_base_addr = SAMD21_FLASH_START_ADDR; samd21_flash_dev.hf_size = params.nvm_number_of_pages * params.page_size; samd21_flash_dev.hf_sector_cnt = params.nvm_number_of_pages/SAMD21_FLASH_PAGES_PER_SECTOR; samd21_flash_dev.hf_align = 1; return 0; }
//! [setup] void configure_nvm(void) { //! [setup_1] struct nvm_config config_nvm; //! [setup_1] //! [setup_2] nvm_get_config_defaults(&config_nvm); //! [setup_2] //! [setup_3] config_nvm.manual_page_write = false; //! [setup_3] //! [setup_4] nvm_set_config(&config_nvm); //! [setup_4] }
otError utilsFlashInit(void) { otError error = OT_ERROR_NONE; struct nvm_config configNvm; nvm_get_config_defaults(&configNvm); configNvm.manual_page_write = false; enum status_code status; while ((status = nvm_set_config(&configNvm)) == STATUS_BUSY) ; if (status != STATUS_OK) { error = OT_ERROR_FAILED; } return error; }
/*---------------------------------------------------------------------------*/ static int open(void) { if (!opened) { struct nvm_config config_nvm; nvm_get_config_defaults(&config_nvm); nvm_set_config(&config_nvm); nvm_get_parameters(¶meters); TRACE("bootloader_number_of_pages: %ld, eeprom_number_of_pages: %ld, nvm_number_of_pages: %d, page_size: %d", parameters.bootloader_number_of_pages, parameters.eeprom_number_of_pages, parameters.nvm_number_of_pages, parameters.page_size); while (!nvm_is_ready()); opened = 1; } return 1; }
/** * \brief Main application */ int main(void) { uint32_t len; uint32_t curr_prog_addr; uint32_t tmp_len; uint8_t buff[NVMCTRL_PAGE_SIZE]; struct nvm_config config; /* Check switch state to enter boot mode or application mode */ check_boot_mode(); /* * Application to be programmed from APP_START_ADDRESS defined in * conf_bootloader.h */ curr_prog_addr = APP_START_ADDRESS; /* Initialize system */ system_init(); /* Configure the SPI slave module */ configure_spi(); /* Get NVM default configuration and load the same */ nvm_get_config_defaults(&config); config.manual_page_write = false; nvm_set_config(&config); /* Turn on LED */ port_pin_set_output_level(BOOT_LED, false); /* Get the length to be programmed */ len = get_length(); do { /* Get remaining or NVMCTRL_PAGE_SIZE as block length */ tmp_len = min(NVMCTRL_PAGE_SIZE, len); /* Acknowledge last received data */ send_ack(); /* Read data from SPI master */ fetch_data(buff, tmp_len); /* Program the data into Flash */ program_memory(curr_prog_addr, buff, tmp_len); /* Increment the current programming address */ curr_prog_addr += tmp_len; /* Update the length to remaining length to be programmed */ len -= tmp_len; /* Do this for entire length */ } while (len != 0); /* Acknowledge last block */ send_ack(); /* Reset module and boot into application */ NVIC_SystemReset(); while (1) { /* Inf loop */ } }
/** * \brief Main application */ int main(void) { char test_file_name[] = "0:sd_image.bin"; FRESULT res; FATFS fs; FIL file_object; uint32_t len=0; uint32_t curr_prog_addr=APP_START_ADDRESS; struct nvm_config config; UINT iRead=0; check_boot_mode(); system_init(); delay_init(); irq_initialize_vectors(); cpu_irq_enable(); /* Initialize SD MMC stack */ sd_mmc_init(); nvm_get_config_defaults(&config); nvm_set_config(&config); /* Turn ON LED */ port_pin_set_output_level(BOOT_LED, false); #ifdef __DEBUG_PRINT__ serial_port_init(); printf("\x0C\n\r-- SD/MMC Card FatFs Boot Loader --\n\r"); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); printf("Please plug an SD/MMC card in slot.\n\r"); #endif /* Wait card present and ready */ sd_mmc_ready(); memset(&fs, 0, sizeof(FATFS)); res = f_mount(LUN_ID_SD_MMC_0_MEM, &fs); if (FR_INVALID_DRIVE == res) { #ifdef __DEBUG_PRINT__ printf("[FAIL] Mounting SD card failed result= %d\r\n", res); #endif } #ifdef __DEBUG_PRINT__ printf("Mounting the SD card successful...\r\n"); #endif res =f_open(&file_object,(const char *)test_file_name,FA_READ); if(res != FR_OK) error_fatal(FILE_OPEN_ERROR); do { if(file_object.fsize > MAX_CODE_SIZE) error_fatal(MAX_SIZE_ERROR); res = f_read(&file_object, (void *) buff, MAX_BUF_SIZE, &iRead); if(res != FR_OK) error_fatal(FILE_READ_ERROR); /* Program the read data into Flash */ if(iRead) { program_memory(curr_prog_addr, buff,iRead); #ifdef __DEBUG_PRINT__ printf("*"); #endif } /* Increment the current programming address */ curr_prog_addr += iRead; len += iRead; if(len > MAX_CODE_SIZE) error_fatal(MAX_SIZE_ERROR); /* Do this till end of file */ } while (iRead != 0); #ifdef __DEBUG_PRINT__ printf("\r\n[PROGRAMMING COMPLETED]..Resetting !!!!\r\n"); #endif // Intentionally not closing the file object to reduce code size !!!. start_application(); while(1); // Should have reset by now !!!. }