Skip to content
Closed
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
17 changes: 13 additions & 4 deletions src/libs/camera/camera.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: EUPL-1.2

use crate::libs::camera::enums::{AIMode, ExposureMode, SleepMode, TrackingSpeed};
use crate::libs::camera::frame::FrameSequence;
use crate::libs::camera::status::CameraStatus;
use crate::libs::camera::transport::CameraTransport;
use crate::libs::errors::T4lError;
Expand All @@ -13,13 +14,15 @@ use errno::Errno;
pub struct Camera {
transport: CameraTransport,
debugging: bool,
sequence: FrameSequence,
}

impl Camera {
pub fn new(hint: &str) -> Result<Self, T4lError> {
Ok(Self {
transport: CameraTransport::new(hint)?,
debugging: false,
sequence: FrameSequence::new(),
})
}

Expand All @@ -31,6 +34,11 @@ impl Camera {
self.transport.send_cmd(unit, selector, cmd, self.debugging)
}

/// Returns a fresh sequence number for the next framed command (unit 2, selector 2).
pub fn next_sequence_nr(&self) -> u16 {
self.sequence.next()
}

pub fn get_status(&self) -> Result<CameraStatus, T4lError> {
self.transport.get_status(self.debugging)
}
Expand Down Expand Up @@ -63,7 +71,7 @@ pub trait Tiny2Camera {

impl Tiny2Camera for Camera {
fn set_sleep_mode(&self, mode: SleepMode) -> Result<(), T4lError> {
let cmd = SleepCommand::build(mode)?;
let cmd = SleepCommand::build(mode, self.next_sequence_nr())?;

self.send_cmd(0x2, 0x2, &cmd)
}
Expand All @@ -83,7 +91,7 @@ impl Tiny2Camera for Camera {
}

fn goto_preset_position(&self, preset_nr: i8) -> Result<(), T4lError> {
let cmd = GotoPresetPositionCommand::build(preset_nr)?;
let cmd = GotoPresetPositionCommand::build(preset_nr, self.next_sequence_nr())?;

self.send_cmd(0x2, 0x2, &cmd)
}
Expand All @@ -93,7 +101,7 @@ impl Tiny2Camera for Camera {
}

fn set_tracking_speed(&self, speed: TrackingSpeed) -> Result<(), T4lError> {
let cmd = TrackingSpeedCommand::build(speed)?;
let cmd = TrackingSpeedCommand::build(speed, self.next_sequence_nr())?;

self.get_status()?.speed = speed;

Expand All @@ -107,7 +115,8 @@ impl Tiny2Camera for Camera {
}

fn set_exposure_mode(&self, mode: ExposureMode) -> Result<(), T4lError> {
let exposure_mode_type_command = ExposureModeTypeCommand::build(mode);
let exposure_mode_type_command =
ExposureModeTypeCommand::build(mode, self.next_sequence_nr());

self.send_cmd(0x2, 0x2, &exposure_mode_type_command)?;

Expand Down
113 changes: 0 additions & 113 deletions src/libs/camera/command02.rs

This file was deleted.

87 changes: 20 additions & 67 deletions src/libs/camera/commands/exposure_mode_type.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
// SPDX-License-Identifier: EUPL-1.2

use crate::{ExposureMode, command02};
use crate::{ExposureMode, frame};

pub struct ExposureModeTypeCommand;

impl ExposureModeTypeCommand {
pub fn build(mode: ExposureMode) -> [u8; 36] {
const FUNCTION_GROUP_EXPOSURE_MODE_TYPE: [u8; 6] = [0x0a, 0x02, 0x82, 0x29, 0x05, 0x00];
const RECEIVER: u8 = 0x02;
const COMMAND: u16 = 0x2982;

let (sequence_nr, checksum, command) = if mode == ExposureMode::Manual {
(
[0x16, 0x00],
[0x58, 0x91],
[0xb2, 0xaf, 0x02, 0x04, 0x00, 0x00],
)
pub fn build(mode: ExposureMode, sequence_nr: u16) -> [u8; 60] {
let data: [u8; 5] = if mode == ExposureMode::Manual {
[0x02, 0x04, 0x00, 0x00, 0x00]
} else {
(
[0x15, 0x00],
[0xa8, 0x9e],
[0xf9, 0x27, 0x01, 0x32, 0x00, 0x00],
)
[0x01, 0x32, 0x00, 0x00, 0x00]
};

command02()
.function_group(FUNCTION_GROUP_EXPOSURE_MODE_TYPE)
frame()
.receiver(Self::RECEIVER)
.command(Self::COMMAND)
.data(&data)
.sequence_nr(sequence_nr)
.checksum(checksum)
.command(command)
.build()
}
}
Expand All @@ -36,56 +29,16 @@ mod tests {
use crate::{ExposureMode, ExposureModeTypeCommand};
use test_case::test_case;

#[test]
fn manual_exposure_mode() {
let exposure_command = ExposureModeTypeCommand::build(ExposureMode::Manual);
// Captured frames, reproduced byte for byte when given the captured sequence number.
#[test_case(ExposureMode::Manual, 0x0016, "aa2516000c0058910a0282290500b2af0204000000"; "manual exposure")]
#[test_case(ExposureMode::Global, 0x0015, "aa2515000c00a89e0a0282290500f9270132000000"; "global automatic exposure")]
#[test_case(ExposureMode::Face, 0x0015, "aa2515000c00a89e0a0282290500f9270132000000"; "face automatic exposure")]
fn exposure_mode_type(mode: ExposureMode, sequence_nr: u16, captured: &str) {
let captured = hex::decode(captured).unwrap();

assert_eq!(
exposure_command[8..14],
[0x0a, 0x02, 0x82, 0x29, 0x05, 0x00],
"Function group should be set for exposure mode type"
);
assert_eq!(
exposure_command[2..4],
[0x16, 0x00],
"Sequence number should be set"
);
assert_eq!(
exposure_command[6..8],
[0x58, 0x91],
"Checksum should be set"
);
assert_eq!(
exposure_command[14..20],
[0xb2, 0xaf, 0x02, 0x04, 0x00, 0x00],
"Command should be set"
);
}

#[test_case(ExposureMode::Global; "global automatic exposure should be set")]
#[test_case(ExposureMode::Face; "face automatic exposure should be set")]
fn automatic_exposure_modes(mode: ExposureMode) {
let exposure_command = ExposureModeTypeCommand::build(mode);
let command = ExposureModeTypeCommand::build(mode, sequence_nr);

assert_eq!(
exposure_command[8..14],
[0x0a, 0x02, 0x82, 0x29, 0x05, 0x00],
"Function group should be set for exposure mode type"
);
assert_eq!(
exposure_command[2..4],
[0x15, 0x00],
"Sequence number should be set"
);
assert_eq!(
exposure_command[6..8],
[0xa8, 0x9e],
"Checksum should be set"
);
assert_eq!(
exposure_command[14..20],
[0xf9, 0x27, 0x01, 0x32, 0x00, 0x00],
"Command should be set"
);
assert_eq!(command[..captured.len()], captured[..]);
assert!(command[captured.len()..].iter().all(|b| *b == 0));
}
}
Loading