#include <string.h>
#include <stdbool.h>
#include "usb_device.h"

#include "usbd_cdc_if.h"
#include "cdc_int.h"
#include "stm32f1xx_hal.h"
#include "eeprom.h"
#include "pwm.h"

extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3;
extern TIM_HandleTypeDef htim4;
extern const uint16_t EE_VirtAddrs[];
extern uint8_t pulsanti;
extern uint16_t ch4 ;
extern uint16_t ch5 ;
extern uint16_t ch6 ;
extern uint16_t ch7 ;
extern uint16_t ch8 ;
extern const uint8_t deftab[];

bool toHex(char c1,char c2,char c3,char c4,uint16_t* retval){
	if((c1>='0')&&(c1<='9')){
		c1-='0';
	}else if((c1>='a')&&(c1<='f')){
		c1=(c1-'a')+10;
	}else return false;

	if((c2>='0')&&(c2<='9')){
		c2-='0';
	}else if((c2>='a')&&(c2<='f')){
		c2=(c2-'a')+10;
	}else return false;

	if((c3>='0')&&(c3<='9')){
		c3-='0';
	}else if((c3>='a')&&(c3<='f')){
		c3=(c3-'a')+10;
	}else return false;

	if((c4>='0')&&(c4<='9')){
		c4-='0';
	}else if((c4>='a')&&(c4<='f')){
		c4=(c4-'a')+10;
	}else return false;

	*retval=c1;
	*retval*=16;
	*retval+=c2;
	*retval*=16;
	*retval+=c3;
	*retval*=16;
	*retval+=c4;
	return true;

}

void manageCDC(void){
	static uint8_t rxbuf[100];
	static uint8_t rxidx=0;
	unsigned char s[100];
	uint8_t mot,dir,dm,m,c,d,u;
	uint16_t val;
	uint16_t st;
	uint16_t eeadd;
	uint8_t i;

	if (CDC_Available()) {
	  int rx = CDC_ReadByte();
	  if (rx < 0) return;
	  //uint8_t out = (uint8_t)c;
	  //if (out >= 'a' && out <= 'z') out -= 32; // to upper
	  rxbuf[rxidx]=rx;
	  while (CDC_Transmit_FS(&rxbuf[rxidx], 1) == USBD_BUSY);//echo
	  if((rx==0x0d)||(rx==0x0a)){
		  if(rxidx){
			  switch(rxbuf[0]){
			  case 'i':
				  sprintf((char*)s,"info\n");
				  while (CDC_Transmit_FS(s, 5) == USBD_BUSY);
				  sprintf((char*)s,"\npwm %d%d%d%d%d%d%d%d",IsPwmRunning(timMot1,FWMot1),IsPwmRunning(timMot1,BWMot1),IsPwmRunning(timMot2,FWMot2),IsPwmRunning(timMot2,BWMot2),IsPwmRunning(timMot3,FWMot3),IsPwmRunning(timMot3,BWMot3),IsPwmRunning(timMot4,FWMot4),IsPwmRunning(timMot4,BWMot4));
				  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
				  sprintf((char*)s,"\n0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx",(uint32_t)__HAL_TIM_GET_COMPARE(timMot1,FWMot1),(uint32_t)__HAL_TIM_GET_COMPARE(timMot1,BWMot1),(uint32_t)__HAL_TIM_GET_COMPARE(timMot2,FWMot2),(uint32_t)__HAL_TIM_GET_COMPARE(timMot2,BWMot2),(uint32_t)__HAL_TIM_GET_COMPARE(timMot3,FWMot3),(uint32_t)__HAL_TIM_GET_COMPARE(timMot3,BWMot3),(uint32_t)__HAL_TIM_GET_COMPARE(timMot4,FWMot4),(uint32_t)__HAL_TIM_GET_COMPARE(timMot4,BWMot4));
				  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
				  sprintf((char*)s,"\nP=0x%x ch4=%05d ch5=%05d ch6=%05d ch7=%05d ch8=%05d",pulsanti,ch4,ch5,ch6,ch7,ch8);
				  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
				  break;
			  case 'I':
				  sprintf((char*)s,"\nID000000");
				  while (CDC_Transmit_FS(s, 9) == USBD_BUSY);
				  break;
			  case 'm':
				  if(rxidx==8){
					  if((rxbuf[1]>='1')&&(rxbuf[1]<='4')){
						  mot=rxbuf[1]-='0';
						  if(rxbuf[2]=='f'){
							  dir=FW;
						  }else if(rxbuf[2]=='b'){
							  dir=BW;
						  }else{
							  sprintf((char*)s,"\n?mnsvvvvv s=f|b");//m nmotore senso valore
							  while (CDC_Transmit_FS(s, 16) == USBD_BUSY);
							  break;
						  }
						  if(((rxbuf[3]>='0')&&(rxbuf[3]<='9'))&&((rxbuf[4]>='0')&&(rxbuf[4]<='9'))&&((rxbuf[5]>='0')&&(rxbuf[5]<='9'))&&((rxbuf[6]>='0')&&(rxbuf[6]<='9'))&&((rxbuf[7]>='0')&&(rxbuf[7]<='9'))){
							  dm=rxbuf[3]-='0';
							  m=rxbuf[4]-='0';
							  c=rxbuf[5]-='0';
							  d=rxbuf[6]-='0';
							  u=rxbuf[7]-='0';
							  val=dm;
							  val*=10;
							  val+=m;
							  val*=10;
							  val+=c;
							  val*=10;
							  val+=d;
							  val*=10;
							  val+=u;
							  SetMot(mot,dir,val);
						  }else{
							  sprintf((char*)s,"\n?mnsvvvvv 00000>=vvvvv<=99999");//m nmotore senso valore
							  while (CDC_Transmit_FS(s, 19) == USBD_BUSY);
						  }

					  }else{
						  sprintf((char*)s,"\n?mnsvvvvv 1>=m<=4");//m nmotore senso valore
						  while (CDC_Transmit_FS(s, 19) == USBD_BUSY);
					  }
				  }else{
					  sprintf((char*)s,"\n?mnsvvvvv");//m nmotore senso valore
					  while (CDC_Transmit_FS(s, 10) == USBD_BUSY);
				  }
				  break;
			  case 'e':
				  if(rxidx>1){
					  if(rxbuf[1]=='r'){
						  if(rxidx==4){
							  if(toHex('0','0',rxbuf[2],rxbuf[3],&eeadd)){
								  st=EEW_Read(eeadd, &val);
								  if (st == EE_OK){
									  sprintf((char*)s,"\nee 0x%02x=0x%04x",eeadd,val);
									  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
								  }else{
									  sprintf((char*)s,"\nee read error %d",st);
									  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
								  }
							  }else{
								  sprintf((char*)s,"\n?eraa hex values");
								  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
							  }
						  }else{
							  sprintf((char*)s,"\n?eraa");
							  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
						  }
					  }else if(rxbuf[1]=='w'){
						  if(rxidx==8){
							  if(toHex('0','0',rxbuf[2],rxbuf[3],&eeadd)){
								  if(toHex(rxbuf[4],rxbuf[5],rxbuf[6],rxbuf[7],&val)){
									  st=EEW_Write(eeadd, val);
									  if (st == EE_OK)sprintf((char*)s,"\ndone 0x%02x=0x%04x",eeadd,val);
									  else sprintf((char*)s,"\nee write error %d", st);
								  }else sprintf((char*)s,"\n?ewaavvvv hex values");
							  }else sprintf((char*)s,"\n?ewaa hex values");
						  }else sprintf((char*)s,"\n?ewaavvvv");
						  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
					  }else if(rxbuf[1]=='d'){
						  if(rxidx==2){
							  for(i=0;i<32;i++){
								  st=EEW_Read(i, &val);
								  if (st == EE_OK){
									  sprintf((char*)s,"0x%02x=0x%04x ",i,val);
									  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
								  }else{
									  sprintf((char*)s,"rderr %d ",st);
									  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
								  }
							  }
							  if((i%4)==0){
								  sprintf((char*)s,"\n");
								  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
							  }
						  }else{
							  sprintf((char*)s,"\n?ed");
							  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
						  }
					  }else if(rxbuf[1]=='x'){
						  if(rxidx==2){
							  for(i=0;i<32;i++){
								  st=EEW_Write(i,deftab[i]);
								  if (st == EE_OK)sprintf((char*)s,"\ndone 0x%02x=0x%04x",eeadd,val);
								  else sprintf((char*)s,"\nee write error %d", st);
								  sprintf((char*)s,"\n");
								  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);

							  }
						  }else{
							  sprintf((char*)s,"\n?ex");
							  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
						  }
					  }else{
						  sprintf((char*)s,"\n?er|w|d|x");
						  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
					  }
				  }else{
					  sprintf((char*)s,"\n?eraa | ewaavvvv");
					  while (CDC_Transmit_FS(s, strlen((char*)s)) == USBD_BUSY);
				  }
				  break;
			  default:
				  sprintf((char*)s,"\n?");
				  while (CDC_Transmit_FS(s, 2) == USBD_BUSY);
				  break;
			  }
		  }
		  rxidx=0;
	  }else rxidx++;
      // tiny spin or yield
    }

}
