/*****************************************************************************
        *
        *    acGetStatus
        *
        *    Purpose:
        *        Get the current status of the driver and the CAN Controller
        *
        *
        *    Arguments:
        *        Status    - status buffer
        *    Returns:
        *        =0 SUCCESS; or <0 failure
        *
        *****************************************************************************/
        public int acGetStatus(ref AdvCan.CanStatusPar_t Status)
        {
            bool flag = false;

            flag = AdvCan.DeviceIoControl(hDevice, AdvCan.CAN_IOCTL_STATUS, IntPtr.Zero, 0, lpStatusBuffer, AdvCan.CAN_CANSTATUS_LENGTH, ref OutLen, GCIoctl.AddrOfPinnedObject());
            if (!flag)
            {
                return(OPERATION_ERROR);
            }
            Status = (AdvCan.CanStatusPar_t)(Marshal.PtrToStructure(lpStatusBuffer, typeof(AdvCan.CanStatusPar_t)));
            return(SUCCESS);
        }
        /*****************************************************************************
        *
        *    acClearRxFifo
        *
        *    Purpose:
        *        Clear can port receive buffer
        *
        *
        *    Arguments:
        *
        *    Returns:
        *        =0 SUCCESS; or <0 failure
        *
        *****************************************************************************/
        public int acClearRxFifo()
        {
            bool flag = false;

            Command.cmd = AdvCan.CMD_CLEARBUFFERS;
            Marshal.StructureToPtr(Command, lpCommandBuffer, true);
            flag = AdvCan.DeviceIoControl(hDevice, AdvCan.CAN_IOCTL_COMMAND, lpCommandBuffer, AdvCan.CAN_COMMAND_LENGTH, IntPtr.Zero, 0, ref OutLen, GCIoctl.AddrOfPinnedObject());
            if (!flag)
            {
                return(OPERATION_ERROR);
            }
            return(SUCCESS);
        }
        /*****************************************************************************
        *
        *    acEnterWorkMode
        *
        *    Purpose:
        *        Enter work mode
        *
        *
        *    Arguments:
        *
        *    Returns:
        *        =0 SUCCESS; or <0 failure
        *
        *****************************************************************************/
        public int acEnterWorkMode()
        {
            bool flag;

            Command.cmd = AdvCan.CMD_START;
            Marshal.StructureToPtr(Command, lpCommandBuffer, true);
            flag = AdvCan.DeviceIoControl(hDevice, AdvCan.CAN_IOCTL_COMMAND, lpCommandBuffer, AdvCan.CAN_COMMAND_LENGTH, IntPtr.Zero, 0, ref OutLen, GCIoctl.AddrOfPinnedObject());
            if (!flag)
            {
                return(OPERATION_ERROR);
            }
            return(SUCCESS);
        }
        /*****************************************************************************
        *
        *    acSetAcceptanceFilterCode
        *
        *    Purpose:
        *        Set acceptance filter code of the CAN Controller
        *
        *
        *    Arguments:
        *        Code        - acceptance filter code
        *    Returns:
        *        =0 SUCCESS; or <0 failure
        *
        *****************************************************************************/
        public int acSetAcceptanceFilterCode(uint Code)
        {
            bool flag = false;

            Config.target = AdvCan.CONF_ACCC;
            Config.val1   = Code;
            Marshal.StructureToPtr(Config, lpConfigBuffer, true);
            flag = AdvCan.DeviceIoControl(hDevice, AdvCan.CAN_IOCTL_CONFIG, lpConfigBuffer, AdvCan.CAN_CONFIG_LENGTH, IntPtr.Zero, 0, ref OutLen, GCIoctl.AddrOfPinnedObject());
            if (!flag)
            {
                return(OPERATION_ERROR);
            }
            return(SUCCESS);
        }
        /*****************************************************************************
        *
        *    acSetBaud
        *
        *    Purpose:
        *	     Set baudrate of the CAN Controller.The two modes of configuring
        *     baud rate are custom mode and standard mode.
        *     -   Custom mode
        *         If Baud Rate value is user defined, driver will write the first 8
        *         bit of low 16 bit in BTR0 of SJA1000.
        *         The lower order 8 bit of low 16 bit will be written in BTR1 of SJA1000.
        *     -   Standard mode
        *         Target value     BTR0      BTR1      Setting value
        *           10K            0x31      0x1c      10
        *           20K            0x18      0x1c      20
        *           50K            0x09      0x1c      50
        *          100K            0x04      0x1c      100
        *          125K            0x03      0x1c      125
        *          250K            0x01      0x1c      250
        *          500K            0x00      0x1c      500
        *          800K            0x00      0x16      800
        *         1000K            0x00      0x14      1000
        *
        *
        *    Arguments:
        *        BaudRateValue     - baudrate will be set
        *    Returns:
        *        =0 SUCCESS; or <0 failure
        *
        *****************************************************************************/
        public int acSetBaud(uint BaudRateValue)
        {
            bool flag;

            Config.target = AdvCan.CONF_TIMING;
            Config.val1   = BaudRateValue;
            Marshal.StructureToPtr(Config, lpConfigBuffer, true);
            flag = AdvCan.DeviceIoControl(hDevice, AdvCan.CAN_IOCTL_CONFIG, lpConfigBuffer, AdvCan.CAN_CONFIG_LENGTH, IntPtr.Zero, 0, ref OutLen, GCIoctl.AddrOfPinnedObject());
            if (!flag)
            {
                return(OPERATION_ERROR);
            }
            return(SUCCESS);
        }
        /*****************************************************************************
        *
        *    acSetListenOnlyMode
        *
        *    Purpose:
        *        Set listen only mode of the CAN Controller
        *
        *
        *    Arguments:
        *        ListenOnly        - true, open only listen mode; false, close only listen mode
        *    Returns:
        *        =0 succeeded; or <0 Failed
        *
        *****************************************************************************/
        public int acSetListenOnlyMode(bool ListenOnly)
        {
            bool flag;

            Config.target = AdvCan.CONF_LISTEN_ONLY_MODE;
            if (ListenOnly)
            {
                Config.val1 = 1;
            }
            else
            {
                Config.val1 = 0;
            }
            Marshal.StructureToPtr(Config, lpConfigBuffer, true);
            flag = AdvCan.DeviceIoControl(hDevice, AdvCan.CAN_IOCTL_CONFIG, lpConfigBuffer, AdvCan.CAN_CONFIG_LENGTH, IntPtr.Zero, 0, ref OutLen, GCIoctl.AddrOfPinnedObject());
            if (!flag)
            {
                return(OPERATION_ERROR);
            }
            return(SUCCESS);
        }
        /*****************************************************************************
        *
        *    acSetSelfReception
        *
        *    Purpose:
        *        Set support for self reception
        *
        *
        *    Arguments:
        *        SelfFlag      - true, open self reception; false, close self reception
        *    Returns:
        *        =0 SUCCESS; or <0 failure
        *
        *****************************************************************************/
        public int acSetSelfReception(bool SelfFlag)
        {
            bool flag;

            Config.target = AdvCan.CONF_SELF_RECEPTION;
            if (SelfFlag)
            {
                Config.val1 = 1;
            }
            else
            {
                Config.val1 = 0;
            }
            Marshal.StructureToPtr(Config, lpConfigBuffer, true);
            flag = AdvCan.DeviceIoControl(hDevice, AdvCan.CAN_IOCTL_CONFIG, lpConfigBuffer, AdvCan.CAN_CONFIG_LENGTH, IntPtr.Zero, 0, ref OutLen, GCIoctl.AddrOfPinnedObject());
            if (!flag)
            {
                return(OPERATION_ERROR);
            }
            return(SUCCESS);
        }