Files
KeyBoard_QT/docs/firmware_proto_transport.md

3.6 KiB

Firmware Proto Transport

Goal

Add CDC and GATT private communication without rewriting the existing keyboard, time, theme, and LED business logic.

The firmware side should:

  • keep standard HID behavior for normal keys
  • receive host commands over CDC and GATT
  • report private state and function key events over CDC and GATT
  • reuse existing modules where possible

Completed Nodes

Node 1: internal function events

Files:

  • src/events/function_bitmap_event.h
  • src/events/function_bitmap_event.c
  • src/events/function_key_event.h
  • src/events/function_key_event.c

Design notes:

  • function_bitmap_event carries the 29-byte function bitmap from host
  • function_key_event carries usage + action when a configured function key is pressed or released
  • these events isolate transport modules from keyboard internals

Planned next nodes

Node 2: keyboard split point

Files updated in this step:

  • src/modules/keyboard_module.c

Design notes:

  • reuse the existing keymap and HID path
  • add one explicit split point before HID submission
  • keep normal keys on HID
  • send configured function keys to private transport only

Implemented behavior:

  • store the 29-byte function bitmap
  • for keyboard usages marked as function keys:
    • stop normal HID reporting
    • emit function_key_event
  • for consumer usages marked as function keys:
    • stop normal HID reporting
    • emit function_key_event

Node 3: nanopb build integration and protocol core

Files updated in this step:

  • CMakeLists.txt
  • prj.conf
  • app.overlay
  • inc/keyboard_proto.h
  • src/modules/keyboard_proto.c

Design notes:

  • use NCS built-in nanopb instead of a hand-written protobuf runtime
  • generate protocol code from the shared .proto
  • keep one firmware-side protocol helper that:
    • encodes and decodes CdcPacketBody
    • encodes and decodes CdcFrame
    • validates checksum
    • routes host commands back into existing modules

Implemented behavior:

  • enable CDC ACM class in Zephyr USB device-next stack
  • add a CDC ACM UART node in devicetree
  • wire zephyr_nanopb_sources() into the build
  • force nanopb generation to use the NCS toolchain Python instead of the broken Windows app alias
  • add protocol helper functions for:
    • body encode/decode
    • CDC frame encode
    • CDC frame stream extraction
    • hello response build
    • ack/error build
    • function key event build
    • LED state build
    • host command dispatch

Planned next nodes

  • GATT transport module

Node 4: CDC transport module

Files added in this step:

  • src/modules/usb_cdc_proto_module.c

Design notes:

  • use the CDC ACM UART abstraction from Zephyr
  • keep CDC transport separate from protocol details by delegating encode/decode to keyboard_proto
  • report private outgoing events back to host over CDC

Implemented behavior:

  • receive raw CDC bytes by UART IRQ
  • accumulate bytes into a stream buffer
  • extract protobuf CdcFrame
  • decode host messages and dispatch them
  • send:
    • HelloRsp
    • Ack
    • Error
    • FunctionKeyEvent
    • LedState

Node 5: GATT transport module

Files added in this step:

  • src/modules/ble_gatt_proto_module.c

Design notes:

  • define one custom service with one RX write characteristic and one TX notify characteristic
  • keep GATT transport byte-oriented by sending raw CdcPacketBody bytes
  • reuse the same host command dispatcher as CDC

Implemented behavior:

  • register the custom GATT service
  • accept host writes on RX
  • decode CdcPacketBody
  • dispatch host messages
  • notify:
    • HelloRsp
    • Ack
    • Error
    • FunctionKeyEvent
    • LedState