Skip to content

Improve ergonomics of boolean fields with enumeration #24

@andreasWallnerIFX

Description

@andreasWallnerIFX

In the current API we don't have a simple to write a bool to a field if that field has an enumeration. Compared to numeric fields where we have a conversion via into() we need to manually match here:

For my tests is added an enumeration to the boolrw() bitfield in our simple.xml:

diff --git a/test_svd/simple.xml b/test_svd/simple.xml
index 707c442..6a53a83 100644
--- a/test_svd/simple.xml
+++ b/test_svd/simple.xml
@@ -112,6 +112,18 @@
                                                        <description>Boolean bitfield Read Write</description>
                                                        <bitRange>[2:2]</bitRange>
                                                        <access>read-write</access>
+                                                       <enumeratedValues>
+                                                                  <name>SomeBoolean</name>
+                                                                  <usage>read-write</usage>
+                                                                  <enumeratedValue>
+                                                                          <name>disabled</name>
+                                                                          <value>0</value>
+                                                                  </enumeratedValue>
+                                                                  <enumeratedValue>
+                                                                          <name>enabled</name>
+                                                                          <value>1</value>
+                                                                  </enumeratedValue>
+                                                       </enumeratedValues>
                                                </field>
                                                <field>
                                                        <name>BitfieldR</name>

For enumerated numeric fields we can do:

TIMER.bitfield_reg().modify(|r| r.bitfieldenumerated().set(0.into()));

whereas for a boolean field (with the enumeration) these don't work:

// fails since we use RegValue for the field
TIMER.bitfield_reg().modify(|r| r.boolrw().set(true))); 
// fails since there is no bool -> EnumBitfieldStruct conversion
TIMER.bitfield_reg().modify(|r| r.boolrw().set(true.into()));

The currently working workarounds are:

// the explicit match
    let xx = match x {
        true => timer::bitfield_reg::BoolRw::SOME_BOOLEAN_ENABLED,
        false => timer::bitfield_reg::BoolRw::SOME_BOOLEAN_DISABLED,
    };
// comparing against the enums if we don't want to presume to values of the enums
    let xx = if x == (timer::bitfield_reg::BoolRw::SOME_BOOLEAN_ENABLED.0 == 1) {
        timer::bitfield_reg::BoolRw::SOME_BOOLEAN_ENABLED
    } else {
        timer::bitfield_reg::BoolRw::SOME_BOOLEAN_DISABLED
    };
// cast to ux and use `.into()`
    TIMER.bitfield_reg().modify(|r| r.boolrw().set((x as u8).into()));

Us using RegValue here has the side-effect that this:

TIMER.bitfield_reg().modify(|r| r.boolrw().set(0xffu8.into()));

compiles. Doesn't cause much harm though since the mask is applied before it's written to the RegisterValue. It's just a bit weird that we allow this.

Describe the solution you'd like

A matching usage between enumerated and non-enumerated fields.

Describe alternatives you've considered

  • Add a RegisterFieldEnumBool to use instead of RegisterField (I don't see a nice way to extend RegisterFieldBool to handle enums as well atm)
  • Add a BooleanEnumBitfieldStruct to use instead of EnumBitfieldStruct that implements From<bool>
  • Generate an impl like impl From<bool> for BoolRw {...} for every boolean bitfield with enumerations - seems hacky and leads to quite a bit more code in our case
  • impl RegNumberT for bool - doesn't work since bool does e.g. not implement Shr and might need some additional bounds across the code
  • Keep as is - considering that for numeric fields .into() works it should work for boolean fields as well for consistency and "least surprise"

I'd favour the first option, but posting here for discussion and possible additional ideas.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions