📄 nfc.c
字号:
#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 + -