Example #1
0
File: nf.c Project: InSoonPark/asf
//! \brief Read the ID of the Nand-Flash
//!
//! \param read_id_cmd  Read_id command (NF_READ_ID_CMD, NF_READ_ID2_CMD)
//! \param nf_num       Nand Flash number
//!
//! \return :
//!   MSB0(ret) (MSB) is the Maker Code,
//!   MSB1(ret) is the Device Id,
//!   MSB2(ret) is 3rd byte returned,
//!   MSB3(ret) (LSB) is 4th byte returned.
//!
//! \pre <code>nf_init()</code> should have been called before.
//!
U32 nf_read_id( U8 read_id_cmd, U8 nf_num )
{
   U32 ret;

   nf_select( nf_num );
   nf_wait_busy();
   //nf_force_CE();
   nf_wr_cmd (read_id_cmd);
   nf_wr_addr( 0 );

   MSB0(ret)= nf_rd_data(); // Maker Code
   MSB1(ret)= nf_rd_data(); // Device Id
   MSB2(ret)= nf_rd_data(); // extra
   MSB3(ret)= nf_rd_data(); // extra (Multi Plane Support)

   //Nfc_action( NFC_ACT_ASSERT_CE, NFC_EXT_NOP);
   return ret;
}
Example #2
0
File: nf.c Project: InSoonPark/asf
void nfc_print_block(U16 block_addr, U8 dev_id)
{
   _MEM_TYPE_SLOW_ U32 page_addr=(U32)block_addr*((U8)1<<G_SHIFT_BLOCK_PAGE);
   _MEM_TYPE_SLOW_ U16 n_bytes;
   _MEM_TYPE_SLOW_ U16 i_byte;
   _MEM_TYPE_SLOW_ U8  i_page;

   trace("\n\rDisplay block 0x");
   trace_hex( MSB(block_addr) );
   trace_hex( LSB(block_addr) );

   n_bytes= ( Is_nf_512() )
   ?  512   // 512B page access
   :  2048  // 2KB  page access
   ;
   nf_select( dev_id );
   //for ( i_page=(U8)1<<G_SHIFT_BLOCK_PAGE ; i_page!=0 ; i_page--, page_addr++ )
   for( i_page=0 ; i_page<64 ; i_page++, page_addr++ )
   {
      trace("\n\rOpening page 0x");
      trace_hex( MSB0(page_addr) );
      trace_hex( MSB1(page_addr) );
      trace_hex( MSB2(page_addr) );
      trace_hex( MSB3(page_addr) );
      #if 0
      nf_open_page_read( page_addr, 0 );
      for( i_byte=0 ; i_byte<n_bytes ; )
      {
         if( !(i_byte%32) )
         {
            trace("\n\r0x");
            trace_hex( MSB(i_byte) );
            trace_hex( LSB(i_byte) );
            trace(" 0x");
         }
         else if( !(i_byte%16) ) trace("   ");
         else if( !(i_byte% 8) ) trace(" ");
         trace_hex( nf_rd_data() );
         trace_hex( nf_rd_data() );
         trace_hex( nf_rd_data() );
         trace_hex( nf_rd_data() );
         i_byte+=4;
      }
      #else
      nf_open_page_read( page_addr, n_bytes );
      #endif
      trace("\n\rSpare zone: 0x");
      for( i_byte=4*4 ; i_byte!=0 ; i_byte-- )
      { // discard spare zone
         if( i_byte%4==0 ) trace_nl();
         trace_hex( nf_rd_data() );
         trace_hex( nf_rd_data() );
         trace_hex( nf_rd_data() );
         trace_hex( nf_rd_data() );
      }
      trace("\n\r");
   }
   trace("\n\rOther way to access spare zone: 0x");
   page_addr=(U32)block_addr*((U8)1<<G_SHIFT_BLOCK_PAGE);
   nf_open_page_read( page_addr, NF_SPARE_POS );
   i_byte=Nfc_rd_data_fetch_next();
   {
      for ( i_byte=4*4 ; i_byte!=0 ; i_byte-- )
      { // discard spare zone
         trace_hex( Nfc_rd_data_fetch_next() );
         trace_hex( Nfc_rd_data_fetch_next() );
         trace_hex( Nfc_rd_data_fetch_next() );
         trace_hex( Nfc_rd_data_fetch_next() );
      }
      trace("\n\r");
   }
}
Example #3
0
/*! \brief Main function.
 */
