Drop doublerate parameter and replace it with a generic speed parameter. Additionally, on linux you can supply any (non-standard) baudrate.
Signed-off-by: Michael Walle <mich...@walle.cc> --- tools/flterm.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 49 insertions(+), 12 deletions(-) diff --git a/tools/flterm.c b/tools/flterm.c index 6c4f28e..d8c84fb 100644 --- a/tools/flterm.c +++ b/tools/flterm.c @@ -35,6 +35,10 @@ #include <getopt.h> #include <sfl.h> +#ifdef __linux__ +#include <linux/serial.h> +#endif + #define DEFAULT_KERNELADR (0x40000000) #define DEFAULT_CMDLINEADR (0x41000000) #define DEFAULT_INITRDADR (0x41002000) @@ -375,7 +379,7 @@ static void gdb_process_packet(int infd, int outfd, int altfd) } static void do_terminal(char *serial_port, - int doublerate, int gdb_passthrough, + int baud, int gdb_passthrough, const char *kernel_image, unsigned int kernel_address, const char *cmdline, unsigned int cmdline_address, const char *initrd_image, unsigned int initrd_address, @@ -390,6 +394,8 @@ static void do_terminal(char *serial_port, struct pollfd fds[3]; int flags; int rsp_pending = 0; + int c_cflag; + int custom_divisor; /* Open and configure the serial port */ if(log_path != NULL) { @@ -406,11 +412,41 @@ static void do_terminal(char *serial_port, return; } + custom_divisor = 0; + switch(baud) { + case 9600: c_cflag = B9600; break; + case 19200: c_cflag = B19200; break; + case 38400: c_cflag = B38400; break; + case 57600: c_cflag = B57600; break; + case 115200: c_cflag = B115200; break; + case 230400: c_cflag = B230400; break; + default: + c_cflag = B38400; + custom_divisor = 1; + break; + } + +#ifdef __linux__ + if(custom_divisor) { + struct serial_struct serial_info; + ioctl(serialfd, TIOCGSERIAL, &serial_info); + serial_info.custom_divisor = serial_info.baud_base / baud; + serial_info.flags &= ~ASYNC_SPD_MASK; + serial_info.flags |= ASYNC_SPD_CUST; + ioctl(serialfd, TIOCSSERIAL, &serial_info); + } +#else + if(custom_divisor) { + printf("[FLTERM] baudrate not supported\n"); + return; + } +#endif + /* Thanks to Julien Schmitt (GTKTerm) for figuring out the correct parameters * to put into that weird struct. */ tcgetattr(serialfd, &my_termios); - my_termios.c_cflag = doublerate ? B230400 : B115200; + my_termios.c_cflag = c_cflag; my_termios.c_cflag |= CS8; my_termios.c_cflag |= CREAD; my_termios.c_iflag = IGNPAR | IGNBRK; @@ -535,7 +571,7 @@ static void do_terminal(char *serial_port, enum { OPTION_PORT, OPTION_GDB_PASSTHROUGH, - OPTION_DOUBLERATE, + OPTION_SPEED, OPTION_DEBUG, OPTION_KERNEL, OPTION_KERNELADR, @@ -563,9 +599,9 @@ static const struct option options[] = { .val = OPTION_DEBUG }, { - .name = "double-rate", - .has_arg = 0, - .val = OPTION_DOUBLERATE + .name = "speed", + .has_arg = 1, + .val = OPTION_SPEED }, { .name = "kernel", @@ -619,7 +655,7 @@ static void print_usage() fprintf(stderr, "the Free Software Foundation, version 3 of the License.\n\n"); fprintf(stderr, "Usage: flterm --port <port>\n"); - fprintf(stderr, " [--double-rate] [--gdb-passthrough] [--debug]\n"); + fprintf(stderr, " [--speed <speed>] [--gdb-passthrough] [--debug]\n"); fprintf(stderr, " [--kernel <kernel_image> [--kernel-adr <address>]]\n"); fprintf(stderr, " [--cmdline <cmdline> [--cmdline-adr <address>]]\n"); fprintf(stderr, " [--initrd <initrd_image> [--initrd-adr <address>]]\n"); @@ -634,7 +670,7 @@ int main(int argc, char *argv[]) { int opt; char *serial_port; - int doublerate; + int baud; int gdb_passthrough; char *kernel_image; unsigned int kernel_address; @@ -648,7 +684,7 @@ int main(int argc, char *argv[]) /* Fetch command line arguments */ serial_port = NULL; - doublerate = 0; + baud = 115200; gdb_passthrough = 0; kernel_image = NULL; kernel_address = DEFAULT_KERNELADR; @@ -667,8 +703,9 @@ int main(int argc, char *argv[]) free(serial_port); serial_port = strdup(optarg); break; - case OPTION_DOUBLERATE: - doublerate = 1; + case OPTION_SPEED: + baud = strtoul(optarg, &endptr, 0); + if(*endptr != 0) baud = 115200; break; case OPTION_DEBUG: debug = 1; @@ -722,7 +759,7 @@ int main(int argc, char *argv[]) tcsetattr(0, TCSANOW, &ntty); /* Do the bulk of the work */ - do_terminal(serial_port, doublerate, gdb_passthrough, + do_terminal(serial_port, baud, gdb_passthrough, kernel_image, kernel_address, cmdline, cmdline_address, initrd_image, initrd_address, -- 1.7.2.5 _______________________________________________ http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org IRC: #milkymist@Freenode