Talking to the DM16L, and receiving a dump
Table of Contents
I built swiss_micros_tools because I was tired of keeping a serial terminal open just to poke a SwissMicros
calculator. 1.8.12 is the release where that stops being a plan for the receive path. The clock was already done. The
dump now is too.
This note is the bench for that release. The short announcement is the door. Here I write down how I actually open the
port, why macOS needed its own body, and which lines dm_receive keeps.
What I plug in #
The USB console is 38400 8N1, no flow control. On the calculator I enter SERIAL CONSOLE mode with C+ON. The host
sees a CP2102N. On macOS and Linux the POSIX helpers find a DM16L:
export DM_SERIAL_DEVICE="$(dm-get-serial-device.sh)"
Windows takes the port name the same way. Every tool accepts -d / --device, or DM_SERIAL_DEVICE if I would rather
not repeat the path. Help is -? or --help.
The shared dialogue lives in Console_IO. A blank line wakes the console. The Voyager prompt comes back doubled —
VOYAGER >> twice — and the verbs I use are ts, t, s and, later, l.
Either end may speak first #
I used to treat the start order as a ritual which I sadly failed all to often: calculator first, then the host, then hope the prompt had already arrived. That is a terminal habit, not a requirement of the protocol.
1.8.12 does not care which side I start as long as it happens within a minute. I can export the device and launch the
tool, then hold C and press ON. Or I can already be sitting at the VOYAGER >> prompt when the programme opens the
port. The wake-up line and the prompt handshake cover both. I checked this with dm_set_time on the DM16L: the clock is
set whichever end I start.
export DM_SERIAL_DEVICE="$(dm-get-serial-device.sh)"
dm_set_time-main
Omit the stamp and the tool uses the host clock. Pass a compact stamp and it sends eight digits, a space, six digits —
YYYYMMDD HHMMSS. That is not the line t prints back (2026-09-22 18:09:26 TUE). --utc / -u sends UTC instead of
local time.
Why macOS needed its own body #
Linux and Windows had been talking to the calculator for a while. macOS had not, and the fault was not the DM16L.
Darwin’s termios is its own record: unsigned long flags, no c_line, c_cc running 0 .. 19, VMIN at 16 and
VTIME at 17. I had been treating that record as if it were the Linux one.
AdaCL.Serial_Communications now has its own Darwin spec and body, under src/macos. No GPR __suffix body.
Data_Rate_Value is an unsigned long. I dropped C_Data_Rate: the old OSC rates above B230400 are
16#FFFF_FFFF#, not a speed I can send.
The exception on macOS is a distinct AdaCL.Serial_Communications.Serial_Error. On Linux and Windows that name renames
GNAT.Serial_Communications.Serial_Error. Callers, and GNATdoc, name the AdaCL exception on all three systems.
With that body in place the same binary finds the DM16L. Same cable, same CP2102N, same 38400 8N1.
dm_receive keeps the lines the decoder wants #
s already dumps RAM. The useful part is short: a model banner, the register rows, and the A / B / C / S / M
/ N / G line at the end. The doubled prompt, the help text and the uptime line are conversation. I was selecting the
block by hand, and I kept missing a line or keeping one I did not want.
dm_receive opens the port, sends s, and writes only that block. No terminal session, no paste.
export DM_SERIAL_DEVICE="$(dm-get-serial-device.sh)"
dm_receive-main
Same device option as dm_set_time. Same either-way start. The file that comes back is the block the programming
tool already expects on the left-hand side, from the model line
through the register line. A DM16 dump looks like this once the chatter is gone:
DM16_MC0
00 00000000000043 0000000000000e 0000000000000e 0000000000000e
04 f0000002800000 f0000002800030 822f00000ff000 eae00000000000
08 00000000000000 00000000001000 cc0280fce40080 00000000000000
c0 03200000000001 00000000000000 00000000000000 00000000000000
c4 00000000000000 00000000000034 00000000000000 00000000000000
fc 00000000000000 00000000000001 00000000000000 00000000000000
A: f0000002800000 B: 00000000000eae C: eae00000000000
S: 00000000000000
M: 1c000000000000 N: 0000000000001c G: 03
I do not keep VOYAGER >>, and I do not keep the help text. Those lines are how the console talks. They are not the
dump.
dm_send is still the missing half. I can pull a dump. I cannot yet push one back without a terminal. The verb is
already l. The tool is not written yet.
Where the rest of the bench is #
The workshop door is Swiss Micros Tools. The clock dialogue, which this tool reuses, is the dm_set_time packages. Generated reference is GNATdoc. Sources are on the master branch.