// TU WIEN - EMCE project ROBOCONTROL
// PIRI DANIEL e0825109
// Juny, 2010


#define F_CPU 8000000UL
#define UART_BAUD_RATE      9600      

#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/delay.h>
#include "uartlibrary/uart.h"
#include <util/twi.h>
#include <i2c.h>

uint8_t timer_scale = 250;	//7.8125/8 ms * 128 * 8 = 1s
uint8_t timer_f;
int8_t pos_sm[6];	//position of stepper motors 0-5
uint8_t scaler;
u08 localBuffer[6];
u08 localBufferLength=6;

uint8_t rotate_stepper(uint8_t motor, int16_t steps);
void i2cHandler(u08 receiveDataLength, u08* receiveData);

uint8_t speedmax[6] = {1, 2, 2, 2, 2, 1};
uint16_t absmax[6] = {700, 300, 400, 0, 0, 600};

//------------------------------------------------------------------------------------
SIGNAL(SIG_OVERFLOW1) {
//------------------------------------------------------------------------------------
	if (--scaler == 0){
		scaler = timer_scale;
		timer_f = 1;
	}
}

//------------------------------------------------------------------------------------
void i2cHandler(u08 receiveDataLength, u08* receiveData){
//------------------------------------------------------------------------------------
	u08 i;
	cbi(PORTB, PB6);
	// this function will run when a master somewhere else on the bus
	// addresses us and wishes to write data to us
	//  copy the received data to a local buffer
	for (i=0; i<receiveDataLength; i++)	{
		localBuffer[i] = *receiveData++;
	}
	localBufferLength = receiveDataLength;

	/*rotate_stepper(0, localBuffer[0]);*/
}

//------------------------------------------------------------------------------------
int main(void) {
//------------------------------------------------------------------------------------
    unsigned int c;
	int8_t rbl=6;
	
	DDRA = 0xFF;	//output all of PORTA
	DDRB = 0x5F;	//output all of PORTB expecting MOSI, SCK, (MISO protected by 180R)
	DDRC = 0xFF;	//output all of PORTC
	DDRD = 0xFA;	//output all of PORTD expecting RXD and PD2 (button)

	//uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 

	i2cInit();

	TCCR1B=0x01;	//no prescale .. 	7.8125ms
	TIMSK|=(1<<TOIE1);
	scaler = timer_scale;
    	sei();
 
	i2cSetLocalDeviceAddr(0x00,1);
 	i2cSetBitrate(100);
	i2cSetSlaveReceiveHandler(i2cHandler);


 	while (PIND&0x04);	//wait for pressing button

		//self test
	 	for (c=0; c<6; c++){
	 		rotate_stepper(c, 0-(absmax[c]/2));		
	 		rotate_stepper(c, absmax[c]);
			rotate_stepper(c, 0-absmax[c]/2); 
		}
 
 
 	
    
    while(1) {
         // Get received character from ringbuffer
	 // uart_getc() returns in the lower byte the received character and in the higher byte (bitmask) 
	 // the last receive error: UART_NO_DATA is returned when no data is available.
        c = uart_getc();
        if ( c & UART_NO_DATA ) { // no data available from UART; do something else
        }
        else {//byte available, check for Frame or Overrun error

            if ( c & UART_FRAME_ERROR ){
                // Framing Error detected, i.e no stop bit detected
                uart_puts_P("UART Frame Error: ");
            }
            if ( c & UART_OVERRUN_ERROR ) {
                 // Overrun, a character already present in the UART UDR register was 
                 // not read by the interrupt handler before the next character arrived,
                 // one or more received characters have been dropped
                uart_puts_P("UART Overrun Error: ");
            }
            if ( c & UART_BUFFER_OVERFLOW ){
                 // We are not reading the receive buffer fast enough,
                 // one or more received character have been dropped 
                uart_puts_P("Buffer overflow error: ");
            }

	    // send received character back
            uart_putc( (unsigned char)c );
	    rotate_stepper(0, 100, c);
	}
		


    }
    
}





//------------------------------------------------------------------------
uint8_t rotate_stepper(uint8_t motor, int16_t steps){
//------------------------------------------------------------------------
  ...
}

