📄 loader.c
字号:
/* *//* Dmitriy Cherkashin *//* dch@ucrouter.ru *//* 2002,2003 *//* */#include "ks32c50.h"#include "evm50100.h"// uncomment V1_0 to use loader v1.0 (without support s3c4530A) //#define V1_0// constant to calculate CRC ////////////////////////////////////////////////////#define CCITT_POLYNOM 0x1021 // x^16+x12^+x^5+x^0// constant to programm flash /////////////////////////////////////////////////// #define ROM2_ADDR 0x0400000 // (2 Mb)#define ROM1_ADDR 0x0200000 // (2 Mb)#define ROM0_ADDR 0x0000000 // (256K)// constant to test SDRAM ///////////////////////////////////////////////////////#define DRAM_BASE 0x1000000 // DRAM base pointer#define DRAM_NEXT 0x2000000 // DRAM next pointer#define CMD_ERASE ((U16)(('C' << 8)|('E'))) // Flash Erase #define CMD_SECTOR_ERASE ((U16)(('S' << 8)|('E'))) // Flash Erase //#define CMD_WRITE ((U16)(('W' << 8)|('R'))) // FLash Write//#define CMD_WRCRC ((U16)(('W' << 8)|('C'))) // FLash Write with CRC reply#define CMD_WRBLOCK ((U16)(('W' << 8)|('B'))) // FLash Write, 128 bytes, offset, CRC reply#define CMD_READ ((U16)(('R' << 8)|('D'))) // Flash Read #define CMD_MANUF ((U16)(('M' << 8)|('C'))) // Read Manufactory Code #define CMD_DEV_ID ((U16)(('I' << 8)|('D'))) // Read Device ID #define CMD_REG_READ ((U16)(('R' << 8)|('R'))) // read registers command#define CMD_DRAM_TEST ((U16)(('D' << 8)|('T'))) // DRAM test command#define CMD_DRAM_BYTE_TEST ((U16)(('D' << 8)|('B'))) // DRAM test command#define CMD_DRAM_HALF_TEST ((U16)(('D' << 8)|('H'))) // DRAM test command#define CMD_DRAM_WORD_TEST ((U16)(('D' << 8)|('W'))) // DRAM test command// set speed #define CMD_SET_SPEED ((U16)(('S' << 8)|('P'))) //// DRAM_TEST_ROTATE = rotate writed value, to increment writed value comment// followed macro#define DRAM_TEST_ROTATE//#define DRAM_TEST_FAST//#define DRAM_CHECK_0X40 //U8 wblock[8+128]; // buffer for write block commandU8 wblock[8+512]; // buffer for write block command#ifdef V1_0 // KS32C50100 support only #elsevolatile unsigned int * uartstat0;unsigned int uartstat_txb_empty;unsigned int uartstat_rcv_ready;#endifvoid put_ch(char ch){#ifdef V1_0 // KS32C50100 support only while(( UARTSTAT0 & UARTSTAT_TXB_EMPTY)==0); #else while((*uartstat0 & uartstat_txb_empty)==0); #endifUARTTXH0 = ch;}int get_ch(void){#ifdef V1_0 // KS32C50100 support only while(( UARTSTAT0 & UARTSTAT_RCV_READY)==0); // wait rx#else while((*uartstat0 & uartstat_rcv_ready)==0); // wait rx#endif return( (UARTRXB0 & 0xFF) ) ; // read byte}/////////////////////////////////////////////////////////////////////////////////// put string to UART0 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void put_string(char * str){ while(*str != 0) {#ifdef V1_0 // KS32C50100 support only while(( UARTSTAT0 & UARTSTAT_TXB_EMPTY)==0);#else while((*uartstat0 & uartstat_txb_empty)==0);#endif UARTTXH0 = *str++; }}/////////////////////////////////////////////////////////////////////////////////// put hexadecimal value to UART0 (upper half byte first) ////////////////////////////////////////////////////////////////////////////////////////////////////////void put_value(U32 val, U8 * buf){ int bit; // bit number U8 ch; // character // for(bit = 28; bit >= 0; bit -= 4) { ch = ((val >> bit) & 0xF); // read half byte if(ch <= 9) { ch += '0'; } else { ch += 'a' - 10; }#ifdef V1_0 // KS32C50100 support only while(( UARTSTAT0&UARTSTAT_TXB_EMPTY)==0); // wait UART0 tx ready#else while((*uartstat0&uartstat_txb_empty)==0); // wait UART0 tx ready#endif UARTTXH0 = ch; // put ASCII character to UART0 if(buf != NULL) { // output buffer not NULL pointer => copy ASCII character to output buffer ////// *buf++ = ch; } }}/////////////////////////////////////////////////////////////////////////////////// get hexadecimal value from UART0 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int get_val(U32 * val){ int pos; U8 ch; if(val == 0) { return(0); } *val = 0; // clear readed value for(pos = 0; pos < 8; ++pos) { *val <<= 4; ch = get_ch(); if(ch >= '0' && ch <= '9') { ch -= '0'; } else if(ch >= 'a' && ch <= 'f') { ch = (ch - 'a') + 10; } else if(ch >= 'A' && ch <= 'F') { ch = (ch - 'A') + 10; } else {// read hexadecimal value error ///////////////////////////////////////////////// return(0); } // write read half byte to destination buffer /////////////////////////////////// *val |= ch; }// return(1);} /////////////////////////////////////////////////////////////////////////////////// output to UART0 register name and value ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// str = register name// val = register valuevoid put_reg(char * str, U32 val){ put_string(str); // put register name put_value(val, 0); // put register value, no output buffer}/////////////////////////////////////////////////////////////////////////////////// calculate CRC /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////U32 calc_crc(U32 crc, U8 ch){ int bit; for(bit = 0; bit < 8; ++bit) { crc <<= 1; if(ch & 0x0080) { crc ^= CCITT_POLYNOM; } ch <<= 1; } return(crc); }void put_dram(U32 pos,U32 crc,U32 ch){ int i; put_string("\nError offset "); put_value (pos,0); put_string("expected "); put_value (crc,0); put_string("value "); if(ch == 4) { crc = *((U32 *)(pos)); } else if(ch == 2) { crc = (U16)(*((U16 *)(pos))); } else if(ch == 1) { crc = (U8 )(*((U8 *)(pos))); } put_value(crc,0); put_string("byte "); crc = 0; for(i = ch - 1; i >= 0; --i) { crc <<= 8; crc |= (U8)(*((U8*)(pos+i))); } put_value(crc,0);}/////////////////////////////////////////////////////////////////////////////////// C Program Entry Point /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void C_Entry(void){ U16 cmd = 0; // received command U32 led; // LED counter (loop count) U32 length; // data length & write offset for block write U32 crc; // calculated CRC U32 pos; // position U8 ch; // character #ifdef V1_0 // KS32C50100 only // UART0 Line Control Register ////////////////////////////////////////////////// UARTLCON0 = // UART0 Line Control register UARTLCON_WL8 | // Word Length 8 bit UARTLCON_PMD_NO; // No parity// UART0 Control register /////////////////////////////////////////////////////// UARTCONT0 = // UART0 Control Register UARTCON_RXM_INTREQ | // rx mode = interrupt request UARTCON_TXM_INTREQ; // tx mode = interrupt request#else // KS32C50100 & s3c4510A if((SYSCFG & 0x0C000000) == 0x0C000000) {// lo bits of PID = 11 => s3C4530 uartstat0 = (volatile unsigned int *)(Base_Addr+0xd004); uartstat_txb_empty = USTAT_THE; // tx holding register is empty uartstat_rcv_ready = USTAT_RDV; // receive data valid bit UCON0 = UCON_TMODE_INTREQ | UCON_RMODE_INTREQ | UCON_WL8; } else { uartstat0 = (volatile unsigned int *)(Base_Addr+0xd008); uartstat_txb_empty = UARTSTAT_TXB_EMPTY; uartstat_rcv_ready = UARTSTAT_RCV_READY;// UART0 Line Control Register ////////////////////////////////////////////////// UARTLCON0 = UARTLCON_WL8 | UARTLCON_PMD_NO; // UART0 Control register /////////////////////////////////////////////////////// UARTCONT0 = UARTCON_RXM_INTREQ | UARTCON_TXM_INTREQ; } #endif// UART0 BaudRate Register ////////////////////////////////////////////////////// UARTBRD0 = // 0x00a20; // 9600 // cnt0 = 162 cnt1 = 0, 0// 0x00500; // 19200 // cnt0 = 80 cnt1 = 0, 1 0x00280; // 38400 // cnt0 = 40 cnt1 = 0, 2// 0x001a0; // 57600 // cnt0 = 26 cnt1 = 0, 3// 0x000d0; // 115200 // cnt0 = 13 cnt1 = 0, 4// 0x00060; // 230400 // cnt0 = 6 cnt1 = 0, 5// 0x00020; // 460800 // cnt0 = 2 cnt1 = 0, 6 not available led = 0; // start LED counter while(1) { led++; // calculate loop count if(led == 0x08000) {// write 1 to P16 /////////////////////////////////////////////////////////////// IOPDATA = 0x10000; // write 1 to P16 put_ch('r'); // output to UART0 rr (receive ready) } else if(led >= 0x10000) {// write 0 to P16 /////////////////////////////////////////////////////////////// IOPDATA = 0x00000; // write 0 to P16 led = 0; // reset counter put_ch('r'); // output to UART0 rr (receive ready) }// continue;#ifdef V1_0 // KS32C50100 support only if(( UARTSTAT0 & UARTSTAT_RCV_READY))#else if((*uartstat0 & uartstat_rcv_ready))#endif {// receive next command byte //////////////////////////////////////////////////// cmd = (cmd << 8) | (UARTRXB0 & 0xFF); }#ifdef CMD_MANUF//////////////////////////////////////////////////////////////////////////////////// read manufactory code command /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(cmd == CMD_MANUF) { put_string("MC"); // output command reply// read flash manufactory code /////////////////////////////////////////////////// *((volatile U8 *)(ROM2_ADDR + 0x555))=0xAA;// 1 autoselect write cicle *((volatile U8 *)(ROM2_ADDR + 0x2AA))=0x55;// 2 autoselect write cicle *((volatile U8 *)(ROM2_ADDR + 0x555))=0x90;// 3 autoselect write cicle cmd = *((volatile U8 *)(ROM2_ADDR+0x00)); // 0x00 = read manufacture code *((volatile U8 *)(ROM2_ADDR + 0x555))=0xF0;// write read reset command // put_value(cmd, 0); // output manufactory code (no output buffer)// cmd = 0; // clear command code continue; // to next loop }#endif // CMD_MANUF#ifdef CMD_DEV_ID//////////////////////////////////////////////////////////////////////////////////// read device ID command ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(cmd == CMD_DEV_ID) { put_string("ID"); // put read device ID command reply// read and output to UART 0 device ID ///////////////////////////////////////// *((volatile U8 *)(ROM2_ADDR + 0x555))=0xAA; // 1 autoselect write command *((volatile U8 *)(ROM2_ADDR + 0x2AA))=0x55; // 2 autoselect write command *((volatile U8 *)(ROM2_ADDR + 0x555))=0x90; // 3 autoselect write command cmd = *((volatile U8 *)(ROM2_ADDR+0x01)); // read (0x01) device code *((volatile U8 *)(ROM2_ADDR + 0x555))=0xF0; // write read reset command // put_value(cmd, 0); // put device ID // cmd = 0; // clear command code continue; // to next loop } #endif // CMD_DEV_ID#ifdef CMD_REG_READ/////////////////////////////////////////////////////////////////////////////////// read registers command //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(cmd == CMD_REG_READ) { put_string("RR"); // output read registers command reply// put_reg("SYSCFG ",SYSCFG ); // System Configuration put_reg("EXTDBWTH ",EXTDBWTH ); // External Bus Width put_reg("ROMCON0 ",ROMCON0 ); // ROM Bank 0 Control Register put_reg("ROMCON1 ",ROMCON1 ); // ROM Bank 1 Control Register put_reg("ROMCON2 ",ROMCON2 ); // ROM Bank 2 Control Register put_reg("ROMCON3 ",ROMCON3 ); // ROM Bank 3 Control Register put_reg("ROMCON4 ",ROMCON4 ); // ROM Bank 4 Control Register put_reg("ROMCON5 ",ROMCON5 ); // ROM Bank 5 Control Register put_reg("DRAMCON0 ",DRAMCON0 ); // DRAM Bank 0 Control Register put_reg("DRAMCON1 ",DRAMCON1 ); // DRAM Bank 1 Control Register put_reg("DRAMCON2 ",DRAMCON2 ); // DRAM Bank 2 Control Register put_reg("DRAMCON3 ",DRAMCON3 ); // DRAM Bank 3 Control Register put_reg("REFEXTCON",REFEXTCON); // Refresh Control Register cmd = 0; // clear command code continue; // to receive next command }#endif // CMD_REG_READ#ifdef CMD_DRAM_TEST/////////////////////////////////////////////////////////////////////////////////// DRAM test ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if( cmd == CMD_DRAM_TEST || cmd == CMD_DRAM_BYTE_TEST || cmd == CMD_DRAM_HALF_TEST || cmd == CMD_DRAM_WORD_TEST ) {/////////////////////////////////////////////////////////////////////////////////// 32 bit test /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// for(ch = 1; ch <= 4; ++ch) {// ch = 1 => byte write/read test // ch = 2 => half word write/read test // ch = 4 => word write/read test if(ch == 3) { continue; } if(ch == 1) { // byte read/write test ///////////////////////////////////////////////////////// if( cmd != CMD_DRAM_TEST && cmd != CMD_DRAM_BYTE_TEST ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -