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

📄 nor.c

📁 davinci的NANDFLASH烧写程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	// Write Data
	flash_write_databuffer(pNorInfo, &address,(void*)data, numBytes);
		
    // Program Buffer to Flash Confirm Write
    flash_write_cmd(pNorInfo, blkAddress, 0, AMD_WRT_BUF_CONF_CMD);                  
    
    // Read last data item                  
    data_temp = flash_read_data(pNorInfo, (Uint32) (data + (address - startAddress)), 0);
        
	while(TRUE)
	{
		//temp1 = flash_read_data(address, 0 );   
		if( (flash_read_data(pNorInfo, address, 0 ) & (BIT7 | BIT15)) == (data_temp & (BIT7 | BIT15) ) )
		{
			break;
		}
		else
		{
		    // Timeout has occurred
			if(flash_issetall(pNorInfo,address, 0, BIT5))
			{
				if( (flash_read_data(pNorInfo,address, 0 ) & (BIT7 | BIT15)) != (data_temp & (BIT7 | BIT15) ) )
				{
				    printf("Timeout ocurred.\r\n",FALSE);
					retval = E_FAIL;
				}
				break;
			}
			// Abort has occurred
			if(flash_issetall(pNorInfo, address, 0, BIT1))
			{
				if( (flash_read_data(pNorInfo, address, 0 ) & (BIT7 | BIT15)) != (data_temp & (BIT7 | BIT15) ) )
				{
				    printf("Abort ocurred.\r\n",FALSE);
					retval = E_FAIL;
					AMD_Write_Buf_Abort_Reset_Flash (pNorInfo);
				}
				break;
			}
		}
	}
	
	// Put chip back into read array mode.
	AMD_Soft_Reset_Flash(pNorInfo);
	if (retval == E_PASS)
	    retval = flash_verify_databuffer(pNorInfo, startAddress,(void*)data, numBytes);
	return retval;
}

// AMD Write Buf Abort Reset Flash
void AMD_Write_Buf_Abort_Reset_Flash(PNOR_INFO pNorInfo)
{
	// Reset Flash to be in Read Array Mode
    AMD_Prefix_Commands(pNorInfo);
    AMD_Soft_Reset_Flash(pNorInfo);
}

// ---------------------------------------------------------------------------
//--------------------- End of AMD specific commands ------------------------
// ---------------------------------------------------------------------------

// Get info on block address and sizes
Uint32 NOR_GetBlockInfo(PNOR_INFO pNorInfo, Uint32 address, Uint32* blockSize, Uint32* blockAddr)
{
    Int32 i;
    Uint32 currRegionAddr, nextRegionAddr;
        
    currRegionAddr = (Uint32) pNorInfo->flashBase;
    if ((address < currRegionAddr) || (address >= (currRegionAddr+pNorInfo->flashSize)))
    {
        return E_FAIL;
    }
    
    for(i=0; i< (pNorInfo->numberRegions); i++)
    {
        nextRegionAddr = currRegionAddr + (pNorInfo->blockSize[i] * pNorInfo->numberBlocks[i]);
        if ( (currRegionAddr <= address) && (nextRegionAddr > address) )
        {
            *blockSize = pNorInfo->blockSize[i];
            *blockAddr = address & (~((*blockSize) - 1));
            break;
        }
        currRegionAddr = nextRegionAddr;
    }
    return E_PASS;
}

// --------------------------- NOR API Functions -----------------------------

//Initialize the AEMIF subsystem and settings
PNOR_INFO NOR_Open(Uint32 baseCSAddr)
{
    VUint32 *ABCR;
    PNOR_INFO pNorInfo;
    Uint8 width;

    // Alloc the main NOR structue
    pNorInfo = (PNOR_INFO) ubl_alloc_mem(sizeof(NOR_INFO));

    // Set NOR flash base address
    pNorInfo->flashBase = baseCSAddr;
    
    //Get the CSOffset (can be 0 through 3 - corresponds with CS2 through CS5)
    pNorInfo->CSOffset = ( ( pNorInfo->flashBase & (0x0FFFFFFF)) >> 25) - 1;

    // Set width to 8 or 16
    width = ( ( (SYSTEM->BOOTCFG) >> 5) & 0x1 );
    pNorInfo->busWidth = (width)?BUS_16BIT:BUS_8BIT;

    // Select ASYNC EMIF Address Lines
    SYSTEM->PINMUX[0] = 0xC1F;

    // Program Asynchronous Wait Cycles Configuration Control Register
    AEMIF->AWCCR |= 0x0 ;

    // Program Asynchronous Bank3-5 Register
    ABCR = &(AEMIF->AB1CR);
    ABCR[pNorInfo->CSOffset] = 0x3FFFFFFC | width;      // Adjust for quicker access times   
    
    // Perform CFI Query
    if (QueryCFI(pNorInfo) == E_PASS)
    {
        // Below is specifically needed to check for AMD flash on DVEVM (rev. D or earlier)
        // since it's top address line is not connected (don't ask me why)
        if (pNorInfo->numberRegions == 1)
        {
            pNorInfo->flashBase += (pNorInfo->flashSize>>1);
            if ( QueryCFI(pNorInfo) == E_PASS )     
	        {
	            pNorInfo->flashSize >>= 1;
                pNorInfo->flashBase -= pNorInfo->flashSize;
	            pNorInfo->numberBlocks[0] >>= 1;
	        }
            else
            {
                pNorInfo->flashBase -= (pNorInfo->flashSize>>1);
            }
        }
    }
    else
    {
        printf("CFI query failed.\r\n", FALSE);
        return NULL;
    }
    
    // Setup function pointers
    printf("NOR Initialization:\r\n", FALSE);
    
    printf("\tCommand Set: ", FALSE);    
    switch (pNorInfo->commandSet)
    {
        case AMD_BASIC_CMDSET:
        case AMD_EXT_CMDSET:
            Flash_Erase          = &AMD_Erase;
            Flash_BufferWrite    = &AMD_BufferWrite;
            Flash_Write          = &AMD_Write;
            Flash_ID             = &AMD_ID;
            printf("AMD\r\n", FALSE);
            break;
        case INTEL_BASIC_CMDSET:
        case INTEL_EXT_CMDSET:
            Flash_Erase          = &Intel_Erase;
            Flash_BufferWrite    = &Intel_BufferWrite;
            Flash_Write          = &Intel_Write;
            Flash_ID             = &Intel_ID;
            printf("Intel\r\n", FALSE);
            break;
        default:
            Flash_Write          = &Unsupported_Write;
            Flash_BufferWrite    = &Unsupported_BufferWrite;
            Flash_Erase          = &Unsupported_Erase;
            Flash_ID             = &Unsupported_ID;
            printf("Unknown\r\n", FALSE);
            break;
    }
    
    if ( (*Flash_ID)(pNorInfo) != E_PASS)
    {
        printf("NOR ID failed.\r\n", FALSE);
        return NULL;
    }
        
    printf("\tManufacturer: ", FALSE);
    switch(pNorInfo->manfID)
    {
        case AMD:
            printf("AMD", FALSE);
            break;
        case FUJITSU:
            printf("FUJITSU", FALSE);
            break;
        case INTEL:
            printf("INTEL", FALSE);
            break;
        case MICRON:
            printf("MICRON", FALSE);
            break;
        case SAMSUNG:
            printf("SAMSUNG", FALSE);
            break;
        case SHARP:
            printf("SHARP", FALSE);
            break;
        default:
            printf("Unknown", FALSE);
            break;
    }
    printf("\r\n", FALSE);
    printf("\tSize: %d MB\r\n", pNorInfo->flashSize>>20);
    
    return pNorInfo;    
}

//Global Erase NOR Flash
Uint32 NOR_GlobalErase(PNOR_INFO pNorInfo)
{
    return NOR_Erase( pNorInfo, (VUint32) pNorInfo->flashBase, (VUint32) pNorInfo->flashSize );
}

// Erase Flash Block
Uint32 NOR_Erase(PNOR_INFO pNorInfo, VUint32 start_address, VUint32 size)
{
	VUint32 addr  = start_address;
	VUint32 range = start_address + size;
	Uint32 blockSize, blockAddr;
	
	printf("Erasing the NOR Flash\r\n", FALSE);
	
   	while (addr < range)
  	{
	    if (NOR_GetBlockInfo(pNorInfo, addr, &blockSize, &blockAddr) != E_PASS)
	    {
	        printf("Address out of range", FALSE);
	        return E_FAIL;
	    }
		
		//Increment to the next block
	    if ( (*Flash_Erase)(pNorInfo, blockAddr) != E_PASS)
	    {
	        printf("Erase failure at block address 0x%x\r\n",blockAddr);
	        return E_FAIL;
	    }
	    addr = blockAddr + blockSize;
	    
	    // Show status messages
	    printf("Erased through 0x%x\r\n", addr);
  	}

	printf("Erase Completed\r\n", FALSE);

  	return(E_PASS);
}

// NOR_WriteBytes
Uint32 NOR_WriteBytes( PNOR_INFO pNorInfo,
                       Uint32 writeAddress,
					   Uint32 numBytes,
					   Uint32 readAddress)
{
	Uint32      blockSize, blockAddr;
	Int32		i;
	Uint32      retval = E_PASS;

	printf("Writing the NOR Flash\r\n", FALSE);

	// Make numBytes even if needed
	if (numBytes & 0x00000001)
		numBytes++;
		
    if (NOR_GetBlockInfo(pNorInfo, writeAddress, &blockSize, &blockAddr) != E_PASS)
    {
        printf("Address out of range", FALSE);
        return E_FAIL;
    }

	while (numBytes > 0)
  	{
        if( (numBytes < pNorInfo->bufferSize) || (writeAddress & (pNorInfo->bufferSize-1) ))
		{
			if ((*Flash_Write)(pNorInfo, writeAddress, flash_read_data(pNorInfo,readAddress,0) ) != E_PASS)
			{
			    printf("\r\nNormal Write Failed.\r\n", FALSE);
			    retval = E_FAIL;
			}
			else
			{
			    numBytes     -= pNorInfo->busWidth;
			    writeAddress += pNorInfo->busWidth;
			    readAddress  += pNorInfo->busWidth;
			}
		}
		else
		{
		    // Try to use buffered writes
			if((*Flash_BufferWrite)(pNorInfo, writeAddress, (VUint8 *)readAddress, pNorInfo->bufferSize) == E_PASS)
			{
				numBytes -= pNorInfo->bufferSize;
				writeAddress += pNorInfo->bufferSize;
			    readAddress  += pNorInfo->bufferSize;
			}
			else
			{
			    // Try normal writes as a backup
			    for(i = 0; i<(pNorInfo->bufferSize>>1); i++)
				{
                    if ((*Flash_Write)(pNorInfo, writeAddress, flash_read_data(pNorInfo,readAddress,0) ) != E_PASS)
					{
						printf("\r\nNormal write also failed\r\n", FALSE);
						retval = E_FAIL;
						break;
					}
			    	else
			        {
			            numBytes     -= pNorInfo->busWidth;
			            writeAddress += pNorInfo->busWidth;
			            readAddress  += pNorInfo->busWidth;
			        }
				}
			}
		}

        // Output status info on the write operation
        if (retval == E_PASS)
        {    
	        if  ( ((writeAddress & (~((blockSize>>4)-1))) == writeAddress) || (numBytes == 0) )
	        {
	            printf("NOR Write OK through 0x%x\r\n", writeAddress);
        		
	            if (NOR_GetBlockInfo(pNorInfo, writeAddress, &blockSize, &blockAddr) != E_PASS)
                {
                    printf("Address out of range", FALSE);
                    return E_FAIL;
                }
	        }
	    }
	    else
	    {
		    printf( "NOR Write Failed...Aborting!\r\n", FALSE);
		    return E_FAIL;
		}
  	}
  	return retval;
}

⌨️ 快捷键说明

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