DM-1801 Pro bring-up checklist
The order to bring the DM-1801 Pro port (make BOARD=dm1801pro) up on a radio, what each step proves, and what to
change when it doesn't work. Steps 0 to 3, 7 and 8 passed on 2026-10-15 (hardware-dm1801pro.md 12). Hardware facts:
hardware-dm1801pro.md.
The feature checklist, with every feature's required HIL tests and the last recorded result, is
tools/bringup.py list --radio dm1801pro. tools/bringup.py run --radio dm1801pro records a run
(tests/hil/README.md). This page keeps the hardware steps and what to
change when one fails.
0. Before anything
- Back up both flashes (1 MB program flash, 16 MB data flash). The port never writes the data flash below 0x700000 and never touches the boot loader, but a backup is the only way back from a mistake.
- Confirm update mode before the first flash: it is the recovery path for every step below. The loader stays in it while
PTT and SK1 are held at power-on (hardware-dm1801pro.md 6.2). Push the cable fully
into the jack, or the loader doesn't answer.
python3 tools/serial_loader.py --model dm1801pro --dry-run IMAGEchecks the image and the cable first. - Flash:
python3 tools/serial_loader.py --model dm1801pro build/dm1801pro/rfoundry_dm1801pro.binover the programming cable. The erase takes about 13 s.rfoundry flash IMAGE --board dm1801prowraps the same tool, and the stub for a radio that runs RadioFoundry withCONFIG_STUB_ENTRY=y(tools/rfoundry/README.md); neither rfoundry route has flashed a radio yet. - The debug link runs on the same cable at 115200 (
RFOUNDRY_PORT=/dev/cu.usbserial-... tools/rfoundry_debug.py diag). The cable's plug switches the internal speaker off: unplug it to listen. - Build:
make BOARD=dm1801pro(csky-elf GCC:tools/build-csky-toolchain.sh).
1. Power and display
| Step | Expect | If not |
|---|---|---|
| Switch on | The radio stays on after the power key is released | Wrong polarity of the power key (PIN_POWER_KEY, power_dm1801pro.c: the level at start-up counts as "on"); wrong latch pin |
| Backlight | Comes on | PIN_LCD_BACKLIGHT |
| Picture | The Home screen, upright and readable | Blank: the controller's init (display_dm1801pro.c, st7567.c); mirrored: seg_reverse / com_reverse; faint or black: contrast, regulator, bias; shifted: col_offset (4) |
| IO mux | The display and the flash both work | io_init in board.c: PTC2-PTC8 must be GPIOs, SPI0's pins on the peripheral |
2. Keys
Open the Diagnostics page (Settings > Diagnostics). The keys line shows the raw scan: matrix bit = strobe x 4 + input
(bits 0-19), the four direct pins in bits 20-23. Press every key in turn and write down the bit. Then fix, in
input_dm1801pro.c: the map table (matrix keys) and direct_keys (PTT, SK1, SK2, SOS). Until then keys are mixed up.
3. Flash, calibration, battery
| Step | Expect | If not |
|---|---|---|
Diagnostics flash |
A JEDEC ID (C84018 GD25Q128, 852018 Puya) |
Chip select, the SPI0 mux, hrc_ssi_init clock |
cal |
factory; the TX center, PA points at 145 and 435 MHz are non-zero |
none: the page tagged 2 wasn't found; compare with a dump (hardware-dm1801pro.md 6.4) |
| Change a setting, switch off and on | It stays | The write floor and flash map in board.c |
bat |
Rises with a full battery; the percentage is close | The ADC divider isn't known: compute the scale from a multimeter and set it in power_dm1801pro.c |
4. FM receive
Tune a known local signal on VHF and UHF. Audio, RSSI (rssi line) and squelch should follow the signal.
| Symptom | Likely cause |
|---|---|
| No audio on either band | The cable is plugged in (it mutes the speaker); PIN_AMP_EN (PTA16) or PIN_SPK_SOURCE (PTB15) |
| Audio on one band only | The path pins' band side is inverted (radio_dm1801pro.c path_pins; hardware-dm1801pro.md 5.5) |
| Wrong frequency or very weak | fd6818_variant_dm1801pro tables, the RF bus speed (RF_BIT_SCALE_US), PIN_RF_CS |
| Narrow / wide swapped | The 12.5 kHz word (bw_fm_12k5, hardware-dm1801pro.md 5.2) |
5. FM transmit
Only with a dummy load or a test set on an allowed frequency. The radio refuses to transmit when the calibration isn't read.
- Key at low power: the carrier is on frequency with no splatter. Check the PA ramp and the TX path pins.
- Compare the three power levels with a meter: L < M < H, the nominal values are hardware-dm1801pro.md 6.4's open item (which level uses which array).
- Deviation and modulation balance with a test set; the modulation byte is read at the calibration page's TX points (hardware-dm1801pro.md 6.4).
- Repeat 1 to 3 on VHF. The
pa 145line shows the VHF drive. No power on VHF while UHF works points at the TX path's VHF side (PTA31, hardware-dm1801pro.md 5.5).
5.1 FM mic gain
The FM mic gain is the board's level for the channel bandwidth (MIC_GAIN_FM_12K5_DB, MIC_GAIN_FM_25K_DB in
boards/dm1801pro/radio_dm1801pro.c) plus the Mic gain setting's offset, (step - 5) x 2 dB
(radio-features.md 3.6). The programming cable cuts the microphone, and no injected
tone passes the mic gain, so every measurement is an over with the cable out. tests/hil/test_mic_gain.py runs the
session: it sets the step and the bandwidth over the debug link, the SDR bench records while you key, and it reads
the step back once the cable is in again.
python3 -m pytest tests/hil/test_mic_gain.py -v -rs -s --manual --allow-rf --fm-mhz MHZ --mic-gain-steps 3,5,7
For each over (3 steps at 12.5 kHz, then at 25 kHz):
- Wait for
=== over N/6: ... ===andGO. The bench records for--mic-gain-windows (30). - Unplug the cable, key PTT, give the same source each time for about 5 s (a steady whistle or a phone playing a 1 kHz tone at a fixed distance, or the same sentence), release PTT, plug the cable back in.
- The test prints sdr_fm_check.py's report and
link back: step S, GCR_ADCL 0xNN.
At the end it prints one row per over: bandwidth, step, offset, GCR_ADCL (bits 5:0 = dB), segment length, voice peak (99.5 %) and rms deviation, and the strongest tone with its deviation. Expect the deviation to rise about 2 dB a step until the deviation limiter. Target with speech: peak about 2.5 kHz at 12.5 kHz and 5 kHz at 25 kHz. Set the two board levels from the step that reaches the target (level = 11 + offset), then rerun at step 5 to confirm.
| If | Check |
|---|---|
| GCR_ADCL doesn't follow the step | set.mic_gain_board=1 in the features view; the FM transmit start writes the register (tx()) |
| No keyed segment | PTT pressed inside the window; the capture under ~/<bench dir>/hil_mic_gain_N/ |
| The same deviation at every step | the limiter (DEV_LIMITER) clips: try lower steps; or the gain isn't in the path the microphone takes |
6. Broadcast FM and air band
6.1 Broadcast FM tuner
Tune the VFO into the broadcast band (airband-and-broadcast.md 4).
tests/hil/test_listen_bands.py checks the view keys without keying.
| Step | Expect | If not |
|---|---|---|
| VFO to 100.1 MHz | bcast=1, bcast_fault=0 in the view: the chip answers at 0x11 with ID 0x58 |
bcast_fault=1: PIN_BCAST_EN polarity, PIN_BCAST_SDA / PIN_BCAST_SCL, the I2C speed (half_us), the reference clock mode (clk_mode), all in platform/hrc7000/bcast_hrc.c and the board's hrc_bcast_cfg_t |
| A local station | Audible; the signal meter moves; the knob steps 200 kHz on the odd tenths | The tuner's audio route; the amplifier (PIN_AMP_EN) is shared with the channel audio |
| Squelch 9 on a weak station | Still plays (broadcast audio ignores the squelch); the green LED stays on | The squelch threshold (RADIO_BCAST_SQL_REF) |
| Scan a zone of broadcast channels | Stops on stations, quiet between them | The squelch threshold |
| PTT | "Broadcast: receive only", nothing keys | The core's refusal |
6.2 Air band AM
| Step | Expect | If not |
|---|---|---|
| VFO to the local ATIS | am=1, "Air Band AM" on Home, AM audio |
FD6818 0x47 (AF type, fd6818_set_am), the AGC and filter (airband-and-broadcast.md 2, 3.3) |
| PTT | "Air band: receive only", nothing keys | The core's refusal |
7. Accelerometer
The diagnostics page has an acc line: x, y and z in milli-g. Lay the radio flat: z reads about +1000 or -1000 and x
and y near 0; tilt it and the values follow. accel none means the chip didn't answer: check PIN_ACCEL_SCL /
PIN_ACCEL_SDA and the address (ACCEL_ADDR in accel_dm1801pro.c; 0x18 if the chip's address pin is low). accel id NN means the chip answered with an ID the driver doesn't accept (this radio's SC7A20 reads 0x11).
8. Vibration motor
The radio vibrates for about 0.3 s when it powers on. No pulse: put a meter on PTB24 (PIN_VIBRATION); if the pin moves
and the motor doesn't, the pin isn't the motor driver (hardware-dm1801pro.md 8 is inferred, no label names it).
9. DMR
DMR is built (CONFIG_DMR), without voice. Do this after FM receive and transmit work. The Diagnostics page starts with the
DMR counters.
| Step | Expect | If not |
|---|---|---|
| Select a DMR channel on a local repeater or hotspot | tk (ticks) climbs by about 33 a second, ts interrupts count up |
No ticks: the modem never got timing; check the DMR mode register set (dmr_table in boards/dm1801pro/rf_tables_dm1801pro.c) and the RX path |
| Receive a transmission | H (headers) and V / T counters rise, crc stays low |
Many crc or u (unusable): the bandwidth word 0x3048 or the DMR register set |
| Hear a call | Silence: the codec is located but not hosted yet | |
| Transmit on a dummy load (data call or a short key-up) | A burst per slot on a meter or SDR, tx, rf and ok rise |
un (underrun) or rj: the per-burst switch takes too long (dmr_rf_switch, RF_BIT_SCALE_US); no carrier: dmr_pa_on, the 28 ms PA delay |
The mic on DMR transmit, no person: pytest tests/hil -k mic_uart_inject --allow-rf --mic-inject on the host the cable is plugged into (its device path, not a network bridge) |
The tone bursts sent on the cable's line show at the vocoder: voice.tx_mic_spread_db 12 or more, tx_mic_level_db 9 dB over a quiet over |
Both overs at the ADC's floor (level about 6, no spread): the mic doesn't reach the codec ADC on DMR. PTB14 must be high, as for FM (hardware-dm1801pro.md 3.1) |
10. VOX and the microphone level
The level comes from the codec ADC's mic PCM (hardware-dm1801pro.md 12). The programming cable in the speaker/mic jack cuts the microphone: unplug it for the talking steps, or read the values from the diagnostics page.
| Step | Expect | If not |
|---|---|---|
FM channel, VOX off; read the features view twice (vox.level), then the diagnostics line mic lvl |
vox.mic=1; mic lvl ... on, and n grows by about 100 a second while the view is read |
off or n stuck: the PCM interrupt or AUDIO_CONTROL b4 (c7 ac line, bit 4) |
| Quiet room, then talk at the radio from 10 cm | lvl and pk low in silence, well up while talking |
Flat while talking: the samples don't carry the microphone in receive (PTB14, the codec ADC mute, CR_ADC b7 in the cd lines) |
| VOX on (Quick tile, FM), dummy load, talk | Keys on speech, drops vox_tail_ms after it |
Keys in silence: the noise floor is above the threshold; lower vox_level or check pk |
11. After this
DMR voice needs the codec hosted (it is the DM-32UV's: hardware-dm1801pro.md 6.5) and the air band and the tuner a check on the radio (6). The open items are in hardware-dm1801pro.md 10.