Skip to content

Commit 951e461

Browse files
authored
Merge pull request #24 from dkm/master
Some little enhancements...
2 parents 681dd11 + 2d92eb3 commit 951e461

File tree

6 files changed

+214
-4
lines changed

6 files changed

+214
-4
lines changed

tm4c-hal/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ documentation = "https://docs.rs/tm4c-hal"
1717

1818
[dependencies]
1919
cortex-m = "0.6"
20+
nb = "0.1.0"
2021

2122
[dependencies.embedded-hal]
2223
version = "0.2.2"

tm4c-hal/src/gpio.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ where
8989
/// Output)
9090
pub struct PushPull;
9191
impl OutputMode for PushPull {}
92+
impl OutputMode for PullDown {}
93+
impl OutputMode for PullUp {}
9294

9395
/// Sub-mode of Output/AlternateFunction: Open drain output (type state for
9496
/// Output)

tm4c-hal/src/lib.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#![deny(warnings)]
66
#![allow(deprecated)]
77

8+
extern crate embedded_hal as hal;
9+
extern crate nb;
10+
811
pub mod bb;
912
pub mod delay;
1013
pub mod gpio;
@@ -207,6 +210,48 @@ macro_rules! gpio_macro {
207210
$PXi { _mode: PhantomData }
208211
}
209212

