/***********************************************************************/
/*                    Demo source for esd NTCAN-API                    */
/*                                                                     */
/*       Copyright by Shanghai ESD Electric Technology Co., Ltd.       */
/*---------------------------------------------------------------------*/
/*         Filename:      objrx.c                                      */
/*         Date:          2022-1-12                                    */
/*         Language:      ANSI C                                       */
/*         Targetsystem:  Windows 10, Linux                            */
/*         Purpose:       Demostrate object mode receive CAN msg       */
/*         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=NTCAN_MODE_OBJECT; /* mode bits for canOpen */
  /* maximum number of messages to transmit, useless here */
  int32_t txqueuesize=2; 
  /* The rxqueuesize should be set to the maximum number of different
   CAN messages (messages with different CAN-IDs) the application 
   wants to receive. */
  int32_t rxqueuesize=5; 
  int32_t txtimeout=1000; /* timeout for transmit in ms, useless here */
  int32_t rxtimeout=1000; /* timeout for receiving data in ms, useless here */
  NTCAN_HANDLE rxhandle; /* can handle returned by canOpen() */
  NTCAN_RESULT retvalue; /* return values of NTCAN API calls */
  uint32_t baud=NTCAN_BAUD_1000; /* configured CAN baudrate 1000K Bit/s */
  int32_t lenRcv=5;
  CMSG cmsgObjRcv[5]; 
  uint32_t idCnt=0x800;
  
/* ############################################################### */
  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 != NTCAN_SUCCESS)
  {
    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);
  }
/* ############################################################### */
/* Initialize the id from 0 to 4 of the CMSG objects of interest. */ 
  for (int i = 0; i < lenRcv; i++)
  {
    cmsgObjRcv[i].id = i;
  }
  printf("press SPACE and then ENTER key to canTake() data once. \n");
  while(1)
  {
		// 0x20 is SPACE key number.
		if(getchar()==0x20)
    {
		  retvalue = canTake(rxhandle, &cmsgObjRcv[0], &lenRcv);
      if(retvalue != NTCAN_SUCCESS)
      {
        printf("canTake() failed with error %d!\n", retvalue);
      }
      else
      { 
        for (int i = 0; i < lenRcv; i++)
        {
          /*check if Bit 5(NTCAN_NO_DATA) of CMSG.len is clear */
          if (!(cmsgObjRcv[i].len & 0x20)){
            printf("Id: %d\n", cmsgObjRcv[i].id);
            printf("Len: %d\n", (cmsgObjRcv[i].len & 0x0f));
            for (int j=0;j<(cmsgObjRcv[i].len & 0x0f);j++)
              printf("Byte %d: %#x\n", j, cmsgObjRcv[i].data[j]);
            printf("\n");
          }
          else
          {
            printf("Id %d: no valid data. \n\n", cmsgObjRcv[i].id);
          }
        }
        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);
}