Skip to content

Commit

Permalink
Adjust BSP I2C examples
Browse files Browse the repository at this point in the history
  • Loading branch information
jbeaurivage committed Oct 24, 2024
1 parent 70740b9 commit c5c4cb1
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 96 deletions.
26 changes: 8 additions & 18 deletions boards/feather_m0/examples/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ use hal::ehal::i2c::I2c;
use hal::fugit::RateExtU32;
use hal::sercom::i2c;

const LENGTH: usize = 1;
const ADDRESS: u8 = 0x77;
// This example is based on the BMP388 pressure sensor. Adjust the device and
// register addresses to your liking
const ADDRESS: u8 = 0x76;

#[entry]
fn main() -> ! {
Expand All @@ -48,31 +49,20 @@ fn main() -> ! {
let channels = dmac.split();
let chan0 = channels.0.init(PriorityLevel::Lvl0);

let buf_src: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();
let buf_dest: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();

let gclk0 = clocks.gclk0();
let sercom3_clock = &clocks.sercom3_core(&gclk0).unwrap();
let pads = i2c::Pads::new(sda, scl);
let mut i2c = i2c::Config::new(&pm, peripherals.sercom3, pads, sercom3_clock.freq())
.baud(100.kHz())
.enable();
.enable()
.with_dma_channel(chan0);

let mut buffer = [0x00; 1];
let mut received = [0x00; 1];

// Test writing then reading from an I2C chip
i2c.write_read(ADDRESS, &[0x00], &mut buffer).unwrap();

// Test writing then reading using DMA
let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.send_with_dma(ADDRESS, init_token, buf_src, chan0, |_| {});
let (chan0, _buf_src, mut i2c) = xfer.wait();
i2c.write_read(ADDRESS, &[0x00; 8], &mut received).unwrap();

let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.receive_with_dma(ADDRESS, init_token, buf_dest, chan0, |_| {});
let (_chan0, _i2c, _buf_dest) = xfer.wait();
defmt::info!("Received: {:#x}", received);

loop {
// Go to sleep
Expand Down
26 changes: 8 additions & 18 deletions boards/feather_m4/examples/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ use hal::ehal::i2c::I2c;
use hal::fugit::RateExtU32;
use hal::sercom::i2c;

const LENGTH: usize = 1;
const ADDRESS: u8 = 0x77;
// This example is based on the BMP388 pressure sensor. Adjust the device and
// register addresses to your liking
const ADDRESS: u8 = 0x76;

#[entry]
fn main() -> ! {
Expand All @@ -49,32 +50,21 @@ fn main() -> ! {
let channels = dmac.split();
let chan0 = channels.0.init(PriorityLevel::Lvl0);

let buf_src: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();
let buf_dest: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();

let gclk0 = clocks.gclk0();
let sercom2_clock = &clocks.sercom2_core(&gclk0).unwrap();
let pads = i2c::Pads::new(sda, scl);
let i2c_sercom = periph_alias!(peripherals.i2c_sercom);
let mut i2c = i2c::Config::new(&mclk, i2c_sercom, pads, sercom2_clock.freq())
.baud(100.kHz())
.enable();
.enable()
.with_dma_channel(chan0);

let mut buffer = [0x00; 1];
let mut received = [0x00; 1];

// Test writing then reading from an I2C chip
i2c.write_read(ADDRESS, &[0x00], &mut buffer).unwrap();

// Test writing then reading using DMA
let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.send_with_dma(ADDRESS, init_token, buf_src, chan0, |_| {});
let (chan0, _buf_src, mut i2c) = xfer.wait();
i2c.write_read(ADDRESS, &[0x00; 8], &mut received).unwrap();

let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.receive_with_dma(ADDRESS, init_token, buf_dest, chan0, |_| {});
let (_chan0, _i2c, _buf_dest) = xfer.wait();
defmt::info!("Received: {:#x}", received);

loop {
// Go to sleep
Expand Down
26 changes: 8 additions & 18 deletions boards/metro_m0/examples/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ use hal::ehal::i2c::I2c;
use hal::fugit::RateExtU32;
use hal::sercom::i2c;

const LENGTH: usize = 1;
const ADDRESS: u8 = 0x77;
// This example is based on the BMP388 pressure sensor. Adjust the device and
// register addresses to your liking
const ADDRESS: u8 = 0x76;

#[entry]
fn main() -> ! {
Expand All @@ -48,31 +49,20 @@ fn main() -> ! {
let channels = dmac.split();
let chan0 = channels.0.init(PriorityLevel::Lvl0);

let buf_src: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();
let buf_dest: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();

let gclk0 = clocks.gclk0();
let sercom3_clock = &clocks.sercom3_core(&gclk0).unwrap();
let pads = i2c::Pads::new(sda, scl);
let mut i2c = i2c::Config::new(&pm, peripherals.sercom3, pads, sercom3_clock.freq())
.baud(100.kHz())
.enable();
.enable()
.with_dma_channel(chan0);

let mut buffer = [0x00; 1];
let mut received = [0x00; 1];

// Test writing then reading from an I2C chip
i2c.write_read(ADDRESS, &[0x00], &mut buffer).unwrap();

// Test writing then reading using DMA
let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.send_with_dma(ADDRESS, init_token, buf_src, chan0, |_| {});
let (chan0, _buf_src, mut i2c) = xfer.wait();
i2c.write_read(ADDRESS, &[0x00; 8], &mut received).unwrap();

let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.receive_with_dma(ADDRESS, init_token, buf_dest, chan0, |_| {});
let (_chan0, _i2c, _buf_dest) = xfer.wait();
defmt::info!("Received: {:#x}", received);

loop {
// Go to sleep
Expand Down
28 changes: 9 additions & 19 deletions boards/metro_m4/examples/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#![no_main]

#[cfg(not(feature = "use_semihosting"))]
use panic_halt as _;
// use panic_halt as _;
#[cfg(feature = "use_semihosting")]
use panic_semihosting as _;

Expand All @@ -23,8 +23,9 @@ use hal::ehal::i2c::I2c;
use hal::fugit::RateExtU32;
use hal::sercom::i2c;

const LENGTH: usize = 1;
const ADDRESS: u8 = 0x77;
// This example is based on the BMP388 pressure sensor. Adjust the device and
// register addresses to your liking
const ADDRESS: u8 = 0x76;

#[entry]
fn main() -> ! {
Expand All @@ -49,32 +50,21 @@ fn main() -> ! {
let channels = dmac.split();
let chan0 = channels.0.init(PriorityLevel::Lvl0);

let buf_src: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();
let buf_dest: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();

let gclk0 = clocks.gclk0();
let sercom5_clock = &clocks.sercom5_core(&gclk0).unwrap();
let pads = i2c::Pads::new(sda, scl);
let i2c_sercom = periph_alias!(peripherals.i2c_sercom);
let mut i2c = i2c::Config::new(&mclk, i2c_sercom, pads, sercom5_clock.freq())
.baud(100.kHz())
.enable();
.enable()
.with_dma_channel(chan0);

let mut buffer = [0x00; 1];
let mut received = [0x00; 1];

// Test writing then reading from an I2C chip
i2c.write_read(ADDRESS, &[0x00], &mut buffer).unwrap();

// Test writing then reading using DMA
let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.send_with_dma(ADDRESS, init_token, buf_src, chan0, |_| {});
let (chan0, _buf_src, mut i2c) = xfer.wait();
i2c.write_read(ADDRESS, &[0x00; 8], &mut received).unwrap();

let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.receive_with_dma(ADDRESS, init_token, buf_dest, chan0, |_| {});
let (_chan0, _i2c, _buf_dest) = xfer.wait();
defmt::info!("Received: {:#x}", received);

loop {
// Go to sleep
Expand Down
26 changes: 8 additions & 18 deletions boards/samd11_bare/examples/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ use hal::ehal::i2c::I2c;
use hal::fugit::RateExtU32;
use hal::sercom::i2c;

const LENGTH: usize = 1;
const ADDRESS: u8 = 0x77;
// This example is based on the BMP388 pressure sensor. Adjust the device and
// register addresses to your liking
const ADDRESS: u8 = 0x76;

#[entry]
fn main() -> ! {
Expand All @@ -48,31 +49,20 @@ fn main() -> ! {
let channels = dmac.split();
let chan0 = channels.0.init(PriorityLevel::Lvl0);

let buf_src: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();
let buf_dest: &'static mut [u8; LENGTH] =
cortex_m::singleton!(: [u8; LENGTH] = [0x00; LENGTH]).unwrap();

let gclk0 = clocks.gclk0();
let sercom0_clock = &clocks.sercom0_core(&gclk0).unwrap();
let pads = i2c::Pads::new(sda, scl);
let mut i2c = i2c::Config::new(&pm, peripherals.sercom0, pads, sercom0_clock.freq())
.baud(100.kHz())
.enable();
.enable()
.with_dma_channel(chan0);

let mut buffer = [0x00; 1];
let mut received = [0x00; 1];

// Test writing then reading from an I2C chip
i2c.write_read(ADDRESS, &[0x00], &mut buffer).unwrap();

// Test writing then reading using DMA
let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.send_with_dma(ADDRESS, init_token, buf_src, chan0, |_| {});
let (chan0, _buf_src, mut i2c) = xfer.wait();
i2c.write_read(ADDRESS, &[0x00; 8], &mut received).unwrap();

let init_token = i2c.init_dma_transfer().unwrap();
let xfer = i2c.receive_with_dma(ADDRESS, init_token, buf_dest, chan0, |_| {});
let (_chan0, _i2c, _buf_dest) = xfer.wait();
defmt::info!("Received: {:#x}", received);

loop {
// Go to sleep
Expand Down
13 changes: 8 additions & 5 deletions hal/src/sercom/i2c/impl_ehal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ mod dma {
SercomPtr(self.data_ptr())
}

/// Walk up the transfer linked list, and calculate the number of beats the entire block list contains.
/// Walk up the transfer linked list, and calculate the number of beats
/// the entire block list contains.
///
/// # Safety
///
Expand Down Expand Up @@ -152,8 +153,8 @@ mod dma {
/// with the descriptor it points to, etc, must point to a valid
/// [`DmacDescriptor`] memory location, or be null. They must not be
/// circular (ie, points to itself). Any linked transfer must
/// strictly be a read transaction (destination pointer is a byte buffer,
/// source pointer is the SERCOM DATA register).
/// strictly be a read transaction (destination pointer is a byte
/// buffer, source pointer is the SERCOM DATA register).
#[inline]
unsafe fn read_linked(
&mut self,
Expand All @@ -168,7 +169,8 @@ mod dma {
return Ok(());
}

// Calculate the total number of bytes for this transaction across all linked transfers, including the first transfer.
// Calculate the total number of bytes for this transaction across all linked
// transfers, including the first transfer.
let transfer_len = dest.len() + Self::linked_transfer_length(&next);

assert!(
Expand Down Expand Up @@ -220,7 +222,8 @@ mod dma {
return Ok(());
}

// Calculate the total number of bytes for this transaction across all linked transfers, including the first transfer.
// Calculate the total number of bytes for this transaction across all linked
// transfers, including the first transfer.
let transfer_len = source.len() + Self::linked_transfer_length(&next);

assert!(
Expand Down

0 comments on commit c5c4cb1

Please sign in to comment.