Skip to content

Write support for the Backup Data Register (BKP_DR, DR1, DR2, ...) #83

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

Closed
mjepronk opened this issue Jul 15, 2019 · 14 comments
Closed

Write support for the Backup Data Register (BKP_DR, DR1, DR2, ...) #83

mjepronk opened this issue Jul 15, 2019 · 14 comments

Comments

@mjepronk
Copy link
Contributor

Currently, we can read from the Backup Data Register (for example DR1) using:

let device = pac::Peripherals::take().unwrap();
let _ = device.BKP.dr1.read().bits();

However, this will not be possible after calling rcc.bkp.constrain, because this function takes ownership of device.BKP:

let mut pwr = device.PWR;
let mut backup_domain = rcc.bkp.constrain(device.BKP, &mut rcc.apb1, &mut pwr);
let _ = device.BKP.dr1.read().bits(); // ERROR: borrow of moved value: `device.BKP`

Writing to the BKP_DR register should normally be only possible after enabling the power and backup interface clocks and setting the DBP bit the Power Control Register (page 81 of the RM0008 reference manual), i.e. calling rcc.bkp.constrain.
I'm not really sure how to fix this. I'm not familiar with svd2rust or any lower level code. I'm willing to help but I would for sure need some pointers...

@therealprof
Copy link
Member

therealprof commented Jul 15, 2019

@mjepronk To enable access to specific registers you might want to add methods to https://github.com/stm32-rs/stm32f1xx-hal/blob/master/src/backup_domain.rs.

@mjepronk
Copy link
Contributor Author

Any ideas on how that should look like? Something like:

let mut backup_domain = rcc.bkp.constrain(device.BKP, &mut rcc.apb1, &mut pwr);
let _ = backup_domain.dr1.read().bits();
backup_domain.dr1.write(|w| w.bits(42));

Or more something higher level? According to RM0008 there are 42 16-bit registers, so with the simple design we would add 42 methods to the BackupDomain struct, which might be a bit too much?

@TheZoq2
Copy link
Member

TheZoq2 commented Jul 15, 2019

I think I would prefer something more high level, perhaps set_reg(id: u8, value: u16) and a similar get_reg function.

@therealprof
Copy link
Member

I agree with @TheZoq2 either a function to set this block of registers with a function taking an index or potentially we could also think about an accessor yielding access to the whole block of data registers.

@TheZoq2
Copy link
Member

TheZoq2 commented Jul 15, 2019

I think giving the whole block of data registers might be difficult as we can't give out access to RTCCR, CR and CSR without breaking other abstractions

@therealprof
Copy link
Member

@TheZoq2 No, I just meant the data registers.

@burrbull
Copy link
Member

burrbull commented Jul 15, 2019

I've collected backup data registers into 2 arrays.
https://docs.rs/stm32f1/0.7.1/stm32f1/stm32f103/bkp/index.html

But they really are not arrays, because numbering starts from 1 and from 11.
Should I modify svdpatch to start numbering from 0 and make them real arrays?

@burrbull
Copy link
Member

With
stm32-rs/stm32-rs#256

BKP will be:

    pub struct RegisterBlock {
        #[doc = "0x00 - Backup data register (BKP_DR)"]
        pub dr: [DR; 10],
        #[doc = "0x28 - RTC clock calibration register (BKP_RTCCR)"]
        pub rtccr: RTCCR,
        #[doc = "0x2c - Backup control register (BKP_CR)"]
        pub cr: CR,
        #[doc = "0x30 - BKP_CSR control/status register (BKP_CSR)"]
        pub csr: CSR,
        _reserved0: [u8; 8usize],
        #[doc = "0x3c - Backup data register (BKP_DR)"]
        pub bkp_dr: [BKP_DR; 32],
    }

@mjepronk
Copy link
Contributor Author

OK, I've updated the PR again. I've checked-out your 'bkp' branch of the stm32-rs crate and rebuild everything. Now the dr1 register works. But the bkp_dr registers still don't work. Reading them always gives back 0 (see the code I use for testing above).

@burrbull
Copy link
Member

burrbull commented Jul 16, 2019

It's strange. Code looks good (except you should assert or debug_assert!(buf.len()+start < 42).

@burrbull
Copy link
Member

But the bkp_dr registers still don't work. Reading them always gives back 0

Not all chips support second region. f100xx does not. Maybe yours same? I'm not sure where to see this.

@mjepronk
Copy link
Contributor Author

I'll add the debug_assert!.

You're right, from RM0008:

20-byte data registers (in medium-density and low-density devices) or 84-byte data
registers (in high-density, XL-density and connectivity line devices)

I have a blue/black pill (STM32F103C8T6), so mine has only the first 10 2-byte data registers... Should we handle this in the library? (i.e. error when using >DR10 on low- or medium-density devices)

@burrbull
Copy link
Member

burrbull commented Jul 16, 2019

Maybe it makes sense to split read/write fns. And add density features to toml.

mjepronk added a commit to mjepronk/stm32f1xx-hal that referenced this issue Jul 29, 2019
mjepronk added a commit to mjepronk/stm32f1xx-hal that referenced this issue Jul 29, 2019
mjepronk added a commit to mjepronk/stm32f1xx-hal that referenced this issue Jul 29, 2019
@TheZoq2 TheZoq2 mentioned this issue Jul 31, 2019
mjepronk added a commit to mjepronk/stm32f1xx-hal that referenced this issue Aug 6, 2019
TheZoq2 pushed a commit that referenced this issue Aug 9, 2019
* Adds support for reading and writing to the Backup Data Register (#83).

* Removed `unsafe` blocks.

* Added feature gate for high backup registers.
@mjepronk
Copy link
Contributor Author

mjepronk commented Aug 9, 2019

This is merged, thank you @therealprof, @TheZoq2, @burrbull!

@mjepronk mjepronk closed this as completed Aug 9, 2019
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

4 participants