Skip to content

Commit 5687091

Browse files
TeXitoitherealprof
authored andcommitted
Handle debugger pins (#79)
* Handle debugger pins At startup, pins used by the debugger are in `Debugger` state, prohibiting their use. `disable_jtag` allow to get PA15, PB3 and PB4 usable as GPIO or alternate functions at the cost of disabling JTAG. * Use the Active marker trait to block Debugger state
1 parent 0c8cce5 commit 5687091

File tree

6 files changed

+68
-17
lines changed

6 files changed

+68
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2020
### Breaking changes
2121

2222
- ADC now requires the clock configuration for intialisation
23+
- `disable_jtag` now transforms PA15, PB3 and PB4 to forbid their use without desactivating JTAG
2324

2425
### Changed
2526

examples/nojtag.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@ fn main() -> ! {
1717
let p = pac::Peripherals::take().unwrap();
1818

1919
let mut rcc = p.RCC.constrain();
20+
let mut gpioa = p.GPIOA.split(&mut rcc.apb2);
2021
let mut gpiob = p.GPIOB.split(&mut rcc.apb2);
2122
let mut afio = p.AFIO.constrain(&mut rcc.apb2);
2223

23-
afio.mapr.disable_jtag();
24+
let (pa15, pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4);
2425

25-
gpiob.pb4.into_push_pull_output(&mut gpiob.crl).set_low();
26+
let mut pa15 = pa15.into_push_pull_output(&mut gpioa.crh);
27+
let mut pb3 = pb3.into_push_pull_output(&mut gpiob.crl);
28+
let mut pb4 = pb4.into_push_pull_output(&mut gpiob.crl);
2629

27-
loop {}
30+
loop {
31+
pa15.toggle();
32+
pb3.toggle();
33+
pb4.toggle();
34+
cortex_m::asm::delay(8_000_000);
35+
}
2836
}

examples/pwm_custom.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,12 @@ fn main() -> ! {
5050
let clocks = rcc.cfgr.freeze(&mut flash.acr);
5151

5252
let mut afio = p.AFIO.constrain(&mut rcc.apb2);
53-
53+
let gpioa = p.GPIOA.split(&mut rcc.apb2);
5454
let mut gpiob = p.GPIOB.split(&mut rcc.apb2);
55+
let (_pa15, _pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4);
5556

5657
// TIM3
57-
let p0 = gpiob.pb4.into_alternate_push_pull(&mut gpiob.crl);
58+
let p0 = pb4.into_alternate_push_pull(&mut gpiob.crl);
5859
let p1 = gpiob.pb5.into_alternate_push_pull(&mut gpiob.crl);
5960

6061
let mut pwm = p.TIM3.pwm(

examples/pwm_input.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ fn main() -> ! {
2525
let mut afio = p.AFIO.constrain(&mut rcc.apb2);
2626
let mut dbg = p.DBGMCU;
2727

28-
let mut gpiob = p.GPIOB.split(&mut rcc.apb2);
28+
let gpioa = p.GPIOA.split(&mut rcc.apb2);
29+
let gpiob = p.GPIOB.split(&mut rcc.apb2);
2930

30-
let pb4 = gpiob.pb4;
31+
let (_pa15, _pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4);
3132
let pb5 = gpiob.pb5;
3233

3334
let pwm_input = p.TIM3.pwm_input(

src/afio.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ use crate::pac::{afio, AFIO};
33

44
use crate::rcc::APB2;
55

6+
use crate::gpio::{
7+
Debugger,
8+
Input,
9+
Floating,
10+
gpioa::PA15,
11+
gpiob::{PB3, PB4},
12+
};
13+
614
pub trait AfioExt {
715
fn constrain(self, apb2: &mut APB2) -> Parts;
816
}
@@ -54,10 +62,22 @@ impl MAPR {
5462
unsafe { &(*AFIO::ptr()).mapr }
5563
}
5664

57-
/// Disables the JTAG to free up pb3, pb4 and pa15 for normal use
58-
pub fn disable_jtag(&mut self) {
65+
/// Disables the JTAG to free up pa15, pb3 and pb4 for normal use
66+
pub fn disable_jtag(
67+
&mut self,
68+
pa15: PA15<Debugger>,
69+
pb3: PB3<Debugger>,
70+
pb4: PB4<Debugger>
71+
) -> (
72+
PA15<Input<Floating>>,
73+
PB3<Input<Floating>>,
74+
PB4<Input<Floating>>,
75+
) {
5976
self.mapr()
60-
.modify(|_, w| unsafe { w.swj_cfg().bits(0b010) })
77+
.modify(|_, w| unsafe { w.swj_cfg().bits(0b010) });
78+
79+
// NOTE(unsafe) The pins are now in the good state.
80+
unsafe { (pa15.activate(), pb3.activate(), pb4.activate()) }
6181
}
6282
}
6383

src/gpio.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,17 @@ pub trait GpioExt {
1313
fn split(self, apb2: &mut APB2) -> Self::Parts;
1414
}
1515

16+
/// Marker trait for active states.
17+
pub trait Active {}
18+
1619
/// Input mode (type state)
1720
pub struct Input<MODE> {
1821
_mode: PhantomData<MODE>,
1922
}
23+
impl<MODE> Active for Input<MODE> {}
2024

25+
/// Used by the debugger (type state)
26+
pub struct Debugger;
2127
/// Floating input (type state)
2228
pub struct Floating;
2329
/// Pulled down input (type state)
@@ -29,6 +35,7 @@ pub struct PullUp;
2935
pub struct Output<MODE> {
3036
_mode: PhantomData<MODE>,
3137
}
38+
impl<MODE> Active for Output<MODE> {}
3239

3340
/// Push pull output (type state)
3441
pub struct PushPull;
@@ -37,11 +44,13 @@ pub struct OpenDrain;
3744

3845
/// Analog mode (type state)
3946
pub struct Analog;
47+
impl Active for Analog {}
4048

4149
/// Alternate function
4250
pub struct Alternate<MODE> {
4351
_mode: PhantomData<MODE>,
4452
}
53+
impl<MODE> Active for Alternate<MODE> {}
4554

4655
pub enum State {
4756
High,
@@ -69,6 +78,8 @@ macro_rules! gpio {
6978
PushPull,
7079
Analog,
7180
State,
81+
Active,
82+
Debugger,
7283
};
7384

7485
/// GPIO parts
@@ -184,7 +195,16 @@ macro_rules! gpio {
184195
_mode: PhantomData<MODE>,
185196
}
186197

187-
impl<MODE> $PXi<MODE> {
198+
impl $PXi<Debugger> {
199+
/// Put the pin in an active state. The caller
200+
/// must enforce that the pin is really in this
201+
/// state in the hardware.
202+
pub(crate) unsafe fn activate(self) -> $PXi<Input<Floating>> {
203+
$PXi { _mode: PhantomData }
204+
}
205+
}
206+
207+
impl<MODE> $PXi<MODE> where MODE: Active {
188208
/// Configures the pin to operate as an alternate function push-pull output
189209
/// pin.
190210
pub fn into_alternate_push_pull(
@@ -402,7 +422,7 @@ macro_rules! gpio {
402422
}
403423
}
404424

405-
impl<MODE> $PXi<MODE> {
425+
impl<MODE> $PXi<MODE> where MODE: Active {
406426
/// Erases the pin number from the type
407427
///
408428
/// This is useful when you want to collect the pins into an array where you
@@ -503,17 +523,17 @@ gpio!(GPIOA, gpioa, gpioa, iopaen, ioparst, PAx, [
503523
PA10: (pa10, 10, Input<Floating>, CRH),
504524
PA11: (pa11, 11, Input<Floating>, CRH),
505525
PA12: (pa12, 12, Input<Floating>, CRH),
506-
PA13: (pa13, 13, Input<Floating>, CRH),
507-
PA14: (pa14, 14, Input<Floating>, CRH),
508-
PA15: (pa15, 15, Input<Floating>, CRH),
526+
PA13: (pa13, 13, Debugger, CRH),
527+
PA14: (pa14, 14, Debugger, CRH),
528+
PA15: (pa15, 15, Debugger, CRH),
509529
]);
510530

511531
gpio!(GPIOB, gpiob, gpioa, iopben, iopbrst, PBx, [
512532
PB0: (pb0, 0, Input<Floating>, CRL),
513533
PB1: (pb1, 1, Input<Floating>, CRL),
514534
PB2: (pb2, 2, Input<Floating>, CRL),
515-
PB3: (pb3, 3, Input<Floating>, CRL),
516-
PB4: (pb4, 4, Input<Floating>, CRL),
535+
PB3: (pb3, 3, Debugger, CRL),
536+
PB4: (pb4, 4, Debugger, CRL),
517537
PB5: (pb5, 5, Input<Floating>, CRL),
518538
PB6: (pb6, 6, Input<Floating>, CRL),
519539
PB7: (pb7, 7, Input<Floating>, CRL),

0 commit comments

Comments
 (0)