Skip to content

Tag: rs485

Low Cost Localtalk to Ethernet Bridge (AKA low-end embedded Linux) – Part 2 OpenWRT MIPS

In the previous post I looked at the aims of the project and the shortlisted hardware. This post will explore OpenWRT and bringing it up on the HLK-7621 Evaluation Board.


This is a series of blog posts exploring how embedded Linux works (especially OpenWRT) to build an Apple LocalTalk to Ethernet bridge. This is the second part, in what I plan to be a small series of posts.

The HLK-7621 is built as a router module. It comes pre-installed with what looks like a MediaTek version build of OpenWRT. It is already supported by OpenWRT so the work needed to bring things up is minimal.

I was able to download a pre-compiled Sysupgrade from OpenWRT and "upgrade" the firmware to the current snapshot version OpenWRT out of the box!

By default, OpenWRT will bring up a bridge LAN containing the switch ports and eth0 on 192.168.1.1. It will also run a DHCP server. This is probably not what you want out of the box. To change the interface we'll need to either change our IP, or use the serial console to set the IP address manually.

The evaluation board has a CH340 onboard to provide console access. J4 on the board allows the selection of RX/TX each UART to be connected to the CH340, which is a nice touch. Out of the box it is jumpered to UART0, which is how OpenWRT is configured. All we need to do is plug a micro-USB cable in and we can get console access.

Terra-term bootup

Once in we can set the IP Address of the device. I used 192.168.0.21. We can use uci to configure out IP address and disable DHCP.

uci set network.lan.proto="static"
uci set network.lan.ipaddr="192.168.0.21"
uci set network.lan.netmask="255.255.255.0"
uci set network.lan.gateway="192.168.0.1"
uci set network.lan.dns="8.8.8.8"
uci commit network
uci set dhcp.lan.ignore="1"
uci commit dhcp
service network restart

With this we can log SSH into the device, or log in the Luci web-UI.

Time to UART

For my aim of building a LocalTalk adaptor I need to use one of the extra UARTs on the MT7621.

Easy peasy right? I installed a dumb-terminal emulator:

$ apk add picocom

... and ran it:

$ picocom /dev/ttyS1
picocom v3.1

port is        : /dev/ttyS1
flowcontrol    : none
baudrate is    : 9600
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
hangup is      : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv -E
imap is        :
omap is        :
emap is        : crcrlf,delbs,
logfile is     : none
initstring     : none
exit_after is  : not set
exit is        : no

FATAL: failed to add port: Cannot get the device attributes: I/O error

I tried each tty device, just in case it was weirdly mapped with no luck. It was as if the UARTs just weren't there.

Customising the device tree

I checked the datasheet and saw the following page on "Pin Sharing":

MT7621 Datasheet on PinSharing

UART 2 & 3's pins can either be set as a UART or GPIO. But where is it set? Checking OpenWRT's device Tech Data page there's a link to the commit which added support for the board.

The commit had two files: a make file and a DTS file. The DTS file turns out to be a device tree definition file.

A device tree is a data structure that describes the hardware components of an embedded system, allowing the kernel to dynamically configure itself to work with the specific hardware present on a given board. It provides a standardized way to describe hardware, decoupling hardware configuration from the kernel source code.

In this case, the DTS file described the buttons, SPI Flash Layout, labelled the WAN port, configured the switch and PCIE adaptor support. What it didn't show was how the UARTS are configured!

However, the it looks like the device tree can be inherited from other trees. In this case, the MT7621 device tree. Looking through I could see the UART configuration, so why didn't it work?

UART Definitions

I needed to know more about device trees, and stumbled upon this excellent guide to Device Trees by Yasir Khan.

Enabling/disabling a device
To enable/disable a device, the status property inside a devicetree node is used.

To enable a device, it should be set as status = "okay"
To disable a device, it should be set as status = "disabled"

Could it be that simple?

I pulled the code for OpenWRT and followed the build setup and build system instructions.

I then modified the HLK-7621 DTS file and added:

&uartlite2 {
    status = "okay";
};

&uartlite3 {
    status = "okay";
};

I rebuilt the image and uploaded the sysupgrade to the device! After resetting the IP address I re-added picocom and tried again.

$ picocom /dev/ttyS1
picocom v3.1

port is        : /dev/ttyS1
flowcontrol    : none
baudrate is    : 9600
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
hangup is      : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv -E
imap is        :
omap is        :
emap is        : crcrlf,delbs,
logfile is     : none
initstring     : none
exit_after is  : not set
exit is        : no

Type [C-a] [C-h] to see available commands
Terminal ready

Success! I jumpered the RX and TX together on the board, and had my text echoed back to me.

One thing I didn't know was whether I could connect at the 1 megabaud needed for TashTalk. The datasheet suggests a maximum baud rate of 345,600 baud.

Only one thing to try:

$ picocom --baud 1000000 /dev/ttyS1
picocom v3.1

port is        : /dev/ttyS1
flowcontrol    : none
baudrate is    : 1000000
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
hangup is      : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv -E
imap is        :
omap is        :
emap is        : crcrlf,delbs,
logfile is     : none
initstring     : none
exit_after is  : not set
exit is        : no

Type [C-a] [C-h] to see available commands
Terminal ready

Success! I also tried connecting UART2 & 3 together and was able to send characters to each other without issue at 1,000,000 buad.

Hooking up TashTalk

The great thing about TashTalk is it's simplicity. It is really just a PIC, an RS485 bus transeiver and a couple of passives.

TashTalk Breadboard.

TashTalk Breadboard connected to the HLK-7621

I grabbed the latest hex file and flashed it on to the PIC with a PikKit (don't forget to set the circuit voltage option!), and put it together on a breadboard. I connected it a Mac Classic and to the UART and CTS pins on the HLK-7621.

I installed Python on to OpenWRT:

$ apk add python3`

and copied over tashtalkd from the Tashtalk repo to /tmp.

I crossed my fingers and ran the code:

$ python3 tashtalkd --device /dev/ttyS1

I ran a LToUTP build of Mini vMac and opened chooser on the Mac Classic.

A Macintosh Classic running System 6 showing Chooser and a mounted share from an emulated System 7 machine. The machine is connected via TashTalk to the emulated Macintosh.

Success! 🎉 The Mac Classic is able to see the emulated System 7 machine running under Windows, via TashTalk running on a HLK-7621.

Recap

In this post we:

  1. flashed a device with the latest snapshot of OpenWRT
  2. customised the device tree to enable UART
  3. built and tested a TashTalk

We're not quite building a full bridge yet, but we've validated the hardware and software side can do what we need (at least with this board).

Next Steps

Now that we've got it working on one board, can we get lucky and do the same with the Luckfox Pico Plus?

Leave a Comment