GLM Capture 2.2 - Raspberry Pi Pico 2 firmware for reading the Genelec GLM RS-485 bus
=====================================================================================

Notice
------
This is not a product of Genelec Oy. It is a personal hobby project by Pasi Vähämartti.
More information: blog.vahamartti.fi

What it does
------------
The firmware listens to the GLM bus (RS-485, 287700 baud, 9 data bits, no parity, 2 stop
bits, 9N2) and sends every complete frame to the PC over USB as one line of text. It only
listens: nothing is ever sent to the bus. There is no display and no menu.

The Pico 2 does the work with both of its cores. A PIO state machine reads the 9N2 bits
(the Pico's UART cannot do 9 data bits). Core 1 only receives: it empties the PIO FIFO,
removes the HDLC escapes, assembles the frames and stores them with a time stamp and a
sequence number in a ring buffer. Core 0 formats the frames as text and sends them over USB.


What you need
-------------
- Raspberry Pi Pico 2 (RP2350).
- A TTL to RS-485 module with a 3.3 V capable transceiver, for example a MAX3485 module.
- A cable or connector for the GLM bus (the bus uses RJ-45 connectors, but it is not Ethernet).
- A USB cable and a Windows PC. No programming tools are needed.


Wiring
------
Receive only. The Pico reads one pin, GP1.

  RS-485 module            connect to
  ---------------------    --------------------------------------------
  VCC                      Pico 3V3 (3.3 V, not 5 V)
  GND (TTL side)           Pico GND
  TXD (receive output)     Pico GP1
  RXD (transmit input)     not connected
  D+ / A                   GLM bus RJ-45 pin 1 (A, D+)
  D- / B                   GLM bus RJ-45 pin 2 (B, D-)
  GND (RS-485 side)        not connected  (RJ-45 pin 8, the bus ground, is not connected)

Notes
- Power the module from 3.3 V. At 5 V the module's receive output would be a 5 V signal,
  which does not suit the Pico's GPIO pin.
- The names TXD and RXD on these modules are from the microcontroller's point of view:
  TXD is the data coming out of the module, RXD is the input for data to be transmitted.
- Leave the module's transmit input (RXD) unconnected. In the original build, connecting it
  to ground disturbed the bus (probably a ground loop).
- The module is used as the last device on the line, so the 120 ohm termination is only at
  the transmitting end of the bus. No termination was added at the receiver and the setup
  works without problems in a ten-speaker system. Many modules have an optional built-in
  120 ohm resistor (for example a solder jumper); leave it off unless you have a reason.
- Check the pin names printed on your own module before wiring. They differ between makers.


Putting the firmware on the Pico 2
-----------------------------------
The firmware is delivered as a ready-made UF2 file, glm_capture.UF2 (in this package).
No programming tools are needed.

1. Unplug the Pico 2 from the USB cable.
2. Hold down the BOOTSEL button on the Pico 2 and, while holding it, plug the USB cable
   into the PC. Release the button. The Pico appears on the PC as a USB drive named RP2350.
3. Copy glm_capture.UF2 onto that drive (drag and drop, or copy and paste).
4. The drive disappears and the Pico restarts by itself. The firmware is now installed.

After this the Pico shows up as a serial port (a COM port on Windows) every time it is
plugged in. To update the firmware later, repeat the steps above with the new file.

The firmware is for the Raspberry Pi Pico 2 (RP2350) only. It does not run on the original
Raspberry Pi Pico (RP2040).


Reading the data
----------------
Any terminal program that can open a serial port works, for example PuTTY.

PuTTY settings
  Connection type: Serial
  Serial line:     the Pico's COM port (see Windows Device Manager, "Ports (COM & LPT)")
  Speed:           115200 (any value; the data goes over USB, so the speed has no effect)
  Connection > Serial: Data bits 8, Stop bits 1, Parity None, Flow control None

Flow control must be None. PuTTY then turns the DTR line on, and the firmware only collects
frames while the USB port is open (DTR high). With any other flow control setting the screen
stays empty.

To save the data, choose Session > Logging > "All session output" and give a log file name,
for example glm_&Y&M&D_&T.txt (the date and time are added to the name).

Only one program can have the serial port open at a time.

Note: the computer and the Genelec GLM application must be running. Without them the bus
carries only the volume information (from the hub, for example when you turn the volume knob
or use the remote control). The other traffic, such as the polling and the replies from the
speakers, appears only while the GLM software is running and talking to the system.


Output format
-------------
One text line per item, CR/LF terminated.

  # glm-capture fw=2.2 baud=287700 fmt=9N2 t=<us>
      Sent once when the port is opened.

  @<us>,<seq> <addr> <cmd> <data...> <crc hi> <crc lo> 07E
      One frame with the HDLC escapes removed.
        <us>   time of the closing 07E in microseconds since the Pico was started
        <seq>  sequence number of the frame; a gap means that frames were lost
      Words are three hexadecimal digits: the first (9 bit) word is the address (1xx),
      the last is the end flag 07E. Example:
        @12345678,89 101 009 05D 0E7 07E

  # stat t=<us> seq=<n> drop=<n> ovf=<n> stall=<n> esc=<n> long=<n> trunc=<n> stray=<n>
      Loss and error counters, every second when something has changed, otherwise every 5 s.
        drop   frames lost because the USB queue was full
        ovf    words lost because the word ring was full
        stall  PIO FIFO overruns
        esc    frames discarded: invalid HDLC escape
        long   frames discarded: longer than 255 bytes
        trunc  frames abandoned: a new address word arrived before 07E
        stray  words received outside a frame (ignored)

The CRC is not checked in the firmware. It is CRC-16/GSM over the address low byte and the
payload; the last two data words before 07E are the CRC.


Status LED
----------
The on-board LED flashes briefly for every frame received. A slow blink means that no
frames have been seen for three seconds: check the wiring, the A/B polarity and that the
GLM system is on.


If nothing appears
------------------
- No lines at all: check the COM port number and that Flow control is None.
- Only "# glm-capture" and "# stat" lines, but no frames: the bus is not reaching the Pico.
  Check the A and B wires (try swapping them), the 3.3 V supply of the module and that the
  Pico's GP1 is connected to the module's TXD pin.
- Frames with a gap in the sequence number or growing "drop" counters: the PC or the USB
  connection is not keeping up. Use a USB port directly on the PC.


Using the log
-------------
The captured lines can be opened in GLM Bus Monitor (Windows) or pasted into the online GLM
decoder, which describes each frame (command, speaker address, values):
  https://vahamartti.fi/filut/glm_decoder_en.html
The meaning of the frames is documented in the GLM bus decoding guide.


Version
-------
Firmware 2.2. The data format is unchanged; any program that reads the lines above works
with it.

Bus rate note
-------------
The bus rate was measured with GLM Baud Measure 1.0 at 287.6-287.8 kbaud (a nominal
288000 baud request divided down from the speaker clock; USARTDIV 9.125 at 42 MHz gives
287671 baud). Earlier versions of this text said 296000 baud, which was an oscilloscope
misreading. The receiver samples eight times per bit, so both values decode without errors.
