Comments (11)
During full duplex SPI communication, data is clocked in at the same time as it's clocked out.
The line before the one you've linked (block!(self.send(word.clone()))?;
) will clock out word
-- but it will also put another word in the hardware's receive buffer. The next line reads that data, and in doing so clears the buffer.
Without that line, the SPI block will probably end up entering an overrun error condition.
from embedded-hal.
The line before the one you've linked (block!(self.send(word.clone()))?;) will clock out word -- but it will also put another word in the hardware's receive buffer. The next line reads that data, and in doing so clears the buffer.
Is that so? This sounds more like a half duplex variant.
Without that line, the SPI block will probably end up entering an overrun error condition.
Here's the funny thing: I'm trying to talk to a APA102C LED which is actually only using a simplex connection. On the STM32F103 it works with this implementation, on the STM32F042 it does not because it blocks on this read()
...
from embedded-hal.
The line before the one you've linked (block!(self.send(word.clone()))?;) will clock out word -- but it will also put another word in the hardware's receive buffer. The next line reads that data, and in doing so clears the buffer.
Is that so? This sounds more like a half duplex variant.
The data is clocked simultaneously (hence full duplex), but to be nonblocking the spi::FullDuplex::send()
function cannot wait for the received data to be available, so the spi::FullDuplex::read()
function exists to do that waiting, and retrieve the data when it's ready.
Even in your LED driving case where, presumably, there's no connected MISO line, the SPI peripheral still clocks bits into the data register. It can be configured not to do this, (on the STM32F103, this is done through the BIDIMODE
and BIDIOE
bits in the CR1
register), but that's not what's currently done -- and it's probably the right choice the majority of the time, since it makes the implementation maximally flexible.
Since there's no electrical connection, that data is garbage -- but it's there, and the act of reading the data register is itself critical to the driver's operation, since it clears the RXNE
flag in the CR1
register (STM32F103 reference manual, page 710) and thus prevents an overrun error.
Without that line, the SPI block will probably end up entering an overrun error condition.
Here's the funny thing: I'm trying to talk to a APA102C LED which is actually only using a simplex connection. On the STM32F103 it works with this implementation, on the STM32F042 it does not because it blocks on this read()...
That's interesting, and sounds to me like a bug in the nonblocking implementation for the SPI driver. I've got some APA102s lying around, and I think an STM32F042. I may be able to play around with them this weekend, and perhaps discover the root of the issue. I can't promise I'll find anything, or even end up having the time -- but if I do, I'd love to try to help debug your issue. Can you point me at the driver code? I see your stm32f042-hal repo, but I don't see SPI in there yet, presumably because it's still WIP.
It looks like the F042 has a different SPI peripheral than the F103 -- maybe there's some subtlety with regards to the RX FIFO that needs to be accounted for? But it's hard to say concretely at this point.
from embedded-hal.
The data is clocked simultaneously (hence full duplex), but to be nonblocking the spi::FullDuplex::send() function cannot wait for the received data to be available, so the spi::FullDuplex::read() function exists to do that waiting, and retrieve the data when it's ready.
I'm using the blocking variant though...
I see your stm32f042-hal repo, but I don't see SPI in there yet, presumably because it's still WIP.
Hm, this is weird now. Just as I wanted to prepare a branch for your testing it started working. 🤔
from embedded-hal.
I'm using the blocking variant though...
But the default blocking variant is written in terms of the nonblocking one, and it's the behavior of that read (never returning a value) that's in question.
Hm, this is weird now. Just as I wanted to prepare a branch for your testing it started working. :
thinking:
Interesting indeed. Glad to hear things are working now, though!
from embedded-hal.
@austinglaser Okay, that "working" state was me commenting out the nb::Error::WouldBlock
part from the read
implementation. Most of that code is copied and adapted from the stm32f103xx-hal
crate where the same example application works just fine.
I've pushed the branch here: https://github.com/therealprof/stm32f042-hal/tree/features/half-assed-spi
from embedded-hal.
Cool, I'll see what I can figure out. Probably won't have time to really dig in until this weekend, though
from embedded-hal.
No worries, will have to implement a few other HALs though to test @japaric fancy new ENC28J60 driver though. ;)
from embedded-hal.
@therealprof Alright, figured out what was wrong and opened a pull request (therealprof/stm32f042-hal#1)
from embedded-hal.
Thanks a lot, I'll check it out and confirm.
from embedded-hal.
Works nicely, merged into master and uploaded new version to crates.io. Thanks again!
from embedded-hal.
Related Issues (20)
- i2c: Merging of consecutive operations in transaction contract
- SpiDevice's interface can't be used for streaming transactions HOT 6
- SpiDevice implementations in embedded-hal-bus don't provide a way to use active-high chip select HOT 3
- Create an I3C Trait
- Read not implemented for &mut [u8] HOT 1
- README: Links to LICENSE-APACHE and LICENSE-MIT are not found
- How do I share an I2c bus between tasks? HOT 1
- Implment `Clone` for async DelayNs HOT 2
- Multipin serial spi interface trait
- embedded-hal-bus no longer builds with target thumbv6m-none-eabi HOT 5
- Split embedded-can? HOT 3
- feature request: embedded_io_async::try_read HOT 2
- Upstreaming some concepts built up in `embedded-time` HOT 1
- Why was ADC removed? HOT 2
- [Discussion] Should sensor driver developers target `embedded-hal-async` only?
- Shared SPI bus between devices with different SPI modes HOT 2
- The Crate Does not Compile when the `defmt-03` Feature is Enabled HOT 4
- honor `ErrorKind::Interrupted` in `write_all()`? HOT 4
- Revisiting the possibility of including generic sensor traits HOT 1
- Generic bus traits HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from embedded-hal.