I’m trying to run an LED matrix display (with a Max7219 controller) from a raspberry pi pico using rust. There is a max7219-crate that I used. But i am unsure about how to prepare the pins I want to use. Can I Use any of the pins? Do I have to set them to push-pull-output?

  • orclev@lemmy.world
    link
    fedilink
    English
    arrow-up
    1
    ·
    1 year ago

    Just one other question regarding multiple displays: as e.g. 4 displays requires 4x16bits does this mean that there would have to be a Write-trait implemented somewhere (or Write<[u16;4]>)?

    Nope. The Write trait is indicating the size of the “packet” that’s written on the SPI bus, it’s the equivalent of the DS generic off the Spi struct. The way SPI works is, when you toggle CS low, the device is notified that it needs to start listening on MOSI, at which point you’re free to start sending it packets. There’s no requirement that you only send a single packet, you can send as many as you want, however many devices will have special rules about processing with respect to the state of the CS pin. E.G. just like with the Max7219 it’s common for devices to buffer commands and not actually process them until CS is sent high.

    The only reason why the Write and the Spi generic are important is because it defines the minimum number of bits that will be written to the bus (or more concretely it’s the stride size the SPI controller uses when reading and writing from its buffers). That’s why using u8/8 as the parameter mostly works except for occasionally demonstrating strange behavior. Using u16 guarantees that it always writes a number of bits that’s a multiple of 16, while using u8 can allow for essentially a half packet to be written.

    As for bit banging vs. SPI controller, it’s essentially the same thing as DMA if you’re familiar with that concept. Using bit banging the CPU is spending time toggling the various pins off and on, which although fast, is still relatively slow by communication standards and puts an upper limit on the speed data is transmitted on the SPI bus that’s directly tied to the frequency of the CPU and the number of cycles it takes to toggle a pin (minimum two pin toggles, maybe one for MOSI, two for CLK). Using the SPI controller on the other hand, the CPU writes bytes into memory and then passes essentially a couple of pointers to the SPI controller then flips some bits in a register. The CPU does need to pause occasionally to refill the buffers, but that’s a relatively fast operation and is mostly decoupled from the actual bus speed of SPI.

    Manually implementing SPI with bit banging is probably a good learning exercise, but understanding how to properly use the SPI controller is also good to know. For an extra challenge you can usually also setup the SPI buffer to be managed using DMA for the most optimal way to handle things. I would suggest configuring a u16 buffer sized based on the number of devices and then using DMA to write its contents out using the SPI buffer would be a very educational exercise.