Hi, I'm trying to learn Rust and use it for embedded work.
I want to write a function which will take several generic parameters.
I have two problems:
compiler won't allow me to add something to the parameter, eg:
let e = end + 1; will report:
expected type parameter, found integral variable
= note: expected type U
found type {integer}
Mixing enums with the problem mention above:
write(reg, Register1Bits::DIVs, Register1Bits::DIVe, 0xBABA);
write(reg, Register2Bits::Rs, Register2Bits::Re, 0xBABA);
Now compiler will report:
no implementation for Register1Bits + Register1Bits
no implementation for Register2Bits + Register2Bits
So I need to (somehow) implement std::ops::Add for every enum I have.
What I'm trying to achive is this:
I have a struct for multiple HW memory mapped registers.
I have bits which are in that register in enums (which are called similiar to register, so there is bunch of these enums).
I want to create function which can write to all this registers (and will take enums as parameter, because it need to know where bit positions are)
How to achive that?
BTW, "+1" in code above is because (AFAIK):
Rust won't allow enums members with same value (eg: Bit1End = 8, Bit2Stard = 8)
Range will not include the last number (eg: 0..8 will not include '8')
(there is '...' but it's experimental)
I'm trying to write drivers for peripheral devices on bare metal MCU. For example, GPIO driver should look something like this:
But I don't know how to manage problems with gpio_write()
Also, is it possible to have read only bits? Something similar already exist, but for bytes or larger types (VolatileCell,, RW, RO, WO).
How can I tell compiler to generate error when someone try to do something like this:
gpio_write(gpioA.Reg2, Reg1::MODE, 0b11); // trying to write enum for Reg1 to Reg2
The type T should be "a backing storage type" for this register, eg. u32 or u16.
(If you assume that all registers are 32 bits, you don't even need that T. But I guess some registers are 16 bits wide?)
Implement this on all your register types, and you can define your gpio_write as:
fn gpio_write<U: Register>(mut reg: RW<U::T>, mask: U, value: U)
{
// this function should be able to write to any Gpio register (Reg1, Reg2, ...)
let read = reg.read();
let new = read & (value.to_bits() & mask.to_bits());
reg.write(new);
}
This will error when using mask and value with different types.
Rust doesn't really understand bits, but one solution I see is to have additional method on Register trait – write_mask, and then write_gpio can mask every write with that mask.
Also, I feel that a library that does the things you ask for already exists. There is a big thread about embedded development, you can try to find some links there or post some suggestions.