1
1
# Tock Register Interface
2
2
3
- This crate provides an interface for defining and manipulating memory mapped
4
- registers and bitfields.
3
+ This crate provides an interface and types for defining and
4
+ manipulating registers and bitfields.
5
5
6
6
## Defining registers
7
7
8
8
The crate provides three types for working with memory mapped registers:
9
9
` ReadWrite ` , ` ReadOnly ` , and ` WriteOnly ` , providing read-write, read-only, and
10
- write-only functionality, respectively.
10
+ write-only functionality, respectively. These types implement the ` Readable ` ,
11
+ ` Writeable ` and ` ReadWriteable ` traits.
11
12
12
13
Defining the registers is done with the ` register_structs ` macro, which expects
13
14
for each register an offset, a field name, and a type. Registers must be
@@ -198,10 +199,12 @@ register_bitfields! [
198
199
## Register Interface Summary
199
200
200
201
There are four types provided by the register interface: ` ReadOnly ` ,
201
- ` WriteOnly ` , ` ReadWrite ` , and ` Aliased ` . They provide the following functions:
202
+ ` WriteOnly ` , ` ReadWrite ` , and ` Aliased ` . They expose the following
203
+ methods, through the implementations of the ` Readable ` , ` Writeable `
204
+ and ` ReadWriteable ` traits respectively:
202
205
203
206
``` rust
204
- ReadOnly <T : IntLike , R : RegisterLongName = ()>
207
+ ReadOnly <T : IntLike , R : RegisterLongName = ()>: Readable
205
208
. get () -> T // Get the raw register value
206
209
. read (field : Field <T , R >) -> T // Read the value of the given field
207
210
. read_as_enum<E >(field : Field <T , R >) -> Option <E > // Read value of the given field as a enum member
@@ -210,11 +213,11 @@ ReadOnly<T: IntLike, R: RegisterLongName = ()>
210
213
. matches_all (value : FieldValue <T , R >) -> bool // Check if all specified parts of a field match
211
214
. extract () -> LocalRegisterCopy <T , R > // Make local copy of register
212
215
213
- WriteOnly <T : IntLike , R : RegisterLongName = ()>
216
+ WriteOnly <T : IntLike , R : RegisterLongName = ()>: Writeable
214
217
. set (value : T ) // Set the raw register value
215
218
. write (value : FieldValue <T , R >) // Write the value of one or more fields,
216
219
// overwriting other fields to zero
217
- ReadWrite <T : IntLike , R : RegisterLongName = ()>
220
+ ReadWrite <T : IntLike , R : RegisterLongName = ()>: Readable + Writeable + ReadWriteable
218
221
. get () -> T // Get the raw register value
219
222
. set (value : T ) // Set the raw register value
220
223
. read (field : Field <T , R >) -> T // Read the value of the given field
@@ -231,7 +234,7 @@ ReadWrite<T: IntLike, R: RegisterLongName = ()>
231
234
. matches_all (value : FieldValue <T , R >) -> bool // Check if all specified parts of a field match
232
235
. extract () -> LocalRegisterCopy <T , R > // Make local copy of register
233
236
234
- Aliased <T : IntLike , R : RegisterLongName = (), W : RegisterLongName = ()>
237
+ Aliased <T : IntLike , R : RegisterLongName = (), W : RegisterLongName = ()>: Readable + Writeable
235
238
. get () -> T // Get the raw register value
236
239
. set (value : T ) // Set the raw register value
237
240
. read (field : Field <T , R >) -> T // Read the value of the given field
@@ -453,3 +456,14 @@ register_bitfields! [
453
456
]
454
457
]
455
458
```
459
+
460
+ ## Implementing custom register types
461
+
462
+ The ` Readable ` , ` Writeable ` and ` ReadWriteable ` traits make it
463
+ possible to implement custom register types, even outside of this
464
+ crate. A particularly useful application area for this are CPU
465
+ registers, such as ARM SPSRs or RISC-V CSRs. It is sufficient to
466
+ implement the ` Readable::get ` and ` Writeable::set ` methods for the
467
+ rest of the API to be automatically implemented by the crate-provided
468
+ traits. For more in-depth documentation on how this works, refer to
469
+ the ` interfaces ` module documentation.
0 commit comments