continue CAN support

This commit is contained in:
Robin Müller 2025-04-08 11:08:25 +02:00
parent e8e7ea9b1c
commit a6c9a6fcdc
Signed by: muellerr
GPG Key ID: A649FB78196E3849
9 changed files with 430 additions and 38 deletions

View File

@ -25,6 +25,7 @@ typenum = "1"
bitflags = "2" bitflags = "2"
bitbybit = "1.3" bitbybit = "1.3"
arbitrary-int = "1.3" arbitrary-int = "1.3"
derive-mmio = "0.4"
fugit = "0.3" fugit = "0.3"
delegate = ">=0.12, <=0.13" delegate = ">=0.12, <=0.13"
heapless = "0.8" heapless = "0.8"

View File

@ -1 +0,0 @@

View File

@ -0,0 +1,67 @@
use arbitrary_int::{u2, u3, u4, u7};
use crate::{clock::Clocks, enable_peripheral_clock, PeripheralSelect};
pub mod regs;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CanId {
Can0 = 0,
Can1 = 1,
}
impl CanId {}
pub struct Can {
id: CanId,
}
pub trait Instance {
const ID: CanId;
const PERIPH_SEL: PeripheralSelect;
}
impl Instance for va416xx::Can0 {
const ID: CanId = CanId::Can0;
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Can0;
}
impl Instance for va416xx::Can1 {
const ID: CanId = CanId::Can1;
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Can1;
}
pub struct ClockConfig {
prescaler: u7,
tseg1: u4,
tseg2: u3,
sjw: u2,
}
impl ClockConfig {
/// New clock configuration from the raw configuration values.
pub fn new(prescaler: u7, tseg1: u4, tseg2: u3, sjw: u2) -> Self {
Self {
prescaler,
tseg1,
tseg2,
sjw,
}
}
}
impl Can {
pub fn new<CanI: Instance>(_can: CanI, clk_config: ClockConfig) -> Self {
enable_peripheral_clock(CanI::PERIPH_SEL);
let id = CanI::ID;
let mut regs = if id == CanId::Can0 {
unsafe { regs::Can::new_mmio_fixed_0() }
} else {
unsafe { regs::Can::new_mmio_fixed_1() }
};
for i in 0..15 {
regs.msg_buf_block_mut(i).reset();
}
Self { id }
}
}

298
va416xx-hal/src/can/regs.rs Normal file
View File

@ -0,0 +1,298 @@
//! Custom register definitions for the CAN register block to circumvent PAC API / SVD
//! shortcomings.
use arbitrary_int::{u2, u3, u4, u7};
pub const CAN_0_BASE: usize = 0x4001_4000;
pub const CAN_1_BASE: usize = 0x4001_4400;
#[derive(Debug)]
#[bitbybit::bitenum(u4)]
pub enum BufferStatus {
RxNotActive = 0b0000,
RxReady = 0b0001,
RxBusy0 = 0b0010,
RxFull = 0b0100,
RxBusy1 = 0b0101,
RxOverrun = 0b0110,
RxBusy2 = 0b0111,
TxNotActive = 0b1000,
TxRtr = 0b1010,
TxOnce = 0b1100,
TxBusy0 = 0b1101,
TxOnceRtr = 0b1110,
TxBusy2 = 0b1111,
}
/// Status control register for individual message buffers.
#[bitbybit::bitfield(u32)]
pub struct BufStatusAndControl {
/// Data length code.
#[bits(12..=15, rw)]
dlc: u4,
#[bits(4..=7, rw)]
priority: u4,
#[bits(0..=3, rw)]
status: Option<BufferStatus>,
}
#[derive(Debug)]
pub struct Data16Bit(arbitrary_int::UInt<u32, 16>);
impl Data16Bit {
pub fn new(value: u16) -> Self {
Self(value.into())
}
pub fn value(&self) -> u16 {
self.0.value() as u16
}
pub fn write(&mut self, value: u16) {
self.0 = value.into();
}
}
#[derive(derive_mmio::Mmio)]
#[repr(C)]
pub struct CanMsgBuf {
stat_ctrl: BufStatusAndControl,
timestamp: Data16Bit,
data3: Data16Bit,
data2: Data16Bit,
data1: Data16Bit,
data0: Data16Bit,
id0: Data16Bit,
id1: Data16Bit,
}
impl MmioCanMsgBuf<'_> {
pub fn reset(&mut self) {
self.write_stat_ctrl(BufStatusAndControl::new_with_raw_value(0));
self.write_timestamp(Data16Bit::new(0));
self.write_data3(Data16Bit::new(0));
self.write_data2(Data16Bit::new(0));
self.write_data1(Data16Bit::new(0));
self.write_data0(Data16Bit::new(0));
self.write_id1(Data16Bit::new(0));
self.write_id0(Data16Bit::new(0));
}
}
#[bitbybit::bitenum(u1, exhaustive = true)]
#[derive(Debug)]
pub enum PinLogicLevel {
DominantIsZero = 0b0,
DominantIsOne = 0b1,
}
#[bitbybit::bitenum(u1, exhaustive = true)]
#[derive(Debug)]
pub enum ErrorInterruptType {
/// EIPND bit is set on every error.
EveryError = 0b0,
/// EIPND bit is only set if error state changes as a result of a receive or transmit
/// error counter increment.
ErrorOnRxTxCounterChange = 0b1,
}
#[bitbybit::bitenum(u1, exhaustive = true)]
#[derive(Debug)]
pub enum DataDirection {
FirstByteAtHighestAddr = 0b0,
LastByteAtHighestAddr = 0b1,
}
#[bitbybit::bitfield(u32)]
pub struct Control {
#[bit(11, rw)]
error_interrupt_type: ErrorInterruptType,
/// Enables special diagnostics features of the CAN like LO, IGNACK, LOOPBACK, INTERNAL.
#[bit(10, rw)]
diag_enable: bool,
/// CANTX and CANRX pins are internally connected to each other.
#[bit(9, rw)]
internal: bool,
/// All messages sent by the CAN controller can also be received by a CAN buffer with a
/// matching buffer ID.
#[bit(8, rw)]
loopback: bool,
/// IGNACK feature. The CAN does not expect to receive an ACK bit.
#[bit(7, rw)]
ignore_ack: bool,
/// LO feature. The CAN is only configured as a receiver.
#[bit(6, rw)]
listen_only: bool,
#[bit(5, rw)]
data_dir: DataDirection,
#[bit(4, rw)]
timestamp_enable: bool,
#[bit(3, rw)]
bufflock: bool,
#[bit(2, rw)]
tx_logic_level: PinLogicLevel,
#[bit(1, rw)]
rx_logic_level: PinLogicLevel,
#[bit(0, rw)]
enable: bool,
}
#[bitbybit::bitfield(u32)]
#[derive(Debug)]
pub struct TimingConfig {
#[bits(0..=2, rw)]
tseg2: u3,
#[bits(3..=6, rw)]
tseg1: u4,
#[bits(7..=8, rw)]
sync_jump_width: u2,
#[bits(9..=15, rw)]
prescaler: u7,
}
#[bitbybit::bitfield(u32)]
#[derive(Debug)]
pub struct InterruptEnable {
#[bit(15, rw)]
error: bool,
#[bit(0, rw)]
buffer: [bool; 15],
}
#[bitbybit::bitfield(u32)]
#[derive(Debug)]
pub struct InterruptClear {
#[bit(15, w)]
error: bool,
#[bit(0, w)]
buffer: [bool; 15],
}
#[bitbybit::bitfield(u32)]
#[derive(Debug)]
pub struct InterruptPending {
#[bit(15, r)]
error: bool,
#[bit(0, r)]
buffer: [bool; 15],
}
#[bitbybit::bitfield(u32)]
#[derive(Debug)]
pub struct ErrorCounter {
#[bits(0..=7, r)]
transmit: u8,
#[bits(8..=15, r)]
receive: u8,
}
#[derive(derive_mmio::Mmio)]
#[repr(C)]
pub struct Can {
#[mmio(inner)]
cmb0: CanMsgBuf,
#[mmio(inner)]
cmb1: CanMsgBuf,
#[mmio(inner)]
cmb2: CanMsgBuf,
#[mmio(inner)]
cmb3: CanMsgBuf,
#[mmio(inner)]
cmb4: CanMsgBuf,
#[mmio(inner)]
cmb5: CanMsgBuf,
#[mmio(inner)]
cmb6: CanMsgBuf,
#[mmio(inner)]
cmb7: CanMsgBuf,
#[mmio(inner)]
cmb8: CanMsgBuf,
#[mmio(inner)]
cmb9: CanMsgBuf,
#[mmio(inner)]
cmb10: CanMsgBuf,
#[mmio(inner)]
cmb11: CanMsgBuf,
#[mmio(inner)]
cmb12: CanMsgBuf,
#[mmio(inner)]
cmb13: CanMsgBuf,
#[mmio(inner)]
cmb14: CanMsgBuf,
#[mmio(inner)]
hcmb: CanMsgBuf,
control: Control,
timing: TimingConfig,
/// Global mask extension.
gmskx: u32,
/// Global mask base.
gmskb: u32,
/// Basic mask extension.
bmskx: u32,
/// Basic mask base.
bmskb: u32,
ien: InterruptEnable,
#[mmio(PureRead)]
ipnd: InterruptPending,
#[mmio(Write)]
iclr: InterruptClear,
/// Interrupt Code Enable Register.
icen: InterruptEnable,
#[mmio(PureRead)]
status_pending: u32,
#[mmio(PureRead)]
error_counter: ErrorCounter,
#[mmio(PureRead)]
diag: u32,
#[mmio(PureRead)]
timer: u32,
}
impl Can {
/// Create a new CAN MMIO instance for peripheral 0.
///
/// # Safety
///
/// This API can be used to potentially create a driver to the same peripheral structure
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
/// interfere with each other.
pub const unsafe fn new_mmio_fixed_0() -> MmioCan<'static> {
Self::new_mmio_at(CAN_0_BASE)
}
/// Create a new CAN MMIO instance for peripheral 1.
///
/// # Safety
///
/// This API can be used to potentially create a driver to the same peripheral structure
/// from multiple threads. The user must ensure that concurrent accesses are safe and do not
/// interfere with each other.
pub const unsafe fn new_mmio_fixed_1() -> MmioCan<'static> {
Self::new_mmio_at(CAN_1_BASE)
}
}
impl MmioCan<'_> {
// TODO: It would be nice if derive-mmio could generate this for us..
pub fn msg_buf_block_mut(&mut self, idx: usize) -> MmioCanMsgBuf<'static> {
assert!(idx < 16, "invalid index for CAN message buffer");
match idx {
0 => unsafe { self.steal_cmb0() },
1 => unsafe { self.steal_cmb1() },
2 => unsafe { self.steal_cmb2() },
3 => unsafe { self.steal_cmb3() },
4 => unsafe { self.steal_cmb4() },
5 => unsafe { self.steal_cmb5() },
6 => unsafe { self.steal_cmb6() },
7 => unsafe { self.steal_cmb7() },
8 => unsafe { self.steal_cmb8() },
9 => unsafe { self.steal_cmb9() },
10 => unsafe { self.steal_cmb10() },
11 => unsafe { self.steal_cmb11() },
12 => unsafe { self.steal_cmb12() },
13 => unsafe { self.steal_cmb13() },
14 => unsafe { self.steal_cmb14() },
15 => unsafe { self.steal_hcmb() },
_ => unreachable!(),
}
}
}

View File

@ -396,16 +396,45 @@ impl Clocks {
} }
/// Returns the frequency of the APB0 which is equal to the system clock. /// Returns the frequency of the APB0 which is equal to the system clock.
///
/// This clock is the reference clock for the following peripherals:
///
/// - Ethernet
/// - SpaceWire
/// - IRQ Router
/// - DMA
/// - Clock Generator
pub const fn apb0(&self) -> Hertz { pub const fn apb0(&self) -> Hertz {
self.sysclk() self.sysclk()
} }
/// Returns system clock divied by 2. /// Returns system clock divied by 2.
///
/// This clock is the reference clock for the following peripherals:
///
/// - Timer[15:0]
/// - UART2
/// - SPI
/// - I2C
/// - CAN
/// - GPIO
/// - IOCONFIG
/// - System Config
pub const fn apb1(&self) -> Hertz { pub const fn apb1(&self) -> Hertz {
self.apb1 self.apb1
} }
/// Returns system clock divied by 4. /// Returns system clock divied by 4.
///
/// This clock is the reference clock for the following peripherals:
///
/// - Timer[23:16]
/// - TRNG
/// - UART[1:0]
/// - DAC
/// - ADC
/// - Watchdog
/// - Utility
pub const fn apb2(&self) -> Hertz { pub const fn apb2(&self) -> Hertz {
self.apb2 self.apb2
} }

View File

@ -3,7 +3,9 @@
//! ## Examples //! ## Examples
//! //!
//! - [PEB1 accelerometer example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/peb1-accelerometer.rs) //! - [PEB1 accelerometer example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/peb1-accelerometer.rs)
use crate::{clock::Clocks, pac, time::Hertz, typelevel::Sealed, PeripheralSelect, SyscfgExt as _}; use crate::{
clock::Clocks, enable_peripheral_clock, pac, time::Hertz, typelevel::Sealed, PeripheralSelect,
};
use core::{marker::PhantomData, ops::Deref}; use core::{marker::PhantomData, ops::Deref};
use embedded_hal::i2c::{self, Operation, SevenBitAddress, TenBitAddress}; use embedded_hal::i2c::{self, Operation, SevenBitAddress, TenBitAddress};
@ -318,13 +320,12 @@ impl<I2C> I2cBase<I2C> {
impl<I2c: Instance> I2cBase<I2c> { impl<I2c: Instance> I2cBase<I2c> {
pub fn new( pub fn new(
i2c: I2c, i2c: I2c,
syscfg: &mut pac::Sysconfig,
clocks: &Clocks, clocks: &Clocks,
speed_mode: I2cSpeed, speed_mode: I2cSpeed,
ms_cfg: Option<&MasterConfig>, ms_cfg: Option<&MasterConfig>,
sl_cfg: Option<&SlaveConfig>, sl_cfg: Option<&SlaveConfig>,
) -> Result<Self, ClockTooSlowForFastI2cError> { ) -> Result<Self, ClockTooSlowForFastI2cError> {
syscfg.enable_peripheral_clock(I2c::PERIPH_SEL); enable_peripheral_clock(I2c::PERIPH_SEL);
let mut i2c_base = I2cBase { let mut i2c_base = I2cBase {
i2c, i2c,
@ -476,13 +477,12 @@ pub struct I2cMaster<I2c, Addr = SevenBitAddress> {
impl<I2c: Instance, Addr> I2cMaster<I2c, Addr> { impl<I2c: Instance, Addr> I2cMaster<I2c, Addr> {
pub fn new( pub fn new(
i2c: I2c, i2c: I2c,
sys_cfg: &mut pac::Sysconfig,
cfg: MasterConfig, cfg: MasterConfig,
clocks: &Clocks, clocks: &Clocks,
speed_mode: I2cSpeed, speed_mode: I2cSpeed,
) -> Result<Self, ClockTooSlowForFastI2cError> { ) -> Result<Self, ClockTooSlowForFastI2cError> {
Ok(I2cMaster { Ok(I2cMaster {
i2c_base: I2cBase::new(i2c, sys_cfg, clocks, speed_mode, Some(&cfg), None)?, i2c_base: I2cBase::new(i2c, clocks, speed_mode, Some(&cfg), None)?,
addr: PhantomData, addr: PhantomData,
} }
.enable_master()) .enable_master())
@ -737,13 +737,12 @@ pub struct I2cSlave<I2c, Addr = SevenBitAddress> {
impl<I2c: Instance, Addr> I2cSlave<I2c, Addr> { impl<I2c: Instance, Addr> I2cSlave<I2c, Addr> {
fn new_generic( fn new_generic(
i2c: I2c, i2c: I2c,
sys_cfg: &mut pac::Sysconfig,
cfg: SlaveConfig, cfg: SlaveConfig,
clocks: &Clocks, clocks: &Clocks,
speed_mode: I2cSpeed, speed_mode: I2cSpeed,
) -> Result<Self, ClockTooSlowForFastI2cError> { ) -> Result<Self, ClockTooSlowForFastI2cError> {
Ok(I2cSlave { Ok(I2cSlave {
i2c_base: I2cBase::new(i2c, sys_cfg, clocks, speed_mode, None, Some(&cfg))?, i2c_base: I2cBase::new(i2c, clocks, speed_mode, None, Some(&cfg))?,
addr: PhantomData, addr: PhantomData,
} }
.enable_slave()) .enable_slave())
@ -884,7 +883,6 @@ impl<I2c: Instance> I2cSlave<I2c, SevenBitAddress> {
/// Create a new I2C slave for seven bit addresses /// Create a new I2C slave for seven bit addresses
pub fn new( pub fn new(
i2c: I2c, i2c: I2c,
sys_cfg: &mut pac::Sysconfig,
cfg: SlaveConfig, cfg: SlaveConfig,
clocks: &Clocks, clocks: &Clocks,
speed_mode: I2cSpeed, speed_mode: I2cSpeed,
@ -892,18 +890,17 @@ impl<I2c: Instance> I2cSlave<I2c, SevenBitAddress> {
if let I2cAddress::TenBit(_) = cfg.addr { if let I2cAddress::TenBit(_) = cfg.addr {
return Err(InitError::WrongAddrMode); return Err(InitError::WrongAddrMode);
} }
Ok(Self::new_generic(i2c, sys_cfg, cfg, clocks, speed_mode)?) Ok(Self::new_generic(i2c, cfg, clocks, speed_mode)?)
} }
} }
impl<I2c: Instance> I2cSlave<I2c, TenBitAddress> { impl<I2c: Instance> I2cSlave<I2c, TenBitAddress> {
pub fn new_ten_bit_addr( pub fn new_ten_bit_addr(
i2c: I2c, i2c: I2c,
sys_cfg: &mut pac::Sysconfig,
cfg: SlaveConfig, cfg: SlaveConfig,
clocks: &Clocks, clocks: &Clocks,
speed_mode: I2cSpeed, speed_mode: I2cSpeed,
) -> Result<Self, ClockTooSlowForFastI2cError> { ) -> Result<Self, ClockTooSlowForFastI2cError> {
Self::new_generic(i2c, sys_cfg, cfg, clocks, speed_mode) Self::new_generic(i2c, cfg, clocks, speed_mode)
} }
} }

View File

@ -97,39 +97,43 @@ pub enum PeripheralSelect {
pub type PeripheralClock = PeripheralSelect; pub type PeripheralClock = PeripheralSelect;
#[inline(always)] #[inline(always)]
pub fn enable_peripheral_clock(syscfg: &mut pac::Sysconfig, clock: PeripheralSelect) { pub fn enable_peripheral_clock(clock: PeripheralSelect) {
syscfg // Safety: Only bit of peripheral is modified.
unsafe { pac::Sysconfig::steal() }
.peripheral_clk_enable() .peripheral_clk_enable()
.modify(|r, w| unsafe { w.bits(r.bits() | (1 << clock as u8)) }); .modify(|r, w| unsafe { w.bits(r.bits() | (1 << clock as u8)) });
} }
#[inline(always)] #[inline(always)]
pub fn disable_peripheral_clock(syscfg: &mut pac::Sysconfig, clock: PeripheralSelect) { pub fn disable_peripheral_clock(clock: PeripheralSelect) {
syscfg // Safety: Only bit of peripheral is modified.
unsafe { pac::Sysconfig::steal() }
.peripheral_clk_enable() .peripheral_clk_enable()
.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << clock as u8)) }); .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << clock as u8)) });
} }
#[inline(always)] #[inline(always)]
pub fn assert_periph_reset(syscfg: &mut pac::Sysconfig, periph: PeripheralSelect) { pub fn assert_periph_reset(periph: PeripheralSelect) {
syscfg // Safety: Only reset bit of peripheral is modified.
unsafe { pac::Sysconfig::steal() }
.peripheral_reset() .peripheral_reset()
.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << periph as u8)) }); .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << periph as u8)) });
} }
#[inline(always)] #[inline(always)]
pub fn deassert_periph_reset(syscfg: &mut pac::Sysconfig, periph: PeripheralSelect) { pub fn deassert_periph_reset(periph: PeripheralSelect) {
syscfg // Safety: Only rest bit of peripheral is modified.
unsafe { pac::Sysconfig::steal() }
.peripheral_reset() .peripheral_reset()
.modify(|r, w| unsafe { w.bits(r.bits() | (1 << periph as u8)) }); .modify(|r, w| unsafe { w.bits(r.bits() | (1 << periph as u8)) });
} }
#[inline(always)] #[inline(always)]
fn assert_periph_reset_for_two_cycles(syscfg: &mut pac::Sysconfig, periph: PeripheralSelect) { fn assert_periph_reset_for_two_cycles(periph: PeripheralSelect) {
assert_periph_reset(syscfg, periph); assert_periph_reset(periph);
cortex_m::asm::nop(); cortex_m::asm::nop();
cortex_m::asm::nop(); cortex_m::asm::nop();
deassert_periph_reset(syscfg, periph); deassert_periph_reset(periph);
} }
#[derive(Debug, Eq, Copy, Clone, PartialEq)] #[derive(Debug, Eq, Copy, Clone, PartialEq)]
@ -190,27 +194,27 @@ pub trait SyscfgExt {
impl SyscfgExt for pac::Sysconfig { impl SyscfgExt for pac::Sysconfig {
#[inline(always)] #[inline(always)]
fn enable_peripheral_clock(&mut self, clock: PeripheralClock) { fn enable_peripheral_clock(&mut self, clock: PeripheralClock) {
enable_peripheral_clock(self, clock) enable_peripheral_clock(clock)
} }
#[inline(always)] #[inline(always)]
fn disable_peripheral_clock(&mut self, clock: PeripheralClock) { fn disable_peripheral_clock(&mut self, clock: PeripheralClock) {
disable_peripheral_clock(self, clock) disable_peripheral_clock(clock)
} }
#[inline(always)] #[inline(always)]
fn assert_periph_reset(&mut self, clock: PeripheralSelect) { fn assert_periph_reset(&mut self, clock: PeripheralSelect) {
assert_periph_reset(self, clock) assert_periph_reset(clock)
} }
#[inline(always)] #[inline(always)]
fn deassert_periph_reset(&mut self, clock: PeripheralSelect) { fn deassert_periph_reset(&mut self, clock: PeripheralSelect) {
deassert_periph_reset(self, clock) deassert_periph_reset(clock)
} }
#[inline(always)] #[inline(always)]
fn assert_periph_reset_for_two_cycles(&mut self, periph: PeripheralSelect) { fn assert_periph_reset_for_two_cycles(&mut self, periph: PeripheralSelect) {
assert_periph_reset_for_two_cycles(self, periph) assert_periph_reset_for_two_cycles(periph)
} }
} }

View File

@ -21,7 +21,7 @@ use crate::{
pac, pac,
time::Hertz, time::Hertz,
typelevel::{NoneT, Sealed}, typelevel::{NoneT, Sealed},
PeripheralSelect, SyscfgExt as _, PeripheralSelect,
}; };
#[cfg(not(feature = "va41628"))] #[cfg(not(feature = "va41628"))]
@ -1041,15 +1041,14 @@ where
/// to be done once. /// to be done once.
/// * `syscfg` - Can be passed optionally to enable the peripheral clock /// * `syscfg` - Can be passed optionally to enable the peripheral clock
pub fn new( pub fn new(
syscfg: &mut pac::Sysconfig,
clocks: &crate::clock::Clocks, clocks: &crate::clock::Clocks,
spi: SpiI, spi: SpiI,
pins: (Sck, Miso, Mosi), pins: (Sck, Miso, Mosi),
spi_cfg: SpiConfig, spi_cfg: SpiConfig,
) -> Self { ) -> Self {
crate::enable_peripheral_clock(syscfg, SpiI::PERIPH_SEL); crate::enable_peripheral_clock(SpiI::PERIPH_SEL);
// This is done in the C HAL. // This is done in the C HAL.
syscfg.assert_periph_reset_for_two_cycles(SpiI::PERIPH_SEL); crate::assert_periph_reset_for_two_cycles(SpiI::PERIPH_SEL);
let SpiConfig { let SpiConfig {
clk, clk,
init_mode, init_mode,

View File

@ -18,7 +18,7 @@ use fugit::RateExtU32;
use crate::clock::Clocks; use crate::clock::Clocks;
use crate::gpio::PF13; use crate::gpio::PF13;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{disable_nvic_interrupt, enable_nvic_interrupt, PeripheralSelect, SyscfgExt as _}; use crate::{disable_nvic_interrupt, enable_nvic_interrupt, PeripheralSelect};
use crate::{ use crate::{
gpio::{ gpio::{
AltFunc1, AltFunc2, AltFunc3, Pin, PA2, PA3, PB14, PB15, PC14, PC4, PC5, PD11, PD12, PE2, AltFunc1, AltFunc2, AltFunc3, Pin, PA2, PA3, PB14, PB15, PC14, PC4, PC5, PD11, PD12, PE2,
@ -630,15 +630,14 @@ impl<TxPinInst: TxPin<UartInstance>, RxPinInst: RxPin<UartInstance>, UartInstanc
Uart<UartInstance, (TxPinInst, RxPinInst)> Uart<UartInstance, (TxPinInst, RxPinInst)>
{ {
pub fn new( pub fn new(
syscfg: &mut va416xx::Sysconfig,
uart: UartInstance, uart: UartInstance,
pins: (TxPinInst, RxPinInst), pins: (TxPinInst, RxPinInst),
config: impl Into<Config>, config: impl Into<Config>,
clocks: &Clocks, clocks: &Clocks,
) -> Self { ) -> Self {
crate::enable_peripheral_clock(syscfg, UartInstance::PERIPH_SEL); crate::enable_peripheral_clock(UartInstance::PERIPH_SEL);
// This is done in the C HAL. // This is done in the C HAL.
syscfg.assert_periph_reset_for_two_cycles(UartInstance::PERIPH_SEL); crate::assert_periph_reset_for_two_cycles(UartInstance::PERIPH_SEL);
Uart { Uart {
inner: UartBase { inner: UartBase {
uart, uart,
@ -651,13 +650,12 @@ impl<TxPinInst: TxPin<UartInstance>, RxPinInst: RxPin<UartInstance>, UartInstanc
} }
pub fn new_with_clock_freq( pub fn new_with_clock_freq(
syscfg: &mut va416xx::Sysconfig,
uart: UartInstance, uart: UartInstance,
pins: (TxPinInst, RxPinInst), pins: (TxPinInst, RxPinInst),
config: impl Into<Config>, config: impl Into<Config>,
clock: impl Into<Hertz>, clock: impl Into<Hertz>,
) -> Self { ) -> Self {
crate::enable_peripheral_clock(syscfg, UartInstance::PERIPH_SEL); crate::enable_peripheral_clock(UartInstance::PERIPH_SEL);
Uart { Uart {
inner: UartBase { inner: UartBase {
uart, uart,