Skip to content

Commit a0e4f46

Browse files
authored
Merge branch 'master' into allow_pullup_inputs_and_opendrain_outputs
2 parents 5d9d6c1 + 82806e1 commit a0e4f46

File tree

9 files changed

+308
-116
lines changed

9 files changed

+308
-116
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616

1717
### Added
1818

19+
- `From<Bps>` for `serial::Config`
1920
- `From<Into<Hertz>>` for `i2c::Mode`
2021
- `exti_rtic` example
2122
- Support for OpenDrain pin configuration on CAN, SPI, UART, PWM output pins
@@ -32,14 +33,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3233
function inputs.
3334

3435
### Fixed
36+
37+
- USART2 remap
3538
- Fix > 2 byte i2c reads
3639
- Send stop after acknowledge errors on i2c
3740
- Fix i2c interactions after errors
3841
- Fix SPI3 alternate function remapping
3942
- Do not enable UART DMA flags unconditionally
43+
- Fix flash erase verification always failing
4044

4145
### Changed
4246

47+
- Move Tx & Rx in Serial. `Read` and `Write` now implemented on `Rx` and `Tx`
4348
- USB driver is now enabled by default for all devices supporting it
4449
- Updated `bxcan` dependency
4550
- Change internal implementation of pins using const generics

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,7 @@ required-features = ["has-can", "rt"]
149149
[[example]]
150150
name = "gpio_input"
151151
required-features = ["stm32f103"]
152+
153+
[[example]]
154+
name = "serial-interrupt-idle"
155+
required-features = ["stm32f103", "rt", "medium"]

examples/serial-interrupt-idle.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//! Serial interface loopback test
2+
//!
3+
//! You have to short the TX and RX pins to make this program work
4+
5+
#![no_main]
6+
#![no_std]
7+
8+
use panic_halt as _;
9+
10+
use cortex_m_rt::entry;
11+
use stm32f1xx_hal::{
12+
pac,
13+
pac::interrupt,
14+
pac::USART1,
15+
prelude::*,
16+
serial::{Config, Rx, Serial, Tx},
17+
};
18+
19+
static mut RX: Option<Rx<USART1>> = None;
20+
static mut TX: Option<Tx<USART1>> = None;
21+
#[entry]
22+
fn main() -> ! {
23+
// Get access to the device specific peripherals from the peripheral access crate
24+
let p = pac::Peripherals::take().unwrap();
25+
26+
// Take ownership over the raw flash and rcc devices and convert them into the corresponding
27+
// HAL structs
28+
let mut flash = p.FLASH.constrain();
29+
let rcc = p.RCC.constrain();
30+
31+
// Freeze the configuration of all the clocks in the system and store the frozen frequencies in
32+
// `clocks`
33+
let clocks = rcc.cfgr.freeze(&mut flash.acr);
34+
35+
// Prepare the alternate function I/O registers
36+
let mut afio = p.AFIO.constrain();
37+
38+
// Prepare the GPIOB peripheral
39+
let mut gpiob = p.GPIOB.split();
40+
41+
// USART1
42+
let tx = gpiob.pb6.into_alternate_push_pull(&mut gpiob.crl);
43+
let rx = gpiob.pb7;
44+
45+
// Set up the usart device. Taks ownership over the USART register and tx/rx pins. The rest of
46+
// the registers are used to enable and configure the device.
47+
let (mut tx, mut rx) = Serial::usart1(
48+
p.USART1,
49+
(tx, rx),
50+
&mut afio.mapr,
51+
Config::default().baudrate(115200.bps()),
52+
clocks,
53+
)
54+
.split();
55+
tx.listen();
56+
rx.listen();
57+
rx.listen_idle();
58+
59+
cortex_m::interrupt::free(|_| unsafe {
60+
TX.replace(tx);
61+
RX.replace(rx);
62+
});
63+
unsafe {
64+
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::USART1);
65+
}
66+
67+
loop {
68+
cortex_m::asm::wfi()
69+
}
70+
}
71+
const BUFFER_LEN: usize = 4096;
72+
static mut BUFFER: &mut [u8; BUFFER_LEN] = &mut [0; BUFFER_LEN];
73+
static mut WIDX: usize = 0;
74+
75+
unsafe fn write(buf: &[u8]) {
76+
if let Some(tx) = TX.as_mut() {
77+
buf.iter()
78+
.for_each(|w| if let Err(_err) = nb::block!(tx.write(*w)) {})
79+
}
80+
}
81+
#[interrupt]
82+
unsafe fn USART1() {
83+
cortex_m::interrupt::free(|_| {
84+
if let Some(rx) = RX.as_mut() {
85+
if rx.is_rx_not_empty() {
86+
if let Ok(w) = nb::block!(rx.read()) {
87+
BUFFER[WIDX] = w;
88+
WIDX += 1;
89+
if WIDX >= BUFFER_LEN - 1 {
90+
write(&BUFFER[..]);
91+
WIDX = 0;
92+
}
93+
}
94+
rx.listen_idle();
95+
} else if rx.is_idle() {
96+
rx.unlisten_idle();
97+
write(&BUFFER[0..WIDX]);
98+
WIDX = 0;
99+
}
100+
}
101+
})
102+
}

src/afio.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl AfioExt for AFIO {
4242
/// ```rust
4343
/// let p = pac::Peripherals::take().unwrap();
4444
/// let mut rcc = p.RCC.constrain();
45-
/// let mut afio = p.AFIO.constrain(&mut rcc.apb2);
45+
/// let mut afio = p.AFIO.constrain();
4646
pub struct Parts {
4747
pub evcr: EVCR,
4848
pub mapr: MAPR,
@@ -70,7 +70,7 @@ impl EVCR {
7070
/// ```rust
7171
/// let dp = pac::Peripherals::take().unwrap();
7272
/// let mut rcc = dp.RCC.constrain();
73-
/// let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
73+
/// let mut afio = dp.AFIO.constrain();
7474
/// function_using_mapr(&mut afio.mapr);
7575
/// ```
7676
pub struct MAPR {

src/flash.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl<'a> FlashWriter<'a> {
170170
// 'start_offset' was.
171171
let size = self.sector_sz.kbytes() as u32;
172172
let start = start_offset & !(size - 1);
173-
for idx in start..start + size {
173+
for idx in (start..start + size).step_by(2) {
174174
let write_address = (FLASH_START + idx as u32) as *const u16;
175175
let verify: u16 = unsafe { core::ptr::read_volatile(write_address) };
176176
if verify != 0xFFFF {

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
//! let clocks = rcc.cfgr.freeze(&mut flash.acr);
6363
//!
6464
//! // Prepare the alternate function I/O registers
65-
//! let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
65+
//! let mut afio = dp.AFIO.constrain();
6666
//! ```
6767
//!
6868
//! ## Usage examples

src/pwm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
// Set up the timer as a PWM output. If selected pins may correspond to different remap options,
2525
// then you must specify the remap generic parameter. Otherwise, if there is no such ambiguity,
2626
// the remap generic parameter can be omitted without complains from the compiler.
27-
let (c1, c2, c3, c4) = Timer::tim2(p.TIM2, &clocks, &mut rcc.apb1)
27+
let (c1, c2, c3, c4) = Timer::tim2(p.TIM2, &clocks)
2828
.pwm::<Tim2NoRemap, _, _, _>(pins, &mut afio.mapr, 1.khz())
2929
.3;
3030
@@ -43,7 +43,7 @@
4343
4444
// Put the timer in PWM mode using the specified pins
4545
// with a frequency of 100 hz.
46-
let (c0, c1, c2, c3) = Timer::tim2(device.TIM2, &clocks, &mut rcc.apb1)
46+
let (c0, c1, c2, c3) = Timer::tim2(device.TIM2, &clocks)
4747
.pwm::<Tim2NoRemap, _, _, _>(pins, &mut afio.mapr, 100.hz());
4848
4949
// Set the duty cycle of channel 0 to 50%

0 commit comments

Comments
 (0)