You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using multiple SPI slaves with an STM32f091RB, I encounter the following problem:
When I change the SPI configuration to MODE_1 and then back to MODE_0, this results in an extra clock cycle, which leads to corrupt data when the CS pin is software controlled. (see code and screenshots below).
// Prepare two SPI configurations, MODE_0 and MODE_1letmut config_mode0 = embassy_stm32::spi::Config::default();
config_mode0.frequency = DOWNSTREAM_SPI_FREQ;
config_mode0.mode = embassy_stm32::spi::MODE_0;letmut config_mode1 = embassy_stm32::spi::Config::default();
config_mode1.frequency = DOWNSTREAM_SPI_FREQ;
config_mode1.mode = embassy_stm32::spi::MODE_1;let cs_pin = Output::new(p.PC9,Level::High,Speed::Low);letmut spidev_with_cfg = SpiDeviceWithConfig::new(spi_bus, cs_pin, config_mode0);// First set the SPI config to MODE_1
spi_bus.lock(|rc_bus| {letmut bus = rc_bus.borrow_mut();// When the following line is commented out, we get the expected behavior.// Only when we temporarily switch to MODE_1, an extra clock cycle is visible in the data
bus.set_config(&config_mode1);});// Then send data using the device (with MODE_0)
spidev_with_cfg.transfer_in_place(&mut[64u8,0,0]);
When the line bus.set_config(&config_mode1); is active, e.g. we temporarily switch to a different SPI mode (without sending any actual data)
When the line is commented out and we never change the SPI config, or when we disable and re-enable the SPI bus between setting the configs:
Workaround
A potential workaround is to change the code in Spi::set_config such that it disables and re-enables the SPI peripheral after applying the configuration change. For example, the following alteration of Spi::set_config seems to fix the problem:
#[cfg(any(spi_v1, spi_f1, spi_v2))]
self.info.regs.cr1().modify(|w| {
w.set_spe(false); // Temporarily disable SPI
w.set_cpha(cpha);
w.set_cpol(cpol);
w.set_br(br);
w.set_lsbfirst(lsbfirst);
});
// After applying a cpha or cpol change, we disable and re-enable the SPI peripheral
// because otherwise the SPI peripheral behaves weirdly for software-managed CS pins.
#[cfg(any(spi_v1, spi_f1, spi_v2))]
self.info.regs.cr1().modify(|w| {
w.set_spe(true); // Re-enable SPI
});
Is this behavior known or documented somewhere?
Or should I open a pull request with the described workaround?
The text was updated successfully, but these errors were encountered:
When using multiple SPI slaves with an STM32f091RB, I encounter the following problem:
When I change the SPI configuration to
MODE_1
and then back toMODE_0
, this results in an extra clock cycle, which leads to corrupt data when the CS pin is software controlled. (see code and screenshots below).When the line
bus.set_config(&config_mode1);
is active, e.g. we temporarily switch to a different SPI mode (without sending any actual data)When the line is commented out and we never change the SPI config, or when we disable and re-enable the SPI bus between setting the configs:
Workaround
A potential workaround is to change the code in
Spi::set_config
such that it disables and re-enables the SPI peripheral after applying the configuration change. For example, the following alteration ofSpi::set_config
seems to fix the problem:Is this behavior known or documented somewhere?
Or should I open a pull request with the described workaround?
The text was updated successfully, but these errors were encountered: