Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/can-echo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn main() -> ! {
let tx = gpiob.pb9.into_alternate().speed(Speed::VeryHigh);

info!("-- Create CAN 1 instance");
let mut can = dp.FDCAN1.fdcan(tx, rx, &mut rcc);
let mut can = dp.FDCAN1.fdcan((tx, rx), &mut rcc);
can.set_protocol_exception_handling(false);

info!("-- Configure nominal timing");
Expand Down
2 changes: 1 addition & 1 deletion examples/uart-dma-rx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn main() -> ! {
//.USART2
.USART3
.usart(
(tx, rx),
(Some(tx), Some(rx)),
FullConfig::default()
.baudrate(115200.bps())
.receiver_timeout_us(1000), // Timeout after 1ms
Expand Down
4 changes: 2 additions & 2 deletions examples/uart-dma-tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ fn main() -> ! {

info!("Init UART");
let gpioa = dp.GPIOA.split(&mut rcc);
let tx = gpioa.pa2.into_alternate();
let rx = gpioa.pa3;
let tx = Some(gpioa.pa2.into_alternate());
let rx = Some(gpioa.pa3);
let mut usart = dp.USART2.usart((tx, rx), 115200.bps(), &mut rcc).unwrap();

let mut delay_syst = cp.SYST.delay(&rcc.clocks);
Expand Down
2 changes: 1 addition & 1 deletion examples/uart-fifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn main() -> ! {
let mut usart = dp
.USART2
.usart(
(tx, rx),
(Some(tx), Some(rx)),
FullConfig::default()
.baudrate(115200.bps())
.fifo_enable()
Expand Down
6 changes: 3 additions & 3 deletions examples/uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,22 @@ fn main() -> ! {
let rx = gpioa.pa3.into_alternate();
let mut usart = dp
.USART2
.usart(tx, rx, FullConfig::default(), &mut rcc)
.usart(((Some(tx), Some(rx)), FullConfig::default(), &mut rcc)
.unwrap();*/
/*let gpioc = dp.GPIOC.split(&mut rcc);
let tx = gpioc.pc4.into_alternate();
let rx = gpioc.pc5.into_alternate();
let mut usart = dp
.USART1
.usart((tx, rx), FullConfig::default(), &mut rcc)
.usart(((Some(tx), Some(rx)), FullConfig::default(), &mut rcc)
.unwrap();*/

let gpioc = dp.GPIOC.split(&mut rcc);
let tx = gpioc.pc10.into_alternate();
let rx = gpioc.pc11.into_alternate();
let mut usart = dp
.USART3
.usart((tx, rx), FullConfig::default(), &mut rcc)
.usart((Some(tx), Some(rx)), FullConfig::default(), &mut rcc)
.unwrap();

writeln!(usart, "Hello USART3, yay!!\r\n").unwrap();
Expand Down
176 changes: 43 additions & 133 deletions src/can.rs
Original file line number Diff line number Diff line change
@@ -1,193 +1,103 @@
//! # Controller Area Network (CAN) Interface
//!
use crate::gpio::alt::CanCommon;
use crate::rcc::{self, Rcc};

mod sealed {
/// A TX pin configured for CAN communication
pub trait Tx<CAN> {}
/// An RX pin configured for CAN communication
pub trait Rx<CAN> {}
}
pub trait Instance: CanCommon + rcc::Instance + crate::Ptr {}

/// Storage type for the CAN controller
#[derive(Debug)]
pub struct Can<FDCAN> {
rb: FDCAN,
pub struct Can<CAN: Instance> {
rb: CAN,
}
#[allow(dead_code)]
impl<FDCAN> Can<FDCAN> {
impl<CAN: Instance> Can<CAN> {
/// Returns a reference to the inner peripheral
fn inner(&self) -> &FDCAN {
fn inner(&self) -> &CAN {
&self.rb
}
}

/// Extension trait for CAN controller
pub trait CanExt: Sized
pub trait CanExt: Sized + Instance
where
Self: rcc::Instance,
Can<Self>: fdcan::Instance,
{
fn fdcan<TX, RX>(
fn fdcan(
self,
_tx: TX,
_rx: RX,
pins: (impl Into<Self::Tx>, impl Into<Self::Rx>),
Comment on lines -34 to +29
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change? Why a pair instead of two arguments?

rcc: &mut Rcc,
) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode>
where
TX: sealed::Tx<Self>,
RX: sealed::Rx<Self>,
{
) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {
Self::enable(rcc);
let _pins = (pins.0.into(), pins.1.into());

self.fdcan_unchecked()
}

fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode>;
}
/// Implements sealed::{Tx,Rx} for pins associated with a CAN peripheral
macro_rules! pins {
($PER:ident =>
(tx: [ $($( #[ $pmetatx:meta ] )* $tx:ident<$txaf:ident>),+ $(,)? ],
rx: [ $($( #[ $pmetarx:meta ] )* $rx:ident<$rxaf:ident>),+ $(,)? ])) => {
$(
$( #[ $pmetatx ] )*
impl sealed::Tx<$PER> for $tx<$txaf> {}
)+
$(
$( #[ $pmetarx ] )*
impl sealed::Rx<$PER> for $rx<$rxaf> {}
)+
};

impl<CAN: Instance> Can<CAN>
where
Self: fdcan::message_ram::Instance,
{
pub fn new(rb: CAN) -> fdcan::FdCan<Self, fdcan::ConfigMode> {
fdcan::FdCan::new(Self { rb }).into_config_mode()
}
}

unsafe impl<CAN: Instance> fdcan::Instance for Can<CAN>
where
Self: fdcan::message_ram::Instance,
{
const REGISTERS: *mut fdcan::RegisterBlock = CAN::PTR as *mut _;
}

impl<CAN: Instance> CanExt for CAN
where
Can<Self>: fdcan::message_ram::Instance,
{
fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {
Can::new(self)
}
}

mod fdcan1 {
use super::sealed;
use super::{Can, CanExt};
use crate::gpio::{AF9, PA11, PA12, PB8, PB9, PD0, PD1};
use super::{Can, Instance};
use crate::stm32::FDCAN1;
use fdcan;

// All STM32G4 models with CAN support these pins
pins! {
FDCAN1 => (
tx: [
PA12<AF9>,
PB9<AF9>,
PD1<AF9>,
],
rx: [
PA11<AF9>,
PB8<AF9>,
PD0<AF9>,
]
)
}
impl Instance for FDCAN1 {}

impl Can<FDCAN1> {
pub fn fdcan1(rb: FDCAN1) -> fdcan::FdCan<Self, fdcan::ConfigMode> {
fdcan::FdCan::new(Self { rb }).into_config_mode()
}
}
impl CanExt for FDCAN1 {
fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {
Can::fdcan1(self)
}
}
unsafe impl fdcan::Instance for Can<FDCAN1> {
const REGISTERS: *mut fdcan::RegisterBlock = FDCAN1::ptr() as *mut _;
}
unsafe impl fdcan::message_ram::Instance for Can<FDCAN1> {
const MSG_RAM: *mut fdcan::message_ram::RegisterBlock = (0x4000_a400 as *mut _);
}
}

#[cfg(any(
feature = "stm32g473",
feature = "stm32g474",
feature = "stm32g483",
feature = "stm32g484",
feature = "stm32g491",
feature = "stm32g4a1",
))]
#[cfg(feature = "fdcan2")]
mod fdcan2 {
use super::sealed;
use super::{Can, CanExt};
use crate::gpio::{AF9, PB12, PB13, PB5, PB6};
use super::{Can, Instance};
use crate::stm32::FDCAN2;
use fdcan;
use fdcan::message_ram;

pins! {
FDCAN2 => (
tx: [
PB6<AF9>,
PB13<AF9>,
],
rx: [
PB5<AF9>,
PB12<AF9>,
])
}
impl Instance for FDCAN2 {}

impl Can<FDCAN2> {
pub fn fdcan2(rb: FDCAN2) -> fdcan::FdCan<Self, fdcan::ConfigMode> {
fdcan::FdCan::new(Self { rb }).into_config_mode()
}
}
impl CanExt for FDCAN2 {
fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {
Can::fdcan2(self)
}
}
unsafe impl fdcan::Instance for Can<FDCAN2> {
const REGISTERS: *mut fdcan::RegisterBlock = FDCAN2::ptr() as *mut _;
}
unsafe impl fdcan::message_ram::Instance for Can<FDCAN2> {
const MSG_RAM: *mut message_ram::RegisterBlock = (0x4000_a750 as *mut _);
}
}

#[cfg(any(
feature = "stm32g473",
feature = "stm32g474",
feature = "stm32g483",
feature = "stm32g484",
))]
#[cfg(feature = "fdcan3")]
mod fdcan3 {
use super::sealed;
use super::{Can, CanExt};
use crate::gpio::{AF11, PA15, PA8, PB3, PB4};
use super::{Can, Instance};
use crate::stm32::FDCAN3;
use fdcan;
use fdcan::message_ram;

pins! {
FDCAN3 => (
tx: [
PA15<AF11>,
PB4<AF11>,
],
rx: [
PA8<AF11>,
PB3<AF11>,
])
}
impl Instance for FDCAN3 {}

impl Can<FDCAN3> {
pub fn fdcan3(rb: FDCAN3) -> fdcan::FdCan<Self, fdcan::ConfigMode> {
fdcan::FdCan::new(Self { rb }).into_config_mode()
}
}
impl CanExt for FDCAN3 {
fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {
Can::fdcan3(self)
}
}
unsafe impl fdcan::Instance for Can<FDCAN3> {
const REGISTERS: *mut fdcan::RegisterBlock = FDCAN3::ptr() as *mut _;
}
unsafe impl fdcan::message_ram::Instance for Can<FDCAN3> {
const MSG_RAM: *mut message_ram::RegisterBlock = (0x4000_aaa0 as *mut _);
}
Expand Down
10 changes: 6 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,17 @@ impl<RB, const A: usize> Sealed for Periph<RB, A> {}
pub trait Ptr: Sealed {
/// RegisterBlock structure
type RB;
/// Pointer to the register block
const PTR: *const Self::RB;
/// Return the pointer to the register block
fn ptr() -> *const Self::RB;
fn ptr() -> *const Self::RB {
Self::PTR
}
}

impl<RB, const A: usize> Ptr for Periph<RB, A> {
type RB = RB;
fn ptr() -> *const Self::RB {
Self::ptr()
}
const PTR: *const Self::RB = Self::PTR;
}

fn stripped_type_name<T>() -> &'static str {
Expand Down
Loading
Loading