#include <MSP430X14X.h>
#include <stdio.h>
#include "Nand.h"
void Init_CLK(void);
//全局变量
extern int nSM_R_B;
void SM_Port_Init(void)
{
P4DIR = 0;
P4DIR |= BIT0; //设置CLE为输出管脚
P4DIR |= BIT1; //设置CE~为输出管脚
P4DIR |= BIT2; //设置ALE为输出管脚
P4DIR |= BIT3; //设置RE~为输出管脚
P4DIR |= BIT4; //设置WE~为输出管脚
P1DIR &= ~(BIT1); //设置R/B为输入管脚
return;
}
void CLE_Enable(void)
{
P4OUT |= BIT0;
return;
}
void CLE_Disable(void)
{
P4OUT &= ~(BIT0);
return;
}
void CE_Enable(void)
{
P4OUT &= ~(BIT1);
return;
}
void CE_Disable(void)
{
P4OUT |= BIT1;
return;
}
void ALE_Enable(void)
{
P4OUT |= BIT2;
return;
}
void ALE_Disable(void)
{
P4OUT &= ~(BIT2);
return;
}
void WE_Enable(void)
{
P4OUT &= ~(BIT4);
return;
}
void WE_Disable(void)
{
P4OUT |= BIT4;
return;
}
void RE_Enable(void)
{
P4OUT &= ~(BIT3);
return;
}
void RE_Disable(void)
{
P4OUT |= BIT3;
return;
}
int GetSMStatus(void)
{
int nTemp = 0;
return nTemp;
}
////////////////////////////////////////
// 正确返回 1,错误返回 0
int PageWrite(int nCol,unsigned long nRow,char *pBuf)
{
int nTemp = 0;
int i;
int j;
unsigned nADD1;
unsigned nADD2;
unsigned nADD3;
nADD1 = nRow & 0x00ff;
nADD2 = (nRow >> 8) &0x00ff;
nADD3 = (nRow >> 16) & 0x00ff; //处理最高地址的时候必须注意的是其余没有用的位必须是 0
CE_Enable();
P5DIR = 0xff; //设置P5口为输出方向
CLE_Enable();
WE_Enable();
P5OUT = 0x80; //页写命令
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCol); // 行的起始地址
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD1;
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD2;
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD3;
WE_Disable();
ALE_Disable();
//WE_Enable();
for(j = 0;j < 528;j++)
{
WE_Enable();
P5OUT = pBuf[j];
//for(i = 3;i > 0;i--);
WE_Disable();
}
//WE_Disable();
CLE_Enable();
WE_Enable();
P5OUT = 0x10;
WE_Disable();
CLE_Disable();
//等待R/B中断
//while(!nSM_R_B) ;
//nSM_R_B = 0;
for(i = 100;i > 0;i--);
CLE_Enable();
WE_Enable();
P5OUT = 0x70;
WE_Disable();
CLE_Disable();
P5DIR = 0x00; //设置P5口为输入方向
for(i = 1000;i > 0;i--)
{
RE_Enable();
nTemp = P5IN;
RE_Disable();
if(nTemp == 0xc0) break;
}
if(nTemp == 0xc0) return 1;
else return 0;
}
////////////////////////////////////////
// 正确返回 1,错误返回 0
int WriteByte(int nCommand,int nCol,unsigned long nRow,char nValue)
{
int nTemp = 0;
int i;
unsigned nADD1;
unsigned nADD2;
unsigned nADD3;
nADD1 = nRow & 0x00ff;
nADD2 = (nRow >> 8) &0x00ff;
nADD3 = (nRow >> 16) & 0x00ff; //处理最高地址的时候必须注意的是其余没有用的位必须是 0
CE_Enable();
P5DIR = 0xff; //设置P5口为输出方向
CLE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCommand); //指针
WE_Disable();
CLE_Disable();
CLE_Enable();
WE_Enable();
P5OUT = 0x80; //页写命令
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCol); // 行的起始地址
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD1;
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD2;
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD3;
WE_Disable();
ALE_Disable();
WE_Enable();
P5OUT = nValue;
WE_Disable();
CLE_Enable();
WE_Enable();
P5OUT = 0x10;
WE_Disable();
CLE_Disable();
//等待R/B中断
//while(!nSM_R_B) ;
//nSM_R_B = 0;
for(i = 100;i > 0;i--);
CLE_Enable();
WE_Enable();
P5OUT = 0x70;
WE_Disable();
CLE_Disable();
P5DIR = 0x00; //设置P5口为输入方向
for(i = 1000;i > 0;i--)
{
RE_Enable();
nTemp = P5IN;
RE_Disable();
if(nTemp == 0xc0) break;
}
//printf("SM Write: nTemp = %x ,",nTemp);
if(nTemp == 0xc0) return 1;
else return 0;
}
////////////////////////////////////////
// 正确返回 1,错误返回 0
char ReadByte(int nCommand,int nCol,unsigned long nRow)
{
int i;
char chrLow = 0;
unsigned char nADD1;
unsigned char nADD2;
unsigned char nADD3;
nADD1 = nRow & 0x00ff;
nADD2 = (nRow >> 8) & 0x00ff;
nADD2 = (nRow >> 16) & 0x00ff;
CE_Enable();
P5DIR = 0xff; //设置P5口为输出方向
CLE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCommand); //输出读命令代码;
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCol);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD1);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD2);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD3);
WE_Disable();
ALE_Disable();
//等待R/B中断
//while(!nSM_R_B) ;
//nSM_R_B = 0;
for(i = 100;i > 0;i--);
P5DIR = 0; //设置P5口为输入方向
RE_Enable();
chrLow = P5IN;
RE_Disable();
CE_Disable();
return chrLow;
}
////////////////////////////////////////
// 正确返回 1,错误返回 0
int PageRead(int nCol,unsigned long nRow,char *pBuf)
{
int nTemp = 0;
int i;
int j;
unsigned char nADD1;
unsigned char nADD2;
unsigned char nADD3;
nADD1 = nRow & 0x00ff;
nADD2 = (nRow >> 8) & 0x00ff;
nADD2 = (nRow >> 16) & 0x00ff;
CE_Enable();
P5DIR = 0xff; //设置P5口为输出方向
CLE_Enable();
WE_Enable();
P5OUT = 0x00; //输出读命令代码 0x00;
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCol);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD1);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD2);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD3);
WE_Disable();
ALE_Disable();
//等待R/B中断
//while(!nSM_R_B) ;
//nSM_R_B = 0;
for(i = 100;i > 0;i--);
P5DIR = 0; //设置P5口为输入方向
//RE_Enable();
for(j = 0;j < 528;j++)
{
RE_Enable();
pBuf[j] = P5IN;
//for(i = 3;i > 0;i--); //是否需要延时
RE_Disable();
}
//RE_Disable();
CE_Disable();
return nTemp;
}
////////////////////////////////////////
// 正确返回 1,错误返回 0
int ReadID(unsigned char pBuf[2])
{
int nTemp = 0;
int nMaker = 0;
int nDevice = 0;
// int nUniqueID = 0;
// int nPlaneCode = 0;
CE_Enable(); // 使能片选信号
ALE_Disable();
CLE_Disable();
RE_Disable();
WE_Disable();
P5DIR = 0XFF; // 设置P5口为输出方向
CLE_Enable();
//for(i = 3;i > 0;i--);
WE_Enable();
//for(i = 5;i > 0;i--);
P5OUT = 0x90; // 输出命令代码 0x90
WE_Disable();
CLE_Disable();
ALE_Enable();
//for(i = 3;i > 0;i--);
WE_Enable();
//for(i = 5;i > 0;i--);
P5OUT = 0x00; // 地址周期
WE_Disable();
ALE_Disable();
P5DIR = 0x00; // 设置P5口为输入方向
RE_Enable();
nMaker = P5IN;