ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to #rust-embedded:matrix.org and logged at https://libera.irclog.whitequark.org/rust-embedded, code of conduct at https://www.rust-lang.org/conduct.html
kenny has quit [Quit: WeeChat 3.8]
kenny has joined #rust-embedded
cr1901_ has joined #rust-embedded
cr1901 has quit [Ping timeout: 246 seconds]
<re_irc> <@sparky:matrix.possumlodge.me> is there any good materials for writing drivers for devices using embedded-hal outside of the knurling material? any libs that make doing so nicer/easier outside of embedded-hal? going to attempt to start and finish a driver for once, vs getting minimal functionality working so anything people can suggest would be nice
starblue3 has quit [Ping timeout: 252 seconds]
starblue3 has joined #rust-embedded
<re_irc> <@avery71:matrix.org> I sometimes go and look at driver code I see on the awesome embedded rust page
cr1901_ is now known as cr1901
<re_irc> <@mburton:matrix.org> I’ve been using packed_struct to define the device, has some quirks but works for me
crabbedhaloablut has joined #rust-embedded
<re_irc> <@sourcebox:matrix.org> I spend a good amount of time with "critical_section::Mutex yesterday" and I could not make it work the way it's describes in the docs here: https://docs.rs/critical-section/1.1.1/critical_section/struct.Mutex.html
<re_irc> <@sourcebox:matrix.org> But: !!!!
<re_irc> <@sourcebox:matrix.org> If I wrap the whole borrow in "critical_section::with" it works!
<re_irc> <@sourcebox:matrix.org> Then I had a look into the sources of the crate and I could not really find where it is acquired and released when doing it the proposed way. Maybe I'm just to stupid to understand it.
<re_irc> <@sourcebox:matrix.org> Ok, I could use "with", but then the CS lasts way to long and I run into reentrace problems quite easily.
<re_irc> <@sourcebox:matrix.org> : Maybe you can shed some light on this.
<re_irc> <@sourcebox:matrix.org> Some test code to run:
<re_irc> use critical_section::{self, set_impl, CriticalSection, Impl, Mutex};
<re_irc> struct MyCriticalSection;
<re_irc> use core::cell::RefCell;
<re_irc> unsafe impl Impl for MyCriticalSection {
<re_irc> unsafe fn acquire() -> critical_section::RawRestoreState {
<re_irc> println!("Acquire CS");
<re_irc> }
<re_irc> unsafe fn release(_restore_state: critical_section::RawRestoreState) {
<re_irc> println!("Release CS");
<re_irc> }
<re_irc> }
<re_irc> set_impl!(MyCriticalSection);
<re_irc> static FOO: Mutex<RefCell<i32>> = Mutex::new(RefCell::new(42));
<re_irc> fn main() {
<re_irc> println!("Version 1:");
<re_irc> let cs = unsafe { CriticalSection::new() };
<re_irc> let foo: &mut i32 = &mut *FOO.borrow_ref_mut(cs);
<re_irc> println!("x: {}", foo);
<re_irc> println!();
<re_irc> println!("Version 2:");
<re_irc> critical_section::with(|cs| {
<re_irc> let foo: &mut i32 = &mut *FOO.borrow_ref_mut(cs);
<re_irc> println!("x: {}", foo);
<re_irc> });
<re_irc> }
<re_irc> The first version does not even use the CS. Hmm...?
<re_irc> <@adamgreig:matrix.org> : I think that documentation is a bit confusing. you should only ever use "unsafe { CriticalSection::new() }" inside some kind of critical section you've created; it's just an empty token that symbolises being inside a CS. with the acquire/release methods you shouldn't ever need to call "new()", and that example should really use "with()" instead
<re_irc> <@adamgreig:matrix.org> "critical_section::Mutex" does not enter a critical section itself - it requires you pass in a "CriticalSection" token to prove that you're currently inside a critical section, as that should be the only way to safely obtain such a token
<re_irc> <@adamgreig:matrix.org> so you have to use "critical_section::with()" to obtain that token and then operate on the mutex inside it
<re_irc> <@adamgreig:matrix.org> in other words, your version 2 is the correct way and the only thing you should expect to work; your version 1 is just unsafely bypassing the safety conditions on CriticalSection to obtain a token even when you're not inside a critical section, and so it doesn't work
<re_irc> <@adamgreig:matrix.org> (if you check the docs for "CriticalSection::new()", it says "This must only be called when the current thread is in a critical section. The caller must ensure that the returned instance will not live beyond the end of the critical section.")
<re_irc> <@adamgreig:matrix.org> that example in the "Mutex" docs is only meant to demonstrate that "RefCell" methods are available directly on a "Mutex<RefCell<T>>", but it's definitely misleading that it uses "CriticalSection::new()", that should either be hidden or changed to "with()"...
<re_irc> <@sourcebox:matrix.org> Yes, I've already seen this. But of course, I took the example code and had a great time to find out the problem. Of course my stupidity.
<re_irc> <@adamgreig:matrix.org> (it's that way for historical reasons, as it used to live in the bare-metal crate before critical-section existed)
<re_irc> <@sourcebox:matrix.org> Knowing that I have to work on the CS implementation itself, which has several pitfalls on multicore systems.
<re_irc> <@sourcebox:matrix.org> I'm not even sure if the atomics really work as expected, because of cache coherency between the cores.
<re_irc> <@sourcebox:matrix.org> For now I use the hardware semaphores of the STM32MP1. That basically works, the docs from ST about them are very misleading also. But I have not solved the reentrance problem.
<re_irc> <@adamgreig:matrix.org> using the hardware semaphores to synchronise the cores is probably how you're expected to do it
<re_irc> <@adamgreig:matrix.org> though atomics "should" work, i guess depending on fine details of the memory system but i'd usually have expected the exclusive monitor to synchronise between the cores I guess... perhaps naively
<re_irc> <@sourcebox:matrix.org> ARM docs mention the existence of an SCU (Snoop Control Unit), which should do the coherency (if I understand that correctly).
<re_irc> <@sourcebox:matrix.org> Pitfall with the hardware semaphores is: they use a COREID, with values 1 and 2, but that is NOT what identifies the 2 Cortex-A cores.
<re_irc> <@sourcebox:matrix.org> Both Cortex-A cores use COREID 1, so COREID 2 is likely what identifies the Cortex-M on the SoC.
<re_irc> <@thejpster:matrix.org> https://github.com/rust-lang/rust/issues/113739
<re_irc> I’ve asked that we regularise the documentation about who the target maintainers are. I’ve also pinged someone at Arm because honestly I thought they were looking after some of this stuff.
<re_irc> <@adamgreig:matrix.org> do you remember why you thought that? my recollection is they are only looking after aarch64
<re_irc> <@adamgreig:matrix.org> it would be a shame if the thumb targets ended up tier 3 as a consequence, lol
<re_irc> <@sourcebox:matrix.org> I think the aarch32 targets do not get much love here, do they?
<re_irc> <@sourcebox:matrix.org> Performance-wise Cortex-A5/7/9 are not that great compared the newer stuff, but I still see them used e.g. as additional cores in FPGAs.
<re_irc> <@sourcebox:matrix.org> +to
<re_irc> <@adamgreig:matrix.org> technically arm include thumb in aarch32, so in a sense they do
<re_irc> <@adamgreig:matrix.org> but yea, i think they are indeed quite focussed on aarch64 for application cores now
<re_irc> <@sourcebox:matrix.org> Just asking myself if it's a good idea to use a CS inside the panic handler that writes the message to some port.
<re_irc> <@whitequark:matrix.org> PSA: I am preparing to bridge this room to IRC through my catircservices.org double puppeting bridge
<re_irc> <@whitequark:matrix.org> if everything goes well: as you speak in this room you will probably get a message from NickServ
<re_irc> <@whitequark:matrix.org> if not everything goes well: I'm going to roll it back since I will watch over the process for a few hours at least
<re_irc> <@whitequark:matrix.org> the room is normally too big to bridge in this way, but I have my bridge configured in such a way as to not create undue load to Libera servers
<re_irc> <@whitequark:matrix.org> this is done coordinated with and the Libera folks and if anything goes wrong I'll pause the link to investigate
whitequark has joined #rust-embedded
<re_irc> <@whitequark:matrix.org> ... go
_catircservices has joined #rust-embedded
_catircservices[ has joined #rust-embedded
vancz[m] has joined #rust-embedded
_catircservices4 has joined #rust-embedded
vancz[m][m] has joined #rust-embedded
vancz[m][m][m] has joined #rust-embedded
_catircservices7 has joined #rust-embedded
vancz[m][m][m][m has joined #rust-embedded
_catircservice10 has joined #rust-embedded
vancz[m][m][m][4 has joined #rust-embedded
re_irc has quit [Remote host closed the connection]
whitequark[cis] has joined #rust-embedded
<whitequark[cis]> that did not go as planned
vancz[m][m][m][4 has quit [Remote host closed the connection]
vancz[m][m][m] has quit [Remote host closed the connection]
_catircservices[ has quit [Remote host closed the connection]
vancz[m][m][m][m has quit [Remote host closed the connection]
_catircservices7 has quit [Remote host closed the connection]
vancz[m] has quit [Remote host closed the connection]
_catircservices has quit [Remote host closed the connection]
_catircservices4 has quit [Remote host closed the connection]
vancz[m][m] has quit [Remote host closed the connection]
_catircservice10 has quit [Remote host closed the connection]
whitequark[cis] has quit [Remote host closed the connection]
_catircservices has joined #rust-embedded
vancz[m] has joined #rust-embedded
whitequark[cis] has joined #rust-embedded
<whitequark[cis]> okay, this seems to go well so far
<whitequark[cis]> I think that's all the IRC-side joins
xnor[m] has joined #rust-embedded
adamgreig[m]1 has joined #rust-embedded
jamesmunns[m] has joined #rust-embedded
therealprof[m] has joined #rust-embedded
appservice-irc[4 has joined #rust-embedded
whitequark[cis]1 has joined #rust-embedded
joelsa[m] has joined #rust-embedded
juliand[m] has joined #rust-embedded
malled[m] has joined #rust-embedded
MTRNord[m]1 has joined #rust-embedded
Shine[m] has joined #rust-embedded
moonling[m] has joined #rust-embedded
lm[m] has joined #rust-embedded
<adamgreig[m]1> how does it pick which matrix-side users to puppet?
jsantos[m] has joined #rust-embedded
M0[m] has joined #rust-embedded
M01luiss[m] has joined #rust-embedded
M0x6202[m] has joined #rust-embedded
<adamgreig[m]1> seem to be getting a steady flow of matrix users joining on irc
<whitequark[cis]> LRU, but I didn't realize it's actively looking at ... last 10 minutes of backfilled events, I think?
DanielHe[m] has joined #rust-embedded
<whitequark[cis]> yes
M1badb002h[m] has joined #rust-embedded
M54321qwer[m] has joined #rust-embedded
Admiral[m] has joined #rust-embedded
M5nip3r2k[m] has joined #rust-embedded
<whitequark[cis]> I don't think I want that to continue; looking into it
M762spr[m] has joined #rust-embedded
<adamgreig[m]1> that doesn't obviously correlate with its choice of users, most of which haven't spoken here recently at all
Ablu[m] has joined #rust-embedded
M54321qwer[m] has quit [Remote host closed the connection]
M5nip3r2k[m] has quit [Remote host closed the connection]
Ablu[m] has quit [Remote host closed the connection]
M1badb002h[m] has quit [Remote host closed the connection]
jamesmunns[m] has quit [Remote host closed the connection]
adamgreig[m]1 has quit [Remote host closed the connection]
vancz[m] has quit [Remote host closed the connection]
M762spr[m] has quit [Remote host closed the connection]
M01luiss[m] has quit [Remote host closed the connection]
jsantos[m] has quit [Remote host closed the connection]
whitequark[cis]1 has quit [Remote host closed the connection]
Shine[m] has quit [Remote host closed the connection]
_catircservices has quit [Remote host closed the connection]
lm[m] has quit [Remote host closed the connection]
MTRNord[m]1 has quit [Remote host closed the connection]
appservice-irc[4 has quit [Remote host closed the connection]
M0x6202[m] has quit [Remote host closed the connection]
juliand[m] has quit [Remote host closed the connection]
therealprof[m] has quit [Remote host closed the connection]
whitequark[cis] has quit [Remote host closed the connection]
xnor[m] has quit [Remote host closed the connection]
DanielHe[m] has quit [Remote host closed the connection]
M0[m] has quit [Remote host closed the connection]
moonling[m] has quit [Remote host closed the connection]
joelsa[m] has quit [Remote host closed the connection]
Admiral[m] has quit [Remote host closed the connection]
malled[m] has quit [Remote host closed the connection]
_catircservices has joined #rust-embedded
whitequark[cis] has joined #rust-embedded
<whitequark[cis]> okay here you go
vancz[m] has joined #rust-embedded
<whitequark[cis]> this should now only bridge to IRC the people who actually talk, and bridge everyone on IRC to Matrix
<whitequark[cis]> I have no idea why it just joined vancz
<agg> specifically it seems to have joined the old matrix-side puppet for vancz's irc user
<whitequark[cis]> let's... uh... trial this...
adamgreig[m]1 has joined #rust-embedded
<adamgreig[m]1> (test, test)
xnor[m] has joined #rust-embedded
jamesmunns[m] has joined #rust-embedded
therealprof[m] has joined #rust-embedded
M9names[m]1 has joined #rust-embedded
<M9names[m]1> it's a test test?
appservice-irc[4 has joined #rust-embedded
whitequark[cis]1 has joined #rust-embedded
joelsa[m] has joined #rust-embedded
juliand[m] has joined #rust-embedded
<whitequark[cis]> no, it still keeps joining random people :(
malled[m] has joined #rust-embedded
MTRNord[m]1 has joined #rust-embedded
Shine[m] has joined #rust-embedded
moonling[m] has joined #rust-embedded
<adamgreig[m]1> two of the old puppets but also a bunch of random matrix users it seems, weird
<whitequark[cis]> the same people even
lm[m] has joined #rust-embedded
jsantos[m] has joined #rust-embedded
M0[m] has joined #rust-embedded
M01luiss[m] has joined #rust-embedded
M0x6202[m] has joined #rust-embedded
DanielHe[m] has joined #rust-embedded
M1badb002h[m] has joined #rust-embedded
M54321qwer[m] has joined #rust-embedded
Admiral[m] has joined #rust-embedded
<adamgreig[m]1> maybe it's sorted by read-receipt activity as well, not sure
M5nip3r2k[m] has joined #rust-embedded
<adamgreig[m]1> that does seem like it might explain the ordering
M762spr[m] has joined #rust-embedded
Ablu[m] has joined #rust-embedded
Diaeresis[m] has joined #rust-embedded
DanielakaCyReVol has joined #rust-embedded
Limeth[m] has joined #rust-embedded
Michi[m] has joined #rust-embedded
<whitequark[cis]> I have looked at the config and it seems correct
TheSirC[m] has joined #rust-embedded
ArneDuin[m] has joined #rust-embedded
AaronTsui[m] has joined #rust-embedded
ArnolddeVos[m] has joined #rust-embedded
toymil[m] has joined #rust-embedded
AaronGowatch[m] has joined #rust-embedded
<whitequark[cis]> I'm calling this off for now. we'll do more testing and then retry
AaronKutch[m] has joined #rust-embedded
aavogt[m] has joined #rust-embedded
abgeana[m] has joined #rust-embedded
AbhishekDhamale[ has joined #rust-embedded
ArthurBonnaudet[ has joined #rust-embedded
aborazmeh[m] has joined #rust-embedded
catch22[m]1 has joined #rust-embedded
AlexRowley[m] has joined #rust-embedded
aavogt[m] has quit [Remote host closed the connection]
M9names[m]1 has quit [Remote host closed the connection]
appservice-irc[4 has quit [Remote host closed the connection]
joelsa[m] has quit [Remote host closed the connection]
xnor[m] has quit [Remote host closed the connection]
AaronKutch[m] has quit [Remote host closed the connection]
aborazmeh[m] has quit [Remote host closed the connection]
AaronTsui[m] has quit [Remote host closed the connection]
Admiral[m] has quit [Remote host closed the connection]
Michi[m] has quit [Remote host closed the connection]
M0[m] has quit [Remote host closed the connection]
AbhishekDhamale[ has quit [Remote host closed the connection]
MTRNord[m]1 has quit [Remote host closed the connection]
malled[m] has quit [Remote host closed the connection]
M54321qwer[m] has quit [Remote host closed the connection]
juliand[m] has quit [Remote host closed the connection]
jamesmunns[m] has quit [Remote host closed the connection]
whitequark[cis]1 has quit [Remote host closed the connection]
jsantos[m] has quit [Remote host closed the connection]
_catircservices has quit [Remote host closed the connection]
TheSirC[m] has quit [Remote host closed the connection]
AlexRowley[m] has quit [Remote host closed the connection]
Ablu[m] has quit [Remote host closed the connection]
toymil[m] has quit [Remote host closed the connection]
Diaeresis[m] has quit [Remote host closed the connection]
ArneDuin[m] has quit [Remote host closed the connection]
M1badb002h[m] has quit [Remote host closed the connection]
DanielakaCyReVol has quit [Remote host closed the connection]
M01luiss[m] has quit [Remote host closed the connection]
ArnolddeVos[m] has quit [Remote host closed the connection]
AaronGowatch[m] has quit [Remote host closed the connection]
M762spr[m] has quit [Remote host closed the connection]
Limeth[m] has quit [Remote host closed the connection]
M5nip3r2k[m] has quit [Remote host closed the connection]
lm[m] has quit [Remote host closed the connection]
adamgreig[m]1 has quit [Remote host closed the connection]
M0x6202[m] has quit [Remote host closed the connection]
DanielHe[m] has quit [Remote host closed the connection]
vancz[m] has quit [Remote host closed the connection]
Shine[m] has quit [Remote host closed the connection]
moonling[m] has quit [Remote host closed the connection]
therealprof[m] has quit [Remote host closed the connection]
abgeana[m] has quit [Remote host closed the connection]
catch22[m]1 has quit [Remote host closed the connection]
ArthurBonnaudet[ has quit [Remote host closed the connection]
whitequark[cis] has quit [Remote host closed the connection]
emerent has quit [Ping timeout: 246 seconds]
emerent has joined #rust-embedded
id_tam has joined #rust-embedded
GenTooMan has quit [Ping timeout: 240 seconds]
GenTooMan has joined #rust-embedded
re_irc has joined #rust-embedded
<re_irc> <@whitequark:matrix.org> LRU, but I didn't realize it's actively looking at ... last 10 minutes of backfilled events, I think?
<re_irc> <@whitequark:matrix.org> yes
<re_irc> <@whitequark:matrix.org> I don't think I want that to continue; looking into it
<re_irc> <@adamgreig:matrix.org> that doesn't obviously correlate with its choice of users, most of which haven't spoken here recently at all
<re_irc> <@whitequark:matrix.org> I think I need to change the mode settings a little more for this to be scalable
<re_irc> <@whitequark:matrix.org> where it doesn't puppet someone at all until they say a thing
<re_irc> <@adamgreig:matrix.org> different v6 address for each puppeted user is cute
<re_irc> <@whitequark:matrix.org> yes, this is preferred by Libera side
<re_irc> <@whitequark:matrix.org> I'm going to disable incremental Matrix-to-IRC membership list sync
<re_irc> <@whitequark:matrix.org> and enable the bridge
<re_irc> <@whitequark:matrix.org> that should do it
<re_irc> <@whitequark:matrix.org> oh, wait; we had initial enabled, too
<re_irc> <@whitequark:matrix.org> I'm going to disable both initial and incremental Matrix-to-IRC sync for this channel specifically, I think
<re_irc> <@whitequark:matrix.org> okay, next attempt
<re_irc> <@whitequark:matrix.org> I... found a bug in the NixOS toml parser?
<re_irc> <@whitequark:matrix.org> ah, no, it's just really bad error reporting on a typo
<re_irc> <@whitequark:matrix.org> okay here you go
<re_irc> <@whitequark:matrix.org> this should now _only_ bridge to IRC the people who actually talk, and bridge everyone on IRC to Matrix
<re_irc> <@whitequark:matrix.org> I have no idea why it just joined vancz
<re_irc> <@whitequark:matrix.org> let's... uh... trial this...
<re_irc> <@libera_agg:catircservices.org> specifically it seems to have joined the old matrix-side puppet for vancz's irc user
<re_irc> <@adamgreig:matrix.org> (test, test)
<re_irc> <@9names:matrix.org> it's a test test?
<re_irc> <@whitequark:matrix.org> no, it still keeps joining random people :(
<re_irc> <@adamgreig:matrix.org> two of the old puppets but also a bunch of random matrix users it seems, weird
<re_irc> <@whitequark:matrix.org> the same people even
<re_irc> <@adamgreig:matrix.org> maybe it's sorted by read-receipt activity as well, not sure
<re_irc> <@adamgreig:matrix.org> that does seem like it might explain the ordering
<re_irc> <@whitequark:matrix.org> I have looked at the config and it seems correct
<re_irc> <@whitequark:matrix.org> I'm calling this off for now. we'll do more testing and then retry
<re_irc> <@whitequark:matrix.org> it seems to simply ignore my configuration override. I'm hoping there's something obvious I'm missing
<re_irc> <@lambdafriend:matrix.org> I've been working on implementing ADC reads using DMA in circular mode and am at the point where I have code written but (ofc) it is not working. So this morning I'm taking some steps back and ensuring that more straight forward methods on ADC reads are working.
<re_irc> So far blocking read work! I'm now working through getting ADC reads using DMA and DMA Stream interrupts to work, but hit opaque instructions in the example for the HAL I'm using:
<re_irc> Does anyone know what that means, and can they point me in the right direction for doing that? My (admittedly naive) thought is that this is probably fine for an example, but isn't something that i.e. would go in a BSP crate, right?
<re_irc> <@lambdafriend:matrix.org> I've been working on implementing ADC reads using DMA in circular mode and am at the point where I have code written but (ofc) it is not working. So this morning I'm taking some steps back and ensuring that more straight forward methods on ADC reads are working. So far blocking read work! I'm now working through getting ADC reads using DMA and DMA Stream interrupts to...
<re_irc> ... work, but hit opaque instructions in the example for the HAL I'm using: https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/adc_dma.rs#L109 Does anyone know what that means, and can they point me in the right direction for doing that? My (admittedly naive) thought is that this is probably fine for an example, but isn't something that i.e. would go in a BSP crate, right?
<re_irc> <@adamgreig:matrix.org> : I think it's just saying "at this point, the DMA transfer is complete into a buffer with a particular memory address, so for the sake of the example you could use your debugger to read out the memory"
<re_irc> <@adamgreig:matrix.org> but in a real application you'd then use the buffer ("BUFFER") to access the readings
<re_irc> <@firefrommoonlight:matrix.org> I"m confused too
<re_irc> <@firefrommoonlight:matrix.org> How do we nknow the buffer is tat that loc?
<re_irc> <@firefrommoonlight:matrix.org> And why is that line in the idle loop?
<re_irc> <@firefrommoonlight:matrix.org> And what's the dest addr?
<re_irc> <@firefrommoonlight:matrix.org> Maybe that was part of a CP demoing a mem to mem xfer?
<re_irc> <@lambdafriend:matrix.org> My understanding is that "#[link_section = ".axisram"]" (set in "memory.x") is how we know that that is the location.
<re_irc> <@lambdafriend:matrix.org> But past that, I'm not really sure how this is suppose to work. Having a tough time finding real world examples of using DMA for ADC reads.
<re_irc> Ideally I want to use circular mode, but I've spend a few days reading up on issues for various HALs and there is no implementation out there. Seems so straight-forward from C/C++.
<re_irc> <@jamesmunns:beeper.com> I'm guessing the C/C++ versions are just being a little more cavalier with memory safety than Rust HAL writers are willing to be.
<re_irc> <@lambdafriend:matrix.org> Sorry, didn't mean for that to come off as dismissive of all the work everyone is doing. I'm just frustrated.
<re_irc> From the issues I've been reading it is quite complex to come up with something both generic enough for e.g. "embedded-hal", and also "safe" in all the ways Rust wants to be safe.
<re_irc> <@firefrommoonlight:matrix.org> See towards bottom of main for circ DMA ADC read
<re_irc> <@lambdafriend:matrix.org> I fought with that example all day yesterday :(
<re_irc> <@firefrommoonlight:matrix.org> What went wrong on particular?
<re_irc> <@lambdafriend:matrix.org> I'm actually working on using that as a basis for the impl I've been writing, but it didn't work so I'm taking a step back and making sure everything is setup properly by working through simpler examples. So far blocking reads work 🙌
<re_irc> Now I'm trying to tackle ADC reads using DMA.
<re_irc> <@adamgreig:matrix.org> have you checked out the reference manual for the chip, in particular any procedures for doing dma from adc?
<re_irc> <@adamgreig:matrix.org> which stm32 is it?
<re_irc> <@firefrommoonlight:matrix.org> Lmk. I'm using something similar to that on G4 and H7 in firmware
<re_irc> <@adamgreig:matrix.org> the stm32h7 is blessed/cursed with extensive and complicated DMA peripherals so there can be a lot of moving parts to line up before anything happens
<re_irc> <@lambdafriend:matrix.org> It's an H7 (STM32H750IBK6) - specifically the daisy seed dev board.
<re_irc> <@firefrommoonlight:matrix.org> Did you set up Mix?
<re_irc> <@firefrommoonlight:matrix.org> * Mux?
<re_irc> <@adamgreig:matrix.org> yep, if you can avoid getting discouraged you'll probably learn a lot of stuff
<re_irc> <@adamgreig:matrix.org> sadly all made-up stuff from ST but nevertheless
<re_irc> <@lambdafriend:matrix.org> I'm 10 years a web engineer. I'm used to this 😄
<re_irc> <@adamgreig:matrix.org> perfect :p
<re_irc> <@adamgreig:matrix.org> the reference manual 25.4.27 "Data management" has a subsection on "Managing conversions using the DMA" which has a few details
<re_irc> <@adamgreig:matrix.org> but as mentioned, on the stm32h7 the DMA engine has a "DMAMUX" where you configure which DMA channels are associated with which DMA requests (eg from the ADC)
<re_irc> <@firefrommoonlight:matrix.org> You have to pair the DMA channel to the peripheral
<re_irc> <@adamgreig:matrix.org> if you're using stm32h7xx-hal, some of this is/can be taken care of for you, though, I believe?
<re_irc> <@firefrommoonlight:matrix.org> * peripheral. (The DMA::mux line in the example I posted)
<re_irc> <@lambdafriend:matrix.org> I think this line (https://github.com/stm32-rs/stm32h7xx-hal/blob/2d47a4a06c30cb95fa6e1f1fb9c8720c6e426c1a/src/dma/mod.rs#L525-L528) should be handling DMAMUX?
<re_irc> <@adamgreig:matrix.org> yep indeed
<re_irc> <@adamgreig:matrix.org> so that should be set up for you
<re_irc> <@lambdafriend:matrix.org> Taking a look at 25.4.27...
<re_irc> <@adamgreig:matrix.org> the best thing to do might be to try and read the various status registers from the ADC and DMA to see if they're even trying to do things - if you have a debug interface hooked up, you could read the register values directly
<re_irc> <@adamgreig:matrix.org> for example, something needs to tell the ADC to begin conversions, and to either keep converting or eventually stop, and to send DMA requests to the DMA peripheral which will actually trigger a write to memory
<re_irc> <@firefrommoonlight:matrix.org> Concur. status regs for both ADC and DMA is the play
<re_irc> <@adamgreig:matrix.org> on the ADC side, check ADC_ISR and be sure ADRDY is set and maybe you expect to see EOSMP, EOC, EOS as it runs, and you could read the ADC_DR to see the value of whatever it most recently sampled which the DMA will be reading too
<re_irc> <@lambdafriend:matrix.org> I have an STLink v3 but need to get debugging setup.
<re_irc> <@adamgreig:matrix.org> then on the DMA side it's the LISR and HISR registers, which you don't want to see error flags set on, and SxNDTR which shows how many transfers it's expecting to get, still
<re_irc> <@adamgreig:matrix.org> it's well worth getting that going first so you stand a chance of working out what's happening with the rest, otherwise you're flying half blind
<re_irc> <@adamgreig:matrix.org> even just for using rtt/defmt for debug printing/logging
<re_irc> <@lambdafriend:matrix.org> Yeah I've got rtt/defmt going (print debugger here 😆)
<re_irc> <@adamgreig:matrix.org> aah cool, that should be all you need then!
<re_irc> <@adamgreig:matrix.org> you can just have your code print out the value of the register
<re_irc> <@adamgreig:matrix.org> "println!("LISR={:08x}", unsafe { core::ptr::read_volatile(0xxxxxxxxxx) });"
<re_irc> <@adamgreig:matrix.org> something like that, but let's see
<re_irc> <@adamgreig:matrix.org> reference manual -> section 2 memory and bus -> 2.3.2 memory map and addresses
<re_irc> <@adamgreig:matrix.org> MDMA is 0x5200_0000, ADC1 is 0x4002_2000, DMA1 is 0x4002_0000, DMA2 is 0x4002_0400, DMAMUX1 is 0x4002_0800 in that table
<re_irc> <@adamgreig:matrix.org> then section 15 DMA -> 15.5.1 LISR says offset 0x00, so DMA1.LISR is at address 0x4002_0000
<re_irc> <@adamgreig:matrix.org> "unsafe { println!("LISR={:08x} HISR={:08x}", core::ptr::read_volatile(0x4002_0000), core::ptr::read_volatile(0x4002_0004)};"
<re_irc> <@adamgreig:matrix.org> * core::ptr::read_volatile(0x4002_0004))};"
<re_irc> <@adamgreig:matrix.org> assuming you're using DMA1!
<re_irc> <@adamgreig:matrix.org> anyway, that's a start, you can see if any status bits are set in DMA, I'd also want to print out the rest of the DMA config registers for whichever stream you're using (CR/NDTR/PAR/M0AR) to check they make sense, and then the ADC ISR
<re_irc> <@adamgreig:matrix.org> depending on how good your hex-to-binary-in-your-head is you might prefer "{:032b}" but I find it harder to keep count that way
<re_irc> <@adamgreig:matrix.org> this is super low-level checking - many people will use a debugger in their IDE that knows where all the registers and fields are (through an SVD file) and uses the stlink to read the values for you without putting anything in your code, and can show it per register and break it down for you etc
<re_irc> <@adamgreig:matrix.org> but it's probably harder to walk you through setting that sort of thing up than just adding a line of code that prints the register value for you, since that printing is already working
<re_irc> <@adamgreig:matrix.org> ah, I was probably taking too much of a liberty with that example too, it's more like "read_volatile(0x4002_0000 as *const u32)"
<re_irc> <@lambdafriend:matrix.org> I've been reading through "mastering stm32" book (any other good books?) and it walks through setting up ST's debugger. I might get that going at some point.
<re_irc> <@firefrommoonlight:matrix.org> Cube programmer will do the reg view thing too
<re_irc> <@firefrommoonlight:matrix.org> I think ideally you have a "read-status" method that provides a set of flags, but I do the print number thing out of laziness
<re_irc> <@firefrommoonlight:matrix.org> * enums etc
<re_irc> <@adamgreig:matrix.org> the book probably won't talk about the ways that are common in the rust world, but for reading registers anything's fine, cube is probably not a bad idea
<re_irc> <@lambdafriend:matrix.org> * debugger (STM32CubeIDE).
<re_irc> <@firefrommoonlight:matrix.org> The raw reg read is also more universal since it doesn't depend on a HAL, lang etc; just the hardware
<re_irc> <@adamgreig:matrix.org> usually i just do exactly what i wrote above, or alternatively connect something like probe-rs command line debugger and just read memory out at runtime
<re_irc> <@adamgreig:matrix.org> but this goes really right to the source and removes every abstraction layer, so you can't get tripped up by bugs in the pac, bugs in the hal, whatever
<re_irc> <@adamgreig:matrix.org> if you've got the code in a repo somewhere feel free to share too
<re_irc> <@lambdafriend:matrix.org> "09:42:54.393 INFO - LISR=00100000 HISR=00000000" That's inside the DMA_STR2 interrupt.
<re_irc> <@adamgreig:matrix.org> so that's HTIF2 set only, which is "stream 2 half transfer interrupt flag", i.e. on stream 2 half of the expected number of transfers have been completed, and no errors
<re_irc> <@lambdafriend:matrix.org> I don't even know how to read this 😆 (looking at 15.5 DMA registers)
<re_irc> <@lambdafriend:matrix.org> : Holy moly, that's beautiful!
<re_irc> <@adamgreig:matrix.org> hopefully you're using stream 2 and perhaps the interrupt is set to trigger on half-complete too
<re_irc> <@adamgreig:matrix.org> in 15.5.1 it has the layout for LISR
<re_irc> <@adamgreig:matrix.org> 0010_0000 hex is 0000_0000_0001_0000 0000_0000_0000_0000 in binary (broken in 16 to match the reference manual)
<re_irc> <@adamgreig:matrix.org> so the one bit that's set is bit 20, HTIF2
<re_irc> <@lambdafriend:matrix.org> Yeah, stream 2 and all interrupts enabled.
<re_irc> <@lambdafriend:matrix.org> Oh, ok, that helps _a ton_!!
<re_irc> <@lambdafriend:matrix.org> Teach a man to fish 😄
<re_irc> <@adamgreig:matrix.org> that's promising then, it suggests it's actually transferred half the things it expected to, which tends to suggest the ADC is doing conversions and telling it to copy the results
<re_irc> <@adamgreig:matrix.org> next I would print out S2CR, S2NDTR, S2PAR, S2M0AR
<re_irc> <@adamgreig:matrix.org> the reference manual says they are "0x10 + 0x18 * x", where x is 2 for stream 2
<re_irc> <@adamgreig:matrix.org> so 0x4002_0040 for S2CR, 0x4002_0044 for S2NDTR, 0x4002_0048 for S2PAR, 0x4002_004C for S2M0AR
<re_irc> <@firefrommoonlight:matrix.org> Is the num data param consistent with your buf size?
<re_irc> <@adamgreig:matrix.org> these mostly just check the HAL did what you are expecting - you should see half the total buffer size in NDTR, you should see the ADC data register address in PAR (0x4002_2040 for ADC1), and your buffer address in M0AR
<re_irc> <@firefrommoonlight:matrix.org> Ie if you're reading 3 channels, the buf is len 3 and you've passed that it's 3 chans to the DMA xfer start
<re_irc> <@adamgreig:matrix.org> well, you might be reading 1 channel 100 times, too
<re_irc> <@adamgreig:matrix.org> or 3 channels 100 times for buffer of length 300
<re_irc> <@firefrommoonlight:matrix.org> Valid
<re_irc> <@firefrommoonlight:matrix.org> Yea great pt
<re_irc> <@lambdafriend:matrix.org> "S2CR=00002c14 S2NDTR=00000000 S2PAR=40022040 S2M0AR=24000000"
<re_irc> Working through those now 👀
<re_irc> <@adamgreig:matrix.org> PAR looks good, M0AR is OK if you had the same axisram thing going on (hopefully the axisram is enabled...), but I'd expect ndtr to be non-zero at the half-complete interrupt (unless the fully-complete flag is also set by now)
<re_irc> <@adamgreig:matrix.org> but, CR doesn't have HTIE set, only TCIE, so I would have only expected a transfer-complete interrupt and not a half-transfer interrupt
<re_irc> <@adamgreig:matrix.org> and EN isn't set, so it looks as though this is the state when the transfer has finished and the DMA has disabled itself
<re_irc> <@lambdafriend:matrix.org> Yeah, all that is right. I removed the half transfer between the last log and this one (sorry).
<re_irc> So that log was from a transfer complete (since the half was disabled).
<re_irc> I also had circ mode on (sort of just trying things 😩).
<re_irc> "AXISRAM (RWX) : ORIGIN = 0x24000000, LENGTH = 512K"
<re_irc> <@lambdafriend:matrix.org> -"AXISRAM (RWX) : ORIGIN = 0x24000000, LENGTH = 512K"
<re_irc> <@adamgreig:matrix.org> : yea, once you're using it in the actual application logic instead of quick sanity checking or debugging, this is the way to go, actually read it properly, use the PAC/HAL methods for it, all that
<re_irc> <@lambdafriend:matrix.org> : Just all 0s (no data being written to the buffer).
<re_irc> <@firefrommoonlight:matrix.org> : DMA mux
<re_irc> <@lambdafriend:matrix.org> : By mux do you mean an external mux chip, or something else? 😟
<re_irc> <@lambdafriend:matrix.org> : I've got that open too. It doesn't help that I'm still somewhat new to embedded as a whole so I'm sort of diving into the _deep_ end of the pool.
<re_irc> <@avery71:matrix.org> : My guess is possibly some camera firmware would be using it
<re_irc> <@jamesmunns:beeper.com> : fwiw, it's straightforward to write, but very hard to make safe. If you look at the data for too long, the DMA will start overwriting, and it's undefined behavior
<re_irc> <@lambdafriend:matrix.org> Yeah, all that is right. I removed the half transfer between the last log and this one (sorry).
<re_irc> So that log was from a transfer complete (since the half was disabled).
<re_irc> I also had circ mode on (sort of just trying things 😩).
<re_irc> Axisram is right, yeah.
<re_irc> <@lambdafriend:matrix.org> Yeah, all that is right. I removed the half transfer interrupt between the last log and this one (sorry).
<re_irc> So that log was from a transfer complete (since the half was disabled).
<re_irc> I also had circ mode on (sort of just trying things 😩).
<re_irc> Axisram is right, yeah.
<re_irc> <@lambdafriend:matrix.org> It's pretty neat seeing how all the Rust code I've been reading maps to what the manual is saying 🙌
<re_irc> <@firefrommoonlight:matrix.org> Is the ADC in continuous mode?
<re_irc> <@lambdafriend:matrix.org> I had it in continious mode in that reading, but I went back to one shot since that's what I'm testing.
<re_irc> <@firefrommoonlight:matrix.org> And is the conversion started?
<re_irc> <@firefrommoonlight:matrix.org> That is a sep step from xfer
<re_irc> <@firefrommoonlight:matrix.org> I think you have to start conversation after xfer is set
<re_irc> <@lambdafriend:matrix.org> Yeah, I'm using the HALs "transfer.start" method.
<re_irc> <@lambdafriend:matrix.org> transfer.start(|adc| {
<re_irc> adc.start_conversion_dma(&mut daisy21, AdcDmaMode::OneShot);
<re_irc> });
<re_irc> <@lambdafriend:matrix.org> Ok, time for some food. I'll report back later once I've digested the advice y'all gave me.
<re_irc> Huge thanks for everything! 😍
<re_irc> <@adamgreig:matrix.org> looks promising so far, maybe worth trying to read out the buffer too and check it's all still zeros, and read out the ADC DR to check it's not _reading_ zeros
<re_irc> <@2:0x2c.org> hi, i'm back at testing my embedded code, and i wonder how i could export my mocks from one crate to another, but only for (host) testing. my crates are "no_std" when not testing so that i can use mockall. If i wanted to export my mocks, i think i would need to compile with std. really not sure how to arrange this.
<re_irc> <@lambdafriend:matrix.org> If I don't enable dcache then the one shot dma has the values in the axisram memory locations. With dcache enabled, they're zeros. Just starting in on why that is the case.
<re_irc> <@lambdafriend:matrix.org> * case (the BSP crate I've been using enabled dcache as part of it's start up routine).
<re_irc> <@adamgreig:matrix.org> aah, right, with caches you're in for a fun new world of learning too
<re_irc> <@adamgreig:matrix.org> the problem is that the DMA operates after the cache, so it's written to the real AXI SRAM, but the CPU reads from the cache instead of the actual RAM, and the cache doesn't know that the DMA has written to the AXI SRAM and so gives the CPU 0s
<re_irc> <@adamgreig:matrix.org> the simplest thing to do is not use the dcache, and maybe much later on you'll know if you really need it
<re_irc> <@adamgreig:matrix.org> the best thing to do is configure the MPU to have a non-cached region in the AXI SRAM and thus leave it uncached - there's no advantage to caching a buffer that the DMA writes and CPU reads
<re_irc> <@adamgreig:matrix.org> the middle ground is to use the cache management functions in "cortex-m", like "invalidate_dcache_by_slice()" https://docs.rs/cortex-m/latest/cortex_m/peripheral/struct.SCB.html#method.invalidate_dcache_by_slice
<re_irc> <@lambdafriend:matrix.org> The C++ BSP I've been porting/working from has cached and non-cached regions so this is all making sense now!
<re_irc> <@adamgreig:matrix.org> "invalidate" means "tell the cache its copy is bad, it needs to reload from the real memory", which is what you need when the DMA has written and the CPU wants to read
<re_irc> <@adamgreig:matrix.org> "clean" means "tell the cache to write what it's got into the real memory", which you need for CPU writing and DMA reading (like maybe an outbound SPI transfer through DMA)
<re_irc> <@adamgreig:matrix.org> but in general it's better performance to disable the cache in a region you just use for DMA buffers, as there's no benefit from the data going through the cache and instead overhead of cache management
<re_irc> <@adamgreig:matrix.org> however, configuring the MPU is a little non-trivial, or at least cortex-m doesn't have convenience wrappers for it at the moment, so you might be better off just disabling the dcache entirely
<re_irc> <@lambdafriend:matrix.org> Do you know where I would find configuration disabling dcache in regions in a C/C++ project that was generated from STM32 Cube?
<re_irc> <@lambdafriend:matrix.org> Like the linker (i.e. memory.x for Rust)?
<re_irc> <@lambdafriend:matrix.org> The question behind the question (good old X/Y problem!) is I'm looking for a thread to pull on for how to configure different regions of RAM as cacheless, but don't know how to find the equivalent config in the C++ project I'm porting over. I've looked in the past but didn't come up with anything.
<re_irc> <@thejpster:matrix.org> You could generate two projects and diff them?
<re_irc> <@thejpster:matrix.org> I assume it involves memory writes into a cache management peripheral, either within the Cortex-M core or a separate peripheral. Or in the case of a cursed TI chip I worked on, both. (It had at least six MMUs).
<re_irc> <@thejpster:matrix.org> The linker only knows how to modify object code to sit at defined locations in memory.
<re_irc> <@thejpster:matrix.org> It cannot generate code, only fix up existing object code.
<re_irc> Oh, it also links multiple object code files together so they can call each other.
<re_irc> <@pinealservo:matrix.org> I worked with a TI chip or two like that.
<re_irc> <@adamgreig:matrix.org> : sorry, was afk
<re_irc> <@adamgreig:matrix.org> you want the MPU configuration
<re_irc> <@thejpster:matrix.org> I wrote Rust for the IPU on the Beagleboard X15 including reverse engineering remoteproc and virtio vrings as no-std Rust
<re_irc> <@adamgreig:matrix.org> seeing if I can find a convenient example around
<re_irc> <@thejpster:matrix.org> Is that in the Cortex-M or is it an ST thing?
<re_irc> <@adamgreig:matrix.org> it's a cortex-m peripheral, not a ST peripheral, so it's documented separately, too
<re_irc> <@thejpster:matrix.org> I only use M0 these days.
<re_irc> <@adamgreig:matrix.org> you want the "ARM Cortex-M7 Devices Generic User Guide", section 4.6 Optional Memory Protection Unit
<re_irc> <@thejpster:matrix.org> Unrelated note, does anyone know if no-std can catch a panic, or how hard it would be?
<re_irc> <@lambdafriend:matrix.org> Here (https://github.com/dobrite/libdaisy-rust/blob/master/src/mpu.rs#L58-L101) is the BSP crate I've been working from. I'm imagining it's those register writes 👀
<re_irc> <@adamgreig:matrix.org> yea, that's the right bit to look at
<re_irc> <@lambdafriend:matrix.org> Ok, that's enough to get me going! I'll report back. Starting to feel bad taking up so much channel bandwidth 😄 Appreciate all the help!!
<re_irc> <@thejpster:matrix.org> I want one binary to jump to another binary, and have a panic in the second cause the first to continue running. I guess I could use an interrupt to store processor state and use the panic handler to trigger a fault that restores the state. A bit like a fork. Or a setjmp.
<re_irc> <@adamgreig:matrix.org> it looks like if you called that function and passed in your buffer address and length, it would configure a MPU region that disables caching it
<re_irc> <@adamgreig:matrix.org> in particular it sets the C bit to 0 for that region, marking it non-cacheable
<re_irc> <@adamgreig:matrix.org> : I feel like you need unwinding support to catch a panic, which I don't think is available on no_std on the target itself (maybe in a debugger), but not entirely sure
<re_irc> <@dirbaio:matrix.org> if you want to "abort the process" on panic and return to the "OS shell" or similar
<re_irc> <@dirbaio:matrix.org> make panic handler call "udf"
<re_irc> <@thejpster:matrix.org> But std must do it _somehow_. Mumble mumble libunwinding.
<re_irc> <@adamgreig:matrix.org> it has the elf
<re_irc> <@dirbaio:matrix.org> and then make hardfault handler restore register state back to running the OS shell
<re_irc> <@dirbaio:matrix.org> you only need unwinding if you want the process itself to catch its own panics and not exit
<re_irc> <@avery71:matrix.org> If it's baremetal, you could use software interrupts
<re_irc> <@dirbaio:matrix.org> you probably don't need "real" processes (with user-mode/kernel-mode separation) for this
<re_irc> <@thejpster:matrix.org> I don’t have the elf. Rather, it’s on disk but I don’t load all of it. I guess it’s Register stacking time.
<re_irc> <@dirbaio:matrix.org> separation with the MPU etc
<re_irc> <@dirbaio:matrix.org> +no
<re_irc> <@thejpster:matrix.org> I assume I can set a global or damage a register so when they’re all popped and don’t immediately try and run the application again.
<re_irc> <@thejpster:matrix.org> * I
<re_irc> <@dirbaio:matrix.org> when the OS boots the app, save the OS registers somewhere
<re_irc> <@dirbaio:matrix.org> when the app hardfaults, restore those registers
<re_irc> <@dirbaio:matrix.org> so it'll look to the OS that the "boot the app" call has returned
<re_irc> <@dirbaio:matrix.org> with the right asm trickery
<re_irc> <@avery71:matrix.org> : Aren't panics at the hardware level?
<re_irc> <@pinealservo:matrix.org> : https://doc.rust-lang.org/nomicon/panic-handler.html <- Is that what you're looking for?
<re_irc> <@thejpster:matrix.org> : No, they’re pure Rust.
<re_irc> <@thejpster:matrix.org> : The panic handler handles the panic but it’s -> ! so you can’t return to where you were.
<re_irc> <@thejpster:matrix.org> : That means I have to implement processes in my OS 🤣
<re_irc> <@thejpster:matrix.org> stack_regs();
<re_irc> if IT_CRASHED { … } else { call _app(); }
<re_irc> <@dirbaio:matrix.org> you probably can't write it in Rust without UB though :D
<re_irc> <@thejpster:matrix.org> The messed up variables are at least in another binary.
<re_irc> <@thejpster:matrix.org> It’s not UB if the optimiser doesn’t know about it.
<re_irc> <@avery71:matrix.org> Sometimes it isn't undefined, it's just extradefined
<re_irc> <@thejpster:matrix.org> And is also a clear design non-goal. If you want processes, using MINIX. Or Linux.
<re_irc> <@thejpster:matrix.org> * use MINIX. Or Linux. Or that V6 UNIX that’s only six files or something.
<re_irc> <@thejpster:matrix.org> This is MS-DOS for Arm. And to be honest, requiring a reboot on panic would be perfectly acceptable. It’s just getting a bit annoying.
<re_irc> <@dirbaio:matrix.org> the RP2040 does have an MPU, so in theory you could have it
<re_irc> <@dirbaio:matrix.org> if you wanted it
<re_irc> <@2:0x2c.org> is there a way i can set a feature flag or a config flag for a crate when i use it for testing?
<re_irc> <@adamgreig:matrix.org> "cfg(test)"
<re_irc> <@adamgreig:matrix.org> +is set for you by cargo
<re_irc> <@dirbaio:matrix.org> and make sure you're using edition 2021, or "resolver = "2"" if you're using a Cargo workspace
<re_irc> <@thejpster:matrix.org> : It’s a Cortex-M0+ so that’s not even an option
<re_irc> <@dirbaio:matrix.org> : put it in "dev-dependencies" with the feature added
<re_irc> <@thejpster:matrix.org> does anyone have a moment to tell me why Github Actions hates me?
<re_irc> Why can't you use a git dependency in cargo inside github actions? It builds locally, and the branch is visible to me - even in private browsing mode.
<re_irc> <@thejpster:matrix.org> oh, i bet it's looking at cargo.lock and I did a force push on that branch
dc740 has joined #rust-embedded
dc740 has quit [Remote host closed the connection]
crabbedhaloablut has quit []
IlPalazzo-ojiisa has quit [Quit: Leaving.]
<re_irc> <@lambdafriend:matrix.org> Done for the day but ended with it continuously converting samples 🙌 The bad part is that they are not what I'm expecting the values to be. I move the pot and the values don't don't change (they change a bit due to noise, but not from like 0 to max u16 like I get with blocking reads).
<re_irc> That's for future-me to figure out.