Example #1
0
//! Initializes the nand flash memory driver.
//!
//! The device identification is performed to initialize the
//! driver accordingly
//!
//! @param none
//!
//! @return none
//!
void nf_init ( void )
{
   trace("NF init\n\r");
   g_nf_init=FALSE;
//   s_pending_write=FALSE;

#if (NF_GENERIC_DRIVER==TRUE)
#error Check this init...
   g_n_zones             = NF_N_ZONES;
   g_n_blocks            = NF_N_BLOCKS;
   g_shift_block_page    = NF_SHIFT_BLOCK_PAGE;
   g_shift_page_byte     = NF_SHIFT_PAGE_BYTE;
   s_shift_sector_byte   = NF_SHIFT_SECTOR_BYTE;
   g_n_row_cycles        = NF_N_ROW_CYCLES;

   if ( Is_nf_2k() ) // 2KB pages
   {
      g_ofst_blk_status     = 0;
   }
   if ( Is_nf_512() ) // 512B pages
   {
      g_ofst_blk_status     = 5;
   }

   s_shift_log_page_sector  = G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE + NF_SHIFT_N_DEVICES;
   s_shift_log_block_sector = s_shift_log_page_sector + G_SHIFT_BLOCK_PAGE;
#endif

   g_cache_lut.ctrl.valid = FALSE; g_cache_lut.ctrl.dirty = FALSE;
   g_cache_fbb.ctrl.valid = FALSE; g_cache_fbb.ctrl.dirty = FALSE;
   g_last_log_sector= 0xFFFFFFFF;
}
Example #2
0
File: nf.c Project: InSoonPark/asf
//! \brief Mark a block as 'invalid' by clearing it entirely.
//!
//! \param page_addr          absolute page address of the block
//!
//! \pre <code>nf_init()</code> should have been called before.
//! The device which holds this bad block should have been selected
//! before with <code>nf_select( id )</code>.
//!
void nf_mark_bad_block(U32 page_addr)
{
   U8  n_bytes;
   U8  i_byte;
   U8  i_page;


   n_bytes= ( Is_nf_512() )
   ?  16  // 512B page access
   :  64  // 2KB  page access
   ;
   // Erasing the block is mandatory to prevent partial programming
   // (some 512B NF does support partial prog, but not after a copy back command).
   nf_erase_block( page_addr, true );
   for ( i_page=(U8)1<<G_SHIFT_BLOCK_PAGE ; i_page!=0 ; i_page--, page_addr++ )
   {
      nf_open_page_write( page_addr, NF_SPARE_POS-8 );
      nf_wr_data('A'); nf_wr_data('t');
      nf_wr_data('m'); nf_wr_data('e');
      nf_wr_data('l'); nf_wr_data(' ');
      nf_wr_data(' '); nf_wr_data(' ');
      for ( i_byte=n_bytes ; i_byte!=0 ; i_byte-=4 )
      {
         nf_wr_data(0);
         nf_wr_data(0);
         nf_wr_data(0);
         nf_wr_data(0);
      }
      nf_wr_cmd(NF_PAGE_PROGRAM_CMD); // Confirm programming
   }
}
Example #3
0
File: nf.c Project: InSoonPark/asf
//! \brief Tests the true busy. Note that we test twice the ready, since there is
//! an hardware minimum requirement between the end of the busy and the first
//! read cycle. Since the busy is not wired, the ready is tested twice.
//!
void nf_wait_busy( void )
{
   ecchrs_freeze(&AVR32_ECCHRS);
   nf_wr_cmd(NF_READ_STATUS_CMD);
   if( Is_nf_2k() )
   {
      if( G_CACHE_PROG )
      {
         while( (nf_rd_data() & NF_MASK_STATUS_T_RDY_2KB )==0 );
         while( (nf_rd_data() & NF_MASK_STATUS_T_RDY_2KB )==0 );
      }
      else
      {
         while( (nf_rd_data() & NF_MASK_STATUS_READY     )==0 );
         while( (nf_rd_data() & NF_MASK_STATUS_READY     )==0 );
      }
   }
   if( Is_nf_512() )
   {
      while( (nf_rd_data() & NF_MASK_STATUS_T_RDY_512B )==0 );
      while( (nf_rd_data() & NF_MASK_STATUS_T_RDY_512B )==0 );
   }
   ecchrs_unfreeze(&AVR32_ECCHRS);
}
Example #4
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");
   }
}