int main(void)
{
  bool   valid_block_found[NF_N_DEVICES];
  U32    u32_nf_ids, i_dev, i_block;
  U8     maker_id, device_id, byte3;
  U32    i, time_s, time_e;
  U8     data;

  // start init
  sysclk_init();

  // Enable clock for require module
  sysclk_enable_hsb_module(SYSCLK_EBI);
  sysclk_enable_pbb_module(SYSCLK_SMC_REGS);
  sysclk_enable_pbb_module(SYSCLK_HMATRIX);

  // Initialize the board.
  // The board-specific conf_board.h file contains the configuration of the board
  // initialization.
  board_init();

  init_stdio();

#ifdef NF_ADDON // addon nandflash board for EVK1104 (not mounted by default)
  // Unselect NF on board
  gpio_set_gpio_pin(AVR32_PIN_PX53);
  gpio_set_gpio_pin(AVR32_PIN_PX52);
#endif

  nf_init(sysclk_get_cpu_hz());
  nf_unprotect();

  printf("\x0C");
  printf("Nand Flash example.\r\n===================\r\n\r\n");

  // - Simple test of the NF communication through the SMC.
  // - Find all bad blocks.
  // - Find a valid block for the remaining tests.
  nf_reset_nands(NF_N_DEVICES);

  printf("\tDetecting Nand Flash device(s).\r\n");
  for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
  {
    // Performs some init here...
    valid_block_found[i_dev] = false;

    // Test Maker and Device ids
    u32_nf_ids = nf_read_id( NF_READ_ID_CMD, i_dev );
    maker_id  = MSB0(u32_nf_ids);
    device_id = MSB1(u32_nf_ids);
    byte3     = MSB3(u32_nf_ids);
    printf("\t\tNF %ld: [Maker=0x%02x] [Device=0x%02x] [byte3=0x%02x]\r\n", i_dev, maker_id, device_id, byte3);
    if( maker_id==M_ID_MICRON )
    {
      printf("\t\t       Micron chip");
      if( (device_id==0xDA) && (byte3==0x15) )
        printf("- MT29F2G08AACWP device\r\n");
      else if( (device_id==0xDA) && (byte3==0x95) )
        printf("- MT29F2G08AADWP device\r\n");
      else
      {
        printf("- *** Error: unexpected chip detected. Please check the board settings and hardware.\r\n");
        return -1;
      }
    }
    else
    {
      printf("\t\t       *** Error: unexpected chip detected. Please check the board settings and hardware.\r\n");
      return -1;
    }
  }

  printf("\r\n\tTesting bad blocks.\r\n");
  for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
  {
    printf("\t\tNF %ld:\r\n", i_dev);
    nf_select(i_dev);
    for( i_block=0 ; i_block<G_N_BLOCKS ; i_block++ )
    {
      nf_open_page_read( nf_block_2_page(i_block), NF_SPARE_POS + G_OFST_BLK_STATUS );
      if( (nf_rd_data()!=0xFF) )
      { // The block is bad.
        printf("\t\t\tBlock %ld (0x%lx) is bad.\r\n", i_block, i_block);
      }
      else
      {
        if( !valid_block_found[i_dev] )
        {
          valid_block_found[i_dev]= true;
          valid_block_addr[i_dev] = i_block;
          printf("\t\t\tFirst valid block is at address %ld (0x%lx).\r\n", i_block, i_block);
        }
      }
    }
  }

  for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
    if( !valid_block_found[i_dev] )
    {
      printf("Error %d\r\n", __LINE__);
      return 0;
    }



  // - Ensure good NF behaviour through simple commands.
  //   Erase, Program, Read
  // - Measures NF timings.
  printf("\r\n\tMeasuring NF timings.\r\n");
  for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
  {
    printf("\t\tNF %ld:\r\n", i_dev);
    nf_select(i_dev);
    nf_erase_block( nf_block_2_page(valid_block_addr[0]), false);
    time_s = Get_sys_count();
    nf_wait_busy();
    time_e = Get_sys_count();

    // Verify that the block is erased.
    nf_open_page_read( nf_block_2_page(valid_block_addr[0]), 0);
    for( i= 0; i<2048 ; i++ )
    {
      data = nf_rd_data();
      if( data!=0xFF )
      {
        printf("\tError: offset %d is not erased (read %d).\r\n", (U8)i, data);
        return 0;
      }
    }
    printf("\t\t\tTime to erase a page:%ld cy (%ld us)\r\n", time_e-time_s, cpu_cy_2_us(time_e-time_s, sysclk_get_cpu_hz()));

    nf_open_page_write( nf_block_2_page(valid_block_addr[0]), 0);
    for( i=0 ; i<2048 ; i++ )
      nf_wr_data(i%256);
    nf_wr_cmd(NF_PAGE_PROGRAM_CMD);

    time_s = Get_sys_count();
    nf_wait_busy();
    time_e = Get_sys_count();
    printf("\t\t\tTime to program a page:%ld cy (%ld us)\r\n", time_e-time_s, cpu_cy_2_us(time_e-time_s, sysclk_get_cpu_hz()));

    time_s = Get_sys_count();
    nf_open_page_read( nf_block_2_page(valid_block_addr[0]), 0);
    time_e = Get_sys_count();
    printf("\t\t\tTime to access to a page:%ld cy (%ld us)\r\n", time_e-time_s, cpu_cy_2_us(time_e-time_s, sysclk_get_cpu_hz()));
    for( i= 0; i<2048 ; i++ )
    {
      data = nf_rd_data();
      if( data!= i%256)
      {
        printf("\tError: expect %d, read %d\r\n", (U8)i, data);
        return 0;
      }
    }
  }

  printf("Example DONE\r\n");

  return 0;
}