	/*
	* MD_USB.c
	*
	* Created: 13.1.2013 16:49:42
	*  Author: MichalM11x
	*/

	#include "MD_USB.h"

	static uchar replyBuf[16] = "Reply Buffer"; //Used for testing
	static uchar dataReceived = 0, dataLength = 0; // USB_DATA_IN
	/*static uchar commandBuf[5] = "0000\0";
	uint8_t iPot_Act;
	uint8_t iPot_Des;
	uint8_t  iCS_Port;*/
	
	semafors *hold;
	digpot *pots;

	uint8_t semaf_pins(unsigned char state, unsigned char port){
		uint8_t data = 0;
		
		if(port == 1){
			switch(state){
				case 0:
				data = GREEN;
				break;
				case 1:
				data = YELLOW;
				break;
				case 2:
				data = RED;
				break;
				case 3:
				data = ORANGE;
				break;
			}
		}
		if(port == 0){
		switch(state){
			case 0:
			data = 0x90;
			break;
			case 1:
			data = 0x50; 
			break;
			case 2:
			data = 0x30;
			break;
			case 3:
			data = 0x70;
			break;
		}
		}
		return data;
	}
	
	void msg_semaf_info(uchar pocet, uchar s1, uchar s2, uchar s3, uchar s4, uchar s5, uchar s6){
//..int i;
		
		hold->number = pocet;
		hold->state[0]= s1;
		hold->state[1]= s2;
		hold->state[2]= s3;
		hold->state[3]= s4;
		hold->state[4]= s5;
		hold->state[5]= s6;
		
		if(hold->number<=2)
			PORTB&=MAZ(0);		
	}
	void msg_onedpot(uchar sel, uchar value){

		//fPot_ChangeTemp(pots, sel);
	}

	void msg_alldpot(uchar v1, uchar v2, uchar v3){
		
	}

	USB_PUBLIC uchar usbFunctionSetup(uchar data[8]) {
		usbRequest_t *rq = (void *)data; // cast data to correct type
		switch(rq->bRequest) { //On PC side, operations on/off/out/write *, are enumerated and this number is saved to bRequest
		case USB_LED_ON:	//Simple way to verify proper communication between controller and PC
		PORTC |= STATUS_LED;
		break;
		
		case USB_LED_OFF:
		PORTC &= ~STATUS_LED;
		break;
		
		case USB_DPOT_TEMP:
		dataLength = (uchar)rq->wLength.word;
		dataReceived = 0;
		
		if(dataLength > sizeof(replyBuf)) // limit to buffer size
		dataLength = sizeof(replyBuf);
		
		return USB_NO_MSG;				//Also contains data
				
		case USB_SEMAF_STATE:
		dataLength = (uchar)rq->wLength.word;
		dataReceived = 0;
		
		if(dataLength > sizeof(replyBuf)) // limit to buffer size
		dataLength = sizeof(replyBuf);
		
		return USB_NO_MSG;
		
		case USB_DPOT_RESET:
		fPot_null(pots);
		break;
		
		case USB_FB:
		usbMsgPtr = replyBuf;
		return sizeof(replyBuf);				
	}
	return 0;
}

USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
	uchar i;
	
	for(i = 0; dataReceived < dataLength && i < len; i++, dataReceived++)
		replyBuf[dataReceived] = data[i];
	
	switch(data[0]){
		case USB_SEMAF_STATE:
		if(data[1]==2){
			PORTB&=MAZ(0);
			PORTB|=data[2];
			PORTD&=MAZ(0<<5);
			PORTD|=data[3];
			
		}
		else if(data[1]==1){
			
			PORTB&=MAZ(0);
			PORTB|=data[2];
					
		}		
		break;
		case USB_DPOT_TEMP:		
		if(data[1]==1){
			fPot_ChangeTemp(data[3], pots->previous[data[2]-1], data[2]-1);
			pots->previous[data[2]-1]=data[3];
			
			return (1);
			
		}
		else if(data[1]==3){

				PORTC &= ~STATUS_LED;
				for(int i= 0; i<3; i++){
					if(pots->previous[i]!=data[i+3]){
					fPot_ChangeTemp((data[i+3]), pots->previous[i], i);
					pots->previous[i]=data[i+3];
				}
					}
			return (1);
		}
		break;
		}
	return (1); // 1 if we received it all, 0 if not
}

void usb_init(){
	uchar i;
	usbInit();
	usbDeviceDisconnect(); // enforce re-enumeration
	for(i = 0; i<250; i++) { // wait 500 ms for USB and DS8400
	wdt_reset(); // watchdog reset
	_delay_ms(2);
	}
	usbDeviceConnect();
}