Skip to content

Firmware Internals

This section documents the internal architecture of the RS-UV3 V2.4a firmware, derived from reverse engineering the original HEX file using Ghidra and gputils.

PropertyValue
Version2.4a
MCUPIC18F46J11-I/PT
PackageTQFP-44
Flash64KB (36,296 bytes used)
RAM3,776 bytes
ClockInternal oscillator, 8 MHz
Voltage3.3V

The firmware handles:

  • Serial command parsing (66 commands across two dispatchers)
  • I2C communication with the RDA1846S transceiver chip
  • EEPROM storage for channel memories and configuration
  • CTCSS/DCS tone encoding and decoding
  • CW and DTMF generation
  • Beacon timing and transmission
┌─────────────────────────────────────────────────────────────┐
│ Main Loop (0x000400) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Check UART │→ │ Parse Cmd │→ │ Dispatch A or B │ │
│ │ RX Buffer │ │ 2-char code │ │ based on 1st char │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌───────────────┴───────────────┐
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────┐
│ Dispatcher A (0x0042b0) │ │ Dispatcher B (0x005972) │
│ 5,826 bytes │ │ 10,632 bytes │
│ ────────────────────────│ │ ────────────────────────│
│ PD, PW, RC, RR, RS │ │ AF, AI, AO, B1, B2... │
│ ST, CP, FD, BL │ │ (bulk of commands) │
└──────────────────────────┘ └──────────────────────────┘
│ │
└───────────────┬───────────────┘
┌──────────────────────────────┐
│ Hardware Abstraction Layer │
│ ─────────────────────────── │
│ • I2C to RDA1846S (synth) │
│ • EEPROM read/write │
│ • UART TX/RX │
│ • ADC for RSSI, temp, volts │
└──────────────────────────────┘
RegionAddressSizePurpose
Reset vector0x0000004BJump to init
High-priority ISR0x00000816BSerial RX entry
Low-priority ISR0x000018874BTimers, buffers
Init + Main0x0004002,098BSetup and event loop
Dispatcher A0x0042b05,826BMemory/power commands
Dispatcher B0x00597210,632BRadio config commands
String tables0x008B38~1,800BResponse strings
Total code36,296B55% of 64KB flash

The reverse engineering was performed with:

ToolVersionPurpose
Ghidra12.0.1PIC-18 decompilation, cross-reference analysis
GhydraMCPGhidra integration for Claude Code
gputils1.5.2gpdasm disassembly, gpasm reassembly
objcopy2.45.1Intel HEX to raw binary conversion
Python 3Annotation scripts (annotate.py, c-port.py)

All reverse-engineered assembly was verified byte-identical to the original firmware:

Terminal window
# Convert both to raw binary and compare
objcopy -I ihex -O binary reassembled.hex /tmp/verify.bin
cmp original.bin /tmp/verify.bin
# Output: (no output = identical)

This verification runs automatically via make verify in the source directory.

  • Command Dispatch — How the firmware parses and routes serial commands
  • Memory Map — RAM variables, EEPROM layout, and register definitions
  • I2C & Synthesizer — Communication with the RDA1846S transceiver chip
  • Source Files — Annotated assembly, C port, and analysis tools