(feature: &Feature)
| 583 | // ─── DSP Getter/Setter (0x96 family via 0x11/0x12) ────────────────────────── |
| 584 | |
| 585 | fn dsp_get(feature: &Feature) -> f32 { |
| 586 | let (family, feature_id) = feature |
| 587 | .id |
| 588 | .dsp_address() |
| 589 | .expect("dsp_get called on non-DSP feature"); |
| 590 | |
| 591 | debug!( |
| 592 | "Querying DSP feature: {} (0x{:02x}:0x{:02x})", |
| 593 | feature.id, family, feature_id |
| 594 | ); |
| 595 | |
| 596 | let mut payload = [0u8; 65]; |
| 597 | payload[1] = 0x5a; |
| 598 | payload[2] = 0x11; |
| 599 | payload[3] = 0x03; |
| 600 | payload[4] = 0x01; |
| 601 | payload[5] = family; |
| 602 | payload[6] = feature_id; |
| 603 | |
| 604 | DEVICE_CONNECTION |
| 605 | .get() |
| 606 | .expect("Device Connection must be initialized") |
| 607 | .lock() |
| 608 | .unwrap() |
| 609 | .write(&payload) |
| 610 | .expect("Failed to send Query to Device"); |
| 611 | |
| 612 | for attempt in 0..MAX_READ_ATTEMPTS { |
| 613 | let Some(response) = read_packet() else { |
| 614 | error!( |
| 615 | "No response on attempt {}/{} for {}", |
| 616 | attempt + 1, |
| 617 | MAX_READ_ATTEMPTS, |
| 618 | feature.id |
| 619 | ); |
| 620 | continue; |
| 621 | }; |
| 622 | |
| 623 | // expected: 5a 11 08 01 00 [family] [id] [f32 LE × 4] |
| 624 | if response[0] == 0x5a |
| 625 | && response[1] == 0x11 |
| 626 | && response[5] == family |
| 627 | && response[6] == feature_id |
| 628 | { |
| 629 | let value = f32::from_le_bytes( |
| 630 | response[7..11] |
| 631 | .try_into() |
| 632 | .expect("Failed to parse f32 from response bytes"), |
| 633 | ); |
| 634 | debug!("Read {} = {}", feature.id, value); |
| 635 | *feature.value.lock().unwrap() = value; |
| 636 | return value; |
| 637 | } |
| 638 | |
| 639 | debug!( |
| 640 | "Discarded stale packet on attempt {}: {:02x?}", |
| 641 | attempt + 1, |
| 642 | &response[..12] |
nothing calls this directly
no test coverage detected