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

📄 nfc_spl_readwrite.c

📁 mx21的NAND Flash Bootloader源代码
💻 C
字号:
#ifndef __NFC_SPL_READWRITE_C_
#define __NFC_SPL_READWRITE_C_
#endif

#include "mx2.h"
#include "nfc.h"

u32 _gRowAddressCycleNum = 2;
u32 _gColAddressCycleNum = 1;
u32 _gMainPageByteSize   = 512;
u32 _gSparePageByteSize  = 16;

static void MemorySet(void* Address, u8 data, u32 ByteSize)
{
  u32 i;

  for(i=0; i<ByteSize; i++)
     *(u8 *)((u8 *)Address+i) = data;
}

static void MemoryCopy(void* SourceAddress, void* TargetAddress, u32 ByteSize)
{
  u32 i;

  for(i=0; i<(ByteSize/4); i++)
     *(u32 *)((u32 *)TargetAddress+i) = *(u32 *)((u32 *)SourceAddress+i);
}

/*****************************************************************************/

static void nfc_RAM_buffer_select(u8 BufferNum)
{
   _reg_NFC_RAM_BUF_ADDR = (u16)BufferNum;
}

/* Activate one address cycle */
static void nfc_address_input(u16 address)
{
//   printf("0x%X\n", address);
   _reg_NFC_NAND_FLASH_ADDR = address;

   _reg_NFC_NF_CONFIG2 = 0x0002;

   while(NFC_BUSY);    /* Wait for Basic Operation Complete */
}

static void nfc_address_cycle(u16 iPageNum, u8 RowAddressCycleNum, u8 iColumnCycleNum)
{
  u8 i;

  for(i=0; i<iColumnCycleNum; i++)  
    nfc_address_input(0);

  for(i=0; i<RowAddressCycleNum; i++)
    nfc_address_input( (u16)(iPageNum>>(i*8)) );
}

static void nfc_command_input(u16 command)
{
    _reg_NFC_NAND_FLASH_CMD  = command;

    _reg_NFC_NF_CONFIG2 = 0x0001;
    
    while(NFC_BUSY); /* Wait for Basic Operation Complete */
}

static void nfc_flash_data_input(void)
{
   _reg_NFC_NF_CONFIG2 = 0x0004;

   while(NFC_BUSY);
}

static void nfc_flash_data_output(void)
{
   _reg_NFC_NF_CONFIG2 = 0x0008;

   while(NFC_BUSY);
}

/*****************************************************************************/

u32 nfc_read_status(void)
{
  u32 status;

  nfc_RAM_buffer_select(3);
  nfc_command_input(NAND_CMD_READ_STATUS);
  
  _reg_NFC_NF_CONFIG2 = 0x0020; // FDO -> Read Status
  
  while(NFC_BUSY);

  status = (*(volatile u32 *)(NFC_MAB3_BASE)) & 0xFF ;
  
  return status;
}

u32 nfc_status_ready(void)
{
#define NAND_STATUS_READY_BIT 0x40

  if( NAND_STATUS_READY_BIT & nfc_read_status() )
    return 1;
  else
    return 0;  
}

/*****************************************************************************/
/*                              NFC READ                                     */
/*****************************************************************************/

/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      nfc_read_page                                                        */
/* DESCRIPTION                                                               */
/*      This function reads NAND page area (528Bytes size)                   */
/* PARAMETERS                                                                */
/*      iPageNum        wanted page number of the upper blk_num block        */
/*                      of the NAND Flash to read                            */
/*      pMBuf           unsigned char type pointer of main area sized        */
/*                      buffer to read                                       */
/*      pSBuf           unsigned char type pointer of spare area sized       */
/*                      buffer to read                                       */
/* RETURN VALUES                                                             */
/*      This function returns NFC_NO_ERR when it does successfully.          */
/*      If previous write error occurs, this function returns NFC_WRITE_ERR. */
/*      If ECC error occured, ECC related error is returned                  */
/*                                                                           */
/*****************************************************************************/
u32 nfc_read_page(u16 iPageNum, u32* pMBuf, u32* pSBuf)
{
  if( (pMBuf == (u32*)0) && (pSBuf == (u32*)0) )
    return NFC_ILLEGAL_ACCESS;
    
  if(!nfc_status_ready())
    return NFC_WRITE_ERR;

  _reg_NFC_BLK_ADD_LOCK = iPageNum / 32;

  nfc_RAM_buffer_select(0);

  _reg_NFC_NF_CONFIG1 = NFC_CONFIG1_READ; 
#ifdef NAND_ECC
  _reg_NFC_NF_CONFIG1 |= NFC_CONFIG1_ECC_EN; 
#endif
  nfc_command_input(NAND_CMD_READ);
  nfc_address_cycle(iPageNum, _gRowAddressCycleNum, _gColAddressCycleNum);
  nfc_flash_data_output();
  if(pMBuf != (u32*)0)
    MemoryCopy((void*)NFC_MAB0_BASE, (void*)pMBuf, _gMainPageByteSize);
  if(pSBuf != (u32*)0)
    MemoryCopy((void*)NFC_SAB0_BASE, (void*)pSBuf, _gSparePageByteSize);
#ifdef NAND_ECC
  if( _reg_NFC_ECC_STAT_RES )
    return ( _reg_NFC_ECC_STAT_RES & 0x0F);
#endif
    
  return NFC_NO_ERR;  
}

