HAL update + CHANGELOG
This commit is contained in:
@ -28,37 +28,42 @@ pub enum FifoEmptyMode {
|
||||
EndTransaction = 1,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct ClockTooSlowForFastI2c;
|
||||
#[error("clock too slow for fast I2C mode")]
|
||||
pub struct ClockTooSlowForFastI2cError;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
|
||||
#[error("invalid timing parameters")]
|
||||
pub struct InvalidTimingParamsError;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Error {
|
||||
InvalidTimingParams,
|
||||
#[error("arbitration lost")]
|
||||
ArbitrationLost,
|
||||
#[error("nack address")]
|
||||
NackAddr,
|
||||
/// Data not acknowledged in write operation
|
||||
#[error("data not acknowledged in write operation")]
|
||||
NackData,
|
||||
/// Not enough data received in read operation
|
||||
#[error("insufficient data received")]
|
||||
InsufficientDataReceived,
|
||||
/// Number of bytes in transfer too large (larger than 0x7fe)
|
||||
#[error("data too large (larger than 0x7fe)")]
|
||||
DataTooLarge,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum InitError {
|
||||
/// Wrong address used in constructor
|
||||
#[error("wrong address mode")]
|
||||
WrongAddrMode,
|
||||
/// APB1 clock is too slow for fast I2C mode.
|
||||
ClkTooSlow(ClockTooSlowForFastI2c),
|
||||
}
|
||||
|
||||
impl From<ClockTooSlowForFastI2c> for InitError {
|
||||
fn from(value: ClockTooSlowForFastI2c) -> Self {
|
||||
Self::ClkTooSlow(value)
|
||||
}
|
||||
#[error("clock too slow for fast I2C mode: {0}")]
|
||||
ClkTooSlow(#[from] ClockTooSlowForFastI2cError),
|
||||
}
|
||||
|
||||
impl embedded_hal::i2c::Error for Error {
|
||||
@ -71,7 +76,7 @@ impl embedded_hal::i2c::Error for Error {
|
||||
Error::NackData => {
|
||||
embedded_hal::i2c::ErrorKind::NoAcknowledge(i2c::NoAcknowledgeSource::Data)
|
||||
}
|
||||
Error::DataTooLarge | Error::InsufficientDataReceived | Error::InvalidTimingParams => {
|
||||
Error::DataTooLarge | Error::InsufficientDataReceived => {
|
||||
embedded_hal::i2c::ErrorKind::Other
|
||||
}
|
||||
}
|
||||
@ -153,9 +158,12 @@ impl Instance for pac::I2c2 {
|
||||
// Config
|
||||
//==================================================================================================
|
||||
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct TrTfThighTlow(u8, u8, u8, u8);
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct TsuStoTsuStaThdStaTBuf(u8, u8, u8, u8);
|
||||
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct TimingCfg {
|
||||
// 4 bit max width
|
||||
tr: u8,
|
||||
@ -179,7 +187,7 @@ impl TimingCfg {
|
||||
pub fn new(
|
||||
first_16_bits: TrTfThighTlow,
|
||||
second_16_bits: TsuStoTsuStaThdStaTBuf,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, InvalidTimingParamsError> {
|
||||
if first_16_bits.0 > 0xf
|
||||
|| first_16_bits.1 > 0xf
|
||||
|| first_16_bits.2 > 0xf
|
||||
@ -189,7 +197,7 @@ impl TimingCfg {
|
||||
|| second_16_bits.2 > 0xf
|
||||
|| second_16_bits.3 > 0xf
|
||||
{
|
||||
return Err(Error::InvalidTimingParams);
|
||||
return Err(InvalidTimingParamsError);
|
||||
}
|
||||
Ok(TimingCfg {
|
||||
tr: first_16_bits.0,
|
||||
@ -230,6 +238,7 @@ impl Default for TimingCfg {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct MasterConfig {
|
||||
pub tx_fe_mode: FifoEmptyMode,
|
||||
pub rx_fe_mode: FifoEmptyMode,
|
||||
@ -256,6 +265,8 @@ impl Default for MasterConfig {
|
||||
|
||||
impl Sealed for MasterConfig {}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct SlaveConfig {
|
||||
pub tx_fe_mode: FifoEmptyMode,
|
||||
pub rx_fe_mode: FifoEmptyMode,
|
||||
@ -318,7 +329,7 @@ impl<I2c: Instance> I2cBase<I2c> {
|
||||
speed_mode: I2cSpeed,
|
||||
ms_cfg: Option<&MasterConfig>,
|
||||
sl_cfg: Option<&SlaveConfig>,
|
||||
) -> Result<Self, ClockTooSlowForFastI2c> {
|
||||
) -> Result<Self, ClockTooSlowForFastI2cError> {
|
||||
syscfg.enable_peripheral_clock(I2c::PERIPH_SEL);
|
||||
|
||||
let mut i2c_base = I2cBase {
|
||||
@ -421,19 +432,22 @@ impl<I2c: Instance> I2cBase<I2c> {
|
||||
});
|
||||
}
|
||||
|
||||
fn calc_clk_div(&self, speed_mode: I2cSpeed) -> Result<u8, ClockTooSlowForFastI2c> {
|
||||
fn calc_clk_div(&self, speed_mode: I2cSpeed) -> Result<u8, ClockTooSlowForFastI2cError> {
|
||||
if speed_mode == I2cSpeed::Regular100khz {
|
||||
Ok(((self.clock.raw() / CLK_100K.raw() / 20) - 1) as u8)
|
||||
} else {
|
||||
if self.clock.raw() < MIN_CLK_400K.raw() {
|
||||
return Err(ClockTooSlowForFastI2c);
|
||||
return Err(ClockTooSlowForFastI2cError);
|
||||
}
|
||||
Ok(((self.clock.raw() / CLK_400K.raw() / 25) - 1) as u8)
|
||||
}
|
||||
}
|
||||
|
||||
/// Configures the clock scale for a given speed mode setting
|
||||
pub fn cfg_clk_scale(&mut self, speed_mode: I2cSpeed) -> Result<(), ClockTooSlowForFastI2c> {
|
||||
pub fn cfg_clk_scale(
|
||||
&mut self,
|
||||
speed_mode: I2cSpeed,
|
||||
) -> Result<(), ClockTooSlowForFastI2cError> {
|
||||
let clk_div = self.calc_clk_div(speed_mode)?;
|
||||
self.i2c
|
||||
.clkscale()
|
||||
@ -472,7 +486,7 @@ impl<I2c: Instance, Addr> I2cMaster<I2c, Addr> {
|
||||
cfg: MasterConfig,
|
||||
clocks: &Clocks,
|
||||
speed_mode: I2cSpeed,
|
||||
) -> Result<Self, ClockTooSlowForFastI2c> {
|
||||
) -> Result<Self, ClockTooSlowForFastI2cError> {
|
||||
Ok(I2cMaster {
|
||||
i2c_base: I2cBase::new(i2c, sys_cfg, clocks, speed_mode, Some(&cfg), None)?,
|
||||
addr: PhantomData,
|
||||
@ -733,7 +747,7 @@ impl<I2c: Instance, Addr> I2cSlave<I2c, Addr> {
|
||||
cfg: SlaveConfig,
|
||||
clocks: &Clocks,
|
||||
speed_mode: I2cSpeed,
|
||||
) -> Result<Self, ClockTooSlowForFastI2c> {
|
||||
) -> Result<Self, ClockTooSlowForFastI2cError> {
|
||||
Ok(I2cSlave {
|
||||
i2c_base: I2cBase::new(i2c, sys_cfg, clocks, speed_mode, None, Some(&cfg))?,
|
||||
addr: PhantomData,
|
||||
@ -895,7 +909,7 @@ impl<I2c: Instance> I2cSlave<I2c, TenBitAddress> {
|
||||
cfg: SlaveConfig,
|
||||
clocks: &Clocks,
|
||||
speed_mode: I2cSpeed,
|
||||
) -> Result<Self, ClockTooSlowForFastI2c> {
|
||||
) -> Result<Self, ClockTooSlowForFastI2cError> {
|
||||
Self::new_generic(i2c, sys_cfg, cfg, clocks, speed_mode)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user