Пример #1
0
/**
 * 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_page_buffer(FOURBYTES *page, 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.
   */
  int istate;
  int status;
  if (page_num + flash_start_page >= FLASH_MAX_PAGES) return -3;
  if (VINTPTR(page) != &(FLASH_BASE[page_num*FLASH_PAGE_SIZE])) return -4;
  /* We must disbale interrupts. However we need to try and ensure that all
   * current interrupt activity is complete before we do that. We talk to
   * the avr every 1ms and this uses interrupt driven I/O so we try to make
   * sure this is complete.
   */
  // Allow any playing sound to complete
  sound_wait();

  // Turn off timer tick call backs
  systick_suspend();
   	
  // Wait until next tick
  systick_wait_ms(1);
 
  // Force a tick to talk to the avr
  nxt_avr_1kHz_update();
 
  // 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();

  // Write the buffer to the selected page
  status = flash_write(page_num + flash_start_page);
  
  // 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 -2;
  return FLASH_PAGE_SIZE*sizeof(U32);
}
Пример #2
0
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;
}