-
Notifications
You must be signed in to change notification settings - Fork 250
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
SPI slave support #469
Comments
Yes, we implement SPI traits from embedded-hal which all define only 1 bit full-duplex master mode. Technically we can define our own API to add SPI slave support (like we had to do for e.g. I2S before) TL;DR this is a feature request for SPI slave functionality 😄 |
As far as I understand from reading #580, slave driver for ESP32 and ESP32-S2 is not implemented due to I could try to investigate this and add implementation if someone guide me through codebase a little bit so I can understand how to get started |
I browsed through available spi options and found some things that could help make it work. reg_block.clock.modify(|_, w| {
w.clkdiv_pre().variant(0)
.clk_equ_sysclk().clear_bit()
.clkcnt_l().variant(0)
.clkcnt_h().variant(0)
.clkcnt_n().variant(0)
}); There are also The next observation is that Unfortunately, I cannot find actual |
I have also written sketchy interrupt-based no-cs slave driver: #[interrupt]
fn GPIO() {
critical_section::with(|cs| {
let mut slave = CLK.borrow_ref_mut(cs);
let slave = slave.as_mut().unwrap();
let mut timer = TIMER0.borrow_ref_mut(cs);
let timer = timer.as_mut().unwrap();
timer.start(100u64.millis());
let input = slave.mosi.is_high().unwrap();
slave.end = false;
slave.buf_n += (input as u8) << (7 - slave.c);
slave.c += 1;
if slave.c == 8 {
slave.c = 0;
slave.buf.push(slave.buf_n);
slave.buf_n = 0;
}
slave.clk.clear_interrupt();
});
}
#[interrupt]
fn TG0_T0_LEVEL() {
critical_section::with(|cs| {
let mut timer = TIMER0.borrow_ref_mut(cs);
let timer = timer.as_mut().unwrap();
let mut slave = CLK.borrow_ref_mut(cs);
let slave = slave.as_mut().unwrap();
if slave.end == false {
println!("{:?}", slave.buf);
slave.buf = Vec::with_capacity(110);
slave.c = 0;
slave.buf_n = 0;
}
slave.end = true;
if timer.is_interrupt_set() {
timer.clear_interrupt();
}
});
} It works fine except low speed (about 10kHz). |
Thanks for working on this! Regarding the interrupt-based implementation I guess we shouldn't include bit-banging protocol implementations in the HAL. Those could go into a 3rd party crate I guess |
Unfortunately, I was unable to figure out what was wrong with ESP32, but I've got ESP32S3, and now test SPI slave with it. I browsed through source code, and spotted strange check at |
By the way, current implementation of SPI slave for ESP32S3 is capable of handling insane clock speed of 10mHz. |
I think the intent is to make sure that all bits are clocked out on MOSI - but probably a good hint what to look at. Maybe just checking |
Now I see the reason: there is only one implementation of According to datasheet,
There is no exact information on whether it is fired when tx list is empty. But, as far as I understand, no transmission takes place when there is nothing to send, so I think, the problem can be solved by introducing different |
Please take a look at #1013 |
We're relatively close to the finish line here I think, so let's try to get this issue closed in the next few weeks/months if able :) I will mention this issue during our team meeting on Monday. |
Update: PR with S2 support #1562. I'm not sure about ESP32, we've spent long time on that but the thing doesn't work. |
(first of all, thanks for all the amazing progress with Rust support for the ESP32, it truly is amazing!)
I'm trying to build an ISP slave device using the ESP32, and of course I want to build it using Rust. However, it seems like there is no support fir this currently?
If I understand correctly, the SPI traits in embedded-hal is only for SPI master, and when slave traits will be added they will be separate and probably named spi_slave. ref: rust-embedded/embedded-hal#396. And as far as I understand, esp-hal is an implementation of embedded-hal?
It seems like the only way right now is to use Rust with the ESP IDF (e.g. using ), and then call the C functions (
spi_slave_initialize
,spi_slave_transmit
, etc.) via theesp_idf_sys
crate?If my understanding is correct, than this is a feature request to add SPI slave support. In either case, any pointers or guidance would be much appreciated!
The text was updated successfully, but these errors were encountered: