/*
  v 1.0 2025.03.03 by Winson Chen
  Create.
*/

#include "canfd.h"

void GetFwVer(WORD hidnum) 
{
  WORD o_wFwVer[2]; 
  double version = o_wFwVer[0];

  printf("Read firmware version.\n");
  if (!CANFD_GetFwVer(hidnum, o_wFwVer)){
    version  = (double)o_wFwVer[0] / 100; 
    printf("%.2f\n", version);
  }
}

void SetSN(WORD hidnum)
{
  //DWORD i_dwSN = 0x6309AB8f;
  DWORD i_dwSN = 0x67d7e644;

  printf("Set board ID()\n");
  if (!CANFD_SetSN(hidnum, i_dwSN))
    printf("OK\n");
  else
    printf("Fail\n");

  printf("This setting will take effect only after a power cycle.\n");
}

void SetCANSTDIDFilter(WORD hidnum)
{
  BYTE i_byCANPort;
  WORD i_wSTDFIDListSize = 3; //0 to clear
  WORD i_wSTDFID1[128] = {0x1, 0x200 ,0x300};
  WORD i_wSTDFID2[128] = {0x1ff, 0x2ff ,0x3ff};
  int i;

  printf("Select CAN port(1 or 2):");
  scanf("%hhd",&i_byCANPort);
  if (i_byCANPort != 1 && i_byCANPort != 2){
    printf("Invalid port.\n");
    return;
  }

  printf("Set CAN%d standrad ID filter. There are %d set of settings\n", i_byCANPort, i_wSTDFIDListSize);
  for (i = 0; i < i_wSTDFIDListSize; i++){
    printf("set%d 0x%x to 0x%x\n",i, i_wSTDFID1[i], i_wSTDFID2[i]);
  }

  if (!CANFD_SetCANSTDIDFilter(hidnum, i_byCANPort, i_wSTDFIDListSize, i_wSTDFID1, i_wSTDFID2)){
    CANFD_SetCANReInitialize(hidnum, i_byCANPort);  //take filer work
    printf("CAN%d setting OK\n",i_byCANPort);
  }
  else
    printf("CAN%d setting Fail\n",i_byCANPort);
}

void GetCANSTDIDFilter(WORD hidnum)
{
  BYTE o_byRejectRFS, o_byRejectRFE;
  WORD o_wSTDFIDListSize, o_wEXTFIDListSize;
  WORD o_wSTDFID1[128];
  WORD o_wSTDFID2[128];
  BYTE i_byCANPort;
  int i;

  for (i_byCANPort = 1; i_byCANPort <=2; i_byCANPort++){
    CANFD_GetCANGlobalFilter(hidnum, i_byCANPort, &o_byRejectRFS, &o_byRejectRFE, &o_wSTDFIDListSize, &o_wEXTFIDListSize);

    printf("Get CAN%d standrad ID filter. There are %d set of settings\n", i_byCANPort, o_wSTDFIDListSize);
    if (!CANFD_GetCANSTDIDFilter(hidnum, i_byCANPort, o_wSTDFID1, o_wSTDFID2)){
      for (i = 0; i < o_wSTDFIDListSize; i++)
        printf("set%d 0x%x start ID to 0x%x end ID\n",i, o_wSTDFID1[i], o_wSTDFID2[i]);
    }   
    else
      printf("CAN%d Fail\n",i_byCANPort);
  }
}

void SetCANEXTIDFilter(WORD hidnum)
{
  WORD i_wEXTFIDListSize = 4;
  DWORD i_dwEXTFID1[64] = {0x01000000,0x02200000,0x03003000,0x04000040};
  DWORD i_dwEXTFID2[64] = {0x11ffffff,0x12ffffff,0x13ffffff,0x14ffffff};
  BYTE i_byCANPort;
  int i;

  printf("Select CAN port(1 or 2):");
  scanf("%hhd",&i_byCANPort);
  if (i_byCANPort != 1 && i_byCANPort != 2){
    printf("Invalid port.\n");
    return;
  }

  printf("Set CAN%d extended ID filter. There are %d set of settings\n", i_byCANPort, i_wEXTFIDListSize);
  for (i = 0; i < i_wEXTFIDListSize; i++){
    printf("set%d 0x%x to 0x%x\n",i, i_dwEXTFID1[i], i_dwEXTFID2[i]);
  }

  if (!CANFD_SetCANEXTIDFilter(hidnum, i_byCANPort, i_wEXTFIDListSize, i_dwEXTFID1, i_dwEXTFID2)){
    CANFD_SetCANReInitialize(hidnum, i_byCANPort);  //take filer work
    printf("CAN%d setting OK\n",i_byCANPort);
  }
  else
    printf("CAN%d setting Fail\n",i_byCANPort);
}

void GetCANEXTIDFilter(WORD hidnum)
{
  BYTE o_byRejectRFS, o_byRejectRFE;
  WORD o_wSTDFIDListSize, o_wEXTFIDListSize;
  DWORD o_dwEXTFID1[64];
  DWORD o_dwEXTFID2[64];
  BYTE i_byCANPort;
  int i;

  for (i_byCANPort = 1; i_byCANPort <=2; i_byCANPort++){
    CANFD_GetCANGlobalFilter(hidnum, i_byCANPort, &o_byRejectRFS, &o_byRejectRFE, &o_wSTDFIDListSize, &o_wEXTFIDListSize);

    printf("Get CAN%d extended ID filter. There are %d set of settings\n", i_byCANPort, o_wEXTFIDListSize);

    if (!CANFD_GetCANEXTIDFilter(hidnum, i_byCANPort, o_dwEXTFID1, o_dwEXTFID2)){
      for (i = 0; i < o_wEXTFIDListSize; i++)
        printf("set%d 0x%x start ID to 0x%x end ID\n", i, o_dwEXTFID1[i], o_dwEXTFID2[i]);
    }
    else
      printf("CAN%d Fail\n",i_byCANPort);
  }
}

void SetCANGlobalFilter(WORD hidnum)
{
  BYTE i_byRejectRFS, i_byRejectRFE, i_byCANPort;

  printf("Select CAN port(1 or 2):");
  scanf("%hhd", &i_byCANPort);
  if (i_byCANPort != 1 && i_byCANPort != 2){
    printf("Invalid port.\n");
    return;
  }

  printf("Set receive(0) or reject(1) standard remote CAN messages:");
  scanf("%hhd", &i_byRejectRFS);
  printf("Set receive(0) or reject(1) extended remote CAN messages:");
  scanf("%hhd", &i_byRejectRFE);

  if (!CANFD_SetCANGlobalFilter(hidnum, i_byCANPort, i_byRejectRFS, i_byRejectRFE)){
    CANFD_SetCANReInitialize(hidnum, i_byCANPort);  //take filer work
    printf("CAN%d setting OK\n",i_byCANPort);
  }
  else
    printf("CAN%d setting Fail\n",i_byCANPort);
}

int GetCANGlobalFilter(WORD hidnum)
{
  BYTE o_byRejectRFS, o_byRejectRFE, i_byCANPort;
  WORD o_wSTDFIDListSize, o_wEXTFIDListSize;

  for (i_byCANPort = 1; i_byCANPort <=2; i_byCANPort++){
    if (!CANFD_GetCANGlobalFilter(hidnum, i_byCANPort, &o_byRejectRFS, &o_byRejectRFE, &o_wSTDFIDListSize, &o_wEXTFIDListSize)){
      if (o_byRejectRFS)
        printf("CAN%d reject standard remote CAN messages(rtr).\n", i_byCANPort);
      else
        printf("CAN%d receive standard remote CAN messages(rtr).\n", i_byCANPort);

      if (o_byRejectRFE)
        printf("CAN%d reject extended remote CAN messages(rtr).\n", i_byCANPort);
      else
        printf("CAN%d receive extended remote CAN messages(rtr).\n", i_byCANPort);
    
      printf("CAN%d standrad filter list size %d extended filter list size %d\n",i_byCANPort, o_wSTDFIDListSize, o_wEXTFIDListSize);
    }
    else
      printf("CAN%d Fail\n",i_byCANPort);

    printf("\n");
  }
}

void ResetModule(WORD hidnum)
{
  printf("Reset the CANFD module.\n");
  if (!CANFD_ResetModule(hidnum))
    printf("Command OK\n");
  else
    printf("Command Fail\n");
}

void CloseDevice(WORD hidnum)
{
  printf("Close CANFD device and quit demo.\n");
  CANFD_CloseDevice(hidnum);
}


void print_menu() {
  printf("\nChoose an option:\n");
  printf("a) Get Firmversion:\r\n");
  printf("b) Set module board ID(BID):\r\n");
  printf("c) Set CAN port standrad ID filter when receive:\r\n");
  printf("d) Get CAN port standrad ID filter when receive:\r\n");
  printf("e) Set CAN port extended ID filter when receive:\r\n");
  printf("f) Get CAN port extended ID filter when receive:\r\n");
  printf("g) Set CAN port Global filter:\r\n");
  printf("h) Get CAN port Global filter:\r\n");
  printf("i) Reset module:\r\n");
  printf("p) print All function message:\r\n");
  printf("q) Shutdown and exit.\r\n");
}

int main() {
  int Ret;
  WORD hidnum;

  Ret = CANFD_ScanDevice();
  if (CANFD_ScanDevice())
    printf("CANFD_ScanDevice error 0x%x\n", Ret);

  Ret = CANFD_OpenDevice(&hidnum, 0x0216, 0x67d7e644);
  if (Ret){
    printf("CANFD_OpenDevice error 0x%x\n",Ret);
    printf("Check demo \"i7565m_list\" first\n");
    return 0;
  }

  print_menu();
  char choice;
  while (1) {
    //print_menu();
    scanf(" %c", &choice);

    switch (choice) {
      case 'a': GetFwVer(hidnum); break;
      case 'b': SetSN(hidnum); break;
      case 'c': SetCANSTDIDFilter(hidnum); break;
      case 'd': GetCANSTDIDFilter(hidnum); break;
      case 'e': SetCANEXTIDFilter(hidnum); break;
      case 'f': GetCANEXTIDFilter(hidnum); break;
      case 'g': SetCANGlobalFilter(hidnum); break;
      case 'h': GetCANGlobalFilter(hidnum); break;
      case 'i': ResetModule(hidnum); break;
      case 'p': print_menu();break;
      case 'q': CloseDevice(hidnum); exit(0);
      default: printf("error input\n");
    }
  }
  return 0;
}

