- #include <stdint.h>
- uint32_t volatile * const rccApb2 = (uint32_t *) 0x40021018u;
- uint32_t volatile * const ioAModerH = (uint32_t *) 0x40010804u;
- uint32_t volatile * const uart1Ctrl = (uint32_t *) 0x40013800u;
-
- void readChar( uint8_t const chr );
- void writeByte( uint8_t b );
- void writeStr( uint8_t const * const str );
- void writeChar( uint8_t const chr );
- void writeWordLe( uint32_t const word );
- void writeWordBe( uint32_t const word );
- void readCmd( uint8_t const * const cmd);
- uint32_t hexToInt(uint8_t const * const hex);
- void readMem(uint32_t const addr, uint32_t const len);
- void writeMem(uint32_t const addr, uint32_t const data);
-
- uint8_t const strHelp[] = "Help\r\n-----------\r\n"
- "ADDR, VAL, LEN: 32-bit Hex encoded:\r\n e.g., 0A1337FF\r\n"
- "-----------\r\n"
- "R ADDR LEN - Read 32-bit word\r\n"
- "W ADDR VAL - Write 32-bit word\r\n"
- "D - Dump all flash memory\r\n"
- "P - Jump into chall4 function\r\n"
- "S - Reboot\r\n"
- "E - Exit\r\n"
- "H - Show help \r\n"
- "---------------\r\n";
-
- int main(void)
- {
- /* IOA + USART1 clock enable */
- *rccApb2 = (uint32_t) 0x4004u;
-
- /* USART1 TX+RX (PA9, PX10) on */
- *ioAModerH = (uint32_t) 0x444444B4u;
-
- /* config and enable uart */
- uart1Ctrl[2] = 0x00000341u;
- uart1Ctrl[3] = 0x0000200Cu;
-
- writeStr("\r\n##############################\r\n"
- "# Low-Level Shell v.0xRoM #\r\n"
- "# CPU-ID: 0x");
- uint32_t cpuid = *((uint32_t *) 0xe000ed00);
- writeWordBe(cpuid);
- writeStr( " #\r\n");
- writeStr("##############################\r\n\r\n");
- writeStr("> ");
-
- while (1)
- {
- if ((uart1Ctrl[0] & 0x80u) && (0))
- {
- uart1Ctrl[1] = 0x33u;
- }
-
- if (uart1Ctrl[0] & 0x20u)
- {
- uint32_t data = uart1Ctrl[1];
- readChar((uint8_t) data);
- }
- }
- }
-
- /* hex must have length 8 */
- uint32_t hexToInt(uint8_t const * const hex)
- {
- uint32_t ind = 0u;
- uint32_t res = 0u;
-
- for (ind = 0; ind < 8; ++ind)
- {
- uint8_t chr = hex[ind];
- uint32_t val = 0u;
-
- res <<= 4u;
-
- if ((chr >= '0') && (chr <= '9'))
- {
- val = chr - '0';
- }
- else if ((chr >= 'a') && (chr <= 'f'))
- {
- val = chr - 'a' + 0x0a;
- }
- else if ((chr >= 'A') && (chr <= 'F'))
- {
- val = chr - 'A' + 0x0a;
- }
- else
- {
- val = 0u;
- }
- res |= val;
- }
-
- return res;
- }
-
- void readChar( uint8_t const chr )
- {
- #define CMDBUF_LEN (64u)
- static uint8_t cmdbuf[CMDBUF_LEN] = {0u};
- static uint32_t cmdInd = 0u;
-
- switch (chr)
- {
- case '\n':
- case '\r':
- cmdbuf[cmdInd] = 0u;
- if (cmdInd != 0)
- {
- writeStr("\r\n");
- }
- readCmd(cmdbuf);
- cmdInd = 0u;
- writeStr("\r\n> ");
- {
- uint32_t ind = 0u;
- for (ind = 0; ind<CMDBUF_LEN; ++ind)
- {
- cmdbuf[ind]=0x00u;
- }
- }
- break;
-
- case 8:
- case 255:
- case 127: /* TODO backspace */
- if (cmdInd > 0u)
- --cmdInd;
- writeChar(chr);
- break;
-
- default:
- if (cmdInd < (CMDBUF_LEN - 1))
- {
- cmdbuf[cmdInd] = chr;
- ++cmdInd;
- writeChar(chr);
- }
- break;
- }
- }
-
- void readCmd( uint8_t const * const cmd )
- {
- void (*chall4)(void) = (void (*)(void))0x08000ba9;
- switch (cmd[0])
- {
- case 0:
- return;
- break;
-
- /* chall4 function */
- case 'p':
- case 'P':
- writeStr("time to change baudrate to 115200\r\n");
- for (volatile uint32_t i = 0; i < 5000000; i++); // Crude delay
- chall4();
- break;
-
- /* read 32-bit command */
- case 'r':
- case 'R':
- /* r 08000000 00000100 */
- readMem(hexToInt(&cmd[2]), hexToInt(&cmd[11]));
- break;
-
- /* write 32-bit command */
- case 'w':
- case 'W':
- /* w 20000000 12345678 */
- writeMem(hexToInt(&cmd[2]), hexToInt(&cmd[11]));
- break;
-
- /* Dump all flash */
- case 'd':
- case 'D':
- writeStr("\r\n\r\n");
- {
- uint32_t const * addr = (uint32_t*) 0x08000000;
- uint32_t br = 8u;
- while (((uintptr_t) addr) < (0x08000000 + 64u * 1024u))
- {
- if (br == 8u)
- {
- writeStr("\r\n[");
- writeWordBe((uint32_t) addr);
- writeStr("]: ");
- br = 0u;
- }
-
- writeWordBe(*addr);
- writeChar(' ');
- ++addr;
- ++br;
- }
- }
- writeStr("\r\n\r\n");
- break;
-
- /* Help command */
- case 'h':
- case 'H':
- writeStr(strHelp);
- break;
-
- /* Reboot */
- case 's':
- case 'S':
- writeStr("Rebooting...\r\n\r\n");
- *((uint32_t *) 0xE000ED0C) = 0x05FA0004u;
- break;
-
- /* exit */
- case 'e':
- case 'E':
- writeStr("Bye.\r\n");
- while (1)
- {
- __asm__ volatile("wfi");
- }
- break;
-
-
- default:
- writeStr("Unknown command: ");
- writeStr(cmd);
- writeStr("\r\n");
- break;
- }
- }
-
- const uint8_t txtMap[] = "0123456789ABCDEF";
-
- void writeByte( uint8_t b )
- {
- writeChar(txtMap[b >> 4]);
- writeChar(txtMap[b & 0x0F]);
- }
-
-
- void writeStr( uint8_t const * const str )
- {
- uint32_t ind = 0u;
-
- while (str[ind])
- {
- writeChar(str[ind]);
- ++ind;
- }
- }
-
- void writeChar( uint8_t const chr )
- {
- while (!(uart1Ctrl[0] & 0x80u))
- {
- /* wait */
- }
-
- uart1Ctrl[1] = chr;
- }
-
- void writeWordLe( uint32_t const word )
- {
- writeByte((word & 0x000000FF));
- writeByte((word & 0x0000FF00) >> 8);
- writeByte((word & 0x00FF0000) >> 16);
- writeByte((word & 0xFF000000) >> 24);
- }
-
- void writeWordBe( uint32_t const word )
- {
- writeByte((word & 0xFF000000) >> 24);
- writeByte((word & 0x00FF0000) >> 16);
- writeByte((word & 0x0000FF00) >> 8);
- writeByte((word & 0x000000FF));
-
- }
-
- void alertCrash( uint32_t crashId )
- {
- writeStr("!!! EXCEPTION !!!\r\nID: ");
- writeByte(crashId);
- writeStr("\r\nRestart required!\r\n\r\n");
- *((uint32_t *) 0xE000ED0C) = 0x05FA0004u;
- while (1);
- }
-
- void readMem(uint32_t const addr, uint32_t const len)
- {
- uint32_t it = 0u;
- uint32_t addrx = 0u;
- uint32_t lenx = 0u;
-
- lenx = len;
- if (lenx == 0u)
- {
- lenx = 4u;
- }
-
- for (it = 0u; it < (lenx / 4u); ++it)
- {
- addrx = addr + it*4u;
- writeStr("Read [");
- writeWordBe(addrx);
- writeStr("]: ");
- writeWordBe(*((uint32_t*)addrx));
- writeStr("\r\n");
- }
- }
-
- void writeMem(uint32_t const addr, uint32_t const data)
- {
- writeStr("Write [");
- writeWordBe(addr);
- writeStr("]: ");
- writeWordBe(data);
- *((uint32_t*) addr) = data;
- writeStr("\r\n");
- }
-