static void data_storage(uint32_t data[], uint32_t len, uint8_t pgnum) { uint32_t * addr; uint8_t patwr; uint32_t i = 0; uint32_t pg_size; uint32_t pg_num; pg_size = NRF_FICR->CODEPAGESIZE; pg_num = pgnum; // There is 4K bytes in one page, datasheet suggest write small packet one time to avoid interrupt BLE operation // Start address: addr = (uint32_t *)(pg_size * pg_num); // Erase page: flash_page_erase(addr); while (i < len) { patwr = data[i]; flash_word_write(addr, (uint32_t)patwr); ++addr; ++i; } }
// Запись флага. modbus_rtu_error_t boot_modbus_on_write_coil(uint16_t address, modbus_rtu_coil_value_t value) { switch(address){ default: return MODBUS_RTU_ERROR_INVALID_ADDRESS; case BOOT_MODBUS_COIL_PAGE_ERASE: if(value == MODBUS_RTU_COIL_ON){ if(!flash_unlock()) return MODBUS_RTU_ERROR_NONRECOVERABLE; if(!flash_page_erase(flash_page_address(boot_modbus.page_number))){ flash_lock(); return MODBUS_RTU_ERROR_NONRECOVERABLE; } flash_lock(); } break; case BOOT_MODBUS_COIL_RUN_APP: if(value == MODBUS_RTU_COIL_ON){ if(!boot_modbus.run_app_callback) return MODBUS_RTU_ERROR_NONRECOVERABLE; boot_modbus.run_app_callback(); } break; } return MODBUS_RTU_ERROR_NONE; }
uint8_t flash_data_set_write(float acc_g_xyz[3], float cal_acc_g_xyz[3], uint8_t event_ID, uint32_t UTC) { uint32_t temp; if (buffer_event_count==BUFFER_EVENT_SIZE) return buffer_event_count;// buffer full return immediately if (event_ID) { is_event_detected = true; event_addr[w_buffer_event_ptr] = w_addr_ptr; event_type[w_buffer_event_ptr] = event_ID; event_utc[w_buffer_event_ptr] = UTC; } if (w_addr_ptr%page_size == 0) flash_page_erase((uint32_t*)w_addr_ptr);// new page, erase before writing if (acc_g_xyz != NULL) { flash_word_write((uint32_t*)w_addr_ptr, w_flash_dummy1++); } w_addr_ptr+=4; if (acc_g_xyz != NULL) { flash_word_write((uint32_t*)w_addr_ptr, w_flash_dummy1++); } w_addr_ptr+=4; if (cal_acc_g_xyz != NULL) { temp = (uint32_t) ((float)(cal_acc_g_xyz[0]+16)*100)<<16 | (uint32_t) ((float)(cal_acc_g_xyz[1]+16)*100); flash_word_write((uint32_t*)w_addr_ptr, temp); } w_addr_ptr+=4; if (cal_acc_g_xyz != NULL) { temp = (uint32_t) ((float)(cal_acc_g_xyz[2]+16)*100); flash_word_write((uint32_t*)w_addr_ptr, temp); } w_addr_ptr+=4; if (w_addr_ptr == w_r_addr[w_buffer_event_ptr]+four_page_size) // ring buffering management, round in 4 pase size w_addr_ptr = w_r_addr[w_buffer_event_ptr]; // if (w_addr_ptr%four_page_size == 0) // bp++; if (is_event_detected) count_down_7s_50Hz--; if (count_down_7s_50Hz==0) { is_event_detected = false; count_down_7s_50Hz = 7*50; w_buffer_event_ptr++; if(w_buffer_event_ptr==BUFFER_EVENT_SIZE) w_buffer_event_ptr = 0; w_addr_ptr = w_r_addr[w_buffer_event_ptr]; buffer_event_count++; } return buffer_event_count; }
void save_settings(const FeatRep_DongleSettings __xdata * pNewSettings) { // get the next empty slot FeatRep_DongleSettings save_img; int8_t new_ndx = get_ndx_of_current_settings() + 1; // if all slots are full if (new_ndx == BLOCKS_CAPACITY) { // erase the two pages and start from the beginning flash_page_erase(DATA0_PAGE_NUM); flash_page_erase(DATA1_PAGE_NUM); new_ndx = 0; } memcpy(&save_img, pNewSettings, sizeof(save_img)); save_img.report_id = 0x00; // this is not really the report ID, it's just a flag that // shows if the block is used or not // save the new settings flash_bytes_write((uint16_t)(DATA0_ADDR + new_ndx), (uint8_t __xdata *) &save_img, sizeof(save_img)); }
/** * @brief Function for application main entry. */ int main(void) { uint32_t *addr; uint8_t patwr; uint8_t patrd; uint8_t patold; uint32_t i; uint32_t pg_size; uint32_t pg_num; init(); patold = 0; pg_size = NRF_FICR->CODEPAGESIZE; pg_num = NRF_FICR->CODESIZE - 1; // Use last page in flash while (true) { // Start address: addr = (uint32_t *)(pg_size * pg_num); // Erase page: flash_page_erase(addr); i = 0; do { // Read pattern from port 0 (pins0-7), and write it to flash: patwr = nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0); if (patold != patwr) { patold = patwr; flash_word_write(++addr, (uint32_t)patwr); i += 4; } // Read pattern from flash and write it to port 1 (pins8-15): patrd = (uint8_t)*addr; nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, patrd); } while (i < pg_size); } }
void main(void) { flash_page_erase(0x400); // apaga a página do endereço 0x000400 while(1); // loop }
void parse_commands(void) { uint8_t count = 0, tmp; if(page_write) { // Multiply nblock with 64 to get block start address in flash: flash_bytes_write(nblock << 6, out1buf, USB_EP1_SIZE); nblock++; nblocks++; in1buf[0] = 0; count = 1; if (nblocks == (FLASH_PAGE_SIZE/USB_EP1_SIZE)) { page_write = false; } } else { switch(out1buf[0]) { case CMD_FIRMWARE_VERSION: in1buf[0] = FW_VER_MAJOR; in1buf[1] = FW_VER_MINOR; count = 2; break; case CMD_FLASH_ERASE_PAGE: flash_page_erase(out1buf[1]); used_flash_pages[out1buf[1]] = false; in1buf[0] = 0; count = 1; break; case CMD_FLASH_WRITE_INIT: // Eight 64 bytes bulk packets <- PC follow after this command if (used_flash_pages[out1buf[1]]) { flash_page_erase(out1buf[1]); } used_flash_pages[out1buf[1]] = 1; nblock = (uint16_t)out1buf[1] << 3; // Multiply page number by 8 to get block number nblocks = 0; page_write = true; in1buf[0] = 0; count = 1; break; case CMD_FLASH_READ: // Read one USB_EP1_SIZE bytes block from the address given // by out1buf[1] << 6 and MS bit set by CMD_FLASH_SELECT_HALF // below: nblock = (nblock & 0xff00) | (uint16_t)out1buf[1]; if (RDIS) { // RDISMB is set. Will return 0x00 for pages that are in use and 0xff // for unused pages. if (used_flash_pages[nblock >> 3]) tmp = 0x00; else tmp = 0xff; for(count=0; count<USB_EP1_SIZE; count++) in1buf[count] = tmp; } else flash_bytes_read((uint16_t)nblock<<6, in1buf, USB_EP1_SIZE); count = USB_EP1_SIZE; break; case CMD_FLASH_SET_PROTECTED: count = 1; INFEN = 1; if (rdismb != 0xff) { in1buf[0] = 1; } else { flash_byte_write((uint16_t)&rdismb, 0x00); in1buf[0] = 0; } INFEN = 0; break; case CMD_FLASH_SELECT_HALF: // When outbuf[1] = 0 program the lower half of the 32K bytes flash // and when outbuf[1] = 1 program the upper part: if (out1buf[1] == 1) nblock = (nblock & 0x00ff) | 0x0100; else nblock &= 0x00ff; in1buf[0] = 0; count = 1; break; default: break; }