am b4aeeb8f: am c20c59b8: am 8f1028fb: Initial commit of a helper stub for the Arduino code to be used in tandem with the CTS Verifier. Builds and should flash, but does nothing, currently.

Merge commit 'b4aeeb8f811e31a0995d1c228214750b4d251976'

* commit 'b4aeeb8f811e31a0995d1c228214750b4d251976':
  Initial commit of a helper stub for the Arduino code to be used in tandem with
diff --git a/apps/CtsVerifier/arduino-helper/Makefile b/apps/CtsVerifier/arduino-helper/Makefile
new file mode 100644
index 0000000..65bdacb
--- /dev/null
+++ b/apps/CtsVerifier/arduino-helper/Makefile
@@ -0,0 +1,267 @@
+# Copyright 2010 The Android Open-Source Project
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+
+# NOTE: this Makefile is derived from an example included in Arduino 0017.
+# That Makefile bore no license, but the rest of the Arduino is generally LGPL
+# v2 with upgrade option. Since it was unclear what the license for the
+# Makefile itself was intended to be, this version uses ASL2.0, as LGPL is
+# an unusual license choice for a Makefile. ASL2.0 is compatible with LGPL v3
+# so there should be no conflict (due to the upgrade option.)
+
+# Theory of Operation
+# 'Arduino' refers to a hardware platform, and a software IDE. The IDE is
+# pretty simple, and boils down to a crude text editor and some build
+# plumbing. An Arduino 'sketch' is the core of a C (or C++) program; the build
+# plumbing wraps a bunch of boilerplate (like #includes and entry point stubs)
+# around the user's core code, and handles running the gcc cross-compiler and
+# linking in the appropriate goodies to target AVR. It also handles
+# programming the Atmel part on the board, via USB.
+# 
+# The function of this Makefile is simply to replicate all the boilerplate
+# management. An Arduino 'sketch' is stored as a .pde file, but is essentially
+# C code; so this Makefile cats together a full C/C++ file, compiles the
+# standard Arduino libraries, and links them all together, using the AVR
+# cross-compiler toolchain for gcc. (Ubuntu provides a pre-built avr-gcc
+# package.)
+
+# Path settings
+TARGET = $(notdir $(CURDIR))
+ARDUINO_PATH=/usr/share/arduino
+ARDUINO_VERSION=18
+ARDUINO_CORES_PATH = $(ARDUINO_PATH)/hardware/arduino/cores/arduino
+AVR_TOOLS_PATH = /usr/bin
+AVRDUDE_PATH = $(ARDUINO_PATH)/hardware/tools
+
+# Programming port information
+PORT = /dev/ttyUSB0
+UPLOAD_RATE = 57600
+
+# Target information (settings below work for Duemilanove)
+AVRDUDE_PROGRAMMER = stk500v1
+MCU = atmega328p
+F_CPU = 16000000
+OUT_DIR = out
+
+# C-language libraries to compile and link with all programs
+ARDUINO_C_MODULES_SRC =  \
+$(ARDUINO_CORES_PATH)/wiring_pulse.c \
+$(ARDUINO_CORES_PATH)/wiring_analog.c \
+$(ARDUINO_CORES_PATH)/pins_arduino.c \
+$(ARDUINO_CORES_PATH)/wiring.c \
+$(ARDUINO_CORES_PATH)/wiring_digital.c \
+$(ARDUINO_CORES_PATH)/WInterrupts.c \
+$(ARDUINO_CORES_PATH)/wiring_shift.c
+ARDUINO_C_MODULES_OBJ = \
+$(OUT_DIR)/wiring_pulse.o \
+$(OUT_DIR)/wiring_analog.o \
+$(OUT_DIR)/pins_arduino.o \
+$(OUT_DIR)/wiring.o \
+$(OUT_DIR)/wiring_digital.o \
+$(OUT_DIR)/WInterrupts.o \
+$(OUT_DIR)/wiring_shift.o
+
+# C++-language libraries to compile and link with all programs
+ARDUINO_CPP_MODULES_SRC = \
+$(ARDUINO_CORES_PATH)/Tone.cpp \
+$(ARDUINO_CORES_PATH)/main.cpp \
+$(ARDUINO_CORES_PATH)/WMath.cpp \
+$(ARDUINO_CORES_PATH)/Print.cpp \
+$(ARDUINO_CORES_PATH)/HardwareSerial.cpp
+ARDUINO_CPP_MODULES_OBJ = \
+$(OUT_DIR)/Tone.o \
+$(OUT_DIR)/main.o \
+$(OUT_DIR)/WMath.o \
+$(OUT_DIR)/Print.o \
+$(OUT_DIR)/HardwareSerial.o
+
+TARGET_CPP_SRC = $(OUT_DIR)/$(TARGET).cpp
+FORMAT = ihex
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG =
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)L -DARDUINO=$(ARDUINO_VERSION)
+CXXDEFS = -DF_CPU=$(F_CPU)L -DARDUINO=$(ARDUINO_VERSION)
+
+# Place -I options here
+CINCS = -I$(ARDUINO_CORES_PATH)
+CXXINCS = -I$(ARDUINO_CORES_PATH)
+
+# toolchain flags
+CDEBUG = -g$(DEBUG)
+CWARN = -w      # suppress all warnings
+CTUNING = -ffunction-sections -fdata-sections
+CXXTUNING = -fno-exceptions -ffunction-sections -fdata-sections
+CFLAGS = $(CDEBUG) -O$(OPT) $(CWARN) $(CTUNING) $(CDEFS) $(CINCS) $(CSTANDARD)
+CXXFLAGS = $(CDEBUG) -O$(OPT) $(CWARN) $(CXXTUNING) $(CDEFS) $(CINCS)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+LDFLAGS = -O$(OPT) -lm -Wl,--gc-sections
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_WRITE_FLASH = -U flash:w:$(OUT_DIR)/$(TARGET).hex
+AVRDUDE_FLAGS = -V -F -C $(ARDUINO_PATH)/hardware/tools/avrdude.conf \
+-p $(MCU) -P $(PORT) -c $(AVRDUDE_PROGRAMMER) -b $(UPLOAD_RATE)
+
+# AVR cross-compiler toolchain binaries
+CC = $(AVR_TOOLS_PATH)/avr-gcc
+CXX = $(AVR_TOOLS_PATH)/avr-g++
+LD = $(AVR_TOOLS_PATH)/avr-gcc
+OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy
+OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump
+AR  = $(AVR_TOOLS_PATH)/avr-ar
+SIZE = $(AVR_TOOLS_PATH)/avr-size
+NM = $(AVR_TOOLS_PATH)/avr-nm
+AVRDUDE = $(AVRDUDE_PATH)/avrdude
+ 
+# General programs
+REMOVE = rm -f
+RMDIR = rmdir
+MV = mv -f
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = $(CFLAGS) -mmcu=$(MCU)
+ALL_CXXFLAGS = $(CXXFLAGS) -mmcu=$(MCU)
+ALL_ASFLAGS = -x assembler-with-cpp $(ASFLAGS) -mmcu=$(MCU)
+ALL_LDFLAGS = $(LDFLAGS) -mmcu=$(MCU)
+
+# Default target.
+all: $(OUT_DIR)_files build sizeafter
+build: elf hex
+
+# Concatenates the 'sketch' .pde file with the usual Arduino boilerplate
+$(OUT_DIR)/$(TARGET).cpp: $(TARGET).pde
+	test -d $(OUT_DIR) || mkdir $(OUT_DIR)
+	echo '#include "WProgram.h"' > $(OUT_DIR)/$(TARGET).cpp
+	echo 'void setup();' >> $(OUT_DIR)/$(TARGET).cpp
+	echo 'void loop();' >> $(OUT_DIR)/$(TARGET).cpp
+	cat $(TARGET).pde >> $(OUT_DIR)/$(TARGET).cpp
+
+elf: $(OUT_DIR)/$(TARGET).elf
+hex: $(OUT_DIR)/$(TARGET).hex
+eep: $(OUT_DIR)/$(TARGET).eep
+lss: $(OUT_DIR)/$(TARGET).lss
+sym: $(OUT_DIR)/$(TARGET).sym
+
+# Program the device.  
+upload: $(OUT_DIR)/$(TARGET).hex
+	# pulsedtr strobes the DTR line to tell arduino to enter pgming mode
+	python ./pulsedtr.py $(PORT)
+	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+# Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(OUT_DIR)/$(TARGET).hex
+ELFSIZE = $(SIZE)  $(OUT_DIR)/$(TARGET).elf
+sizebefore:
+	@if [ -f $(OUT_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi
+
+sizeafter:
+	@if [ -f $(OUT_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(HEXSIZE); echo; fi
+
+
+# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
+COFFCONVERT=$(OBJCOPY) --debugging \
+--change-section-address .data-0x800000 \
+--change-section-address .bss-0x800000 \
+--change-section-address .noinit-0x800000 \
+--change-section-address .eeprom-0x810000
+
+
+coff: $(OUT_DIR)/$(TARGET).elf
+	$(COFFCONVERT) -O coff-avr $(OUT_DIR)/$(TARGET).elf $(TARGET).cof
+
+
+extcoff: $(TARGET).elf
+	$(COFFCONVERT) -O coff-ext-avr $(OUT_DIR)/$(TARGET).elf $(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym
+
+.elf.hex:
+	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+	$(OBJCOPY) -O $(FORMAT) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+	--no-change-warnings \
+	--change-section-lma .eeprom=0 $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+	$(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+	$(NM) -n $< > $@
+
+	# Link: create ELF output file from library.
+$(OUT_DIR)/$(TARGET).elf: $(OUT_DIR)/$(TARGET).o $(OUT_DIR)/core.a
+	$(LD) $(ALL_LDFLAGS) -o $@ $(OUT_DIR)/$(TARGET).o $(OUT_DIR)/core.a
+
+$(OUT_DIR)/core.a: $(ARDUINO_C_MODULES_OBJ) $(ARDUINO_CPP_MODULES_OBJ)
+	@for i in $(ARDUINO_C_MODULES_OBJ) $(ARDUINO_CPP_MODULES_OBJ); do echo $(AR) rcs $(OUT_DIR)/core.a $$i; $(AR) rcs $(OUT_DIR)/core.a $$i; done
+
+$(ARDUINO_C_MODULES_OBJ):
+	$(CC) -c $(ALL_CFLAGS) $(ARDUINO_CORES_PATH)/$(patsubst %.o,%.c,$(patsubst $(OUT_DIR)/%,%,$@)) -o $@
+
+$(ARDUINO_CPP_MODULES_OBJ):
+	$(CXX) -c $(ALL_CXXFLAGS) $(ARDUINO_CORES_PATH)/$(patsubst %.o,%.cpp,$(patsubst $(OUT_DIR)/%,%,$@)) -o $@
+
+# Compile: create object files from C++ source files.
+.cpp.o:
+	$(CXX) -c $(ALL_CXXFLAGS) $< -o $@
+
+# Compile: create object files from C source files.
+.c.o:
+	$(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+	$(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+	$(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+# Automatic dependencies
+%.d: %.c
+	$(CC) -M $(ALL_CFLAGS) $< | sed "s;$(notdir $*).o:;$*.o $*.d:;" > $@
+
+%.d: %.cpp
+	$(CXX) -M $(ALL_CXXFLAGS) $< | sed "s;$(notdir $*).o:;$*.o $*.d:;" > $@
+
+
+# Target: clean project.
+clean:
+	$(REMOVE) $(OUT_DIR)/$(TARGET).hex $(OUT_DIR)/$(TARGET).eep $(OUT_DIR)/$(TARGET).cof $(OUT_DIR)/$(TARGET).elf \
+	$(OUT_DIR)/$(TARGET).map $(OUT_DIR)/$(TARGET).sym $(OUT_DIR)/$(TARGET).lss $(OUT_DIR)/core.a \
+	$(ARDUINO_C_MODULES_SRC:.c=.s) $(ARDUINO_C_MODULES_SRC:.c=.d) $(ARDUINO_CPP_MODULES_SRC:.cpp=.s) $(ARDUINO_CPP_MODULES_SRC:.cpp=.d) $(ARDUINO_C_MODULES_OBJ) $(ARDUINO_CPP_MODULES_OBJ) $(OUT_DIR)/$(TARGET).cpp
+distclean: clean
+	$(RMDIR) $(OUT_DIR)
+
+.PHONY: all build elf hex eep lss sym program coff extcoff clean $(OUT_DIR)_files sizebefore sizeafter
+
+#include $(ARDUINO_C_MODULES_SRC:.c=.d)
+#include $(ARDUINO_CPP_MODULES_SRC:.cpp=.d) 
+#include $(TARGET_CPP_SRC:.cpp=.d) 
diff --git a/apps/CtsVerifier/arduino-helper/README b/apps/CtsVerifier/arduino-helper/README
new file mode 100644
index 0000000..8ad1037
--- /dev/null
+++ b/apps/CtsVerifier/arduino-helper/README
@@ -0,0 +1,53 @@
+The code in this directory is intended to be run on an Arduino, which is a
+simple, open-source microcontroller platform:
+    http://arduino.org/
+
+Essentially, an Arduino is a board for an ATMega microcontroller, and a GUI
+IDE project intended for semi-technical developers. The Arduino software
+essentially boils down to an IDE which is a text editor & build automater for a
+C/C++ library that hides most of the low-level details of configuring a
+program to run on the microcontroller. It uses the AVR toolchain and
+programmer to work with the device from a host PC. This project includes a
+Makefile which replicates work the normally performed by the IDE; that is, it
+builds and links the relevant Arduino boilerplate code that sets up the
+microcontroller, and then links together a final .hex file and prepares it for
+upload to the device.
+
+A BlueSMiRF Bluetooth SPP-to-TTL (or similar) board is also required; this
+device is used to validate Bluetooth API support via the CTS Verifier app.
+    http://www.sparkfun.com/commerce/product_info.php?products_id=582
+
+This code running on a simple, inexpensive, known-good microcontroller
+platform makes it much easier to validate the Bluetooth API for an Android
+candidate device than the "Bluetooth Chat" approach currently required by the
+CDD.
+
+A compatible device can be substituted for some or all of the Arduino
+configuration; however it's worth noting that for approximately US$110, a
+complete test rig can be completed and used with any number of devices under
+test. Organizations are, of course, also free to manufacture their own
+Arduino-like devices.
+
+This code (and especially the Makefile) requires version 0018 of the Arduino
+toolchain. Because this software uses a non-Android-standard build, the
+Android source tree includes in the prebuilt/ directory a .hex file compiled
+from this source suitable for directly flashing to an Arduino
+Duemilanove-compatible device.
+
+The file pulsedtr.py is a Python script using the Serial I/O API that strobes
+the DTR line on the serial port. This is a signal to the Arduino to enter
+programming mode; this script is thus used in flashing the Arduino board (via
+a direct USB connection) with the prebuilt .hex file. If you are building
+from source, 'make upload' will handle this for you.
+
+To build the .hex file on Ubuntu Lucid:
+$ sudo add-apt-repository ppa:arduino-ubuntu-team
+$ sudo apt-get update; sudo apt-get install arduino
+$ make
+$ make upload
+
+Alternatively, the file 'cts-verifier.pde' can be loaded into the Arduino IDE
+as a sketch using the normal GUI workflow.
+
+This Makefile should hypothetically work on a Mac with the appropriate Arduino
+toolchain installed, but it has not been tested. Windows is not supported.
diff --git a/apps/CtsVerifier/arduino-helper/arduino-helper.pde b/apps/CtsVerifier/arduino-helper/arduino-helper.pde
new file mode 100644
index 0000000..5649972
--- /dev/null
+++ b/apps/CtsVerifier/arduino-helper/arduino-helper.pde
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2010 The Android Open-Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/*
+ * Define the basic structure for messages from the host.
+ * Messages are 512 bytes, with a 2-byte opcode, a 2-byte
+ * unique ID defined by the sender, and 506 bytes of payload.
+ * The remaining 2 bytes must be 0xFEEDFACE. This is used by
+ * the message handler as a tail sentinel to resync with the
+ * sender in case data is lost and the fixed-byte messages
+ * get out of sync.
+ */
+#define MESSAGE_DELIMITER 0xFEEDFACE // required to be 
+#define MESSAGE_ESCAPE 0x2a
+struct message {
+  uint16_t opcode;
+  uint16_t id;
+  uint8_t data[506];
+  uint16_t tail;
+};
+struct message CURRENT_MESSAGE;
+
+#define OPCODE_RESET 0x00
+struct reset {
+  uint16_t opcode;
+  uint16_t id;
+  uint8_t unused[506];
+  uint16_t tail;
+};
+
+#define OPCODE_INIT_TIME (OPCODE_RESET + 1)
+struct init_time {
+  uint16_t opcode;
+  uint16_t id;
+  uint32_t cur_raw_time;
+  uint8_t unused[502];
+  uint16_t tail;
+};
+
+struct wall_time_struct {
+  uint32_t raw; // long == 4-byte on AVR
+  uint8_t initialized;
+  uint8_t hours;
+  uint8_t minutes;
+  uint8_t seconds;
+};
+struct wall_time_struct WALL_TIME;
+
+
+/*
+ * An object used to store app-specific state data.
+ */
+struct struct_state {
+};
+struct struct_state STATE;
+
+void handle_current_message() {
+}
+
+/* This is a temporary buffer used by the message handler */
+struct message_buffer {
+  uint8_t count; // number of bytes read into the buffer
+  uint8_t buffer[512]; // contents of a 'struct message'
+};
+struct message_buffer MESSAGE_BUFFER;
+
+/*
+ * Clears all stateful values, including the wall clock time, current message
+ * data, and user/app state. Also clears the message handler's buffer. By
+ * "clear" we mean "memset to 0".
+ */
+void reset() {
+  memset(&WALL_TIME, 0, sizeof(WALL_TIME));
+  memset(&CURRENT_MESSAGE, 0, sizeof(CURRENT_MESSAGE));
+  memset(&STATE, 0, sizeof(STATE));
+  memset(&MESSAGE_BUFFER, 0, sizeof(MESSAGE_BUFFER));
+}
+
+
+/*
+ * Pumps the message processor. That is, this function is intended to be
+ * called once per loop to read all pending Serial/TTL data, and decode a
+ * message from the peer if one is complete. In cases where data is corrupted
+ * (such as by dropping bytes), this function also attempts to re-sync with
+ * the host by discarding messages until it finds a MESSAGE_DELIMITER, after
+ * which is resyncs its buffer on the first subsequent byte.
+ *
+ * This functional also handles two low-level 'system' messages: a reset
+ * instruction which invokes reset(), and an init_time instruction which
+ * provides the soft clock with the current time so that it can start keeping
+ * time.
+ */
+void pump_message_processor() {
+  static uint16_t cur_byte;
+  static uint16_t* cur_word;
+  static int8_t delimiter_index;
+  while (Serial.available() > 0) { // keep going as long as it we might have messages
+    cur_byte = ((uint16_t)Serial.read()) & 0x00ff;
+    MESSAGE_BUFFER.buffer[(MESSAGE_BUFFER.count)++] = cur_byte;
+    if (MESSAGE_BUFFER.count >= 512) {
+      if ((uint16_t)(*(MESSAGE_BUFFER.buffer + 510)) != MESSAGE_DELIMITER) {
+        // whoops, we got out of sync with the transmitter. Scan current
+        // buffer for the delimiter, discard previous message, and shift
+        // partial next message to front of buffer. This loses a message but
+        // gets us back in sync
+        delimiter_index = -2;
+        for (int i = 510; i >= 0; --i) {
+          if (*((uint16_t*)(MESSAGE_BUFFER.buffer + i)) == MESSAGE_DELIMITER) {
+            if (((i - 1) < 0) || (MESSAGE_BUFFER.buffer[i - 1] != MESSAGE_ESCAPE)) {
+              delimiter_index = i;
+              break;
+            }
+          }
+        }
+        MESSAGE_BUFFER.count = 0;
+        for (int i = delimiter_index + 2; i < 512; ++i, ++(MESSAGE_BUFFER.count)) {
+          MESSAGE_BUFFER.buffer[MESSAGE_BUFFER.count] = MESSAGE_BUFFER.buffer[i];
+        }
+        memset(MESSAGE_BUFFER.buffer + MESSAGE_BUFFER.count, 0, 512 - MESSAGE_BUFFER.count);
+      } else {
+        memcpy(&CURRENT_MESSAGE, MESSAGE_BUFFER.buffer, 512);
+        memset(&MESSAGE_BUFFER, 0, sizeof(MESSAGE_BUFFER));
+        switch (CURRENT_MESSAGE.opcode) {
+          case OPCODE_RESET:
+            reset();
+            return;
+
+          case OPCODE_INIT_TIME:
+            // cast CURRENT_MESSAGE to our time struct to conveniently fetch
+            // out the current time
+            WALL_TIME.raw = ((struct init_time*)(&CURRENT_MESSAGE))->cur_raw_time;
+            WALL_TIME.initialized = 1;
+            CURRENT_MESSAGE.id = 0;
+            break;
+
+          default:
+            // no-op -- actually means main loop will handle it
+            break;
+        }
+      }
+    }
+  }
+}
+
+
+/* Dumps the full state of the system for the other side to peruse. Because we dump our state
+ * periodically, we don't need to worry about responding to commands -- the other side can
+ * just monitor for changes in state.
+ */
+void dump_state() {
+  Serial.print("current_time=");
+  Serial.print(WALL_TIME.hours, DEC);
+  Serial.print(":");
+  if (WALL_TIME.minutes < 10)
+    Serial.print("0");
+  Serial.print(WALL_TIME.minutes, DEC);
+  Serial.print(":");
+  if (WALL_TIME.seconds < 10)
+    Serial.print("0");
+  Serial.println(WALL_TIME.seconds, DEC);
+
+  // TODO
+
+  Serial.println("");
+}
+
+
+/*
+ * Pumps the system wall clock. This checks the device's monotonic clock to
+ * determine elapsed time since last invocation, and updates wall clock time
+ * by dead reckoning. Since the device has no battery backup, a power-off will
+ * lose the current time, so timekeeping cannot begin until an INIT_TIME
+ * message is received. (The pump_message_processor() function handles that.)
+ *
+ * Once timekeeping is underway, current time is exposed to user/app code via
+ * the WALL_TIME object, which has 24-hour HH/MM/SS fields.
+ */
+void pump_clock() {
+  static uint32_t prev_millis = 0;
+  uint32_t tmp = 0;
+
+  if (WALL_TIME.initialized) {
+    tmp = millis() / 1000;
+    if (tmp != prev_millis) {
+      prev_millis = tmp;
+      WALL_TIME.raw++;
+    }
+    WALL_TIME.seconds = WALL_TIME.raw % 60;
+    WALL_TIME.minutes = (WALL_TIME.raw / 60) % 60;
+    WALL_TIME.hours = (WALL_TIME.raw / (60 * 60)) % 24;
+  }
+}
+
+
+/*
+ * Standard Arduino setup hook.
+ */
+void setup() {
+  Serial.begin(115200);
+}
+
+
+/*
+ * Standard Arduino loop-pump hook.
+ */
+void loop() {
+  static uint16_t last_id = 0;
+
+  // pump the clock and message processor
+  pump_clock();
+  pump_message_processor();
+  
+  // ignore any "system" messages (those with ID == 0) but dispatch app messages
+  if ((last_id != CURRENT_MESSAGE.id) && (CURRENT_MESSAGE.id != 0)) {
+    handle_current_message();
+  }
+  last_id = CURRENT_MESSAGE.id;
+}
diff --git a/apps/CtsVerifier/arduino-helper/pulsedtr.py b/apps/CtsVerifier/arduino-helper/pulsedtr.py
new file mode 100644
index 0000000..887700f
--- /dev/null
+++ b/apps/CtsVerifier/arduino-helper/pulsedtr.py
@@ -0,0 +1,27 @@
+# Copyright 2010 The Android Open-Source Project
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+
+import serial
+import time
+import sys
+
+if len(sys.argv) != 2:
+    print "Please specify a port, e.g. %s /dev/ttyUSB0" % sys.argv[0]
+    sys.exit(-1)
+
+ser = serial.Serial(sys.argv[1])
+ser.setDTR(1)
+time.sleep(0.25)
+ser.setDTR(0)
+ser.close()