Skip to content

Commit 400d350

Browse files
author
Jorge Aparicio
committed
move documentation to src/lib.rs
1 parent 5c9441b commit 400d350

File tree

2 files changed

+245
-213
lines changed

2 files changed

+245
-213
lines changed

README.md

Lines changed: 2 additions & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -5,219 +5,9 @@
55

66
> Generate Rust register maps (`struct`s) from SVD files
77
8-
## Usage
8+
# [Documentation](https://docs.rs/svd2rust)
99

10-
- Get the start address of each peripheral register block.
11-
12-
```
13-
$ svd2rust -i STM32F30x.svd
14-
const GPIOA: usize = 0x48000000;
15-
const GPIOB: usize = 0x48000400;
16-
const GPIOC: usize = 0x48000800;
17-
const GPIOD: usize = 0x48000c00;
18-
const GPIOE: usize = 0x48001000;
19-
const GPIOF: usize = 0x48001400;
20-
(..)
21-
```
22-
23-
- Generate a register map for a single peripheral.
24-
25-
```
26-
$ svd2rust -i STM32F30x.svd rcc | head
27-
#[repr(C)]
28-
/// Reset and clock control
29-
pub struct Rcc {
30-
/// Clock control register
31-
pub cr: Cr,
32-
/// Clock configuration register (RCC_CFGR)
33-
pub cfgr: Cfgr,
34-
/// Clock interrupt register (RCC_CIR)
35-
pub cir: Cir,
36-
/// APB2 peripheral reset register (RCC_APB2RSTR)
37-
(..)
38-
```
39-
40-
## API
41-
42-
The `svd2rust` generates the following API for each peripheral:
43-
44-
### Register block
45-
46-
A register block "definition" as a `struct`. Example below:
47-
48-
``` rust
49-
/// Inter-integrated circuit
50-
#[repr(C)]
51-
pub struct I2c1 {
52-
/// 0x00 - Control register 1
53-
pub cr1: Cr1,
54-
/// 0x04 - Control register 2
55-
pub cr2: Cr2,
56-
/// 0x08 - Own address register 1
57-
pub oar1: Oar1,
58-
/// 0x0c - Own address register 2
59-
pub oar2: Oar2,
60-
/// 0x10 - Timing register
61-
pub timingr: Timingr,
62-
/// 0x14 - Status register 1
63-
pub timeoutr: Timeoutr,
64-
/// 0x18 - Interrupt and Status register
65-
pub isr: Isr,
66-
/// 0x1c - Interrupt clear register
67-
pub icr: Icr,
68-
/// 0x20 - PEC register
69-
pub pecr: Pecr,
70-
/// 0x24 - Receive data register
71-
pub rxdr: Rxdr,
72-
/// 0x28 - Transmit data register
73-
pub txdr: Txdr,
74-
}
75-
```
76-
77-
The user has to "instantiate" this definition for each peripheral instance. They have several
78-
choices:
79-
80-
- `static`s and/or `static mut`s. Example below:
81-
82-
``` rust
83-
extern "C" {
84-
// I2C1 can be accessed in read-write mode
85-
pub static mut I2C1: I2c;
86-
// whereas I2C2 can only be accessed in "read-only" mode
87-
pub static I2C1: I2c;
88-
}
89-
```
90-
91-
Where the addresses of these register blocks must be provided by a linker script:
92-
93-
``` ld
94-
/* layout.ld */
95-
I2C1 = 0x40005400;
96-
I2C2 = 0x40005800;
97-
```
98-
99-
This has the side effect that the `I2C1` and `I2C2` symbols get "taken" so no other C/Rust symbol
100-
(`static`, `function`, etc.) can have the same name.
101-
102-
- "constructor" functions. Example, equivalent to the `static` one, below:
103-
104-
``` rust
105-
// Addresses of the register blocks. These are private.
106-
const I2C1: usize = 0x40005400;
107-
const I2C2: usize = 0x40005800;
108-
109-
// NOTE(unsafe) can alias references to mutable memory
110-
pub unsafe fn i2c1() -> &'mut static I2C {
111-
unsafe { &mut *(I2C1 as *mut I2c) }
112-
}
113-
114-
pub fn i2c2() -> &'static I2C {
115-
unsafe { &*(I2C2 as *const I2c) }
116-
}
117-
```
118-
119-
### `read` / `modify` / `write`
120-
121-
Each register in the register block, e.g. the `cr1` field in the `I2c` struct, exposes a combination
122-
of the `read`, `modify` and `write` methods. Which methods exposes each register depends on whether
123-
the register is read-only, read-write or write-only:
124-
125-
- read-only registers only expose the `read` method.
126-
- write-only registers only expose the `write` method.
127-
- read-write registers exposes all the methods: `read`, `modify` and `write`.
128-
129-
This is signature of each of these methods:
130-
131-
(using the `CR2` register as an example)
132-
133-
``` rust
134-
impl Cr2 {
135-
pub fn modify<F>(&mut self, f: F)
136-
where for<'w> F: FnOnce(&Cr2R, &'w mut Cr2W) -> &'w mut Cr2W
137-
{
138-
..
139-
}
140-
141-
pub fn read(&self) -> Cr2R { .. }
142-
143-
pub fn write<F>(&mut self, f: F)
144-
where F: FnOnce(&mut Cr2W) -> &mut Cr2W,
145-
{
146-
..
147-
}
148-
}
149-
```
150-
151-
The `read` method performs a single, volatile `LDR` instruction and returns a proxy `Cr2R` struct
152-
which allows access to only the readable bits (i.e. not to the reserved bits) of the `CR2` register:
153-
154-
``` rust
155-
impl Cr2R {
156-
/// Bit 0 - Slave address bit 0 (master mode)
157-
pub fn sadd0(&self) -> bool { .. }
158-
159-
/// Bits 1:7 - Slave address bit 7:1 (master mode)
160-
pub fn sadd1(&self) -> u8 { .. }
161-
162-
(..)
163-
}
164-
```
165-
166-
Usage looks like this:
167-
168-
``` rust
169-
// is the SADD0 bit of the CR2 register set?
170-
if i2c1.c2r.read().sadd0() {
171-
// something
172-
} else {
173-
// something else
174-
}
175-
```
176-
177-
The `write` method performs a single, volatile `STR` instruction to write a value to the `CR2`
178-
register. This method involves the `Cr2W` struct which only allows constructing valid states of the
179-
`CR2` register.
180-
181-
The only constructor that `Cr2W` provides is `reset_value` which returns the value of the `CR2`
182-
register after a reset. The rest of `Cr2W` methods are "builder" like and can be used to set or
183-
reset the writable bits of the `CR2` register.
184-
185-
``` rust
186-
impl Cr2W {
187-
/// Reset value
188-
pub fn reset_value() -> Self {
189-
Cr2W { bits: 0 }
190-
}
191-
192-
/// Bits 1:7 - Slave address bit 7:1 (master mode)
193-
pub fn sadd1(&mut self, value: u8) -> &mut Self { .. }
194-
195-
/// Bit 0 - Slave address bit 0 (master mode)
196-
pub fn sadd0(&mut self, value: bool) -> &mut Self { .. }
197-
}
198-
```
199-
200-
The `write` method takes a closure with signature `&mut Cr2W -> &mut Cr2W`. If passed the identity
201-
closure, `|w| w`, the `write` method will set the `CR2` register to its reset value. Otherwise, the
202-
closure specifies how that reset value will be modified before it's written to `CR2`.
203-
204-
Usage looks like this:
205-
206-
``` rust
207-
// Write to CR2, its reset value but with its SADD0 and SADD1 fields set to `true` and `0b0011110`
208-
i2c1.cr2.write(|w| w.sadd0(true).sadd1(0b0011110));
209-
```
210-
211-
Finally, the `modify` method performs a read-modify-write operation that involves at least one `LDR`
212-
instruction, one `STR` instruction plus extra instructions to modify the fetched value of the `CR2`
213-
register. This method accepts a closure that specifies how the `CR2` register will be modified.
214-
215-
Usage looks like this:
216-
217-
``` rust
218-
// Toggle the STOP bit of the CR2 register and set the START bit
219-
i2c1.cr2.modify(|r, w| w.stop(!r.stop()).start(true));
220-
```
10+
# [API](https://docs.rs/svd2rust)
22111

22212
## License
22313

0 commit comments

Comments
 (0)