summaryrefslogtreecommitdiff
path: root/util/ec_uartd.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2011-12-13 14:15:01 -0800
committerRandall Spangler <rspangler@chromium.org>2011-12-13 14:34:29 -0800
commit3d2efff5188964b473c6af5c41106615c2c29de3 (patch)
tree500f103b46892250f1e56b115996e1bb1143f698 /util/ec_uartd.c
parentcaba91fe2797f2e7a2792a151d337c20d080a950 (diff)
downloadchrome-ec-3d2efff5188964b473c6af5c41106615c2c29de3.tar.gz
Add ec_uartd build-side utility
This provides a pty for the EC UART channel on the BD-ICDI-B FTDI daughtercard for EC debugging. Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=none TEST=make && build/bds/util/ec_uartd (with EC attached to FTDI board) Change-Id: I51fe50d0da6345962affb860b923425197a04fa1
Diffstat (limited to 'util/ec_uartd.c')
-rw-r--r--util/ec_uartd.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/util/ec_uartd.c b/util/ec_uartd.c
new file mode 100644
index 0000000000..ae2e51a580
--- /dev/null
+++ b/util/ec_uartd.c
@@ -0,0 +1,126 @@
+/* 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 BD-ICDI-B board for EC debugging
+ *
+ * based on chromeos_public/src/third_party/hdctools/src/ftdiuart.c
+ *
+ * compile with:
+ * gcc -o ftdi_uartd ftdi_uartd.c -lftdi
+ */
+
+/* Force header files to define grantpt(), posix_openpt(), cfmakeraw() */
+#define _BSD_SOURCE
+#define _XOPEN_SOURCE 600
+
+#include <fcntl.h>
+#include <ftdi.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <unistd.h>
+
+int main(int argc, char **argv)
+{
+ struct ftdi_context fcontext;
+ struct termios tty_cfg;
+ char ptname[PATH_MAX];
+ char buf[1024];
+ int fd;
+ int rv;
+
+ /* 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 pty */
+ fd = posix_openpt(O_RDWR | O_NOCTTY);
+ if (fd == -1) {
+ perror("opening pty master");
+ return 3;
+ }
+ if (grantpt(fd) == -1) {
+ perror("grantpt");
+ return 3;
+ }
+ if (unlockpt(fd) == -1) {
+ perror("unlockpt");
+ return 3;
+ }
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
+ perror("fcntl setfl -> nonblock");
+ return 3;
+ }
+ if (ptsname_r(fd, ptname, PATH_MAX) != 0) {
+ perror("getting name of pty");
+ return 3;
+ }
+ fprintf(stderr, "pty name = %s\n", ptname);
+ if (!isatty(fd)) {
+ perror("not a TTY device\n");
+ return 3;
+ }
+ cfmakeraw(&tty_cfg);
+ tcsetattr(fd, TCSANOW, &tty_cfg);
+ if (chmod(ptname, 0666) == -1) {
+ perror("setting pty attributes");
+ return 3;
+ }
+
+ /* Read and write data forever */
+ while (1) {
+ int bytes = read(fd, buf, sizeof(buf));
+ if (bytes > 0) {
+ rv = ftdi_write_data(&fcontext, buf, bytes);
+ if (rv != bytes) {
+ perror("writing to uart");
+ break;
+ }
+ }
+
+ usleep(1000);
+
+ bytes = ftdi_read_data(&fcontext, buf, sizeof(buf));
+ if (bytes > 0) {
+ int bytes_remaining = bytes;
+ while ((bytes = write(fd, buf, bytes_remaining)) > 0)
+ bytes_remaining -= bytes;
+
+ if (bytes == -1)
+ perror("writing ftdi data to pty");
+
+ } else if (bytes < 0) {
+ perror("failed ftdi_read_data");
+ break;
+ }
+ }
+
+ /* Cleanup */
+ close(fd);
+ ftdi_usb_close(&fcontext);
+ ftdi_deinit(&fcontext);
+ return 0;
+}