167 lines
4.3 KiB
C
167 lines
4.3 KiB
C
|
|
//-------------------------------------------------------------------------
|
|
//-------------------------------------------------------------------------
|
|
|
|
//The raspberry pi wants you to not have your kernel.img file loaded
|
|
//at address 0x0000. Using a bootloader like this it works just fine
|
|
//but to avoid having example binaries that are at 0x8000 for running
|
|
//from the sd card and a binary at 0x0000 for loading with the
|
|
//bootloader, instead the bootloader is going to default to 0x8000
|
|
//as well.
|
|
#define ARMBASE 0x8000
|
|
|
|
extern void PUT32 ( unsigned int, unsigned int );
|
|
extern void PUT16 ( unsigned int, unsigned int );
|
|
extern void PUT8 ( unsigned int, unsigned int );
|
|
extern unsigned int GET32 ( unsigned int );
|
|
extern unsigned int GETPC ( void );
|
|
extern void BRANCHTO ( unsigned int );
|
|
extern void dummy ( unsigned int );
|
|
|
|
extern void uart_init ( void );
|
|
extern unsigned int uart_lcr ( void );
|
|
extern void uart_send ( unsigned int );
|
|
extern unsigned int uart_recv ( void );
|
|
extern void hexstring ( unsigned int );
|
|
extern void hexstrings ( unsigned int );
|
|
extern void timer_init ( void );
|
|
extern unsigned int timer_tick ( void );
|
|
|
|
extern void timer_init ( void );
|
|
extern unsigned int timer_tick ( void );
|
|
|
|
//------------------------------------------------------------------------
|
|
unsigned char xstring[256];
|
|
//------------------------------------------------------------------------
|
|
int notmain ( void )
|
|
{
|
|
unsigned int ra;
|
|
//unsigned int rb;
|
|
unsigned int rx;
|
|
unsigned int addr;
|
|
unsigned int block;
|
|
unsigned int state;
|
|
|
|
unsigned int crc;
|
|
|
|
uart_init();
|
|
hexstring(0x12345678);
|
|
hexstring(GETPC());
|
|
timer_init();
|
|
|
|
//SOH 0x01
|
|
//ACK 0x06
|
|
//NAK 0x15
|
|
//EOT 0x04
|
|
|
|
//block numbers start with 1
|
|
|
|
//132 byte packet
|
|
//starts with SOH
|
|
//block number byte
|
|
//255-block number
|
|
//128 bytes of data
|
|
//checksum byte (whole packet)
|
|
//a single EOT instead of SOH when done, send an ACK on it too
|
|
|
|
block=1;
|
|
addr=ARMBASE;
|
|
state=0;
|
|
crc=0;
|
|
rx=timer_tick();
|
|
while(1)
|
|
{
|
|
ra=timer_tick();
|
|
if((ra-rx)>=4000000)
|
|
{
|
|
uart_send(0x15);
|
|
rx+=4000000;
|
|
}
|
|
if((uart_lcr()&0x01)==0) continue;
|
|
xstring[state]=uart_recv();
|
|
rx=timer_tick();
|
|
if(state==0)
|
|
{
|
|
if(xstring[state]==0x04)
|
|
{
|
|
uart_send(0x06);
|
|
BRANCHTO(ARMBASE);
|
|
break;
|
|
}
|
|
}
|
|
switch(state)
|
|
{
|
|
case 0:
|
|
{
|
|
if(xstring[state]==0x01)
|
|
{
|
|
crc=xstring[state];
|
|
state++;
|
|
}
|
|
else
|
|
{
|
|
//state=0;
|
|
uart_send(0x15);
|
|
}
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
if(xstring[state]==block)
|
|
{
|
|
crc+=xstring[state];
|
|
state++;
|
|
}
|
|
else
|
|
{
|
|
state=0;
|
|
uart_send(0x15);
|
|
}
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
if(xstring[state]==(0xFF-xstring[state-1]))
|
|
{
|
|
crc+=xstring[state];
|
|
state++;
|
|
}
|
|
else
|
|
{
|
|
uart_send(0x15);
|
|
state=0;
|
|
}
|
|
break;
|
|
}
|
|
case 131:
|
|
{
|
|
crc&=0xFF;
|
|
if(xstring[state]==crc)
|
|
{
|
|
for(ra=0;ra<128;ra++)
|
|
{
|
|
PUT8(addr++,xstring[ra+3]);
|
|
}
|
|
uart_send(0x06);
|
|
block=(block+1)&0xFF;
|
|
}
|
|
else
|
|
{
|
|
uart_send(0x15);
|
|
}
|
|
state=0;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
crc+=xstring[state];
|
|
state++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
//-------------------------------------------------------------------------
|
|
//-------------------------------------------------------------------------
|