The Max 7219 chip communicates using SPI. The last time I used it I had apparently written my own bit-banging SPI routine in the Arduino IDE. Which works just fine (the SPI protocol being so simple) but it seems clunky. And since the ATTiny2313 has a built-in USI (Universal Serial Interface) capable of doing SPI I thought I might as well use that.
After a bit of Googling and reading of the datasheet, this is what I came up with:
#define PIN_LOAD PB4 // Utitlity method to shift 8 bits out the USI pins in 3-wire (SPI) mode static unsigned char spiByte(unsigned char val) { USIDR = val; // Set data byte to send USISR = (1<<USIOIF); // Clear Counter Overflow Interrupt Flag (by writing 1 to the USIOIF bit) do { USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC); // 3-wire mode; shift reg. clock source: external pos. edge; 4-bit counter source: USITC; Toggle USICK pin 0->1 or 1->0 (shift register will only clock on 0->1) } while ((USISR & (1<<USIOIF)) == 0); // Check for OIF set which will happen after 16 cycles. I.e. 8 bits since the clock toggles twice per bit. return USIDR; // Return data value } void sendToMax7219( char reg, char value ) { PORTB &= ~(1 << PIN_LOAD); // LOAD low spiByte( reg ); spiByte( value ); PORTB |= (1<<PIN_LOAD; // LOAD high }