/********************************************************************************/
/*                      Demo source for esd NTCAN-API                           */
/*                                                                              */
/*              Copyright by Shanghai ESD Electric Technology Co., Ltd.         */
/*------------------------------------------------------------------------------*/
/*          Filename:       ts_rx.c                                             */
/*          Date:           2020-2-18                                           */
/*          Language:       ANSI C                                              */
/*          Targetsystem:   Windows 10, Linux                                   */
/*          Purpose:        Demostrate how to use the timestampes of received   */
/*                          CAN messages by CMSG_T and canReadT().              */
/*          Author:         Bob Tu                                              */
/*------------------------------------------------------------------------------*/ 
/* Revision history:                                                            */
/*------------------------------------------------------------------------------*/
/* v1.0     Birth of module                                                     */
/********************************************************************************/

#include <stdio.h>
#include "ntcan.h"
int main()
{
	int net=3; /* logical net number */
	uint32_t mode=0; /* mode used for canOpen() */
	int32_t txqueuesize=8; /* size of transmit queue */
	int32_t rxqueuesize=8; /* size of receive queue */
	int32_t txtimeout=1000; /* timeout for transmit operations in ms */
	int32_t rxtimeout=10000; /* timeout for receive operations in ms */
	NTCAN_HANDLE rxhandle; /* can txhandle returned by canOpen() */
	NTCAN_RESULT retvalue; /* return values of NTCAN API calls */
	uint32_t baud=NTCAN_BAUD_1000; /* 1000k bit/s, 2 for 500k bit/s, 4 for 250k bit/s */
	uint64_t timestampFreq; /* timestamp frequency */
	uint64_t timestamp; /* timestamp */
	CMSG_T cmsg_t;
	int32_t lenRcv;
	uint32_t idCnt=0x800;
	CAN_IF_STATUS cstat;
	double last=0.0;
/* ############################################################### */
	retvalue = canOpen(net,
						mode,
						txqueuesize,
						rxqueuesize,
						txtimeout,
						rxtimeout,
						&rxhandle);

	if (retvalue != NTCAN_SUCCESS)
	{
		printf("canOpen() failed with error %d!\n", retvalue);
		return(-1);
	}
/* ############################################################### */
	retvalue = canSetBaudrate(rxhandle, baud);
	if (retvalue != 0)
	{
		printf("canSetBaudrate() failed with error %d!\n", retvalue);
		canClose(rxhandle);
		return(-1);
	}
/* ############################################################### */
	/* All 11-bit ID CAN messages can be received */
	retvalue = canIdRegionAdd(rxhandle, 0, &idCnt);
	if (retvalue != NTCAN_SUCCESS)
	{
		printf("canIdAdd() failed with error %d!\n", retvalue);
		canClose(rxhandle);
		return(-1);
	}
/* ############################################################### */
	/*check if device supports NTCAN_FEATURE_TIMESTAMP*/
	retvalue = canStatus(rxhandle, &cstat);
	if (retvalue != NTCAN_SUCCESS) {
		printf("canStatus() failed with %d\n", retvalue);
		canClose(rxhandle);
		return(-1);
	}
	if(!cstat.features & NTCAN_FEATURE_TIMESTAMP){
		printf("timestamp feature NOT supported.\n");
		canClose(rxhandle);
		return(-1);
	}
/* ############################################################### */
	/* Request timestamp/tick frequency of interface */
	retvalue = canIoctl(rxhandle, NTCAN_IOCTL_GET_TIMESTAMP_FREQ, &timestampFreq);
	if (retvalue != NTCAN_SUCCESS) {
		printf("Gathering timestamp frequency failed with %d\n", retvalue);
		canClose(rxhandle);
		return(-1);
	}
	retvalue = canIoctl(rxhandle, NTCAN_IOCTL_GET_TIMESTAMP, &timestamp);
	if (retvalue != NTCAN_SUCCESS) {
		printf("Gathering timestamp failed with %d\n", retvalue);
		canClose(rxhandle);
		return(-1);
	}
	last=(double)timestamp/(double)timestampFreq;
/* ############################################################### */
	printf("Send CAN msg with 11-bit ID=0 to Exit Program!\n");
	while(1)
	{
    	lenRcv = 1;
    	retvalue = canReadT(rxhandle, &cmsg_t, &lenRcv, NULL);
    	if (retvalue == NTCAN_RX_TIMEOUT)
    	{
      		printf("canRead() returned timeout\n");
      		continue;
   		}
    	else if(retvalue != NTCAN_SUCCESS)
    	{
      		printf("canRead() failed with error %d!\n", retvalue);
    	}
    	else
    	{ 
			printf("=====================================\n");
     		printf("Timestamp(T): %lld (ticks)\n", cmsg_t.timestamp);
		  	printf("TimestampFreq(F): %lld (ticks per second)\n", timestampFreq);
			printf("T/F(Last)= %f (seconds)\n", last);
       		printf("T/F(Now)= %f (seconds)\n", (double)cmsg_t.timestamp/(double)timestampFreq);
       		printf("Diff b/w Now & Last= %f (seconds)\n", (double)cmsg_t.timestamp/(double)timestampFreq-last);
			last=(double)cmsg_t.timestamp/(double)timestampFreq;
			printf("=====================================\n");
      		printf("Id of received message: %x!\n", cmsg_t.id);
			if (cmsg_t.id == 0){
        		printf("Exit program!\n");
        		break;
      		}
      		printf("Len of received message: %x!\n", (cmsg_t.len & 0x0f));

       		for (int i=0;i<(cmsg_t.len & 0x0f);i++)
        		printf("Byte %d of received message :%x!\n", i, cmsg_t.data[i]);
      		printf("\n");
    	}
	}
/* ############################################################### */
	retvalue = canIdRegionDelete(rxhandle, 0 , &idCnt);
	if (retvalue != NTCAN_SUCCESS)
	  printf("canIdRegionDelete() failed with error %d!\n", retvalue);
/* ############################################################### */
	retvalue = canClose (rxhandle);
	if (retvalue != NTCAN_SUCCESS)
		printf("canClose failed with error %d!\n", retvalue);
/* ############################################################### */
	return(0);
}