📄 flashwriternor.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// Copyright 1999, 2000, 2001, 2002, 2003, 2004 by Texas Instruments Incorporated. All rights
// reserved. Property of Texas Instruments Incorporated. Restricted rights to use,
// duplicate or disclose this code are granted through contract.
//
///////////////////////////////////////////////////////////////////////////////
//
// This file contains the stand-alone code for copying an Image from Memory to
// Flash.
//
// Last Revision date: 2-2-04
// Release 1.8
//
//Headers
//
#include "types.h"
#include "Flash_params.h"
#include "OMAP.h"
//
//Globals
//
//Parameters downloaded in .vars section
//(this sits at fixed memory locations!)
#pragma DATA_SECTION ( image, ".image" )
ULONG image;
#pragma DATA_SECTION ( global_vars, ".vars" )
Download_Parms global_vars;
Download_Parms *gp_vars = &global_vars;
//
//Build Parameters
#define USES_CCS
void printinfo(ULONG size, ULONG srcAddr, ULONG destAddr)
{
printf("FlashWriter Version 1.8\n");
printf("Starting Download to NOR Flash\n");
printf("Image is %d bytes long\n", size);
printf("Reading Image from: %08X\n", srcAddr);
printf("Writing Image to: %08X\n", destAddr);
}
void printNORflashtype(enum NORFlashType flash_id)
{
switch (flash_id)
{
case FLASH_NOT_FOUND:
printf("Flash not Found or unsupported!\n");
break;
case FLASH_AMD_DL323_4MB_BOTTOM: // chip size is 4MB (AM29DL323CB: 2MBx16bit)
printf("Flash AMD DL323 4MB Bottom\n");
break;
case FLASH_FUJITSU_DL323_4MB_BOTTOM:// chip size is 4MB (MBM29DL323BD: 2MBx16bit)
printf("Flash Fujitsu DL323 4MB Bottom\n");
break;
case FLASH_AMD_LV160_2MB_BOTTOM:
printf("Flash AMD LV160 2MB Bottom\n");
break;
case FLASH_AMD_LV256M_32MB:
printf("Flash AMD LV256M 32MB\n");
break;
case FLASH_INTEL_BURST_16MB_BOTTOM: // 4 2MB devices=8MB total
printf("Flash Intel Burst 8MB Bottom\n");
break;
case FLASH_INTEL_STRATA_J3_4MB: // 2 4MB devices=8MB
printf("Flash Intel J3 Strata 8 MB\n");
break;
case FLASH_INTEL_STRATA_J3_8MB: // 2 8MB devices=16MB
printf("Flash Intel J3 Strata 16MB\n");
break;
case FLASH_INTEL_STRATA_J3_16MB: // 2 16MB devices=32MB
printf("Flash Intel J3 Strata 32 MB\n");
break;
case FLASH_INTEL_STRATA_K3_16MB: // 16MB devices=32MB
printf("Flash Intel K3 Strata 32 MB\n");
break;
case FLASH_INTEL_W18_16MB_BOTTOM:
printf("Flash Intel W18 16MB Bottom\n");
break;
case FLASH_INTEL_W18_16MB_TOP:
printf("Flash Intel W18 16MB Muxed Top\n");
break;
case FLASH_INTEL_L18_16MB_BOTTOM:
printf("Flash Intel L18 16MB Bottom\n");
break;
case FLASH_INTEL_L18_16MB_TOP:
printf("Flash Intel L18 16MB Muxed Top\n");
break;
case FLASH_INTEL_L18_32MB_BOTTOM:
printf("Flash Intel L18 32MB Bottom\n");
break;
case FLASH_INTEL_L18_32MB_TOP:
printf("Flash Intel L18 32MB Muxed Top\n");
break;
case FLASH_INTEL_K18_32MB_BOTTOM:
printf("Flash Intel K18 32 MB Stacked device\n");
break;
case FLASH_MICRON_16MB_TOP:
printf("Flash Micron 16MB Top\n");
break;
case FLASH_SAMSUNG_16MB_TOP:
printf("Flash SAMSUNG 16MB Top\n");
break;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// IdentifyNORFlash
//
// Description:
// Reads the Flash Manufacturer ID and device codes to differentiate
// the flash device for the Flash Device at address 0x0C000000.
//
// Return:
// FLASH_NOT_FOUND
// FLASH_UNSUPPORTED
// FLASH_device
//
///////////////////////////////////////////////////////////////////////////////
enum NORFlashType IdentifyNORFlash(ULONG addr)
{
enum NORFlashType flash_id;
Hwd manf;
Hwd code;
Hwd code1; // First Mult-Address Code //
Hwd code2; // Second Mult-Address Code //
volatile USHORT *fladdr = (volatile USHORT *) addr;
// Initialize Function Pointers.
User_Flash_Erase_Block = (void (*)(ULONG))Flash_Do_Nothing;
User_Flash_Erase_All = (void (*)(ULONG))Flash_Do_Nothing;
User_Flash_Write = (int (*)(ULONG *, USHORT))Flash_Do_Nothing;
User_Flash_Optimized_Write = (int (*)(ULONG *, USHORT[], ULONG))Flash_Do_Nothing;
// First try the AMD device
*(fladdr + AMD_CMD0_ADDR) = AMD_ID_CMD0;
*(fladdr + AMD_CMD1_ADDR) = AMD_ID_CMD1;
*(fladdr + AMD_CMD2_ADDR) = AMD_ID_CMD2;
manf = *fladdr;
if (manf == AMD_MANF_ID)
{
// Check device ID
code = *(fladdr + AMD_DEVICE_ID_OFFSET); // device code at address 1
switch (code)
{
case AMD1_DEVICE_ID: // More Codes need to go here
flash_id = FLASH_AMD_DL323_4MB_BOTTOM;
User_Flash_Erase_Block = AMD_Flash_Erase_Block;
User_Flash_Erase_All = AMD_Flash_Erase_All;
User_Flash_Write_Entry = Flash_Do_Nothing;
User_Flash_Write = AMD_Flash_Write;
User_Flash_Write_Exit = Flash_Do_Nothing;
break;
case AMD2_DEVICE_ID: // More Codes need to go here
flash_id = FLASH_AMD_LV160_2MB_BOTTOM;
User_Flash_Erase_Block = AMD_Flash_Erase_Block;
User_Flash_Erase_All = AMD_Flash_Erase_All;
User_Flash_Write_Entry = Flash_Do_Nothing;
User_Flash_Write = AMD_Flash_Write;
User_Flash_Write_Exit = Flash_Do_Nothing;
break;
case AMD_DEVICE_ID_MULTI: //For Multi-Address ID Devices
{
code1 = *(fladdr + AMD_DEVICE_ID_OFFSET1);
code2 = *(fladdr + AMD_DEVICE_ID_OFFSET2);
//first multi-address device check
if ((code1 == AMD3_DEVICE_ID1) && (code2 == AMD3_DEVICE_ID2))
{
flash_id = FLASH_AMD_LV256M_32MB;
User_Hard_Reset_Flash = Flash_Do_Nothing;
User_Soft_Reset_Flash = AMD_Soft_Reset_Flash;
User_Flash_Erase_Block = AMD_Flash_Erase_Block;
User_Flash_Erase_All = AMD_Flash_Erase_All;
User_Flash_Write_Entry = Flash_Do_Nothing;
User_Flash_Write = AMD_Flash_Write;
User_Flash_Write_Exit = Flash_Do_Nothing;
User_Flash_Optimized_Write = AMD_Flash_Optimized_Write;
break;
}
//Add additional multi-address device checks here.
//NOTE: intentional drop through to "default case".
}
default:
flash_id = FLASH_NOT_FOUND;
}
// Put back into Read ArrayMode
AMD_Soft_Reset_Flash((ULONG) fladdr);
}
else if (manf == FUJITSU_MANF_ID)
{
// Check device ID
code = *(fladdr + AMD_DEVICE_ID_OFFSET); // device code at address 1
switch (code)
{
case FUJITSU1_DEVICE_ID:
flash_id = FLASH_FUJITSU_DL323_4MB_BOTTOM;
User_Flash_Erase_Block = AMD_Flash_Erase_Block;
User_Flash_Erase_All = AMD_Flash_Erase_All;
User_Flash_Write_Entry = Flash_Do_Nothing;
User_Flash_Write = AMD_Flash_Write;
User_Flash_Write_Exit = Flash_Do_Nothing;
break;
default:
flash_id = FLASH_NOT_FOUND;
}
// Put back into Read ArrayMode
AMD_Soft_Reset_Flash((ULONG) fladdr);
} else if (manf == SAMSUNG_MANF_ID)
{
//Try SAMSUNG (which programs like an AMD device)
// Check device ID
code = *(fladdr + AMD_DEVICE_ID_OFFSET); // device code at address 1
switch (code)
{
case SAMSUNG_K8S2815E_128T:
flash_id = FLASH_SAMSUNG_16MB_TOP;
User_Flash_Erase_Block = AMD_Flash_Erase_Block;
User_Flash_Erase_All = AMD_Flash_Erase_All;
User_Flash_Write_Entry = Flash_Do_Nothing;
User_Flash_Write = AMD_Flash_Write;
User_Flash_Write_Exit = Flash_Do_Nothing;
break;
default:
flash_id = FLASH_NOT_FOUND;
}
// Put back into Read ArrayMode
AMD_Soft_Reset_Flash((ULONG) fladdr);
} else
{
//Try INTEL
// Okay Now Let's Try Intel
INTEL_Soft_Reset_Flash((ULONG) fladdr);
*fladdr = INTEL_ID_CMD; // Send the Get ID command
manf = *fladdr; // Check Manufacturer ID
code = *(++fladdr); // Check device ID
INTEL_Soft_Reset_Flash((ULONG) fladdr);
if (manf == INTEL_MANF_ID || manf == MICRON_MANF_ID)
{
switch (code)
{
case INTEL_DEVICE_16B:
flash_id = FLASH_INTEL_BURST_16MB_BOTTOM;
break;
case INTELS_J3_DEVICE_32:
flash_id = FLASH_INTEL_STRATA_J3_4MB;
break;
case INTELS_J3_DEVICE_64:
flash_id = FLASH_INTEL_STRATA_J3_8MB;
break;
case INTELS_J3_DEVICE_128:
flash_id = FLASH_INTEL_STRATA_J3_16MB;
break;
case INTELS_K3_DEVICE_64:
flash_id = FLASH_INTEL_STRATA_K3_8MB;
break;
case INTELS_K3_DEVICE_128:
flash_id = FLASH_INTEL_STRATA_K3_16MB;
break;
case INTELS_K3_DEVICE_256:
flash_id = FLASH_INTEL_STRATA_K3_32MB;
break;
case INTELS_W18_DEVICE_128B:
flash_id = FLASH_INTEL_W18_16MB_BOTTOM;
break;
case INTELS_W18_DEVICE_128T:
flash_id = FLASH_INTEL_W18_16MB_TOP;
break;
case INTELS_L18_DEVICE_128B:
flash_id = FLASH_INTEL_L18_16MB_BOTTOM;
break;
case INTELS_L18_DEVICE_128T:
flash_id = FLASH_INTEL_L18_16MB_TOP;
break;
case INTELS_L18_DEVICE_256B:
flash_id = FLASH_INTEL_L18_32MB_BOTTOM;
break;
case INTELS_L18_DEVICE_256T:
flash_id = FLASH_INTEL_L18_32MB_TOP;
break;
case INTELS_K18_DEVICE_256B:
flash_id = FLASH_INTEL_K18_32MB_BOTTOM;
break;
case MICRON_MT28F_DEVICE_128T:
flash_id = FLASH_MICRON_16MB_TOP;
break;
default:
flash_id = FLASH_NOT_FOUND;
return(flash_id);
}
User_Flash_Erase_Block = INTEL_Flash_Erase_Block;
//Flash_Erase_All = INTEL_Flash_Erase_All;
User_Flash_Write = INTEL_Flash_Write;
//Note W18 doesn't appear to support block writes!!!
if ((flash_id != FLASH_INTEL_W18_16MB_TOP) &&
(flash_id != FLASH_INTEL_W18_16MB_BOTTOM) &&
(flash_id != FLASH_MICRON_16MB_TOP))
{
User_Flash_Optimized_Write = INTEL_Flash_Optimized_Write;
}
} else //Did not find any
{
return(FLASH_NOT_FOUND);
}
}
return(flash_id);
}
///////////////////////////////////////////////////////////////////////////////
//
// Erase Flash Block
//
// Description:
// This routine checks erases flash blocks, if they haven't already been
// erased, based on a start address, byte count, and flash type. All counts
//
// Return:
// status - SUCCESS
///////////////////////////////////////////////////////////////////////////////
int EraseNORFlash(ULONG start_address, ULONG size, enum NORFlashType flash_id)
{
ULONG addr = start_address; //byte address
ULONG range = start_address + size; //end address
ULONG block_size;
ULONG addr_without_cs;
printf("Erasing the Flash\n");
while (addr < range)
{
addr_without_cs = (addr & 0x01FFFFFF); // address offset within a CS <32MB
switch (flash_id)
{
case FLASH_NOT_FOUND: // return ERROR
return(0);
case FLASH_AMD_DL323_4MB_BOTTOM: // chip size is 4MB (AM29DL323CB: 2MBx16bit)
case FLASH_FUJITSU_DL323_4MB_BOTTOM:// chip size is 4MB (MBM29DL323BD: 2MBx16bit)
if (addr_without_cs >= 0x00400000) // return ERROR
{
return(0);
}
if (addr_without_cs < 0x10000)
{
block_size = 0x2000; // 8KB
// Round down to the next block
addr &= 0xFFFFE000;
}
else
{
block_size = 0x10000; // 64 KB
// Must round down address range to 0x8000
addr &= 0xFFFF0000;
}
break;
case FLASH_SAMSUNG_16MB_TOP:// chip size is 16MB
if (addr_without_cs >= 0x01000000) // return ERROR
{
return(0);
}
if (addr_without_cs >= 0xFF0000)
{
block_size = 0x2000; // 8KB
// Round down to the next block
addr &= 0xFFFFE000;
}
else
{
block_size = 0x10000; // 64 KB
// Must round down address range to 0x8000
addr &= 0xFFFF0000;
}
break;
case FLASH_AMD_LV160_2MB_BOTTOM:
if (addr_without_cs >= 0x00200000) // return ERROR
{
return(0);
}
if (addr_without_cs < 0x4000)
{
block_size = 0x4000; // 16KB
// Round down to the next block
addr &= 0xFFFFC000;
}
else if (addr_without_cs < 0x8000)
{
block_size = 0x2000; // 8KB
// Must round down address range to 0x4000
addr &= 0xFFFFE000;
}
else if (addr_without_cs < 0x10000)
{
block_size = 0x8000; // 32 KB
// Must round down address range to 0x8000
addr &= 0xFFFF8000;
}
else // This case entered only if(addr_without_cs >= 0x10000)
{
block_size = 0x10000; // 64 KB
// Must round down address range to 0x8000
addr &= 0xFFFF0000;
}
break;
case FLASH_AMD_LV256M_32MB:
if (addr_without_cs >= 0x02000000) // return ERROR
{
return(0);
}
block_size = 0x10000; // uniform sector size (64 KB)
// Clear intra-sector byte addresses
// (round down to first byte address in sector)
addr &= 0xFFFF0000;
break;
case FLASH_INTEL_BURST_16MB_BOTTOM: // 4 2MB devices=8MB total
if (addr_without_cs >= 0x800000) // return ERROR
{
return(0);
}
if (addr_without_cs < 0x10000)
{
block_size = 0x2000;
// round down to next block
addr &= 0xFFFFE000;
}
else if (addr_without_cs < 0x200000)
{
block_size = 0x10000;
// round down to next block
addr &= 0xFFFF0000;
}
else if (addr_without_cs < 0x210000)
{
block_size = 0x2000;
// round down to next block
addr &= 0xFFFFE000;
}
else if (addr_without_cs < 0x400000)
{
block_size = 0x10000;
// round down to next block
addr &= 0xFFFF0000;
}
else if (addr_without_cs < 0x410000)
{
block_size = 0x2000;
// round down to next block
addr &= 0xFFFFE000;
}
else if (addr_without_cs < 0x600000)
{
block_size = 0x10000;
// round down to next block
addr &= 0xFFFF0000;
}
else if (addr_without_cs < 0x610000)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -