/***********************************************************************/
/*                    Demo source for esd NTCAN-API                    */
/*                                                                     */
/*       Copyright by Shanghai ESD Electric Technology Co., Ltd.       */
/*---------------------------------------------------------------------*/
/*         Filename:      sif.c                                        */
/*         Date:          2022-1-5                                     */
/*         Language:      ANSI C                                       */
/*         Targetsystem:  Windows 10, Linux                            */
/*         Purpose:       Demostrate smart ID filter, usage of 1st     */
/*                        filter stage and 2nd filter stage.           */
/*         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 bits for canOpen */
  int32_t txqueuesize=8; /* maximum number of messages to transmit */
  int32_t rxqueuesize=8; /* maximum number of messages to receive */
  int32_t txtimeout=1000; /* timeout for transmit in ms */
  int32_t rxtimeout=10000; /* timeout for receiving data in ms */
  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 */
  int32_t lenRcv;
  CMSG cmsgRcv; 
  uint32_t idCnt = 0x800; 
  NTCAN_FILTER_MASK filter;
/* ############################################################### */
  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);
  }
/* ############################################################### */
/* CAN msgs with 11-bit ID=0x1, 0x5, 0x9, 0xC can be received. */
  retvalue = canIdRegionAdd(rxhandle, 0, &idCnt);
  if (retvalue != NTCAN_SUCCESS)
  {
    printf("canIdAdd() failed with error %d!\n", retvalue);
    canClose(rxhandle);
    return(-1);
  }
  filter.acr = 0x00000001;
  filter.amr = 0x0000000C;
  filter.idArea = NTCAN_IDS_REGION_20A;
  canIoctl(rxhandle, NTCAN_IOCTL_SET_HND_FILTER, &filter);
/* ############################################################### */  
  printf("CAN msgs with 11-bit ID=0x1, 0x5, 0x9, 0xC can be received.\n");

  while(1)
  {
    lenRcv = 1;
    retvalue = canRead(rxhandle, &cmsgRcv, &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("Id of received message :%x!\n", cmsgRcv.id);
      if (cmsgRcv.id == 0){
        printf("Exit program!\n");
        break;
      }
      printf("Len of received message :%x!\n", (cmsgRcv.len & 0x0f));
      printf("Rtr of received message :%x!\n", ((cmsgRcv.len & 0x10)>>4));
      for (int i=0;i<(cmsgRcv.len & 0x0f);i++)
        printf("Byte %d of received message :%x!\n", i, cmsgRcv.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);
}
