Nova Voyager Open Firmware
Open-source replacement firmware for the Teknatool Nova Voyager DVR
drill press HMI controller (GD32F303RCT6, ST7920 16x4 LCD, FreeRTOS).
 |
 |
| Idle — target 1500 RPM, load bar empty |
Drilling at 1487 RPM, 32% load, 12.4 mm depth |
 |
 |
| Tapping at 580 RPM with Depth+LoadInc+Quill triggers |
Menu navigation (wraps at top/bottom) |
Community-developed firmware based on reverse engineering.
Installing this replaces the OEM firmware. Back up your OEM image
first — see docs/HARDWARE_SETUP.md.
What this adds
- Tapping — 6 combinable triggers (depth, load increase, load slip,
clutch, quill direction, peck) with GF bit 2 direction-change polling
- Foot pedal — uses the unused X11 connector on the HMI board for
hands-free chip-break and reverse override
- Load bar — ST7920 CGRAM bar graph on row 3 (40-step, 16x16 custom chars)
- F4 display modes — load bar / temperature + DC bus voltage / speed info / off
- Material speed calculator — 12 materials, 9 bit types, auto RPM
- Configurable motor — overload threshold (LD), speed ramp (DN),
max speed, advanced PID submenu, motor profiles (Soft/Normal/Hard)
- OEM-compatible EEPROM — speed presets and max RPM survive firmware
switches; custom settings in 0xB0-0xFF; crash dump persists across power cycles
- Step drilling — automatic RPM adjustment by tool diameter
- Favorite speeds — F1 cycles presets, long-press saves current RPM
- Sensor alignment — ALIGN command tests RPS phases via voltage hold
- F0 fault decoding — motor error screen shows decoded MCB fault code
- Settings export — DUMP (all settings) + EEDUMP (EEPROM hex dump)
- Games — optional Pong, Snake, Penguin in a separate FreeRTOS task
(
pio run -e nova_voyager_games); zero game code in default build
- Serial console — 61 production + 38 debug commands (9600 baud)
- USB DFU updates — with the companion
bootloader,
no ST-Link needed for subsequent flashes
- Documented MCB protocol — see
docs/MOTOR_PROTOCOL.md
and docs/EEPROM_MAP.md
Quick start
# Build (production, no games)
pio run -e nova_voyager
# Build with games (Pong, Snake, Penguin)
pio run -e nova_voyager_games
# Flash via ST-Link (fast — assumes flash already unlocked)
./flash_firmware.sh quick
# First-time install (unlocks flash protection, writes bootloader + app)
./flash_firmware.sh custom
# Restore OEM firmware
./flash_firmware.sh original
For bench setup, wiring, and first-flash instructions see
docs/HARDWARE_SETUP.md.
Hardware
|
|
| MCU |
GD32F303RCT6 (ARM Cortex-M4F, 120 MHz, 256 KB flash, 48 KB RAM) |
| Display |
ST7920 16x4 character LCD, 8-bit parallel |
| Motor link |
USART3 @ 9600 baud to MCB (Switched Reluctance Motor controller) |
| Inputs |
Rotary encoder + 7 buttons (EXTI), foot pedal |
| Sensors |
Depth (ADC), guard switch, E-Stop |
| Bootloader |
DFU at 0x08000000 (12 KB), application at 0x08003000 (244 KB) |
Pin map
| Signal |
Pin |
Notes |
| LCD data bus |
PA0-PA7 |
8-bit parallel |
| LCD RS / RW / E |
PB0 / PB1 / PB2 |
Control lines |
| Encoder A / B / Btn |
PC13 / PC14 / PC15 |
4 counts/detent, button = fine/coarse toggle |
| E-Stop |
PC0 |
Active high, direct GPIO cutoff path |
| Guard switch |
PC2 |
Active high (open = high) |
| Foot pedal |
PC3 |
Active low (X11 connector) |
| Depth ADC |
PC1 |
ADC1 channel 11 |
| Motor UART |
PB10 / PB11 |
TX / RX |
| Debug UART |
PA9 / PA10 |
TX / RX, 9600 baud |
LCD layout
1487 1500 <- actual RPM (left), target RPM (right)
32 DRL --- FWD <- load, state, triggers, direction
T: D: 12.4 <- target depth, current depth
[|||||||| ] <- load bar (F4 cycles: load / temp / speed / off)
State codes: IDL idle, DRL drilling, TAP tapping, STP step drill, MNU menu.
F-keys
| Key |
Short press |
Long press |
| F1 |
Cycle favorite speeds |
Save current RPM to favorites |
| F2 |
Arm / disarm tapping |
— |
| F3 |
Set depth target to current depth |
— |
| F4 |
Cycle row 3 (load bar / temperature / speed info / off) |
— |
Tapping
Six combinable triggers. Enable any subset in the menu; arm with F2.
| Code |
Trigger |
Watches |
Use case |
D |
Depth |
Quill depth sensor |
Stop / reverse at target depth |
I |
Load Inc |
KR (load %) spike |
Blind holes, excessive resistance |
S |
Load Slip |
CV overshoot |
Through-hole exit detection |
C |
Clutch |
Load plateau |
Torque limiter engaged |
Q |
Quill |
Quill direction change |
Auto-reverse on quill lift |
K |
Peck |
Timed cycles |
Chip clearance |
P |
Pedal |
Foot pedal |
Manual chip-break / hold |
Priority: Pedal > Quill > Depth > Load > Peck.
The HMI board exposes PC3 on the X11 connector. The OEM firmware
doesn’t use it; this firmware reads it as a foot-pedal input.
| Part |
Spec |
| Foot switch |
TFS-1 momentary SPST, NO contacts |
| Panel jack |
GX12 2-pin, panel-mounted |
| Internal cable |
JST PH 2.54mm 3-pin to X11 |
foot switch chassis panel jack HMI board X11
┌─────┐ ┌─────────┐ ┌──────────┐
│TFS-1│──── 2 wire ───┤ GX12 ├──── 2 wire ───┤ PC3 sig │
│ NO │ │ 2-pin │ │ GND │
└─────┘ └─────────┘ │ N/C │
└──────────┘
Active low, internal pull-up. Disable in Menu > Tapping > Pedal
if wired but not wanted for a session.
Architecture
5 FreeRTOS tasks (+ 1 dynamic game task when games are active):
| Task |
Prio |
Stack |
Rate |
Role |
| Main |
1 |
256 W |
~100 Hz |
Event queue, console, watchdog |
| Depth |
2 |
96 W |
50 Hz |
ADC quill sensor |
| UI |
2 |
256 W |
50 Hz |
Buttons, encoder, LCD |
| Tapping |
3 |
160 W |
20 Hz |
Trigger state machine |
| Motor |
4 |
192 W |
2/20 Hz |
UART to MCB (adaptive) |
Per-task heartbeat watchdog: the main loop feeds the IWDG only when
all tasks have checked in and the event queue is draining. HAL tick
kept in sync via vApplicationTickHook() → HAL_IncTick().
Motor stack:
task_motor.c FreeRTOS task, command queue, status polling
+- motor.c MCB parameter API (profile, PID, power)
+- motor_protocol.c Packet build / parse
+- motor_uart.c USART3 hardware (DMA RX)
Safety
- E-Stop — ISR drives PD4 low (motor enable) before any queued
command. Cannot be delayed by a stuck task, full queue, or UART failure.
- Guard interlock — motor refuses to start with guard open;
auto-stops and activates spindle hold if guard opens while running.
- Queue purge — E-Stop, guard open, and motor fault purge the motor
command queue to prevent stale FORWARD/REVERSE from re-enabling the motor.
- Watchdog — IWDG ~3 s, fed only when all 5 tasks are alive and the
event queue is draining. Queue saturation = stall = reset.
- EEPROM settings — when EEPROM is present, no flash writes needed
(no 20ms CPU stall, safe to save while motor running).
- COMM FAULT — 15 consecutive UART failures trigger hardware motor
disable + fault state with F0 code decoding.
- USART overrun handling — ORE flag cleared on every RX poll to
prevent silent data loss during FreeRTOS task switches.
- Depth target — auto-stop and beep when quill reaches target depth
or step drill reaches target diameter.
Serial console
9600 baud on PA9/PA10. 61 production commands — start with HELP.
| Command |
What it does |
STATUS |
System state, queues, overflow counters |
STACK |
Per-task stack high-water marks |
DEPTH |
Live depth sensor |
GUARD |
Guard / pedal / E-Stop GPIO state |
KR |
Query MCB load percentage |
CV |
Query MCB current speed |
TAP |
Show / configure tapping triggers |
SPEED <rpm> |
Set target RPM |
DUMP |
Export all settings as key=value |
EEDUMP |
Hex dump HMI EEPROM (256 bytes) |
ALIGN [A/B/C/OFF] |
Sensor alignment test |
GAME P/S/N |
Pong / Snake / Penguin (games build only) |
DFU |
Reboot into USB DFU bootloader |
SAVE |
Persist settings to EEPROM |
Project status
- All features implemented; firmware in daily use
- 389 unit tests across 13 suites (all passing)
- 0 compiler warnings
- ~31% flash / ~28% RAM (production); ~34% / ~41% RAM with games
License
GPL-3.0 — see LICENSE.
Community reverse-engineered. No warranty. Use at your own risk.
Credits
Reverse engineering based on independent analysis of the Teknatool
firmware (R2P05x, R2P06e, R2P06k), logic-analyzer captures of the MCB
protocol, and patient experimentation.
评论