601afcbd0b
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18930 a1c6a512-1295-4272-9138-f99709370657
156 lines
3.4 KiB
C
156 lines
3.4 KiB
C
// minimalistic monitor
|
|
// to be loaded with the UART boot feature
|
|
// capable of reading and writing bytes, commanded by UART
|
|
|
|
#include "sh7034.h"
|
|
#include "minimon.h"
|
|
|
|
// scalar types
|
|
typedef unsigned char UINT8;
|
|
typedef unsigned short UINT16;
|
|
typedef unsigned long UINT32;
|
|
|
|
typedef void(*tpFunc)(void); // type for exec
|
|
typedef int(*tpMain)(void); // type for start vector to main()
|
|
|
|
|
|
// prototypes
|
|
int main(void);
|
|
|
|
// our binary has to start with a vector to the entry point
|
|
tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main};
|
|
|
|
|
|
UINT8 uart_read(void)
|
|
{
|
|
UINT8 byte;
|
|
while (!(SSR1 & SCI_RDRF)); // wait for char to be available
|
|
byte = RDR1;
|
|
SSR1 &= ~SCI_RDRF;
|
|
return byte;
|
|
}
|
|
|
|
|
|
void uart_write(UINT8 byte)
|
|
{
|
|
while (!(SSR1 & SCI_TDRE)); // wait for transmit buffer empty
|
|
TDR1 = byte;
|
|
SSR1 &= ~SCI_TDRE;
|
|
}
|
|
|
|
|
|
int main(void)
|
|
{
|
|
UINT8 cmd;
|
|
UINT32 addr;
|
|
UINT32 size;
|
|
UINT32 content;
|
|
volatile UINT8* paddr = 0;
|
|
volatile UINT8* pflash = 0; // flash base address
|
|
|
|
while (1)
|
|
{
|
|
cmd = uart_read();
|
|
switch (cmd)
|
|
{
|
|
case BAUDRATE:
|
|
content = uart_read();
|
|
uart_write(cmd); // acknowledge by returning the command value
|
|
while (!(SSR1 & SCI_TEND)); // wait for empty shift register, before changing baudrate
|
|
BRR1 = content;
|
|
break;
|
|
|
|
case ADDRESS:
|
|
addr = (uart_read() << 24) | (uart_read() << 16) | (uart_read() << 8) | uart_read();
|
|
paddr = (UINT8*)addr;
|
|
pflash = (UINT8*)(addr & 0xFFF80000); // round down to 512k align
|
|
uart_write(cmd); // acknowledge by returning the command value
|
|
break;
|
|
|
|
case BYTE_READ:
|
|
content = *paddr++;
|
|
uart_write(content); // the content is the ack
|
|
break;
|
|
|
|
case BYTE_WRITE:
|
|
content = uart_read();
|
|
*paddr++ = content;
|
|
uart_write(cmd); // acknowledge by returning the command value
|
|
break;
|
|
|
|
case BYTE_READ16:
|
|
size = 16;
|
|
while (size--)
|
|
{
|
|
content = *paddr++;
|
|
uart_write(content); // the content is the ack
|
|
}
|
|
break;
|
|
|
|
case BYTE_WRITE16:
|
|
size = 16;
|
|
while (size--)
|
|
{
|
|
content = uart_read();
|
|
*paddr++ = content;
|
|
}
|
|
uart_write(cmd); // acknowledge by returning the command value
|
|
break;
|
|
|
|
case BYTE_FLASH:
|
|
content = uart_read();
|
|
pflash[0x5555] = 0xAA; // set flash to command mode
|
|
pflash[0x2AAA] = 0x55;
|
|
pflash[0x5555] = 0xA0; // byte program command
|
|
*paddr++ = content;
|
|
uart_write(cmd); // acknowledge by returning the command value
|
|
break;
|
|
|
|
case BYTE_FLASH16:
|
|
size = 16;
|
|
while (size--)
|
|
{
|
|
content = uart_read();
|
|
pflash[0x5555] = 0xAA; // set flash to command mode
|
|
pflash[0x2AAA] = 0x55;
|
|
pflash[0x5555] = 0xA0; // byte program command
|
|
*paddr++ = content;
|
|
}
|
|
uart_write(cmd); // acknowledge by returning the command value
|
|
break;
|
|
|
|
case HALFWORD_READ:
|
|
content = *(UINT16*)paddr;
|
|
paddr += 2;
|
|
uart_write(content >> 8); // highbyte
|
|
uart_write(content & 0xFF); // lowbyte
|
|
break;
|
|
|
|
case HALFWORD_WRITE:
|
|
content = uart_read() << 8 | uart_read();
|
|
*(UINT16*)paddr = content;
|
|
paddr += 2;
|
|
uart_write(cmd); // acknowledge by returning the command value
|
|
break;
|
|
|
|
case EXECUTE:
|
|
{
|
|
tpFunc pFunc = (tpFunc)paddr;
|
|
pFunc();
|
|
uart_write(cmd); // acknowledge by returning the command value
|
|
}
|
|
break;
|
|
|
|
|
|
default:
|
|
{
|
|
volatile UINT16* pPortB = (UINT16*)0x05FFFFC2;
|
|
*pPortB |= 1 << 6; // bit 6 is red LED on
|
|
uart_write(~cmd); // error acknowledge
|
|
}
|
|
|
|
} // case
|
|
}
|
|
|
|
return 0;
|
|
}
|