Skip to content

Commit

Permalink
Merge pull request stm32-rs#1 from stm32-rs/master
Browse files Browse the repository at this point in the history
Merge upstream master
  • Loading branch information
justacec authored Jan 21, 2020
2 parents 8f19128 + b9ce574 commit 0a555c9
Show file tree
Hide file tree
Showing 19 changed files with 266 additions and 213 deletions.
Binary file added BluePillPinout.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 8 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [v0.5.3] - 2020-01-20

- Add `InputPin` impl for generic open drain outputs
- Implement `Read<u8>` / `Write<u8>` for `Serial` (#171)
- Fix docs.rs build

## [v0.5.2] - 2019-12-15

Expand Down Expand Up @@ -85,7 +89,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Replace gpio traits with digital::v2
- Bump `stm32f1` dependency (`0.8.0`)
- ADC now requires the clock configuration for initialisation
- `disable_jtag` now transforms PA15, PB3 and PB4 to forbid their use without desactivating JTAG
- `disable_jtag` now transforms PA15, PB3 and PB4 to forbid their use without deactivating JTAG

### Changed

Expand All @@ -106,7 +110,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Add methods `stop`, `release` and `clear_update_interrupt_flag` to `Timer` (`clear_update_interrupt_flag` does not apply to `Timer<SYST>`)
- Add timer interrupt example using RTFM
- Implement IndependentWatchdog for the IWDG peripheral
- Remove all PWM channel configurations except 'all the channels for default remapping' configuratons
- Remove all PWM channel configurations except 'all the channels for default remapping' configurations
- Update PWM documentation: clarify custom selection of channels
- Add PWM example for custom selection of channels

Expand Down Expand Up @@ -160,7 +164,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- First tagged version

[Unreleased]: https://github.com/stm32-rs/stm32f1xx-hal/compare/v0.5.2...HEAD
[Unreleased]: https://github.com/stm32-rs/stm32f1xx-hal/compare/v0.5.3...HEAD
[v0.5.3]: https://github.com/stm32-rs/stm32f1xx-hal/compare/v0.5.2...v0.5.3
[v0.5.2]: https://github.com/stm32-rs/stm32f1xx-hal/compare/v0.5.1...v0.5.2
[v0.5.1]: https://github.com/stm32-rs/stm32f1xx-hal/compare/v0.5.0...v0.5.1
[v0.5.0]: https://github.com/stm32-rs/stm32f1xx-hal/compare/v0.4.0...v0.5.0
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ repository = "https://github.com/stm32-rs/stm32f1xx-hal"
documentation = "https://docs.rs/stm32f1xx-hal"
readme = "README.md"
edition = "2018"
version = "0.5.1"
version = "0.5.3"

[package.metadata.docs.rs]
features = ["stm32f103", "rt", "stm32-usbd"]
default-target = "x86_64-unknown-linux-gnu"

[[example]]
name = "timer-interrupt-rtfm"
Expand Down
179 changes: 116 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,119 @@
[![crates.io](https://img.shields.io/crates/v/stm32f1xx-hal.svg)](https://crates.io/crates/stm32f1xx-hal)
[![Released API docs](https://docs.rs/stm32f1xx-hal/badge.svg)](https://docs.rs/stm32f1xx-hal)

## Usage
## Quick start guide

Embedded Rust development requires a bit more setup than ordinary development.
For this guide, we'll assume you're using a stm32 blue pill board (shown
below), but if you have another f1 microcontroller, you should be able to adapt
it.

![blue pill pinout](BluePillPinout.jpg "opt title")

You will also need a debug probe, for example an [stlink v3
mini](https://www.st.com/en/development-tools/stlink-v3mini.html) for programming and debugging.
(There are many different STLink probes out there, all of them _should_ work fine with this instructions given here, other JTAG or SWD debug probes will work as well but will need different software or configuration).

### Installing software

To program your microcontroller, you need to install:
- [openocd](http://openocd.org/)
- `arm-none-eabi-gdb`

Finally, you need to install arm target support for the Rust compiler. To do
so, run
```
rustup target install thumbv7m-none-eabi
```


### Setting up your project

Create a new Rust project as you usually do with `cargo init`. The hello world
of embedded development is usually to blink an LED and code to do so is
available in [examples/blinky.rs](examples/blinky.rs). Copy that file to the
`main.rs` of your project.

You also need to add some dependencies to your `Cargo.toml`:

```toml
[dependencies]
embedded-hal = "0.2.3"
nb = "0.1.2"
cortex-m = "0.6.2"
cortex-m-rt = "0.6.11"
# Panic behaviour, see https://crates.io/keywords/panic-impl for alternatives
panic-halt = "0.2.0"

[dependencies.stm32f1xx-hal]
version = "0.5.3"
features = ["rt", "stm32f103", "medium"]
```

If you build your project now, you should get a single error: `error: language
item required, but not found: eh_personality`. This unhelpful error message
is fixed by compiling for the right target.

We also need to tell Rust how to link our executable, and how to lay out the
result in memory. To accomplish all this, copy [.cargo/config](.cargo/config) and
[memory.x](memory.x) from the stm32f1xx-hal repo to your project.

```bash
cargo build
```

If everything went well, your project should have built without errors.


### Programming the microcontroller

It is now time to actually run the code on the hardware. To do so plug your
debug probe into the blue pill and start `openocd` using
```bash
openocd -f interface/stlink-v3.cfg -f target/stm32f1x.cfg
```
If you are not using an stlink V3, change the interface accordingly.
For more information, see the [embeddonomicon].

If all went well, it should detect your microcontroller and say `Info :
stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints`. Keep it running in
the background.

We will use gdb for uploading the compiled binary to the microcontroller and
for debugging. Cargo will automatically start `gdb` thanks to the
[.cargo/config](.cargo/config) you added earlier. `gdb` also needs to be told
to connect to openocd which is done by copying [.gdbinit](.gdbinit) to the root
of your project.

You may also need to tell `gdb` that it is safe to load `.gdbinit` from the
working directory.
- Linux
```bash
echo "set auto-load safe-path $(pwd)" >> ~/.gdbinit
```
- Windows
```batch
echo set auto-load safe-path %CD% >> %USERPROFILE%\.gdbinit
```

If everything was successful, cargo should compile your project, start gdb,
load your program and give you a prompt. If you type `continue` in the gdb
prompt, your program should start and the green led on the blue pill should
start blinking.


### Going further

From here on, you can start adding more code to your project to make it do
something more interesting. For crate documentation, see
[docs.rs/stm32f1xx-hal](https://docs.rs/stm32f1xx-hal). There are also a lot
more [examples](examples) available. If something is unclear in the docs or
examples, please, open an issue and we will try to improve it.




## Selecting a microcontroller

This crate supports multiple microcontrollers in the
stm32f1 family. Which specific microcontroller you want to build for has to be
Expand All @@ -31,7 +143,7 @@ device) but check the datasheet or CubeMX to be sure.
* `stm32f103`


### Trying out the examples
## Trying out the examples

You may need to give `cargo` permission to call `gdb` from the working directory.
- Linux
Expand Down Expand Up @@ -62,76 +174,17 @@ an stlink V2, use `stlink-v2.cfg`. For more information, see the



### Using as a Dependency
## Using as a Dependency

When using this crate as a dependency in your project, the microcontroller can
be specified as part of the `Cargo.toml` definition.

```toml
[dependencies.stm32f1xx-hal]
version = "0.5.2"
version = "0.5.3"
features = ["stm32f100", "rt"]
```

## Blinky example

The following example blinks an LED connected to pin PC13. For instructions on
how set up a project and run the example, see the [documentation]. For more
examples, see the [examples](examples) directory.

[documentation]: https://docs.rs/stm32f1xx-hal/

```rust
#![no_std]
#![no_main]

extern crate panic_halt;

use nb::block;

use stm32f1xx_hal::{
prelude::*,
pac,
timer::Timer,
};
use cortex_m_rt::entry;

#[entry]
fn main() -> ! {
// Get access to the core peripherals from the cortex-m crate
let cp = cortex_m::Peripherals::take().unwrap();
// Get access to the device specific peripherals from the peripheral access crate
let dp = pac::Peripherals::take().unwrap();

// Take ownership over the raw flash and rcc devices and convert them into the corresponding
// HAL structs
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();

// Freeze the configuration of all the clocks in the system and store
// the frozen frequencies in `clocks`
let clocks = rcc.cfgr.freeze(&mut flash.acr);

// Acquire the GPIOC peripheral
let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);

// Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function
// in order to configure the port. For pins 0-7, crl should be passed instead.
let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
// Configure the syst timer to trigger an update every second
let mut timer = Timer::syst(cp.SYST, clocks)
.start_count_down(1.hz());

// Wait for the timer to trigger an update and change the state of the LED
loop {
block!(timer.wait()).unwrap();
led.set_high().unwrap();
block!(timer.wait()).unwrap();
led.set_low().unwrap();
}
}
```

## Documentation

The documentation can be found at [docs.rs](https://docs.rs/stm32f1xx-hal/).
Expand Down
2 changes: 1 addition & 1 deletion examples/adc-dma-circ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use cortex_m_rt::entry;

#[entry]
fn main() -> ! {
// Aquire peripherals
// Acquire peripherals
let p = pac::Peripherals::take().unwrap();
let mut flash = p.FLASH.constrain();
let mut rcc = p.RCC.constrain();
Expand Down
2 changes: 1 addition & 1 deletion examples/adc-dma-rx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use cortex_m_rt::entry;

#[entry]
fn main() -> ! {
// Aquire peripherals
// Acquire peripherals
let p = pac::Peripherals::take().unwrap();
let mut flash = p.FLASH.constrain();
let mut rcc = p.RCC.constrain();
Expand Down
2 changes: 1 addition & 1 deletion examples/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use cortex_m_semihosting::hprintln;

#[entry]
fn main() -> ! {
// Aquire peripherals
// Acquire peripherals
let p = pac::Peripherals::take().unwrap();
let mut flash = p.FLASH.constrain();
let mut rcc = p.RCC.constrain();
Expand Down
2 changes: 1 addition & 1 deletion examples/adc_temperature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use cortex_m_semihosting::hprintln;

#[entry]
fn main() -> ! {
// Aquire peripherals
// Acquire peripherals
let p = pac::Peripherals::take().unwrap();
let mut flash = p.FLASH.constrain();
let mut rcc = p.RCC.constrain();
Expand Down
2 changes: 1 addition & 1 deletion examples/blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! This assumes that a LED is connected to pc13 as is the case on the blue pill board.
//!
//! Note: Without additional hardware, PC13 should not be used to drive an LED, see page 5.1.2 of
//! the reference manaual for an explanation. This is not an issue on the blue pill.
//! the reference manual for an explanation. This is not an issue on the blue pill.
#![deny(unsafe_code)]
#![no_std]
Expand Down
2 changes: 1 addition & 1 deletion examples/blinky_rtc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! This assumes that a LED is connected to pc13 as is the case on the blue pill board.
//!
//! Note: Without additional hardware, PC13 should not be used to drive a LED, see
//! section 5.1.2 of the reference manaual for an explanation.
//! section 5.1.2 of the reference manual for an explanation.
//! This is not an issue on the blue pill.
#![deny(unsafe_code)]
Expand Down
2 changes: 1 addition & 1 deletion examples/led.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//! If compiled for the stm32f100, this assumes that an active high LED is connected to pc9
//!
//! Note: Without additional hardware, PC13 should not be used to drive a LED, see
//! section 5.1.2 of the reference manaual for an explanation.
//! section 5.1.2 of the reference manual for an explanation.
//! This is not an issue on the blue pill.
#![deny(unsafe_code)]
Expand Down
21 changes: 14 additions & 7 deletions examples/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn main() -> ! {

// Set up the usart device. Taks ownership over the USART register and tx/rx pins. The rest of
// the registers are used to enable and configure the device.
let serial = Serial::usart3(
let mut serial = Serial::usart3(
p.USART3,
(tx, rx),
&mut afio.mapr,
Expand All @@ -68,22 +68,29 @@ fn main() -> ! {
&mut rcc.apb1,
);

// Split the serial struct into a receiving and a transmitting part
let (mut tx, mut rx) = serial.split();

// Loopback test. Write `X` and wait until the write is successful.
let sent = b'X';

// Write `X` and wait until the write is successful
block!(tx.write(sent)).ok();
block!(serial.write(sent)).ok();

// Read the byte that was just sent. Blocks until the read is complete
let received = block!(rx.read()).unwrap();
let received = block!(serial.read()).unwrap();

// Since we have connected tx and rx, the byte we sent should be the one we received
assert_eq!(received, sent);

// Trigger a breakpoint to allow us to inspect the values
asm::bkpt();


// You can also split the serial struct into a receiving and a transmitting part
let (mut tx, mut rx) = serial.split();
let sent = b'Y';
block!(tx.write(sent)).ok();
let received = block!(rx.read()).unwrap();
assert_eq!(received, sent);
asm::bkpt();


loop {}
}
2 changes: 1 addition & 1 deletion examples/timer-interrupt-rtfm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! This assumes that a LED is connected to pc13 as is the case on the blue pill board.
//!
//! Note: Without additional hardware, PC13 should not be used to drive an LED, see page 5.1.2 of
//! the reference manaual for an explanation. This is not an issue on the blue pill.
//! the reference manual for an explanation. This is not an issue on the blue pill.
#![no_std]
#![no_main]
Expand Down
2 changes: 1 addition & 1 deletion src/backup_domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::pac::BKP;

/**
The existence of this struct indicates that writing to the the backup
domain has been enabled. It is aquired by calling `constrain` on `rcc::Rcc::BKP`
domain has been enabled. It is acquired by calling `constrain` on `rcc::Rcc::BKP`
*/
pub struct BackupDomain {
pub(crate) _regs: BKP,
Expand Down
Loading

0 comments on commit 0a555c9

Please sign in to comment.