diff options
Diffstat (limited to 'CHANGELOG.md')
| -rw-r--r-- | CHANGELOG.md | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index b5be6d3..b5a4a1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,134 @@ ## [Unreleased] +**BREAKING** The `reset_reg!` macro is removed. It may be added later. + +**BREAKING** The API uses raw pointers to access registers, avoiding +references. To support this goal, the package has new read, write, and modify +macros. The macros expect a different definition for register blocks and +registers. + +Here's a small example demonstrating the new definition of register blocks, +registers, and fields. It also demonstrates the macro syntax. + +```rust +// +// Peripheral definition. +// +#![allow(non_snake_case)] + +pub mod pit { + #[repr(C)] + pub struct RegisterBlock { + pub MCR: u32, + pub LTMR: [u32; 2], + _reserved_0: [u8; 16], + pub CHANNEL: [CHANNEL::RegisterBlock; 4], + } + + ral_registers::register!(pub MCR<u32> RW [ + FRZ start(0) width(1) RW {} + MDIS start(1) width(1) RW { + DISABLE = 1, + ENABLE = 0, + } + ]); + + ral_registers::register!(pub LTMR<u32> RO []); + + pub mod CHANNEL { + #[repr(C)] + pub struct RegisterBlock { + pub LDVAL: u32, + pub CVAL: u32, + pub TCTRL: u32, + pub TFLG: u32, + } + + ral_registers::register!(pub LDVAL RW []); + ral_registers::register!(pub CVAL RO []); + + ral_registers::register!(pub TCTRL<u32> RW [ + TEN start(0) width(1) RW { + DISABLE = 0, + ENABLE = 1, + } + TIE start(1) width(1) RW {} + CHN start(2) width(1) RW {} + ]); + ral_registers::register!(pub TFLG<u32> RW [ + TIF start(0) width(1) RW {} + ]); + } +} + +// +// Peripheral usage. +// +use ral_registers as ral; + +// pit1() expanded from ral::instances! shown later +let pit1 = unsafe { instances::pit1() }; +ral::modify_reg!(pit, pit1, MCR, MDIS: ENABLE); +ral::modify_reg!(pit, pit1, CHANNEL[2].TCTRL, TEN: ENABLE); +loop { + while ral::read_reg!(pit, pit1, CHANNEL[2].TFLG, TIF == 0) {} + ral::write_reg!(pit, pit1, CHANNEL[2].TFLG, TIF: 1); +} + +// +// NEW: instance definitions. +// +mod instances { + ral::instances! { + unsafe { + pit1<pit::RegisterBlock> = 0x4008_4000; + pit2<pit::RegisterBlock> = 0x400C_4000; + + // Expansion: + // pub const unsafe fn pit1() -> ral::Instance<pit::RegisterBlock> { /* ... */ } + // pub const unsafe fn pit2() -> ral::Instance<pit::RegisterBlock> { /* ... */ } + } + } +} +``` + +A `RegisterBlock` only describes a layout using unsigned or signed primitives. +There are no more `RWRegister`, `RORegister`, or `WORegister` types to convey +access. Instead, each register module describes its access. The approach allows +a single register block layout to be shared for different use cases, cases that +may vary the access for a given register. + +The `register!` macros provides a convenient way to define fields and field +enums. The macro is optional; the expanded code is specified and stable. Codegen +tools can directly generate compatible modules without using `register!`. + +Despite the new register block and register definitions, the read, write, and +modify macros support the same syntax as 0.1. Specifically, + +```rust +ral::modify_reg!(pit, pit1, MCR, MDIS: ENABLE); +``` + +is unchanged from the 0.1 macros. The remaining usages like + +```rust +ral::modify_reg!(pit, pit1, CHANNEL[2].TCTRL, TEN: ENABLE); +``` + +is newly supported. All macros expand through an arbitrary depth of array +offset and block members from the top-level instance. + +For compatibility with the macros, the instance type must implement the +unsafe `ral_registers::Inst` trait. The type must implement an +`fn as_ptr() -> *mut RegisterBlock` method. For convenience, the package +provides an opinionated `Instance` type. + +Finally, the package exports an `instances!` macro that lets users declare +the base address of register blocks. Each name-address pair expands to a +`const unsafe fn` that produces an `Instance` object. The `const fn` permits +C-style usage when inlined directly into the macro. + ## [v0.1.3] - 2023-06-18 * Allow trailing commas inside macros (#7) |
