Commit b6e9f221 authored by Christian Eichler's avatar Christian Eichler
Browse files

Remove xmccomm (unused, replaced by aladdin)

parent e41b8db8
......@@ -60,7 +60,7 @@ OBJS += src/System_$(UC).o
OBJS_MAIN = $(OBJS) $(SRC_MAIN:.c=.o)
#### Rules ####
all: $(OBJS) bin/xmc.bin xmccomm
all: $(OBJS) bin/xmc.bin
src/System_$(UC).o: $(CMSIS_SRC)
$(CC) -c $(CFLAGS) $< -o $@
......@@ -124,8 +124,5 @@ fastgdb:
sleep 1
make gdb
xmccomm: xmccomm.c
gcc -std=c99 -g xmccomm.c -o xmccomm
clean:
rm -f src/*.o src/*.d bin/*
#define _POSIX_C_SOURCE 199309L
#define _XOPEN_SOURCE 500
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#define SHELL_ESC "\x1b"
#define streq(A,B) (!strcmp(A,B))
// stty -F /dev/ttyACM0 115200
static void print_ok() {
printf(SHELL_ESC"[;32;02m[ok] "SHELL_ESC"[m");
}
static void print_er() {
printf(SHELL_ESC"[;31;02m[ER] "SHELL_ESC"[m");
}
static void print_vb(char *msg) {
fprintf(stderr, SHELL_ESC"[;36;02m[vb] "SHELL_ESC"[m%s", msg);
}
static bool recv_response(FILE *fh, char *buf, size_t buf_size) {
int pos = 0;
while(pos < buf_size) {
int c = fgetc(fh);
if(EOF != c) {
if('\n' == c) {
buf[pos] = '\0';
return true;
} else if('\r' == c) {
buf[pos] = '\0';
return false;
} else {
buf[pos] = c;
++pos;
}
} else {
if(ferror(fh)) {
perror("fgetc(TTY)");
exit(EXIT_FAILURE);
} else {
fprintf(stderr, "Unexpected EOF\n");
exit(EXIT_FAILURE);
}
}
}
}
static int connect_tty(char *tty) {
bool exists = false;
unsigned retry = 0;
do {
print_vb("");
fprintf(stderr, "open('%s') try %u\n", tty, retry);
++retry;
struct stat sbuf;
int res = stat(tty, &sbuf);
exists = (0 == res);
if(!exists) {
usleep(500 * 1000);
}
} while(!exists && errno != EACCES && retry < 10);
int fd = open(tty, O_RDWR | O_NOCTTY);
if(-1 == fd) {
perror("open(TTY)");
if(EACCES == errno) {
fprintf(stderr, "Make sure current user `%s` is in group `dialout`\n", getlogin());
}
exit(EXIT_FAILURE);
} else {
print_vb(""); fprintf(stderr, "%s successfully opened\n", tty);
}
// setup control structure
struct termios toptions;
if(0 != tcgetattr(fd, &toptions)) { perror("tcgetattr"); }
if(0 != cfsetispeed(&toptions, B115200)) { perror("cfsetispeed"); }
if(0 != cfsetospeed(&toptions, B115200)) { perror("cfsetospeed"); }
toptions.c_cflag &= ~PARENB; // no parity bit
toptions.c_cflag &= ~CSTOPB; // no stop bits
toptions.c_cflag &= ~CSIZE; // char. size
toptions.c_cflag |= CS8; // 8 bits
/* enable receiver, ignore status lines */
toptions.c_cflag |= CREAD | CLOCAL;
/* disable input/output flow control, disable restart chars */
toptions.c_iflag &= ~(IXON | IXOFF | IXANY);
/* disable canonical input, disable echo,
disable visually erase chars,
disable terminal-generated signals */
toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
toptions.c_oflag &= ~OPOST; // disable postprocessing
if(0 != tcsetattr(fd, TCSANOW, &toptions)) { perror("tcsetattr"); }
if(0 != tcflush(fd, TCIFLUSH)) { perror("tcflush"); }
return fd;
}
static char* strsw(char *str, char *start) {
const uint32_t N = strlen(start);
if(!strncmp(str, start, N)) {
return &str[N];
}
return NULL;
}
uint32_t remote_frequency = 0;
static void resp_inf(bool success, char *resp) {
char *rem = NULL;
if(streq(resp, "4wt")) { printf("DWT: 4 comparators for watchpoints+triggers available"); }
else if(streq(resp, "4w" )) { printf("DWT: 4 comparators for watchpoints available"); }
else if(streq(resp, "1wt")) { printf("DWT: 1 comparator for watchpoints+triggers available"); }
else if(streq(resp, "1w" )) { printf("DWT: 1 comparator for watchpoints available"); }
else if(streq(resp, "0" )) { printf("DWT: NOT AVAILABLE"); }
else if(streq(resp, "v" )) { printf("Unexpected value ain DWT->CTRL"); }
else if(rem = strsw(resp, "freq ")) {
remote_frequency = strtoull(rem, NULL, 10);
char prefixes[] = { ' ', 'k', 'M', 'G' };
double freq_dbl = remote_frequency;
int idx = 0;
while(freq_dbl > 500) {
++idx;
freq_dbl /= 1000.;
}
printf("Frequency: %.2f%cHz", freq_dbl, prefixes[idx]);
} else if(rem = strsw(resp, "ic ")) {
printf("Instruction Cache: Currently %s", ('e' == *rem) ? "enabled" : "disabled");
} else if(rem = strsw(resp, "ov ")) {
printf("Timer Overflow Detection: Currently %s", ('e' == *rem) ? "enabled" : "disabled");
} else if(rem = strsw(resp, "id ")) {
printf("Device ID: %s", rem);
} else if(rem = strsw(resp, "wspflash ")) {
printf("Flash Wait States: %s", rem);
} else {
printf("Unparsed: %s", resp);
}
}
static void resp_bch(bool success, char *resp) {
char *rem = NULL;
if(streq(resp, "start")) {
printf("Benchmark started...");
} else if(rem = strsw(resp, "end ")) {
printf("Benchmark done: ");
uint64_t cycles = strtoull(rem, NULL, 10);
printf("%lu cy / %0.2f s", cycles, (double)cycles / remote_frequency);
} else if(rem = strsw(resp, "ov")) {
printf("Overflow in input data");
} else {
printf("Unparsed: %s", resp);
}
}
static void resp_dic(bool success, char *resp) {
printf("Instruction Cache now disabled!");
}
static void resp_eic(bool success, char *resp) {
printf("Instruction Cache now enabled!");
}
static void response_loop(FILE *fh, void (*cb)(bool, char*)) {
bool done = false;
char buf[128];
while(!done) {
done = recv_response(fh, buf, 128);
bool success;
switch(buf[0]) {
case 'o':
success = true;
print_ok();
break;
case 'e':
success = false;
print_er();
break;
default:
printf(SHELL_ESC"[;31;02m[ER] Invalid response!");
return;
}
char *rem = NULL;
if(rem = strsw(buf, "e:uc")) {
printf("Command not known to device; are you trying to benchmark on an IDS?\n");
exit(EXIT_FAILURE);
} else {
cb(success, '\0' != &buf[1] ? &buf[2] : NULL);
}
printf(SHELL_ESC"[m\n");
fflush(stdout);
}
}
struct command {
char *cmd;
uint32_t nparam;
void (*callback)(bool, char*);
};
static struct command commands[] = {
{"bch", 1, resp_bch},
{"dic", 0, resp_dic},
{"eic", 0, resp_eic},
{"inf", 0, resp_inf},
{"rst", 0, NULL}
};
static const size_t commands_count = sizeof(commands)/sizeof(struct command);
int main(int argc, char *argv[]) {
if(2 != argc) {
fprintf(stderr, "Usage: %s <tty> \n", argv[0]);
return EXIT_FAILURE;
}
int fd = connect_tty(argv[1]);
FILE *fh = fdopen(fd, "r+");
if(fh == NULL) {
perror("fdopen(TTY)");
return EXIT_FAILURE;
}
print_vb("Requesting device info...\n");
fprintf(fh, "inf \n");
fflush(fh);
response_loop(fh, resp_inf);
print_vb("Sending user commands...\n");
char input[512];
while(NULL != fgets(input, sizeof(input), stdin)) {
struct command *cmd = NULL;
input[strlen(input) - 1] = '\0';
for(int j = 0; j < commands_count && NULL == cmd; ++j) {
if(!strncmp(input, commands[j].cmd, strlen(commands[j].cmd))) {
cmd = &commands[j];
}
}
if(NULL == cmd) {
print_er();
printf("Unknown command `%s`; ABORTING\n", input);
return EXIT_FAILURE;
}
print_vb(""); fprintf(stderr, "Sending command '%s'...\n", input);
fprintf(fh, "%s \n", input);
fflush(fh);
response_loop(fh, cmd->callback);
}
return EXIT_SUCCESS;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment