UART Daisy Chain: Expert Debugging With The ODROID-C2

UART Daisy Chain

This article explains how to use multiple UART ports on ODROID-C2 running the Android OS. We will use 3 UART ports and create a data flow called a Daisy Chain. The basic flow of data is out from TX of UART 1 into RX of UART 2 then going to TX UART 2, which will send the data to RX of UART 3. Once RX of the UART 3 receives the data is send it out of UART 3’s TX back to UART 1 RX. For this you need to use the latest Android 6.0.1 image version 3.6 or higher to use 3 UART ports simultaneously.

Figure 1 - Annotated schematic of an ODROID-C2
Figure 1 – Annotated schematic of an ODROID-C2

Hardware

Before starting there are a few things that need to be done. First, download the Fritzing diagram at https://goo.gl/Q1YhP3. Check the J2 2×20 pin layout at https://goo.gl/44XGpB.

PORT

PIN

TX

RX

UART_A (ttyS1) 8 10
UART_B (ttyS2) 3 5
UART_C (ttyS3) 32 26

Software

You need to modify the Device Tree file to enable UART_B(ttyS2) and UART_C(ttyS3) since stock Android uses it for other purpose like GPIO/I2C.

Disable I2C

 $ diff --git a/arch/arm64/boot/dts/meson64_odroidc2.dts b/arch/arm64/boot/dts/meson64_odroidc2.dts
 index e6a25b0..db09b04 100755
 --- a/arch/arm64/boot/dts/meson64_odroidc2.dts
 +++ b/arch/arm64/boot/dts/meson64_odroidc2.dts
 @@ -813,18 +813,6 @@

};

-&i2c_a {
 - status = "okay";
 -
 - /* Hardkernel I2C RTC */
 - pcf8563: pcf8563@51 {
 - status = "disabled";
 - compatible = "nxp,pcf8563";
 - reg = <0x51>;
 - #clock-cells = <0>;
 - };
 -};
 -
&i2c_b {
 status = "okay";

Add UART_B and UART_C definitions

The kernel/arch/arm64/boot/dts/meson64_odroidc2.dts file can be found at https://goo.gl/Y7c5Wr, as shown below:

$ diff --git a/arch/arm64/boot/dts/meson64_odroidc2.dts b/arch/arm64/boot/dts/meson64_odroidc2.dts
 index e6a25b0..fd41552 100755
 --- a/arch/arm64/boot/dts/meson64_odroidc2.dts
 +++ b/arch/arm64/boot/dts/meson64_odroidc2.dts
 @@ -31,6 +31,8 @@
aliases {
 serial0 = &uart_AO;
 serial1 = &uart_A;
 + serial2 = &uart_B;
 + serial3 = &uart_C;
};

gpu_dvfs_tbl: gpu_dvfs_tbl {
 @@ -459,6 +461,32 @@
 pinctrl-0 = <&a_uart_pins>;
};

+ uart_B: serial@c11084dc {
 + compatible = "amlogic, meson-uart";
 + reg = <0x0 0xc11084dc 0x0 0x18>;
 + interrupts = <0 75 1>;
 + status = "okay";
 + clocks = <&clock CLK_XTAL>;
 + clock-names = "clk_uart";
 + fifosize = < 64 >;
 + pinctrl-names = "default";
 + pinctrl-0 = <&b_uart_pins>;
 + resets = <&clock GCLK_IDX_UART1>;
 + };
 +
 + uart_C: serial@c1108700 {
 + compatible = "amlogic, meson-uart";
 + reg = <0x0 0xc1108700 0x0 0x14>;
 + interrupts = <0 93 1>;
 + status = "okay";
 + clocks = <&clock CLK_XTAL>;
 + clock-names = "clk_uart";
 + fifosize = < 64 >;
 + pinctrl-names = "default";
 + pinctrl-0 = <&c_uart_pins>;
 + resets = <&clock GCLK_IDX_UART2>;
+ };
+
canvas {
 compatible = "amlogic, meson, canvas";
 dev_name = "amlogic-canvas";

Compile dts to dtb

Meson64_odroidc2.dtd file can be downloaded at https://goo.gl/qha1vx, as shown below:

$ make odroidc2_[i2c_]defconfig
 KBUILD_CFLAGS_MODULE:-DMODULE
#
# configuration written to .config
#

#### make completed successfully ####

[~/projects/c2/marshmallow/kernel]$ make dtbs
 KBUILD_CFLAGS_MODULE:-DMODULE
 KBUILD_CFLAGS_MODULE:-DMODULE
 scripts/kconfig/conf --silentoldconfig Kconfig
 KBUILD_CFLAGS_MODULE:-DMODULE
 WRAP arch/arm64/include/generated/asm/bug.h
 WRAP arch/arm64/include/generated/asm/bugs.h
 WRAP arch/arm64/include/generated/asm/checksum.h
 WRAP arch/arm64/include/generated/asm/clkdev.h
 WRAP arch/arm64/include/generated/asm/cputime.h
 WRAP arch/arm64/include/generated/asm/current.h
 WRAP arch/arm64/include/generated/asm/delay.h
 WRAP arch/arm64/include/generated/asm/div64.h
 WRAP arch/arm64/include/generated/asm/dma.h
 WRAP arch/arm64/include/generated/asm/emergency-restart.h
 WRAP arch/arm64/include/generated/asm/early_ioremap.h
 WRAP arch/arm64/include/generated/asm/errno.h
 WRAP arch/arm64/include/generated/asm/ftrace.h
 WRAP arch/arm64/include/generated/asm/hw_irq.h
 WRAP arch/arm64/include/generated/asm/ioctl.h
 WRAP arch/arm64/include/generated/asm/ioctls.h
 WRAP arch/arm64/include/generated/asm/ipcbuf.h
 WRAP arch/arm64/include/generated/asm/irq_regs.h
 WRAP arch/arm64/include/generated/asm/kdebug.h
 WRAP arch/arm64/include/generated/asm/kmap_types.h
 WRAP arch/arm64/include/generated/asm/kvm_para.h
 WRAP arch/arm64/include/generated/asm/local.h
 WRAP arch/arm64/include/generated/asm/local64.h
 WRAP arch/arm64/include/generated/asm/mman.h
 WRAP arch/arm64/include/generated/asm/msgbuf.h
 WRAP arch/arm64/include/generated/asm/mutex.h
 WRAP arch/arm64/include/generated/asm/pci.h
 WRAP arch/arm64/include/generated/asm/poll.h
 WRAP arch/arm64/include/generated/asm/posix_types.h
 WRAP arch/arm64/include/generated/asm/resource.h
 WRAP arch/arm64/include/generated/asm/scatterlist.h
 WRAP arch/arm64/include/generated/asm/sections.h
 WRAP arch/arm64/include/generated/asm/segment.h
 WRAP arch/arm64/include/generated/asm/sembuf.h
 WRAP arch/arm64/include/generated/asm/serial.h
 WRAP arch/arm64/include/generated/asm/shmbuf.h
 WRAP arch/arm64/include/generated/asm/simd.h
 WRAP arch/arm64/include/generated/asm/sizes.h
 WRAP arch/arm64/include/generated/asm/socket.h
 WRAP arch/arm64/include/generated/asm/sockios.h
 WRAP arch/arm64/include/generated/asm/switch_to.h
 WRAP arch/arm64/include/generated/asm/swab.h
 WRAP arch/arm64/include/generated/asm/termbits.h
 WRAP arch/arm64/include/generated/asm/termios.h
 WRAP arch/arm64/include/generated/asm/topology.h
 WRAP arch/arm64/include/generated/asm/trace_clock.h
 WRAP arch/arm64/include/generated/asm/types.h
 WRAP arch/arm64/include/generated/asm/unaligned.h
 WRAP arch/arm64/include/generated/asm/user.h
 WRAP arch/arm64/include/generated/asm/vga.h
 WRAP arch/arm64/include/generated/asm/xor.h
 WRAP arch/arm64/include/generated/asm/preempt.h
 WRAP arch/arm64/include/generated/asm/hash.h
 WRAP arch/arm64/include/generated/uapi/asm/kvm_para.h
 HOSTCC scripts/dtc/checks.o
 HOSTCC scripts/dtc/data.o
 SHIPPED scripts/dtc/dtc-lexer.lex.c
 SHIPPED scripts/dtc/dtc-parser.tab.h
 HOSTCC scripts/dtc/dtc-lexer.lex.o
 SHIPPED scripts/dtc/dtc-parser.tab.c
 HOSTCC scripts/dtc/dtc-parser.tab.o
 HOSTCC scripts/dtc/dtc.o
 HOSTCC scripts/dtc/flattree.o
 HOSTCC scripts/dtc/fstree.o
 HOSTCC scripts/dtc/livetree.o
 HOSTCC scripts/dtc/srcpos.o
 HOSTCC scripts/dtc/treesource.o
 HOSTCC scripts/dtc/util.o
 HOSTLD scripts/dtc/dtc
 CC scripts/mod/empty.o
 HOSTCC scripts/mod/mk_elfconfig
 MKELF scripts/mod/elfconfig.h
 CC scripts/mod/devicetable-offsets.s
 GEN scripts/mod/devicetable-offsets.h
 HOSTCC scripts/mod/file2alias.o
 HOSTCC scripts/mod/modpost.o
 HOSTCC scripts/mod/sumversion.o
 HOSTLD scripts/mod/modpost
 HOSTCC scripts/selinux/genheaders/genheaders
 HOSTCC scripts/selinux/mdp/mdp
 HOSTCC scripts/kallsyms
 HOSTCC scripts/pnmtologo
 HOSTCC scripts/conmakehash
 HOSTCC scripts/bin2c
 HOSTCC scripts/recordmcount
 HOSTCC scripts/sortextable
 DTC arch/arm64/boot/dts/meson64_odroidc2.dtb
 Warning (reg_format): "reg" property in /spi-gpio/spi-gpio@0 has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
 Warning (avoid_default_addr_size): Relying on default #address-cells value for /spi-gpio/spi-gpio@0
 Warning (avoid_default_addr_size): Relying on default #size-cells value for /spi-gpio/spi-gpio@0

#### make completed successfully (4 seconds) ####

Install modified dtb file

$ sudo fastboot flash dtb \
 out/target/product/odroidc2/obj/KERNEL_OBJ/arch/arm64/boot/dts/meson64_odroidc2.dtb
You have to edit /storage/internal/boot.ini file to load alternative Kernel image. There is an alternative kernel image to use the I2C pins for UART function.
# movi read boot 0 ${loadaddr}
fatload mmc 0:1 ${loadaddr} Image_android

Edit ueventd.odroidc2.rc

Change the permission of ttyS2 and ttyS3 for system access.

shell@odroidc2:/ $ su
root@odroidc2:/ # mount -o rw,remount /
[ 1243.002784@2] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
root@odroidc2:/ # vi /ueueventd.odroidc2.rc ueventd.rc
root@odroidc2:/ # vi /ueventd.odroidc2.rc

/dev/ttyS* 0666 system system

Set-up Android app example code

Download the WiringPi NDK library at https://goo.gl/uuDeys, and the App source code Project from GitHub at https://goo.gl/YNXTUn.

$ sudo apt install git
$ git clone https://github.com/codewalkerster/example-wiringPi -b odroid-c_3_uart
Figure 2 - wire connection for three daisy-chained UART ports
Figure 2 – wire connection for three daisy-chained UART ports

Figure 3 - Test the daisy-chained UART by typing a string
Figure 3 – Test the daisy-chained UART by typing a string

Figure 4 - Results of the daisy-chained UART test
Figure 4 – Results of the daisy-chained UART test

For comments, questions and suggestions, please visit the original post at https://goo.gl/jteQuV.

Be the first to comment

Leave a Reply