Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register Write Limitation #859

Open
AdinAck opened this issue Aug 26, 2024 · 3 comments
Open

Register Write Limitation #859

AdinAck opened this issue Aug 26, 2024 · 3 comments

Comments

@AdinAck
Copy link

AdinAck commented Aug 26, 2024

Moved from stm32-rs-nightlies

I ran into an issue when writing to a register where I wanted to return a value from the write, like this:

let val = reg.write(|w| {
    T::set(w.field())
});

But, the signature of write forbids this:

pub fn write<F, T>(&self, f: F)
    where
        F: FnOnce(&mut REG::Writer) -> &mut W<REG>,

So I'm curious, why not change the signature to:

pub fn write<F, T>(&self, f: F) -> T
    where
        F: FnOnce(&mut REG::Writer) -> T

By implementing it like this:

pub fn write<F, T>(&self, f: F) -> T
where
    F: FnOnce(&mut W<REG>) -> T,
{
    let mut writer = W {
        bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
            | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
        _reg: marker::PhantomData,
    };
    let result = f(&mut writer);

    self.register.set(writer.bits);

    result
}

Is there a drawback to this?

@burrbull
Copy link
Member

#738 (comment)

@AdinAck
Copy link
Author

AdinAck commented Aug 26, 2024

I don't believe my proposal is related to that. I don't want to return the writer, in fact, the proposed body of write forbids T ever being W or &mut W since bits is moved out of the writer for register.set, no?

@AdinAck
Copy link
Author

AdinAck commented Aug 26, 2024

Ok yes I believe I set up an analogous setup in rust playground:

#[derive(Debug)]
struct Bits(u32);

#[derive(Debug)]
struct W {
    bits: Bits,
    _reg: (),
}

fn consume_bits(Bits(num): Bits) {
    println!("bits: {}", num);
}

fn write<F, T>(f: F) -> T
where
    F: FnOnce(&mut W) -> T,
{
    let mut writer = W { bits: Bits(0), _reg: () };
    
    let result = f(&mut writer);
    
    consume_bits(writer.bits);
    
    result
}

fn main() {
    let outside = write(|_w| 0xaa);
    // let outside = write(|w| w); <- does not compile
    println!("outisde: {:?}", outside);
}

So I don't believe this introduces any complications as mentioned in #738.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants