// 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}; static UINT8 uart_read(void) { UINT8 byte; while (!(SSR1 & SCI_RDRF)); // wait for char to be available byte = RDR1; SSR1 &= ~SCI_RDRF; return byte; } static 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; }