2021-05-11 03:07:37 +02:00
#![ macro_use ]
//! HAL interface to the TWIM peripheral.
//!
//! See product specification:
//!
//! - nRF52832: Section 33
//! - nRF52840: Section 6.31
2021-06-04 17:31:35 +02:00
use core ::future ::Future ;
2021-05-11 03:07:37 +02:00
use core ::marker ::PhantomData ;
use core ::sync ::atomic ::{ compiler_fence , Ordering ::SeqCst } ;
2021-06-04 17:31:35 +02:00
use core ::task ::Poll ;
2021-05-11 03:07:37 +02:00
use embassy ::interrupt ::{ Interrupt , InterruptExt } ;
2021-09-11 01:53:53 +02:00
use embassy ::util ::Unborrow ;
use embassy ::waitqueue ::AtomicWaker ;
2021-07-29 13:44:51 +02:00
use embassy_hal_common ::unborrow ;
2021-06-04 17:31:35 +02:00
use futures ::future ::poll_fn ;
2021-05-11 03:07:37 +02:00
use crate ::chip ::{ EASY_DMA_SIZE , FORCE_COPY_BUFFER_SIZE } ;
2021-06-07 00:10:54 +02:00
use crate ::gpio ;
2021-05-11 03:07:37 +02:00
use crate ::gpio ::Pin as GpioPin ;
use crate ::pac ;
use crate ::util ::{ slice_in_ram , slice_in_ram_or } ;
pub enum Frequency {
#[ doc = " 26738688: 100 kbps " ]
K100 = 26738688 ,
#[ doc = " 67108864: 250 kbps " ]
K250 = 67108864 ,
#[ doc = " 104857600: 400 kbps " ]
K400 = 104857600 ,
}
#[ non_exhaustive ]
pub struct Config {
pub frequency : Frequency ,
2021-05-26 18:15:05 +02:00
pub sda_pullup : bool ,
pub scl_pullup : bool ,
2021-05-11 03:07:37 +02:00
}
impl Default for Config {
fn default ( ) -> Self {
Self {
frequency : Frequency ::K100 ,
2021-05-26 18:15:05 +02:00
sda_pullup : false ,
scl_pullup : false ,
2021-05-11 03:07:37 +02:00
}
}
}
2022-01-13 23:56:25 +01:00
#[ derive(Debug, Copy, Clone, Eq, PartialEq) ]
#[ cfg_attr(feature = " defmt " , derive(defmt::Format)) ]
#[ non_exhaustive ]
pub enum Error {
TxBufferTooLong ,
RxBufferTooLong ,
TxBufferZeroLength ,
RxBufferZeroLength ,
Transmit ,
Receive ,
DMABufferNotInDataMemory ,
AddressNack ,
DataNack ,
Overrun ,
}
2022-03-08 16:42:46 +01:00
/// Interface to a TWIM instance using EasyDMA to offload the transmission and reception workload.
///
/// For more details about EasyDMA, consult the module documentation.
2021-05-11 03:07:37 +02:00
pub struct Twim < ' d , T : Instance > {
phantom : PhantomData < & ' d mut T > ,
}
impl < ' d , T : Instance > Twim < ' d , T > {
pub fn new (
2021-05-17 12:23:04 +02:00
_twim : impl Unborrow < Target = T > + ' d ,
2021-05-11 03:07:37 +02:00
irq : impl Unborrow < Target = T ::Interrupt > + ' d ,
sda : impl Unborrow < Target = impl GpioPin > + ' d ,
scl : impl Unborrow < Target = impl GpioPin > + ' d ,
config : Config ,
) -> Self {
2021-05-17 12:23:04 +02:00
unborrow! ( irq , sda , scl ) ;
2021-05-11 03:07:37 +02:00
let r = T ::regs ( ) ;
// Configure pins
sda . conf ( ) . write ( | w | {
w . dir ( ) . input ( ) ;
w . input ( ) . connect ( ) ;
w . drive ( ) . s0d1 ( ) ;
2021-05-26 18:15:05 +02:00
if config . sda_pullup {
w . pull ( ) . pullup ( ) ;
}
2021-05-11 03:07:37 +02:00
w
} ) ;
scl . conf ( ) . write ( | w | {
w . dir ( ) . input ( ) ;
w . input ( ) . connect ( ) ;
w . drive ( ) . s0d1 ( ) ;
2021-05-26 18:15:05 +02:00
if config . scl_pullup {
w . pull ( ) . pullup ( ) ;
}
2021-05-11 03:07:37 +02:00
w
} ) ;
// Select pins.
r . psel . sda . write ( | w | unsafe { w . bits ( sda . psel_bits ( ) ) } ) ;
r . psel . scl . write ( | w | unsafe { w . bits ( scl . psel_bits ( ) ) } ) ;
// Enable TWIM instance.
r . enable . write ( | w | w . enable ( ) . enabled ( ) ) ;
// Configure frequency.
r . frequency
. write ( | w | unsafe { w . frequency ( ) . bits ( config . frequency as u32 ) } ) ;
// Disable all events interrupts
r . intenclr . write ( | w | unsafe { w . bits ( 0xFFFF_FFFF ) } ) ;
irq . set_handler ( Self ::on_interrupt ) ;
irq . unpend ( ) ;
irq . enable ( ) ;
Self {
phantom : PhantomData ,
}
}
fn on_interrupt ( _ : * mut ( ) ) {
let r = T ::regs ( ) ;
let s = T ::state ( ) ;
if r . events_stopped . read ( ) . bits ( ) ! = 0 {
s . end_waker . wake ( ) ;
r . intenclr . write ( | w | w . stopped ( ) . clear ( ) ) ;
}
if r . events_error . read ( ) . bits ( ) ! = 0 {
s . end_waker . wake ( ) ;
r . intenclr . write ( | w | w . error ( ) . clear ( ) ) ;
}
}
/// Set TX buffer, checking that it is in RAM and has suitable length.
unsafe fn set_tx_buffer ( & mut self , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
slice_in_ram_or ( buffer , Error ::DMABufferNotInDataMemory ) ? ;
if buffer . len ( ) = = 0 {
return Err ( Error ::TxBufferZeroLength ) ;
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::TxBufferTooLong ) ;
}
let r = T ::regs ( ) ;
r . txd . ptr . write ( | w |
// We're giving the register a pointer to the stack. Since we're
// waiting for the I2C transaction to end before this stack pointer
// becomes invalid, there's nothing wrong here.
//
// The PTR field is a full 32 bits wide and accepts the full range
// of values.
w . ptr ( ) . bits ( buffer . as_ptr ( ) as u32 ) ) ;
r . txd . maxcnt . write ( | w |
// We're giving it the length of the buffer, so no danger of
// accessing invalid memory. We have verified that the length of the
// buffer fits in an `u8`, so the cast to `u8` is also fine.
//
// The MAXCNT field is 8 bits wide and accepts the full range of
// values.
w . maxcnt ( ) . bits ( buffer . len ( ) as _ ) ) ;
Ok ( ( ) )
}
/// Set RX buffer, checking that it has suitable length.
unsafe fn set_rx_buffer ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
// NOTE: RAM slice check is not necessary, as a mutable
// slice can only be built from data located in RAM.
if buffer . len ( ) = = 0 {
return Err ( Error ::RxBufferZeroLength ) ;
}
if buffer . len ( ) > EASY_DMA_SIZE {
return Err ( Error ::RxBufferTooLong ) ;
}
let r = T ::regs ( ) ;
r . rxd . ptr . write ( | w |
// We're giving the register a pointer to the stack. Since we're
// waiting for the I2C transaction to end before this stack pointer
// becomes invalid, there's nothing wrong here.
//
// The PTR field is a full 32 bits wide and accepts the full range
// of values.
w . ptr ( ) . bits ( buffer . as_mut_ptr ( ) as u32 ) ) ;
r . rxd . maxcnt . write ( | w |
// We're giving it the length of the buffer, so no danger of
// accessing invalid memory. We have verified that the length of the
// buffer fits in an `u8`, so the cast to the type of maxcnt
// is also fine.
//
// Note that that nrf52840 maxcnt is a wider
// type than a u8, so we use a `_` cast rather than a `u8` cast.
// The MAXCNT field is thus at least 8 bits wide and accepts the
// full range of values that fit in a `u8`.
w . maxcnt ( ) . bits ( buffer . len ( ) as _ ) ) ;
Ok ( ( ) )
}
fn clear_errorsrc ( & mut self ) {
let r = T ::regs ( ) ;
r . errorsrc
. write ( | w | w . anack ( ) . bit ( true ) . dnack ( ) . bit ( true ) . overrun ( ) . bit ( true ) ) ;
}
/// Get Error instance, if any occurred.
2022-01-13 20:47:28 +01:00
fn check_errorsrc ( & self ) -> Result < ( ) , Error > {
2021-05-11 03:07:37 +02:00
let r = T ::regs ( ) ;
let err = r . errorsrc . read ( ) ;
if err . anack ( ) . is_received ( ) {
return Err ( Error ::AddressNack ) ;
}
if err . dnack ( ) . is_received ( ) {
return Err ( Error ::DataNack ) ;
}
if err . overrun ( ) . is_received ( ) {
return Err ( Error ::DataNack ) ;
}
Ok ( ( ) )
}
2022-01-13 20:47:28 +01:00
fn check_rx ( & self , len : usize ) -> Result < ( ) , Error > {
let r = T ::regs ( ) ;
if r . rxd . amount . read ( ) . bits ( ) ! = len as u32 {
Err ( Error ::Receive )
} else {
Ok ( ( ) )
}
}
fn check_tx ( & self , len : usize ) -> Result < ( ) , Error > {
let r = T ::regs ( ) ;
if r . txd . amount . read ( ) . bits ( ) ! = len as u32 {
Err ( Error ::Transmit )
} else {
Ok ( ( ) )
}
}
2021-05-11 03:07:37 +02:00
/// Wait for stop or error
2022-01-13 20:47:28 +01:00
fn blocking_wait ( & mut self ) {
2021-05-11 03:07:37 +02:00
let r = T ::regs ( ) ;
loop {
if r . events_stopped . read ( ) . bits ( ) ! = 0 {
r . events_stopped . reset ( ) ;
break ;
}
if r . events_error . read ( ) . bits ( ) ! = 0 {
r . events_error . reset ( ) ;
r . tasks_stop . write ( | w | unsafe { w . bits ( 1 ) } ) ;
}
}
}
2022-01-13 20:47:28 +01:00
/// Wait for stop or error
fn async_wait ( & mut self ) -> impl Future < Output = ( ) > {
poll_fn ( move | cx | {
let r = T ::regs ( ) ;
let s = T ::state ( ) ;
s . end_waker . register ( cx . waker ( ) ) ;
if r . events_stopped . read ( ) . bits ( ) ! = 0 {
r . events_stopped . reset ( ) ;
return Poll ::Ready ( ( ) ) ;
}
// stop if an error occured
if r . events_error . read ( ) . bits ( ) ! = 0 {
r . events_error . reset ( ) ;
r . tasks_stop . write ( | w | unsafe { w . bits ( 1 ) } ) ;
}
Poll ::Pending
} )
}
2022-03-02 22:45:38 +01:00
fn setup_write_from_ram (
& mut self ,
address : u8 ,
buffer : & [ u8 ] ,
inten : bool ,
) -> Result < ( ) , Error > {
2021-05-11 03:07:37 +02:00
let r = T ::regs ( ) ;
compiler_fence ( SeqCst ) ;
r . address . write ( | w | unsafe { w . address ( ) . bits ( address ) } ) ;
// Set up the DMA write.
unsafe { self . set_tx_buffer ( buffer ) ? } ;
// Clear events
r . events_stopped . reset ( ) ;
r . events_error . reset ( ) ;
r . events_lasttx . reset ( ) ;
self . clear_errorsrc ( ) ;
2022-01-13 20:47:28 +01:00
if inten {
r . intenset . write ( | w | w . stopped ( ) . set ( ) . error ( ) . set ( ) ) ;
} else {
r . intenclr . write ( | w | w . stopped ( ) . clear ( ) . error ( ) . clear ( ) ) ;
2021-05-11 03:07:37 +02:00
}
2022-01-13 20:47:28 +01:00
// Start write operation.
r . shorts . write ( | w | w . lasttx_stop ( ) . enabled ( ) ) ;
r . tasks_starttx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-05-11 03:07:37 +02:00
Ok ( ( ) )
}
2022-01-13 20:47:28 +01:00
fn setup_read ( & mut self , address : u8 , buffer : & mut [ u8 ] , inten : bool ) -> Result < ( ) , Error > {
2021-05-11 03:07:37 +02:00
let r = T ::regs ( ) ;
compiler_fence ( SeqCst ) ;
r . address . write ( | w | unsafe { w . address ( ) . bits ( address ) } ) ;
// Set up the DMA read.
unsafe { self . set_rx_buffer ( buffer ) ? } ;
// Clear events
r . events_stopped . reset ( ) ;
r . events_error . reset ( ) ;
self . clear_errorsrc ( ) ;
2022-01-13 20:47:28 +01:00
if inten {
r . intenset . write ( | w | w . stopped ( ) . set ( ) . error ( ) . set ( ) ) ;
} else {
r . intenclr . write ( | w | w . stopped ( ) . clear ( ) . error ( ) . clear ( ) ) ;
2021-05-11 03:07:37 +02:00
}
2022-01-13 20:47:28 +01:00
// Start read operation.
r . shorts . write ( | w | w . lastrx_stop ( ) . enabled ( ) ) ;
r . tasks_startrx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2021-05-11 03:07:37 +02:00
Ok ( ( ) )
}
2022-03-02 22:45:38 +01:00
fn setup_write_read_from_ram (
2021-05-11 03:07:37 +02:00
& mut self ,
address : u8 ,
wr_buffer : & [ u8 ] ,
rd_buffer : & mut [ u8 ] ,
2022-01-13 20:47:28 +01:00
inten : bool ,
2021-05-11 03:07:37 +02:00
) -> Result < ( ) , Error > {
let r = T ::regs ( ) ;
compiler_fence ( SeqCst ) ;
r . address . write ( | w | unsafe { w . address ( ) . bits ( address ) } ) ;
// Set up DMA buffers.
unsafe {
self . set_tx_buffer ( wr_buffer ) ? ;
self . set_rx_buffer ( rd_buffer ) ? ;
}
// Clear events
r . events_stopped . reset ( ) ;
r . events_error . reset ( ) ;
self . clear_errorsrc ( ) ;
2022-01-13 20:47:28 +01:00
if inten {
r . intenset . write ( | w | w . stopped ( ) . set ( ) . error ( ) . set ( ) ) ;
} else {
r . intenclr . write ( | w | w . stopped ( ) . clear ( ) . error ( ) . clear ( ) ) ;
}
2021-05-11 03:07:37 +02:00
// Start write+read operation.
r . shorts . write ( | w | {
w . lasttx_startrx ( ) . enabled ( ) ;
w . lastrx_stop ( ) . enabled ( ) ;
w
} ) ;
r . tasks_starttx . write ( | w | unsafe { w . bits ( 1 ) } ) ;
2022-01-13 20:47:28 +01:00
Ok ( ( ) )
}
2021-05-11 03:07:37 +02:00
2022-03-02 22:45:38 +01:00
fn setup_write_read (
& mut self ,
address : u8 ,
wr_buffer : & [ u8 ] ,
rd_buffer : & mut [ u8 ] ,
inten : bool ,
) -> Result < ( ) , Error > {
match self . setup_write_read_from_ram ( address , wr_buffer , rd_buffer , inten ) {
Ok ( _ ) = > Ok ( ( ) ) ,
Err ( Error ::DMABufferNotInDataMemory ) = > {
trace! ( " Copying TWIM tx buffer into RAM for DMA " ) ;
2022-03-02 22:48:58 +01:00
let tx_ram_buf = & mut [ 0 ; FORCE_COPY_BUFFER_SIZE ] [ .. wr_buffer . len ( ) ] ;
tx_ram_buf . copy_from_slice ( wr_buffer ) ;
self . setup_write_read_from_ram ( address , & tx_ram_buf , rd_buffer , inten )
2022-03-02 22:45:38 +01:00
}
Err ( error ) = > Err ( error ) ,
}
}
fn setup_write ( & mut self , address : u8 , wr_buffer : & [ u8 ] , inten : bool ) -> Result < ( ) , Error > {
match self . setup_write_from_ram ( address , wr_buffer , inten ) {
Ok ( _ ) = > Ok ( ( ) ) ,
Err ( Error ::DMABufferNotInDataMemory ) = > {
trace! ( " Copying TWIM tx buffer into RAM for DMA " ) ;
2022-03-02 22:48:58 +01:00
let tx_ram_buf = & mut [ 0 ; FORCE_COPY_BUFFER_SIZE ] [ .. wr_buffer . len ( ) ] ;
tx_ram_buf . copy_from_slice ( wr_buffer ) ;
self . setup_write_from_ram ( address , & tx_ram_buf , inten )
2022-03-02 22:45:38 +01:00
}
Err ( error ) = > Err ( error ) ,
}
}
2022-01-13 20:47:28 +01:00
/// Write to an I2C slave.
///
/// The buffer must have a length of at most 255 bytes on the nRF52832
/// and at most 65535 bytes on the nRF52840.
pub fn blocking_write ( & mut self , address : u8 , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . setup_write ( address , buffer , false ) ? ;
self . blocking_wait ( ) ;
2021-05-11 03:07:37 +02:00
compiler_fence ( SeqCst ) ;
2022-01-13 20:47:28 +01:00
self . check_errorsrc ( ) ? ;
self . check_tx ( buffer . len ( ) ) ? ;
Ok ( ( ) )
}
2021-05-11 03:07:37 +02:00
2022-03-08 16:42:46 +01:00
/// Same as [`blocking_write`](Twim::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
2022-03-02 22:45:38 +01:00
pub fn blocking_write_from_ram ( & mut self , address : u8 , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . setup_write_from_ram ( address , buffer , false ) ? ;
self . blocking_wait ( ) ;
compiler_fence ( SeqCst ) ;
self . check_errorsrc ( ) ? ;
self . check_tx ( buffer . len ( ) ) ? ;
Ok ( ( ) )
}
2022-01-13 20:47:28 +01:00
/// Read from an I2C slave.
///
/// The buffer must have a length of at most 255 bytes on the nRF52832
/// and at most 65535 bytes on the nRF52840.
pub fn blocking_read ( & mut self , address : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . setup_read ( address , buffer , false ) ? ;
self . blocking_wait ( ) ;
compiler_fence ( SeqCst ) ;
self . check_errorsrc ( ) ? ;
self . check_rx ( buffer . len ( ) ) ? ;
Ok ( ( ) )
}
2021-05-11 03:07:37 +02:00
2022-01-13 20:47:28 +01:00
/// Write data to an I2C slave, then read data from the slave without
/// triggering a stop condition between the two.
///
/// The buffers must have a length of at most 255 bytes on the nRF52832
/// and at most 65535 bytes on the nRF52840.
pub fn blocking_write_read (
& mut self ,
address : u8 ,
wr_buffer : & [ u8 ] ,
rd_buffer : & mut [ u8 ] ,
) -> Result < ( ) , Error > {
self . setup_write_read ( address , wr_buffer , rd_buffer , false ) ? ;
self . blocking_wait ( ) ;
compiler_fence ( SeqCst ) ;
self . check_errorsrc ( ) ? ;
self . check_tx ( wr_buffer . len ( ) ) ? ;
self . check_rx ( rd_buffer . len ( ) ) ? ;
2021-05-11 03:07:37 +02:00
Ok ( ( ) )
}
2022-03-08 16:42:46 +01:00
/// Same as [`blocking_write_read`](Twim::blocking_write_read) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
2022-03-02 22:45:38 +01:00
pub fn blocking_write_read_from_ram (
2021-05-11 03:07:37 +02:00
& mut self ,
address : u8 ,
wr_buffer : & [ u8 ] ,
rd_buffer : & mut [ u8 ] ,
) -> Result < ( ) , Error > {
2022-03-02 22:45:38 +01:00
self . setup_write_read_from_ram ( address , wr_buffer , rd_buffer , false ) ? ;
self . blocking_wait ( ) ;
compiler_fence ( SeqCst ) ;
self . check_errorsrc ( ) ? ;
self . check_tx ( wr_buffer . len ( ) ) ? ;
self . check_rx ( rd_buffer . len ( ) ) ? ;
Ok ( ( ) )
2021-05-11 03:07:37 +02:00
}
2021-06-05 11:58:50 +02:00
2022-01-13 20:47:28 +01:00
pub async fn read ( & mut self , address : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Error > {
self . setup_read ( address , buffer , true ) ? ;
self . async_wait ( ) . await ;
compiler_fence ( SeqCst ) ;
self . check_errorsrc ( ) ? ;
self . check_rx ( buffer . len ( ) ) ? ;
Ok ( ( ) )
}
2021-06-05 11:58:50 +02:00
2022-01-13 20:47:28 +01:00
pub async fn write ( & mut self , address : u8 , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . setup_write ( address , buffer , true ) ? ;
self . async_wait ( ) . await ;
compiler_fence ( SeqCst ) ;
self . check_errorsrc ( ) ? ;
self . check_tx ( buffer . len ( ) ) ? ;
Ok ( ( ) )
}
2021-06-05 11:58:50 +02:00
2022-03-08 16:42:46 +01:00
/// Same as [`write`](Twim::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
2022-03-02 22:45:38 +01:00
pub async fn write_from_ram ( & mut self , address : u8 , buffer : & [ u8 ] ) -> Result < ( ) , Error > {
self . setup_write_from_ram ( address , buffer , true ) ? ;
self . async_wait ( ) . await ;
compiler_fence ( SeqCst ) ;
self . check_errorsrc ( ) ? ;
self . check_tx ( buffer . len ( ) ) ? ;
Ok ( ( ) )
}
2022-01-13 20:47:28 +01:00
pub async fn write_read (
& mut self ,
address : u8 ,
wr_buffer : & [ u8 ] ,
rd_buffer : & mut [ u8 ] ,
) -> Result < ( ) , Error > {
self . setup_write_read ( address , wr_buffer , rd_buffer , true ) ? ;
self . async_wait ( ) . await ;
compiler_fence ( SeqCst ) ;
self . check_errorsrc ( ) ? ;
self . check_tx ( wr_buffer . len ( ) ) ? ;
self . check_rx ( rd_buffer . len ( ) ) ? ;
Ok ( ( ) )
2021-06-05 11:58:50 +02:00
}
2022-03-02 22:45:38 +01:00
2022-03-08 16:42:46 +01:00
/// Same as [`write_read`](Twim::write_read) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
2022-03-02 22:45:38 +01:00
pub async fn write_read_from_ram (
& mut self ,
address : u8 ,
wr_buffer : & [ u8 ] ,
rd_buffer : & mut [ u8 ] ,
) -> Result < ( ) , Error > {
self . setup_write_read_from_ram ( address , wr_buffer , rd_buffer , true ) ? ;
self . async_wait ( ) . await ;
compiler_fence ( SeqCst ) ;
self . check_errorsrc ( ) ? ;
self . check_tx ( wr_buffer . len ( ) ) ? ;
self . check_rx ( rd_buffer . len ( ) ) ? ;
Ok ( ( ) )
}
2021-05-11 03:07:37 +02:00
}
impl < ' a , T : Instance > Drop for Twim < ' a , T > {
fn drop ( & mut self ) {
2021-12-23 13:43:14 +01:00
trace! ( " twim drop " ) ;
2021-05-11 03:07:37 +02:00
2022-01-13 20:47:28 +01:00
// TODO: check for abort
2021-05-11 03:07:37 +02:00
// disable!
let r = T ::regs ( ) ;
r . enable . write ( | w | w . enable ( ) . disabled ( ) ) ;
2021-05-26 18:09:18 +02:00
gpio ::deconfigure_pin ( r . psel . sda . read ( ) . bits ( ) ) ;
gpio ::deconfigure_pin ( r . psel . scl . read ( ) . bits ( ) ) ;
2021-05-11 03:07:37 +02:00
2021-12-23 13:43:14 +01:00
trace! ( " twim drop: done " ) ;
2021-05-11 03:07:37 +02:00
}
}
pub ( crate ) mod sealed {
use super ::* ;
pub struct State {
pub end_waker : AtomicWaker ,
}
impl State {
pub const fn new ( ) -> Self {
Self {
end_waker : AtomicWaker ::new ( ) ,
}
}
}
pub trait Instance {
fn regs ( ) -> & 'static pac ::twim0 ::RegisterBlock ;
fn state ( ) -> & 'static State ;
}
}
2021-05-15 00:05:32 +02:00
pub trait Instance : Unborrow < Target = Self > + sealed ::Instance + 'static {
2021-05-11 03:07:37 +02:00
type Interrupt : Interrupt ;
}
macro_rules ! impl_twim {
( $type :ident , $pac_type :ident , $irq :ident ) = > {
impl crate ::twim ::sealed ::Instance for peripherals ::$type {
fn regs ( ) -> & 'static pac ::twim0 ::RegisterBlock {
unsafe { & * pac ::$pac_type ::ptr ( ) }
}
fn state ( ) -> & 'static crate ::twim ::sealed ::State {
static STATE : crate ::twim ::sealed ::State = crate ::twim ::sealed ::State ::new ( ) ;
& STATE
}
}
impl crate ::twim ::Instance for peripherals ::$type {
type Interrupt = crate ::interrupt ::$irq ;
}
} ;
}
2022-01-13 23:56:25 +01:00
// ====================
mod eh02 {
use super ::* ;
impl < ' a , T : Instance > embedded_hal_02 ::blocking ::i2c ::Write for Twim < ' a , T > {
type Error = Error ;
fn write < ' w > ( & mut self , addr : u8 , bytes : & ' w [ u8 ] ) -> Result < ( ) , Error > {
if slice_in_ram ( bytes ) {
self . blocking_write ( addr , bytes )
} else {
let buf = & mut [ 0 ; FORCE_COPY_BUFFER_SIZE ] [ .. ] ;
for chunk in bytes . chunks ( FORCE_COPY_BUFFER_SIZE ) {
buf [ .. chunk . len ( ) ] . copy_from_slice ( chunk ) ;
self . blocking_write ( addr , & buf [ .. chunk . len ( ) ] ) ? ;
}
Ok ( ( ) )
}
}
}
impl < ' a , T : Instance > embedded_hal_02 ::blocking ::i2c ::Read for Twim < ' a , T > {
type Error = Error ;
fn read < ' w > ( & mut self , addr : u8 , bytes : & ' w mut [ u8 ] ) -> Result < ( ) , Error > {
self . blocking_read ( addr , bytes )
}
}
impl < ' a , T : Instance > embedded_hal_02 ::blocking ::i2c ::WriteRead for Twim < ' a , T > {
type Error = Error ;
fn write_read < ' w > (
& mut self ,
addr : u8 ,
bytes : & ' w [ u8 ] ,
buffer : & ' w mut [ u8 ] ,
) -> Result < ( ) , Error > {
2022-03-02 22:45:38 +01:00
self . blocking_write_read ( addr , bytes , buffer )
2022-01-13 23:56:25 +01:00
}
}
}
#[ cfg(feature = " unstable-traits " ) ]
mod eh1 {
use super ::* ;
impl embedded_hal_1 ::i2c ::Error for Error {
fn kind ( & self ) -> embedded_hal_1 ::i2c ::ErrorKind {
match * self {
Self ::TxBufferTooLong = > embedded_hal_1 ::i2c ::ErrorKind ::Other ,
Self ::RxBufferTooLong = > embedded_hal_1 ::i2c ::ErrorKind ::Other ,
Self ::TxBufferZeroLength = > embedded_hal_1 ::i2c ::ErrorKind ::Other ,
Self ::RxBufferZeroLength = > embedded_hal_1 ::i2c ::ErrorKind ::Other ,
Self ::Transmit = > embedded_hal_1 ::i2c ::ErrorKind ::Other ,
Self ::Receive = > embedded_hal_1 ::i2c ::ErrorKind ::Other ,
Self ::DMABufferNotInDataMemory = > embedded_hal_1 ::i2c ::ErrorKind ::Other ,
Self ::AddressNack = > embedded_hal_1 ::i2c ::ErrorKind ::NoAcknowledge (
embedded_hal_1 ::i2c ::NoAcknowledgeSource ::Address ,
) ,
Self ::DataNack = > embedded_hal_1 ::i2c ::ErrorKind ::NoAcknowledge (
embedded_hal_1 ::i2c ::NoAcknowledgeSource ::Data ,
) ,
Self ::Overrun = > embedded_hal_1 ::i2c ::ErrorKind ::Overrun ,
}
}
}
impl < ' d , T : Instance > embedded_hal_1 ::i2c ::ErrorType for Twim < ' d , T > {
type Error = Error ;
}
impl < ' d , T : Instance > embedded_hal_1 ::i2c ::blocking ::I2c for Twim < ' d , T > {
fn read ( & mut self , address : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Self ::Error > {
self . blocking_read ( address , buffer )
}
fn write ( & mut self , address : u8 , buffer : & [ u8 ] ) -> Result < ( ) , Self ::Error > {
self . blocking_write ( address , buffer )
}
fn write_iter < B > ( & mut self , _address : u8 , _bytes : B ) -> Result < ( ) , Self ::Error >
where
B : IntoIterator < Item = u8 > ,
{
todo! ( ) ;
}
fn write_iter_read < B > (
& mut self ,
_address : u8 ,
_bytes : B ,
_buffer : & mut [ u8 ] ,
) -> Result < ( ) , Self ::Error >
where
B : IntoIterator < Item = u8 > ,
{
todo! ( ) ;
}
fn write_read (
& mut self ,
address : u8 ,
wr_buffer : & [ u8 ] ,
rd_buffer : & mut [ u8 ] ,
) -> Result < ( ) , Self ::Error > {
self . blocking_write_read ( address , wr_buffer , rd_buffer )
}
fn transaction < ' a > (
& mut self ,
_address : u8 ,
2022-02-12 00:24:04 +01:00
_operations : & mut [ embedded_hal_1 ::i2c ::blocking ::Operation < ' a > ] ,
2022-01-13 23:56:25 +01:00
) -> Result < ( ) , Self ::Error > {
todo! ( ) ;
}
fn transaction_iter < ' a , O > (
& mut self ,
_address : u8 ,
_operations : O ,
) -> Result < ( ) , Self ::Error >
where
2022-02-12 00:24:04 +01:00
O : IntoIterator < Item = embedded_hal_1 ::i2c ::blocking ::Operation < ' a > > ,
2022-01-13 23:56:25 +01:00
{
todo! ( ) ;
}
}
2022-02-12 00:24:04 +01:00
}
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
cfg_if ::cfg_if! {
if #[ cfg(all(feature = " unstable-traits " , feature = " nightly " )) ] {
impl < ' d , T : Instance > embedded_hal_async ::i2c ::I2c for Twim < ' d , T > {
type ReadFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn read < ' a > ( & ' a mut self , address : u8 , buffer : & ' a mut [ u8 ] ) -> Self ::ReadFuture < ' a > {
self . read ( address , buffer )
}
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
type WriteFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn write < ' a > ( & ' a mut self , address : u8 , bytes : & ' a [ u8 ] ) -> Self ::WriteFuture < ' a > {
self . write ( address , bytes )
}
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
type WriteReadFuture < ' a > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn write_read < ' a > (
& ' a mut self ,
address : u8 ,
wr_buffer : & ' a [ u8 ] ,
rd_buffer : & ' a mut [ u8 ] ,
) -> Self ::WriteReadFuture < ' a > {
self . write_read ( address , wr_buffer , rd_buffer )
}
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
type TransactionFuture < ' a , ' b > = impl Future < Output = Result < ( ) , Self ::Error > > + ' a where Self : ' a , ' b : ' a ;
2022-01-13 23:56:25 +01:00
2022-02-16 03:54:39 +01:00
fn transaction < ' a , ' b > (
& ' a mut self ,
address : u8 ,
operations : & ' a mut [ embedded_hal_async ::i2c ::Operation < ' b > ] ,
) -> Self ::TransactionFuture < ' a , ' b > {
let _ = address ;
let _ = operations ;
async move { todo! ( ) }
}
}
2022-01-13 23:56:25 +01:00
}
}