Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNS - I2C ToF #26

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a76e007
initial commit
Aux1r Oct 14, 2024
6a1c274
initial ToF code
Aux1r Oct 17, 2024
f6d2c11
Merge branch 'main' into kacper/hype-27-implement-time-of-flight
Aux1r Oct 17, 2024
97bc9ae
updates to tof file
Aux1r Oct 24, 2024
ac06130
tof.rs updates, i2c.rs updates
Aux1r Oct 31, 2024
5a0f491
need to start writing tests now
Aux1r Nov 7, 2024
c5b556c
Merge branch 'main' into kacper/hype-27-implement-time-of-flight
Aux1r Nov 7, 2024
e2e0c7f
need to write tests, made some changes to i2c
Aux1r Nov 7, 2024
801c9fa
nearly done with tests
Aux1r Nov 14, 2024
15163d8
Tests & Task done
Aux1r Nov 14, 2024
c61d213
Merge branch 'main' into kacper/hype-27-implement-time-of-flight
Aux1r Nov 14, 2024
2a6465e
tof_test added + 16-bit changes
Aux1r Nov 14, 2024
d3f4eec
add semicolons
Aux1r Nov 14, 2024
c15a348
hopefully fixed clippy
Aux1r Nov 14, 2024
c3ea4cc
clippy please
Aux1r Nov 14, 2024
5706f91
check if range read test works
Aux1r Nov 16, 2024
344b048
see if board build works
Aux1r Nov 16, 2024
94051df
testing
Aux1r Nov 16, 2024
d8cc8a9
fixing i2c.rs
Aux1r Nov 16, 2024
f48b519
please
Aux1r Nov 16, 2024
3ac350d
getting somewhere
Aux1r Nov 16, 2024
0e282c8
seeing where new() is failing
Aux1r Nov 16, 2024
e04407d
seeing where new() is failing part 2
Aux1r Nov 16, 2024
5173bbd
seeing where new() is failing part 3
Aux1r Nov 16, 2024
99cc6d6
seeing where new() is failing part 4
Aux1r Nov 16, 2024
a7732f6
seeing where new() is failing part 4
Aux1r Nov 16, 2024
f8a0be0
seeing where new() is failing part 5
Aux1r Nov 16, 2024
a846302
seeing where new() is failing part 6 PROGRESS
Aux1r Nov 16, 2024
a27d3e7
seeing where new() is failing part 7 PROGRESS
Aux1r Nov 16, 2024
db47381
finding the bad u8
Aux1r Nov 16, 2024
4c62b4d
finding the bad u8 part 2
Aux1r Nov 16, 2024
af4d1e0
try removing the bad u8
Aux1r Nov 16, 2024
98d4f0c
try removing the 2nd bad u8
Aux1r Nov 16, 2024
b17a295
try removing the 3rd bad u8
Aux1r Nov 16, 2024
e2a05e7
try removing the 4th bad u8, final one?
Aux1r Nov 16, 2024
66f4525
what
Aux1r Nov 16, 2024
dc0080c
what 2
Aux1r Nov 16, 2024
ae52a9b
what 3
Aux1r Nov 16, 2024
26a6ba1
what
Aux1r Nov 16, 2024
b5fd966
what
Aux1r Nov 16, 2024
123dc1c
please
Aux1r Nov 16, 2024
eb848b6
Hopefully tests work now
Aux1r Nov 16, 2024
345505d
run fmt and fix clippy
Aux1r Nov 16, 2024
24f29f5
run fmt and fix clippy 2
Aux1r Nov 16, 2024
c56810d
run fmt and fix clippy 3
Aux1r Nov 16, 2024
822a3c5
ToF sensor working!
davidbeechey Nov 20, 2024
f59f5f6
Check tests
Aux1r Nov 21, 2024
c246276
Fixing ToF Tests
Aux1r Nov 21, 2024
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
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions boards/stm32f767zi/src/io/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@ impl<'d> HypedI2c for Stm32f767ziI2c<'d> {
}
}

/// Read a byte from a register with a 16-bit address on a device
fn read_byte_16(&mut self, device_address: u8, register_address: u16) -> Option<u8> {
let register_addr_hi = (register_address >> 8) as u8 & 0xFF;
let register_addr_lo = register_address as u8 & 0xFF;
let mut read = [0];
let result = self.i2c.blocking_write_read(
device_address,
[register_addr_hi, register_addr_lo].as_ref(),
&mut read,
);
match result {
Ok(_) => Some(read[0]),
Err(_) => None,
}
}

/// Write a byte to a register on a device
fn write_byte_to_register(
&mut self,
Expand All @@ -41,6 +57,33 @@ impl<'d> HypedI2c for Stm32f767ziI2c<'d> {
}),
}
}

// Write a byte to a register with a 16-bit address on a device
fn write_byte_to_register_16(
&mut self,
device_address: u8,
register_address: u16,
data: u8,
) -> Result<(), I2cError> {
let register_addr_hi = (register_address >> 8) as u8;
let register_addr_lo = register_address as u8;
let result = self.i2c.blocking_write(
device_address,
[register_addr_hi, register_addr_lo, data].as_ref(),
);
match result {
Ok(_) => Ok(()),
Err(e) => Err(match e {
embassy_stm32::i2c::Error::Bus => I2cError::Bus,
embassy_stm32::i2c::Error::Arbitration => I2cError::Arbitration,
embassy_stm32::i2c::Error::Nack => I2cError::Nack,
embassy_stm32::i2c::Error::Timeout => I2cError::Timeout,
embassy_stm32::i2c::Error::Crc => I2cError::Crc,
embassy_stm32::i2c::Error::Overrun => I2cError::Overrun,
embassy_stm32::i2c::Error::ZeroLengthTransfer => I2cError::ZeroLengthTransfer,
}),
}
}
}

impl<'d> Stm32f767ziI2c<'d> {
Expand Down
2 changes: 2 additions & 0 deletions boards/stm32l476rg/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions boards/stm32l476rg/src/bin/tof_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![no_std]
#![no_main]

use embassy_executor::Spawner;
use embassy_time::{Duration, Timer};
use hyped_boards_stm32l476rg::tasks::tof::read_tof_range;
use {defmt_rtt as _, panic_probe as _};

#[embassy_executor::main]
async fn main(spawner: Spawner) -> ! {
spawner.spawn(read_tof_range()).unwrap();

loop {
Timer::after(Duration::from_secs(1)).await;
}
}
43 changes: 43 additions & 0 deletions boards/stm32l476rg/src/io/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@ impl<'d> HypedI2c for Stm32l476rgI2c<'d> {
}
}

/// Read a byte from a register with a 16-bit address on a device
fn read_byte_16(&mut self, device_address: u8, register_address: u16) -> Option<u8> {
let register_addr_hi = (register_address >> 8) as u8 & 0xFF;
let register_addr_lo = register_address as u8 & 0xFF;
let mut read = [0];
let result = self.i2c.blocking_write_read(
device_address,
[register_addr_hi, register_addr_lo].as_ref(),
&mut read,
);
match result {
Ok(_) => Some(read[0]),
Err(_) => None,
}
}

/// Write a byte to a register on a device
fn write_byte_to_register(
&mut self,
Expand All @@ -41,6 +57,33 @@ impl<'d> HypedI2c for Stm32l476rgI2c<'d> {
}),
}
}

// Write a byte to a register with a 16-bit address on a device
fn write_byte_to_register_16(
&mut self,
device_address: u8,
register_address: u16,
data: u8,
) -> Result<(), I2cError> {
let register_addr_hi = (register_address >> 8) as u8;
let register_addr_lo = register_address as u8;
let result = self.i2c.blocking_write(
device_address,
[register_addr_hi, register_addr_lo, data].as_ref(),
);
match result {
Ok(_) => Ok(()),
Err(e) => Err(match e {
embassy_stm32::i2c::Error::Bus => I2cError::Bus,
embassy_stm32::i2c::Error::Arbitration => I2cError::Arbitration,
embassy_stm32::i2c::Error::Nack => I2cError::Nack,
embassy_stm32::i2c::Error::Timeout => I2cError::Timeout,
embassy_stm32::i2c::Error::Crc => I2cError::Crc,
embassy_stm32::i2c::Error::Overrun => I2cError::Overrun,
embassy_stm32::i2c::Error::ZeroLengthTransfer => I2cError::ZeroLengthTransfer,
}),
}
}
}

