Advertisement
Guest User

Untitled

a guest
Aug 19th, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.84 KB | None | 0 0
  1. /* suu.c -- simple UART utility */
  2. /* ITJUSTWORKS(tm) on Cygwin, Linux. */
  3.  
  4. #include <stdio.h>
  5. #include <stdint.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <sys/select.h>
  10. #include <errno.h>
  11. #include <termios.h>
  12. #include <getopt.h>
  13.  
  14. int open_port(const char *port) {
  15.     int fd;
  16.  
  17.     fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
  18.     if (fd == -1) {
  19.         perror("open_port: Unable to open \"port\" - ");
  20.     } else {
  21.         fcntl(fd, F_SETFL, 0);
  22.     }
  23.  
  24.     return fd;
  25. }
  26.  
  27. int write_port(int fd, uint8_t *byte) {
  28.     fd_set output;
  29.  
  30.     FD_ZERO(&output);
  31.     FD_SET(fd, &output);
  32.     if (select(fd+1, NULL, &output, NULL, NULL) > 0) {
  33.         if (FD_ISSET(fd, &output)) {
  34.             write(fd, byte, 1);
  35.         }
  36.     }
  37.  
  38.     return 0;
  39. }
  40.  
  41. int read_port(int fd, uint8_t *byte) {
  42.     fd_set input;
  43.  
  44.     FD_ZERO(&input);
  45.     FD_SET(fd, &input);
  46.     if (select(fd+1, &input, NULL, NULL, NULL) > 0) {
  47.         if (FD_ISSET(fd, &input)) {
  48.             read(fd, byte, 1);
  49.         }
  50.     }
  51.  
  52.     return 0;
  53. }
  54.  
  55. int close_port(int fd) {
  56.     if (fd == -1) {
  57.         perror("close_port: Unable to close \"fd\" - ");
  58.     } else {
  59.         close(fd);
  60.     }
  61.  
  62.     return fd;
  63. }
  64.  
  65. struct termios g_backup_options;
  66. int restore_options(int fd) {
  67.     tcsetattr(fd, TCSADRAIN, &g_backup_options);
  68.     return 0;
  69. }
  70.  
  71. int update_options(speed_t baud, int fd) {
  72.     struct termios options;
  73.  
  74.     tcgetattr(fd, &g_backup_options);
  75.     tcgetattr(fd, &options);
  76.  
  77.     cfsetispeed(&options, baud);
  78.     cfsetospeed(&options, baud);
  79.  
  80.     options.c_cflag |= (CLOCAL | CREAD);
  81.     options.c_cflag &= ~PARENB;
  82.     options.c_cflag &= ~CSTOPB;
  83.     options.c_cflag &= ~CSIZE;
  84.     options.c_cflag |= CS8;
  85.  
  86.     options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  87.  
  88.     options.c_iflag |= IGNPAR;
  89.     options.c_iflag &= ~(IXON | IXOFF | IXANY);
  90.  
  91.     options.c_oflag &= ~OPOST;
  92.  
  93.     options.c_cc[VTIME] = 0;
  94.     options.c_cc[VMIN]  = 1;
  95.  
  96.     tcsetattr(fd, TCSANOW, &options);
  97.  
  98.     return 0;
  99. }
  100.  
  101. void print_usage() {
  102.     fputs("NAME                                                     \n", stdout);
  103.     fputs(" suu - simple UART utility                               \n", stdout);
  104.     fputs("                                                         \n", stdout);
  105.     fputs("SYNOPSIS                                                 \n", stdout);
  106.     fputs(" suu [-p port] [-b baud] [-m mode] [-i input] [-o output]\n", stdout);
  107.     fputs("                                                         \n", stdout);
  108.     fputs("DESCRIPTION                                              \n", stdout);
  109.     fputs(" suu handles UART input and output in specified mode.    \n", stdout);
  110.     fputs("                                                         \n", stdout);
  111.     fputs("  -p port, --port=port                                   \n", stdout);
  112.     fputs("   Specifies serial port.                                \n", stdout);
  113.     fputs("   Default is /dev/ttyS0.                                \n", stdout);
  114.     fputs("                                                         \n", stdout);
  115.     fputs("  -b baud --baud=baud                                    \n", stdout);
  116.     fputs("   Specifies baud rate from 75, 110, 134, 150, 300, 600, \n", stdout);
  117.     fputs("   1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600,    \n", stdout);
  118.     fputs("   115200.                                               \n", stdout);
  119.     fputs("   Default is 115200.                                    \n", stdout);
  120.     fputs("                                                         \n", stdout);
  121.     fputs("  -m mode, --mode=mode                                   \n", stdout);
  122.     fputs("   Specifies mode from loader or io.                     \n", stdout);
  123.     fputs("   Default is loader                                     \n", stdout);
  124.     fputs("                                                         \n", stdout);
  125.     fputs("  -i input, --input=input                                \n", stdout);
  126.     fputs("   Specifies input file.                                 \n", stdout);
  127.     fputs("   Default is - which means stdin.                       \n", stdout);
  128.     fputs("                                                         \n", stdout);
  129.     fputs("  -o output, --output=output                             \n", stdout);
  130.     fputs("   Specifies output file.                                \n", stdout);
  131.     fputs("   Default is - which means stdout.                      \n", stdout);
  132.     return;
  133. }
  134.  
  135. int main (int argc, char *argv[]) {
  136.     int ch;
  137.     struct option longopts[] ={
  138.         {"port",   required_argument, NULL, 'p'},
  139.         {"baud",   required_argument, NULL, 'b'},
  140.         {"mode",   required_argument, NULL, 'm'},
  141.         {"input",  required_argument, NULL, 'i'},
  142.         {"output", required_argument, NULL, 'o'},
  143.         {"help",   no_argument,       NULL, 'h'},
  144.         {0,        0,                    0,  0 }
  145.     };
  146.     int opt_idx = 0;
  147.     char port[256] = "/dev/ttyS0";
  148.     speed_t baud = B115200;
  149.     #define MODE_LOADER 0
  150.     #define MODE_IO     1
  151.     #define MODE_WRITE  2
  152.     #define MODE_READ   3
  153.     int mode = MODE_LOADER;
  154.     char ifile[256] = "-";
  155.     char ofile[256] = "-";
  156.  
  157.     while((ch = getopt_long(argc, argv, "p:b:m:i:o:h", longopts, &opt_idx)) != -1) {
  158.         switch (ch) {
  159.             case 'p':
  160.                 strncpy(port, optarg, sizeof(port));
  161.                 break;
  162.             case 'b':
  163.                         if (strcmp(optarg,     "75") == 0) { baud = B75;     }
  164.                    else if (strcmp(optarg,    "110") == 0) { baud = B110;    }
  165.                    else if (strcmp(optarg,    "134") == 0) { baud = B134;    }
  166.                    else if (strcmp(optarg,    "150") == 0) { baud = B150;    }
  167.                    else if (strcmp(optarg,    "300") == 0) { baud = B300;    }
  168.                    else if (strcmp(optarg,    "600") == 0) { baud = B600;    }
  169.                    else if (strcmp(optarg,   "1200") == 0) { baud = B1200;   }
  170.                    else if (strcmp(optarg,   "1800") == 0) { baud = B1800;   }
  171.                    else if (strcmp(optarg,   "2400") == 0) { baud = B2400;   }
  172.                    else if (strcmp(optarg,   "4800") == 0) { baud = B4800;   }
  173.                 /* else if (strcmp(optarg,   "7200") == 0) { baud = B7200;   } */ /* Undefined on Cygwin. */
  174.                    else if (strcmp(optarg,   "9600") == 0) { baud = B9600;   }
  175.                 /* else if (strcmp(optarg,  "14400") == 0) { baud = B14400;  } */ /* Undefined on Cygwin. */
  176.                    else if (strcmp(optarg,  "19200") == 0) { baud = B19200;  }
  177.                    else if (strcmp(optarg,  "38400") == 0) { baud = B38400;  }
  178.                    else if (strcmp(optarg,  "57600") == 0) { baud = B57600;  }
  179.                    else if (strcmp(optarg, "115200") == 0) { baud = B115200; }
  180.                 /* else if (strcmp(optarg, "128000") == 0) { baud = B128000; } */ /* Undefined on Linux. */
  181.                 break;
  182.             case 'm':
  183.                      if (strcmp(optarg, "loader") == 0) { mode = MODE_LOADER; }
  184.                 else if (strcmp(optarg,     "io") == 0) { mode = MODE_IO;     }
  185.                 else if (strcmp(optarg,  "write") == 0) { mode = MODE_WRITE;  }
  186.                 else if (strcmp(optarg,   "read") == 0) { mode = MODE_READ;   }
  187.                 break;
  188.             case 'i':
  189.                 strncpy(ifile, optarg, sizeof(ifile));
  190.                 break;
  191.             case 'o':
  192.                 strncpy(ofile, optarg, sizeof(ofile));
  193.                 break;
  194.             case 'h':
  195.             default:
  196.                 print_usage();
  197.                 return 0;
  198.         }
  199.     }
  200.  
  201.     int fd;
  202.     FILE *ifp;
  203.     FILE *ofp;
  204.  
  205.     if ((fd = open_port(port)) == -1) {
  206.         return 0;
  207.     }
  208.     update_options(baud, fd);
  209.     if (strcmp(ifile, "-") == 0) {
  210.         ifp = stdin;
  211.     } else {
  212.         ifp = fopen(ifile, "r");
  213.     }
  214.     if (strcmp(ofile, "-") == 0) {
  215.         ofp = stdout;
  216.     } else {
  217.         ofp = fopen(ofile, "w");
  218.     }
  219.  
  220.     uint32_t winst;
  221.     uint32_t rinst;
  222.     uint8_t  byte;
  223.     switch (mode) {
  224.         case MODE_LOADER:
  225.             while (!feof(ifp)) {
  226.                 fscanf(ifp, "%05X\n", &winst);
  227.                 byte = (uint8_t)((0x000000FF & winst) >> 0*8); write_port(fd, &byte);
  228.                 byte = (uint8_t)((0x0000FF00 & winst) >> 1*8); write_port(fd, &byte);
  229.                 byte = (uint8_t)((0x00030000 & winst) >> 2*8); write_port(fd, &byte);
  230.                 fprintf(ofp, "< %05X\n", winst);
  231.             }
  232.             break;
  233.         case MODE_IO:
  234.             while (!feof(ifp)) {
  235.                 fscanf(ifp, "%06X\n", &winst);
  236.                 byte = (uint8_t)((0xFF0000 & winst) >> 2*8); write_port(fd, &byte);
  237.                 if (byte == 0x00) {
  238.                     byte = (uint8_t)((0x00FF00 & winst) >> 1*8); write_port(fd, &byte);
  239.                     byte = (uint8_t)((0x0000FF & winst) >> 0*8); write_port(fd, &byte);
  240.                     fprintf(ofp, "< %06X\n", winst);
  241.                 } else if (byte == 0x01) {
  242.                     byte = (uint8_t)((0x00FF00 & winst) >> 1*8); write_port(fd, &byte);
  243.                     fprintf(ofp, "< %04X\n", (0xFFFF00 & winst) >> 1*8);
  244.                 }
  245.                 rinst = 0x000000;
  246.                 read_port(fd, &byte); rinst |= byte << 2*8;
  247.                 read_port(fd, &byte); rinst |= byte << 1*8;
  248.                 read_port(fd, &byte); rinst |= byte << 0*8;
  249.                 fprintf(ofp, "> %06X\n", rinst);
  250.             }
  251.             break;
  252.         case MODE_WRITE:
  253.             fprintf(ofp, "< ");
  254.             while (!feof(ifp)) {
  255.                 fscanf(ifp, "%c", &byte);
  256.                 write_port(fd, &byte);
  257.                 fprintf(ofp, "%c", byte);
  258.                 if (byte == '\n') {
  259.                     fprintf(ofp, "< ");
  260.                 }
  261.             }
  262.             break;
  263.         case MODE_READ:
  264.             fprintf(ofp, "> ");
  265.             while (1) {
  266.                 read_port(fd, &byte);
  267.                 fprintf(ofp, "%c", byte);
  268.                 if (byte == '\n') {
  269.                     fprintf(ofp, "> ");
  270.                 }
  271.             }
  272.             break;
  273.         default:
  274.             /* NOT REACHED */
  275.             break;
  276.     }
  277.  
  278.     fclose(ifp);
  279.     fclose(ofp);
  280.     restore_options(fd);
  281.     close_port(fd);
  282.  
  283.     return 0;
  284. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement