Skip to content

feat: PicoMSO Flutter mobile app — full architecture scaffold#36

Draft
Copilot wants to merge 8 commits into
mainfrom
copilot/analyze-architecture-for-flutter-app
Draft

feat: PicoMSO Flutter mobile app — full architecture scaffold#36
Copilot wants to merge 8 commits into
mainfrom
copilot/analyze-architecture-for-flutter-app

Conversation

Copilot AI commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Implements the complete Flutter app scaffold for PicoMSO based on the architecture proposal: mobile-first waveform viewer for logic-only and mixed-signal triggered captures over USB.

Transport / Protocol

  • UsbTransport singleton stub (EP0 control + EP6 bulk IN); swappable via abstract Transport
  • ProtocolCodec: ByteData little-endian encode/decode for all wire types; mirrors firmware packed structs exactly including the optional 25th byte (analog_channels bitmask) in REQUEST_CAPTURE
  • protocol_constants.dart mirrors all firmware #defines

Domain Models

  • DigitalTrack: packed bits (1 bit/sample, LSB-first) + pre-computed transition index list for O(log n) binary-search rendering
  • AnalogTrack: normalized Float32List (12-bit ADC → 0.0–1.0)
  • MinMaxPyramid: 4× downsampling levels, async build via Isolate.run
  • ViewportState: zoom/pan/cursor math helpers
  • Sealed CaptureState for the lifecycle FSM

Repository

  • CaptureRepository.runCapture: SET_MODE → REQUEST_CAPTURE → READ_DATA_BLOCK loop; handles dual-stream independent TERMINAL flags for mixed-signal; assembles CaptureSession off-thread
  • ADC demux mirrors libsigrok driver scope_demux_phase counter (interleaved channels in ascending index order)

Controllers (Riverpod)

  • CaptureController (Notifier<CaptureState>): sealed Idle → Arming → Armed → Downloading → Complete | Error
  • ViewportController: auto zoom-to-fit on new session arrival
  • DecoderController: runs all active decoders in an isolate; invalidates on session or config change

Decoders

Stateless, isolate-safe plugins behind ProtocolDecoder<C extends DecoderConfig>:

  • UART: start/data/parity/stop detection, configurable baud/format/idle-polarity
  • SPI: CPOL/CPHA-configurable clock edge sampling
  • I2C: START/STOP/ACK/NACK, 7-bit address decode

UI

  • HomeScreenCaptureSetupSheet (bottom sheet: trigger config, rate/count, pre-trigger %, analog channel toggles) → CaptureRunScreen (pulsing armed animation + download progress) → WaveformViewerScreen
  • WaveformViewerScreen: manual GestureDetector (split-axis pan/zoom); Stack + RepaintBoundary per layer; ChannelLabelList sidebar (long-press → DecoderConfigSheet); retrigger FAB
  • DecoderConfigSheet: segmented UART/SPI/I2C config, pre-populates from existing config

Painters

Each in its own RepaintBoundary; Paint/Path pre-allocated as fields, never inside paint():

Painter Strategy
GridPainter Auto-scaling interval (1/2/5×decade), ns–s labels
DigitalTrackPainter Binary-search transition walk; single drawPath per track
AnalogTrackPainter Pyramid level selected by samplesPerPixel; raw polygon at zoom-in
DecoderOverlayPainter RRect annotations with severity color
CursorPainter Own RepaintBoundary; cursor drag doesn't invalidate signal layers

Tests

  • protocol_codec_test: encoding correctness, sequence counter, ACK/error/DATA_BLOCK decode
  • uart_decoder_test: synthetic frame encode → decode round-trip for 0x00/0x55/0xFF; format variants; edge cases
  • capture_controller_test: state machine transitions via ProviderContainer

Copilot AI and others added 8 commits April 9, 2026 20:49
- pubspec.yaml: Flutter project config with Riverpod, go_router, freezed
- analysis_options.yaml: lint rules extending flutter_lints
- README.md: architecture overview and getting-started guide
- lib/transport/transport_interface.dart: abstract Transport + TransportException
- lib/transport/usb_transport.dart: singleton USB stub (EP0/EP6)
- lib/protocol/protocol_constants.dart: wire constants mirroring firmware headers
- lib/protocol/protocol_codec.dart: little-endian encode/decode for all packet types
- lib/protocol/capture_request_builder.dart: validated CaptureRequest builder

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: dgatf <33811722+dgatf@users.noreply.github.com>
Add 10 immutable Dart domain model files under
mobile_app/lib/domain/models/:

- capture_mode.dart        – CaptureMode enum (logicOnly / mixedSignal)
- trigger_config.dart      – TriggerConfig + TriggerMatch enum w/ wire values
- capture_request.dart     – CaptureRequest (maps to picomso_request_capture_request_t)
- digital_track.dart       – DigitalTrack with packed-bit storage & transition index
- analog_track.dart        – AnalogTrack with normalized Float32List samples
- min_max_pyramid.dart     – MinMaxPyramid for efficient waveform downsampling
- capture_session.dart     – CaptureSession (immutable capture result)
- decoder_result.dart      – DecoderResult + DecoderSeverity enum
- viewport_state.dart      – ViewportState with zoom/pan helpers
- device_info.dart         – DeviceInfo, DeviceCapabilities, DeviceStatus

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: dgatf <33811722+dgatf@users.noreply.github.com>
- domain/decoders: DecoderConfig/ProtocolDecoder interface, UART, SPI, I2C decoders
- repository: DeviceRepository (GET_INFO/CAPS/STATUS), CaptureRepository (full capture cycle with isolate assembly)
- controllers: DeviceController, CaptureController (state machine), ViewportController (pan/zoom/cursors), DecoderController (isolate-based dispatch)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: dgatf <33811722+dgatf@users.noreply.github.com>
- ui/shared/theme/app_theme.dart: dark/light Material 3 theme, channel/analog colors, waveform canvas colors
- ui/shared/widgets/connection_state_chip.dart: Riverpod-backed USB connection status chip
- ui/waveform/painters/grid_painter.dart: time-axis grid with auto-scaling intervals and labels
- ui/waveform/painters/digital_track_painter.dart: transition-indexed fast digital waveform renderer
- ui/waveform/painters/analog_track_painter.dart: min-max pyramid downsampling analog renderer
- ui/waveform/painters/decoder_overlay_painter.dart: protocol decoder annotation overlay
- ui/waveform/painters/cursor_painter.dart: dashed cursor A/B lines with labels

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: dgatf <33811722+dgatf@users.noreply.github.com>
- lib/main.dart: app entry point with ProviderScope
- lib/app.dart: root MaterialApp with named routes and dark theme
- test/protocol/protocol_codec_test.dart: codec encode/decode tests
- test/domain/decoders/uart_decoder_test.dart: UART decoder tests
- test/controllers/capture_controller_test.dart: state machine tests
- android/: minimal Android project stubs (build.gradle, settings.gradle,
  gradle wrapper, app/build.gradle, AndroidManifest.xml, MainActivity.kt)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: dgatf <33811722+dgatf@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants