sajattack / bitbang-hal Goto Github PK
View Code? Open in Web Editor NEWImplements embedded-hal traits by bitbanging
License: MIT License
Implements embedded-hal traits by bitbanging
License: MIT License
Clock stretching tends to be a failure case for a lot of hal implementations. It would be cool if this library supported controlling clock stretching timeouts as master or allowed intentionally stretching out the clock as a slave. The use case I originally thought of was to use this crate as a way to test any other microcontroller's hal implementation.
The embedded hal trait (duplicated below for reference) requires that an actual SPI transaction be performed only from the send()
function. send()
should clock out the provided byte, as well as clocking in the byte sent by the slave. A subsequent read()
call will return that cached byte (in most implementations this'll come from a register, but for bitbang it'll just be some storage in the struct).
The current implementation clocks data explicitly in both functions, meaning there's no way to simultaneously read and write data. This will render it impossible to interface with many SPI peripherals, and will break implementations expecting the HAL-defined behavior which try to use this.
/// Full duplex (master mode)
///
/// # Notes
///
/// - It's the task of the user of this interface to manage the slave select lines
///
/// - Due to how full duplex SPI works each `read` call must be preceded by a `send` call.
///
/// - Some SPIs can work with 8-bit *and* 16-bit words. You can overload this trait with different
/// `Word` types to allow operation in both modes.
pub trait FullDuplex<Word> {
/// An enumeration of SPI errors
type Error;
/// Reads the word stored in the shift register
///
/// **NOTE** A word must be sent to the slave before attempting to call this
/// method.
fn read(&mut self) -> nb::Result<Word, Self::Error>;
/// Sends a word to the slave
fn send(&mut self, word: Word) -> nb::Result<(), Self::Error>;
}
Hello @sajattack
What do you think if I replace Metro-M4 examples by BluePill examples ? BluePill is a much more common board than Metro. So more users will be able to start experimenting right away without additional tinkering with example code.
Regards,
Sergey
In SPI Mode 2 & 3 (CPOL = 1), the idle level is high.
In the current implementation, if the user does not set the clock to HIGH before calling SPI::new(...)
, the first bit will be lost.
The serial read appears to be broken.
The first issue is that it's loading bits from the LSB - so the final byte will be reversed. It should be loading from the MSB and shifting right.
The second issue I found when experimenting, is that in practice the start bit delay was too short - this resulted in the received byte being 4x as large (truncated) as the intended value (when the first issue was accounted for). Adding 2 extra delay periods in the start bit seemed to fix this. Please see if you can reproduce this problem as it may just be my equipment.
fn read(&mut self) -> nb::Result<u8, Self::Error> {
let mut data_in = 0;
// wait for start bit
while self.rx.is_high().map_err(Error::Bus)? {}
block!(self.timer.wait()).ok();
for _bit in 0..8 {
data_in <<= 1;
if self.rx.is_high().map_err(Error::Bus)? {
data_in |= 1
}
block!(self.timer.wait()).ok();
}
// wait for stop bit
block!(self.timer.wait()).ok();
Ok(data_in)
}
should be:
fn read(&mut self) -> nb::Result<u8, Self::Error> {
let mut data_in = 0;
// wait for start bit
while self.rx.is_high().map_err(Error::Bus)? {}
block!(self.timer.wait()).ok();
block!(self.timer.wait()).ok();
block!(self.timer.wait()).ok();
for _bit in 0..8 {
data_in >>= 1;
if self.rx.is_high().map_err(Error::Bus)? {
data_in |= 0x80
}
block!(self.timer.wait()).ok();
}
// wait for stop bit
block!(self.timer.wait()).ok();
Ok(data_in)
}
even then I cant get it to work reliably...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.