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


void CANConfig(unsigned 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("%d",&CanConfig.BaudRate);
		if (CanConfig.BaudRate){
			if (CanConfig.BaudRate>8){
				if (CanConfig.BaudRate==9){
					break;
				}
				else{
					printf("Baud %d out of range\r\n");
					continue;
				}
			}
		}
		else{
			printf("Input BT0: ");
			scanf("%d",&CanConfig.BT0);
			printf("Input BT1: ");
			scanf("%d",&CanConfig.BT1);
		}
		printf("Input acceptance code: ");
		scanf("%lx",(unsigned long *)&CanConfig.AccCode[0]);
		printf("Input acceptance mask: ");
		scanf("%lx",(unsigned long *)&CanConfig.AccMask[0]);
		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')
			break;
		
	}
	
			
}

void SendOneCANMsg(unsigned 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;
		if (strlen(InputStr)>40){
			printf("CAN message error\r\n");
			continue;
		}
		ptr=&InputStr[0];
		ptr1=strchr(ptr,',');
		if (ptr1==NULL){
			printf("CAN mode error\r\n");
			continue;
		}
		
		*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;
		}
		*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;
		}
		*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;
		}
		*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;
			}
		}
		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(unsigned 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 | %3x | %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 : %d\r\n",(int)SlotNo,cnt);
}


int main(void)
{
	int wRetVal, Ret=1, x=1;
	unsigned int SlotNo,Selection;
   
  while(1){

  	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;
  	}
RETRY:
	  printf("\033[2J");
	  printf("\033[0;0H");
  	printf("                  i-8120W 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);
  	switch(Selection){
  		case 1:
  			CANConfig(SlotNo);
  			goto RETRY;
  		case 2:
  			SendOneCANMsg(SlotNo);
  			goto RETRY;
  		case 3:
  			ReceiveCANMsgs(SlotNo);
  			goto RETRY;
		case 4:
			break;
  		default :
  			printf("Error selection.\r\n");
  			goto RETRY;
  			break;
  	}
  	if (Selection==4) break;
  }
  
  Close_Slot(SlotNo);
  return 0;
}
