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

📄 flash.cpp

📁 cs850实验板的flash存储器编程
💻 CPP
字号:

#include <vxworks.h>
#include "smc.h"

typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  DWORD;
typedef DWORD ADDRESS;
typedef volatile UINT16 FLASHDATA;

#define LLD_DEV_MULTIPLIER 		0x001e0000
#define LLD_DB_READ_MASK   		0x0000FFFF
#define LLD_DEV_READ_MASK  	0x000000FF
#define LLD_UNLOCK_ADDR1   		0x00000555
#define LLD_UNLOCK_ADDR2   		0x000002AA
#define LLD_BYTES_PER_OP   		0x00000002
#define LLD_BUFFER_SIZE    		16

#define FLASH_OFFSET(b,o)       	(*(( (FLASHDATA*)(b) ) + (o)))
#define FLASH_WR(b,o,d)		 	(*((volatile UINT16 *)((UINT32)(b)+(UINT32)(o<<1)))) = (d)
#define FLASH_RD(b,o) 		 	(*((volatile UINT16 *)((UINT32)(b)+(UINT32)(o<<1))))
#define Addr555(flbase) 		 	((volatile UINT16 *)((WORD)(flbase)+(WORD)(0x555<<1)))
#define Addr2aa(flbase)		 	((volatile UINT16 *)((WORD)(flbase)+(WORD)(0x2AA<<1)))


UINT16 buffer[5]={100};
UINT32 *hh;


/* Address/Command Info */
void ProgramCmd(
UINT32 * base_addr,               		/* device base address in system */
int offset,                  		     		/* address offset from base address */
UINT16 data          		    		/* variable containing data to program */
)
{
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR1, 0xAA);
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR2, 0x55);
  	/* Write Program Command */
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR1, 0xA0);
  	/* Write Data */
  	FLASH_WR(base_addr, offset, data);
}


void SectorEraseCmd(UINT32 * base_addr,UINT32 offset)
{
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR1, 0xAA);
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR2, 0x55);
	FLASH_WR(base_addr, LLD_UNLOCK_ADDR1, 0x80);
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR1, 0xAA);
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR2, 0x55);
  	FLASH_WR(base_addr, offset, 0x30);
}


int GetStatus(UINT32 * addr)
{
	UINT16 temp;
	temp=(UINT16)FLASH_RD(addr,0);
	while(((temp&0x0020)==0)&&((temp&0x0080)==0))
		temp=(UINT16)FLASH_RD(addr,0);

	if(temp&0x0080) 
		return 1;
	return 0;
}


void ResetCmd
(
UINT32 * base_addr   /* device base address in system */
)
{       
   	 /* Write Software RESET command */
    	FLASH_WR(base_addr, 0, 0xF0);
}


UINT32 GetDeviceId
(
	UINT32 * base_addr   /* device base address in system */
)
{
  	UINT32 id=0;

  
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR1, 0xAA);
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR2, 0x55);
  	FLASH_WR(base_addr, LLD_UNLOCK_ADDR1, 0x90);
  
 	id  = (UINT16)(FLASH_RD(base_addr, 0x0000)) ;
  	id  = id<<16; 
  	id  |= (UINT16)(FLASH_RD(base_addr, 0x0001)) ;

  	ResetCmd(base_addr);
  	return(id);
}


/* the entry of program:write and read flash */
void main(void)
{
  	int i=0, n;
  	startup();
  	UCHAR ch;
  	UINT32 * flashbase ;
  	UINT16 id;
  	flashbase =(UINT32 *) 0x29e0000;
  	SectorEraseCmd(flashbase,0x00);
  	if(!GetStatus(flashbase))
 	{
    		result("ERROR");
     		return ;
  	}

        char *tip="please input something ESC to quit\n\r";
        for(i=0;tip[i];i++)
           SMCPutChar(tip[i]);

  	ch=SMCGetChar();
  	i=0;
  	while(ch!=27) /*esc*/
  	{
    		ProgramCmd(flashbase, i, (UINT16)ch);
    		ch=SMCGetChar();
    		i++;
    
    		if(i%256==0) 
    		{
	 		SectorEraseCmd(flashbase, 0x00);
			if(!GetStatus(flashbase))
			{
	  			result("ERROR");
	   			return ;
			}
    		}
  	}
  
  	n=i;
  	for(i=0;i<n;i++)
  	{  
    		ch =(char) FLASH_RD(flashbase,i);
    		SMCPutChar(ch);
  	}
  	SMCPutChar('O');
  	SMCPutChar('K');
  	SMCPutChar('\n');
	return;
}


void result(char s[])
{
  	int i;
  	UINT8 ch;
  	SMCPutChar('\n');
  	for(i=0;  i<sizeof(s); i++)
    		SMCPutChar(s[i]);
  	SMCPutChar('\n');
  	return ;
}

/* read flash ID */
int mt()
{
	startup();
	UCHAR ch;
	UINT32 * flashbase ;
	UINT16 id;
	flashbase =(UINT32 *) 0x29e0000;
	ResetCmd(flashbase);

	ProgramCmd(flashbase,1,0x44);
	if(!GetStatus(flashbase)) 
		return 0;
	id = GetDeviceId(flashbase);
	SMCPutChar((id&0x00ff0000)>>16);
	SMCPutChar((id&0x0000ff00)>>8);
	SMCPutChar((id&0x000000ff));

	return 1;	/*GetStatus(flashbase)*/;
}

