#define OP_NOOP   0
#define OP_DIGIT0 1
#define OP_DIGIT1 2
#define OP_DIGIT2 3
#define OP_DIGIT3 4
#define OP_DIGIT4 5
#define OP_DIGIT5 6
#define OP_DIGIT6 7
#define OP_DIGIT7 8
#define OP_DECODEMODE  9
#define OP_INTENSITY   10
#define OP_SCANLIMIT   11
#define OP_SHUTDOWN    12
#define OP_DISPLAYTEST 15


int CLK = 13;
int LOAD = 12;
int DIN_L = 11;
int DIN_R = 10;


void maxLoad()
{
  digitalWrite(LOAD, HIGH);
  digitalWrite(LOAD, LOW);
}



void sendData( byte address_L, byte data_L, byte address_R, byte data_R)
{
  byte packet_L[2];
  byte packet_R[2];
  byte bitmask;
  byte i;
  packet_L[0] = address_L;
  packet_L[1] = data_L;
  packet_R[0] = address_R;
  packet_R[1] = data_R;

  for (i = 0; i < 2; i++)
    for ( bitmask = 0x80 ; bitmask != 0 ; bitmask = bitmask >> 1 )
    {
      if (bitmask & packet_L[i]) digitalWrite(DIN_L, 1);
      else digitalWrite(DIN_L, 0);
      if (bitmask & packet_R[i]) digitalWrite(DIN_R, 1);
      else digitalWrite(DIN_R, 0);

      digitalWrite(CLK, HIGH);
      digitalWrite(CLK, LOW);
    }
}

void clearDisplay()
{
  for (int i = 0; i < 8; i++)
  {
    for (int j = 0; j < 4; j++)  sendData(i + 1, 0, i + 1, 0);
    maxLoad();
  }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(DIN_L, OUTPUT);
  pinMode(DIN_R, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(LOAD, OUTPUT);
  digitalWrite(LOAD, LOW);
  Serial.begin(57600);

  for (int i = 0; i < 4; i++) sendData(OP_DISPLAYTEST, 0,OP_DISPLAYTEST, 0); 
  maxLoad();
  for (int i = 0; i < 4; i++)  sendData(OP_INTENSITY, 0,OP_INTENSITY, 0); 
  maxLoad();
  for (int i = 0; i < 4; i++)  sendData(OP_SCANLIMIT, 7,OP_SCANLIMIT, 7); 
  maxLoad();
  for (int i = 0; i < 4; i++)  sendData(OP_DECODEMODE, 0,OP_DECODEMODE, 0); 
  maxLoad();
  for (int i = 0; i < 4; i++)  sendData(OP_SHUTDOWN, 1,OP_SHUTDOWN, 1); 
  maxLoad();  
  
}

uint16_t Matrix[32]={
  0xAA01,
  0x5502,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000,
  0x0000
};

void displayMatrix()
{
   uint16_t bm=0x8000;
   uint8_t row=8;
   while(bm!=0x0010)
   {
       for(int d=0;d<4;d++)
       {
            uint8_t pck_L=0;
            uint8_t pck_R=0;
            for(int j=0;j<8;j++)
            {
               if(Matrix[d*8+j]&bm) pck_L=pck_L|(0x01<<j);
               if(Matrix[d*8+j]&(bm>>8)) pck_R=pck_R|(0x01<<j);
            }
            sendData(row, pck_L, row,pck_R );
       }
    row--;
    bm>>=1;
    maxLoad();
   }
}

void loop() {
  // put your main code here, to run repeatedly:
  clearDisplay();
  Matrix[31]=0xAB04;
  displayMatrix();
  delay(1000);
  clearDisplay();
  delay(1000);
}