⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nanddriver.c

📁 at91rm9200 的 vxworks bsp包。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------*/

static void tffsset16 (unsigned char FAR0 *dst,
		       unsigned char      val,
		       int                len)
{
  register unsigned short  wval = ((unsigned short)val << 8) | val;
  register int   i = 0;

  /* set data in 16-bit words */
  for (i = 0;  i < (len >> 1);  i++)
    *((unsigned short *) dst + i) = wval;

  /* set last byte (if any) */
  if (len & 1)
    *(dst + len-1) = val;
}

/*----------------------------------------------------------------------*/
/*                      m a p C o n t I n t e r f a c e			*/
/*									*/
/* Select flash device.							*/
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	address		: Address in flash.				*/
/*									*/
/* Returns:								*/
/*	Pointer to the mapped window.					*/
/*                                                                      */
/*----------------------------------------------------------------------*/

static Interface mapContInterface(FLFlash vol, CardAddress address)
{
  Interface interface = (Interface) flMap(vol.socket,(CardAddress)0);
  LEushort  tmp;

  toLE2(*((LEushort FAR0 *) &tmp), (unsigned short)(address / (vol.chipSize * vol.interleaving)));

  /* Select flash device with 16-bit write */
  *((unsigned short *) &interface->deviceSelector) = *((unsigned short *) &tmp);

  return interface;
}


/*----------------------------------------------------------------------*/
/*                      w a i t F o r R e a d y				*/
/*									*/
/* Wait for the selected device to be ready.				*/
/*									*/
/* Parameters:                                                          */
/*	Interface	: Pointer tot the window.			*/
/*									*/
/* Returns:								*/
/*	TRUE if device is ready, FALSE if timeout error.		*/
/*                                                                      */
/*----------------------------------------------------------------------*/

static FLBoolean waitForReady (Interface interface)
{
  int i;

  for( i = 0;  i < 20000;  i++)
  {
    if( (~interface->signals.w & DBL(RB)) == 0)
      return TRUE ;                     /* ready at last..*/
  }

#ifdef DEBUG_PRINT
  DEBUG_PRINT("Debug: timeout error in NFDC 2048.\n");
#endif

  return FALSE;                       /* timeout error  */
}


/*----------------------------------------------------------------------*/
/*		          c o m m a n d					*/
/*									*/
/* Latch command byte to selected flash device.				*/
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	Interface       : Pointer to window.				*/
/*	code		: Command to set.				*/
/*                                                                      */
/*----------------------------------------------------------------------*/

static void command(FLFlash vol, Interface interface, unsigned char code)
{
  interface->signals.w = DBL( CLE | NOT_WP | CE ) ;

  if ( vol.interleaving == 1 )                          /* 8-bit */
    interface->io[0].b =      code ;
  else                                              /* 16-bit */
    interface->io[0].w = DBL( code ) ;

  interface->signals.w = DBL(       NOT_WP ) ;
}

#endif

/*----------------------------------------------------------------------*/
/*		          m a k e C o m m a n d				*/
/*									*/
/* Set Page Pointer to Area A, B or C in page.				*/
/*                                                                      */
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	cmd	: receives command relevant to area			*/
/*	addr	: receives the address to the right area.		*/
/*	modes	: mode of operation (EXTRA ...)				*/
/*                                                                      */
/*----------------------------------------------------------------------*/

static void makeCommand (FLFlash vol, PointerOp *cmd, CardAddress *addr , int modes )
{
  unsigned short offset;

  if ( !(vol.flags & BIG_PAGE) ) 
  {
    if (modes & EXTRA) {
      offset = *addr & (SECTOR_SIZE - 1);
      *cmd = AREA_C;
      if (vol.interleaving == 1) {
	if (offset < 8)     	/* First half of extra area */
	  *addr += 0x100;	/* ... assigned to 2nd page */
	else			/* Second half of extra area */
	  *addr -= 8;		/* ... assigned to 1st page */
      }
    }
    else
      *cmd = AREA_A;
  }
  else 
  {
    offset = (unsigned short)(*addr) & thisVars->pageMask ;   /* offset within device Page */

    *addr -= offset;          	/* align at device Page*/

    if (vol.interleaving == 2 && offset >= 512)
      offset += 16;		/* leave room for 1st extra area */
    if (modes & EXTRA)
      offset += SECTOR_SIZE;

    if ( offset < thisVars->pageAreaSize )  /* starting in area A*/
      *cmd = AREA_A ;
    else if ( offset < thisVars->pageSize )    /* starting in area B */
      *cmd = AREA_B ;
    else                                  /* got into area C*/
      *cmd = AREA_C ;

    offset &= (thisVars->pageAreaSize - 1) ;          /* offset within area of device Page*/
    *addr += offset ;
  }
}




