Skip to content

Commit 14bffe5

Browse files
committed
MZTC: address the review findings and correct the driver against the camera manual
Answers all eight Qodo findings and all eight questions from the review comment on iNavFlight#11837, then corrects the driver against the BJ core serial protocol manual that ships with the camera. Serial protocol The old sender wrote a variable-length prefix of a fixed-layout struct. The checksum and the 0xFF terminator sat past that prefix. Neither was ever transmitted and uninitialized bytes went out in their place. The size field was payload+8 where the protocol says payload+4. For a full payload the computed length ran past the end of the struct. The packet is now built contiguously and matches the manual's own worked example byte for byte: brightness 100 is F0 05 36 78 02 00 64 14 FF. The receive parser is length driven. A 0xF0 or 0xFF byte inside a payload can no longer split or truncate a packet. Responses are decoded by class and subclass with per-payload length checks. Corrections from the camera manual Auto shutter values were off by one. The camera takes 0x01 temperature only, 0x02 time only and 0x03 time and temperature. It answers 0x00 with a threshold error. The driver sent the zero-based setting straight through. The default sent an out of range value. The shutter interval belongs to the camera. 0x7C/0x05 takes two bytes of minutes and the camera runs the schedule from it. The driver never sent that command and ran a competing host-side timer instead. The interval is pushed on connect now. mztc_ffc_interval accepts 1 to 60. TEMP_ONLY is how time-driven correction is turned off. The initialization status reply arrives on class 0x7D subclass 0x06. The host asks on 0x7C/0x14. The decoder matched the request address and never fired. Connection state Opening the UART no longer counts as a connected camera. The driver probes for the device model and reports connected once the camera answers. An established link that stops answering for three seconds is closed and retried. connection_quality is the share of recent probes answered. It was hardcoded to 100. The configuration burst moved out of the serial receive interrupt. Removed surfaces The camera exposes a UART for control and a composite video output for the picture. It has no digital data interface. Its manual defines 26 class and subclass pairs. None of them read a frame or a temperature. 0x78/0x01 appears only in the manual's invalid-subclass error example. 0x74/0x0C reads the ISP parameter version number. Frame data is removed. mztcFrameData_t, mztcGetFrameData(), MSP2_MZTC_FRAME_DATA, the undocumented 0x78/0x30 request and the rand() based simulator are all gone, along with frame_count and last_frame_time. Temperature is removed. camera_temperature, ambient_temperature, mztc_temperature_unit, mztc_temperature_alerts, mztc_alert_high_temp, mztc_alert_low_temp and MSP2_SET_MZTC_ALERTS are gone. Three settings were stored and validated but never transmitted. They did nothing. mztc_bad_pixel_removal drove an interactive on-screen cursor that a flight controller cannot walk. mztc_vignetting_correction is a one-shot action at 0x7C/0x0C that needs the lens on a uniform surface first. It becomes the mztc_vignetting command and MSP2_SET_MZTC_VIGNETTING. mztc_crosshair_enabled had no camera command at all. MSP The commands move out of 0x3000, where MSP2_BETAFLIGHT_BIND and MSP2_RX_BIND already live, into a contiguous block from 0x2240 to 0x2249. The identifiers nothing handled are dropped along with the duplicate aliases. Every field is serialized with sbufRead and sbufWrite. No struct is cast over the stream buffer. Padding and alignment stay off the wire. The config payload is 15 bytes and the status payload 7. SET_MZTC_CONFIG validates the whole request before applying any of it. An update_rate of zero was a reachable divide-by-zero in the camera task and an unbounded baudrate indexed past baudRates[]. OSD The module formatted strings and drew nothing. OSD_MZTC_STATUS replaces it as a real element driven by INAV's own layout and render pipeline. That grows OSD_ITEM_COUNT. Adding items moves the per-layout offsets in osdLayoutsConfig. PG_OSD_LAYOUTS_CONFIG therefore goes to version 4. Dead code mztc_camera_cli.c was not in CMakeLists, was never initialized and called APIs that do not exist. msp_mztc.c had a dispatch that was never invoked. Both are removed. msp_mztc.h stays for the command IDs and the payload layouts. mztc_shutter was identical to mztc_calibrate and mztc_simulate faked link liveness. mztc_save and mztc_defaults are added so the camera flash commands are reachable. Configuration The reset template is driven from the SETTING_*_DEFAULT macros. The fresh-EEPROM defaults and the CLI defaults cannot diverge. That settles the baudrate at 115200 and the mode at STANDBY. The limits live in the settings.yaml constants block. Compile-time assertions check that the C limits still match. A value the CLI rejects cannot be accepted over MSP. last_calibration widens to uint16 after wrapping at about 4.25 hours. The PG version goes to 1 because the PR test builds are already out. Tests The unit test properties were applied after the loop that creates every target. USE_MZTC never reached the compiler. The whole test body was preprocessed away. They move ahead of the loop. The tautological assertions are replaced with 40 tests across three suites. They cover the wire format against the hardware capture, the configuration validator, and the receive path driven through the serial callback. The receive tests exercise framing resynchronisation, payloads containing framing markers, checksum rejection, response dispatch, and the exact bytes the configuration burst puts on the wire. Five mutations confirmed the tests fail when each fixed bug is reintroduced. Docs The feature doc is rewritten around commands that exist. Its preset, camera management, video input and OSD settings were never implemented. docs/Settings.md is regenerated. The MSP messages are added by hand to msp_messages.json per docs/development/msp/README.md, with the MSP docs regenerated. Validated on three builds. SPEEDYBEEF405AIO with MZTC on, MATEKF722SE with MZTC off, and SITL. All three compile with no warnings in any MZTC file. 556 of 556 unit tests pass.
1 parent 1faf409 commit 14bffe5

