Skip to content

Commit 10d5d70

Browse files
committed
First compiling commit of CAN driver with all traits marked with unimplemented!()
Signed-off-by: delphi <[email protected]>
1 parent 37d0dec commit 10d5d70

File tree

5 files changed

+279
-1
lines changed

5 files changed

+279
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ nb = "0.1.2"
1616
void = { version = "1.0.2", default-features = false }
1717
cast = { version = "0.2.3", default-features = false }
1818
vcell = "0.1.2"
19+
embedded-can = "0.3.0"
1920

2021
[dependencies.embedded-hal]
2122
version = "0.2.3"

src/afio.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,11 @@ macro_rules! remap {
119119
}
120120

121121
remap! {
122+
CAN0 => (can0_remap, u8),
123+
CAN1 => (can1_remap, bool),
122124
I2C0 => (i2c0_remap, bool),
123125
SPI0 => (spi0_remap, bool),
124-
SPI2 => (spi2_remap, bool),
126+
SPI2 => (spi2_remap, bool),
125127
USART0 => (usart0_remap, bool),
126128
USART1 => (usart1_remap, bool),
127129
USART2 => (usart2_remap, u8),

src/can.rs

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
//! # Controller area network controller
2+
3+
use nb;
4+
5+
pub use crate::hal_can::{Id, Frame as FrameTrait,Can as CanTrait};
6+
use crate::pac::{can0, CAN0, CAN1};
7+
use crate::gpio::gpioa::{PA11, PA12};
8+
use crate::gpio::gpiob::{PB5, PB6, PB8, PB9, PB12, PB13};
9+
use crate::gpio::gpiod::{PD0, PD1};
10+
use crate::gpio::{Alternate, Floating, Input, PushPull};
11+
use crate::rcu::{Rcu, Enable, Reset, BaseFrequency};
12+
use crate::time::Hertz;
13+
use crate::afio::{Afio, Remap};
14+
use core::{convert::TryInto, ops::Deref};
15+
16+
pub struct Frame{
17+
}
18+
19+
impl FrameTrait for Frame {
20+
/// Creates a new frame.
21+
/// Returns an error when the data slice is too long.
22+
fn new(id: impl Into<Id>, data: &[u8]) -> Result<Self, ()>{
23+
unimplemented!()
24+
}
25+
26+
/// Creates a new remote frame (RTR bit set).
27+
/// Returns an error when the data length code (DLC) is not valid.
28+
fn new_remote(id: impl Into<Id>, dlc: usize) -> Result<Self, ()>{
29+
unimplemented!()
30+
}
31+
32+
/// Returns true if this frame is a extended frame.
33+
fn is_extended(&self) -> bool{
34+
unimplemented!()
35+
}
36+
37+
38+
/// Returns true if this frame is a remote frame.
39+
fn is_remote_frame(&self) -> bool{
40+
unimplemented!()
41+
}
42+
43+
/// Returns the frame identifier.
44+
fn id(&self) -> Id{
45+
unimplemented!()
46+
}
47+
48+
/// Returns the data length code (DLC) which is in the range 0..8.
49+
///
50+
/// For data frames the DLC value always matches the length of the data.
51+
/// Remote frames do not carry any data, yet the DLC can be greater than 0.
52+
fn dlc(&self) -> usize{
53+
unimplemented!()
54+
}
55+
56+
/// Returns the frame data (0..8 bytes in length).
57+
fn data(&self) -> &[u8]{
58+
unimplemented!()
59+
}
60+
}
61+
62+
/// Can error
63+
#[derive(Debug)]
64+
pub enum Error {
65+
/// Overrun occurred
66+
Overrun,
67+
/// Mode fault occurred
68+
ModeFault,
69+
/// CRC error
70+
Crc,
71+
#[doc(hidden)]
72+
_Extensible,
73+
}
74+
75+
pub enum CanMode{
76+
Normal = 0b00,
77+
Silent = 0b10,
78+
Loopback = 0b01,
79+
SilentLoopback = 0b11
80+
}
81+
82+
#[derive(Clone)]
83+
pub struct TimeQuantaConfiguration{
84+
pub sync: u8,
85+
pub propagandation: u8,
86+
pub before_sample: u8,
87+
pub after_sample: u8
88+
}
89+
90+
impl TimeQuantaConfiguration{
91+
fn sum(&self) -> u32{
92+
(self.sync + self.propagandation + self.before_sample + self.after_sample) as u32
93+
}
94+
fn bs1(&self) -> u8 {
95+
self.propagandation + self.before_sample
96+
}
97+
fn bs2(&self) -> u8 {
98+
self.after_sample
99+
}
100+
}
101+
102+
#[doc(hidden)]
103+
pub trait CanX: Deref<Target = can0::RegisterBlock> {}
104+
impl CanX for CAN0 {}
105+
impl CanX for CAN1 {}
106+
107+
pub trait Pins<CAN> {
108+
type Variant;
109+
const REMAP: Self::Variant;
110+
}
111+
112+
impl Pins<CAN0>
113+
for (
114+
PA11<Input<Floating>>,
115+
PA12<Alternate<PushPull>>,
116+
)
117+
{
118+
type Variant = u8;
119+
const REMAP: u8 = 0b00;
120+
}
121+
impl Pins<CAN0>
122+
for (
123+
PB8<Input<Floating>>,
124+
PB9<Alternate<PushPull>>,
125+
)
126+
{
127+
type Variant = u8;
128+
const REMAP: u8 = 0b10;
129+
}
130+
impl Pins<CAN0>
131+
for (
132+
PD0<Input<Floating>>,
133+
PD1<Alternate<PushPull>>,
134+
)
135+
{
136+
type Variant = u8;
137+
const REMAP: u8 = 0b11;
138+
}
139+
140+
impl Pins<CAN1>
141+
for (
142+
PB12<Input<Floating>>,
143+
PB13<Alternate<PushPull>>,
144+
)
145+
{
146+
type Variant = bool;
147+
const REMAP: bool = false;
148+
}
149+
impl Pins<CAN1>
150+
for (
151+
PB5<Input<Floating>>,
152+
PB6<Alternate<PushPull>>,
153+
)
154+
{
155+
type Variant = bool;
156+
const REMAP: bool = true;
157+
}
158+
159+
pub struct Can<CAN, PINS> {
160+
can: CAN,
161+
pins: PINS,
162+
}
163+
164+
impl<PINS: Pins<CAN0, Variant=u8>> Can<CAN0, PINS> {
165+
pub fn can0(
166+
can: CAN0,
167+
pins: PINS,
168+
afio: &mut Afio,
169+
tqc : TimeQuantaConfiguration,
170+
mode: CanMode,
171+
freq: impl Into<Hertz>,
172+
rcu: &mut Rcu
173+
) -> Self
174+
{
175+
CAN0::remap(afio, PINS::REMAP);
176+
Can::new(can, pins, tqc, mode,freq, rcu)
177+
}
178+
}
179+
180+
impl<PINS: Pins<CAN1, Variant=bool>> Can<CAN1, PINS> {
181+
pub fn can1(
182+
can: CAN1,
183+
pins: PINS,
184+
afio: &mut Afio,
185+
tqc : TimeQuantaConfiguration,
186+
mode: CanMode,
187+
freq: impl Into<Hertz>,
188+
rcu: &mut Rcu
189+
) -> Self
190+
{
191+
CAN1::remap(afio, PINS::REMAP);
192+
Can::new(can, pins, tqc, mode, freq, rcu)
193+
}
194+
}
195+
196+
197+
impl<CAN, PINS> Can<CAN, PINS> where CAN: CanX
198+
{
199+
const MAX_PSC : u16 = 0b111111111;
200+
fn new(
201+
can: CAN,
202+
pins: PINS,
203+
tqc : TimeQuantaConfiguration,
204+
mode: CanMode,
205+
freq: impl Into<Hertz>,
206+
rcu: &mut Rcu
207+
) -> Self where CAN: Enable + Reset + BaseFrequency {
208+
209+
let baudpsc:u16= (
210+
CAN::base_frequency(rcu).0 / (freq.into().0 * tqc.sum() )
211+
).try_into().unwrap_or(Self::MAX_PSC);
212+
let baudpsc:u16 = if baudpsc > Self::MAX_PSC {
213+
Self::MAX_PSC
214+
} else if baudpsc == 0 {
215+
unreachable!();
216+
} else{
217+
baudpsc
218+
};
219+
220+
CAN::enable(rcu);
221+
CAN::reset(rcu);
222+
can.bt.write(|w| unsafe{w
223+
.baudpsc().bits(baudpsc)
224+
.scmod().bit(match mode {
225+
CanMode::Silent | CanMode::SilentLoopback => {true},
226+
_ => {false},
227+
})
228+
.lcmod().bit(match mode {
229+
CanMode::Loopback | CanMode::SilentLoopback => {true},
230+
_ => {false},
231+
})
232+
.sjw().bits(tqc.sync)
233+
.bs1().bits(tqc.bs1())
234+
.bs2().bits(tqc.bs2())
235+
});
236+
Can{can, pins}
237+
}
238+
}
239+
240+
241+
/// A CAN interface that is able to transmit and receive frames.
242+
impl<CAN, PINS> CanTrait for Can<CAN, PINS> {
243+
/// Associated frame type.
244+
type Frame = Frame;
245+
246+
/// Associated error type.
247+
type Error = Error;
248+
249+
/// Puts a frame in the transmit buffer to be sent on the bus.
250+
///
251+
/// If the transmit buffer is full, this function will try to replace a pending
252+
/// lower priority frame and return the frame that was replaced.
253+
/// Returns `Err(WouldBlock)` if the transmit buffer is full and no frame can be
254+
/// replaced.
255+
///
256+
/// # Notes for implementers
257+
///
258+
/// * Frames of equal identifier shall be transmited in FIFO fashion when more
259+
/// than one transmit buffer is available.
260+
/// * When replacing pending frames make sure the frame is not in the process of
261+
/// being send to the bus.
262+
fn try_transmit(&mut self, frame: &Self::Frame)
263+
-> nb::Result<Option<Self::Frame>, Self::Error>{
264+
unimplemented!()
265+
}
266+
267+
/// Returns a received frame if available.
268+
fn try_receive(&mut self) -> nb::Result<Self::Frame, Self::Error>{
269+
unimplemented!()
270+
}
271+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
pub use gd32vf103_pac as pac;
99

1010
use embedded_hal as hal;
11+
use embedded_can as hal_can;
1112

1213
pub mod afio;
1314
pub mod backup_domain;
15+
pub mod can;
1416
pub mod delay;
1517
pub mod eclic;
1618
pub mod exmc;

src/rcu.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ base_freq! {
285285
SPI0 => pclk2,
286286
SPI1 => pclk1,
287287
SPI2 => pclk1,
288+
CAN0 => pclk1,
289+
CAN1 => pclk1,
288290
TIMER0 => timer0,
289291
TIMER1 => timerx,
290292
TIMER2 => timerx,

0 commit comments

Comments
 (0)