Added more unittests
This commit is contained in:
parent
b98614fe8e
commit
9f95813f97
@ -416,6 +416,10 @@ pub fn calculate_axis_value(
|
|||||||
) -> u16 {
|
) -> u16 {
|
||||||
use crate::hardware::{ADC_MAX, ADC_MIN, AXIS_CENTER};
|
use crate::hardware::{ADC_MAX, ADC_MIN, AXIS_CENTER};
|
||||||
|
|
||||||
|
if min >= max || center <= min || center >= max {
|
||||||
|
return center;
|
||||||
|
}
|
||||||
|
|
||||||
if value <= min {
|
if value <= min {
|
||||||
return ADC_MIN;
|
return ADC_MIN;
|
||||||
}
|
}
|
||||||
@ -660,6 +664,20 @@ mod tests {
|
|||||||
assert_eq!(result, AXIS_CENTER);
|
assert_eq!(result, AXIS_CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_calculate_axis_value_degenerate_calibration() {
|
||||||
|
let expo_lut = ExpoLUT::new(0.0);
|
||||||
|
|
||||||
|
// When calibration collapses to a single point (min=max=center),
|
||||||
|
// the output should remain at that center rather than clamping low/high.
|
||||||
|
let result = calculate_axis_value(2100, 2100, 2100, 2100, (0, 0, 0), false, &expo_lut);
|
||||||
|
assert_eq!(result, 2100);
|
||||||
|
|
||||||
|
// Also handle centers outside the valid window by returning center directly.
|
||||||
|
let result = calculate_axis_value(1500, 1400, 2000, 1400, (0, 0, 0), false, &expo_lut);
|
||||||
|
assert_eq!(result, 1400);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_remap_function() {
|
fn test_remap_function() {
|
||||||
// Test basic remapping
|
// Test basic remapping
|
||||||
|
|||||||
@ -8,9 +8,9 @@
|
|||||||
//! - Evaluate special combinations (bootloader, calibration, etc.)
|
//! - Evaluate special combinations (bootloader, calibration, etc.)
|
||||||
//! - Expose a compact state consumed by USB report generation
|
//! - Expose a compact state consumed by USB report generation
|
||||||
|
|
||||||
use crate::mapping::*;
|
|
||||||
use crate::button_matrix::ButtonMatrix;
|
use crate::button_matrix::ButtonMatrix;
|
||||||
use crate::hardware::{NUMBER_OF_BUTTONS, AXIS_CENTER, BUTTON_ROWS, BUTTON_COLS};
|
use crate::hardware::{AXIS_CENTER, BUTTON_COLS, BUTTON_ROWS, NUMBER_OF_BUTTONS};
|
||||||
|
use crate::mapping::*;
|
||||||
use embedded_hal::digital::InputPin;
|
use embedded_hal::digital::InputPin;
|
||||||
use rp2040_hal::timer::Timer;
|
use rp2040_hal::timer::Timer;
|
||||||
|
|
||||||
@ -39,7 +39,6 @@ pub struct Button {
|
|||||||
|
|
||||||
// ==================== SPECIAL ACTIONS ====================
|
// ==================== SPECIAL ACTIONS ====================
|
||||||
/// High‑level actions triggered by dedicated button combinations.
|
/// High‑level actions triggered by dedicated button combinations.
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum SpecialAction {
|
pub enum SpecialAction {
|
||||||
None,
|
None,
|
||||||
@ -55,7 +54,6 @@ pub enum SpecialAction {
|
|||||||
|
|
||||||
// ==================== BUTTON MANAGER ====================
|
// ==================== BUTTON MANAGER ====================
|
||||||
/// Aggregates and processes all buttons, exposing a stable API to the rest of the firmware.
|
/// Aggregates and processes all buttons, exposing a stable API to the rest of the firmware.
|
||||||
|
|
||||||
pub struct ButtonManager {
|
pub struct ButtonManager {
|
||||||
pub buttons: [Button; TOTAL_BUTTONS],
|
pub buttons: [Button; TOTAL_BUTTONS],
|
||||||
}
|
}
|
||||||
@ -77,7 +75,10 @@ impl ButtonManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update button states from the button matrix snapshot.
|
/// Update button states from the button matrix snapshot.
|
||||||
pub fn update_from_matrix(&mut self, matrix: &mut ButtonMatrix<BUTTON_ROWS, BUTTON_COLS, NUMBER_OF_BUTTONS>) {
|
pub fn update_from_matrix(
|
||||||
|
&mut self,
|
||||||
|
matrix: &mut ButtonMatrix<BUTTON_ROWS, BUTTON_COLS, NUMBER_OF_BUTTONS>,
|
||||||
|
) {
|
||||||
for (index, key) in matrix.buttons_pressed().iter().enumerate() {
|
for (index, key) in matrix.buttons_pressed().iter().enumerate() {
|
||||||
self.buttons[index].pressed = *key;
|
self.buttons[index].pressed = *key;
|
||||||
}
|
}
|
||||||
@ -162,7 +163,11 @@ impl ButtonManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check for special button combinations (bootloader, calibration state/mode, VT, etc.).
|
/// Check for special button combinations (bootloader, calibration state/mode, VT, etc.).
|
||||||
pub fn check_special_combinations(&self, unprocessed_axis_value: u16, calibration_active: bool) -> SpecialAction {
|
pub fn check_special_combinations(
|
||||||
|
&self,
|
||||||
|
unprocessed_axis_value: u16,
|
||||||
|
calibration_active: bool,
|
||||||
|
) -> SpecialAction {
|
||||||
// Secondary way to enter bootloader
|
// Secondary way to enter bootloader
|
||||||
if self.buttons[BUTTON_FRONT_LEFT_LOWER].pressed
|
if self.buttons[BUTTON_FRONT_LEFT_LOWER].pressed
|
||||||
&& self.buttons[BUTTON_TOP_LEFT_MODE].pressed
|
&& self.buttons[BUTTON_TOP_LEFT_MODE].pressed
|
||||||
@ -297,13 +302,14 @@ fn update_button_press_type(button: &mut Button, current_time: u32) {
|
|||||||
|
|
||||||
// Auto‑release generated USB press after minimum hold time
|
// Auto‑release generated USB press after minimum hold time
|
||||||
const USB_MIN_HOLD_MS: u32 = 50;
|
const USB_MIN_HOLD_MS: u32 = 50;
|
||||||
if button.usb_press_active
|
let elapsed = current_time.saturating_sub(button.usb_press_start_time);
|
||||||
&& (!button.pressed
|
let should_release = if button.long_press_handled {
|
||||||
&& !button.long_press_handled
|
!button.enable_long_hold && elapsed >= USB_MIN_HOLD_MS
|
||||||
&& current_time - button.usb_press_start_time >= USB_MIN_HOLD_MS)
|
} else {
|
||||||
|| (!button.enable_long_hold
|
!button.pressed && elapsed >= USB_MIN_HOLD_MS
|
||||||
&& button.long_press_handled
|
};
|
||||||
&& current_time - button.usb_press_start_time >= USB_MIN_HOLD_MS)
|
|
||||||
|
if button.usb_press_active && should_release
|
||||||
{
|
{
|
||||||
button.usb_changed = true;
|
button.usb_changed = true;
|
||||||
button.usb_press_active = false;
|
button.usb_press_active = false;
|
||||||
@ -483,6 +489,37 @@ mod tests {
|
|||||||
assert!(button.long_press_handled);
|
assert!(button.long_press_handled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_button_press_type_long_press_auto_release_once() {
|
||||||
|
let mut button = Button::default();
|
||||||
|
button.usb_button_long = 2;
|
||||||
|
button.enable_long_press = true;
|
||||||
|
button.enable_long_hold = false;
|
||||||
|
|
||||||
|
// Press the button
|
||||||
|
button.pressed = true;
|
||||||
|
update_button_press_type(&mut button, 0);
|
||||||
|
button.previous_pressed = button.pressed;
|
||||||
|
|
||||||
|
// Hold long enough to trigger the long press path
|
||||||
|
update_button_press_type(&mut button, 250);
|
||||||
|
assert!(button.usb_press_active);
|
||||||
|
assert_eq!(button.active_usb_button, 2);
|
||||||
|
|
||||||
|
// Clear the changed flag to emulate USB stack observing it
|
||||||
|
button.usb_changed = false;
|
||||||
|
|
||||||
|
// Keep holding and ensure we auto-release exactly once
|
||||||
|
update_button_press_type(&mut button, 320);
|
||||||
|
assert!(!button.usb_press_active);
|
||||||
|
assert!(button.usb_changed);
|
||||||
|
|
||||||
|
button.usb_changed = false;
|
||||||
|
update_button_press_type(&mut button, 400);
|
||||||
|
assert!(!button.usb_press_active);
|
||||||
|
assert!(!button.usb_changed);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_timer_integration_method_exists() {
|
fn test_timer_integration_method_exists() {
|
||||||
let manager = ButtonManager::new();
|
let manager = ButtonManager::new();
|
||||||
|
|||||||
@ -135,7 +135,9 @@ impl CalibrationManager {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Save calibration data to storage
|
// Save calibration data to storage
|
||||||
let _ = storage::write_calibration_data(write_fn, &axis_data, self.gimbal_mode);
|
if storage::write_calibration_data(write_fn, &axis_data, self.gimbal_mode).is_err() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// End calibration mode
|
// End calibration mode
|
||||||
self.active = false;
|
self.active = false;
|
||||||
@ -519,6 +521,20 @@ mod tests {
|
|||||||
assert!(!manager.is_active()); // Should end calibration
|
assert!(!manager.is_active()); // Should end calibration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_save_calibration_failure_keeps_active() {
|
||||||
|
let mut manager = CalibrationManager::new();
|
||||||
|
manager.start_calibration();
|
||||||
|
let axes = [GimbalAxis::new(); NBR_OF_GIMBAL_AXIS];
|
||||||
|
|
||||||
|
let mut write_fn = |_page: u32, _data: &[u8]| Err(());
|
||||||
|
|
||||||
|
let result = manager.save_calibration(&axes, &mut write_fn);
|
||||||
|
|
||||||
|
assert!(!result);
|
||||||
|
assert!(manager.is_active());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_save_calibration_inactive() {
|
fn test_save_calibration_inactive() {
|
||||||
let mut manager = CalibrationManager::new(); // Note: not starting calibration
|
let mut manager = CalibrationManager::new(); // Note: not starting calibration
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user