Coder Social home page Coder Social logo

Comments (20)

jonahbron avatar jonahbron commented on September 25, 2024

SPIF is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively, the SPIF bit is cleared by first reading the SPI status register with SPIF set, then accessing the SPI data register (SPDR).

It seems like something is happening before the flush method is called that's clearing the interrupt flag. I tried disabling the interrupt (SPIE) but that didn't change the behavior.

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

Some more reading through section 17.1.2 made me realize I might be causing a conflict on the SS pin. I tried disconnecting everything, and now it's actually returning. However it doesn't seem to be reading any data back. Still debugging.

from avr-hal.

lights0123 avatar lights0123 commented on September 25, 2024

Did the SPI feedback example work for you?

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

@lights0123 That's what I'm going to try next.

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

Hmmm, yup, the example worked perfectly. Must be something else.

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

Figured it out. The CS pin must be set to output mode before SPI is initialized. The example does that and it works fine, but my code was setting it to output mode after. All good!

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

Also for future reference, I had written code like this:

block!(spi.send(0).and_then(|_| { spi.read() }))?

This is incorrect because it will retry the entire expression if the read blocks at all, which causes it to re-send, creating an infinite loop of writing and retrying. The correct syntax is

block!(spi.send(0)).and_then(|_| { block!(spi.read()) })?

from avr-hal.

Rahix avatar Rahix commented on September 25, 2024

Figured it out. The CS pin must be set to output mode before SPI is initialized. The example does that and it works fine, but my code was setting it to output mode after. All good!

This is an ugly detail that one can easily step over :/ Maybe we can handle this in avr-hal in a way that downstream code can't do it wrong?

from avr-hal.

Rahix avatar Rahix commented on September 25, 2024

image

So the peripheral is probably immediately reset into slave mode in the case of configuring CS afterwards ... I think this is definitely something the HAL should handle.

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

We could accept a borrow of the CS pin as an argument and set its mode. Then the user would still have ownership.

from avr-hal.

lights0123 avatar lights0123 commented on September 25, 2024

@jonahbron setting the mode is done by transferring ownershipβ€”into_output takes ownership of the pin and returns a new struct that only has output features.

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

Ah okay, so it would need to pass back out an OutputPin. The only way I know of to do that is for the constructor to return a tuple.

from avr-hal.

Rahix avatar Rahix commented on September 25, 2024

I think we can't avoid moving the CS pin into the SPI device (and keeping it there). Any other way would leave open the possibility that a user later changes the pin's mode again. And this would immediately break the SPI device ...

Though of course the pin needs to be accessible to the user, for setting its state. We can either provide methods on the SPI device for that, or add a method that returns a reference to the pin:

// Either
pub fn cs_set_high(&mut self) { self.cs.set_high() }
pub fn cs_set_low(&mut self) { self.cs.set_low() }

// Or
pub fn cs(&mut self) -> &mut $CsType { &mut self.cs }

I think both approaches would be sound.

from avr-hal.

Rahix avatar Rahix commented on September 25, 2024

Ah, but users probably want to move the CS pin into a driver ... So we'll need to somehow allow the user to own the pin but in a way where they can't modify its mode. I think the only feasible way to archieve this is with a wrapper type:

pub struct CsPin($CsType);

impl OutputPin for CsPin {
    // ...
}

impl Spi {
    pub fn new(peripheral: ..., cs: $CsType) -> (Spi, CsPin) {
        // ...
        (Spi { ...}, CsPin(cs))
    }
}

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

I think that's a great idea. If we take that approach, we still need a way to unwrap it if the user decides they don't want SPI active anymore. Maybe...

impl Spi {
            pub fn release(self, cs: CsPin) -> (Spi, SCLK, MOSI, MISO) {
                self.peripheral.spcr.write(|w| {
                    w.spe().clear_bit()
                });
                (self.peripheral, self.sclk, self.mosi, self.miso, cs.0)
            }
}

Although, it's possible that if a chip had two SPI peripherals, the user could use one to falsely unwrap the CS pin from another. So it's not 100% safe.

from avr-hal.

Rahix avatar Rahix commented on September 25, 2024

Although, it's possible that if a chip had two SPI peripherals, the user could use one to falsely unwrap the CS pin from another.

We can prevent that by creating separate wrapper types for each SPI peripheral. So I think this approach looks like the way to go!

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

Excellent point. I'll get to work on it.

from avr-hal.

Rahix avatar Rahix commented on September 25, 2024

@jonahbron, are you still interested in working on this or should someone else take up this issue?

from avr-hal.

jonahbron avatar jonahbron commented on September 25, 2024

I am but I forgot about it 😁 . Github doesn't do a great job of floating assigned issues up to your attention.

from avr-hal.

Rahix avatar Rahix commented on September 25, 2024

No problem! Just need to know whether I should keep you assigned or not ;)

from avr-hal.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.