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

📄 loader.c

📁 本source code 為s3c4510的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 			*//* 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 + -