#define FLASH_STATUS_WRITE_SUSPENDED 0x04
#define FLASH_STATUS_ERROR 0x3E
#define FLASH_STATUS_ERASE_ERROR 0x3A
#define FLASH_STATUS_PROGRAMING_ERROR 0x1A
#define FLASH_START_ADDRESS 0x70000000
#define FLASH_CHECK_EMPTY_END_ADDRESS 0x70100000
#define FLASH_ERASE_8K_BLOCKS 8
#define FLASH_ERASE_64K_BLOCKS 31
#define DRAM_BLOCK_SIZE 0x40000 /* 256KB */
#define SYSCON1_VALUE 0x00840100 /* EXCKEN, BZMOD=TOG,UART1EN */
#define SYSCON2_VALUE 0x00000006 /* 16bit DRAM, KBD6 */
#define MEMCFIG1_VALUE 0x03010100 /* CS3: 8bitC, CS2,1: 32bit, CS0:16bit */
#define DRAM_FRESH_RATE 0x83
/*#define UART1_CONFIG 0x74005 */ /* 38400 8N1 Enable FIFO */
/*#define UART1_CONFIG 0x60003 */ /* 57600 8N1 Enable FIFO */
#define UART1_CONFIG 0x74001 /* 115200 8N1 Enable FIFO */
#define SYSCON2_VALUE_BEEP_ON 0x00004006 /* BuzzerFreq, 16bit DRAM,KBD6 */
#define SYSCON2_VALUE_BEEP_OFF 0x00000006 /* 16bit DRAM, KBD6 */
#define HbDdrAData 0x00 /* all inputs */
#define HbDdrBData 0x14 /* bit 2,4 output */
#define HbDdrDData 0x00 /* all output (direction def reversed) */
#define HbDdrEData 0x0F /* all output */
#define HbDrBData 0x00 /* HbDrBData & HbDrDData disable printer heating*/
#define HbDrDData 0x00
#define HbDrEData 0x02 /* UCHARge battery, disable step motor */
#define UART1_TX_FIFO_FULL (1<<23)
#define UART1_TX_BUSY (1<<11)
#define UART1_RX_FIFO_EMPTY (1<<22)
#define BUZZER_TOGGLE (1<<9)
#define UCHAR unsigned char
#define DWORD unsigned int
/* Function prototypes */
/*
void SetCp15(DWORD dwCp15Val);
DWORD ReadCp15();
*/
void PrintMsg(UCHAR * pszMsg);
void RecvData(void);
DWORD RecvDword(void);
void SendChar(register UCHAR ch);
UCHAR ReceiveChar(void);
void PrintDword(DWORD dwValue);
void ToAscii(UCHAR ch, UCHAR * pcAscii);
void Beep(void);
UCHAR* FlashBlockErase(UCHAR * pucBlockAddr, DWORD dwBlocks, DWORD
dwBlockSize);
void FlashChipErase(void);
void FlashCheckEmpty(void);
void FlashWrite(void);
void FlashChipUnlock(void);
void FlashErrorHandler(UCHAR * pszMsg, UCHAR * pcAddr2Dump);
/* Globle Variable */
const DWORD g_dwDramBase[] = {0xc0080000, 0xc0200000, 0xc0280000,
0xc0800000, 0xc0880000, 0xc0a00000, 0xc0a80000}; /*DRAM_BLOCK_SIZE each*/
const DWORD g_dwSaveAddr; /* Will changed by RecvData() */
const DWORD g_dwSaveCount; /* Will changed by RecvData() */
const DWORD g_dwCheckSum;
const UCHAR g_AsciiTable[] = "0123456789abcdef";
const UCHAR g_szByteMsg[] = "0xXX ";
const UCHAR g_szWordMsg[] = "0xXXXXYYYY\n";
const UCHAR g_szBootLdrStart[] = "+++START LOADER\r\n";
const UCHAR g_szReceiving[] = "Receiving data ...\r\n";
const UCHAR g_szReceived[] = "Receiving finished!\n";
const UCHAR g_szIds[] = "Device code/Manufacturer code: ";
const UCHAR g_szUnlockingFlash[] = "Unlocking Flash ...\n";
const UCHAR g_szErasingFlash[] = "Erasing flash ...\n";
const UCHAR g_szProgrammingFlash[] = "Programming Flash ...\n";
const UCHAR g_szDone[] = "Data has been programmed into flash\n";
const UCHAR g_szBootLdrEnd[] = "+++BOOTLOADER END\n";
const UCHAR g_szEraseFlashError[] = "Error erasing flash\n";
const UCHAR g_szFlashNotEmpty[] = "Error flash not empty\n";
const UCHAR g_szProgramFlashError[] = "Error programming flash\n";
const UCHAR g_szDramError[] = "DRAM Error!\n";
/* Implementation */
asm ("
.text
.global _start
_start:
bl _my_start /* Omit the entry code for function c_start() */
");
void c_start(void)
{
register DWORD* pdwFlashStartAddr;
register DWORD* pdwFlashEndAddr;
register DWORD* pdwDramStartAddr;
register DWORD dwHardwareBase;
asm ("_my_start:
mov r14, #0x70
mcr p15, 0, r14, c1, c0, 0 /* MMU disabled, 32 Bit mode, Little endian */
mrs r14, cpsr
bic r14, r14, #0x1f /* Mask */
orr r14, r14, #0xc0 + 0x13 /* Diasble IRQ and FIQ, SVC32 Mode */
msr cpsr, r14
ldr r13, =0xc0020000 /* Setup Stack */
");
dwHardwareBase = (DWORD)HW1base;
*((DWORD*)(dwHardwareBase + HW1_INTMR1)) = 0; /* disable Interrupt */
*((DWORD*)(dwHardwareBase + (0x1000+HW2_INTMR2))) = 0; /* disable Interrupt */
*((DWORD*)(dwHardwareBase + HW1_SYSCON1)) = SYSCON1_VALUE;
*((DWORD*)(dwHardwareBase + (0x1000+HW2_SYSCON2))) =SYSCON2_VALUE;
*((DWORD*)(dwHardwareBase + HW1_MEMCFG1)) = MEMCFIG1_VALUE;
*((DWORD*)(dwHardwareBase + HW1_DRFPR)) = DRAM_FRESH_RATE;
/* **** We can call functions from here! **** */
PrintMsg((UCHAR*)&g_szReceiving);
PrintMsg((UCHAR*)&g_szBootLdrStart);
Beep();
*((DWORD*)(dwHardwareBase + HW1_UBRLCR1)) = UART1_CONFIG; /*115200 8n1 */
/*
make sure that before reinitializing UART there is enough
time to send out last message
So far Beep gives enough time
*/
pdwFlashStartAddr = (DWORD *)FLASH_START_ADDRESS;
RecvData(); /* receive data */
PrintMsg((UCHAR*)&g_szReceived);
PrintMsg((UCHAR*)&g_szIds); /* display Flash Id message */
*((UCHAR *)pdwFlashStartAddr) = FLASH_COMMAND_READ_ID; /* read ID */
PrintDword(*pdwFlashStartAddr);
PrintMsg((UCHAR*)&g_szUnlockingFlash);
FlashChipUnlock();
PrintMsg((UCHAR*)&g_szErasingFlash);
FlashChipErase();
FlashCheckEmpty();
PrintMsg((UCHAR*)&g_szProgrammingFlash);
FlashWrite();
PrintMsg((UCHAR*)&g_szDone);
PrintMsg((UCHAR*)&g_szBootLdrEnd);
Beep();
while(1);
}
void PrintMsg(UCHAR * pszMsg)
{
UCHAR ch;
for (;;)
{
ch = *pszMsg++;
if (ch) SendChar(ch);
else break;
}
}
void PrintDword(DWORD dwValue)
{
register DWORD dw;
for ( dw = 0; dw < 4; dw++)
{
ToAscii((dwValue>>(dw*8)), (UCHAR*)&g_szWordMsg + 8 - 2*dw);
}
PrintMsg((UCHAR*)&g_szWordMsg);
}
void ToAscii(UCHAR ch, UCHAR * pcAscii)
{
pcAscii[0] = g_AsciiTable[(ch>>4) & 0x0F];
pcAscii[1] = g_AsciiTable[ch & 0x0F];
}
/**************************************************************/
void RecvData()
{
register DWORD dwBlockCounter, dwInBlockCounter;
register DWORD dwCharCounter;
register UCHAR * pucBuf;
register DWORD dwCheckSum;
1 2 3 4 5 6