/*****************************************************************************/
/*                              NFC WRITE                                    */
/*****************************************************************************/

/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      nfc_write_page                                                            */
/* DESCRIPTION                                                               */
/*      This function writes into NAND                                       */
/* PARAMETERS                                                                */
/*      iPageNum        wanted page number of the upper blk_num block        */
/*                      of the NAND Flash to write                           */
/*      pMBuf           unsigned char type pointer of main area sized        */
/*                      buffer to write                                      */
/*      pSBuf           unsigned char type pointer of spare area sized       */
/*                      buffer to write                                      */
/* RETURN VALUES                                                             */
/*      This function returns NFC_NO_ERR when it does successfully.          */
/*      If previous write error occurs, this function returns NFC_WRITE_ERR. */
/*      Because of interleaving write method, this function doen't check     */
/*      comletion of current write operation                                 */
/*                                                                           */
/*****************************************************************************/
u32 nfc_write_page(u16 iPageNum, u32* pMBuf, u32* pSBuf)
{
    if((pMBuf == (u32*)0) && (pSBuf == (u32*)0))
      return NFC_ILLEGAL_ACCESS;

    if(!nfc_status_ready())
      return NFC_WRITE_ERR;

    nfc_RAM_buffer_select(0);

    if (pMBuf != (u32*)0) {
        MemoryCopy((void*)pMBuf, (void*)NFC_MAB0_BASE, _gMainPageByteSize);
        if (pSBuf == (u32*)0)
           MemorySet((void*)NFC_SAB0_BASE, 0xFF, _gSparePageByteSize);
        else
           MemoryCopy((void*)pSBuf, (void*)NFC_SAB0_BASE, _gSparePageByteSize);
    }
    else {
      MemoryCopy((void*)pSBuf, (void*)NFC_SAB0_BASE, _gSparePageByteSize);
    }

  _reg_NFC_NF_CONFIG1 = NFC_CONFIG1_READ; 
#ifdef NAND_ECC
  _reg_NFC_NF_CONFIG1 |= NFC_CONFIG1_ECC_EN; 
#endif
  nfc_command_input(NAND_CMD_PAGE_PROG);
  nfc_address_cycle(iPageNum, _gRowAddressCycleNum, _gColAddressCycleNum);
  nfc_flash_data_input();
  nfc_command_input(NAND_CMD_PAGE_PROG_CONFIRM);

  return NFC_NO_ERR;
}

/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      nfc_erase                                                            */
/* DESCRIPTION                                                               */
/*      This function erases a block of NAND flash                           */
/* PARAMETERS                                                                */
/*      iBlockNum           block number of the NAND Flash to be erased      */
/* RETURN VALUES                                                             */
/*      This function returns NFC_NO_ERR when it does successfully.          */
/*      If previous write error occurs, this function returns NFC_WRITE_ERR. */
/*      Because of interleaving write method, this function doen't check     */
/*      comletion of current write operation                                 */
/*                                                                           */
/*****************************************************************************/
u32 nfc_erase(u16 iPageNum)
{

  nfc_command_input(NAND_CMD_ERASE);

  nfc_address_cycle(iPageNum, _gRowAddressCycleNum, 0);
 
  nfc_command_input(NAND_CMD_ERASE_CONFIRM);
  
  return NFC_NO_ERR;
}

/*****************************************************************************/
/*                             NFC READ ID                                   */
/*****************************************************************************/
/*****************************************************************************/
/*                                                                           */
/* NAME                                                                      */
/*      cmd_flash_readid (interface function)                                */
/* DESCRIPTION                                                               */
/*      This function reads ManufavturerID and DeviceID                      */
/* PARAMETERS                                                                */
/*      iManufacturer       NAND Flash iManufacturer ID                      */
/*                          NOW, only detect SAMSUNG (0xEC)                  */
/*      iDevice             NAND Flash device ID                             */
/* RETURN VALUES                                                             */
/*      This function returns NFC_NO_ERR except previous write error         */
/*                                                                           */
/*****************************************************************************/
u32 nfc_readid(u32* id)
{
  u32 tmp;

  if(!nfc_status_ready())
    return NFC_WRITE_ERR;

  _reg_NFC_NF_CONFIG1 = NFC_CONFIG1_READ; // ECC Bypass, Main & Spare Area, Read Operation

  nfc_RAM_buffer_select(0);
  nfc_command_input(NAND_CMD_READID);
  nfc_address_input(0);

  _reg_NFC_NF_CONFIG2 = 0x0010; // FDO = ID Read

  while(NFC_BUSY);

  *id  = *(volatile u32 *)(NFC_MAB0_BASE);

  //*iManufacturer  = (u8)tmp;
  //*iDevice        = (u8)(tmp>>16);
   
  return (NFC_NO_ERR);
}

⌨️ 快捷键说明

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