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

📄 intel28f640_16x1.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* intel28f640_16x1.c:
 * Support for INTEL 28f640 or the 28f128 (double the size of the 640).
 * Bank configuration is as a single 16-bit device.
 */
#include "config.h"
#if INCLUDE_FLASH
#ifdef PIF_FLASH
#include "endian.h"
#include "stddefs.h"
#include "genlib.h"
#include "cpu.h"
#include "flash.h"
#include "intel28f640_16x1.h"
//stone added
#include "Pif.h"
#include "risc.h"
#include "28F640J3.h"
//stone added end
#define FLASHCFG_16x1	1
#include "strata.h"

/* Manufacturer and device id... */
#define INTEL_DT28F128J5		0x00890018
#define INTEL_28F640			0x00890017
#define INTEL_DT28F640J5		0x00890015
#define ST_M58LW064D			0x00200017

/*
*************************************************************************************
*                                       PifPCMCIAModeRegSet
*
* Description: Set rPIF_PCI_CTL.
*
* Arguments  : mode         can be the following values:
*                             PIF_BOOT_MODE;
*                             PIF_CBUS_MODE;
*                             PIF_DBUS_MODE
*              mstr-bs      It specifies the burst size on the memory bus for master 
*                           transactions. can be:
*                             PCMCIA_MSTR_BS_8BYTE
*                             PCMCIA_MSTR_BS_16BYTE
*                             PCMCIA_MSTR_BS_32BYTE
*                             PCMCIA_MSTR_BS_64BYTE
*
* Return     : none.
*
* Note(s)    : 
*************************************************************************************
*/
void PifPCMCIAModeRegSet(int mode, int mstr_bs)
{
    rPIF_PCI_CTL = (mode<<26) | (mstr_bs<<21);                  
}

/*
*************************************************************************************
*                                       PifTimingRegSet
*
* Description: Set rPIF_PCI_TIM.
*
* Arguments  : setup         controls the setup time from PCMCIA CS on to the 
*                            OE/WE/IOWR/IORD strobe on. It’s the PIF clock cycles.
*              hold          controls the hold time from the OE/WE/IOWR/IORD strobe 
*                            off to the CS.
*              interval      controls the interval of the OE/WE/IOWR/IORD on time.
*              wait_cycle    This field is useful when 'swait' bit is 1. It is the 
*                            idle cycles between each access started from asserting CS.
*              ioack_wait    can be:
*                              PIF_WAIT_INPACK - wait for 'inpack' signal during IORD
*                              PIF_NO_WAIT - don’t care 'inpack' signal
*              pimcia_width  can be:
*                              PCMCIA_WIDTH_8BIT – PCMCIA data is 8 bit wide
*                              PCMCIA_WIDTH_16BIT – PCMCIA data is 16 bit wide
*                              PCMCIA_WIDTH_DEPEND – PCMCIA width is depending on 
*                                                    'is_16bit' pin input
*              wait          can be:
*                              PCMCIA_CHECK_WAIT – PCMCIA check the ‘wait’ input 
*                                                  pin during OE/WE/IOWR/IORD pulse
*                              PCMCIA_NO_CHECK – PCMCIA doesn’t check ‘wait’ input pin
*              swait         can be:
*                              PCMCIA_INSERT_IDLE – PCMCIA insert idle cycles for 
*                                                   specified cycles before actual
*                                                   transfer cycle
*                              PCMCIA_NO_INSERT – PCMCIA doesn’t insert idle cycles
*              devID         controls which PCMCIA device to access. One of the 
*                            4 CS signals are enabled according to:
*                              PIF_CS0
*                              PIF_CS1
*                              PIF_CS2
*                              PIF_CS3
*
*              xfr_type      can be:
*                              PIF_IORD - IO read use IORD
*                              PIF_IOWR - IO write use IOWR
*                              PIF_OE - memory read use OE
*                              PIF_WE - memory write use WE
*
* Return     : none.
*
* Note(s)    : 
*********************************************************************************************
*/
void PifTimingRegSet(int setup, int hold, int interval, int wait_cycle, int ioack_wait,\
                     int pcmcia_width, int wait, int swait, int devID, int xfr_type)
{
    rPIF_PCI_TIM = setup | (hold<<4) | (interval<<8) | (wait_cycle<<16) | (ioack_wait<23)|\
                   (pcmcia_width<<24) | (wait<<26) | (swait<<27) | (devID<<28) |\
                   (xfr_type<<30);	
}


/*
*********************************************************************************************
*                                       PifWaitTillDone
*
* Description: It is a delay function, waiting the master transaction is finished.
*
* Arguments  : none
*
* Return     : none.
*
* Note(s)    : 
*********************************************************************************************
*/
void PifWaitTillDone(void)
{
    /* Wait till the busy bit is clear & the done bit is set */	
    while(rPIF_INTR & 0x60000000 ^ (0x1<<29));
    
    /* Clear the done bit */
    PIF_DONE_CLEAR();	
}

/*
**************************************************************************************
*                                       NorFlashPifInit
*
* Description: initialize the PCMCIA interface
*
* Arguments  : devID     controls which PCMCIA device to access. 
*                                  0 – CS0
*                                  1 – CS1
*                                  2 – CS2
*                                  3 – CS3
*                            For Virtex-4, devID = 0.
*
* Return     : none
*
* Note(s)    : Before any Nor flash operations, you should call it at first.
**************************************************************************************
*/
/*4> word 0xa80a0000
0x04000000
5> word 0xa80a0010
0x890F0FFF
6>*/ 
void NorFlashPifInit(void)
{
    unsigned int tmp;
    
    PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);    
    
    PifTimingRegSet(0xf /* setup */, 0xf /* hold */, 0xf /* interval */, \
                    0xf /* wait_cycle */, PIF_NO_WAIT /* ioack_wait */, \
                    PCMCIA_WIDTH_16BIT /* pcmcia_width */, PCMCIA_NO_CHECK /* wait */, \
                    PCMCIA_INSERT_IDLE /* swait */, PIF_CS0 /* devID */, \
                    PIF_OE /* xfr_type */);
    
    PIF_INTR_DIS();       // Disable the PIF interrupts
    PIF_DONE_CLEAR();     // Clear the bit done
    
    tmp = *(unsigned int *)0xa80a001c;
    tmp &= 0x7fffffff;
    *(unsigned int *)0xa80a001c = tmp;
}

/*
*********************************************************************************************
*                                       NorFlashRd
*
* Description: read the data from the specified address.
*
* Arguments  : start_addr       is the start byte address.
*              data             is the data pointer.
*              number           is the data of number to be read. It is counted by half-words.
*
* Return     : none.
*
* Note(s)    : 
*********************************************************************************************
*/
void NorFlashRd(int start_addr, short *data, int number)
{
    unsigned int i, tmp;	        

    PIF_READ_SET();
    rPIF_PCI_LEN = 2;          // rPIF_PCI_LEN is counted by bytes.  	
        
    for(i = 0; i < number; i++) {
    	rPIF_PCI_DEV_A = start_addr;    // the byte address
    	start_addr += 2;	    	
    	PIF_START();    	
        *data++ = rPIF_PCMCIA_DATA;	        
    }
}

/*
*********************************************************************************************
*                                       NorFlashRdData
*
* Description: read the data from the specified address.
*
* Arguments  : start_addr       is the start byte address.
*              data             is the data pointer.
*              number           is the data of number to be read. It is counted by half-words.
*
* Return     : none.
*
* Note(s)    : 
*********************************************************************************************
*/
void NorFlashRdData(int start_addr, short *data, int number)
{
    int i;	
	
    /* The read array command */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    PIF_START();
    rPIF_PCMCIA_DATA = NOR_FLASH_RD_ARRAY;
    
    PifWaitTillDone();           // Wait till the first cycle complete
    
    NorFlashRd(start_addr, data, number);    	
}

/*
*********************************************************************************************
*                                       NorFlashRdID
*
* Description: read the manufacture ID, device ID, and block lock configuration.
*
* Arguments  : mID              is the manufacture ID pointer.
*              deviceID         is the device ID pointer.
*              block_lock_cfg   is the block lock configuration.
*
* Return     : none.
*
* Note(s)    : 
*********************************************************************************************
*/
void NorFlashRdID(short *mID, short *deviceID, short *block_lock_cfg)
{
    short status;
    	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    PIF_START();
    rPIF_PCMCIA_DATA = NOR_FLASH_RD_ID;
    
    PifWaitTillDone();         // Wait till the first cycle complete	
    
    NorFlashRd(0, mID, 1);
    NorFlashRd(2, deviceID, 1);
    NorFlashRd(4, block_lock_cfg, 1);
}

/*
*********************************************************************************************
*                                       NorFlashProg
*
* Description: program a half-word into the specified address
*
* Arguments  : addr     is the byte address. 
*              data     is the half-word to be programmed.
*
* Return     : SUCCESSFUL  shows the erasure is successful.
*              FAILED      shows the erasure is failed.
*
* Note(s)    : 
*********************************************************************************************
*/
int NorFlashProg(int addr, short data)
//int NorFlashProg(unsigned char *addr, unsigned char *data)
{
    short status;
    	
    /* the first cycle */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    PIF_START();
    rPIF_PCMCIA_DATA = NOR_FLASH_PROG_WORD;
    
    PifWaitTillDone();         // Wait till the first cycle complete
    
    /* the second cycle */	
    rPIF_PCI_DEV_A = addr;     // the byte address
    PIF_START();
    rPIF_PCMCIA_DATA = data;
    
    PifWaitTillDone();         // Wait till the second cycle complete
    
    status = 0x0;
    
    while(!(status & 0x80)) {     // Flash is busy?
        NorFlashRd(0, &status, 1);
    }
    if(status & 0x1a)             // Whether the SR1 SR3 or SR4 is set
        return FAILED;
    return SUCCESSFUL;
}


/* Intel28f640_16x1_erase():
 * Erase sector 'snum'.
 * Return 0 if success, else negative.
 */
int
Intel28f640_16x1_erase(struct flashinfo *fdev,int snum)
{

	short status;
    	
    /* the first cycle of block erase */	
    PIF_WRITE_SET();
    rPIF_PCI_LEN = 2;
    rPIF_PCI_DEV_A = fdev->sectors[snum].begin;    // the byte address
    PIF_START();
    rPIF_PCMCIA_DATA = NOR_FLASH_ERASE_BLOCK1;
    
    PifWaitTillDone();         // Wait till the first cycle complete
    
    /* the second cycle of block erase */	
    PIF_START();
    rPIF_PCMCIA_DATA = NOR_FLASH_ERASE_BLOCK2;
    
    PifWaitTillDone();         // Wait till the second cycle complete
    
    status = 0x0;
    
    while(!(status & 0x80)) {     // Flash is busy?
        NorFlashRd(0, &status, 1);
    }
    if(status & 0x30)             // Whether the SR4 or SR5 is set
        {
		printf("erase sec[%d] error\r\n",snum);
		return -1;
    	}
	printf("erase sec[%d] successful\r\n",snum);
    return 0;
	//return 0;//zx debug
/*	
	// Issue the setup/confirm sequence:
	
	STRATACMD_BLOCKERASE(fdev->sectors[snum].begin);
	STRATACMD_CONFIRM(fdev->sectors[snum].begin);

	// Wait for completion:
	
	WAIT_FOR_WSMS_STATUS_READY();

	// Cleanup:
	 
	STRATACMD_CLEARSTATUS();
	STRATACMD_READARRAY();
	WAIT_FOR_FF(fdev->sectors[snum].begin);
	return(0);
*/
}

/* EndIntel28f640_16x1_erase():
 * Function place holder to determine the end of the above function.
 */
void
EndIntel28f640_16x1_erase(void)
{}

int
Intel28f640_16x1_write(struct flashinfo *fdev,uchar *dest,uchar *src,
	long bytecnt)
{
	int		i,addr;
	short	data;
	uchar	temp;

	addr = dest;
	for(i = 0; i < bytecnt/2; i ++) {
		//printf("current char : %c\r\n",src[i]);
		temp = *src++;
		data = (*src<<8) | temp;
		/*data = *src<<8;
		src++;
		data |= *src;*/
		//printf("program data is 0x%x\t Addr is:0x%x\r\n",data,addr);
		NorFlashProg(addr, data);
		//printf("After program\r\n");
		/* Flash program setup command */
		addr +=2;
		src++;
	}
	printf("Write %d byte OK!\r\n",bytecnt);
	
}

int
Intel28f640_16x1_write1(struct flashinfo *fdev,uchar *dest,uchar *src,
	long bytecnt)
{
	volatile int	tot, ret;
	int				i, giveup, aligntot, size;
	volatile uchar	buf[BUFFER_SIZE], *aligndest, *block;

	return 0;//zx debug
	
	/* The write buffer can only be used on 32-byte blocks; hence, the
	 * low 5 bits of the destination must be zero at the start of a 
	 * buffer write.  This means that we must align the destination
	 * address on this boundary.  To do this, we decrement the destination
	 * address until the alignment is reached, then load that space with
	 * the same data that is already there.
	 */ 
	aligntot = 0;
	aligndest = dest;
	while(((ulong)aligndest & BUFFER_ALIGN) != 0) {
		aligndest--;
		aligntot++;
		bytecnt++;
	}

	ret = tot = 0;
	while((tot < bytecnt) && (ret == 0)) {
		size = bytecnt - tot;
		if (size > BUFFER_SIZE)
			size = BUFFER_SIZE;

		block = aligndest;

		/* Copy buffer's worth of data into local buffer just in
		 * case the source is this flash device.
		 */
		for(i=0;i<size;i++) {
			if (aligndest < dest)
				buf[i] = *aligndest++;
			else
				buf[i] = *src++;
		}
		if (size & 1) {

⌨️ 快捷键说明

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