/* 
2010-08-10
Adjusting the display chip to show output when it receives something on the 2-wire serial bus.

I'll stick it at address 0x10, as a slave.

BYTE COMMANDS:

(76)(543210)
bits 76 = 00 - special command
	  01 - digit 1 (command is the digit value)
	  10 - digit 2
	  11 - digit 3
bits (543210) - command
 */

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 8000000UL/8UL
#include <util/delay.h>

#include "new_driver.h"

/* Need some functions to build numbers for the display. */

void display_number(unsigned int x){
  /* assuming ports C and D are properly set up */
  /* get the digits */
  unsigned char d0,d1,d2,t1;
  if(x>999) d0 = d1 = d2 = 10;
  else{
    d2 = x / 100;
    t1 = x % 100;
    d1 = t1 / 10;
    d0 = t1 % 10;
  };
  /* build the portout */
  set_digits(d2,d1,d0);

}

/* Two Wire Interface initialisation tasks */
void init_twi(void){
	/* set options:
		enable acknowledge
		enable interrupt
		enable device
	*/
	TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);
	/* set address:
		I don't think I care about 'general call' right now.
	*/
	TWAR = 0x10<<1;
	TWAMR = 0;
}

int main(void){
  /* Go to 8 MHz */
  CLKPR = _BV(CLKPCE);
  CLKPR = 0;
  /* ports C and D to output */
  DDRC = 0xff;
  DDRD = 0xff;
  DDRB = 0xff;
  PORTB = 0;
  PORTC = 0;
  PORTD = 0;

  DDRC = 0;
  PORTC = 0;
  init_driver();
  init_twi();
  sei();
  set_smile();
  while(1){
  }
  return 0;
}

/* translate ye olde byte into a command! */
void command(unsigned char c){
	switch(c>>6){
		case 0:	/* special commands */
			//only one for now 
			set_smile();
			break;
		case 1: /* digit 1 */
			set_digit_1(c & 0x3f);
			break;
		case 2: /* digit 2 */
			set_digit_2(c & 0x3f);
			break;
		case 3: /* digit 3 */
			set_digit_3(c & 0x3f);
			break;
		default: /* THE HELL */
			set_digits(DIGITE,DIGITR,DIGITR);
	}
};

/* Two Wire Interface interrupt handler */
ISR(TWI_vect){
 	/* check status : slave receiver mode */
	switch(TWSR & 0xf8){
		case 0x60:	/* received slave address, acknowledged */
		case 0x68:
			TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);
			break;
		case 0x70: /* general call */
		case 0x78:
			TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);
			break;
		case 0x80:  /* received a byte */
		case 0x88:
			command(TWDR);
			TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);
			break;
		case 0xA0:
			TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);
			break;
		/* misc states: ERROR */
		case 0x00:
			/* bus error */
			/*reset everything */
			set_digits(DIGITE,DIGITR,DIGITR);
			TWCR = _BV(TWSTO) | _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);
			break;
		default:
			display_number(888);
	}
}