213+
/// Configures the pin to serve as alternate function 1 through 15 with
214+
/// a weak pull-up resistor.
215+
pub fn into_af_pull_up<AF>(
216+
self,
217+
_gpio_control: &mut GpioControl,
218+
) -> $PXi<AlternateFunction<AF, PullUp>> where AF: AlternateFunctionChoice {
219+
let p = unsafe { &*$GPIOX::ptr() };
220+
let mask = 0xF << ($i * 4);
221+
let bits = AF::number() << ($i * 4);
222+
unsafe {
223+
p.pctl.modify(|r, w| w.bits((r.bits() & !mask) | bits));
224+
}
225+
unsafe { bb::change_bit(&p.afsel, $i, true); }
226+
unsafe { bb::change_bit(&p.dir, $i, false); }
227+
unsafe { bb::change_bit(&p.odr, $i, false); }
228+
unsafe { bb::change_bit(&p.pur, $i, true); }
229+
unsafe { bb::change_bit(&p.pdr, $i, false); }
230+
unsafe { bb::change_bit(&p.den, $i, true); }
231+
$PXi { _mode: PhantomData }
232+
}
233+
234+
/// Configures the pin to serve as alternate function 1 through 15 with
235+
/// a weak pull-down resistor.
236+
pub fn into_af_pull_down<AF>(
237+
self,
238+
_gpio_control: &mut GpioControl,
239+
) -> $PXi<AlternateFunction<AF, PullDown>> where AF: AlternateFunctionChoice {
240+
let p = unsafe { &*$GPIOX::ptr() };
241+
let mask = 0xF << ($i * 4);
242+
let bits = AF::number() << ($i * 4);
243+
unsafe {
244+
p.pctl.modify(|r, w| w.bits((r.bits() & !mask) | bits));
245+
}
246+
unsafe { bb::change_bit(&p.afsel, $i, true); }
247+
unsafe { bb::change_bit(&p.dir, $i, false); }
248+
unsafe { bb::change_bit(&p.odr, $i, false); }
249+
unsafe { bb::change_bit(&p.pur, $i, false); }
250+
unsafe { bb::change_bit(&p.pdr, $i, true); }
251+
unsafe { bb::change_bit(&p.den, $i, true); }
252+
$PXi { _mode: PhantomData }
253+
}
254+
210255
/// Configures the pin to serve as alternate function 1 through 15.
211256
/// Enables open-drain (useful for I2C SDA, for example).
212257
pub fn into_af_open_drain<AF, ODM>(

tm4c123x-hal/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ pub mod prelude;
3434
pub mod serial;
3535
pub mod spi;
3636
pub mod sysctl;
37+
pub mod timer;
3738

38-
use embedded_hal as hal;
39+
extern crate embedded_hal as hal;
40+
extern crate nb;
3941
pub use tm4c123x;
4042
pub use tm4c123x::{CorePeripherals, Peripherals};

tm4c123x-hal/src/spi.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,8 @@ macro_rules! hal {
130130
spi.cr0.modify(|_,w| unsafe {
131131
w.spo().bit(mode.polarity == Polarity::IdleHigh)
132132
.sph().bit(mode.phase == Phase::CaptureOnSecondTransition)
133-
// FIXME: How to use FRFR::MOTO and DSS:: ?
134-
.frf().bits(0)
135-
.dss().bits(0x7)
133+
.frf().moto()
134+
.dss()._8()
136135
.scr().bits(scr)
137136
});
138137

tm4c123x-hal/src/timer.rs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
//! Timers
2+
3+
extern crate embedded_hal as hal;
4+
5+
use tm4c_hal::time::Hertz;
6+
7+
use crate::sysctl;
8+
use hal::timer::{CountDown, Periodic};
9+
use nb;
10+
use tm4c123x::{TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5};
11+
use tm4c123x::{WTIMER0, WTIMER1, WTIMER2, WTIMER3, WTIMER4, WTIMER5};
12+
13+
use crate::sysctl::Clocks;
14+
use void::Void;
15+
16+
/// Hardware timers
17+
pub struct Timer<TIM> {
18+
tim: TIM,
19+
clocks: Clocks,
20+
timeout: Hertz,
21+
}
22+
23+
/// Interrupt events
24+
pub enum Event {
25+
/// Timer timed out / count down ended
26+
TimeOut,
27+
}
28+
29+
macro_rules! hal {
30+
($($TIM:ident: ($tim:ident, $powerDomain:ident),)+) => {
31+
$(
32+
impl Periodic for Timer<$TIM> {}
33+
34+
impl CountDown for Timer<$TIM> {
35+
type Time = Hertz;
36+
37+
#[allow(unused_unsafe)]
38+
fn start<T>(&mut self, timeout: T)
39+
where
40+
T: Into<Hertz>,
41+
{
42+
// Disable timer
43+
self.tim.ctl.modify(|_, w|
44+
w.taen().clear_bit()
45+
.tben().clear_bit()
46+
);
47+
self.timeout = timeout.into();
48+
49+
let frequency = self.timeout.0;
50+
let ticks = self.clocks.sysclk.0 / frequency;
51+
52+
self.tim.tav.write(|w| unsafe { w.bits(ticks) });
53+
self.tim.tailr.write(|w| unsafe { w.bits(ticks) });
54+
55+
// // start counter
56+
self.tim.ctl.modify(|_, w|
57+
w.taen().set_bit()
58+
);
59+
}
60+
61+
fn wait(&mut self) -> nb::Result<(), Void> {
62+
if self.tim.ris.read().tatoris().bit_is_clear () {
63+
Err(nb::Error::WouldBlock)
64+
} else {
65+
self.tim.icr.write(|w| w.tatocint().set_bit());
66+
Ok(())
67+
}
68+
}
69+
}
70+
71+
impl Timer<$TIM> {
72+
// XXX(why not name this `new`?) bummer: constructors need to have different names
73+
// even if the `$TIM` are non overlapping (compare to the `free` function below
74+
// which just works)
75+
/// Configures a TIM peripheral as a periodic count down timer
76+
pub fn $tim<T>(tim: $TIM, timeout: T,
77+
pc: &sysctl::PowerControl,
78+
clocks: &Clocks,
79+
) -> Self
80+
where
81+
T: Into<Hertz>,
82+
{
83+
// power up
84+
sysctl::control_power(
85+
pc, sysctl::Domain::$powerDomain,
86+
sysctl::RunMode::Run, sysctl::PowerState::On);
87+
sysctl::reset(pc, sysctl::Domain::$powerDomain);
88+
89+
// Stop Timers
90+
tim.ctl.write(|w|
91+
w.taen().clear_bit()
92+
.tben().clear_bit()
93+
.tastall().set_bit()
94+
);
95+
96+
// GPTMCFG = 0x0 (chained - 2x16 = 32bits) This
97+
// will not force 32bits wide timer, this will
98+
// really force the wider range to be used (32 for
99+
// 16/32bits timers, 64 for 32/64).
100+
tim.cfg.write(|w| w.cfg()._32_bit_timer());
101+
102+
tim.tamr.write(|w| w.tamr().period());
103+
104+
let mut timer = Timer {
105+
tim:tim,
106+
clocks: *clocks,
107+
timeout: Hertz(0),
108+
};
109+
timer.start(timeout);
110+
111+
timer
112+
}
113+
114+
/// Starts listening for an `event`
115+
pub fn listen(&mut self, event: Event) {
116+
match event {
117+
Event::TimeOut => {
118+
// Enable update event interrupt
119+
self.tim.imr.modify(|_,w| w.tatoim().set_bit());
120+
}
121+
}
122+
}
123+
124+
/// Stops listening for an `event`
125+
pub fn unlisten(&mut self, event: Event) {
126+
match event {
127+
Event::TimeOut => {
128+
// Enable update event interrupt
129+
self.tim.imr.modify(|_,w| w.tatoim().clear_bit());
130+
}
131+
}
132+
}
133+
134+
/// Releases the TIM peripheral
135+
pub fn free(self) -> $TIM {
136+
// pause counter
137+
self.tim.ctl.write(|w|
138+
w.taen().clear_bit()
139+
.tben().clear_bit());
140+
self.tim
141+
}
142+
}
143+
)+
144+
}
145+
}
146+
147+
hal! {
148+
TIMER0: (timer0, Timer0),
149+
TIMER1: (timer1, Timer1),
150+
TIMER2: (timer2, Timer2),
151+
TIMER3: (timer3, Timer3),
152+
TIMER4: (timer4, Timer4),
153+
TIMER5: (timer5, Timer5),
154+
155+
WTIMER0: (wtimer0, WideTimer0),
156+
WTIMER1: (wtimer1, WideTimer1),
157+
WTIMER2: (wtimer2, WideTimer2),
158+
WTIMER3: (wtimer3, WideTimer3),
159+
WTIMER4: (wtimer4, WideTimer4),
160+
WTIMER5: (wtimer5, WideTimer5),
161+
}

0 commit comments

Comments
 (0)