Add serial.h to properly setup the serial port.

Change-Id: I0a61d2d251ad8f0d3cfbb53c5d1b66dd03873e16
diff --git a/y2019/jevois/BUILD b/y2019/jevois/BUILD
index b944d98..e4587b5 100644
--- a/y2019/jevois/BUILD
+++ b/y2019/jevois/BUILD
@@ -1,3 +1,5 @@
+package(default_visibility = ["//visibility:public"])
+
 spi_crc_args = [
     "$(location //third_party/pycrc:pycrc_main)",
     "--width=16",
@@ -115,3 +117,12 @@
         "//third_party/GSL",
     ],
 )
+
+cc_library(
+    name = "serial",
+    hdrs = ["serial.h"],
+    srcs = ["serial.cc"],
+    deps = [
+        "//aos/logging:logging",
+    ],
+)
diff --git a/y2019/jevois/serial.cc b/y2019/jevois/serial.cc
new file mode 100644
index 0000000..7c49b4f
--- /dev/null
+++ b/y2019/jevois/serial.cc
@@ -0,0 +1,78 @@
+#include "y2019/jevois/serial.h"
+
+#include "aos/logging/logging.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <termios.h>
+#include <unistd.h>
+
+namespace y2019 {
+namespace jevois {
+
+int open_via_terminos(const char *tty_name) {
+  int itsDev = ::open(tty_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
+  if (itsDev == -1) {
+    LOG(FATAL, "problem opening: %s\n", tty_name);
+  }
+
+  termios options = {};
+  if (tcgetattr(itsDev, &options) == -1) LOG(FATAL, "Failed to get options");
+
+  // get raw input from the port
+  options.c_cflag |= (CLOCAL     // ignore modem control lines
+                      | CREAD);  // enable the receiver
+
+  options.c_iflag &= ~(IGNBRK    // ignore BREAK condition on input
+                       | BRKINT  // If IGNBRK is not set, generate SIGINT on
+                                 // BREAK condition, else read BREAK as \0
+                       | PARMRK | ISTRIP  // strip off eighth bit
+                       | INLCR            // donot translate NL to CR on input
+                       | IGNCR            // ignore CR
+                       | ICRNL            // translate CR to newline on input
+                       | IXON  // disable XON/XOFF flow control on output
+                       );
+
+  // disable implementation-defined output processing
+  options.c_oflag &= ~OPOST;
+  options.c_lflag &= ~(ECHO      // dont echo i/p chars
+                       | ECHONL  // do not echo NL under any circumstance
+                       | ICANON  // disable cannonical mode
+                       | ISIG    // do not signal for INTR, QUIT, SUSP etc
+                       | IEXTEN  // disable platform dependent i/p processing
+                       );
+
+  cfsetispeed(&options, B115200);
+  cfsetospeed(&options, B115200);
+
+  // Set the number of bits:
+  options.c_cflag &= ~CSIZE;  // mask off the 'size' bits
+  options.c_cflag |= CS8;
+
+  // Set parity option:
+  options.c_cflag &= ~(PARENB | PARODD);
+
+  // Set the stop bits option:
+  options.c_cflag &= ~CSTOPB;
+
+  // Set the flow control:
+  options.c_cflag &= ~CRTSCTS;
+  options.c_iflag &= ~(IXON | IXANY | IXOFF);
+
+  options.c_cc[VMIN] = 1;
+  options.c_cc[VTIME] = 2;
+
+  // Flow control:
+  // flow soft:
+  // options.c_iflag |= (IXON | IXANY | IXOFF);
+  // flow hard:
+  // options.c_cflag |= CRTSCTS;
+
+  if (tcsetattr(itsDev, TCSANOW, &options) == -1)
+    LOG(FATAL, "Failed to set port options");
+  return itsDev;
+}
+
+}  // namespace jevois
+}  // namespace y2019
diff --git a/y2019/jevois/serial.h b/y2019/jevois/serial.h
new file mode 100644
index 0000000..9dd4b0c
--- /dev/null
+++ b/y2019/jevois/serial.h
@@ -0,0 +1,12 @@
+#ifndef Y2019_JEVOIS_SERIAL_H_
+#define Y2019_JEVOIS_SERIAL_H_
+
+namespace y2019 {
+namespace jevois {
+
+int open_via_terminos(const char *tty_name);
+
+}  // namespace jevois
+}  // namespace frc971
+
+#endif  // Y2019_JEVOIS_SERIAL_H_