optical/NxFuncs/norflash/norflash.c

915 lines
17 KiB
C
Raw Normal View History

2025-09-04 01:45:08 +00:00
#include "norflash.h"
#include "trigger.h"
#include "shell.h"
#include "delay.h"
//--------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//----------------------------------------------
// serial Norflash <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><>׼/˫·/<2F><>·SPIָ<49><D6B8>)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>
// // ʵ<><CAB5>
#define SNF_WT_ENABLE 0x06 // * // дʹ<D0B4><CAB9>
#define SNF_VSR_WR_ENABLE 0x50 // // <20><>ʧ<EFBFBD><EFBFBD><E6B4A2>SRдʹ<D0B4><CAB9>
#define SNF_WT_DISABLE 0x04 // * // д<><D0B4><EFBFBD><EFBFBD>
#define SNF_RD_STREG1 0x05 // * // <20><>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>1(S7--S0)
#define SNF_RD_STREG2 0x35 // * // <20><>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>2(S15--S8)
#define SNF_WT_STREG12 0x01 // * // д״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>1<EFBFBD><31>2(S7--S0 S15--S8)
#define SNF_READ_DATA 0x03 // * // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (3<>ֽڵ<D6BD>ַ+<2B><><EFBFBD><EFBFBD>1<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>)
#define SNF_FAST_READ 0x0B // * // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B><><EFBFBD>ٶ<EFBFBD>ָ<EFBFBD><D6B8>] (3<>ֽڵ<D6BD>ַ+1<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD><EFBFBD>1<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>)
#define SNF_PAGE_PROGRAM 0x02 // * // ҳд<D2B3><D0B4><EFBFBD><EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д128<32><38><EFBFBD><EFBFBD>(256<35><36><EFBFBD>ֽ<EFBFBD>)<29><><EFBFBD><EFBFBD>,<2C>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD>Կ<EFBFBD>ҳ] <20><>3<EFBFBD><33><EFBFBD>ֽڵĵ<DAB5>ַ+2<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD><EFBFBD><EFBFBD>
#define SNF_4K_ERASE 0x20 // * // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(4KB) (3<>ֽڵ<D6BD>ַ)
#define SNF_32K_ERASE 0x52 // * // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(32KB) (3<>ֽڵ<D6BD>ַ)
#define SNF_64K_ERASE 0xD8 // * // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(64KB) (3<>ֽڵ<D6BD>ַ)
#define SNF_CHIP_ERASE 0xC7 // * // Ƭ<><C6AC><EFBFBD><EFBFBD> <20><> 0x60
#define SNF_EP_SUSPEND 0x75 // // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define SNF_EP_RESUME 0x7A // // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>ָ<EFBFBD>(<28>ӹ<EFBFBD><D3B9><EFBFBD><EFBFBD>У<EFBFBD>
#define SNF_POWER_DOWN 0xB9 // // <20><><EFBFBD><EFBFBD>
#define SNF_WKUP_DEVICE_ID 0xAB // // <20>ϵ<EFBFBD><CFB5>Ͷ<EFBFBD>ȡ<EFBFBD>豸ID (3<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>+1<>ֽ<EFBFBD><D6BD>豸ID)
#define SNF_MANU_DEVICE_ID 0x90 // * // <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID<49><44><EFBFBD>豸ID (2<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>+00H+1<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>ID+1<>ֽ<EFBFBD><D6BD>豸ID)
#define SNF_JEDEC_ID 0x9F // * // оƬ JEDEC ID <20><><EFBFBD><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD>Э<EFBFBD>ᣩ(1<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>ID+2<>ֽ<EFBFBD><D6BD>豸ID(<28><EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>))
#define SNF_UNIQUE_ID 0x4B // * // <20><><EFBFBD><EFBFBD>ID (4<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>+8<>ֽ<EFBFBD>UID)
#define SNF_RD_SFDP 0x5A // // <20><>SFDP<44>Ĵ<EFBFBD><C4B4><EFBFBD>(3<>ֽڵ<D6BD>ַ+1<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD><EFBFBD>1<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>)
#define SNF_ERASE_SECURITY 0x44 // // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ĵ<EFBFBD><C4B4><EFBFBD>(3<>ֽڵ<D6BD>ַ) <20><><EFBFBD><EFBFBD>ܼĴ<DCBC><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ 0x0010xx 0x0020xx 0x0030xx
#define SNF_PROGRAM_SECURITY 0x42 // // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ĵ<EFBFBD><C4B4><EFBFBD>(3<>ֽڵ<D6BD>ַ+<2B><><EFBFBD><EFBFBD>1<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>)
#define SNF_READ_SECURITY 0x48 // // <20><>ȡ <20><><EFBFBD><EFBFBD> <20>Ĵ<EFBFBD><C4B4><EFBFBD>(3<>ֽڵ<D6BD>ַ+<2B><><EFBFBD><EFBFBD>1<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>)
#define SNF_RESET_DEVICE 0x66 // // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
#define SNF_ENABLE_RESET 0x99 // // <20><>λоƬ
/*
#define SNF_BLOCK_LOCK 0x7E // // ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define SNF_BLOCK_UNLOCK 0x98 // // ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define SNF_ENTER_QPI 0x38 // // <20><><EFBFBD><EFBFBD>QPIģʽ
#define SNF_INDV_BLOCK_LOCK 0x36 // // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define SNF_INDV_BLOCK_UNLOCK 0x39 // // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define SNF_READ_BLOCK_LOCK 0x3D // // <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
*/
//---------------------------------------------------
#define DUMMY_BYTE 0xFF
//--------------------------------------------------------------------------------------------
int SNFWaitNotBusyMs(u32 timeout);
int SNFWaitNotBusy10Us(u32 timeout);
u8 SNFReadStatusReg1(void);
u8 SNFReadStatusReg2(void);
void SNFWriteStatusReg1And2(u8 reg1, u8 reg2);
void ShowSNFInfo(void);
void SNFlashTest(char * para1, char * para2); // NorFlash <20><><EFBFBD><EFBFBD>
//--------------------------------------------------------------------------------------------
typedef struct
{
int inited;
// SPI <20><>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
void (*spicson)(void);
void (*spicsoff)(void);
u8 (*spird)(void);
void (*spiwr)(u8 wb);
}SNFCtrl;
SNFCtrl g_snfCtrl;
//--------------------------------------------------------------------------------------------
// NorFlash <20><>ʼ<EFBFBD><CABC>
int SNFlashInit(void (*spicson)(void), void (*spicsoff)(void), u8 (*spird)(void), void (*spiwr)(u8 wb))
{
memset(&g_snfCtrl, 0, sizeof(SNFCtrl));
g_snfCtrl.spicson = spicson;
g_snfCtrl.spicsoff = spicsoff;
g_snfCtrl.spird = spird;
g_snfCtrl.spiwr = spiwr;
if (g_snfCtrl.spicson == NULL ||
g_snfCtrl.spicsoff == NULL ||
g_snfCtrl.spird == NULL ||
g_snfCtrl.spiwr == NULL ||
0 )
{
printf("SNFlashInit para error\r\n");
return -1;
}
g_snfCtrl.inited = 1;
SNFWirteEnable();
SNFWriteStatusReg1And2(0, 0);
SNFWaitNotBusyMs(100);
SNFWirteDisable();
#if (0)
ShowSNFInfo();
AddShellCmd("NORFLASH", "test nor flash", SNFlashTest);
#endif
return 0;
}
//---------------------------------
// дʹ<D0B4>ܿ<EFBFBD>
// <20><><EFBFBD><EFBFBD>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>е<EFBFBD>WEL λ Ϊ1
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>֮ǰ<D6AE><C7B0>WELλ<4C><CEBB>1
void SNFWirteEnable(void)
{
if (g_snfCtrl.inited == 0)
{
return;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_WT_ENABLE);
g_snfCtrl.spicsoff();
}
//---------------------------------
// дʹ<D0B4>ܹأ<DCB9><D8A3>ɹرշ<D8B1><D5B7><EFBFBD>ʧ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>дʹ<D0B4>ܣ<EFBFBD>
// <20><><EFBFBD><EFBFBD>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>е<EFBFBD>WEL λ Ϊ0
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>֮ǰ<D6AE><C7B0>WELλ<4C><CEBB>1
void SNFWirteDisable(void)
{
if (g_snfCtrl.inited == 0)
{
return;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_WT_DISABLE);
g_snfCtrl.spicsoff();
}
//---------------------------------
// <20><>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>1
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>
// SRP0 SEC TB PB2 PB1 PB0 WEL BUSY
u8 SNFReadStatusReg1(void)
{
u8 dat;
if (g_snfCtrl.inited == 0)
{
return 0;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_RD_STREG1);
dat = g_snfCtrl.spird(); //
g_snfCtrl.spicsoff();
return dat;
}
//---------------------------------
// <20><>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>2
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>
// SUS CMP LB3 LB2 LB1 (R) QE SRP1
u8 SNFReadStatusReg2(void)
{
u8 dat;
if (g_snfCtrl.inited == 0)
{
return 0;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_RD_STREG2);
dat = g_snfCtrl.spird(); //
g_snfCtrl.spicsoff();
return dat;
}
//---------------------------------
// д״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>1<EFBFBD><31>2
void SNFWriteStatusReg1And2(u8 reg1, u8 reg2)
{
if (g_snfCtrl.inited == 0)
{
return;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_WT_STREG12);
g_snfCtrl.spiwr(reg1);
g_snfCtrl.spiwr(reg2);
g_snfCtrl.spicsoff();
}
//---------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>ж<EFBFBD>Nor<6F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD>״̬
// <20><><EFBFBD><EFBFBD>ֵ: 0, <20><><EFBFBD><EFBFBD>
// 1, æ
int SNFIsdStatusBusy(void)
{
u8 sta1;
sta1 = SNFReadStatusReg1();
sta1 &= 0x01; // WIP flag
return sta1;
}
//---------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(50M<30><4D><EFBFBD>µ<EFBFBD><C2B5>ٶȣ<D9B6>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ
int SNFlashRdData(u32 addr, u8 * pBuf, int len)
{
int i;
if (pBuf == NULL ||
len <= 0 ||
g_snfCtrl.inited == 0 ||
0 )
{
return -1;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_READ_DATA);
g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));
for (i = 0; i < len; i++)
{
*pBuf++ = g_snfCtrl.spird();
}
g_snfCtrl.spicsoff();
return 0;
}
//---------------------------------
// <20><><EFBFBD>ٶ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>ɴﵽ104M<34><4D>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ
int SNFFastReadData(u32 addr, u8 * pBuf, int len)
{
int i;
if (pBuf == NULL ||
len <= 0 ||
g_snfCtrl.inited == 0 ||
0 )
{
return -1;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_FAST_READ);
g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));
g_snfCtrl.spiwr(DUMMY_BYTE);
for (i = 0; i < len; i++)
{
*pBuf++ = g_snfCtrl.spird();
}
g_snfCtrl.spicsoff();
return 0;
}
//---------------------------------
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>
int IsSNFlashEmpty(u32 addr, int len)
{
u32 i;
int rslt = 0;
if (g_snfCtrl.inited == 0)
{
return 0;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_READ_DATA);
g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));
for (i = 0; i < len; i++)
{
if (g_snfCtrl.spird() != 0xff)
{
rslt = 1;
break;
}
}
g_snfCtrl.spicsoff();
return rslt;
}
//---------------------------------
// ҳ<><D2B3>д<EFBFBD><D0B4><EFBFBD><EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д256<35><36><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>]
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>һҳ<D2BB><D2B3><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ѭ<EFBFBD><D1AD><EFBFBD>ص<EFBFBD>һҳ<D2BB><D2B3><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>д<EFBFBD><D0B4>
int SNFPageProgram(u32 addr, u8 * pBuf, int len)
{
int i;
if (pBuf == NULL ||
len <= 0 ||
g_snfCtrl.inited == 0 ||
0 )
{
return -1;
}
SNFWirteEnable();
SNFWaitNotBusy10Us(100);
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_PAGE_PROGRAM);
g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));
for (i = 0; i < len; i++)
{
g_snfCtrl.spiwr(*pBuf++);
}
g_snfCtrl.spicsoff();
return SNFWaitNotBusy10Us(300);
}
//---------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(4KB)
int SNFlash4kErase(u32 addr, int wait)
{
int rslt = 1;
if (g_snfCtrl.inited == 0)
{
return rslt;
}
SNFWirteEnable();
SNFWaitNotBusy10Us(100);
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_4K_ERASE);
g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));
g_snfCtrl.spicsoff();
if (wait != 0)
{
rslt = SNFWaitNotBusyMs(300);
}
return rslt;
}
//---------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(32KB)
int SNFlash32kErase(u32 addr, int wait)
{
int rslt = 1;
if (g_snfCtrl.inited == 0)
{
return rslt;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_32K_ERASE);
g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));
g_snfCtrl.spicsoff();
if (wait != 0)
{
rslt = SNFWaitNotBusyMs(800);
}
return rslt;
}
//---------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(64KB)
int SNFlash64kErase(u32 addr, int wait)
{
int rslt = 1;
if (g_snfCtrl.inited == 0)
{
return rslt;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_64K_ERASE);
g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));
g_snfCtrl.spicsoff();
if (wait != 0)
{
rslt = SNFWaitNotBusyMs(1000);
}
return rslt;
}
//---------------------------------
// <20><>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD>
int SNFlashChipErase(u32 addr, int wait)
{
int rslt = 1;
if (g_snfCtrl.inited == 0)
{
return rslt;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_CHIP_ERASE);
g_snfCtrl.spicsoff();
if (wait != 0)
{
rslt = SNFWaitNotBusyMs(6000);
}
return rslt;
}
//---------------------------------
// <20><>ȡ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> id <20><> <20>豸 ID
// manufacturer id + device id
u32 SNFGetManufacDeviceID(void)
{
u32 mdid;
u8 mid,did;
if (g_snfCtrl.inited == 0)
{
return 0;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_MANU_DEVICE_ID);
g_snfCtrl.spiwr(0);
g_snfCtrl.spiwr(0);
g_snfCtrl.spiwr(0);
mid = g_snfCtrl.spird();
did = g_snfCtrl.spird();
g_snfCtrl.spicsoff();
mdid = MAKEDWORDF(did, mid, 0, 0);
// printf("Nor flash manufacturer id and device id = 0x%x\r\n", mdid);
return mdid;
}
//---------------------------------
// <20><>ȡ JEDEC ID
// manufacturer id + memory type + capacity
u32 SNFGetJedecID(void)
{
u32 jid;
u8 id1,id2,id3;
if (g_snfCtrl.inited == 0)
{
return 0;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_JEDEC_ID);
id3 = g_snfCtrl.spird();
id2 = g_snfCtrl.spird();
id1 = g_snfCtrl.spird();
g_snfCtrl.spicsoff();
jid = MAKEDWORDF(id1, id2, id3, 0);
// printf("Nor flash jedec id = 0x%x\r\n", jid);
return jid;
}
//---------------------------------
// <20><>ȡ Unique ID
// 8<>ֽڵ<D6BD>Ψһ<CEA8><D2BB><EFBFBD>к<EFBFBD>
u64 SNFGetUniqueID(void)
{
int i;
u8 id;
u64 uid;
u8 * pId = (u8 *)(&uid);
if (g_snfCtrl.inited == 0)
{
return 0;
}
g_snfCtrl.spicson();
g_snfCtrl.spiwr(SNF_UNIQUE_ID);
g_snfCtrl.spiwr(DUMMY_BYTE);
g_snfCtrl.spiwr(DUMMY_BYTE);
g_snfCtrl.spiwr(DUMMY_BYTE);
g_snfCtrl.spiwr(DUMMY_BYTE);
printf("Nor flash Unique id = ");
for (i = 0; i < 8; i++)
{
id = g_snfCtrl.spird();
*pId++ = id;
printf("0x%x, ", id);
}
printf("\r\n");
g_snfCtrl.spicsoff();
return uid;
}
//---------------------------------
// <20><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
int SNFlashWrData(u32 addr, u8 *data, int len)
{
int rslt;
u32 pglen;
pglen = addr % SNF_BYTES_PER_PAGE;
if (pglen == 0)
{
pglen = SNF_BYTES_PER_PAGE;
}
do
{
rslt = SNFPageProgram(addr, data, pglen);
if (rslt != 0)
{
break;
}
addr += pglen;
data += pglen;
len -= pglen;
if (len >= SNF_BYTES_PER_PAGE)
{
pglen = SNF_BYTES_PER_PAGE;
}
else if (len > 0)
{
pglen = len;
}
else
{
break;
}
}while(1);
return rslt;
}
//---------------------------------
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* ---------------------- eaddr:<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ(<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ַ) -----
* | | |
* | | |
* | ҳ1 | |
* ---------------------- |
* | | |
* | | elen:<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ<EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD>
* | ҳ2 | |
* ---------------------- ---- addr:д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ַ |
* | | | |
* | | len:д<EFBFBD><EFBFBD><EFBFBD> |
* | ҳ3 | | |
* ---------------------- ----- ----
* | |
* | |
* | ҳ4 |
* ----------------------
* | |
* | |
* | ҳ5 |
* ----------------------
* | |
* | |
* | ҳ6 |
* ----------------------
* | |
* | |
* | ҳ7 |
* ----------------------
* | |
* | |
* | ҳ8 |
* ----------------------
* | |
* | |
* | ҳ9 |
* ----------------------
* | |
* | |
* | ҳ10 |
* ----------------------
* | |
* | |
* | ҳ11 |
* ----------------------
* | |
* | |
* | ҳ12 |
* ----------------------
* | |
* | |
* | ҳ13 |
* ----------------------
* | |
* | |
* | ҳ14 |
* ----------------------
* | |
* | |
* | ҳ15 |
* ----------------------
* | |
* | |
* | ҳ16 |
* ----------------------
*/
// д<><D0B4><EFBFBD>ݣ<EFBFBD><DDA3>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int SNFlashWrDataWithErase(u32 addr, u8 *data, int len)
{
int i, erflag, rslt; // erflag:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־ = 1,<2C><><EFBFBD><EFBFBD>
u8 rdata[SNF_BYTES_PER_SEC]; // <20><EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
u32 eaddr; // <20><><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ
u32 elen, wlen; // elen:<3A><><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ<EFBFBD><D6B7>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><C9B5>ֽ<EFBFBD><D6BD><EFBFBD> wlen:д<><EFBFBD><EBB3A4>
eaddr = (addr/SNF_BYTES_PER_SEC) * SNF_BYTES_PER_SEC; // ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ
rslt = 0;
printf("nwe, fad=0x%x, sad=0x%x len=%d, \r\n", addr, eaddr, len);
while(addr < SNF_TOTAL_BYTES && len > 0)
{
erflag = 0;
SNFlashRdData(eaddr, rdata, SNF_BYTES_PER_SEC); // <20><>ȡһ<C8A1><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
elen = SNF_BYTES_PER_SEC;
if ((addr-eaddr)+len < elen)
{
elen = len+(addr-eaddr); // <20><><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ<EFBFBD><D6B7>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><C9B5>ֽ<EFBFBD><D6BD><EFBFBD>
}
wlen = elen-(addr-eaddr);
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
for (i = (addr-eaddr); i < elen; i++) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>(<28><><EFBFBD><EFBFBD>0--1)
{
if ((rdata[i] & data[i]) != data[i]) // <20><>֮<EFBFBD>󣬺<EFBFBD>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD><EFBFBD>
{
erflag = 1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
break;
}
}
// printf("elen=%d, wlen=%d, bufbeg=%d\r\n", elen, wlen, addr-eaddr);
if (erflag != 0)
{
SNFlash4kErase(eaddr, 1); // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
memcpy(&(rdata[(addr-eaddr)]), data, wlen); // <20><><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EBBBBA><EFBFBD><EFBFBD>
rslt = SNFlashWrData(eaddr, rdata, SNF_BYTES_PER_SEC); // д<><D0B4>flash
printf("Erase 4K and wr\r\n");
}
else
{
// printf("wr to fls\r\n");
rslt = SNFlashWrData(addr, data, wlen); // д<><D0B4>flash
}
if (rslt != 0)
{
break;
}
len -= wlen;
data += wlen;
addr += wlen; // <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>
eaddr += SNF_BYTES_PER_SEC;
}
return rslt;
}
//---------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>ȴ<EFBFBD>Nor<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>ֵ: 0, <20><><EFBFBD><EFBFBD>
// -1, <20><>ʱ
int SNFWaitNotBusyMs(u32 timeout)
{
u32 i;
int rst = -1;
for (i = 0; i < timeout; i++)
{
if (SNFIsdStatusBusy() == 0)
{
rst = 0;
break;
}
DelayMs(1); // <20>˴<EFBFBD><CBB4><EFBFBD><EFBFBD>滻Ϊ<E6BBBB><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
}
return rst;
}
//---------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>ȴ<EFBFBD>Nor<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>ֵ:0 <20><><EFBFBD><EFBFBD>
// -1:<3A><>ʱ
int SNFWaitNotBusy10Us(u32 timeout)
{
u32 i;
int rst = -1;
for (i = 0; i < timeout; i++)
{
if (SNFIsdStatusBusy() == 0)
{
rst = 0;
break;
}
DelayUs(10); // <20>˴<EFBFBD><CBB4><EFBFBD><EFBFBD>滻Ϊ<E6BBBB><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
}
return rst;
}
//---------------------------------
void ShowSNFInfo(void)
{
u32 id;
printf("--------------nor flash info--------------\r\n");
id = SNFGetManufacDeviceID(); // <20><>ȡ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> id <20><> <20>豸 ID
printf("manufacturer id = 0x%x\r\n", HIBYTE(LOWORD(id)));
printf("device id = 0x%x\r\n", LOBYTE(LOWORD(id)));
id = SNFGetJedecID(); // <20><>ȡ jedec id
printf("manufacturer id = 0x%x\r\n", LOBYTE(HIWORD(id)));
printf("memory type = 0x%x\r\n", HIBYTE(LOWORD(id)));
printf("capacity = 0x%x\r\n", LOBYTE(LOWORD(id)));
SNFGetUniqueID(); // 8<>ֽڵ<D6BD>Ψһ<CEA8><D2BB><EFBFBD>к<EFBFBD>
printf("------------------------------------------\r\n");
}
// NorFlash <20><><EFBFBD><EFBFBD>
void SNFlashTest(char * para1, char * para2)
{
int p1, p2;
p1 = p2 = 0;
if (para1 != NULL && strcmp(para1, "") != 0)
{
p1 = atoi(para1);
}
if (para2 != NULL && strcmp(para2, "") != 0)
{
p2 = atoi(para2);
}
if (p1 == p2)
{
}
//--------------------------------
{
u8 buff[1024];
int i;
if (p1 == 0)
{// <20>ӵ<EFBFBD>ַp2<70><32>ʼ<EFBFBD><CABC>ȡ1K<31>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
memset(buff, 0, 1024);
DatFlashRdData(p2, buff, 1024);
printf("DatFlashRdData addr=0x%x,\r\n", p2);
for (i = 0; i < 1024; i++)
{
if ((i%16) == 0)
{
printf("\r\n%d:\t", i+1);
DelayMs(10);
}
printf("%02x ", buff[i]);
}
printf("\r\n");
}
else if (p1 == 1)
{// <20>ӵ<EFBFBD>ַp2<70><32>ʼд<CABC><D0B4>1K<31>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
printf("DatFlashWrDataWithErase addr=0x%x,\r\n", p2);
for (i = 0; i < 1024; i++)
{
buff[i] = p2 + i;
}
DatFlashWrDataWithErase(p2, buff, 1024);
printf("done \r\n");
}
else if (p1 == 3)
{// <20>ӵ<EFBFBD>ַ0x190000<30><30>ʼ<EFBFBD><CABC>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
int circle = p2;
int count = 0;
do
{
memset(buff, 0, 1024);
DatFlashRdData(0x190000+count*0x400, buff, 1024);
printf("DatFlashRdData addr=0x%x,\r\n", 0x190000+count*0x400);
for (i = 0; i < 1024; i++)
{
if ((i%16) == 0)
{
printf("\r\n%d:\t", count*1024+i+1);
DelayMs(10);
}
printf("%02x ", buff[i]);
}
printf("\r\n");
circle--;
count++;
if (circle <= 0)
{
break;
}
}while(1);
}
}
}