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

Reply via email to