summaryrefslogtreecommitdiff
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
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
-rw-r--r--Makefile.rules9
-rw-r--r--Makefile.toolchain1
-rw-r--r--util/build.mk1
-rw-r--r--util/ec_uartd.c126
4 files changed, 134 insertions, 3 deletions
diff --git a/Makefile.rules b/Makefile.rules
index 888425daa1..bd2472e22c 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -11,7 +11,8 @@ build-utils := $(foreach u,$(build-util-bin),$(out)/util/$(u))
host-utils := $(foreach u,$(host-util-bin),$(out)/util/$(u))
# Create output directories if necessary
-_dir_create := $(foreach d,$(dirs),$(shell [ -d $(out)/$(d) ] || mkdir -p $(out)/$(d)))
+_dir_create := $(foreach d,$(dirs),$(shell [ -d $(out)/$(d) ] || \
+ mkdir -p $(out)/$(d)))
section = $(subst .,,$(suffix $(1)))
@@ -29,9 +30,11 @@ cmd_elf_to_flat = $(OBJCOPY) -O binary $^ $@
cmd_elf_to_dis = $(OBJDUMP) -D $< > $@
cmd_elf = $(LD) $(LDFLAGS) $(objs) -o $@ -T $< -Map $(out)/$*.map
cmd_c_to_o = $(CC) $(CFLAGS) -MMD -MF $@.d -c $< -o $@
-cmd_c_to_build = $(BUILDCC) $(BUILD_CFLAGS) -MMD -MF $@.d $< -o $@
+cmd_c_to_build = $(BUILDCC) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) \
+ -MMD -MF $@.d $< -o $@
cmd_c_to_host = $(HOSTCC) $(HOST_CFLAGS) -MMD -MF $@.d $< -o $@
-cmd_qemu = ./util/run_qemu_test --image=build/$(BOARD)/$*/$*.bin test/$*.py $(silent)
+cmd_qemu = ./util/run_qemu_test --image=build/$(BOARD)/$*/$*.bin test/$*.py \
+ $(silent)
.PHONY: all tests utils
diff --git a/Makefile.toolchain b/Makefile.toolchain
index d52967edde..a7a961c4f8 100644
--- a/Makefile.toolchain
+++ b/Makefile.toolchain
@@ -30,3 +30,4 @@ CFLAGS=$(CPPFLAGS) $(CFLAGS_CPU) $(CFLAGS_DEBUG) $(CFLAGS_WARN)
BUILD_CFLAGS=$(CPPFLAGS) -O3 $(CFLAGS_DEBUG) $(CFLAGS_WARN)
HOST_CFLAGS=$(CPPFLAGS) -O3 $(CFLAGS_DEBUG) $(CFLAGS_WARN)
LDFLAGS=-nostdlib -X
+BUILD_LDFLAGS=-lftdi
diff --git a/util/build.mk b/util/build.mk
index 6d44606562..024f2054cf 100644
--- a/util/build.mk
+++ b/util/build.mk
@@ -6,3 +6,4 @@
#
host-util-bin=ectool
+build-util-bin=ec_uartd
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;
+}