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

📄 amd.cpp

📁 Ep93XX TionProV2 BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:

    ULONG	nResult = 0 ;

#ifdef READ_FROM_REGISTRY
    BYTE cTempBuffer[SECTOR_SIZE];
#endif

   
	RETAILMSG(ZONE_TEST, (TEXT("FMD_WriteSector: startAdd =%x num=%x)  sector_add=%x sectorinfo_add=%x.\r\n"),startSectorAddr,dwNumSectors,
							pSectorBuff,pSectorInfoBuff));


    //----- 1. Check the input parameters -----
    //         NOTE: The FAL insures that the starting sector address is in the allowable range.
    if((dwNumSectors == 0) || ((pSectorBuff == NULL) && (pSectorInfoBuff == NULL)))
    {
        return(FALSE);
    }

    //----- 2. Process the write request(s)... -----

    bLastMode = SetKMode(TRUE);
    
    for(i = startSectorAddr; i < (startSectorAddr + dwNumSectors); i++)
    {
        //----- Determine the block this physical sector resides in -----
        blockID = (i / g_FMDInfo.SectorsPerBlock);

        //----- Compute the physical address for the requested sector -----
        // Note we do this differently based on whether the caller wants us to write the sector information structure as well.  Since we're
        // dealing with a NOR flash which is XIP-able, one might want to use this function to write an XIP region (i.e., no sector information
        // structures in flash).
        //
        if (!g_bXIPMode)
            physicalSectorAddr = g_FMDInfo.BaseAddress + i*(SECTOR_SIZE + sizeof(SectorInfo)) 
								+ (blockID * g_FMDInfo.UnusedBytesPerBlock);
        else
            physicalSectorAddr = g_FMDInfo.BaseAddress + (i*SECTOR_SIZE);

        // Compute the block address for this sector write.
        //
        ulBlockAddress = (ULONG)(physicalSectorAddr - (physicalSectorAddr % g_FMDInfo.BlockSize));
        
        //----- Write the necessary sector data -----       
        if(pSectorBuff)
        {
            
#ifdef READ_FROM_REGISTRY                
            // Check for unaligned pointer.  Only need to do this if the FMD is being used as 
            // a block driver (and therefore READ_FROM_REGISTRY is set)
            if ((DWORD)pSectorBuff & (dwBusWidth - 1))
            {
                RETAILMSG(ZONE_TEST, (TEXT("FMD_WriteSector: Unaligned pointer - using internal buffer\r\n")));
                memcpy(cTempBuffer, pSectorBuff, SECTOR_SIZE);
                pBuffer = cTempBuffer;
            }
            else
#endif
            {
                pBuffer = pSectorBuff;
            }


            // from Intel: if the sector is not aligned modulo write buffer size - 
            // performance can be enhanced my doing a partial write to align the buffer 
            // for the rest of the writes to complete the sector.  If you are doing 
            // partial writes to align the buffer address, and a single word 
            // (or DWORD of x32) is being written, it is faster to use the flash's WORD  
            // write command instead of the buffered write.
			k = DoBufferedWrite(ulBlockAddress, physicalSectorAddr , pBuffer, SECTOR_SIZE);
			if (!k)
				goto exit;

			nResult=1;

			pSectorBuff += SECTOR_SIZE;
        }

        //----- Write the necessary sector info data (metadata) -----
        //      NOTE: Notice that the 6 metadata bytes are just stored after the sector data...
        if((!g_bXIPMode && pSectorInfoBuff)&&(nResult))
        {
          	RETAILMSG(ZONE_TEST, (TEXT("FMD_WriteSector: write info\r\n")));
			
            if (!DoBufferedWrite(ulBlockAddress, physicalSectorAddr+SECTOR_SIZE, (PUCHAR)pSectorInfoBuff, sizeof(SectorInfo)))
                goto exit;

            pSectorInfoBuff += sizeof(SectorInfo);
        }
    }

    fRet = TRUE;

exit:
    //----- 3. Put the Flash back into READ ARRAY mode -----

    SetKMode(bLastMode);

	RETAILMSG(ZONE_TEST, (TEXT("FMD_WriteSector: over %x \r\n"),fRet ));

    return fRet;
}


