From 97cfd709745fef23853735ea3c2e8eb0f4fb71f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= Date: Tue, 26 Jan 2021 20:29:46 +0100 Subject: [PATCH 01/11] Add i2c with interrupts --- src/i2c.rs | 4 +- src/i2cint.rs | 377 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 3 files changed, 380 insertions(+), 2 deletions(-) create mode 100644 src/i2cint.rs diff --git a/src/i2c.rs b/src/i2c.rs index ce7eb1c80..331153858 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -81,8 +81,8 @@ cfg_if! { /// I2C peripheral operating in master mode pub struct I2c { - i2c: I2C, - pins: PINS, + pub(crate) i2c: I2C, + pub(crate) pins: PINS, } macro_rules! busy_wait { diff --git a/src/i2cint.rs b/src/i2cint.rs new file mode 100644 index 000000000..41cbc5fc3 --- /dev/null +++ b/src/i2cint.rs @@ -0,0 +1,377 @@ +//! Inter-Integrated Circuit (I2C) bus interruption + +use core::fmt; +use crate::{i2c::{I2c, Instance, SclPin, SdaPin}}; +use crate::rcc::{Clocks, APB1}; +use crate::time::Hertz; + +/// I2c errors. +#[derive(Debug, Copy, Clone)] +pub enum I2cError { + /// Device is busy, can't start something else + DeviceBusy, + /// Received a nack + Nack, + /// Error happened on the bus + BusError, + /// Arbitration loss, + ArbitrationLoss, + /// Overrun detected (salve mode) + Overrun, + /// Unable to compute the stop state because previous state was not expected + StateError, + /// Transfer complete status but nothing do do next + TransferCompleteNoRead, +} + +/// State of i2c communication. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum State { + /// I2c is Idle + Idle, + /// Send has started + TxStart, + /// Ready for send + TxReady, + /// Data written in send buffer + TxSent, + /// Send is complete, but device is not stopped + TxComplete, + /// Send is complete + TxStop, + /// Receive has started + RxStart, + /// Ready for receive + RxReady, + /// Received is complete + RxStop, + /// Nack for send + TxNack, +} + +impl core::fmt::Display for State { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +/// I2c1Int provides interface to communicate with i2c devices using interruptions. +pub struct I2cInt { + dev: I2c, + state: State, + /// Last error that happened on i2c communications. + pub last_error: Option, + current_write_addr: Option, + tx_ind: usize, + tx_buf: Option<&'static [u8]>, + rx_ind: usize, + rx_buf: [u8; 256], // for the moment use a static buffer here. + recv: Option<(u8, usize)>, +} + +impl I2cInt where I2C: Instance { + /// Configures the I2C peripheral to work in master mode + pub fn new_int(i2c: I2C, pins: (SCL, SDA), freq: F, clocks: Clocks, apb1: &mut APB1) -> I2cInt + where + SCL: SclPin, + SDA: SdaPin, + F: Into, + { + let i2c = I2c::new(i2c, pins, freq, clocks, apb1); + + I2cInt { + dev: i2c, + state: State::Idle, + last_error: None, + current_write_addr: None, + tx_ind: 0, + tx_buf: None, + rx_ind: 0, + rx_buf: [0; 256], + recv: None, + } + } + + /// Enable the i2c device. + pub fn enable(&mut self) { + // Enable the peripheral + self.dev.i2c.cr1.modify(|_, w| w.pe().set_bit()); + } + + /// Disable the i2c device. + pub fn disable(&mut self) { + self.dev.i2c.cr1.modify(|_, w| w.pe().disabled()); + self.last_error = None; + } + + /// Enables all interrupts for i2c device. + pub fn enable_interrupts(&mut self) { + self.dev.i2c.cr1.modify(|_, w| { + w.errie() + .enabled() + .tcie() + .enabled() + .stopie() + .enabled() + .nackie() + .enabled() + .rxie() + .enabled() + .txie() + .enabled() + }); + } + + /// Disables all interrupts for i2c device. + pub fn disable_interrupts(&mut self) { + self.dev.i2c.cr1.modify(|_, w| { + w.errie() + .disabled() + .tcie() + .disabled() + .stopie() + .disabled() + .nackie() + .disabled() + .rxie() + .disabled() + .txie() + .disabled() + }); + } + + /// Write bytes through i2c. Supports only write < 256 bytes. + /// + /// # Arguments + /// * `addr` - Destination address. + /// * `bytes` - Bytes to send. + /// + /// # Errors + /// * `I2cError::DeviceBusy` if the device is already busy. + pub fn write(&mut self, addr: u8, bytes: &'static [u8]) -> Result<(), I2cError> { + self._write(addr, true, bytes) + } + + /// Write bytes through i2c. Supports only write < 256 bytes. + /// + /// # Arguments + /// * `addr` - Destination address. + /// * `auto_stop` - i2c autostop enabled. + /// * `bytes` - Bytes to send. + /// + /// # Errors + /// * `I2cError::DeviceBusy` if the device is already busy. + fn _write(&mut self, addr: u8, auto_stop: bool, bytes: &'static [u8]) -> Result<(), I2cError> { + if self.is_busy() { + self.last_error = Some(I2cError::DeviceBusy); + return Err(I2cError::DeviceBusy); + } + self.tx_ind = 0; + self.tx_buf = Some(bytes); + self.write_start(addr, bytes.len() as u8, auto_stop); + Ok(()) + } + + /// Start a write sequence on i2c channel. + /// + /// # Arguments + /// * `addr` - Destination address. + /// * `n_bytes` - number of bytes which will be sent. + /// * `auto_stop` - i2c autostop enabled. + fn write_start(&mut self, addr: u8, n_bytes: u8, auto_stop: bool) { + self.current_write_addr = Some(addr); + self.dev.i2c.cr2.modify(|_, w| { + w.sadd() + .bits(u16::from(addr << 1)) + .rd_wrn() + .write() + .nbytes() + .bits(n_bytes) + .start() + .start() + .autoend() + .bit(auto_stop) + }); + self.state = State::TxStart; + } + + /// Reads from i2c interface. Supports only read < 256 bytes. + /// + /// # Arguments + /// * `addr` - Destination address. + /// * `len` - number of bytes to read. + pub fn read(&mut self, addr: u8, len: usize) { + self.dev.i2c.cr2.modify(|_, w| { + w.sadd() + .bits(u16::from(addr << 1)) + .rd_wrn() + .read() + .nbytes() + .bits(len as u8) + .start() + .start() + .autoend() + .automatic() + }); + self.state = State::RxStart; + } + + /// Write bytes through i2c. Supports only write and read < 256 bytes. + /// + /// # Arguments + /// * `addr` - Destination address. + /// * `bytes` - Bytes to send. + /// * `recv_len` - Number of bytes to receive. + /// + /// # Errors + /// * `I2cError::DeviceBusy` if the device is already busy. + pub fn write_read( + &mut self, + addr: u8, + bytes: &'static [u8], + recv_len: usize, + ) -> Result<(), I2cError> { + self.recv = Some((addr, recv_len)); + self._write(addr, false, bytes) + } + + /// Send a stop. + /// + /// # Arguments + /// * `addr` - Destination address. + /// + /// # Errors + /// * `I2cError::DeviceBusy` if the device is already busy. + pub fn stop(&mut self, addr: u8) { + self.dev.i2c + .cr2 + .modify(|_, w| w.sadd().bits(u16::from(addr << 1)).stop().stop()); + } + + /// This function must be called when there is an interruption on i2c device. + /// It will compute the current state based on ISR register and execute work based on the state. + pub fn interrupt(&mut self) { + let isr_state = self.isr_state(); + match isr_state { + Ok(State::TxReady) => { + self.tx_buf + .map(|buf| self.write_tx_buffer(buf[self.tx_ind])); + self.tx_ind += 1; + } + Ok(State::RxReady) => { + self.rx_buf[self.rx_ind] = self.dev.i2c.rxdr.read().rxdata().bits(); + self.rx_ind += 1; + } + Ok(State::TxStop) => { + self.tx_ind = 0; + self.current_write_addr = None; + } + Ok(State::TxComplete) => { + self.tx_ind = 0; + // When receiving Tx complete, we should read after + // if not it should be a tx stop + self.last_error = self.recv.map_or_else( + || Some(I2cError::TransferCompleteNoRead), + |recv| { + self.read(recv.0, recv.1); + None + }, + ); + // if there was an error send a stop + if self.last_error.is_some() { + self.current_write_addr.map(|addr| self.stop(addr)); + } + self.current_write_addr = None; + } + Ok(State::RxStop) => { + self.rx_ind = 0; + } + Ok(State::TxNack) => { + self.tx_ind = 0; + self.last_error = Some(I2cError::Nack); + self.current_write_addr = None; + } + Err(err) => { + self.last_error = Some(err); + self.current_write_addr = None; + } + _ => {} + } + } + + /// Computes the states based on IRS register. + fn isr_state(&mut self) -> Result { + let isr = self.dev.i2c.isr.read(); + if isr.berr().bit() { + self.dev.i2c.icr.write(|w| w.berrcf().bit(true)); + return Err(I2cError::BusError); + } else if isr.arlo().bit() { + self.dev.i2c.icr.write(|w| w.arlocf().bit(true)); + return Err(I2cError::ArbitrationLoss); + } else if isr.ovr().bit() { + self.dev.i2c.icr.write(|w| w.ovrcf().bit(true)); + return Err(I2cError::Overrun); + } + if isr.nackf().bit() { + self.dev.i2c.icr.write(|w| w.nackcf().bit(true)); + self.state = State::TxNack; + } else if isr.tc().bit() { + self.state = State::TxComplete; + } else if isr.txis().bit() && isr.txe().bit() { + self.state = State::TxReady; + } else if isr.rxne().bit() { + self.state = State::RxReady; + } else if isr.stopf().bit() { + // clear stop bit once read + self.dev.i2c.icr.write(|w| w.stopcf().bit(true)); + self.state = match self.state { + State::TxSent | State::TxComplete => State::TxStop, + State::RxReady => State::RxStop, + _ => return Err(I2cError::StateError), + } + } + Ok(self.state) + } + + /// Write a bute into the tx buffer. + fn write_tx_buffer(&mut self, byte: u8) { + self.dev.i2c.txdr.write(|w| w.txdata().bits(byte)); + self.state = State::TxSent; + } + + /// Is the device Busy ? + /// # Returns + /// true if busy, false if not. + pub fn is_busy(&mut self) -> bool { + self.dev.i2c.isr.read().busy().bit() + } + + /// Get the state of the device. + pub fn get_tx_state(&self) -> State { + self.state + } + + /// Get the content of the receive buffer. + /// + /// # Arguments + /// * `len` - len of the slice to get. + /// + /// # Returns + /// A slice containing of the rx buffer. + pub fn get_rx_buf(&self, len: usize) -> &[u8] { + self.rx_buf.split_at(len).0 + } + + /// Set the device state to idle. + pub fn reset_state(&mut self) { + self.state = State::Idle; + self.last_error = None; + self.tx_buf = None; + self.recv = None; + } + + /// Debug function which returns the content of the ISR register. + pub fn get_isr(&self) -> u32 { + self.dev.i2c.isr.read().bits() + } +} diff --git a/src/lib.rs b/src/lib.rs index da4c2fec7..abf358840 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -181,6 +181,7 @@ cfg_if::cfg_if! { pub mod flash; pub mod gpio; pub mod i2c; + pub mod i2cint; pub mod prelude; pub mod pwm; pub mod rcc; From 896fef32492b99cd0f16f785e306b7809ac9b808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= Date: Wed, 27 Jan 2021 22:45:14 +0100 Subject: [PATCH 02/11] Generate transmit buffer empty error when we have a tx ready interrupt with no write buffer --- src/i2cint.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/i2cint.rs b/src/i2cint.rs index 41cbc5fc3..845c23538 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -22,6 +22,8 @@ pub enum I2cError { StateError, /// Transfer complete status but nothing do do next TransferCompleteNoRead, + /// Send buffer is empty + TxBufferEmpty, } /// State of i2c communication. @@ -254,9 +256,12 @@ impl I2cInt where I2C: Instance { let isr_state = self.isr_state(); match isr_state { Ok(State::TxReady) => { - self.tx_buf - .map(|buf| self.write_tx_buffer(buf[self.tx_ind])); - self.tx_ind += 1; + if let Some(buf) = self.tx_buf { + self.write_tx_buffer(buf[self.tx_ind]); + self.tx_ind += 1; + } else { + self.last_error = Some(I2cError::TxBufferEmpty); + } } Ok(State::RxReady) => { self.rx_buf[self.rx_ind] = self.dev.i2c.rxdr.read().rxdata().bits(); From f8f16907b2ac8f3b22aa35704bbd5ce7042131ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= Date: Wed, 27 Jan 2021 22:58:18 +0100 Subject: [PATCH 03/11] Don't send stop for transfer complete without following read --- src/i2cint.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/i2cint.rs b/src/i2cint.rs index 845c23538..ca1bd89fd 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -275,16 +275,10 @@ impl I2cInt where I2C: Instance { self.tx_ind = 0; // When receiving Tx complete, we should read after // if not it should be a tx stop - self.last_error = self.recv.map_or_else( - || Some(I2cError::TransferCompleteNoRead), - |recv| { - self.read(recv.0, recv.1); - None - }, - ); - // if there was an error send a stop - if self.last_error.is_some() { - self.current_write_addr.map(|addr| self.stop(addr)); + if let Some(recv) = self.recv { + self.read(recv.0, recv.1) + } else { + self.last_error = Some(I2cError::TransferCompleteNoRead); } self.current_write_addr = None; } From ea411510ebc5c2beaefae1d79209bdcf7cc1bd33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= Date: Wed, 27 Jan 2021 23:06:36 +0100 Subject: [PATCH 04/11] Fix issues with rustfmt --- src/i2cint.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/i2cint.rs b/src/i2cint.rs index ca1bd89fd..6fa331ceb 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -1,9 +1,9 @@ //! Inter-Integrated Circuit (I2C) bus interruption -use core::fmt; -use crate::{i2c::{I2c, Instance, SclPin, SdaPin}}; +use crate::i2c::{I2c, Instance, SclPin, SdaPin}; use crate::rcc::{Clocks, APB1}; use crate::time::Hertz; +use core::fmt; /// I2c errors. #[derive(Debug, Copy, Clone)] @@ -71,9 +71,18 @@ pub struct I2cInt { recv: Option<(u8, usize)>, } -impl I2cInt where I2C: Instance { +impl I2cInt +where + I2C: Instance, +{ /// Configures the I2C peripheral to work in master mode - pub fn new_int(i2c: I2C, pins: (SCL, SDA), freq: F, clocks: Clocks, apb1: &mut APB1) -> I2cInt + pub fn new_int( + i2c: I2C, + pins: (SCL, SDA), + freq: F, + clocks: Clocks, + apb1: &mut APB1, + ) -> I2cInt where SCL: SclPin, SDA: SdaPin, @@ -245,7 +254,8 @@ impl I2cInt where I2C: Instance { /// # Errors /// * `I2cError::DeviceBusy` if the device is already busy. pub fn stop(&mut self, addr: u8) { - self.dev.i2c + self.dev + .i2c .cr2 .modify(|_, w| w.sadd().bits(u16::from(addr << 1)).stop().stop()); } From 0f95321aca940378795f6367423f713b26c22dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= <8177358-clement.bizeau4@users.noreply.gitlab.com> Date: Thu, 15 Dec 2022 21:43:30 +0100 Subject: [PATCH 05/11] use if expression for computing isr state --- src/i2cint.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/i2cint.rs b/src/i2cint.rs index fb5096f1e..38a47e3ea 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -320,24 +320,27 @@ where self.dev.i2c.icr.write(|w| w.ovrcf().bit(true)); return Err(I2cError::Overrun); } - if isr.nackf().bit() { + self.state = if isr.nackf().bit() { self.dev.i2c.icr.write(|w| w.nackcf().bit(true)); - self.state = State::TxNack; + State::TxNack } else if isr.tc().bit() { - self.state = State::TxComplete; + State::TxComplete } else if isr.txis().bit() && isr.txe().bit() { - self.state = State::TxReady; + State::TxReady } else if isr.rxne().bit() { - self.state = State::RxReady; + State::RxReady } else if isr.stopf().bit() { // clear stop bit once read self.dev.i2c.icr.write(|w| w.stopcf().bit(true)); - self.state = match self.state { + match self.state { State::TxSent | State::TxComplete => State::TxStop, State::RxReady => State::RxStop, _ => return Err(I2cError::StateError), } } + else { + return Err(I2cError::StateError) + }; Ok(self.state) } From b7a41f3d943cd4c7aebf24cff54e5287a068ab88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= <8177358-clement.bizeau4@users.noreply.gitlab.com> Date: Sun, 18 Dec 2022 22:16:41 +0100 Subject: [PATCH 06/11] i2c write read sequence sends start after wite is finished and must read the rx buffer when transfer is completed. --- src/i2cint.rs | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/i2cint.rs b/src/i2cint.rs index 38a47e3ea..6d77ffa0a 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -26,6 +26,12 @@ pub enum I2cError { TxBufferEmpty, } +impl core::fmt::Display for I2cError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + /// State of i2c communication. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum State { @@ -45,6 +51,8 @@ pub enum State { RxStart, /// Ready for receive RxReady, + /// Read is complete, last byte ready for read + RxComplete, /// Received is complete RxStop, /// Nack for send @@ -210,7 +218,7 @@ where /// # Arguments /// * `addr` - Destination address. /// * `len` - number of bytes to read. - pub fn read(&mut self, addr: u8, len: usize) { + pub fn read(&mut self, addr: u8, len: usize, auto_stop: bool) { self.dev.i2c.cr2.modify(|_, w| { w.sadd() .bits(u16::from(addr << 1)) @@ -221,7 +229,7 @@ where .start() .start() .autoend() - .automatic() + .bit(auto_stop) }); self.state = State::RxStart; } @@ -261,13 +269,22 @@ where /// This function must be called when there is an interruption on i2c device. /// It will compute the current state based on ISR register and execute work based on the state. - pub fn interrupt(&mut self) { + pub fn interrupt(&mut self) -> Result { let isr_state = self.isr_state(); match isr_state { Ok(State::TxReady) => { if let Some(buf) = self.tx_buf { self.write_tx_buffer(buf[self.tx_ind]); self.tx_ind += 1; + if self.tx_ind >= buf.len() { + self.tx_buf = None; + // When receiving Tx complete, we should read after + // if not it should be a tx stop + if let Some(recv) = self.recv { + self.read(recv.0, recv.1, false); + self.state = State::RxStart; + } + } } else { self.last_error = Some(I2cError::TxBufferEmpty); } @@ -282,14 +299,13 @@ where } Ok(State::TxComplete) => { self.tx_ind = 0; - // When receiving Tx complete, we should read after - // if not it should be a tx stop - if let Some(recv) = self.recv { - self.read(recv.0, recv.1) - } else { - self.last_error = Some(I2cError::TransferCompleteNoRead); - } self.current_write_addr = None; + self.dev.i2c.cr2.modify(|_, w| w.stop().stop()); + } + Ok(State::RxComplete) => { + self.rx_buf[self.rx_ind] = self.dev.i2c.rxdr.read().rxdata().bits(); + self.rx_ind += 1; + self.dev.i2c.cr2.modify(|_, w| w.stop().stop()); } Ok(State::RxStop) => { self.rx_ind = 0; @@ -305,6 +321,7 @@ where } _ => {} } + return isr_state; } /// Computes the states based on IRS register. @@ -324,7 +341,10 @@ where self.dev.i2c.icr.write(|w| w.nackcf().bit(true)); State::TxNack } else if isr.tc().bit() { - State::TxComplete + match self.state { + State::RxReady | State::RxStart => State::RxComplete, + _ => State::TxComplete, + } } else if isr.txis().bit() && isr.txe().bit() { State::TxReady } else if isr.rxne().bit() { @@ -334,17 +354,16 @@ where self.dev.i2c.icr.write(|w| w.stopcf().bit(true)); match self.state { State::TxSent | State::TxComplete => State::TxStop, - State::RxReady => State::RxStop, + State::RxReady | State::RxComplete => State::RxStop, _ => return Err(I2cError::StateError), } - } - else { - return Err(I2cError::StateError) + } else { + return Err(I2cError::StateError); }; Ok(self.state) } - /// Write a bute into the tx buffer. + /// Write a byte into the tx buffer. fn write_tx_buffer(&mut self, byte: u8) { self.dev.i2c.txdr.write(|w| w.txdata().bits(byte)); self.state = State::TxSent; From 31b34ce347663591e29620d454d1a641d6b1eca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= <8177358-clement.bizeau4@users.noreply.gitlab.com> Date: Sun, 18 Dec 2022 22:27:43 +0100 Subject: [PATCH 07/11] add a way to free i2c device. --- src/i2cint.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/i2cint.rs b/src/i2cint.rs index 6d77ffa0a..e23e74e91 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -158,6 +158,11 @@ where }); } + /// Releases the I2C peripheral and associated pins + pub fn free(self) -> (I2C, (SCL, SDA)) { + (self.dev.i2c, self.dev.pins) + } + /// Write bytes through i2c. Supports only write < 256 bytes. /// /// # Arguments From 8798af7547280d7323c318b1fb0e237484f7821d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= <8177358-clement.bizeau4@users.noreply.gitlab.com> Date: Sun, 18 Dec 2022 22:29:47 +0100 Subject: [PATCH 08/11] get state of i2c device. --- src/i2cint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i2cint.rs b/src/i2cint.rs index e23e74e91..e6c9ff8a4 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -382,7 +382,7 @@ where } /// Get the state of the device. - pub fn get_tx_state(&self) -> State { + pub fn get_state(&self) -> State { self.state } From 658c3727aa80b9759ea1d37a868ac111c46d93ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= <8177358-clement.bizeau4@users.noreply.gitlab.com> Date: Sun, 18 Dec 2022 22:30:45 +0100 Subject: [PATCH 09/11] react on interrupt function. --- src/i2cint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i2cint.rs b/src/i2cint.rs index e6c9ff8a4..bac1962de 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -274,7 +274,7 @@ where /// This function must be called when there is an interruption on i2c device. /// It will compute the current state based on ISR register and execute work based on the state. - pub fn interrupt(&mut self) -> Result { + pub fn react_on_interrupt(&mut self) -> Result { let isr_state = self.isr_state(); match isr_state { Ok(State::TxReady) => { From ee3791e20c6e58dc3065e42f79d5abe9e22f1bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= <8177358-clement.bizeau4@users.noreply.gitlab.com> Date: Sun, 18 Dec 2022 22:32:11 +0100 Subject: [PATCH 10/11] simple constructor name. --- src/i2cint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i2cint.rs b/src/i2cint.rs index bac1962de..7585cb459 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -84,7 +84,7 @@ where I2C: Instance, { /// Configures the I2C peripheral to work in master mode - pub fn new_int( + pub fn new( i2c: I2C, pins: (SCL, SDA), freq: Hertz, From ba02de015b231b8db87302dd358b094408cbcb18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bizeau?= <8177358-clement.bizeau4@users.noreply.gitlab.com> Date: Sun, 18 Dec 2022 22:55:46 +0100 Subject: [PATCH 11/11] get last error function for i2c int --- src/i2cint.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i2cint.rs b/src/i2cint.rs index 7585cb459..1c3b0a350 100644 --- a/src/i2cint.rs +++ b/src/i2cint.rs @@ -70,7 +70,7 @@ pub struct I2cInt { dev: I2c, state: State, /// Last error that happened on i2c communications. - pub last_error: Option, + last_error: Option, current_write_addr: Option, tx_ind: usize, tx_buf: Option<&'static [u8]>, @@ -386,6 +386,14 @@ where self.state } + /// Get last error that happened on the device + /// + /// # Returns + /// Some if there is an error, None if not + pub fn get_last_error(&self) -> Option { + self.last_error + } + /// Get the content of the receive buffer. /// /// # Arguments