rust-embedded / svd2rust

Generate Rust register maps (`struct`s) from SVD files
Apache License 2.0
675 stars 147 forks source link

Implement disjoint array #748

Closed kossnikita closed 8 months ago

kossnikita commented 9 months ago

660

Is it possible to add an unsafe method that returns a register from an array? For compatibility with similar syntax for continuous arrays.

In my case the registers are separated due to their size. And I can't use them with indexes anymore.

<register>
  <dim>4</dim>
  <dimIncrement>0x4</dimIncrement>
  <dimIndex>1-4</dimIndex>
  <name>C%sDT</name>
  <displayName>C1DT</displayName>
  <description>Channel data register</description>
  <addressOffset>0x34</addressOffset>
  <size>0x10</size>
  <access>read-write</access>
  <resetValue>0x00000000</resetValue>
  <writeConstraint>
    <range>
      <minimum>0</minimum>
      <maximum>65535</maximum>
    </range>
  </writeConstraint>
</register>
#[doc = "0x34 - Channel data register"]
pub c1dt: CDT,
_reserved14: [u8; 0x02],
#[doc = "0x38 - Channel data register"]
pub c2dt: CDT,
_reserved15: [u8; 0x02],
#[doc = "0x3c - Channel data register"]
pub c3dt: CDT,
_reserved16: [u8; 0x02],
#[doc = "0x40 - Channel data register"]
pub c4dt: CDT,
_reserved17: [u8; 0x02],

I'd like to see something like this

impl RegisterBlock {
    #[doc = "0x34..0x44 - Channel data register"]
    #[inline(always)]
    pub const unsafe fn cdt(&self, n: u8) -> &CDT {
        &*(self as *const Self)
            .cast::<u8>()
            .add(52usize + 4usize * (n - 1))
            .cast()
    }
}
burrbull commented 9 months ago

Try to run svd2rust --const_generic. It should generate ArrayProxy so you can access with cdt[1]. Although this is low tested.

kossnikita commented 9 months ago

Yes, I already checked this flag. It didn't have any impact. Literally. It didn't change anything.

If I understand correctly, this only affects fields and clusters.

kossnikita commented 9 months ago

Oops. I found what this does. This adds struct ArrayProxy in generics.rs. But this still does not allow registers to be called as an array.

burrbull commented 9 months ago

I think the problem is your indexes don't start from 0: https://github.com/rust-embedded/svd2rust/blob/460ea2ecbc5306085a019a3291f7aab38aeae74c/src/generate/peripheral.rs#L1116

Try to replace sequential_indexes_from0 with just sequential_indexes to remove zero restriction.

kossnikita commented 9 months ago

It's about clusters. Should I convert my array to a cluster?

Same behavior

let sequential_indexes = array_info
    .indexes_as_range()
    .is_some();
burrbull commented 9 months ago

Could you upload complete SVD somewhere?

kossnikita commented 9 months ago

https://github.com/kossnikita/at32f4xx-pac/blob/test/cdt-16bit/src/at32f415/at32f415.svd