Ejemplo n.º 1
0
        public bool CAN_OpenChannel(int mode)
        {
            int _hnd = -1;

            if (mode == 0)
            {
                _hnd = Canlib.canOpenChannel(this._Channel, Canlib.canOPEN_ACCEPT_LARGE_DLC);
            }
            else
            {
                _hnd = Canlib.canOpenChannel(this._Channel, Canlib.canOPEN_ACCEPT_LARGE_DLC);
            }

            if (_hnd >= 0)
            {
                this.handle = _hnd;
                Canlib.canAccept(handle, 0x7DF, Canlib.canFILTER_SET_CODE_STD);
                Canlib.canAccept(handle, 0x7D0, Canlib.canFILTER_SET_MASK_STD);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 2
0
        public bool CanLongMsgSend(int id, byte[] data, int datalength, int retrycount, double timeout, ref int EcuID, ref byte[] READDATA, ref string errmsg)
        {
            if ((datalength < 9) || (data.Length < 9))
            {
                errmsg = "Command Data Length <=8";
                return(false);
            }

            bool _LoopChk = true;
            int  _EcuID;

            byte[] _EcuData = new byte[8];
            int    _EcuDlc;
            int    _EcuFlags;
            long   _EcuTime;

            int    _Ecu_FS    = -1; // 정상적으로 수신시 확인되는 값, FS FlowStatus, BS BlockSize, STmin
            int    _Ecu_BS    = 0;
            int    _Ecu_STmin = 0;
            double _Ecu_Stmin_sec; // 소수점단위 계산
            bool   _Ecu_FlowControl_Receive_OK = false;

            byte[] _Data_FF           = new byte[8];
            byte[] _Data_CF           = new byte[8];
            int    _LastSendDataIndex = 0;

            Canlib.canStatus status;
            Stopwatch        _stopwatch_total = new Stopwatch();
            Stopwatch        _stopwatch_send  = new Stopwatch();

            // 명령 만들기
            _Data_FF[0] = 0x10;

            Int32 _DataLength_12bit = 0x00000000;

            _DataLength_12bit = (Int32)datalength;
            _DataLength_12bit = _DataLength_12bit & 0x00000FFF;

            byte byte1Lownibble;
            byte byte2;

            byte1Lownibble = (byte)((_DataLength_12bit & 0x00000F00) >> 16);
            byte2          = (byte)(_DataLength_12bit & 0x000000FF);

            _Data_FF[0] = (byte)(0x10 | byte1Lownibble);
            _Data_FF[1] = byte2;
            _Data_FF[2] = data[0];
            _Data_FF[3] = data[1];
            _Data_FF[4] = data[2];
            _Data_FF[5] = data[3];
            _Data_FF[6] = data[4];
            _Data_FF[7] = data[5];

            _LastSendDataIndex = 6;
            //
            //Canlib.canBusOn(handle);
            //status = Canlib.canWrite(handle, id, _Data_FF, 8, flags);
            //Open up a new handle for reading
            readHandle = Canlib.canOpenChannel(channel, Canlib.canOPEN_ACCEPT_LARGE_DLC);
            status     = Canlib.canAccept(readHandle, 0x7DF, Canlib.canFILTER_SET_CODE_STD);
            status     = Canlib.canAccept(readHandle, 0x7D0, Canlib.canFILTER_SET_MASK_STD);
            status     = Canlib.canBusOn(readHandle);
            if (status == Canlib.canStatus.canOK)
            {
                onBus = true;
            }
            else
            {
                onBus = false;
            }
            if (readHandle < 0)
            {
                errmsg = "canOpenChannel Handle create error";
                return(false);
            }
            if (!onBus)
            {
                errmsg = "onBus false";
                return(false);
            }
            _stopwatch_total.Reset();
            _stopwatch_total.Start();
            _stopwatch_send.Reset();
            _stopwatch_send.Start();
            // Receive Channel Open -> SEND
            Canlib.canBusOn(handle);
            status = Canlib.canWrite(handle, id, _Data_FF, 8, flags);
            while (_LoopChk)
            {
                // TimeOut Check
                long   st            = _stopwatch_total.ElapsedMilliseconds;
                double _durationtime = st / 1000.0;  // ms -> sec
                if (_durationtime > timeout)
                {
                    // 설정시간안에 메세지 및 처리를 못했을 경우 종료
                    errmsg   = "timeout error";
                    _LoopChk = false;
                    break;
                }
                // Message Recieve Check
                bool _RecvOK = false;
                status = Canlib.canReadWait(readHandle, out _EcuID, _EcuData, out _EcuDlc, out _EcuFlags, out _EcuTime, 100); // 100ms timeout
                if (status == Canlib.canStatus.canOK)
                {
                    if ((_EcuFlags & Canlib.canMSG_ERROR_FRAME) == Canlib.canMSG_ERROR_FRAME)
                    {
                        errmsg = "***ERROR FRAME RECEIVED***";
                    }
                    else
                    {
                        errmsg = String.Format("ID={0:X4}  {1}  {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2}   {10}\r",
                                               _EcuID, _EcuDlc, _EcuData[0], _EcuData[1], _EcuData[2], _EcuData[3], _EcuData[4],
                                               _EcuData[5], _EcuData[6], _EcuData[7], _EcuTime);
                        if (_EcuID == 0x07D9)
                        {
                            _RecvOK = true;
                        }
                    }
                }
                else if (status != Canlib.canStatus.canERR_NOMSG)
                {
                    errmsg = "TimeOut:NO MSG";
                }
                //CheckStatus("Read message " + errmsg, status);
                //Canlib.canBusOff(readHandle);
                if ((_EcuID == 0x07D9) && (_RecvOK))
                {
                    byte EcuFC_Check = _EcuData[0];
                    EcuFC_Check = (byte)((EcuFC_Check & 0x00F0) >> 4);
                    if (EcuFC_Check == 3)
                    {
                        _LoopChk   = false;
                        _Ecu_FS    = (_EcuData[0] & 0x000F);
                        _Ecu_BS    = (int)(_EcuData[1] & 0x00FF);
                        _Ecu_STmin = (int)(_EcuData[2] & 0x00FF);
                        if (_Ecu_STmin <= 0x7F)
                        {
                            _Ecu_Stmin_sec = _Ecu_STmin * 0.001;
                        }
                        if (_Ecu_STmin >= 0xF1)
                        {
                            _Ecu_Stmin_sec = (_Ecu_STmin - 0xF0) * 0.0001;
                        }
                        _Ecu_FlowControl_Receive_OK = true;
                    }
                    string sndmsg = String.Format("ID={0:X4}  {1}  {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2}\r",
                                                  id, 8, _Data_FF[0], _Data_FF[1], _Data_FF[2], _Data_FF[3], _Data_FF[4],
                                                  _Data_FF[5], _Data_FF[6], _Data_FF[7]);
                    CheckStatus("PC->ECU " + sndmsg, Canlib.canStatus.canOK);
                    CheckStatus("ECU->PC " + errmsg, status);
                }
            }

            Canlib.canClose(readHandle);

            if (!_Ecu_FlowControl_Receive_OK)
            {
                errmsg = "Ecu FlowControl not arrived";
                return(false);
            }
            if (_Ecu_FS > 0)
            {
                errmsg = "Ecu FlowControl signal Busy";
                return(false);
            }



            // ECU에서 FC를 정상적으로 수신후 데이터 전송....
            _stopwatch_total.Reset();
            _stopwatch_total.Start();
            _stopwatch_send.Reset();
            _stopwatch_send.Start();
            _LoopChk = true;
            int  _SequenceNumber     = 1;
            byte _SN                 = (byte)_SequenceNumber;
            int  _BlockSendLoopCount = _Ecu_BS;

            Canlib.canBusOn(handle);
            bool _EcuLastReceiveOK = false;

            // CF 전송후 수신확인.
            //Open up a new handle for reading
            readHandle = Canlib.canOpenChannel(channel, Canlib.canOPEN_ACCEPT_LARGE_DLC);
            status     = Canlib.canAccept(readHandle, 0x7DF, Canlib.canFILTER_SET_CODE_STD);
            status     = Canlib.canAccept(readHandle, 0x7D0, Canlib.canFILTER_SET_MASK_STD);
            status     = Canlib.canBusOn(readHandle);
            if (status == Canlib.canStatus.canOK)
            {
                onBus = true;
            }
            else
            {
                onBus = false;
            }
            if (readHandle < 0)
            {
                errmsg = "canOpenChannel Handle create error";
                return(false);
            }
            if (!onBus)
            {
                errmsg = "onBus false";
                return(false);
            }

            while (_LoopChk)
            {
                // TimeOut Check
                long   st            = _stopwatch_total.ElapsedMilliseconds;
                double _durationtime = st / 1000.0;  // ms -> sec
                if (_durationtime > timeout)
                {
                    // 설정시간안에 메세지 및 처리를 못했을 경우 종료
                    errmsg   = "timeout error";
                    _LoopChk = false;
                    break;
                }
                if (datalength < _LastSendDataIndex)
                {
                    _LoopChk = false;
                    break;
                }
                _stopwatch_send.Reset();
                _stopwatch_send.Start();
                // CF 전송
                for (int hs = 0; hs < _BlockSendLoopCount; hs++)
                {
                    // FF전송후 CF 데이터 전송 준비
                    _Data_CF[0] = 0x20;
                    _Data_CF[0] = (byte)(_Data_CF[0] + _SN);
                    for (int i = 0; i < 7; i++)
                    {
                        if (_LastSendDataIndex < datalength)
                        {
                            _Data_CF[1 + i] = data[_LastSendDataIndex];
                        }
                        else
                        {
                            _Data_CF[1 + i] = 0x00; // 0xAA;
                        }
                        _LastSendDataIndex++;
                    }
                    _SN++;
                    if (_SN > 16)
                    {
                        _SN = 0;
                    }
                    status = Canlib.canWrite(handle, id, _Data_CF, 8, flags);
                    long   _dt    = _stopwatch_send.ElapsedMilliseconds;
                    string sndmsg = String.Format("ID={0:X4}  {1}  {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2}   {10:D5}ms\r",
                                                  id, 8, _Data_CF[0], _Data_CF[1], _Data_CF[2], _Data_CF[3], _Data_CF[4],
                                                  _Data_CF[5], _Data_CF[6], _Data_CF[7], _dt);
                    CheckStatus("PC->ECU " + sndmsg, status);
                    break; // Only One Run-----------------------------------------------실제 전송될 데이터 길이만큼만 전송함----------------------------------------------------------
                }


                // Message Recieve Check
                bool _RecvOK = false;

                bool      _FinalReceiveCheck = true;
                Stopwatch _Final             = new Stopwatch();
                _Final.Reset();
                _Final.Start();
                while (_FinalReceiveCheck)
                {
                    if ((_Final.ElapsedMilliseconds / 1000.0) > 3.0)
                    {
                        errmsg             = "Finnal ECU Receive Msg TIMEOUT";
                        _FinalReceiveCheck = false;
                        break;
                    }
                    status = Canlib.canReadWait(readHandle, out _EcuID, _EcuData, out _EcuDlc, out _EcuFlags, out _EcuTime, 100); // 100ms timeout
                    if (status == Canlib.canStatus.canOK)
                    {
                        if ((_EcuFlags & Canlib.canMSG_ERROR_FRAME) == Canlib.canMSG_ERROR_FRAME)
                        {
                            errmsg = "***ERROR FRAME RECEIVED***";
                        }
                        else
                        {
                            errmsg = String.Format("ID={0:X4}  {1}  {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2}   {10}\r",
                                                   _EcuID, _EcuDlc, _EcuData[0], _EcuData[1], _EcuData[2], _EcuData[3], _EcuData[4],
                                                   _EcuData[5], _EcuData[6], _EcuData[7], _EcuTime);
                            if (_EcuID == 0x07D9)
                            {
                                _RecvOK = true;
                                CheckStatus("ECU->PC " + errmsg, status);
                            }
                        }
                    }
                    else if (status != Canlib.canStatus.canERR_NOMSG)
                    {
                        errmsg = "TimeOut:NO MSG";
                    }
                    //CheckStatus("Read message " + errmsg, status);
                    //Canlib.canBusOff(readHandle);
                    if ((_EcuID == 0x07D9) && (_RecvOK))
                    {
                        Canlib.canBusOn(handle);
                        byte[] temp = new byte[8] {
                            0x30, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
                        };
                        status = Canlib.canWrite(handle, 0x07D1, _Data_FF, 8, flags);
                        CheckStatus("PC->ECU " + "PC AutoResponse(0x30,0x00,0x02,0xAA,0xAA,0xAA,0xAA,0xaa", status);
                        Canlib.canBusOff(handle);
                        status = Canlib.canReadWait(readHandle, out _EcuID, _EcuData, out _EcuDlc, out _EcuFlags, out _EcuTime, 100);
                        if (status == Canlib.canStatus.canOK)
                        {
                            errmsg = String.Format("ID={0:X4}  {1}  {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2}   {10}\r",
                                                   _EcuID, _EcuDlc, _EcuData[0], _EcuData[1], _EcuData[2], _EcuData[3], _EcuData[4],
                                                   _EcuData[5], _EcuData[6], _EcuData[7], _EcuTime);
                            if (_EcuID == 0x07D9)
                            {
                                _RecvOK = true;
                                CheckStatus("ECU->PC " + errmsg, status);
                            }
                        }
                        _FinalReceiveCheck = false;
                        _EcuLastReceiveOK  = true;
                        _LoopChk           = false;
                        break;
                    }
                }
            }
            if (readHandle >= 0)
            {
                Canlib.canClose(readHandle);
            }
            if (_EcuLastReceiveOK)
            {
                if (_EcuData[1] == 0x62)
                {
                    return(true);
                }
                return(false);
            }
            else
            {
                return(false);
            }
        }
        /*
         * Looks for messages and sends them to the output box.
         */
        void Receiver_MessageHandlerLoop(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            Canlib.canStatus status  = Canlib.canStatus.canERR_NOMSG;
            bool             noError = true;
            int errorFrameCount      = 0;

            //Create a Windows event handle
            Object winHandle = new IntPtr(-1);

            status = Canlib.canIoCtl(readHandle, Canlib.canIOCTL_GET_EVENTHANDLE, ref winHandle);
            if (status != Canlib.canStatus.canOK)
            {
                worker.ReportProgress((int)ReceiverReport.ERROR_STOP, status);
                noError = false;
            }
            status = Canlib.canAccept(readHandle, 0x610, Canlib.canFILTER_SET_CODE_STD);
            if (status != Canlib.canStatus.canOK)
            {
                worker.ReportProgress((int)ReceiverReport.ERROR_STOP, status);
                noError = false;
            }
            status = Canlib.canAccept(readHandle, 0xFFE, Canlib.canFILTER_SET_MASK_STD);
            if (status != Canlib.canStatus.canOK)
            {
                worker.ReportProgress((int)ReceiverReport.ERROR_STOP, status);
                noError = false;
            }

            WaitHandle waitHandle = (WaitHandle) new CanlibWaitEvent(winHandle);

            while (noError && isReaderBusOn && readHandle >= 0)
            {
                //Wait for 25ms for an event to occur on the channel (BBMS CAN communication period: 25ms)
                bool eventHappened = waitHandle.WaitOne(25);
                if (!eventHappened)
                {
                    continue;
                }

                int    id;
                byte[] data = new byte[Defined.MAX_DLC];
                int    dlc;
                int    flags;
                long   time;
                string msgLog;

                //To attain the initial msg
                status = Canlib.canRead(readHandle, out id, data, out dlc, out flags, out time);

                //This while loop is to repeat canRead() until the msg boxes for readHandle becomes exhausted.
                while (status == Canlib.canStatus.canOK)
                {
                    if ((flags & Canlib.canMSG_ERROR_FRAME) == Canlib.canMSG_ERROR_FRAME)
                    {
                        msgLog = "***ERROR FRAME RECEIVED*** Count = " + (++errorFrameCount);
                        if (errorFrameCount > Defined.ERROR_FRAME_ENDURANCE_COUNT_LIMIT)
                        {
                            worker.ReportProgress((int)ReceiverReport.REPORT_RUNNING, "Too many error frames received. Bus off.");
                            break;
                        }
                    }
                    else
                    {
                        msgLog = String.Format("0x{0:x3}  {1}  {2:x2} {3:x2} {4:x2} {5:x2} {6:x2} {7:x2} {8:x2} {9:x2}   @{10}",
                                               id, dlc, data[0], data[1], data[2], data[3], data[4],
                                               data[5], data[6], data[7], time);
                    }

                    //Sends the message to the ProcessMessage method
                    worker.ReportProgress((int)ReceiverReport.REPORT_RUNNING, "[Rx] " + msgLog);

                    //Result status of the following canRead() will finish the while loop if status!=Canlib.canStatus.canOK
                    status = Canlib.canRead(readHandle, out id, data, out dlc, out flags, out time);
                }

                //If the reason to exit the while loop of canRead() was not canERR_NOMSG, an error is expected.
                if (status != Canlib.canStatus.canERR_NOMSG)
                {
                    //Sends the error status to the ProcessMessage method and breaks the loop
                    worker.ReportProgress((int)ReceiverReport.ERROR_STOP, status);
                    noError = false;
                }
            }
            if (isReaderBusOn)
            {
                worker.ReportProgress((int)ReceiverReport.FORCED_STOP, "Force Bus Off");
            }
        }