summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2011-10-24 10:44:30 -0700
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2011-10-24 10:44:30 -0700
commit84c5a86d241b05ac9c76cad30600416f9a21f9e6 (patch)
tree1b1269903412c2eb72bacde98826599aac1a1a82
parentdd449d1b72ff4a6f7e3762b46b84a6af6e962da3 (diff)
parent406de3fe81cbe537a6254acbb6c4d490ca9d2e0f (diff)
downloadchrome-ec-84c5a86d241b05ac9c76cad30600416f9a21f9e6.tar.gz
Merge "Add ec_uartd utility"
-rw-r--r--utility/Makefile11
-rw-r--r--utility/ec_uartd.c183
2 files changed, 194 insertions, 0 deletions
diff --git a/utility/Makefile b/utility/Makefile
new file mode 100644
index 0000000000..5386089b91
--- /dev/null
+++ b/utility/Makefile
@@ -0,0 +1,11 @@
+# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+all: ec_uartd
+
+clean:
+ rm -f ec_uartd
+
+ec_uartd: ec_uartd.c
+ gcc -o ec_uartd -lftdi ec_uartd.c
diff --git a/utility/ec_uartd.c b/utility/ec_uartd.c
new file mode 100644
index 0000000000..a21450c3a2
--- /dev/null
+++ b/utility/ec_uartd.c
@@ -0,0 +1,183 @@
+/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* ec_uartd.c - UART daemon for serial output from a FTDI FT2232 chip
+ *
+ * based on chromeos_public/src/third_party/hdctools/src/ftdiuart.c
+ *
+ * compile with:
+ * gcc -o ec_uartd ec_uartd.c -lftdi
+ */
+
+#include <fcntl.h>
+#include <ftdi.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <termios.h>
+#include <unistd.h>
+
+int grantpt(int fd);
+int unlockpt(int fd);
+int ptsname_r(int fd, char *buf, size_t buflen);
+int posix_openpt(int flags);
+
+
+/* Create a pty. Returns the pty handle, which should be closed with
+ * close(), or -1 if error. */
+int openpty(const char* desc) {
+ char ptname[PATH_MAX];
+ struct termios tty_cfg;
+ int fd;
+
+ if ((fd = posix_openpt(O_RDWR | O_NOCTTY)) == -1) {
+ perror("opening pty master");
+ return -1;
+ }
+ if (grantpt(fd) == -1) {
+ perror("grantpt");
+ return -1;
+ }
+ if (unlockpt(fd) == -1) {
+ perror("unlockpt");
+ return -1;
+ }
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
+ perror("fcntl setfl -> nonblock");
+ return -1;
+ }
+ if (ptsname_r(fd, ptname, PATH_MAX) != 0) {
+ perror("getting name of pty");
+ return -1;
+ }
+ fprintf(stderr, "%s pty name = %s\n", desc, ptname);
+ if (!isatty(fd)) {
+ perror("not a TTY device\n");
+ return -1;
+ }
+ cfmakeraw(&tty_cfg);
+ tcsetattr(fd, TCSANOW, &tty_cfg);
+ if (chmod(ptname, 0666) == -1) {
+ perror("setting pty attributes");
+ return -1;
+ }
+
+ return fd;
+}
+
+
+int main(int argc, char **argv) {
+ struct ftdi_context fcontext;
+ char buf[1024], buf_ec[1024], buf_x86[1024];
+ int fd_ec, fd_x86;
+ int rv, i;
+
+ // Init
+ if (ftdi_init(&fcontext) < 0)
+ {
+ fprintf(stderr, "ftdi_init failed\n");
+ return 1;
+ }
+
+ // Open interface B (UART) in the FTDI device and set 115kbaud
+ ftdi_set_interface(&fcontext, INTERFACE_B);
+ rv = ftdi_usb_open(&fcontext, 0x0403, 0xbcda);
+ if (rv < 0)
+ {
+ fprintf(stderr, "error opening ftdi device: %d (%s)\n",
+ rv, ftdi_get_error_string(&fcontext));
+ return 2;
+ }
+ rv = ftdi_set_baudrate(&fcontext, 115200);
+ if (rv < 0)
+ {
+ fprintf(stderr, "error setting baudrate: %d (%s)\n",
+ rv, ftdi_get_error_string(&fcontext));
+ return 2;
+ }
+ // Set DTR; this muxes RX on the ICDI board
+ ftdi_setdtr(&fcontext, 1);
+
+ // Open the ptys
+ fd_ec = openpty("EC");
+ fd_x86 = openpty("x86");
+ if (fd_ec == -1 || fd_x86 == -1)
+ return 3;
+
+ // Read and write data forever
+ while (1) {
+ int bytes;
+ int bytes_ec = 0;
+ int bytes_x86 = 0;
+
+ // Copy data from EC pty, turning high bit on
+ if ((bytes = read(fd_ec, buf, sizeof(buf))) > 0) {
+ for (i = 0; i < bytes; i++)
+ buf[i] |= 0x80;
+
+ rv = ftdi_write_data(&fcontext, buf, bytes);
+ if (rv != bytes) {
+ perror("writing to uart");
+ break;
+ }
+ }
+
+ // Copy data from x86 pty, turning high bit off
+ if ((bytes = read(fd_x86, buf, sizeof(buf))) > 0) {
+ for (i = 0; i < bytes; i++)
+ buf[i] &= ~0x80;
+
+ rv = ftdi_write_data(&fcontext, buf, bytes);
+ if (rv != bytes) {
+ perror("writing to uart");
+ break;
+ }
+ }
+
+ usleep(1000);
+
+ // Get output from UART
+ bytes = ftdi_read_data(&fcontext, buf, sizeof(buf));
+ if (bytes < 0) {
+ perror("failed ftdi_read_data");
+ break;
+ }
+
+ // Split into EC and x86 buffers
+ for (i = 0; i < bytes; i++) {
+ if (buf[i] & 0x80)
+ buf_ec[bytes_ec++] = buf[i] & ~0x80;
+ else
+ buf_x86[bytes_x86++] = buf[i];
+ }
+
+ // Copy data to EC pty
+ if (bytes_ec > 0) {
+ int bytes_remaining = bytes_ec;
+ while ((bytes = write(fd_ec, buf_ec, bytes_remaining)) > 0) {
+ bytes_remaining -= bytes;
+ }
+ if (bytes == -1) {
+ perror("writing ftdi data to EC pty");
+ }
+ }
+
+ // Copy data to x86 pty
+ if (bytes_x86 > 0) {
+ int bytes_remaining = bytes_x86;
+ while ((bytes = write(fd_x86, buf_x86, bytes_remaining)) > 0) {
+ bytes_remaining -= bytes;
+ }
+ if (bytes == -1) {
+ perror("writing ftdi data to x86 pty");
+ }
+ }
+ }
+
+ // Cleanup
+ close(fd_ec);
+ close(fd_x86);
+ ftdi_usb_close(&fcontext);
+ ftdi_deinit(&fcontext);
+}