DWORD DoBufferedWrite(volatile ULONG ulBlockAddress,
                      volatile SECTOR_ADDR physicalSectorAddr,
                      PUCHAR pBuffer,
                      USHORT NumWriteBytes)
{
    DWORD k = 0;
    ULONG ulCount,ulCount1=0;
    DWORD dwBusWidth = g_bPairedFlash ? sizeof(ULONG) : sizeof(USHORT);
    DWORD dwWordCount = (NumWriteBytes / dwBusWidth);
    PULONG pLongBuffer = (PULONG)pBuffer;
    PUSHORT pShortBuffer = (PUSHORT)pBuffer;

    int iResult = FLASH_ERR_OK;


	volatile USHORT *   pusDest16;
	volatile ULONG  *   pusDest32;

	DWORD m_offset=0;

//RETAILMSG(1, (TEXT("WRITE: ).\r\n")));
    if (g_bPairedFlash)
    {
		pusDest32= (volatile ULONG *)g_FMDInfo.ChipBaseAddress;

		WRITE_COMMAND(pusDest32+ AMD_SETUP_ADDR1,AMD_SETUP_CODE1);
		WRITE_COMMAND(pusDest32+ AMD_SETUP_ADDR2,AMD_SETUP_CODE2);
		WRITE_COMMAND(pusDest32+ AMD_SETUP_ADDR1,0x0020);
	}
	else
	{
		pusDest16= (volatile USHORT*)g_FMDInfo.ChipBaseAddress;

		WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR1,AMD_SETUP_CODE1);
		WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR2,AMD_SETUP_CODE2);
		WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR1,0x0020);
	}
	m_offset=physicalSectorAddr-g_FMDInfo.ChipBaseAddress;

	for(k = 0 ; k < dwWordCount ; k ++)
	{
		if (g_bPairedFlash)
		{
            pusDest32= (volatile ULONG *)g_FMDInfo.ChipBaseAddress;
	
			WRITE_COMMAND(pusDest32+ 0x00000,0x00a0);
	
			*(pusDest32+(m_offset>>2)+k)=*(pLongBuffer+k) ;	
			  
			DelayInuSec(100);
			ulCount = 0;

			while ( *(pusDest32+(m_offset>>2)+k) != *(pLongBuffer+k)   )
	        {
		    	DelayInuSec(1);
				
		    	if ( ulCount++== 1000)
		    	{
		        	RETAILMSG(ZONE_TEST, (TEXT("DoWordWrite: %x  %x\r\n"),*(pusDest32+(m_offset>>2)+k),*(pLongBuffer+k) ));
					iResult = FLASH_ERR_DRV_TIMEOUT;		
		        	//return 0;
		        	break;
		    	}
			}
		}
		else
		{
			pusDest16= (PUSHORT)g_FMDInfo.ChipBaseAddress;
		     
			WRITE_COMMAND(pusDest16+ 0x00000,0x00a0);
			  
			*(pusDest16+(m_offset>>1)+k)=*(pShortBuffer+k) ;	
				
			DelayInuSec(1);
	    	ulCount = 0;
			
			while ( *(pusDest16+(m_offset>>1)+k) != *(pShortBuffer+k)   )
	        {
		    	DelayInuSec(1);
				
		    	if ( ulCount++== 1000 )
		    	{
		        	RETAILMSG(ZONE_TEST, (TEXT("DoWordWrite: Timed out writing buffered data 1\r\n")));
					iResult = FLASH_ERR_DRV_TIMEOUT;		
		        	break;
		    	}
			}
		}
	    DelayInuSec(1);
	    ulCount = 0;
	}

    if (g_bPairedFlash)
	{
		pusDest32= (volatile ULONG *)g_FMDInfo.ChipBaseAddress;
		WRITE_COMMAND(pusDest32+ AMD_SETUP_ADDR1,0x0090);
		WRITE_COMMAND(pusDest32+ AMD_SETUP_ADDR2,0x0000);
     }

	else
	{
		pusDest16= (volatile USHORT *)g_FMDInfo.ChipBaseAddress;
		WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR1,0x0090);
		WRITE_COMMAND(pusDest16+ AMD_SETUP_ADDR2,0x0000);
	}
//RETAILMSG(1, (TEXT("--WRITE: ).\r\n")));
    return NumWriteBytes;
}


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       FMD_EraseBlock()

Description:    Erases the specified Flash block.

