help interfacing with max6960 led matrix

Anybody successuful interfacing themax6960 led matrix driver with arduino?

Could you please share your code?

Thanks in advance!

OK, I did some research, wrote my own code, and it works!
It´s a simple example of using Arduino to talk to the MAX6960

#define DATAOUT 11//MOSI
#define DATAIN  12//MISO 
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss
#define RESET 9 //reset

byte clr;

void setup()
{
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  pinMode(RESET,OUTPUT);

  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10); 

  digitalWrite(SLAVESELECT,HIGH);  
  digitalWrite(RESET,HIGH); 
  delay(5);  
  digitalWrite(RESET,LOW);
  delay(5);
  digitalWrite(RESET,HIGH);
  delay(200);
  //configurar registros aquí

//Panel Configuration Register
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x0d);
  spi_transfer(0x01);  
  digitalWrite(SLAVESELECT,HIGH);
    
//Panel Intensity Register    
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x02);
  spi_transfer(0x30);  
  digitalWrite(SLAVESELECT,HIGH);
  
//Number of Cascaded Devices Register  
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x0e);
  spi_transfer(0x03);  
  digitalWrite(SLAVESELECT,HIGH);
 
//Number of Display Rows Register  
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x0f);
  spi_transfer(0x01);  
  digitalWrite(SLAVESELECT,HIGH);

  delay (500);

  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x00);
  spi_transfer(0x00);
  spi_transfer(0x88);  
  digitalWrite(SLAVESELECT,HIGH);
while (1)
  {
  };
}

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void loop()
{
while (1);
  {
  };
}

Thanks for sharing the code!

I have tried to communicate with MAX6963 but to no avail. Do you actually know the difference between MAX6960/1/2/3 ?

One important thing when hooking it up to the Arduino is that you should put voltage dividers on all lines going to the MAX6960 since it runs on 3.3 volts! Signals going back to the Arduino are being interpreted correctly since +3.3 equals 1 also for the Arduino.

Did you work further on your code? As far as i can tell you are just initializing the chip. How would you actually light up the LEDs??

Would be good to receive also something from the chip itself.. like the device id for example:

uint8_t devid = (read16(0x8500) & 0x60) >> 5;

Thanks for your help
bye

I have tried to communicate with MAX6963 but to no avail. Do you actually know the difference between MAX6960/1/2/3 ?

I´m using the eval board from maxim.
From the manual:
The MAX6963 drives monocolor displays with two-step
intensity control. The MAX6962 drives monocolor displays
with two-step or four-step intensity control. The MAX6961
drives monocolor or RGY displays with two-step intensity
control. The MAX6960 drives monocolor or RGY displays
with two-step or four-step intensity control.

One important thing when hooking it up to the Arduino is that you should put voltage dividers on all lines going to the MAX6960 since it runs on 3.3 volts! Signals going back to the Arduino are being interpreted correctly since +3.3 equals 1 also for the Arduino.

oops, I didn´t consider the voltage levels,,,,however it works on 5v levels basis,,,, may be not for much time :wink:
I´m gonna add the dividers,,,,

Did you work further on your code? As far as i can tell you are just initializing the chip. How would you actually light up the LEDs??

I forgot to comment in the code the last write, but in fact, the last one, is a writing to light up two leds:

  //light up two leds, the first and the fifth, of the first row of the matrix
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x00);
  spi_transfer(0x00);
  spi_transfer(0x88);
  digitalWrite(SLAVESELECT,HIGH);

We have another version to write the entire four matrix of the evaluation board. Its just a while cycle, who receives data from the serial port, and, write to the correspondent address of the max6960.

Regards,,,

Hi Eeddgar,

I´m using the eval board from maxim.

O.k. So, now i understand why you are setting up 4xMax6960 in the Cascaded Device Register.

//Number of Cascaded Devices Register
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x0e);
  spi_transfer(0x03);
  digitalWrite(SLAVESELECT,HIGH);

I forgot to comment in the code the last write, but in fact, the last one, is a writing to light up two leds:

oh, i c :sunglasses:

the max chip is still not showing anything on my display... maybe i should also get an evkit board for trying out the code ... they seem to be not really easy available. you can buy them only directly through maxim, isn't it?

i was cleaning up your code a bit and put send/read functions for better overview.. could you try it out on your arduino? especially i am curious if the read functions are working!

#define DATAOUT 11      //MOSI
#define DATAIN  12      //MISO
#define SPICLOCK  13    //SCK
#define SLAVESELECT 10  //SS
#define RESET 9         //Reset

byte clr;

void spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR&_BV(SPIF))) { }
 }

uint8_t spi_receive() {
  uint8_t val = 0;
  SPDR = 0x00; // Start clock
  while (!(SPSR&_BV(SPIF))) { }
    val = SPDR;
  return val;
}

void write8(uint8_t payload) {
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(payload);
  digitalWrite(SLAVESELECT,HIGH);
}

void write16(uint16_t payload) {
  payload &= 0xEFFF; // zero out the factory reserved bit / datasheet page 11
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(payload>>8);
  spi_transfer(payload&0xff);
  digitalWrite(SLAVESELECT,HIGH);
}

void write24(uint32_t payload) {
  payload &= 0xEFFF; // zero out the factory reserved bit / datasheet page 11
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(payload>>16);
  spi_transfer(payload>>8);
  spi_transfer(payload&0xff);
  digitalWrite(SLAVESELECT,HIGH);
}

uint8_t read16(uint16_t payload) {
  write16(payload);
  return spi_receive();
}

uint8_t read24(uint32_t payload) {
  write24(payload);
  return spi_receive();
}

void setup()
{
  Serial.begin(9600);
  Serial.println("booting...");
  
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  pinMode(RESET,OUTPUT);

  // SPCR register
  // SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0
  //  D7  D6  D5   D4   D3    D2   D1   D0

  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);

  clr=SPSR;
  clr=SPDR;
  delay(10);

  digitalWrite(SLAVESELECT,HIGH);
  digitalWrite(RESET,HIGH);
  delay(5);
  digitalWrite(RESET,LOW);
  delay(5);
  digitalWrite(RESET,HIGH);
  delay(200);
 
  //Panel Configuration Register
  write16(0x0d01);

  //Panel Intensity Register
  write16(0x0230);

  //Number of Cascaded Devices Register
  write16(0x0e03);

  //Number of Display Rows Register
  write16(0x0f01);
  
  delay (500);

  //light up two leds, the first and the fifth, of the first row of the matrix
  write24(0x000088);
}

void loop()
{
while (1);
  {
  };

}

THUMBS UP ++ BIG THANKS for sharing your code :slight_smile:
ritzdank

I have some code for the MAX6960.

I've actually written a library for the Arduino and have been considering releasing it, but it's not been tested much on more than my own design which consists of:

2x MAX6960 maxtrix drivers
1x 8.1008 MHz oscillator
1x 74LVC244 buffer IC for signal level conversion from 5V to 3.3V
4x 8x8 LEDMS88R LED matrices from futurlec.com

The driver is kind of generic and should work with any of the MAX696x devices and I've gone to some effort to comment it well and make it simple to use and configure, but I stress again, I've not tested it beyond my own requirements and testing and it has only been tested on Arduino 12.

I've only used the MAX6960 in Mono mode but I have managed to get all the display driver features working (eg pixel intensity control, automatic frame switching etc) and even found a bug in the MAX6960 in the process! I found that when I enable the MUX FLIP bit in the Global Panel Configuration register, all the data displayed by the 2nd MAX6960 is rotated through one bit. Very confusing for a while but Maxim have confirmed it as a bug in the chip, so just disable MUX FLIP to fix it.

But I need to take another look at the driver again before I release it to make sure it's in a working state... I haven't used it for a few months now. I also have a character set I created to work with the display which I should release along with it...

Stay tuned...