<re_irc>
const CFG_BUF_SIZE: usize = MSG_SIZE_WITHOUT_PAYLOAD + PAYLOAD_LEN_CFG as usize;
<re_irc>
let mut cfg_write_buf = [0; CFG_BUF_SIZE];
<re_irc>
cfg_msg.to_buf(&mut cfg_write_buf);
<re_irc>
uart.write(&cfg_write_buf)?;
<re_irc>
// The GNSS sends its ack at the new baud, so set it before reading.
<re_irc>
uart.set_baud(BAUD, clock_cfg)?;
<re_irc>
// Due to the delay on possible responses, don't check here.
<re_irc>
Ok(())
<re_irc>
}
<re_irc>
<@firefrommoonlight:matrix.org> *I guess this probably doesn't help much since your issue is I2C-centric
<re_irc>
<@firefrommoonlight:matrix.org> Any reason for I2C here? Of note, I think Uart works better here since the data is in long packets. I tend to think of I2C as for register-style APIs
<re_irc>
<@firefrommoonlight:matrix.org> But obv either is fine
<re_irc>
<@firefrommoonlight:matrix.org> So, I will say this re one of your suspicions. If I don't delay for ~300ms between power on and setup, it doesn't work
<re_irc>
<@firefrommoonlight:matrix.org> I don't know why
<re_irc>
<@firefrommoonlight:matrix.org> Easy enough to test
<re_irc>
<@firefrommoonlight:matrix.org> But the more important question is this: How the hell di dyou get that device?
<re_irc>
<@firefrommoonlight:matrix.org> * did you
<re_irc>
<@firefrommoonlight:matrix.org> If you have the UART pins exposed, it may be worth trying them
<re_irc>
<@whitequark:matrix.org> I'm going to try and bridge using catircservices.org again soonish
<re_irc>
<@whitequark:matrix.org> (after matrix-appservice-irc is upgraded to 1.0.1 in nixos... so at least tomorrow, probably)
<re_irc>
<@whitequark:matrix.org> that would fix it
crabbedhaloablut has joined #rust-embedded
duderonomy has joined #rust-embedded
<re_irc>
<@xobs:matrix.org> Hey, I've got a question. I'm trying to upstream support for my OS, "riscv32imac-unknown-xous-elf". However, I notice that the RISC-V foundation renamed the arch, and it's now "riscv32imac_zicsr-unknown-xous-elf".
<re_irc>
Have there been any other embedded targets that are going to rename their architectures? The issue I'm facing is that code compiled with "cc-rs" doesn't have access to CSRs, so for example I can't compile "libunwind".
<re_irc>
<@whitequark:matrix.org> it looks like you can detect the vector extension (idk how... presumably riscv has an intrinsic for it?) and gate the entire block if it's not found
<re_irc>
<@xobs:matrix.org> I was considering just hardcoding the opcode for "csrr" as a ".word", which could work. I've been patching "cc-rs" for now, which works, but isn't pretty at all.
<re_irc>
<@whitequark:matrix.org> I'm a libunwind reviewer, if you add the conditional, I'll commit it for you
<re_irc>
<@xobs:matrix.org> I don't know that there is a "#define" to look for when vector extensions are enabled.
<re_irc>
<@xobs:matrix.org> But I'll check!
<re_irc>
<@whitequark:matrix.org> "__riscv_v"
<re_irc>
<@whitequark:matrix.org> but it's easier to branch on "__riscv_zicsr" which I suggested in the comment
<re_irc>
<@whitequark:matrix.org> actually, thinking about it more, branching on "__riscv_v" is more correct
<re_irc>
<@whitequark:matrix.org> this way you won't end up with a broken libunwind if by some accident you end up with +v -zicsr
<re_irc>
<@whitequark:matrix.org> "__riscv_vector" also works and looks nicer
<re_irc>
<@xobs:matrix.org> That seems like a fantastic solution.
<re_irc>
<@whitequark:matrix.org> (I'm looking at the output of "riscv64-unknown-elf-gcc -dM -E -march=rv64gv - </dev/null|grep -i risc")
<re_irc>
<@whitequark:matrix.org> IMO people are way too hesitant to patch LLVM components when there are obvious bugs
<re_irc>
<@whitequark:matrix.org> LLVM bugs happen all the time, especially off the trodden path
<re_irc>
<@whitequark:matrix.org> oh gods, I'm so sorry for anyone on the IRC side
<re_irc>
<@xobs:matrix.org> I'm pretending I'm Sgx so I'm using "UnwindRustSgx.c". How welcome do you think they'd be to modifying and reusing that? It seems like a bit of a hack, but it's a hack that's perfect for my target. Mostly I include "#include <link.h>" to get "alloca()", and I disable the body of "vwrite_err()" since I have no output handy.
<re_irc>
<@whitequark:matrix.org> what's Sgx?
<re_irc>
<@whitequark:matrix.org> UnwindRustSgx isn't an upstream thing in LLVM
<re_irc>
<@whitequark:matrix.org> so you'd be talking to someone in the Rust project, not the LLVM project (i.e. not me)
<re_irc>
<@xobs:matrix.org> Alright, let me submit this to phabricator
hmw has quit [Quit: Bye.]
<re_irc>
<@xobs:matrix.org> Okay, that's nice. I didn't realise llvm decided to ignore it when instructions were removed from the base spec. That's incredibly helpful, and explains why RISC-V "asm!()" code didn't break: https://llvm.org/docs/RISCVUsage.html#id5
hmw has joined #rust-embedded
<re_irc>
<@sourcebox:matrix.org> Hi. I have a bunch of things to address regarding interfacing with C/C++ code. I did some basic setup using the "cc" crate and that generally works. What does not work out the box is linking to functions from libc or libm because there's no newlib in the game, so there has to be some solution for that. For the math functions, I did a test with the libm crate and wrap the functions to give them extern C linkage. Don't know...
<re_irc>
... if that's a good idea.
<re_irc>
<@sourcebox:matrix.org> I also found "tinylibc" from . That is possibly something I should use.
<re_irc>
<@9names:matrix.org> > there's no newlib in the game, so there has to be some solution for that.
<re_irc>
well one solution is to link in newlib. have you considered it?
<re_irc>
<@sourcebox:matrix.org> Yes, but I want to avoid that if possible. I think it requires to use the linker from the ARM toolchain.
<re_irc>
<@sourcebox:matrix.org> The C/C++ code I'm talking about is mainly DSP code done by someone else. I expect that there will be some calls to math functions.
<re_irc>
<@sourcebox:matrix.org> Making printf work would also not be a bad thing.
<re_irc>
<@9names:matrix.org> how about trying picolibc?
<re_irc>
i don't think there's precompiled binaries for it, but it's pretty simple to compile if you've got a linux dev environment, and there are scripts for building with clang for thumbv6m and thumbv7m targets.
<re_irc>
if nothing else, building your own libc and linking it in yourself should help demystify the process somewhat
<re_irc>
<@9names:matrix.org> - edit: precompiled binaries built by clang. there are gcc built ones, and a gcc toolchain, but the goal here is to avoid tools that magically solve your problems.
<re_irc>
<@sourcebox:matrix.org> Ok, picolibc is (at least partly) GPL, so I don't need to read any further.
<re_irc>
<@sourcebox:matrix.org> Maybe I should ask the other way around: is there some reason not to wrap libm functions like this:
<re_irc>
#[no_mangle]
<re_irc>
extern "C" fn sinf(x: f32) -> f32 {
<re_irc>
libm::sinf(x)
<re_irc>
}
<re_irc>
<@diondokter:matrix.org> If that's what you need, why not just link in the 'normal' C libm?
<re_irc>
<@ryan-summers:matrix.org> : I haven't been following closely, but if you want free, fast sin/cos functions, check out https://github.com/quartiq/idsp :)
<re_irc>
<@sourcebox:matrix.org> Because I think the number of functions used is manageable.
<re_irc>
<@9names:matrix.org> : did you read the licence section of the readme? it seems to me that you didn't.
<re_irc>
<@sourcebox:matrix.org> : No, I just saw it on the meta info on GitHub.
<re_irc>
<@sourcebox:matrix.org> : I don't need that functions in Rust, it's for the part written in C/C++ by someone else.
<re_irc>
<@sourcebox:matrix.org> But you're right, licensing is ok if I read the details.
<re_irc>
<@sourcebox:matrix.org> It's only because GH says "GPL-2.0 and 2 other licenses found".
<re_irc>
<@sourcebox:matrix.org> Regarding performance, there will be LUTs used, I'm quite sure. But even if calculated via "constexpr", the functions have to be working.
<re_irc>
<@sourcebox:matrix.org> Another things is how to deal with "malloc". If I'm going to provide that, it should use the "embedded-alloc" crate under the hood. Mainly because my setup is multi-core.
<re_irc>
<@dirbaio:matrix.org> nothing new, we already knew we were sacrificing these use cases when we switched SpiDevice to the operation-list API
<re_irc>
<@dirbaio:matrix.org> but still interesting, they make some strong points
<re_irc>
<@diondokter:matrix.org> Just add an operation that takes a closure ;)
<re_irc>
<@dirbaio:matrix.org> Box<dyn Fn>? ew :D
<re_irc>
<@diondokter:matrix.org> Function pointer would work better :P
<re_irc>
<@dirbaio:matrix.org> jokes aside, that defeats the point of the operation-list, which is to make SpiDevice implementable on top of linux spidev
<re_irc>
<@diondokter:matrix.org> I know, just joking
<re_irc>
<@dirbaio:matrix.org> we could just add an operation that contains an eBPF binary π€ͺ
<re_irc>
<@dirbaio:matrix.org> no, that's doing separate CS toggles for each write
<re_irc>
<@dirbaio:matrix.org> the ST7789 didn't seem to care, I don't know if others do
<re_irc>
<@dirbaio:matrix.org> * other displays do
<re_irc>
<@dirbaio:matrix.org> like, that code does
<re_irc>
- DC low
<re_irc>
- CS low
<re_irc>
- write command
<re_irc>
- CS high
<re_irc>
- DC high
<re_irc>
- CS low
<re_irc>
- write data
<re_irc>
- CS high
<re_irc>
<@dirbaio:matrix.org> which is perfectly doable with SpiDevice
<re_irc>
<@dirbaio:matrix.org> vs the "right" way would be
<re_irc>
<@dirbaio:matrix.org> like, that code does
<re_irc>
- DC low
<re_irc>
- DC high
<re_irc>
- write command
<re_irc>
- CS low
<re_irc>
- write data
<re_irc>
- CS high
<re_irc>
<@dirbaio:matrix.org> - DC low
<re_irc>
- write command
<re_irc>
- CS low
<re_irc>
- DC high
<re_irc>
- write data
<re_irc>
- CS high
<re_irc>
<@bugadani:matrix.org> : why does this example copy some of the display-interface-spi code?
<re_irc>
<@dirbaio:matrix.org> because display-interface-spi is still on eh0.2 which doesn't have SpiDevice
<re_irc>
<@bugadani:matrix.org> ah yeah that thing needs to be cleaned up and released :(
<re_irc>
<@bugadani:matrix.org> +right
kenrendell[m] has quit [Write error: Connection reset by peer]
whitequark has quit [Remote host closed the connection]
<re_irc>
<@dirbaio:matrix.org> it can't use SpiDevice thoguh due to the DC thing
<re_irc>
<@dirbaio:matrix.org> unless it's guaranteed that all displays are OK with separate CS toggles?
<re_irc>
<@dirbaio:matrix.org> in that case the discussion on the e-h issue is a bit moot π
<re_irc>
<@bugadani:matrix.org> I'd think nothing is guaranteed, but unless someone finds a device that cares about it...
<re_irc>
<@bugadani:matrix.org> well I've removed the "SPIInterface" that togged CS but even that drew the line between data and command: each had their own transaction. I don't think there was any feedback that this is incorrect
<re_irc>
<@dirbaio:matrix.org> that's never toggling CS though?
<re_irc>
<@dirbaio:matrix.org> vs that embassy example is toggling CS "too much"
<re_irc>
<@bugadani:matrix.org> okay I'll need to read back for context
kenrendell[m] has joined #rust-embedded
<re_irc>
<@dhylands:matrix.org> I can give you a data sheet of a device Epson Gs370 IMU) that doesnβt want its CS toggled for transfers in burst mode.
whitequark has joined #rust-embedded
<re_irc>
<@dirbaio:matrix.org> we're talking about SPI displays with a DC pin :)
<re_irc>
<@dhylands:matrix.org> Ahhh. In that case I have no experience to offer.
<re_irc>
<@bugadani:matrix.org> oh they are trying to read from that display, that's new π but the datasheet seems to be fine with keeping D/C low in this specific case
<re_irc>
<@vollbrecht:matrix.org> the e-hal traits just need support for quad spi than we could misuses one of the lines as a dc line π€―
<re_irc>
<@bugadani:matrix.org> and also how do I start an I2C read after the 3rd bit of the second byte has been read?
Guest4814 has left #rust-embedded [Error from remote client]
<re_irc>
<@dirbaio:matrix.org> what?
<re_irc>
<@bugadani:matrix.org> I'm just trolling, asking where e-h should draw the line: a completely generic interface is impossible because linux doesn't like to work with callbacks, so how many exceptions does e-h want to define around SPI?
<re_irc>
<@jamesmunns:beeper.com> personal request not to go to trolling, both for not being mean, and particularly as we have folks with varying levels of english, and sarcasm and similar is fairly hard to parse in a language you are not native to.
<re_irc>
<@bugadani:matrix.org> : apologies
<re_irc>
<@jamesmunns:beeper.com> it's also _really_ hard for anyone over text to tell the difference between "I'm joking with you" and "im making fun of you"
<re_irc>
<@jamesmunns:beeper.com> (IM/chat lacks a lot of subtlety and context clues that'd be okay in person)
<re_irc>
<@bugadani:matrix.org> Yeah I understand, and I'm always trying to get better but I've started pretty low on the communication skill scale, unfortunately. I'm never trying to make fun of anyone, except maybe myself.
<re_irc>
<@bugadani:matrix.org> With that said
<re_irc>
<@bugadani:matrix.org> My serious take is that there will always be exceptions. Some displays will not work with the mipidsi crate just becasue a minute detail, some will not work with display-interface. I feel like it's okay for embedded-hal to draw the line at one point, there will always be hardware, or combinations of hardware that it will not be able to support.
<re_irc>
<@jamesmunns:beeper.com> I think this is very true, but I think you will find everyone _wants_ that line to be drawn somewhere different :)
<re_irc>
<@jamesmunns:beeper.com> but yeah, e-hal maintainers are always allowed to say "no".
<re_irc>
<@bugadani:matrix.org> : also true, but we have a specific issue where I think it is not necessary :)
<re_irc>
<@almindor:matrix.org> CS in most displays is really just a enabler (e.g. if CS is high, the device just ignores any inputs) and AFAICS (for my list of displays) it doesn't impact state (e.g. switching CS between DC doesn't change the logical outcome)
<re_irc>
<@almindor:matrix.org> i didn't do any reading yet though to see if it becomes an issue there
<re_irc>
<@almindor:matrix.org> as for sharing displays on one SPI, it's doable and I have a working demo
dc740 has joined #rust-embedded
<re_irc>
<@sourcebox:matrix.org> When writing a wrapper for redirecting C's "malloc" to Rust, I think something like this will do it:
<Shell>
hold up, no. malloc specifically returns a pointer that is aligned to alignof(max_align_t)
<re_irc>
<@sourcebox:matrix.org> Shell: What does that mean in practice. I'm on an ARM Cortex-A7, so alignment is typically 4.
<re_irc>
<@sourcebox:matrix.org> * practice?
<Shell>
ah, fair.
<re_irc>
<@ryan-summers:matrix.org> : For free etc, you'd have to do pointer math to figure out the memory locations to dealloc, just like C does I think
<re_irc>
<@sourcebox:matrix.org> : That's obvious, but the free() function does not give me any size information of what the pointer was allocated before.
<re_irc>
<@sourcebox:matrix.org> I could easily do a malloc(1024) but free is not knowing that.
<re_irc>
<@sourcebox:matrix.org> But the problem of leaking is more a hypothetical one because memory is typically allocated once on startup when doing embedded.
<re_irc>
<@sourcebox:matrix.org> And it's never freed.
Guest4814 has joined #rust-embedded
<re_irc>
<@sourcebox:matrix.org> Shell: But I think there's some constant in the core library that is set to the target's alignment, so it would be a good practice to use that instead of hardcoding it.
<Shell>
exactly
<re_irc>
<@almindor:matrix.org> does anyone know what causes rust-analyzer to keel over with tons of errors such as
<re_irc>
can't find crate for `std`
<re_irc>
the `riscv32imac-unknown-none-elf` target may not support the standard library
<re_irc>
? This seems to come deep from dependency tree, in this case "byteorder" crate, but "cargo check" (and others) work fine for the project. The project is "!#[no_std]" of course.
<re_irc>
<@almindor:matrix.org> nvm, solved. It seems including tinygif in my workspace caused this somehow
Guest4814 has left #rust-embedded [Error from remote client]
dc740 has quit [Remote host closed the connection]
<re_irc>
<@ryan-summers:matrix.org> Looks to be pretty new too
IlPalazzo-ojiisa has joined #rust-embedded
<re_irc>
<@2:0x2c.org> nice
Guest4814 has joined #rust-embedded
<re_irc>
<@dngrs:matrix.org> : maybe because of its "dev-dependencies"
crabbedhaloablut has quit []
exark has quit [Quit: quit]
exark has joined #rust-embedded
<re_irc>
<@gussius:matrix.org> I have been wondering lately, if there is a way, maybe with probe-rs or something where you can check that the board you are flashing to is the correct one. When you are developing on a multi-board system for instance, if you flash the wrong firmware to a power board, then you can blow FETs pretty quickly. Not sure how this would work, but it you could interrogate the program memory first before flashing the new firmware,...
<re_irc>
... then you could check some version variable or something.
<re_irc>
<@jamesmunns:beeper.com> For chip specific support, I think there might be some kind of chip/manufacturer ID that is visible from SWD, though if it's not part of the SWD spec, then it's probably not portable.
<re_irc>
For projects I've worked on in the past where you have the SAME IC but in different system parts, if you can spare a few GPIOs as "strapping lines", you can encode "board ID" by pulling those pins on every board high or low in a unique combination, or using resistors and an ADC to set a specific value
<re_irc>
<@jamesmunns:beeper.com> so for that, it's possible to do something like:
<re_irc>
- boot
<re_irc>
- read 3 pins, if the value is NOT "my" special value, like "high low high", then just halt or go back to bootloader mode
<re_irc>
<@jamesmunns:beeper.com> so on the "motor board" you could put "low low low", and on the "sensor board" you could do "low low high", and so on.
<re_irc>
<@jamesmunns:beeper.com> I know for example the nrf family has registers you can read to figure out what chip it is, but I think that's specific to their family, and stm32 probably has something similar, but might be at a different location.
<re_irc>
<@jamesmunns:beeper.com> but, you could probably write a small tool to "pre-check it" by using the probe-rs API to manually read those peripheral registers, and check the USB device before flashing, as a project specific tool.
<re_irc>
<@grantm11235:matrix.org> It is common for a bootloader/firmware updater to check that the new firmware matches the current board, but that won't save you from flashing the wrong bootloader, and it won't save you if you are flashing the firmware directly during development
<re_irc>
<@gussius:matrix.org> : Ok, thanks for the insight James.
dc740 has quit [Remote host closed the connection]
<re_irc>
<@gussius:matrix.org> : Maybe you could run a validate with the old firmware before compiling and flashing the new firmware.
<re_irc>
<@gussius:matrix.org> Is it possible to do just a validate, without flashing first?
dc740 has joined #rust-embedded
<re_irc>
<@shakencodes:matrix.org> I'm trying to pass a *const c_char (a pointer to a C string) into a function that takes &[u8]... and am stuck at how to cast between the two. My Googling has not found anything that makes sense. The function in question checks for null termination (https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html#method.from_bytes_with_nul).
<re_irc>
The signature of the function receiving the C data is:
dc740 has quit [Remote host closed the connection]
<re_irc>
<@shakencodes:matrix.org> That is what my code is using now as a workaround, but it does not check for null-termination. It looks like from_bytes_nul is the function you _should_ use, but the data types are not helpful. (We need from_ptr_nul()...)
<re_irc>
<@jamesmunns:beeper.com> if you ONLY get a pointer, then there's really no _safer_ way to calculate len and/or test null termination
<re_irc>
<@jamesmunns:beeper.com> from_ptr does calculate the len by running the ptr until it hits a nul
<re_irc>
<@jamesmunns:beeper.com> IF you got a ptr+len, you could do "core::slice::from_raw_parts(ptr.cast::<u8>(), len)" to get a slice
<re_irc>
<@jamesmunns:beeper.com> (in both cases you should test that "ptr" itself is not null)
<re_irc>
<@shakencodes:matrix.org> Thank you, James. I think I see what you are saying. Would it make sense to combine the "from_raw_parts" with "from_byte_with_nul" and use an arbitrary "my string will never be more than NNN bytes as the length? It seems like this would ensure the thing doesn't run away in the case of an invalid string being passed in, and the case that is not null-terminated before NNN with give an error.
<re_irc>
<@jamesmunns:beeper.com> Yeah, so that would be like subbing strnlen for strlen
<re_irc>
<@jamesmunns:beeper.com> which I agree would be "harm reduction"
<re_irc>
<@jamesmunns:beeper.com> though you could do the same, BUT tbh if you aren't getting a properly null terminated string passed in, you're PROBABLY walking across invalid memory, which is sorta already in the "oops UB" territory
kenrendell[m] has quit [Ping timeout: 245 seconds]
whitequark has quit [Ping timeout: 245 seconds]
<re_irc>
<@shakencodes:matrix.org> Much appreciated, James. I feel like my skill level at Rust is making good progress and might be "passable" at the moment. It is really good having someone else to discuss this with. (I'm taking another engineer through the Exercism Rust track now, and they may join my team -- currently of one -- in the next few months. Which will be nice.)