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?

  • exocortexOP
    link
    fedilink
    English
    arrow-up
    1
    ·
    1 year ago

    Thank you.

    Ive actually read the section you quoted a few times and my brain just couldn’t parse it. But i finally understand how the max7219 makes this. I’ve thought about it completely wrong. It just shifting through all the bits from chip to chip so obvious now.

    I think i will go a step back and not use spi for a while and just do the bit-banging -thingy first to get more familiar first.

    I’ve read somewhere that Is faster and I guess it’s cheaper for the cpu to use as the cpu doesn’t have to set the pin outs high or low with each cycle. Instead (i guess) the cpu can simply call a spi-out-funtctio one time and the spi does its thing for a while while the cpu can do other things.

    But right now I don’t do much yet on the rest of the CPU, so i can afford to do it manually.

    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]>)?

    could it be that the max7219-crate is incomplete here? The write-funtion you corrected seems like it was copied 1to1 from the cpp-lib (LedControl).

    • 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.