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

📄 nfc.c

📁 uart.tar, 龙珠i.MX21上的NAND Flash驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef __NFC_C_
#define __NFC_C_
#endif

#include "common.h"
#include "NFC.H"
#include "MX21.h"

#define NF_FMS_2KB  0x20
#define NF_FMS_512B 0x00
#define NF_16BIT    0x10
#define NF_8BIT     0x00

/* define page size  */
#define NAND_PAGE_SIZE 512  /* 512-Byte */
//#define NAND_PAGE_SIZE 2048 /* 2048-Byte */

/* define block size */
#define NAND_PAGE_ADDRESS_WIDTH   5   /* 5 for 32 pages per block */
//#define NAND_PAGE_ADDRESS_WIDTH   6   /* 6 for 64 pages per block */

/* define number of address cycle*/
#define NAND_ADDRESS_CYCLE 4
//#define NAND_ADDRESS CYCLE 5

/***********************************************************/
/* NAND Flash Command Set for 8-bit I/O                    */
/***********************************************************/
#define NAND_CMD_READ              (0x0000)
#define NAND_CMD_READ1             (0x0101)
#define NAND_CMD_READ2             (0x5050)       
#define NAND_CMD_READ_CONFIRM      (0x3030)
#define NAND_CMD_PAGE_PROG         (0x8080)
#define NAND_CMD_PAGE_PROG_CONFIRM (0x1010)
#define NAND_CMD_ERASE             (0x6060)
#define NAND_CMD_ERASE_CONFIRM     (0xD0D0)
#define NAND_CMD_READID            (0x9090)
#define NAND_CMD_RESET             (0xFFFF)
#define NAND_CMD_READ_STATUS       (0x7070)

/***********************************************************/
/* Settings for NFC Config1 Register                       */
/***********************************************************/
#define NFC_CONFIG1_ECC_EN  (0x0008)
#define NFC_CONFIG1_SP_ONLY (0x0004)
#define NFC_CONFIG1_READ    (0x0002)
#define NFC_CONFIG1_WRITE   (0x0001)

/***********************************************************/
/* MACRO                                                   */
/***********************************************************/
#define NFC_BUSY  (!( *(p_uint16_t)NFC_NF_CONFIG2 & 0x8000 ))


static void MemorySet(void* Address, uint8_t data, uint32_t ByteSize)
{
  uint32_t i;

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

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

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

void 
nfc_init(void)
{
  *(volatile p_uint32_t)SYS_FMCR  |= ( NF_8BIT | NF_FMS_512B );
//  *(volatile p_uint32_t)CRM_PCDR  |= 0x00004000;    // NFCDIV
  *(volatile p_uint32_t)CRM_PCDR0  |= 0x00004000;    // NFCDIV

//  *(volatile p_uint32_t)CRM_PCCR0 |= 0x00080000;    // Enable NFC
  *(volatile p_uint32_t)PCCR0 |= 0x00080000;    // Enable NFC, for TO2 change

  *(volatile p_uint16_t)NFC_CONFIGURATION = 0x0002; // unlock the internal RAM buffer
  *(volatile p_uint16_t)NFC_NF_CONFIG2    = 0x0000; // clear all operation
}

void 
nfc_RAM_buffer_select(uint8_t BufferNum)
{
   *(volatile p_uint16_t)NFC_RAM_BUF_ADDR = (uint16_t)BufferNum;
}

/* Activate one address cycle */
void
nfc_address_input(uint16_t address)
{
   *(volatile p_uint16_t)NFC_NAND_FLASH_ADDR = address;

   *(volatile p_uint16_t)NFC_NF_CONFIG2 = 0x0002;

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

void 
nfc_address_cycle(uint16_t iBlockNum, uint16_t iPageNum)
{
  nfc_address_input(0);

#if NAND_PAGE_SIZE == 512
  nfc_address_input((iBlockNum<<NAND_PAGE_ADDRESS_WIDTH) & (iPageNum));
  nfc_address_input(iBlockNum>>(8-NAND_PAGE_ADDRESS_WIDTH));
  nfc_address_input(iBlockNum>>(16-NAND_PAGE_ADDRESS_WIDTH));
#if NAND_ADDRESS_CYCLE == 5
  nfc_address_input(iBlockNum>>(24-NAND_PAGE_ADDRESS_WIDTH));
#endif
#endif

#if NAND_PAGE_SIZE == 2048
  nfc_address_input(0);
  nfc_address_input( (iBlockNum<<NAND_PAGE_ADDRESS_WIDTH) & (iPageNum) );
  nfc_address_input( iBlockNum>>(8-NAND_PAGE_ADDRESS_WIDTH));
#if NAND_ADDRESS_CYCLE == 5
  nfc_address_input(iBlockNum>>(16-NAND_PAGE_ADDRESS_WIDTH));
#endif
#endif    
}

void 
nfc_command_input(uint16_t command)
{
    *(volatile p_uint16_t)NFC_NAND_FLASH_CMD  = command;

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

void 
nfc_flash_data_input(void)
{
   *(volatile p_uint16_t)NFC_NF_CONFIG2 = 0x0004;

   while(NFC_BUSY);
}

void 
nfc_flash_data_output(void)
{
   *(volatile p_uint16_t)NFC_NF_CONFIG2 = 0x0008;

   while(NFC_BUSY);
}

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

uint32_t 
nfc_read_status(void)
{
  uint32_t status;

  nfc_RAM_buffer_select(3);
  nfc_command_input(NAND_CMD_READ_STATUS);
  
  *(volatile p_uint16_t)NFC_NF_CONFIG2 = 0x0020; // FDO -> Read Status
  
  while(NFC_BUSY);

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

uint32_t 
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                                                             */
/* DESCRIPTION                                                               */
/*      This function reads NAND page area (528Bytes size)                   */
/* PARAMETERS                                                                */
/*      iBlockNum       wanted block number of the NAND Flash to read        */
/*      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                                       */
/*      iCmdType        command type                                         */
/* 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                  */
/*                                                                           */
/*****************************************************************************/
uint32_t 
nfc_read(uint16_t iBlockNum, uint16_t iPageNum, 
         uint32_t* pMBuf, uint32_t* pSBuf, uint16_t iCmdType)
{
  if( (pMBuf == (uint32_t*)0) && (pSBuf == (uint32_t*)0) )
    return NFC_ILLEGAL_ACCESS;
    
  if(!nfc_status_ready())
    return NFC_WRITE_ERR;

  *(volatile p_uint16_t)NFC_BLK_ADD_LOCK = iBlockNum;

  nfc_RAM_buffer_select(0);

  switch(iCmdType) {
  case NFC_CMD_RD_PB_ECC:
    *(volatile p_uint16_t)NFC_NF_CONFIG1 = NFC_CONFIG1_READ|NFC_CONFIG1_ECC_EN; 
    nfc_command_input(NAND_CMD_READ);
    nfc_address_cycle(iBlockNum, iPageNum);
    nfc_flash_data_output();
    if(pMBuf != (uint32_t*)0)
      MemoryCopy((void*)NFC_MAB0_BASE, (void*)pMBuf, NAND_PAGE_SIZE);
    if(pSBuf != (uint32_t*)0)
      MemoryCopy((void*)NFC_SAB0_BASE, (void*)pSBuf, NAND_PAGE_SIZE/32);
    if( *(p_uint16_t)NFC_ECC_STAT_RES )
      return ( *(p_uint16_t)NFC_ECC_STAT_RES & 0x0F);

⌨️ 快捷键说明

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