-
I have a project with an Arduino Uno, an ethernet shield (v1), and an OV5642 SPI/I2C. There are actually 3 SPI peripherals in this setup, because the ethernet shield includes an SD card reader. The CS pins in use are The current SPI implementation does not easily allow for use of SPI devices using a channel select pin other than 10. The avr-hal/mcu/atmega-hal/src/spi.rs Line 25 in e897783 PB2 (pin 10). If a user attempts to create their own type
The following error occurs:
How can I use the SPI functionality for multiple devices? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
I have prototyped an alternate SPI implementation by modifying the code that already exists to allow the channel-select and SCLK/MOSI/MISO pins to exist separately until it is time to transmit/receive data. https://github.com/mutantbob/arduino-spi I look forward to folks proposing improvements, but the old SPI implementation is definitely not usable. |
Beta Was this translation helpful? Give feedback.
-
I think you've misunderstood how the First of all, the chip select pin you pass to the constructor does not need to be used as a CS pin. In fact, CS management is meant to be handled entirely outside the Now, to actually do chip select operation, peripheral drivers currently need to contain their own manual implementation. The pattern is to consume a pub struct MyPeripheralDriver<SPI, CSPIN> {
bus: SPI,
cs: CSPIN,
}
impl<SPI, CSPIN> MyPeripheralDriver<SPI, CSPIN>
where
SPI: blocking::spi::Write<u8>, CSPIN: OutputPin,
{
pub fn do_something(&mut self) {
self.cs.set_low();
self.bus.write(&[0xc0, 0xff, 0xee]);
self.cs.set_high();
}
} This of course consumes the let spi = Spi::new(...);
let spibus = shared_bus::BusManagerSimple::new(spi);
let cs1 = pins.d10.into_output();
let driver1 = Driver1::new(spibus.acquire_spi(), cs1);
let cs2 = pins.d6.into_output();
let driver2 = Driver2::new(spibus.acquire_spi(), cs2); That said, this pattern has a number of issues related to concurrency. That's why there is a move towards a new design, as proposed upstream in rust-embedded/embedded-hal#351. With this, CS management is finally moved out of the peripheral driver and will be handled at the layer where |
Beta Was this translation helpful? Give feedback.
I think you've misunderstood how the
Spi
bus driver is meant to be used.First of all, the chip select pin you pass to the constructor does not need to be used as a CS pin. In fact, CS management is meant to be handled entirely outside the
Spi
bus driver. The reason you have to pass the CS pin to the constructor (and then receive it back) is that the hardware requires the pin to be an output. If it is not, the spi peripheral does not actually work - it will switch to slave mode instead of operating as bus master. You can read up more on this in issue #27. Again, this is the only reason for passing this pin to the constructor at all.Now, to actually do chip select operation, peripheral dr…