/*
  7seg.c
  Sample of C code to use a mikroElektronika Serial 7-seg Display module
  with the Acme Systems FOX Board LX. 

  http://www.acmesystems.it/?id=71  

  Based on the C example code provided by Mikroelektronika.
*/


#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "sys/ioctl.h"
#include "fcntl.h"
#include "time.h"
#include "string.h"
#include "linux/gpio_syscalls.h"

#define CS_HI gpiosetbits(PORTG,PG1)
#define CS_LO gpioclearbits(PORTG,PG1)
#define SCK_HI gpiosetbits(PORTG,PG3)
#define SCK_LO gpioclearbits(PORTG,PG3)
#define DIN_HI gpiosetbits(PORTG,PG4)
#define DIN_LO gpioclearbits(PORTG,PG4)


void SPI_init(void) {
  CS_HI;    
  SCK_LO;    
  DIN_LO;    
}

void SPI_write(unsigned char value) {
  int i;
  for (i=7;i>=0;i--) {
    if (value&(1<<i)) {
      DIN_HI;
    } else {
      DIN_LO;
    }
    SCK_HI;    
    SCK_LO;    
  }
}

void max7219_init1() {
  CS_LO;
  SPI_write(0x09);             // BCD mode for digit decoding
  SPI_write(0x5F);
  CS_HI;

  CS_LO;
  SPI_write(0x0A);
  SPI_write(0x0F);             // Segment luminosity intensity
  CS_HI;

  CS_LO;
  SPI_write(0x0B);
  SPI_write(0x07);             // Display refresh
  CS_HI;

  CS_LO;
  SPI_write(0x0C);
  SPI_write(0x01);             // Turn on the display
  CS_HI;

  CS_LO;
  SPI_write(0x00);
  SPI_write(0xFF);             // No test
  CS_HI;
}

void display_number(unsigned int data) {

  CS_LO;
  SPI_write(4);                // send Thousands digit
  SPI_write(data/1000);
  CS_HI;

  CS_LO;
  SPI_write(3);                // send Hundreds digit
  SPI_write((data/100)%10);
  CS_HI;

  CS_LO;
  SPI_write(2);                // send Tens digit
  SPI_write((data/10)%10);
  CS_HI;

  CS_LO;
  SPI_write(1);                // send Ones digit
  SPI_write(data%10);
  CS_HI;
}


int main(int argc, char **argv) {
  int cnt;

  SPI_init();
  max7219_init1();             // initialize  max7219
  
  for (cnt=0;cnt<10000;cnt++) {
    display_number(cnt);
    usleep(1000);
  }


  return(0);
}

