Skip to content
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 communication doesn't work #25

Open
wiktorwieclaw opened this issue Jan 8, 2023 · 6 comments · May be fixed by #43
Open

SPI communication doesn't work #25

wiktorwieclaw opened this issue Jan 8, 2023 · 6 comments · May be fixed by #43

Comments

@wiktorwieclaw
Copy link

The following code is not right, as it would require the data to be prepended with a dummy byte

impl<SPI, CS> SPIInterface<SPI, CS>
where
    SPI: Transfer<u8>,
    CS: OutputPin,
{
    fn read_any_register(
        &mut self,
        register: u8,
        data: &mut [u8],
    ) -> Result<(), Error<SPIError<SPI::Error, CS::Error>>> {
        self.cs
            .set_low()
            .map_err(|e| Error::Bus(SPIError::Pin(e)))?;
        self.spi
            .transfer(data, &[register])
            .map_err(|e| Error::Bus(SPIError::SPI(e)))?;
        self.cs
            .set_high()
            .map_err(|e| Error::Bus(SPIError::Pin(e)))?;
        Ok(())
    }
}

Spitting the transfer would do the job:

bus.write(&[register])?;
bus.read(data)
@VersBinarii
Copy link
Owner

Fixed with #23

@wiktorwieclaw
Copy link
Author

@VersBinarii I believe that #23 doens't fix the issue. The actual fix is this:

From:

self.spi
    .transfer(data, &[register])
    .map_err(|e| Error::Bus(SPIError::SPI(e)))?;

To:

self.device
    .transaction(|bus| {
        bus.write(&[register])?;
        bus.read(data)
     })

Please reopen the issue, I'll prepare a new, updated PR that resolves conflicts.

@VersBinarii VersBinarii reopened this Jan 16, 2023
@VersBinarii
Copy link
Owner

Have you tested it though?
I dont have the hardware on my desk to confirm it.
I'll get some by the end of the week.

@wiktorwieclaw
Copy link
Author

wiktorwieclaw commented Jan 16, 2023

@VersBinarii Yup. I'll test it again on Wednesday just to be sure.

For now I could try to explain why the current approach doesn't work.

Look at impl of transfer from stm32f4xx_hal:

fn transfer(&mut self, buff: &mut [W], data: &[W]) -> Result<(), Self::Error> {
    assert_eq!(data.len(), buff.len());

    for (d, b) in data.iter().cloned().zip(buff.iter_mut()) {
         nb::block!(<Self as FullDuplex<W>>::write(self, d))?;
         *b = nb::block!(<Self as FullDuplex<W>>::read(self))?;
     }

     Ok(())
}

Let's say we want to read 3 bytes from address 0xb7. For each byte we want to read, we need to provide a dummy byte to write. So, something like this wouldn't work:

let write = [0xb7];
let mut read = [0x00; 3];
spi.transfer(&write, &mut read)

If we really want to use transfer method, we shall do this:

let write = [0xb7, 0x00, 0x00, 0x00];
let mut read = [0x00, 0x00, 0x00, 0x00];
spi.transfer(&write, &mut read);

let response = &read[1..];

HAL_SPI_TransmitReceive from the C HAL works exactly same.

Note that I didn't use transfer in my PR to avoid slicing and copying the response from the read buffer.

@VersBinarii
Copy link
Owner

I see, you're correct.
Feel free to make a PR then if you wish 😁 If not i'll look at fixing this later this week.

@wiktorwieclaw
Copy link
Author

FYI, I connected everything today, but I'll finish the PR tomorrow :P

fredszaq added a commit to fredszaq/bme280-rs that referenced this issue Nov 17, 2024
This fixes VersBinarii#25.

Any try to call the `init` function will fail with an `UnsupportedChip`
error without this (using the defautl `sync` feature).

Previous attempts were made to fix this (VersBinarii#28 and VersBinarii#38) but these where
made before `embedded-hal` `1.0.0` and currently have conflicts
preventing their merge (and can't directly be used in a project using
`embedded-hal` `1.0.0`

closes VersBinarii#28
@fredszaq fredszaq linked a pull request Nov 17, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants