this post was submitted on 03 Aug 2023
8 points (90.0% liked)

Embedded

443 readers
1 users here now

This sub is dedicated to discussion and questions about embedded systems: "a controller programmed and controlled by a real-time operating system (RTOS) with a dedicated function within a larger mechanical or electrical system, often with real-time computing constraints."

founded 1 year ago
MODERATORS
 

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?

you are viewing a single comment's thread
view the rest of the comments
[โ€“] exocortex@discuss.tchncs.de 1 points 1 year ago (1 children)

Hi, Thank you. It took me a while, but I experimented around a little bit. I have not yet tried to fix the max7219-library though. I think it is from_be_bytes (the other one didn't work).

But one thing that I am not understanding (I think this is a "can't tell the forest from the trees"-situation) is how exactly multiple 8x8-matrices are connected i.e. how the data-stream looks exactly.

In your example (from the max7219-library) it seems like if I use 4 devices I send 4 times a u16 out and the 4 connected Max7219's figure out themselves which one is meant?

[โ€“] orclev@lemmy.world 1 points 1 year ago

So it took me a little while to figure out between reading the datasheet for the Max7219 and looking at the source code. Basically it's taking advantage of a feature of the Max7219 that allows daisy chaining multiple chips off the same SPI connection. In order to take advantage of this feature you would take N Max7219 chips and wire all their CS and CLK pins together with your controller, and then run the connection from the controller to the first chips DIN port, and then the DOUT port from the first chip to the DIN port of the next chip. Keep chaining DOUT to DIN to daisy chain all the chips together.

In the datasheet for the Max7219 there's this section:

For the MAX7219, serial data at DIN, sent in 16-bit packets, is shifted into the internal 16-bit shift register with each rising edge of CLK regardless of the state of LOAD. For the MAX7221, CS must be low to clock data in or out. The data is then latched into either the digit or control registers on the rising edge of LOAD/CS. LOAD/CS must go high concurrently with or after the 16th rising clock edge, but before the next rising clock edge or data will be lost. Data at DIN is propagated through the shift register and appears at DOUT 16.5 clock cycles later

Essentially what that all boils down to, is that each Max7219 maintains a 16 bit internal shift register, so as each bit is received on DIN it's pushed onto the register, and the highest bit of the register gets pushed out to DOUT. When you daisy chain multiple chips together it's effectively like concatenating all their shift registers together. So if you have 4 chips, that's 64 bits of register. If you write 64 bits out to MOSI the first 16 bits will end up on the farthest out chip, the next 16 in the next closest, etc. Switching the CS pin from low to high is the trigger for the Max7219 to actually lock in and read the contents of those shift registers. The way the driver crates code is structured that's the purpose of the buffer field in the various Connector structs. So if you have say 4 chips, you need 4 x u16 storage, and each write cycle you write all 4 u16 values out, one to each daisy chained device. Technically the driver is less efficient than it could be, in that it takes advantage of the fact that writing 0 to a chip is a no-op, so in practice while it does write to every device each time, when you call write_raw it actually 0s the buffer for all but the selected chip.

If you think about a sequence of chips, lets say once again 4 of them labeled A to D. They would be connected like so:

RP-Pico-MOSI----DIN-A-DOUT----DIN-B-DOUT----DIN-C-DOUT----DIN-D-DOUT
       -CS----------CS------------CS------------CS------------CS
       -CLK---------CLK-----------CLK-----------CLK-----------CLK

Then you write to all four chips like so:

  • Set CS low
  • Write u16 for D
  • Write u16 for C
  • Write u16 for B
  • Write u16 for A
  • Set CS high