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

📄 norflash.c

📁 这是一个基于硬件平台s3c44B0和操作系统为ucos的矩阵键盘的程序
💻 C
字号:
#include "44blib.h"
#include "uart_lib.h"
#include "NorFlash.h"


#define BufLength  4096
volatile unsigned short g_Buf16[BufLength]; 


#define ROM_BASE  	0
#define	CMD_ADDR0	*((volatile unsigned short *)(0x5555*2+ROM_BASE))
#define	CMD_ADDR1	*((volatile unsigned short *)(0x2aaa*2+ROM_BASE))



void DelayCycle(unsigned short n)
{
	while(n--);
}


static void SWPIDEntry(void)
{
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x9090;
	DelayCycle(10);
}

static void SWPIDExit(void)
{
	CMD_ADDR0 = 0xf0f0;
}


int GetFlashID(void)
{
	int i;
	
	SWPIDEntry();
	
	i  = *(volatile unsigned short *)(0x0+ROM_BASE);
	i |= (*(volatile unsigned short *)(2+ROM_BASE))<<16;
	
	SWPIDExit();
	return i;	
}




int FlashSectorErase(volatile unsigned short * addr)
{
	int count = 5000000;
	 
	CMD_ADDR0 = 0xaaaa;	
	CMD_ADDR1 = 0x5555;	
	CMD_ADDR0 = 0x8080;	
	CMD_ADDR0 = 0xaaaa;	
	CMD_ADDR1 = 0x5555;	
	*addr = 0x3030;		

    while (--count && ((*addr & 0xff) != 0xff))
    {
    }
 
	return count;
}



int FlashBlockErase(volatile unsigned short * addr)
{
	 int count = 5000000;

	CMD_ADDR0 = 0xaaaa;	
	CMD_ADDR1 = 0x5555;	
	CMD_ADDR0 = 0x8080;	
	CMD_ADDR0 = 0xaaaa;	
	CMD_ADDR1 = 0x5555;	
	*addr = 0x5050;		

    while (--count && ((*addr & 0xff) != 0xff))
    {
    }
 
	return count;
}



int FlashChipErase(void)
{
	int count = 5000000;

	CMD_ADDR0 = 0xaaaa;	
	CMD_ADDR1 = 0x5555;	
	CMD_ADDR0 = 0x8080;	
	CMD_ADDR0 = 0xaaaa;	
	CMD_ADDR1 = 0x5555;	
	CMD_ADDR0 = 0x1010;	

    while (--count && ((CMD_ADDR1 & 0xff) != 0xff))
    {
    }
 
	return count;
}



int FlashProgram(volatile unsigned short * addr, volatile unsigned short * data, unsigned int word_len)
{
     int count;
     unsigned short temp_data,temp1, temp2;

     while(word_len--) 
     {
     	temp_data = *data;
     	CMD_ADDR0 = 0xaaaa;
        CMD_ADDR1 = 0x5555;
        CMD_ADDR0 = 0xa0a0;
        *addr = temp_data;	
        count = 1000;
        
        while (--count)
        {
        	temp1 = *addr;
        	temp2 = *addr;
        	if( (temp1&(1<<6)) == (temp2&(1<<6)) )
        		break; 
        }
        
        if (count == 0)
            break;
            
        addr++;
        data++;
     }

     if ( count == 0  )
          Uart_Printf("Failed @ 0x%06x, req: 0x%04x, act: 0x%04x, now: 0x%04x\r\n", addr, *data, temp2, *addr);
     return count;
}



static void SecurityIdEntry(void)
{
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x8888;
	DelayCycle(10);
}

static void SecurityIdExit(void)
{
	CMD_ADDR0 = 0xf0f0;
	DelayCycle(10);
}




void GetSecurityID(unsigned short *SecurityID)
{
	unsigned short i;
	
	SecurityIdEntry();
	
	for(i=0x00;i<0x20;i++)
		*SecurityID++  = *(volatile unsigned short *)(ROM_BASE+i*2);
	
	SecurityIdExit();
}



void ShowSecurityID(void)
{
	int i;
	unsigned short SecurityID[32];
	
	for(i=0;i<32;i++)
		SecurityID[i]=0xffff;
	
	GetSecurityID(SecurityID);
	
	for(i=0;i<32;i++)
	{
    	if(i<8)
    	{
    		Uart_Printf("SID[0x%02x]=0x%04x\n",i,SecurityID[i]);
    	}
    	
    	if(i>=16 && i<24)	
    	{
    		Uart_Printf("SID[0x%02x]=0x%04x\n",i,SecurityID[i]);
    	}	
    }
}



void UserSIDWrite( unsigned short index, unsigned short data)
{
	 volatile unsigned short * addr;
	
	 addr = (volatile unsigned short *)ROM_BASE;
	
     {
     	CMD_ADDR0 = 0xaaaa;
        CMD_ADDR1 = 0x5555;
        CMD_ADDR0 = 0xa5a5;
        *(addr+index) = data;	
        
        DelayCycle(10000);
     }
}




//***************************************//
// Nor Flash 测试函数
//***************************************//

int TestNorFlash()
{
	int i;
	
	volatile unsigned short * addr = (volatile unsigned short * )0x200000;		// 2M
	static int gCount;
	
	char ch;
	
	i=GetFlashID();
    Uart_Printf("FlashID=%xh\r\n",i);
	
	
	do{
    	Uart_Printf("\nkey 'e' to erase\r\n");
    	Uart_Printf("key 'r' to read\r\n");
    	Uart_Printf("key 'w' to write\r\n");
     	Uart_Printf("key 'p' to previous sector\r\n");
     	Uart_Printf("key 'n' to next sector\r\n\r\n");
   	
		ch = SerialGetChar(0);
		    
		switch(ch)
		{
			case 'p': 	// 选择前一个扇区
				addr -= 1024*2;
				break;
				
			case 'n': 	// 选择后一个扇区
				addr += 1024*2;
				break;
				
			case 'e': 	// 擦除扇区
				
				// 擦除的最小单位是扇区,39VF3201的扇区大小是4K
			
                Uart_Printf("Erase sector at 0x%06x ", addr);
                if( FlashSectorErase(addr))
                    Uart_Printf("OK!\r\n");
                else 
                    Uart_Printf("Failed!\r\n");

				break;
				
			case 'E': 	// 擦除芯片
				
                Uart_Printf("Erase chip ");
                if( FlashChipErase())
                    Uart_Printf("OK!\r\n");
                else 
                    Uart_Printf("Failed!\r\n");

				break;
				
			case 'r': 	// 读扇区
				
				// 数据可以按字/字节方式读
			
                Uart_Printf("Read data from 0x%06x:\r\n------------\r\n ",addr);
				for(i=0;i<4096;i++)
				{
					if(i%16==0)
						Uart_Printf("\r\n[0x%06X]:\t",(volatile unsigned char *)addr+i);
					
					//if(i%16==0)
						Uart_Printf("0x%02X\t",*((volatile unsigned char *)addr+i)) ;
					
				}	
                Uart_Printf("\r\n-----------\nRead data end\r\n ");

				break;
				
			case 'w': 	// 写部分扇区
				// 数据可以按字(16位短整数)方式写入,但必须先在所写位置为空(0xffff)的时候才可以写入正确的值
				// 不能按字节写,因为该FLASH是2M*16的FLASH,一次至少要写16位
			
                Uart_Printf("Burn data to 0x%06x ",addr);
                for(i=0;i<128;i++)
                	g_Buf16[i]=i;
                
                if( FlashProgram(addr, g_Buf16, 128) )
                    Uart_Printf("OK!\r\n");
                else 
                    Uart_Printf("Failed!\r\n");
				
				break;
				
			case 'W': 	// 写多个扇区
			
                Uart_Printf("Burn data to 0x%06x ",addr);
                for(i=0;i<BufLength;i++)
                {
                	g_Buf16[i]= (int)addr + i*2;
                    //Uart_Printf("Buf32[0x%04x]=0x%04x\r\n",i,Buf32[i]);
                }
                
                if( FlashProgram(addr, g_Buf16, BufLength) )
                    Uart_Printf("OK!\r\n");
                else 
                    Uart_Printf("Failed!\r\n");
				
				break;
				
			case 's': 	// 写1个扇区
			
				gCount++;
			
                Uart_Printf("Burn data 0x%04x to 0x%06x ",gCount,addr);
                for(i=0;i<2048;i++)
                {
                	g_Buf16[i]= gCount;
                    //Uart_Printf("Buf32[0x%04x]=0x%04x\r\n",i,Buf32[i]);
                }
                
                if( FlashProgram(addr, g_Buf16, 2048) )
                    Uart_Printf("OK!\r\n");
                else 
                    Uart_Printf("Failed!\r\n");
				
                Uart_Printf("g_Buf16[0x%04x]=0x%04x\r\n",16,g_Buf16[16]);
				
				break;
				
			
			
			case 'i':	// Security ID

				ShowSecurityID();

				break;
				
					
				
			default:
				break;
		}		
	} while(ch!=0x1b);  //KEY_ESC
				
	return 0;
}

⌨️ 快捷键说明

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