Skip to content

fix: compilation on nightly #207

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

Merged
merged 1 commit into from
Dec 4, 2023
Merged

fix: compilation on nightly #207

merged 1 commit into from
Dec 4, 2023

Conversation

amaanq
Copy link
Contributor

@amaanq amaanq commented Oct 31, 2023

This fixes a bug when casting a *const _ to *mut _ on nightly, it's being phased out as acceptable and is now a hard error 😬

I could be completely wrong in my fix, but the compiler is happy - also, I noticed in spi.rs that the comment about writing 8 bits vs 16 bits mattered - I couldn't find anything about that in any manual for the f769 (board I have) but I could have easily missed something there.

Any feedback is appreciated!

@adamgreig
Copy link
Member

In RM0385 for example (F74x, F75x) in 32.5.9 it says (emphasis mine):

The handling of FIFOs depends on the data exchange mode (duplex, simplex), data frame
format (number of bits in the frame), access size performed on the FIFO data registers (8-bit
or 16-bit)
, and whether or not data packing is used when accessing the FIFOs (see
Section 32.5.13: TI mode).

All data to be written is written into the DR register, and it then goes through a small FIFO inside the SPI peripheral before it gets transmitted. For efficiency, when the SPI peripheral is configured to do 8-bit words, you can write 16 bits to the FIFO and it's treated as two sequential words to transmit.

What that means is that performing a strb instruction (store a single byte) will do something very different from strh (store halfword, i.e. 16-bit) or str (32-bit). The svd2rust write() function you call in this PR always performs a 32-bit access, which would cause two bytes to be written to the SPI FIFO. In this case, that means every byte will get send as [byte, 0x00] on the wire. The only correct thing to do is use write_volatile() directly with a *mut u8 to cause Rust to emit a strb. I guess you'll need a more roundabout conversion in this case, like ptr as *const u32 as u32 as *mut u8 or something.

@amaanq
Copy link
Contributor Author

amaanq commented Nov 1, 2023

Thanks! But casting it to *const u32 is also invalid as well, the only way would be to first cast as its own type as *mut T, which...feels a bit annoying

It'd be something like &(*USART::ptr()).tdr as *mut stm32f7::Reg<stm32f7::stm32f7x9::usart1::tdr> as *mut u32 which just doesnt...look nice and might not work depending on which board feature is enabled

@adamgreig
Copy link
Member

Ugh, yea, that is a pain.

It looks like you could do something like (USART::ptr().offset(10) as u32) as *mut u8, though it's a bit annoying. Could replace the 10 with offset_of!(RegisterBlock, tdr) but even so..

@amaanq
Copy link
Contributor Author

amaanq commented Nov 4, 2023

that works for me, but that's not great-looking I'll agree, a special note for the relevant spots can be added explaining why that was done

@maximeborges
Copy link
Member

Is there any open issue for that on stm32-rs?

@rtvd
Copy link
Contributor

rtvd commented Nov 14, 2023

Hi @maximeborges,

I do not see an open issue for it on stm32-rs but it is true that warnings/errors do pop up when trying to build this project.

For example, if I check out the current version and build "cargo build -F stm32f722" I see 3 warnings. Sometimes these warnings are seen as errors, which is confusing. I suppose this merge request is targeting all of those cases.

@Sh3Rm4n
Copy link
Member

Sh3Rm4n commented Nov 22, 2023

The fix in probe-rs/hs-probe-firmware#45 looks rather simple. I wonder if it just hides the compiler error? 🤔

But wouldn't core::ptr::addr_of! and core::ptr::addr_of_mut! to at least ensure, that we can obtain a valid address of the register without invoking undefined behavior?

e.g.

- &(*USART::ptr()).tdr as *mut stm32f7::Reg<stm32f7::stm32f7x9::usart1::tdr> as *mut u32
+ core::ptr::addr_of_mut!((*USART::ptr()).tdr) as *mut u32

@amaanq
Copy link
Contributor Author

amaanq commented Nov 22, 2023

Hey, sorry about the delay - I was planning to use core::ptr::addr_of, just rebased as well for the USART changes @adamgreig

@Sh3Rm4n
Copy link
Member

Sh3Rm4n commented Nov 22, 2023

You should probably change that invocation as well:

&self.dr as *const _ as _

@maximeborges maximeborges merged commit 302953f into stm32-rs:main Dec 4, 2023
@maximeborges
Copy link
Member

Thanks!

@amaanq
Copy link
Contributor Author

amaanq commented Dec 4, 2023

thanks, sorry for the delay :)

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

Successfully merging this pull request may close these issues.

5 participants