/*----------------------------------------------------------------------*/
/*		          s e t A d d r e s s				*/
/*									*/
/* Latch address to selected flash device.				*/
/*									*/
/* Parameters:                                                          */
/*	vol		: Pointer identifying drive			*/
/*	Interface	: Pointer to window.				*/
/*	address		: address to set.				*/
/*                                                                      */
/*----------------------------------------------------------------------*/

static void setAddress(FLFlash vol, CardAddress address )
{
  address &= (vol.chipSize * vol.interleaving - 1) ;  /* address within flash device*/
  address /= vol.interleaving ;                         /* .................... chip */

  if ( vol.flags & BIG_PAGE )
  {
    /*
       bits  0..7     stays as are
       bit      8     is thrown away from address
       bits 31..9 ->  bits 30..8
    */
    address = ((address >> 9) << 8)  |  ((unsigned char)address) ;
  }

  /* send address to flash in the following sequence: */
  /*      bits  7...0 first                           */
  /*      bits 15...8 next                            */
  /*      bits 23..16 finally                         */
  
  WRITE_NAND_ADDRESS((unsigned char)address);
  WRITE_NAND_ADDRESS((unsigned char)(address >> 8));
  WRITE_NAND_ADDRESS((unsigned char)(address >> 16));
  #if 0
  TFFS_CDSN_DEBUG_PRINT((DEBUG_TFFS_READ | DEBUG_TFFS_WRITE), ("%s: col %x row1 %x row2 %x.\n", 
  	               __FUNCTION__, 
  	               (unsigned char)address,
  	               (unsigned char)(address >> 8),
  	               (unsigned char)(address >> 16)));  
  #endif
}


/*----------------------------------------------------------------------*/
/*		          r e a d C o m m a n d				*/
/*									*/
/* Issue read command.							*/
/*									*/
/* Parametes:                                                          	*/
/*	vol		: Pointer identifying drive			*/
/* 	Interface       : Pointer to window.				*/
/*      cmd		: Command to issue (according to area). 	*/
/*	addr		: address to read from.				*/
/*									*/
/*----------------------------------------------------------------------*/

static void readCommand (FLFlash vol, PointerOp  cmd, CardAddress addr)
{
  WRITE_NAND_COMMAND(cmd);
  #if 0
  TFFS_CDSN_DEBUG_PRINT(DEBUG_TFFS_READ, ("%s: cmd %x.\n", __FUNCTION__, cmd));
  #endif
  setAddress (&vol, addr);
  nand_flash_wait_ready();
}


/*----------------------------------------------------------------------*/
/*		          w r i t e C o m m a n d			*/
/*									*/
/* Issue write command.							*/
/*									*/
/* Parametes:                                                          	*/
/*	vol		: Pointer identifying drive			*/
/* 	interface	: Pointer to window.				*/
/*      cmd		: Command to issue (according to area). 	*/
/*	addr		: address to write to.				*/
/*									*/
/*----------------------------------------------------------------------*/

static void writeCommand (FLFlash vol, PointerOp  cmd, CardAddress addr)
{
  if (vol.flags & FULL_PAGE) 
  {
    nand_flash_reset_chip();
  }
  WRITE_NAND_COMMAND(cmd);    /* move flash pointer to respective area of the page  */
  #if 0
  TFFS_CDSN_DEBUG_PRINT(DEBUG_TFFS_WRITE, ("%s: cmd %x.\n", __FUNCTION__, cmd));
  #endif
  WRITE_NAND_COMMAND(CMD_WRITE);       /* start data loading for write  */
  setAddress (&vol, addr) ;
}

/*----------------------------------------------------------------------*/
/*		          w r i t e E x e c u t e			*/
/*									*/
/* Execute write.							*/
/*									*/
/* Parametes:								*/
/*	vol		: Pointer identifying drive			*/
/*	interface	: Pointer to window.				*/
/* Returns:                                                          	*/
/*	FLStatus	: 0 on success, otherwise failed.		*/
/*									*/
/*----------------------------------------------------------------------*/

static FLStatus writeExecute (FLFlash vol)
{
  WRITE_NAND_COMMAND(CMD_WRITE2); /* execute page program*/
  if (nand_flash_wait_ready() == ERROR)
  {
    TFFS_CDSN_DEBUG_PRINT(DEBUG_TFFS_ALWAYS, ("%s: time out.\n", __FUNCTION__));
    return flTimedOut;
  }

  if( readStatus() & NAND_FLASH_IO_0)
  {
    TFFS_CDSN_DEBUG_PRINT(DEBUG_TFFS_ALWAYS, ("%s: write failed.\n", __FUNCTION__));
    return flWriteFault ;
  }

  return flOK ;
}



/*----------------------------------------------------------------------*/
/*		          r e a d O n e S e c t o r			*/
/*									*/
/* Read up to one 512-byte block from flash.				*/
/*									*/
/* Parameters:								*/
/*	vol		: Pointer identifying drive			*/
/* 	address	: Address to read from.					*/
/*	buffer	: buffer to read to.					*/
/*	length	: number of bytes to read (up to sector size).		*/
/*	modes	: EDC flag etc.						*/
/*									*/
/* Returns:                                                          	*/
/*	FLStatus: 0 on success, otherwise failed.			*/
/*									*/
/*----------------------------------------------------------------------*/

static FLStatus readOneSector (FLFlash vol,
			     CardAddress address,  /* starting flash address*/
			     char FAR1 *buffer,     /* target buffer */
			     int length,           /* bytes to read */
			     int modes)            /* EDC flag etc.*/
{
  FLStatus  status = flOK;
  PointerOp   cmd;
  CardAddress addr  = address;
  
  ENABLE_NAND_CE; 

  /* move flash pointer to areas A,B or C of page*/
  makeCommand (&vol, &cmd, &addr, modes) ;

  readCommand (&vol, cmd, addr);

  tffscpy8b((unsigned char*)buffer, (const unsigned char *) AT91_NANDFLASH_BASE, length );
  
  DISABLE_NAND_CE; 

  return status;

}



/*----------------------------------------------------------------------*/
/*		          w r i t e O n e S e c t o r			*/
/*									*/
/* Write data in one 512-byte block to flash.				*/
/* Assuming that EDC mode never requested on partial block writes.    	*/
/*									*/
/* Parameters:								*/
/*	vol		: Pointer identifying drive			*/
/* 	address	: Address of sector to write to.			*/
/*	buffer	: buffer to write from.					*/
/*	length	: number of bytes to write (up to sector size).		*/
/*	modes	: OVERWRITE, EDC flags etc.				*/
/*									*/
/* Returns:                                                          	*/
/*	FLStatus: 0 on success, otherwise failed.			*/
/*									*/
/*----------------------------------------------------------------------*/

static FLStatus writeOneSector(FLFlash vol,
			     CardAddress address,    /* target flash addres  */
			     const char FAR1 *buffer, /* source RAM buffer   */
			     int length,             /* bytes to write (up to BLOCK) */
			     int modes)              /* OVERWRITE, EDC flags etc.  */
{
  FLStatus    status;
  PointerOp cmd;

  if (flWriteProtected(vol.socket))
    return flWriteProtect;

  ENABLE_NAND_CE; 

  /* move flash pointer to areas A,B or C of page  */
  makeCommand (&vol, &cmd, &address, modes) ;
  writeCommand(&vol, cmd, address);

  /* load data and syndrom*/                                               
  tffscpy8b((unsigned char FAR0 *)AT91_NANDFLASH_BASE,             
               (const unsigned char *)buffer,
               length);

  if(modes & EDC)
  {
    unsigned short extraBytes[SYNDROM_BYTES / sizeof(unsigned short) + 1];
	
    /* Read the ECC syndrom*/
    extraBytes[0] = extraBytes[1] = extraBytes[2] = 0xffff;
    extraBytes[SYNDROM_BYTES / sizeof(unsigned short)] = 0x5555;	/* Anand mark */

    tffscpy8b((unsigned char FAR0 *) AT91_NANDFLASH_BASE, (const unsigned char *)extraBytes,
                                            sizeof extraBytes);
  }

  status = writeExecute(&vol);

  DISABLE_NAND_CE; 

  return status;
}


    /*觚

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -