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.
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.dtbYou 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
For comments, questions and suggestions, please visit the original post at https://goo.gl/jteQuV.
Be the first to comment