/* over write flash ID */
void testhh()
{
	startup();
	
	unsigned int id;
	UCHAR ch;
	UINT32 * flashbase ;
	flashbase =(UINT32 *) 0x29e0000;

	ResetCmd(flashbase);
	for(id=0;id<0xFFFFF;id++);

       int i;
       for(i=0xf0;i<0xff;i++)
      {
      		ResetCmd(flashbase);
		for(id=0;id<0xFFF;id++);
		ProgramCmd(flashbase,i,0x44);
	}

	/*adding delay!!!!, or maybe increccet, for flash operation speed can't match ppc core's*/
	id = FLASH_RD(flashbase,0x0000);

	SMCPutChar((UCHAR)id);

}

void startup()
{
	base = GetIMMR();
	mysmc=(SMC_PARAM *)(base+0x3E80);

	RxTxBD = (BDRINGS *)(base+0x2400);
	SMCBuffers = (LB *)(base+0x2500);
	SMCInit();
	*(BR0(base)) = (0x2800801);
}

UINT32 GetIMMR()
{
    	__asm__(" mfspr  3,638 ");        /* IMMR is spr #638 */
    	__asm__("rlwinm 3,3,0,0,15");
}


void SMCInit(void)

{
	UINT16 addr;

	/* Allow SMC TX, RX out */
	*(PBPAR(base)) |= (0x00C0); 
	*(PBDIR(base)) &= 0xFF3F;
	*(PBODR(base)) &=0xFF3F;
	*(PBDAT(base)) =0;

	/* Set Baud Rate to 115200 for 64.5 MHz System Clock.  */
	/* Enable BRG Count					  */
	*(BRGC2(base))= (0x00000044 | 0x10000);

	*(SIMODE(base)) &= ~(0x00008000);	/* SCM1:  NMSI mode */
	*(SIMODE(base)) &= 0xFFFF8FFF;
        *(SIMODE(base)) |=0x1000;	/*	 SCM1:  Tx/Rx Clocks are BRG2 */
        *(SDCR(base)) = 0x01;
  
	/* Set RXBD  */
	addr = (UINT16) (&RxTxBD->RxBD-base);
	addr = addr-0x2000;
	mysmc->rbase =  addr;
    	/*(UINT16) (&RxTxBD->RxBD-base-0x2000);*/

	/* Set TXBD table */
	addr= (UINT16) (&RxTxBD->TxBD-base);
	addr=addr-0x2000;
	mysmc->tbase = addr;	    

	for(*(CPCR(base)) = 0x0091;*(CPCR(base)) & 0x0001;) 

	mysmc->rfcr = 0x18;  
	mysmc->tfcr = 0x18;  

	 /* MRBLR = MAX buffer length */
	mysmc->mrblr = 1/*BUFFER_SIZE*/;    

	/* MAX_IDL = Disable MAX Idle Feature */
	mysmc->maxidl = 0;  
 
	/* BRKEC = No break condition occurred */
	mysmc->brkec = 0;    

	/* BRKCR = 1 break char sent on top XMIT */
	mysmc->brkcr = 1;    

	InitBDs();

	*(SMCE1(base)) = 0xFF;  /* Clear any pending events */
	*(SMCM1(base)) =0x17;/*12 13 00 normal 10 echo mode*/

	*(SMCMR1(base)) = 0x4820;
	*(SMCMR1(base)) |=0x0003;
}

void InitBDs(void)
{
   	RxTxBD->RxBD.statusMode = 0xA000;            /* Enable, Last BD */
  	RxTxBD->RxBD.dataLength = 1;
   	RxTxBD->RxBD.dataPointer = &(SMCBuffers->RxBuffer);

       RxTxBD->TxBD.statusMode = 0x2000;      /* Buffer not yet ready; Last BD */
   	RxTxBD->TxBD.dataLength = 1;
   	RxTxBD->TxBD.dataPointer = &(SMCBuffers->TxBuffer);
}

void SMCPutChar(UCHAR ch)
{
 	while (RxTxBD->TxBD.statusMode  &  0x8000);    

	*(RxTxBD->TxBD.dataPointer) = ch;                  
   	RxTxBD->TxBD.dataLength = 1;
	RxTxBD->TxBD.statusMode |= 0x8000;             
} 

UCHAR SMCGetChar(void)
{
	UCHAR ch;   /* output character from SMC */

   	while (RxTxBD->RxBD.statusMode  &  0x8000);      

   	ch = *(RxTxBD->RxBD.dataPointer);   
	 RxTxBD->RxBD.statusMode |= 0x8000;  

   	return ch;
}

UINT8 SMCPoll(void)
{
   	if(RxTxBD->RxBD.statusMode & 0x8000) 
   	{
		return 0;  /*  character NOT available */
   	} 
   	else
   	{
		return 1;  /*  character IS available */
   	}
} 

void  EchoChar(void)
{
	UCHAR mych;

	mych = SMCGetChar();
   
	SMCPutChar(mych);
} 

⌨️ 快捷键说明

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