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

📄 strata16.c

📁 三星公司S3c2443的测试程序源码
💻 C
字号:
/*======================================================================

 Project Name : S3C2443 verification project

 Copyright 2006 by Samsung Electronics, Inc.
 All rights reserved.

 Project Description :
 This software is only for verifying functions of the S3C2443. 
 Anybody can use this code without our permission.

 File Name    : strata16.c
 Description  : Program Strata 16-bit NOR Flash(32MB)
 Author       : Junon Jeon
 Dept         : AP
 Created Date : 2006.06.02
 Version      : 0.0
 History
   R0.0 (2006.06.02): Junon draft
		- This code is derived from flash.c of S3C2413A test code.
		
=======================================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "option.h"
#include "2443addr.h"
#include "Console.h"
#include "strata16.h"

static void InputAddresses(void);
static int  Strata_ProgFlash(unsigned int realAddr,unsigned short data);
static void	Strata_EraseSector(int targetAddr);
static int  Strata_CheckID(int targetAddr);
static int  Strata_CheckDevice(int targetAddr);
static void Strata_Unlock(int targetAddr);
static void Strata_SetBlockLock(int targetAddr);
static int  Strata_CheckBlockLock(int targetAddr);
static void	Strata_ClearBlockLock(int targetAddr); 
static int  Strata_BlankCheck(int targetAddr,int targetSize);
static int  _WAIT(void);

static unsigned int srcAddress;
static unsigned int targetOffset; 
static unsigned int targetAddress; 
static unsigned int targetSize; 

// Because S3C2443 is connected to Intel StrataFlash 28F128J3A,
// the addr parameter has to be a WORD address, so called in Intel specification.
#define _WR(addr,data)  *((volatile unsigned short *)(addr))=(unsigned short)data 
#define _RD(addr)       ( *((volatile unsigned short *)(addr)) )       

// _RESET() : Read Array
#define _RESET()    _WR(targetAddress,0x00ff)


static int Strata_CheckID(int targetAddr) 
{
    _RESET();
    _WR(targetAddr, 0x0090); 
	printf("Identification code=%x, Target Addr=%x\n",_RD(targetAddr), targetAddr);
	return _RD(targetAddr); // Read Identifier Code, including lower, higher 16-bit, 8MB, Intel Strate Flash ROM
                            // targetAddress must be the beginning location of a Block Address
}


static int Strata_CheckDevice(int targetAddr) 
{
    //_RESET();
    _WR(targetAddr, 0x0090);
	printf("Identification code=%x\n",_RD(targetAddr+0x2));
	return _RD(targetAddr+0x2); // Read Device Code, including lower, higher 16-bit, 8MB, Intel Strate Flash ROM
                                // targetAddress must be the beginning location of a Block Address
}


static void Strata_Unlock(int targetAddr) 
{
    _RESET();
    _WR(targetAddr, 0x0060);
    _WR(targetAddr, 0x00D0);
}


static void Strata_SetBlockLock(int targetAddr)
{
	_RESET();
	_WR(targetAddr, 0x0060);
	_WR(targetAddr, 0x0001);
}


static int Strata_CheckBlockLock(int targetAddr) 
{
    //_RESET();
    _WR(targetAddr, 0x0090);
    return _RD(targetAddr+0x4); // Read Block Lock configuration, 
                                // targetAddress must be the beginning location of a Block Address
}


//==========================================================================================
static void Strata_ClearBlockLock(int targetAddr) 
{
    unsigned int status,ReadStatus;
	unsigned long bSR7,bSR1;
    //_RESET();
    _WR(targetAddr, 0x0060);
    _WR(targetAddr, 0x00d0);

	_WR(targetAddr, 0x0090);
	status=_RD(targetAddr+0x4); 
	bSR7=status & (1<<7);
	bSR1=status & (1<<1);
	
	printf("Block status register value: %x\n",status);
	
	while(bSR1) 
	{
		_WR(targetAddr, 0x0090);
		status=_RD(targetAddr+0x4); 
		bSR1=status & (1<<1);
		if(!bSR1)break;
	}

	printf("Device is unlocked\n");
	
	_WR(targetAddr, 0x0070);	// Read Status Register
	ReadStatus=_RD(targetAddr);	// realAddr is any valid address within the device
	bSR7=ReadStatus & (1<<7);
	while(!bSR7 ) 
	{
		_WR(targetAddr, 0x0070);		  // Read Status Register
		ReadStatus=_RD(targetAddr);
		bSR7=ReadStatus & (1<<7);
	}
	
    _RESET();
}

//==========================================================================================
void Strata_EraseSector(int targetAddress) 
{
    unsigned long ReadStatus;
    unsigned long bSR5;     // Erase and Clear Lock-bits Status, lower 16bit, 8MB Intel Strate Flash ROM
    unsigned long bSR7;     // Write State Machine Status, lower 16bit, 8MB Intel Strate Flash ROM

    //_RESET();
    _WR(targetAddress, 0x0020); // Block Erase, First Bus Cycle, targetAddress is the address withint the block
    _WR(targetAddress, 0x00d0); // Block Erase, Second Bus Cycle, targetAddress is the address withint the block
    
    //_RESET();
    _WR(targetAddress, 0x0070); // Read Status Register, First Bus Cycle, targetAddress is any valid address within the device
    ReadStatus=_RD(targetAddress);  // Read Status Register, Second Bus Cycle, targetAddress is any valid address within the device
    bSR7=ReadStatus & (1<<7);       // lower 16-bit 8MB Strata
    while(!bSR7) 
    {
        _WR(targetAddress, 0x0070);
        ReadStatus=_RD(targetAddress);
        bSR7=ReadStatus & (1<<7);
    }

    _WR(targetAddress, 0x0070); // When the block erase is complete, status register bit SR.5 should be checked. 
                    // If a block erase error is detected, the status register should be cleared before
                    // system software attempts correct actions.
    ReadStatus=_RD(targetAddress);  
    bSR5=ReadStatus & (1<<5);           // lower 16-bit 8MB Strata 
    if (bSR5==0) 
    {
        printf("Block_%x Erase O.K. \n",targetAddress);
    } 
    else 
    {
        printf("Error in Block Erasure!!\n");
        _WR(targetAddress, 0x0050); // Clear Status Register
    }

    _RESET();   // write 0xffh(_RESET()) after the last opoeration to reset the device to read array mode.
}


//==========================================================================================
int Strata_BlankCheck(int targetAddr,int targetSize) 
{
    int i,j;
    for (i=0; i<targetSize; i+=2) 
    {
        j=*((volatile unsigned short *)(i+targetAddr));
        if (j!=0xffff)      // In erasure it changes all block dta to 0xff
        {
            printf("E : %x = %x\n", (i+targetAddr), j);
            return 0;
        }
    }
    return 1;
}


int Strata_ProgFlash(unsigned int realAddr,unsigned short data) 
{
	volatile unsigned short *ptargetAddr;
	unsigned int ReadStatus;
	unsigned int bSR7;	  // Write State Machine Status, 8MB Intel Strate Flash ROM

	ptargetAddr = (volatile unsigned short *)realAddr;

	_WR(realAddr, 0x0040);	// realAddr is any valid adress within the device
	*ptargetAddr=data;			// 16 bit data

	_WR(realAddr, 0x0070);	// Read Status Register
	ReadStatus=_RD(realAddr);	// realAddr is any valid address within the device
	bSR7=ReadStatus & (1<<7);

	while(!bSR7 ) 
	{
		_WR(realAddr, 0x0070);		  // Read Status Register
		ReadStatus=_RD(realAddr);
		bSR7=ReadStatus & (1<<7);
	}
	
	_WR(realAddr, 0x0070); 
	ReadStatus=_RD(realAddr);			  // Real Status Register

	if(ReadStatus&(1<<3))
	{
		printf("Voltage Range Error\n");
		_WR(realAddr, 0x0050);			// Clear Status Register	
		return 0;
	}	
	if(ReadStatus&(1<<1))
	{
		printf("Device Protect Error\n");
		_WR(realAddr, 0x0050);			// Clear Status Register	
		return 0;
	}	
	if(ReadStatus&(1<<4))
	{
		printf("Programming Error\n");
		_WR(realAddr, 0x0050);			// Clear Status Register	
		return 0;
	}	
	
	return 1;
}


#define TARGET_ADDR_28F128      0x08000000  // nRCS1
#define SOURCE_ADDR_FOR_28F128    0x31000000  // After 16MB of SDRAM
                                            // 0x30000000 - 0x30ffffff : Area for this test program

//==========================================================================================                                            
void Program28F128J3A(void)
{
// FlashROM write program must reside at RAM region NOT ROM region
// In reading and writing all interrupts are disabled because the flash ROM
// strongly dislike to be disturbed by other stuff.
// And the region of flash ROM must be I/O region which means NO cacheable
// and NO bufferable in MMU. Check it out !!!
// 2001.6.18. Mon. It's local rain. I'll hope it eliminates the drought in Korea. by chc

    int i;

    printf("\n[ 28F128J3A-16bit Flash Writing Program ]\n\n");
   
	// Bandwidth : 16-bit, asyncronous
//	rSMBCR0 = 
//	rSROM_BW=rSROM_BW&~(1<<9);
//	rSROM_BW=(rSROM_BW&~(0x40))|(0x1<<6);
	
    rINTMSK = BIT_ALLMSK;   
    targetAddress=TARGET_ADDR_28F128;
    targetSize=UartDownProgramSize;

	printf("Src size=%x\n",targetSize);

    if(targetSize==0)
    {
        printf("\nThe data must be downloaded using ICE or USB from 0x11000000\n");
        srcAddress=UartDownAddress; 
    }
    else
    { 
        srcAddress=UartDownAddress+4; //to discard the data head for the size
    }
        
    InputAddresses(); //srcAddress,targetSize,targetOffset will be determined.      
    printf("Source base address(0x11000000) = 0x%x\n",srcAddress);
    printf("Target base address(0x08000000) = 0x%x\n",targetAddress);
    printf("Target offset      (0x0)        = 0x%x\n",targetOffset);
    printf("Target size        (0x20000*n)  = 0x%x\n",targetSize);

    if ( (Strata_CheckID(targetAddress) & 0xffff) != 0x0089)       // ID number = 0x0089
    {
        printf("Identification check error(%x)!!\n",Strata_CheckID(targetAddress) & 0xffff);
        return ;
    }

    if ( (Strata_CheckDevice(targetAddress) & 0xffff) != 0x8803)   // Device number=0x0018 0x8803 
    {
        printf("Device check error !!\n");
        return ;
    }
	
	for(i=0;i<targetSize;i+=0x10000)
    {
	   	Strata_ClearBlockLock(targetAddress+targetOffset+i); 
	    Strata_EraseSector(targetAddress+targetOffset+i);
    }

    printf("\nErase the sector : 0x%x.\n", targetAddress);

    if(!Strata_BlankCheck(targetAddress+targetOffset,targetSize))
    {
        printf("Blank Check Error!!!\n");
        return;
    }

    printf("\nStart of the data writing...\n");

    for (i=0; i<targetSize; i+=2) 
    {
	    Strata_ProgFlash(i+targetAddress+targetOffset, *((unsigned short *)(srcAddress+i)));
	    if(i%0x10000==0xfffc)
            printf("[%x]",(i+4)/0x10000);
    }
    printf("\nEnd of the data writing \n");

    _RESET();


    printf("Verifying Start...\n");
    for (i=0; i<targetSize; i+=2) 
    {
        if (*((unsigned short *)(i+targetAddress+targetOffset)) !=*((unsigned short *)(i+srcAddress))) 
        {
            printf("verify error  src %08x = %04x\n", srcAddress+i, *((unsigned short *)(srcAddress+i)));
            printf("verify error  des %08x = %04x\n", i+targetAddress+targetOffset, *((unsigned short *)(i+targetAddress)));
			return;
        }
	 }

	printf("Verifying End!!!");
}


void Erase28F128J3A(void)  
{
// FlashROM write program must reside at RAM region NOT ROM region
// In reading and writing all interrupts are disabled because the flash ROM
// strongly dislike to be disturbed by other stuff.
// And the region of flash ROM must be I/O region which means NO cacheable
// and NO bufferable in MMU. Check it out !!!

    int i;

    printf("\n[ 28F128J3A Flash Writing Program ]\n\n");
    printf("     *** Very Important Notes ***\n");
    printf("1. 28F128J3A must be located at 0x08000000.\n");
    printf("2. After programming, 28F128J3A may be located at 0x0.\n");

    rINTMSK = BIT_ALLMSK;   
    targetAddress=TARGET_ADDR_28F128;
    targetSize=UartDownProgramSize;
    //UartDownAddress=0x31000000;

    if(targetSize==0)
    {
        printf("\nThe data must be downloaded using ICE or USB from 0x31000000\n");
        srcAddress=UartDownAddress; 
    }
    else
    { 
        srcAddress=UartDownAddress+4; //to discard the data head for the size
    }

    InputAddresses(); //srcAddress,targetSize,targetOffset will be determined.      
    printf("Source base address(0x31000000) = 0x%x\n",srcAddress);
    printf("Target base address(0x08000000) = 0x%x\n",targetAddress);
    printf("Target offset      (0x0)        = 0x%x\n",targetOffset);
    printf("Target size        (0x20000*n)  = 0x%x\n",targetSize);

    if ( Strata_CheckID(targetAddress)  != 0x0089 )       // ID number = 0x0089
    {
		printf("Read ID : 0x%x\n", Strata_CheckID(targetAddress));
        printf("Identification check error !!\n");
        return ;
    }

    if ( Strata_CheckDevice(targetAddress) != 0x0018 )   // Device number=0x0018
    {
        printf("Device check error !!\n");
        return ;
    }
		
#if 1 // lock bit setting test 
//	Strata_SetBlockLock(targetAddress+0x10000); //just test
    for(i=0;i<10;i++)
		printf("%d block value is %d\n", i, Strata_CheckBlockLock(targetAddress+0x20000*i)&0x00010001);
//	    if ( Strata_CheckBlockLock(targetAddress+0x20000*i) != 0x0 )   // Device number=0x0018
//	        printf("%d block is locked !!\n", i);
	Strata_Unlock(targetAddress);
	for(i=0;i<10;i++)
	printf("%d block value is %d\n", i, Strata_CheckBlockLock(targetAddress+0x20000*i)&0x00010001);
#endif
//	Strata_Unlock(targetAddress);

    printf("\nErase the sector : 0x%x.\n", targetAddress);

    for(i=0;i<targetSize;i+=0x20000)
    {
        Strata_EraseSector(targetAddress+targetOffset+i);
    }
    
    if(!Strata_BlankCheck(targetAddress+targetOffset,targetSize))
    {
        printf("Blank Check Error!!!\n");
        return;
    }

}


//==========================================================================================
static void InputAddresses(void)
{
    printf("\n[ 28F128J3A Writing Program ]\n");

    printf("\nSource size [0x?] : 0h~%xh\n",UartDownProgramSize);
    printf("\nAvailable Target Offset Address:0h,10000h,20000h, ..., ff0000h\n"); 
    printf("Input target address offset [0x?] : ");
    targetOffset=GetIntNum();
	if(targetOffset==(unsigned int)(-1)) targetOffset=0x0;	
    if(targetSize==0)
    {
        printf("Input target size [0x?] : ");
		if(targetOffset==(unsigned int)(-1)) targetOffset=0x0;	
        targetSize=GetIntNum();
    }
}


⌨️ 快捷键说明

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