Firmware

Firmware Architecture

Inside the RT-900 firmware — source tree, build system, task scheduling, and programming protocol. Essential reading for anyone building custom firmware.

Source Tree

DirectoryPurposeKey Files
App/Application logic (menus, modes)AppMain.c, AppMenu.c, AppScan.c, AppDtmf.c, AppFm.c, AppAlarm.c
BSP/Board support (GPIO, clocks)Board initialization and peripheral setup
Core/Radio core logicRadio.c (RF control), RadioTask.c (state machine), Functions.c
Driver/Hardware driversDevBK4819.c, st7735s.c, NorFlash.c, keyboard.c, Rda5807.c
Gui/Display renderingDisplayMain.c, DisplayMenu.c, DisplayFm.c, LcdFillDot.c
CPS/Programming supportProgromFlash.c (UART flash protocol)
Interface/Communication busesI2C, UART low-level drivers
Libraries/CMSIS + STM32 HALStartup assembly, peripheral definitions, CMSIS core
Voice/Audio playbackBeep.c (tone generation), VoiceBroadcast.c (voice prompts)
Common/Shared types/utilitiesType definitions, common macros

Total codebase: ~19,500 lines of C.

Build System

  • Toolchain: arm-none-eabi-gcc (GCC ARM Embedded)
  • CPU target: -mcpu=cortex-m0
  • Optimization: -Os -flto (size-optimized with link-time optimization)
  • Linker script: firmware.ld
  • Build: run make to produce firmware.bin
  • Output: firmware.elf (debug), firmware.bin (flashable binary)

Firmware source is publicly available at github.com/pdrbsts/radtel-rt-900-firmware.

Task Loop

The firmware runs a cooperative multitasking loop driven by a 1ms SysTick interrupt:

IntervalTaskResponsibility
10msRF + KeysBK4819 state machine, keyboard scan, radio control
50msDisplayLCD refresh, GUI updates
100msStatusBattery monitoring, status updates
500msMaintenanceSettings save, power management

SysTick interrupt sets flags (g_10msFlag, g_50msFlag, etc.) which the main loop checks and services.

Startup Sequence

  1. Board_Init() configure GPIO, SPI, UART, timers
  2. ST7735S_Init() initialize color LCD over SPI2
  3. RadioConfig_Init() load channel and VFO data from SPI flash
  4. Rfic_Init() initialize BK4819 RF chip
  5. UI_DisplayPowerOn() show splash screen
  6. Enter main loop begin task scheduling
Boot splash screen rendered after ST7735S_Init() and RadioConfig_Init()
Boot splash — rendered after ST7735S_Init() and RadioConfig_Init()

CPS Programming Protocol

For programming the radio from a computer (firmware upload, channel read/write).

Connection: UART1 at 57600 baud, 8N1 (PA9=TX, PA10=RX)

Packet Format

FieldSizeDescription
Header1 byte0xA5 (sync marker)
Command1 byteCommand ID
Packet ID1 byteSequential counter
Length2 bytesData length (little-endian)
DatavariableCommand-specific payload

Commands

IDNameDescription
0x02HandshakeInitiate communication
0x03AddressSet target flash address
0x04EraseErase sector/block/chip
0x06EndTerminate session
0x57WriteWrite data to flash
  • Erase modes: 0x01 (full chip), 0x02 (4K sector), 0x03 (32K block), 0x04 (64K block)
  • Response codes: 0x59 = OK, 0x010x06 = various errors
  • Write flow: handshake → set address → erase → write chunks → end → radio reboots

Note

The CPS protocol writes directly to the SPI NOR flash. This is how both firmware and channel data are programmed. A Web Serial implementation of this protocol would enable browser-based programming — similar to what rfsplatter already does for the UV-K5.