Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ set(SOURCES_LIST
capture/src/raw_packet_queue.cpp
capture/src/waveform_parser.cpp
capture/src/waveform_ring_buffer.cpp
core/src/waveform_scaling.cpp
core/src/instrument_scaling_profile.cpp
${imgui_SOURCE_DIR}/imgui.cpp
${imgui_SOURCE_DIR}/imgui_draw.cpp
${imgui_SOURCE_DIR}/imgui_tables.cpp
Expand All @@ -62,6 +64,9 @@ set(HEADERS_LIST
capture/inc/raw_packet_queue.h
capture/inc/waveform_parser.h
capture/inc/waveform_ring_buffer.h
core/inc/waveform_scaling.h
core/inc/instrument_model.h
core/inc/instrument_scaling_profile.h
)

set(RAW_PACKET_QUEUE_TEST_SOURCES_LIST
Expand All @@ -76,6 +81,14 @@ set(WAVEFORM_RING_BUFFER_TEST_SOURCES_LIST
tests/waveform_ring_buffer_test.cpp
)

set(WAVEFORM_SCALING_TEST_SOURCES_LIST
tests/waveform_scaling_test.cpp
)

set(INSTRUMENT_SCALING_PROFILE_TEST_SOURCES_LIST
tests/instrument_scaling_profile_test.cpp
)

if(CMAKE_BUILD_TYPE MATCHES "Debug")
message(STATUS ">>> Debug build")
add_compile_definitions(_DEBUG)
Expand Down Expand Up @@ -103,6 +116,7 @@ target_include_directories(${APP_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/usb/inc
${CMAKE_CURRENT_SOURCE_DIR}/capture/inc
${CMAKE_CURRENT_SOURCE_DIR}/core/inc
${imgui_SOURCE_DIR}
${imgui_SOURCE_DIR}/backends
)
Expand Down Expand Up @@ -153,6 +167,29 @@ if(BUILD_TESTING)
enable_project_warnings(waveform_ring_buffer_tests)
add_test(NAME waveform_ring_buffer COMMAND waveform_ring_buffer_tests)
add_dependencies(${APP_NAME} waveform_ring_buffer_tests)
add_executable(waveform_scaling_tests
${WAVEFORM_SCALING_TEST_SOURCES_LIST}
core/src/waveform_scaling.cpp
)
target_include_directories(waveform_scaling_tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/core/inc
)
enable_project_warnings(waveform_scaling_tests)
add_test(NAME waveform_scaling COMMAND waveform_scaling_tests)
add_dependencies(${APP_NAME} waveform_scaling_tests)
add_executable(instrument_scaling_profile_tests
${INSTRUMENT_SCALING_PROFILE_TEST_SOURCES_LIST}
core/src/instrument_scaling_profile.cpp
)
target_include_directories(instrument_scaling_profile_tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/core/inc
)
enable_project_warnings(instrument_scaling_profile_tests)
add_test(
NAME instrument_scaling_profile
COMMAND instrument_scaling_profile_tests
)
add_dependencies(${APP_NAME} instrument_scaling_profile_tests)
add_test(
NAME release_updater
COMMAND ${Python3_EXECUTABLE}
Expand Down
62 changes: 62 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,3 +365,65 @@ Records key decisions, structural changes, and completed development stages.
- Verified application shutdown during acquisition: no hang or crash; the
status LED blinked red briefly, then turned off.

### Stage 4 - Scaling logic

- Added a new `core` module with deterministic, hardware-independent
functions that convert raw two-channel capture samples into volts and
elapsed capture time.
- Centered voltage scaling on the ADC midpoint (raw sample 128) with 32 raw
counts per vertical grid division, matching the legacy `glbox`/
`hantekdsoathread` display convention (8 vertical divisions across the
256-value 8-bit sample range).
- Modeled elapsed sample time as a fraction of the full capture spanning the
10 horizontal grid divisions at the selected timebase.
- Added shared voltage-scale and timebase lookup tables as the single source
of truth for both the scaling math and the existing UI combo-box labels,
with compile-time checks that the tables and labels stay in sync.
- Wired the status line to show the scaled CH1/CH2 voltage and elapsed time
at the decoded trigger sample, proving the scaling pipeline end to end
without yet plotting the waveform shape, which remains a separate future
task.
- Added deterministic CTest coverage for characteristic and boundary raw
sample values and sample-time fractions, including a zero-sample-count
guard.
- Verified warning-free Debug and Release builds and a full CTest pass.

### Stage 4 - Per-instrument scaling profile

- Introduced `EInstrumentModel` and `SInstrumentScalingProfile` so timebase
steps, voltage-scale steps, grid divisions, and the ADC zero-volt center
value are looked up per connected instrument instead of one fixed table.
- Replaced the single shared voltage/timebase lookup tables and their
compile-time label checks with `findInstrtScalingProfile()`, resolved once
per frame from the connected or last-scanned device identity, falling back
to the DSO-2250 profile so the UI always has scale steps to display.
- Added deterministic CTest coverage for profile lookup, including the
fallback and an unknown-model case.

### Known issue - live capture on real DSO-2250 hardware reports no waveform

- Symptom: `GetCaptureState` polling never leaves the empty-buffer state on a
physical Hantek DSO-2250 (state byte stays `0x00`), so no channel data is
ever read and the display keeps showing no waveform, while Demo mode and
every deterministic CTest continue to pass.
- Investigated and ruled out across several verified, warning-free
Debug/Release builds, each checked against fresh USB captures from the
physical device: a missing `ForceTrigger` before polling, an incomplete
`configureCapture()` command sequence, missing empty-response retry
handling, resending `TriggerEnabled` on every poll, and a missing
`SetOffset` (`CONTROL_SETOFFSET`, request `0xB4`) channel/trigger offset
command derived from the device's calibration table - all implemented,
hardware-tested, and individually confirmed insufficient.
- Found by correlating each USB command byte with its immediately following
response byte across a full Windows reference driver capture (naive
per-endpoint response counts are misleading, because `GetCaptureState`,
`GetChannelData`, and the unrelated logic-channel/auto-range subsystem all
share bulk-IN endpoint `0x86`): the reference driver's completed-capture
state value is `3`, not the previously assumed `2`. Corrected
`captureCompleteState` from `2U` to `3U` for both DSO-2250 profiles in
`usb/src/usb_device.cpp`.
- This correction is warning-free in Debug/Release and passes all CTest
cases, but still did NOT resolve the symptom on hardware retest - the
root cause remains open. Treated as a known, unresolved bug pending
further hardware-side USB capture analysis.

26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ hardware-independent parser functions. Each supported-device entry supplies its
capture protocol, including endpoints, packet size, commands, channel layout,
sample count, and completion state. After a completed capture, the acquisition
worker reads and queues the complete profile-defined sample buffer, then starts
the next capture. Live waveform rendering is not yet implemented. A processing
worker decodes complete captures and publishes the latest frame and trigger
point safely for rendering.
the next capture. A processing worker decodes complete captures and publishes
the latest frame and trigger point safely for rendering. Deterministic
functions convert raw capture samples into volts and elapsed capture time from
the selected voltage-scale and timebase settings. Live waveform rendering is
not yet implemented.

## Planned Stack

Expand All @@ -43,7 +45,9 @@ Oscilloscope/
├── capture/ Sample acquisition and processing.
│ ├── inc/ Capture module headers.
│ └── src/ Capture module implementations.
├── core/ Shared types and application logic.
├── core/ Voltage/timebase scaling and shared application types.
│ ├── inc/ Core module headers.
│ └── src/ Core module implementations.
├── docs/ Project documentation.
├── firmware/ Default path for local device firmware files.
├── render/ Oscilloscope waveform rendering.
Expand Down Expand Up @@ -211,10 +215,20 @@ and restores the previous files if the build fails.
CI can update only the version metadata by passing `--skip-build`.


## Known Issues

- Live capture on a physical Hantek DSO-2250 never reports a waveform:
`GetCaptureState` polling stays at the empty-buffer state, so no channel
data is read. Demo mode and the full CTest suite are unaffected. See
`HISTORY.md` ("Known issue - live capture on real DSO-2250 hardware
reports no waveform") for the investigation and ruled-out causes.

## Next Steps

1. Render live and demo waveforms on the display grid.
2. Implement the two-channel model, timebase, and instrument controls.
1. Diagnose the live-capture-never-completes issue on real DSO-2250
hardware.
2. Render live and demo waveforms on the display grid.
3. Implement the two-channel model, timebase, and instrument controls.

The full goals, constraints, and architecture are documented in
`WorkingDocs/TECHNICAL_SPECIFICATION.md`.
Expand Down
Loading
Loading