Returns:        Boolean indicating success.
------------------------------------------------------------------------------*/
BOOL  FMD_EraseBlock(BLOCK_ID blockID)
{
    volatile ULONG ulBlockAddress = 0;
    ULONG ulStatus = 0;
    BOOL bLastMode = SetKMode(TRUE);
	unsigned int  j;
	ULONG ulCount=0;

	volatile USHORT  *  pusDest16;
	volatile ULONG   *  pusDest32;
	DWORD m_offset=0;

	RETAILMSG(ZONE_TEST, (TEXT("FMD_EraseBlock: id =%x ).\r\n"), blockID));
    // Determine the address for the specified block.
	ulBlockAddress  =  g_FMDInfo.BaseAddress + (blockID * g_FMDInfo.BlockSize);

	pusDest16= (PUSHORT)ulBlockAddress;
	pusDest32= (PULONG)ulBlockAddress;

	if(GetEraseFlashSectorIndex(ulBlockAddress-g_FMDInfo.ChipBaseAddress)==FALSE)
	{
		RETAILMSG(ZONE_TEST, (TEXT("ERASE Block error,not aligned\r\n")));
		return FALSE;
	}
	if(g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size==g_FMDInfo.BlockSize)
	{
 		if (g_bPairedFlash)
 		{
			m_offset=ulBlockAddress-g_FMDInfo.ChipBaseAddress;
			// Issue erase and confirm command.
			// Note: eventually this should be changed to issue mass block erases, then loop to
			// verify each completes.
			pusDest32= (volatile ULONG *)g_FMDInfo.ChipBaseAddress;

			WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR1, AMD_SETUP_CODE1);
			WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR2, AMD_SETUP_CODE2);
			WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR1, AMD_SETUP_ERASE);
			WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR1, AMD_SETUP_CODE1);
			WRITE_COMMAND(pusDest32+AMD_SETUP_ADDR2, AMD_SETUP_CODE2);

			*(pusDest32+(m_offset>>2))= (AMD_BLOCK_ERASE<<16)|AMD_BLOCK_ERASE;

			ulCount = 0;

			while ((*(pusDest32+(m_offset>>2)) &AMD_SECTOR_ERASE_TIMER)!=AMD_SECTOR_ERASE_TIMER)
			{
				DelayInuSec(1);
				if ( ulCount++ == 10000 )
				//Sleep(1);
				//if ( ulCount++ == 10 )
				{
					RETAILMSG(ZONE_TEST, (TEXT("erase: Timed out writing buffered data 1\r\n")));
					return 0;
				}
			}
 		}
		else
		{
//			m_offset=ulBlockAddress-g_FMDInfo.ChipBaseAddress;

			pusDest16=(volatile USHORT *)g_FMDInfo.ChipBaseAddress;
			// Issue erase and confirm command.
			// Note: eventually this should be changed to issue mass block erases, then loop to
			// verify each completes.
			*(pusDest16+ AMD_SETUP_ADDR1)= AMD_SETUP_CODE1;	
			*(pusDest16+ AMD_SETUP_ADDR2)= AMD_SETUP_CODE2;	
			*(pusDest16+ AMD_SETUP_ADDR1)= AMD_SETUP_ERASE;		
			*(pusDest16+ AMD_SETUP_ADDR1)= AMD_SETUP_CODE1;	
			*(pusDest16+ AMD_SETUP_ADDR2)=AMD_SETUP_CODE2;	

//			*(pusDest16+(m_offset>>1))= AMD_BLOCK_ERASE;

			Sleep(5);
//			DelayInuSec(5000);
			
			pusDest16=(PUSHORT)ulBlockAddress;
			*pusDest16 = AMD_BLOCK_ERASE;

			Sleep(10);
//			DelayInuSec(10000);

			ulCount = 0;

			while (!CHECK_STATUS(ulBlockAddress, AMD_SECTOR_ERASE_TIMER))
			{
				//DelayInuSec(1);
				//if ( ulCount++ == 10000 )
				Sleep(1);
				if ( ulCount++ == 10 )
	    		{
	        		RETAILMSG(1, (TEXT("erase: Timed out writing buffered data 1\r\n")));
	        		return 0;
	    		}
			}
		}
		DelayInuSec(100);
	} //g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].block_size==g_FMDInfo.BlockSize
	else
	{
   		for(j = g_FMDInfo.gdwCurEraseBlock; 
			j< g_FlashRegion[g_FMDInfo.gdwCurEraseRegion].blocks; j++)
		{
		 	if (g_bPairedFlash)
		 	{

⌨️ 快捷键说明

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