25 files changed

Lines changed: 2721 additions & 3530 deletions

docs/MassZero_Thermal_Camera.md

Lines changed: 251 additions & 547 deletions
Large diffs are not rendered by default.

docs/Settings.md

Lines changed: 4 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3519,26 +3519,6 @@ Mask of RX channels that may be overridden by MSP `SET_RAW_RC`. Note that this r
35193519

35203520
---
35213521

3522-
### mztc_alert_high_temp
3523-
3524-
High temperature alert threshold
3525-
3526-
| Default | Min | Max |
3527-
| --- | --- | --- |
3528-
| 80.0 | -40 | 200 |
3529-
3530-
---
3531-
3532-
### mztc_alert_low_temp
3533-
3534-
Low temperature alert threshold
3535-
3536-
| Default | Min | Max |
3537-
| --- | --- | --- |
3538-
| -10.0 | -40 | 200 |
3539-
3540-
---
3541-
35423522
### mztc_auto_shutter
35433523

35443524
Auto shutter calibration mode
@@ -3551,23 +3531,13 @@ Auto shutter calibration mode
35513531

35523532
---
35533533

3554-
### mztc_bad_pixel_removal
3555-
3556-
Enable bad pixel removal
3557-
3558-
| Default | Min | Max |
3559-
| --- | --- | --- |
3560-
| ON | OFF | ON |
3561-
3562-
---
3563-
35643534
### mztc_baudrate
35653535

3566-
Baud rate for MassZero Thermal Camera
3536+
Baud rate index for MassZero Thermal Camera. Index 8 is 115200. MassZero cameras ship at that rate.
35673537

35683538
| Default | Min | Max |
35693539
| --- | --- | --- |
3570-
| 6 | 0 | 10 |
3540+
| 8 | 1 | 10 |
35713541

35723542
---
35733543

@@ -3591,16 +3561,6 @@ Image contrast (0-100)
35913561

35923562
---
35933563

3594-
### mztc_crosshair_enabled
3595-
3596-
Enable crosshair overlay
3597-
3598-
| Default | Min | Max |
3599-
| --- | --- | --- |
3600-
| OFF | OFF | ON |
3601-
3602-
---
3603-
36043564
### mztc_digital_enhancement
36053565

36063566
Digital enhancement level (0-100)
@@ -3623,11 +3583,11 @@ Enable MassZero Thermal Camera
36233583

36243584
### mztc_ffc_interval
36253585

3626-
Flat Field Calibration interval in minutes (0=disabled)
3586+
Automatic shutter interval in minutes. The camera runs the schedule itself. Set mztc_auto_shutter to TEMP_ONLY to stop it correcting on a timer.
36273587

36283588
| Default | Min | Max |
36293589
| --- | --- | --- |
3630-
| 5 | 0 | 60 |
3590+
| 5 | 1 | 60 |
36313591

36323592
---
36333593

@@ -3704,28 +3664,6 @@ Spatial denoising level (0-100)
37043664

37053665
---
37063666

3707-
### mztc_temperature_alerts
3708-
3709-
Enable temperature alerts
3710-
3711-
| Default | Min | Max |
3712-
| --- | --- | --- |
3713-
| OFF | OFF | ON |
3714-
3715-
---
3716-
3717-
### mztc_temperature_unit
3718-
3719-
Temperature unit (Celsius, Fahrenheit, Kelvin)
3720-
3721-
| Allowed Values | |
3722-
| --- | --- |
3723-
| CELSIUS | Default |
3724-
| FAHRENHEIT | |
3725-
| KELVIN | |
3726-
3727-
---
3728-
37293667
### mztc_temporal_denoise
37303668

37313669
Temporal denoising level (0-100)
@@ -3746,16 +3684,6 @@ Frame update rate in Hz
37463684

37473685
---
37483686

3749-
### mztc_vignetting_correction
3750-
3751-
Enable vignetting correction
3752-
3753-
| Default | Min | Max |
3754-
| --- | --- | --- |
3755-
| ON | OFF | ON |
3756-
3757-
---
3758-
37593687
### mztc_zoom_level
37603688

37613689
Digital zoom level

docs/development/msp/README.md

Lines changed: 264 additions & 0 deletions
Large diffs are not rendered by default.

