MAX6954 with AVR MCU, using SPI. Code inside.

MAX6954 SPI requirements.

The MAX6954 is written to using the following sequence:

  1. Take CLK low.
  2. Take CS low. This enables the internal 16-bit shift register.
  3. Clock 16 bits of data into DIN, D15 first to D0 last, observing the setup and hold times. Bit D15 is low, indicating a write command.
  4. Take CS high (while CLK is still high after clocking in the last data bit).
  5. Take CLK low.

OR

PROBLEM:

SPI.h waits for CLK to finish. A flag is raised when the transfer is complete, THEN you are allowed to raise CS to finish the SPI communication. This is incomparable with what MAX6954 asks for.

SOLUTION:

Software serial. As long as MAX9654 receives it's data, it doesn't care how long it takes to get it. Driving LEDs is not a safety critical application so sending the right sequence of data matters more.

Turn off SPI (SPI.end(), SPI.endTransmission())

//Pin mapping for ATTiny167
#define CS1        14  // MAX6954
#define DATAOUT    11 // MOSI
#define DATAIN     12 // MISO
#define CLK        13 // sck


const byte DECODE             = 0x01;
const byte INTENSITY         = 0x02;
const byte ScanLIMIT          = 0x03;
const byte CONFIGURATION = 0x04;
const byte TEST                  = 0x07;
const byte DigitTYPE            = 0x0C;


void setup() {
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(CS1, OUTPUT);
  pinMode(CLK, OUTPUT);

  digitalWrite(CS1, HIGH);
  digitalWrite(DATAIN, HIGH);

  delay(40);

  send_first_8(TEST);
  send_seccond_8(0x01);

  delay(40);


}

void loop() {
  delay(1000);
}

/*FUNCTIONS*/

void chip_select_low(void) {
  digitalWrite(CS1, LOW);
}

void chip_select_high(void) {
  digitalWrite(CS1, HIGH);
}

void sclk() {
  digitalWrite(CLK, HIGH);
  digitalWrite(CLK, LOW);
}


void send_first_8(char data) {
  char abit;
  char index;
  chip_select_low();
  for (index = 7; index >= 0; index--) {
    abit = ((data >> index) & 0x01);
    if (abit == 1)
    {
      digitalWrite(DATAOUT, HIGH);
      sclk();
    } else {
      digitalWrite(DATAOUT, LOW);
      sclk();
    }
  }
}

void send_seccond_8(char data) {
  char abit;
  char index;
  for (index = 7; index >= 0; index--) {
    abit = ((data >> index) & 0x01);
    if (abit == 1)
    {
      digitalWrite(DATAOUT, HIGH);
    } else {
      digitalWrite(DATAOUT, LOW);
    }
    if (index == 0) {
      digitalWrite(CLK, HIGH);
    } else {
      sclk();
    }
  }
  chip_select_high();
  digitalWrite(CLK, LOW);
}

NECESSARY HARDWARE:

The data out line on the MAX is not high impedance. This means that when you attach it to your SPI lines it will interfere with an ISP. Series resistance as per Atmel's design guides is required.
If you do not care about receiving data from the MAX, just remove connection from the data out line. An open circuit is about as high impedance as you can get.

Testing mostly complete.

0x07 / 0x01 - Test mode on
0x07 / 0x00 - Test mode off

0x0C / 0xFF - Set all (eight or less) digits to use the 14-segment font map
0x04 / 0x01 - Exit shutdown mode, disable blinking and select global intensity control

Setting digit0 character.

These commands have been tested and currently work.

-Digits appear dim without attempts to change intensity.

0x02 0xFF - Set all digits to max brightness.

Tested and works.

Writing properly to 4 different digits.

Currently this solution is recommended for anyone in similar circumstances.

-Next will be testing for speed of communication.