//SMbus je zapojeno takto: SMBdata=portD,3(int1); SMBclk=portD,4
//USB je zapojeno takto: USB_D+=portD,0; USB_D-=portD,2(int0)
//pokud nepracuje tak jak má, nastavit optimalizace na O2
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#define F_CPU 12000000UL
#include "util/delay.h"
#include <avr/pgmspace.h>
//#include <avr/eeprom.h>
#include "usbdrv/usbdrv.h"
#include "usbdrv/oddebug.h"

#include "SMbus.h"



extern uchar address1,address2,acknowledge, block[20],checksum;

static uchar    currentPosition,bytesRemaining;
static uchar 	prijata_data[5]={0,1,0,0};
static uchar	odeslana_data[4] = {55,42,8};
volatile static uchar prijata=0;
uchar vysledek=0;

PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH]={/* USB report descriptor */
 	0x06, 0x00, 0xff,              // USAGE_PAGE (Generic Desktop) 
    0x09, 0x01,                    // USAGE (Vendor Usage 1) 
    0xa1, 0x01,                    // COLLECTION (Application) 
    0x19, 0x01,                    //   USAGE_MINIMUM (0) 
    0x29, 0x03,                    //   USAGE_MAXIMUM (3) 
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0) 
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255) 
    0x75, 0x08,                    //   REPORT_SIZE (8) 
    0x95, 0x03,                    //   REPORT_COUNT (3) 
    0x81, 0x02,                    //   INPUT (Data,Var,Abs) 
    0x19, 0x01,                    //   USAGE_MINIMUM (0) 
    0x29, 0x03,                    //   USAGE_MAXIMUM (3) 
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0) 
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8) 
    0x95, 0x03,                    //   REPORT_COUNT (3)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs) 
    0xc0                           // END_COLLECTION

};

//-------------------------------------------------------------------------

ISR(TIMER0_OVF_vect){
		
}

//----------------------------------------------------------------
uchar   usbFunctionWrite(uchar *data, uchar len)  //zápis přijatých dat do bufferu
{
 uchar i;
    if(len > bytesRemaining)                // if this is the last incomplete chunk
    	len = bytesRemaining;               // limit to the amount we can store
    bytesRemaining -= len;
	prijata=1;
    for(i = 0; i < len; i++)
        prijata_data[currentPosition++] = data[i];
    return bytesRemaining == 0;             // return 1 if we have all data
}

/* ------------------------------------------------------------------------- */

usbMsgLen_t usbFunctionSetup(uchar setupData[8]) //přicházejí data
{
  
    usbRequest_t *rq = (void *)setupData;   			// cast to structured data for parsing
    switch(rq->bRequest){
		case USBRQ_HID_SET_REPORT:
    	    currentPosition = 0;                		// initialize position index
    	    bytesRemaining = rq->wLength.word;  		// store the amount of data requested
    	    if(bytesRemaining > sizeof(prijata_data)) 	// limit to buffer size
     	       bytesRemaining = sizeof(prijata_data);
       		return USB_NO_MSG;        					// tell driver to use usbFunctionWrite()
    }
    return 0;                               			// ignore all unknown requests
} 



// ------------------------------------------------------
//-------- MAIN -----------------------------------------
//-*******************************************************/
int main() {
uchar i,ans;

DDRD|=(1<<6)|(1<<7);				//IO ports
DDRC=255;
	detect();						//detect a device on SMBus
	wdt_enable(WDTO_1S); 			// enable 1s watchdog timer
	odDebugInit();
    usbInit();
	usbDeviceDisconnect(); 			// enforce re-enumeration

    for(i = 0; i<250; i++) { 		// wait 500 ms
        wdt_reset(); 				// keep the watchdog happy
        _delay_ms(2);	
    }
	
    usbDeviceConnect();				//USB connected

    sei();		
	
    while(1) { 
					
		if(prijata){				//when data came
			prijata=0;
			LED_CHANGE;
			usbPoll();
			if((ans=action(&prijata_data[0],&odeslana_data[0]))>0){
				if(ans==1){
					if(usbInterruptIsReady()) 				// poslední přerušení už je vyřízeno - můžeme poslat 
            			usbSetInterrupt(odeslana_data, 3); 	//vlastní odeslání dat, sizeof(odeslana_data)
				}	
				else{
				
					if(ans-((ans/2)*2)){			//round 2 Byte
						block[ans]=0;
						ans++;
						}
						

					for(i=0;i<ans;i=i+2){			//send block per 2B packet
						odeslana_data[0]=(prijata_data[0]-150);
						odeslana_data[1]=block[i];
						odeslana_data[2]=block[i+1];
						while(!usbInterruptIsReady()) {}		// poslední přerušení už je vyřízeno - můžeme poslat 
						usbSetInterrupt(odeslana_data, 3);	 //vlastní odeslání dat, sizeof(odeslana_data)
					}//for
					
				
				}//else
			}
			LED_OFF;
		}//prijata
	

		usbPoll();											//udržování komunikace s USB na "životě"
		wdt_reset(); 										//keep watchdog happy
		_delay_ms(30);

    }//while
    return 0;
}//main

