#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h>
#include "msw.h"
#include "lincon.h"
//#include "I8120.h"
#include "i8120W.h"

void CANConfig(int SlotNo)
{
	int Ret;
	ConfigStruct CanConfig;
	char e;

	while(1){
		printf("------------------------------------------------\r\n");
		printf("Input Baud (0[user-defined], 1[10K], 2[20K], 3[50K], 4[125K], 5[250K], 6[500K], 7[800K], 8[1M], 9[exit]):");
		scanf("%hhd",&CanConfig.BaudRate);
      
		if (CanConfig.BaudRate){
			if (CanConfig.BaudRate>8){
				if (CanConfig.BaudRate==9){
					break;   //cindy
				}
				else{
					printf("BaudRate: out of range\n");
					continue;  //cindy
				}
			}
		}
		else{   //0[user-defined baud rate]
			printf("Input BT0: ");
			scanf("%hhd",&CanConfig.BT0);
			printf("Input BT1: ");
			scanf("%hhd",&CanConfig.BT1);
		}
		printf("Input acceptance code: ");
		scanf("%lx",(unsigned long *)&CanConfig.AccCode[0]);
		printf("Input acceptance mask: ");
		scanf("%lx",(unsigned long *)&CanConfig.AccMask[0]);
        
        	//CanConfig.BaudRate=8; //baudrate, 4: 125K, 8: 1M
	CanConfig.AccCode[0]=0;
	CanConfig.AccCode[1]=0;
	CanConfig.AccCode[2]=0;
	CanConfig.AccCode[3]=0;
	CanConfig.AccMask[0]=0xFF;
	CanConfig.AccMask[1]=0xFF;
	CanConfig.AccMask[2]=0xFF;
	CanConfig.AccMask[3]=0xFF;
        
        
        
		Ret=I8120_Config(SlotNo,&CanConfig);
		if (Ret){
			printf("Configure fail, error code %d\r\n",Ret);
		}
		else
			printf("Configure OK\r\n");

		//break;
		printf("Exit? [y/n]");
		scanf("%c",&e);
		if(e=='y'||e=='Y')  //cindy
			break;

	}

}

void SendOneCANMsg(int SlotNo)
{
	//unsigned char *ptr1,InputStr[100]; 
  char *ptr,*ptr1,*endptr,InputStr[100];
	//char *ptr,*endptr;
	int Ret,i;
	PacketStruct CANMsg;
	while(1){
		printf("------------------------------------------------\r\n");
		printf("Input CAN message in hex format: Mode,ID,RTR,DataLen,Data0,Data1,Data2,Data3,Data4,Data5,Data6,Data7 \n");
		printf("or input 'e' for exit: \r\n");
	
		scanf("%s",InputStr);
		//printf("\r\n");
		InputStr[99]=0;
		if (InputStr[0]=='e' || InputStr[0]=='E') break;  //cindy
		if (strlen(InputStr)>40){
			printf("CAN message error\r\n");
			continue;  //cindy
		}
		ptr=&InputStr[0];
		ptr1=strchr(ptr,',');
		if (ptr1==NULL){
			printf("CAN mode error\r\n");
			continue;  //cindy
		}

		*ptr1=0;
		if (strtoul(ptr,&endptr,16)) CANMsg.Mode=1;
		else CANMsg.Mode=0;
		ptr=ptr1+1;
		ptr1=strchr(ptr,',');
		if (ptr1==NULL){
			printf("CAN ID error\r\n");
			continue;  //cindy
		}
		*ptr1=0;
		CANMsg.Id=strtoul(ptr,&endptr,16);
		if (CANMsg.Mode) CANMsg.Id&=0x1fffffffUL;
		else CANMsg.Id&=0x7ff;
		ptr=ptr1+1;
		ptr1=strchr(ptr,',');
		if (ptr1==NULL){
			printf("CAN RTR error\r\n");
			continue;  //cindy
		}
        
		*ptr1=0;
		if (strtoul(ptr,&endptr,16)) CANMsg.Rtr=1;
		else CANMsg.Rtr=0;

		ptr=ptr1+1;
		ptr1=strchr(ptr,',');

		if (ptr1==NULL){
			printf("CAN Dlen error\r\n");
			continue;  //cindy
		}
        
		*ptr1=0;
		CANMsg.Len=strtoul(ptr,&endptr,16);
		if (CANMsg.Len>8) CANMsg.Len=8;
		if (!CANMsg.Rtr){
			for (i=0;i<CANMsg.Len;i++){
				ptr=ptr1+1;
				ptr1=strchr(ptr,',');
				if (ptr1==NULL&&(i!=(CANMsg.Len-1))){
					printf("CAN data[%d] error\r\n",i);
					break;
				}
				if(i==(CANMsg.Len-1))
					ptr1=strchr(ptr,'\0');
				*ptr1=0;
				CANMsg.Data[i]=(unsigned char)strtoul(ptr,&endptr,16);
			}
			if (i!=CANMsg.Len){
				continue;  //cindy
			}
		}
		Ret=I8120_SendMsg(SlotNo,&CANMsg);
		if (Ret){
			printf("Send CAN message fail, error code %d\r\n",Ret);
		}
		else{
			printf("Send CAN message (Mode=%d,ID=%lx,RTR=%d,Len=%d,Data[%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x] OK\r\n",
			        CANMsg.Mode,CANMsg.Id,CANMsg.Rtr,CANMsg.Len,CANMsg.Data[0],CANMsg.Data[1],CANMsg.Data[2],
			        CANMsg.Data[3],CANMsg.Data[4],CANMsg.Data[5],CANMsg.Data[6],CANMsg.Data[7]);
		}
	}
}

int Kbhit(void){
  int n;
  ioctl(0,FIONREAD,&n);
  return n;
}/**/

void ReceiveCANMsgs(int SlotNo)
{
	int Ret,i,j;
	unsigned short count=0;
	unsigned long cnt=0;
	PacketStruct CANMsg;

	printf("------------------------------------------------\r\n");
	printf("Any key to exit\r\n");
	printf("   No.|  ID | RTR | LEN | D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 |\r\n");
	while(1)
	{
		if (Kbhit())break;
		I8120_RxMsgCount((int)SlotNo,&count);
		for(i=0;i<count;i++)
		{
			usleep(100);
			Ret=I8120_ReceiveMsg((int)SlotNo,&CANMsg);
			if (!Ret){
				printf("%5ld | %3lx | %3d | %3d | %2x | %2x | %2x | %2x | %2x | %2x | %2x | %2x |\r\n"
				,cnt,CANMsg.Id,CANMsg.Rtr,CANMsg.Len,CANMsg.Data[0],CANMsg.Data[1],CANMsg.Data[2],
				CANMsg.Data[3],CANMsg.Data[4],CANMsg.Data[5],CANMsg.Data[6],CANMsg.Data[7]);
				cnt++;
			}
			if((cnt%10)==0&&cnt!=0)
			{
				for(j=0;j<10;j++)
					printf("\b\r");
			}

		}
		usleep(100);
		//printf("%d\r",Cnt);
		//pthread_mutex_unlock(&work_mutex[*(int*)SlotNo]);
		//if(Cnt==55000)break;

	}
	printf("Node %d : Receive message count : %ld\r\n",(int)SlotNo,cnt);
}

//int main(int argc, char **argv)
//int main()
int main(void)
{
	int wRetVal, ret=1,selection, SlotNo;

  	printf("Input Slot No.: ");
  	scanf("%d",&SlotNo);
  
    wRetVal = Open_Slot(SlotNo);
    if (wRetVal > 0) {
		  printf("Open Slot failed!\n");
		  return (-1);
	}
    
  
 	ret=I8120_Init(SlotNo);
  	if (ret){
  		printf("Init SlotNo %d error, error code %d\r\n",SlotNo,ret);
  		//continue;
          Close_Slot(SlotNo);
          return 0;
  	} /**/
    
     while(1){
RETRY:
    //setbuf(stdin,NULL); 
    
	  //printf("\033[2J");
	  //printf("\033[0;0H");
  	printf("\n       I-8120W plug-in Slot %d Test             \r\n",SlotNo);
  	printf("=========================================\r\n");
  	printf(" Please choose one of the following :               \r\n");
  	printf("     1. CAN Configure              \r\n");
  	printf("     2. Send one CAN message       \r\n");
  	printf("     3. Receive CAN messages       \r\n");
  	printf("     4. Exit                       \r\n");
  	printf("Your choice: ");
  	scanf("%d",&selection);
   
    //selection=1;
    //getchar();
  /*	ret=I8120_Init(SlotNo);
  	if (ret){
  		printf("Init SlotNo %d error, error code %d\r\n",SlotNo,ret);
  		//continue;
          Close_Slot(SlotNo);
          return 0;
  	} */
  	switch(selection){
  		case 1:
  		    CANConfig(SlotNo);	//break;
  			goto RETRY; 
             
  		case 2:
  			SendOneCANMsg(SlotNo);	//break;
  			goto RETRY;
              
  		case 3:
  			ReceiveCANMsgs(SlotNo);	//break;
  			goto RETRY;
             
		case 4:
			break;
  		default :
  			printf("Error selection.\r\n");
  			goto RETRY;
  			break;
  	}
    
  	if (selection==4) break;
  }
  
  Close_Slot(SlotNo);
  return 0;
}
