/** * Write a page from the supplied flash buffer to flash memory * The flash buffer must have been obtained through a call to * flash_get_page_buffer, before making this call * returns > 0 number of bytes written < 0 error * Error returns: * -1 Timeout waiting for TWI to complete * -2 Timeout waiting for flash write to complete * -3 Bad page number * -4 bad flash buffer */ int flash_write(int page_num) { /* Write page to flash memory. * This function must run out of ram and while it executes no other code * (especially any flash resident) code must run. This is becuase the * flash memory is only a single plane and can not be accessed for both read * and write at the same time. */ // Write the buffer to the selected page FLASH_CMD_REG = (0x5A000001 + (((page_num) & 0x000003FF) << 8)); return wait_flash_ready(); }
void mem_to_flash(u_long address, int numbytes, u_long flash_adr) { int thisbytes; thisbytes = FLASH_PAGE_BYTES; while (numbytes > 0) { wait_flash_ready(); if (numbytes < FLASH_PAGE_BYTES) { thisbytes = numbytes; } jtag_out(address, thisbytes, flash_adr); jtag_set_mem(MC_FMR, MCLK_MHZ << 16); jtag_set_mem(MC_FCR, ((flash_adr & 0x1ff80) << 1) | 0x5a000001); flash_adr += thisbytes; address += thisbytes; numbytes -= thisbytes; } }
int flash_write_page(int start_page, U32 *page, int page_num) { int i, istate; int status; if (page_num + start_page > 1023) return 0; systick_suspend(); systick_wait_ms(1); nxt_avr_1kHz_update(); // modified based on the latest leJOS source (April 16th takashic) // Wait for it to complete status = wait_twi_complete(); if (status != 0) return -1; // Now we can turn off all ints istate = interrupts_get_and_disable(); for (i = 0; i < 64; i++) FLASH_BASE[(page_num*64)+i] = page[i]; FLASH_CMD_REG = (0x5A000001 + (((page_num + start_page) & 0x000003FF) << 8)); status = wait_flash_ready(); // modified based on the latest leJOS source (April 16th takashic) // Turn ints back on if (istate) interrupts_enable(); // Ensure that we are back in-sync. systick_wait_ms(1); // Allow call backs on 1ms tick systick_resume(); if (!(status & AT91C_MC_FRDY)) return -1; return 1; }