//Gyöngyösi Balázs 
//2011.10.24
#include <msp430g2252.h>
#define CS BIT0
#define digit1 BIT1
#define digit2 BIT2
#define digit3 BIT3
#define digit4 BIT4

// required
#define SCL BIT4
#define SDA BIT5
#define READ 0xd1
#define WRITE 0xd0
#define FAILURE -1
#define SUCCESS 0

// required
void sendByte(void);
void receiveByte(void);
void sendAck(void);
void receiveAck(void);
void start(void);
void stop(void);

// required
unsigned char txData = 0;
unsigned char rxData = 0;
unsigned char ackFlag = 0;
unsigned char bitCounter = 0;
unsigned int address = 0; 

// optional
int writeChar(void);
int readChar(void);
int readCurrentChar(void);
int writeInt(void);
int readInt(void);

// optional
unsigned char charData = 0;
unsigned int intData = 0;
// óra változók
unsigned char hour1=0;
unsigned char hour2=0;
unsigned char min1=0;
unsigned char min2=0;
unsigned char sec1=0;
unsigned char sec2=0;
unsigned char fris=0;



// optional
int readCurrentChar(void) {
    start();
    txData = READ;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    receiveByte();
    ackFlag = 0;
    sendAck();
    stop();
    charData = rxData;
    return SUCCESS;
}
// optional
int readChar(void) {
    start();
    txData = WRITE;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    txData = address;
    sendByte();
    receiveAck();
    start();
    txData = READ;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    receiveByte();
    ackFlag = 0;
    sendAck();
    charData = rxData;
    stop();
    return SUCCESS;
}
// optional
int writeChar(void) {
    start();
    txData = WRITE;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    txData = address;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    txData = charData;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    stop();
    return SUCCESS;
}
// optional
int readInt(void) {
    start();
    txData = WRITE;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    txData = address;
    sendByte();
    receiveAck();
    start();
    txData = READ;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    receiveByte();
    ackFlag = 1;
    sendAck();
    intData = rxData;
    intData <<= 8;
    receiveByte();
    ackFlag = 0;
    sendAck();
    intData |= rxData;
    stop();
    return SUCCESS;
}

// optional
int writeInt(void) {
    start();
    txData = WRITE;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    txData = address;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    txData = intData >> 8;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    txData = intData;
    sendByte();
    receiveAck();
    if(!ackFlag)
        return FAILURE;
    stop();
    return SUCCESS;
}

// required
// send byte to slave
void sendByte(void) {
    P2DIR |= SDA;
    bitCounter = 0;
    while(bitCounter < 8) {
        (txData & BIT7) ? (P2OUT |= SDA) : (P2OUT &= ~SDA);
        P2OUT |= SCL;
        txData <<= 1;
        bitCounter++;
        P2OUT &= ~SCL;
    }
    P2OUT |= SDA;
    P2DIR &= ~SDA;
}
// required
// receive byte from slave
void receiveByte(void) {
    bitCounter = 0;
    while(bitCounter < 8) {
        P2OUT |= SCL;
        rxData <<= 1;
        bitCounter++;
        if(P2IN & SDA) {
            rxData |= BIT0;
        }
        P2OUT &= ~SCL;
    }
}
// required
// send master's ACK
void sendAck(void) {
    P2DIR |= SDA;
    (ackFlag) ? (P2OUT &= ~SDA) : (P2OUT |= SDA);
    P2OUT |= SCL;
    P2OUT &= ~SCL;
    P2OUT |= SDA;
    P2DIR &= ~SDA;
}
// required
// receive slave's ACK
void receiveAck(void) {
    P2OUT |= SCL;
    (P2IN & SDA) ? (ackFlag = 0) : (ackFlag = 1);
    P2OUT &= ~SCL;
}
// required
// start condition
void start(void) {
    P2OUT |= SCL;
    P2DIR |= SDA;
    P2OUT &= ~SDA;
    P2OUT &= ~SCL;
    P2OUT |= SDA;
    P2DIR &= ~SDA;

}
// required
// stop condition
void stop(void) {
    P2DIR |= SDA;
    P2OUT &= ~SDA;
    P2OUT |= SCL;
    P2OUT |= SDA;
    P2DIR &= ~SDA;
}


//spi.c
long data2 =0;
unsigned  s =700;
void spiInit(void) {
	  USICTL = USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE; //enable spi out, clock enable, MSB(leave unset), data output Enable
	  USICTL1 |= USIIE + USICKPH;             // Counter interrupt, flag remains set
      USICKCTL = USIDIV_1 + USISSEL_2;          // /16 ACLK
  	  USICTL0 &= ~USISWRST;                     // USI released for operation
      USICNT = 8;                   // init-load counter
//      _low_power_mode_0();            
}

void spiStart(void){
//  	  USICTL1 |= USIIE;
  	  USICTL0 &= ~USISWRST;                     // USI released for operation
}

void spiStop(void){
USICTL0 &= ~USISWRST;
//USICNT =1;
USICTL0 |= USISWRST; //turn off USI operation
}

void spiTx(unsigned char c) {
USICNT &= ~USI16B;
USISRL = c;
USICNT = 8;

}

void spiTxINT(unsigned int i) {
USICNT |= USI16B;				//set to use 16 bits, this may need to be set every time
USISR = i; //was USISRL
USICNT |= 0x10;	

//I want to send 16 bits worth of data, this sets usicnt4 to 1.
//USICNT =USI16B | 16;		//This is an alt method of setting usi16b and sending data //returns 0x640A ..this is correct!
//delay(1); //this isn't needed...clean up and use the usi interupt.
} 

unsigned char spiRx()
{
USICNT &= ~USI16B;
USICNT = 8;
 __low_power_mode_0();
return 	USISRL;
}

void enablePin(unsigned char bits)
{
	P1OUT &= ~bits;
}
 
void disablePin(unsigned char bits)
{
  P1OUT |= bits;
}
void delay(unsigned int ms)
{
 while (ms--)
    {
        __delay_cycles(50);
    }
}
void kirak (short seg,short digit)
{
  enablePin(CS);
        spiTx (seg);
       __delay_cycles(5);
        disablePin(CS);
       
        disablePin(digit);
        __delay_cycles(4400);   //bekapcsolva maradás ideje   // 34000
        enablePin(digit);
  
}
// szám karaktertábla
#define seg0 0xEE
#define seg1 0x48
#define seg2 0xBA
#define seg3 0xDA
#define seg4 0x5C
#define seg5 0xD6
#define seg6 0xF6
#define seg7 0x4A
#define seg8 0xFE
#define seg9 0xDE

const unsigned char number[10] = {
0xEE, 0x48, 0xBA, 0xDA, 0x5C, 0xD6, 0xF6, 0x4A, 0xFE, 0xDE
};


void nullaz (void) // óra, perc, másodperc nullázás 
{
address = 0;
      charData = 0 ;// set intData, we will save it
        writeChar(); // write intData to address 0 (2 bytes)
        //handle failure
         __delay_cycles(100); // delay for testing 
         address = 2;
      charData = 0 ;// set intData, we will save it
        writeChar(); // write intData to address 0 (2 bytes)
        //handle failure
         __delay_cycles(100); // delay for testing 
         address = 1;
      charData = 0 ;// set intData, we will save it
        writeChar(); // write intData to address 0 (2 bytes)
        //handle failure
         __delay_cycles(100); // delay for testing 
        
}
void kiiras(void)
{
 // hour
 address = 2; // set address to 0
        readChar(); // read int from address 0 (2 bytes)
        //handle failure, readInt will return FAILURE or SUCCESS, check before using intData, it might be corrupted
 hour1= (charData&0x30);
 hour1= hour1 >> 4;
 hour2= (charData&0xf);
 kirak  (number[hour1],digit1);
kirak  (number[hour2],digit2);

//min
  address = 1; // set address to 0
        readChar(); // read int from address 0 (2 bytes)
        //handle failure, readInt will return FAILURE or SUCCESS, check before using intData, it might be corrupted
 min1= (charData&0x70);
 min1= min1>>4;
 min2= (charData&0xf);
kirak  (number[min1],digit3);
kirak  (number[min2],digit4);
      }
// óra beállítás
void szam1fris(void)
{
address = 2; // set address to 0
        readChar(); // read int from address 0 (2 bytes)
        //handle failure, readInt will return FAILURE or SUCCESS, check before using intData, it might be corrupted
         address = 2;
charData = charData+16 ;// set intData, we will save it
        writeChar(); // write intData to address 0 (2 bytes)
        //handle failure
         __delay_cycles(5000); // delay for testing 
}

void szam2fris(void)
{
address = 2; // set address to 0
        readChar(); // read int from address 0 (2 bytes)
        //handle failure, readInt will return FAILURE or SUCCESS, check before using intData, it might be corrupted
         address = 2;
charData = charData+1 ;// set intData, we will save it
        writeChar(); // write intData to address 0 (2 bytes)
        //handle failure
         __delay_cycles(5000); // delay for testing 
}
void szam3fris(void)
{
address = 1; // set address to 0
        readChar(); // read int from address 0 (2 bytes)
        //handle failure, readInt will return FAILURE or SUCCESS, check before using intData, it might be corrupted
         address = 1;
charData = charData+16 ;// set intData, we will save it
        writeChar(); // write intData to address 0 (2 bytes)
        //handle failure
         __delay_cycles(5000); // delay for testing 
}
void szam4fris(void)
{
address = 1; // set address to 0
        readChar(); // read int from address 0 (2 bytes)
        //handle failure, readInt will return FAILURE or SUCCESS, check before using intData, it might be corrupted
         address = 1;
charData = charData+1 ;// set intData, we will save it
        writeChar(); // write intData to address 0 (2 bytes)
        //handle failure
         __delay_cycles(5000); // delay for testing 
}

void hourfris (void)
{

if (!(P2IN & BIT7)) szam2fris (),__delay_cycles(400000); 
else if  (!(P2IN & BIT0)) szam1fris  (),__delay_cycles(400000); 
else kiiras ();
}
void minfris (void)
{
if (!(P2IN & BIT6)) szam3fris (),__delay_cycles(400000);
else if  (!(P1IN & BIT7)) szam4fris  (),__delay_cycles(400000) ;
else kiiras ();
}
// óra beállítás vége


void main( void )
{
    WDTCTL = WDTPW + WDTHOLD; 
     P2SEL=0;
    P2OUT|= SCL;
    P2DIR=(0x0| SCL);   
P1DIR |= CS;
  P1DIR |= digit1+digit2+digit3+digit4;
    //P1DIR |= digit2;
     //P1DIR |= digit3;
     //P1DIR |= digit4;
    P1OUT=0;
    
    address = 0x08;
      charData = 0xB0 ;// set intData, we will save it
        writeChar(); // write intData to address 0 (2 bytes)
        //handle failure
         __delay_cycles(1000); // delay for testing 
         address = 0x09;
      charData = 0xA5 ;// set intData, we will save it
        writeChar(); // write intData to address 0 (2 bytes)
        //handle failure
         __delay_cycles(1000); // delay for testing 
   
  spiInit(); //get things going
  spiStop();	
	spiStart();
  //nullaz();

 while(1) 
    {
      hourfris();
      minfris();
   kiiras();
      }
   }








   



         
      