docs/development/msp/inav_enums.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,13 @@
944944
"DJI_OSD_CN_ADJUSTEMNTS": "6",
945945
"DJI_OSD_CN_MAX_ELEMENTS": "7"
946946
},
947+
"dronecanAsyncState_e": {
948+
"_source": "inav/src/main/drivers/dronecan/dronecan.h",
949+
"DRONECAN_ASYNC_IDLE": "0",
950+
"DRONECAN_ASYNC_PENDING": "1",
951+
"DRONECAN_ASYNC_READY": "2",
952+
"DRONECAN_ASYNC_ERROR": "3"
953+
},
947954
"dronecanBitrate_e": {
948955
"_source": "inav/src/main/drivers/dronecan/dronecan.h",
949956
"DRONECAN_BITRATE_125KBPS": "0",
@@ -3203,7 +3210,10 @@
32033210
"OSD_THROTTLE_GAUGE": "168",
32043211
"OSD_GPS_EXTRA_STATS": "169",
32053212
"OSD_AUTO_SPEED": "170",
3206-
"OSD_ITEM_COUNT": "171"
3213+
"OSD_MZTC_TEMPERATURE": "171",
3214+
"OSD_MZTC_STATUS": "172",
3215+
"OSD_MZTC_ALERT": "173",
3216+
"OSD_ITEM_COUNT": "174"
32073217
},
32083218
"osd_sidebar_arrow_e": {
32093219
"_source": "inav/src/main/io/osd_grid.c",
@@ -3876,7 +3886,11 @@
38763886
"FUNCTION_CRSF_SENSOR": "(1 << 24)",
38773887
"FUNCTION_MSP_OSD": "(1 << 25)",
38783888
"FUNCTION_GIMBAL": "(1 << 26)",
3879-
"FUNCTION_GIMBAL_HEADTRACKER": "(1 << 27)"
3889+
"FUNCTION_GIMBAL_HEADTRACKER": "(1 << 27)",
3890+
"FUNCTION_MZTC_CAMERA": [
3891+
"(1 << 28)",
3892+
"USE_MZTC"
3893+
]
38803894
},
38813895
"serialPortIdentifier_e": {
38823896
"_source": "inav/src/main/io/serial.h",

docs/development/msp/inav_enums_ref.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
- [displayTransactionOption_e](#enum-displaytransactionoption_e)
7474
- [displayWidgetType_e](#enum-displaywidgettype_e)
7575
- [DjiCraftNameElements_t](#enum-djicraftnameelements_t)
76+
- [dronecanAsyncState_e](#enum-dronecanasyncstate_e)
7677
- [dronecanBitrate_e](#enum-dronecanbitrate_e)
7778
- [dronecanState_e](#enum-dronecanstate_e)
7879
- [dshotCommands_e](#enum-dshotcommands_e)
@@ -1613,6 +1614,18 @@
16131614
| `DJI_OSD_CN_ADJUSTEMNTS` | 6 | |
16141615
| `DJI_OSD_CN_MAX_ELEMENTS` | 7 | |
16151616

1617+
---
1618+
## <a id="enum-dronecanasyncstate_e"></a>`dronecanAsyncState_e`
1619+
1620+
> Source: ../../../src/main/drivers/dronecan/dronecan.h
1621+
1622+
| Enumerator | Value | Condition |
1623+
|---|---:|---|
1624+
| `DRONECAN_ASYNC_IDLE` | 0 | |
1625+
| `DRONECAN_ASYNC_PENDING` | 1 | |
1626+
| `DRONECAN_ASYNC_READY` | 2 | |
1627+
| `DRONECAN_ASYNC_ERROR` | 3 | |
1628+
16161629
---
16171630
## <a id="enum-dronecanbitrate_e"></a>`dronecanBitrate_e`
16181631

@@ -4653,7 +4666,10 @@
46534666
| `OSD_THROTTLE_GAUGE` | 168 | |
46544667
| `OSD_GPS_EXTRA_STATS` | 169 | |
46554668
| `OSD_AUTO_SPEED` | 170 | |
4656-
| `OSD_ITEM_COUNT` | 171 | |
4669+
| `OSD_MZTC_TEMPERATURE` | 171 | |
4670+
| `OSD_MZTC_STATUS` | 172 | |
4671+
| `OSD_MZTC_ALERT` | 173 | |
4672+
| `OSD_ITEM_COUNT` | 174 | |
46574673

46584674
---
46594675
## <a id="enum-osd_sidebar_arrow_e"></a>`osd_sidebar_arrow_e`
@@ -5600,6 +5616,7 @@
56005616
| `FUNCTION_MSP_OSD` | (1 << 25) | |
56015617
| `FUNCTION_GIMBAL` | (1 << 26) | |
56025618
| `FUNCTION_GIMBAL_HEADTRACKER` | (1 << 27) | |
5619+
| `FUNCTION_MZTC_CAMERA` | (1 << 28) | USE_MZTC |
56035620

56045621
---
56055622
## <a id="enum-serialportidentifier_e"></a>`serialPortIdentifier_e`

0 commit comments

Comments
 (0)