impl<'d> Stm32l476rgI2c<'d> {
Expand Down
1 change: 1 addition & 0 deletions boards/stm32l476rg/src/tasks.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod keyence;
pub mod temperature;
pub mod tof;
34 changes: 34 additions & 0 deletions boards/stm32l476rg/src/tasks/tof.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use crate::io::i2c::Stm32l476rgI2c;
use defmt_rtt as _;
use embassy_stm32::i2c::I2c;
use embassy_stm32::time::Hertz;
use hyped_sensors::tof::{TimeOfFlight, ToFAddresses};

// Test task that continuously starts a single shot measurement and reads the result
#[embassy_executor::task]
pub async fn read_tof_range() -> ! {
let p = embassy_stm32::init(Default::default());
let i2c = I2c::new_blocking(p.I2C1, p.PB8, p.PB9, Hertz(100_000), Default::default());
let mut hyped_i2c = Stm32l476rgI2c::new(i2c);

let mut tof_sensor = TimeOfFlight::new(&mut hyped_i2c, ToFAddresses::Address29).expect(
"Failed to create Time of Flight sensor. Check the wiring and I2C address of the sensor.",
);

loop {
defmt::info!("Starting single shot measurement");
tof_sensor.start_ss_measure();
defmt::info!("Polling for range");
tof_sensor.poll_range().await;
defmt::info!("Reading range");
Aux1r marked this conversation as resolved.
Show resolved Hide resolved

match tof_sensor.read_range() {
Some(range) => {
defmt::info!("Range: {:?}", range)
davidbeechey marked this conversation as resolved.
Show resolved Hide resolved
}
None => {
defmt::info!("Failed to read range")
}
}
}
}
35 changes: 33 additions & 2 deletions lib/io/src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,26 @@ pub enum I2cError {
/// I2C trait used to abstract the I2C peripheral
pub trait HypedI2c {
fn read_byte(&mut self, device_address: u8, register_address: u8) -> Option<u8>;
fn read_byte_16(&mut self, device_address: u8, register_address: u16) -> Option<u8>;
fn write_byte_to_register(
&mut self,
device_address: u8,
register_address: u8,
data: u8,
) -> Result<(), I2cError>;
fn write_byte_to_register_16(
&mut self,
device_address: u8,
register_address: u16,
data: u8,
) -> Result<(), I2cError>;
}

pub mod mock_i2c {
use heapless::FnvIndexMap;

/// A fixed-size map of I2C values, indexed by device address and register address
type I2cValues = FnvIndexMap<(u8, u8), Option<u8>, 16>;
type I2cValues = FnvIndexMap<(u8, u16), Option<u8>, 64>;

/// A mock I2C instance which can be used for testing
pub struct MockI2c {
Expand All @@ -38,18 +45,42 @@ pub mod mock_i2c {
impl crate::i2c::HypedI2c for MockI2c {
/// Reads a byte by looking up the device address and register address in the map
fn read_byte(&mut self, device_address: u8, register_address: u8) -> Option<u8> {
self.values
.get(&(device_address, register_address.into()))
.copied()
.unwrap()
}

/// Reads a byte by looking up the device address and register address in the map
fn read_byte_16(&mut self, device_address: u8, register_address: u16) -> Option<u8> {
self.values
.get(&(device_address, register_address))
.copied()
.unwrap()
}

/// Writes a byte to the map so that it can be read later to check the value
/// Writes a byte to the map 9with 8-bit register address) so that it can be read later to check the value

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: 9 should be (

fn write_byte_to_register(
&mut self,
device_address: u8,
register_address: u8,
data: u8,
) -> Result<(), super::I2cError> {
match self
.writes
.insert((device_address, register_address.into()), Some(data))
{
Ok(_) => Ok(()),
Err(_) => Err(super::I2cError::Unknown),
}
}

/// Writes a byte to the map (with 16-bit register address) so that it can be read later to check the value
fn write_byte_to_register_16(
&mut self,
device_address: u8,
register_address: u16,
data: u8,
) -> Result<(), super::I2cError> {
match self
.writes
Expand Down
2 changes: 2 additions & 0 deletions lib/sensors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ edition = "2021"

[dependencies]
heapless = "0.8.0"
defmt = "0.3.8"
embassy-time = { version = "0.3.1", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"], git = "https://github.com/embassy-rs/embassy", rev = "1c466b81e6af6b34b1f706318cc0870a459550b7"}

hyped_core = { path = "../core" }
hyped_io = { path = "../io" }
Expand Down
1 change: 1 addition & 0 deletions lib/sensors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

pub mod keyence;
pub mod temperature;
pub mod tof;
38 changes: 28 additions & 10 deletions lib/sensors/src/temperature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ mod tests {
let _ = Temperature::new(&mut i2c, TemperatureAddresses::Address3f);
assert_eq!(
i2c.get_writes()
.get(&(TemperatureAddresses::Address3f as u8, STTS22H_CTRL)),
.get(&(TemperatureAddresses::Address3f as u8, STTS22H_CTRL.into())),
Some(&Some(STTS22H_CONFIG_SETTINGS))
);
}
Expand All @@ -146,11 +146,17 @@ mod tests {
fn test_temperature_read_0() {
let mut i2c_values = FnvIndexMap::new();
let _ = i2c_values.insert(
(TemperatureAddresses::Address3f as u8, STTS22H_DATA_TEMP_H),
(
TemperatureAddresses::Address3f as u8,
STTS22H_DATA_TEMP_H as u16,
),
Some(0x00),
);
let _ = i2c_values.insert(
(TemperatureAddresses::Address3f as u8, STTS22H_DATA_TEMP_L),
(
TemperatureAddresses::Address3f as u8,
STTS22H_DATA_TEMP_L as u16,
),
Some(0x00),
);
let mut i2c = MockI2c::new(i2c_values);
Expand All @@ -162,11 +168,17 @@ mod tests {
fn test_temperature_read_25() {
let mut i2c_values = FnvIndexMap::new();
let _ = i2c_values.insert(
(TemperatureAddresses::Address3f as u8, STTS22H_DATA_TEMP_H),
(
TemperatureAddresses::Address3f as u8,
STTS22H_DATA_TEMP_H as u16,
),
Some(0x09),
);
let _ = i2c_values.insert(
(TemperatureAddresses::Address3f as u8, STTS22H_DATA_TEMP_L),
(
TemperatureAddresses::Address3f as u8,
STTS22H_DATA_TEMP_L as u16,
),
Some(0xc4),
);
let mut i2c = MockI2c::new(i2c_values);
Expand All @@ -178,11 +190,17 @@ mod tests {
fn test_temperature_read_minus_10() {
let mut i2c_values = FnvIndexMap::new();
let _ = i2c_values.insert(
(TemperatureAddresses::Address3f as u8, STTS22H_DATA_TEMP_H),
(
TemperatureAddresses::Address3f as u8,
STTS22H_DATA_TEMP_H as u16,
),
Some(0xfc),
);
let _ = i2c_values.insert(
(TemperatureAddresses::Address3f as u8, STTS22H_DATA_TEMP_L),
(
TemperatureAddresses::Address3f as u8,
STTS22H_DATA_TEMP_L as u16,
),
Some(0x18),
);
let mut i2c = MockI2c::new(i2c_values);
Expand All @@ -194,7 +212,7 @@ mod tests {
fn test_temperature_status_busy() {
let mut i2c_values = FnvIndexMap::new();
let _ = i2c_values.insert(
(TemperatureAddresses::Address3f as u8, STTS22H_STATUS),
(TemperatureAddresses::Address3f as u8, STTS22H_STATUS.into()),
Some(STTS22H_STATUS_BUSY),
);
let mut i2c = MockI2c::new(i2c_values);
Expand All @@ -206,7 +224,7 @@ mod tests {
fn test_temperature_status_temp_over_upper_limit() {
let mut i2c_values = FnvIndexMap::new();
let _ = i2c_values.insert(
(TemperatureAddresses::Address3f as u8, STTS22H_STATUS),
(TemperatureAddresses::Address3f as u8, STTS22H_STATUS.into()),
Some(STTS22H_TEMP_OVER_UPPER_LIMIT),
);
let mut i2c = MockI2c::new(i2c_values);
Expand All @@ -218,7 +236,7 @@ mod tests {
fn test_temperature_status_temp_under_lower_limit() {
let mut i2c_values = FnvIndexMap::new();
let _ = i2c_values.insert(
(TemperatureAddresses::Address3f as u8, STTS22H_STATUS),
(TemperatureAddresses::Address3f as u8, STTS22H_STATUS.into()),
Some(STTS22H_TEMP_UNDER_LOWER_LIMIT),
);
let mut i2c = MockI2c::new(i2c_values);
Expand Down
Loading
Loading