3 /* According to POSIX.1-2001 */
4 #include <sys/select.h>
12 #include "stlink-common.h"
14 #define STLINKY_MAGIC 0xDEADF00D
23 /* Detects stlinky in RAM, returns handler */
24 struct stlinky* stlinky_detect(stlink_t* sl)
26 static const uint32_t sram_base = 0x20000000;
27 struct stlinky* st = malloc(sizeof(struct stlinky));
29 printf("sram: 0x%x bytes @ 0x%x\n", sl->sram_base, sl->sram_size);
31 for (off = 0; off < sl->sram_size; off += 4) {
32 stlink_read_mem32(sl, sram_base + off, 4);
33 if ( STLINKY_MAGIC== *(uint32_t*) sl->q_buf)
35 printf("stlinky detected at 0x%x\n", sram_base + off);
36 st->off = sram_base + off;
37 stlink_read_mem32(sl, st->off + 4, 4);
38 st->bufsize = (size_t) *(unsigned char*) sl->q_buf;
39 printf("stlinky buffer size 0x%zu \n", st->bufsize);
46 int stlinky_canrx(struct stlinky *st)
48 stlink_read_mem32(st->sl, st->off+4, 4);
49 unsigned char tx = (unsigned char) st->sl->q_buf[1];
53 size_t stlinky_rx(struct stlinky *st, char* buffer)
57 stlink_read_mem32(st->sl, st->off+4, 4);
58 tx = (unsigned char) st->sl->q_buf[1];
60 size_t rs = tx + (4 - (tx % 4)); /* voodoo */
61 stlink_read_mem32(st->sl, st->off+8, rs);
62 memcpy(buffer, st->sl->q_buf, (size_t) tx);
64 stlink_write_mem8(st->sl, st->off+5, 1);
68 size_t stlinky_tx(struct stlinky *st, char* buffer, size_t sz)
72 stlink_read_mem32(st->sl, st->off+4, 4);
73 rx = (unsigned char) st->sl->q_buf[2];
75 memcpy(st->sl->q_buf, buffer, sz);
76 size_t rs = sz + (4 - (sz % 4)); /* voodoo */
77 stlink_write_mem32(st->sl, st->off+8+st->bufsize, rs);
78 *st->sl->q_buf=(unsigned char) sz;
79 stlink_write_mem8(st->sl, st->off+6, 1);
90 FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
91 select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
92 return FD_ISSET(STDIN_FILENO, &fds);
95 void nonblock(int state)
97 struct termios ttystate;
99 //get the terminal state
100 tcgetattr(STDIN_FILENO, &ttystate);
104 //turn off canonical mode
105 ttystate.c_lflag &= ~ICANON;
106 ttystate.c_lflag &= ~ECHO;
107 //minimum of number input read.
108 ttystate.c_cc[VMIN] = 1;
112 //turn on canonical mode
113 ttystate.c_lflag |= ICANON | ECHO;
115 //set the terminal attributes.
116 tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
120 static int keep_running = 1;
121 static int sigcount=0;
122 void cleanup(int dummy)
126 printf("\n\nGot a signal\n");
128 printf("\n\nGot a second signal - bailing out\n");
134 int main(int ac, char** av) {
140 sl = stlink_open_usb(10, 1);
142 printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n");
144 stlink_enter_swd_mode(sl);
145 printf("chip id: %#x\n", sl->chip_id);
146 printf("core_id: %#x\n", sl->core_id);
148 cortex_m3_cpuid_t cpuid;
149 stlink_cpu_id(sl, &cpuid);
150 printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant);
151 printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision);
154 stlink_force_debug(sl);
158 /* wait for device to boot */
159 /* TODO: Make timeout adjustable via command line */
162 struct stlinky *st = stlinky_detect(sl);
165 printf("stlinky magic not found in sram :(\n");
168 char* rxbuf = malloc(st->bufsize);
169 char* txbuf = malloc(st->bufsize);
172 int fd = fileno(stdin);
173 int saved_flags = fcntl(fd, F_GETFL);
174 fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK);
175 signal(SIGINT, cleanup);
176 printf("Entering interactive terminal. CTRL+C to exit\n\n\n");
178 if (stlinky_canrx(st)) {
179 tmp = stlinky_rx(st, rxbuf);
180 fwrite(rxbuf,tmp,1,stdout);
184 tmp = read(fd, txbuf, st->bufsize);
185 stlinky_tx(st,txbuf,tmp);
192 stlink_exit_debug_mode(sl);