]> code.bitgloo.com Git - clyne/funreg.git/commitdiff
update documentation 1/head
authorClyne Sullivan <clyne@bitgloo.com>
Wed, 10 Aug 2022 02:06:06 +0000 (22:06 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Wed, 10 Aug 2022 02:06:06 +0000 (22:06 -0400)
GUIDE.md
README.md

index 6d3b702ca46a71cd0528a6a36b303299b3cf0b3e..80abfb6bdcab81a7acb729651d1a11d74abe6b74 100644 (file)
--- a/GUIDE.md
+++ b/GUIDE.md
@@ -10,12 +10,12 @@ For an 8-bit register at memory address `0x0021`, you would write:
 using PORTA_OUT = fr::MemRegister<uint8_t, 0x0021>;
 ```
 
-`fr::MemRegister` is an `fr::Register` that uses `MemoryIO` access. Registers
+`MemRegister` is an `Register` that uses `MemoryIO` access. Registers
 have static functions for interacting with their contents; for example, we
 could now do `PORTA_OUT::write(0x10)` or `auto state = PORTA::read()`.
 
 A lot more can be done with registers once we define some register masks. A
-`fr::RegisterMask` lets us name one or more bits within a register.
+`RegisterMask` lets us name one or more bits within a register.
 
 To name our two LEDs, which are only controlled by single bits, we write:
 
@@ -40,15 +40,16 @@ These calls can also be made through the register using template parameters:
 PORTA_OUT::set<LED_2>();
 ```
 
-Registers can take multiple masks at once:
+Registers can take multiple masks at once too. The masks will be merged so that
+the register is only read and written once:
 
 ```cpp
 PORTA_OUT::toggle<LED_1, LED_2>();
 ```
 
-They also support a `modify` function, which takes a list of mask operations as
-shown below. Through `modify`, the register is only read and written once,
-minimizing I/O.
+A `modify` function is also supported, which takes a list of mask operations as
+shown below. This allows the different operations to be carried out together,
+still keeping to a single register read and write:
 
 ```cpp
 PORTA_OUT::modify<LED_1::set, LED_2::clear>(); // Only have LED_1 turned on
@@ -57,7 +58,7 @@ PORTA_OUT::modify<LED_1::set, LED_2::clear>(); // Only have LED_1 turned on
 What if we need to add a third LED? And what if that LED is on a different
 register, PORTB?
 
-This is what you could do:
+This is where `RegisterGroup` comes in handy:
 
 ```cpp
 using PORTB_OUT = fr::MemRegister<uint8_t, 0x0041>;
@@ -68,10 +69,9 @@ using LED_3 = fr::RegisterMask<PORTB_OUT, (1 << 5)>;
 using LEDS = fr::RegisterGroup<PORTA_OUT, PORTB_OUT>;
 ```
 
-By defining a `RegisterGroup`, we can make the same calls to modify the LEDs as
-we would with the single register. `RegisterGroup` will direct masks to their
-appropriate registers, while merging operations on the same register to
-maintain that minimal I/O:
+By grouping the two registers, we can carry out our modification calls without
+worrying about which mask is for what register. The `RegisterGroup` will take
+of that, while still merging operations when possible to maintain minimal I/O:
 
 ```cpp
 LEDS::clear<LED_1, LED_2, LED_3>();
@@ -98,8 +98,8 @@ CLOCK_DIV::write<0x03>();
 ```
 
 This will read the register's current value, clear all bits selected by the
-mask, bitwise-OR the value `0x03` to the mask's location, then write the new
-value to the register.
+mask, set the new value `0x03` in the mask's location, then update the
+register.
 
 `write` can also be included in `modify` chains:
 
@@ -107,13 +107,13 @@ value to the register.
 CLOCK_CONTROL::modify<CLOCK_DIV::write<0x03>, CLOCK_ENABLE::set>();
 ```
 
-You may also define a `RegisterMaskValue` to name a specific value:
+A `RegisterMaskValue` can also be defined to identify specific values:
 
 ```cpp
 using CLOCK_DIV4 = fr::RegisterMaskValue<CLOCK_DIV, 0x03>;
 ```
 
-Three functions are supported for `RegisterMaskValue`: `set`, which would call
+`RegisterMaskValue` supports three functions: `set`, which would call
 `CLOCK_DIV::write<0x03>()`; `clear`, which clears the masked bits; and `test`,
 which would confirm that the register contains the value `0x03` in the masked
 bits' location.
@@ -122,7 +122,7 @@ bits' location.
 
 "External" registers are registers that are not memory-mapped. These are also
 supported in *funreg*, and can even be placed in `RegisterGroup`s with
-memory-mapped or other register types.
+other register types.
 
 An "access type" must be defined to specify how the register is accessed. Here
 is the definition of `MemoryIO`, which is used for memory-mapped registers:
index c46b2957c2d56d8831c0c0331a95b035fd1b3e20..7ca829c3b009cf3f6fbbb87a560b06a1b6efff41 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,16 +1,34 @@
-# funreg: Functional Memory-mapped Register I/O
+# funreg: Functional Register I/O using modern C++
 
-*funreg* provides a functional approach to operating on memory-mapped registers
-with zero overhead. This library primarily targets embedded firmware, where
-these types of operations are frequently encountered.
+*funreg* provides a functional approach to interacting with registers.
+The library includes support for memory-mapped registers; however, other types
+of registers can be supported through creating a simple access interface.
 
-What makes this library unique is its ability to carry out multiple register
-operations with a single function call, reducing this to a single register read
-and write. Further, registers can be organized into "groups": these groups can
-receive a list of operations for any of the contained registers, and will
-optimize down to a single read and write for each register.
+A unique feature of this library is its ability to handle multiple register
+operations with a single function call; these operations will be merged
+together so that the register is only read and written once.
 
-A tutorial or guide will be added soon.
+Registers may also be organized into groups. These groups can similarly receive
+a list of operations, which will be directed the to the appropriate registers
+for the same single-read-single-write process.
+
+For example, LEDs can be controlled by a microcontroller with a single call:
+
+```cpp
+LEDS::modify<LED1::set, LED2::clear, LED3::set>();
+```
+
+...no matter if the LEDs use different registers, or if any of them are
+controlled by an external circuit rather than a built-in IO peripheral.
+
+See `GUIDE.md` for a walk-through of the available functionality.
+
+## Feature overview
+
+* Define registers of any size, at any address, with optional custom access interface
+* Define register masks to name the bits of registers
+* Define register groups so ease programming (e.g. define an `RTC` group to work with all real-time clock registers at once)
+* Make modifications through groups, masks, or the registers directly
 
 ## Requirements