lpc-rs / lpc-pac

Peripheral Access Crates for LPC microcontrollers
9 stars 9 forks source link

USART.FCR register missing from lpc11uxx #47

Open roblabla opened 4 years ago

roblabla commented 4 years ago

The USART FCR and IIR registers both live at the same address - one is write-only, the other is read-only. The LPC11UXX crate currently only defines one of those - the iir register - and makes it read-only. The SVD does define both, so I guess this might be an svd2rust issue?

roblabla commented 4 years ago

Seems related to https://github.com/rust-embedded/svd2rust/issues/16

rnestler commented 4 years ago

Yes the LPC11 has a lot of registers on the same address, sometimes they differ in read / write and sometimes the functionality depends on some state in different registers. It is quite hard to generate proper code for these edge cases.

roblabla commented 4 years ago

Actually, it looks like the github repo has definitions for them (probably thanks to using a more up to date svd2rust?). Is there any plan to make a new release?

rnestler commented 4 years ago

I do not really work on a project with an LPC11 currently, so I'm not sure if I'll find the time to work on this. Would you like to contribute and test this crate? I'm sure the others of @lpc-rs/all wouldn't mind more help :slightly_smiling_face:

roblabla commented 4 years ago

Sure! FWIW I started some work on a embedded-hal impl for the lpc11uxx series, with impls for the Serial, SPI, and I2C, and some facilities to do type-safe pinmuxing and clock configuration (not currently on github, will push a WIP soon-ish). I also did some bindings to access the various ROM APIs (like the USB driver and the IAP).

WRT the registers, the APIs in master generate those registers that overlap just fine, but I think the way it exposes them is unsound. For instance, in USART, dll, thr and rbr all share the same register address. The way it works is that a bit in the lcr register (the DLAB bit) decides whether accesses to that address gives dll or rbr/thr.

This means that accessing dll with DLAB=0, or rbr/thr with DLAB=1, is UB. But the way the API is generated, those accesses are allowed and safe. Now I guess this is more of an svd2rust issue? it should probably generate unsafe accessors if there's some overlaps or something, especially since it might allow writing to reserved bits that would be otherwise unsafe to touch.

rnestler commented 4 years ago

Sure! FWIW I started some work on a embedded-hal impl for the lpc11uxx series,

I started some work on a HAL at https://github.com/lpc-rs/lpc11uxx-hal/, so feel free to take a look there as well, but as far as I remember I didn't do much there :slightly_smiling_face:

WRT the registers, the APIs in master generate those registers that overlap just fine, but I think the way it exposes them is unsound. For instance, in USART, dll, thr and rbr all share the same register address. The way it works is that a bit in the lcr register (the DLAB bit) decides whether accesses to that address gives dll or rbr/thr.

As far as I remember these overlapping ones get generated as a union, no? So access should be unsafe.

roblabla commented 4 years ago

As far as I remember these overlapping ones get generated as a union, no? So access should be unsafe.

Well, look at the doc link I sent. That's the latest master afaik, and access is definitely possible from safe code. It's generated as function calls doing pointer arithmetics and casting, no union involved: https://github.com/lpc-rs/lpc-pac/blob/master/lpc11uxx/src/usart.rs#L45-L72

rnestler commented 4 years ago

@roblabla I gave you write access to this repository and made you an owner of the lpc11uxx crate.