예제 #1
0
        /*        public CANMessage waitForMessage(uint a_canID, int a_timeout)
        {
            CANMessage retMsg;
            m_canMessage.setID(0);  // init so we cannot receive the same frame twice <GS-10022010>
            lock (m_canMessage)
            {
                m_waitMsgID = a_canID;
            }
            m_resetEvent.WaitOne(a_timeout, true);
            lock (m_canMessage)
            {
                retMsg = m_canMessage;
            }

            return retMsg;
        }
        */
        public override void handleMessage(CANMessage a_message)
        {
            lock (m_canMessage)
            {
                if (a_message.getID() == m_waitMsgID)
                {
                    m_canMessage.setData(a_message.getData());
                    m_canMessage.setFlags(a_message.getFlags());
                    m_canMessage.setID(a_message.getID());
                    m_canMessage.setLength(a_message.getLength());
                    m_canMessage.setTimeStamp(a_message.getTimeStamp());
                    m_resetEvent.Set();
                }
            }
        }
예제 #2
0
 /// <summary>
 /// This message sends a CANMessage to the CAN device.
 /// The open method must have been called and returned possitive result
 /// before this method is called.
 /// </summary>
 /// <param name="a_message">The CANMessage</param>
 /// <returns>true on success, otherwise false.</returns>
 public abstract bool sendMessage(CANMessage a_message);
예제 #3
0
        /// <summary>
        /// Send a message that starts a session. This is used to test if there is 
        /// a connection.
        /// </summary>
        /// <returns></returns>
        private bool sendSessionRequest()
        {
            CANMessage msg1 = new CANMessage(0x220, 0, 8);
            LAWICEL.CANMsg msg = new LAWICEL.CANMsg();
            msg1.setData(0x000040021100813f);

            if (!sendMessage(msg1))
                return false;
            if (waitForMessage(0x238, 1000, out msg) == 0x238)
            {
                //Ok, there seems to be a ECU somewhere out there.
                //Now, sleep for 10 seconds to get a session timeout. This is needed for
                //applications on higher level. Otherwise there will be no reply when the
                //higher level application tries to start a session.
                Thread.Sleep(10000);
                return true;
            }
            return false;
        }
예제 #4
0
 /// <summary>
 /// sendMessage send a CANMessage.
 /// </summary>
 /// <param name="a_message">A CANMessage.</param>
 /// <returns>true on success, othewise false.</returns>
 public override bool sendMessage(CANMessage a_message)
 {
     LAWICEL.CANMsg msg = new LAWICEL.CANMsg();
     msg.id = a_message.getID();
     msg.len = a_message.getLength();
     msg.flags = a_message.getFlags();
     msg.data = a_message.getData();
     int writeResult;
     AddToCanTrace("Sending message");
     writeResult = LAWICEL.canusb_Write(m_deviceHandle, ref msg);
     if (writeResult == LAWICEL.ERROR_CANUSB_OK)
     {
         AddToCanTrace("Message sent successfully");
         return true;
     }
     else
     {
         switch (writeResult)
         {
             case LAWICEL.ERROR_CANUSB_COMMAND_SUBSYSTEM:
                 AddToCanTrace("Message failed to send: ERROR_CANUSB_COMMAND_SUBSYSTEM");
                 break;
             case LAWICEL.ERROR_CANUSB_INVALID_PARAM:
                 AddToCanTrace("Message failed to send: ERROR_CANUSB_INVALID_PARAM");
                 break;
             case LAWICEL.ERROR_CANUSB_NO_MESSAGE:
                 AddToCanTrace("Message failed to send: ERROR_CANUSB_NO_MESSAGE");
                 break;
             case LAWICEL.ERROR_CANUSB_NOT_OPEN:
                 AddToCanTrace("Message failed to send: ERROR_CANUSB_NOT_OPEN");
                 break;
             case LAWICEL.ERROR_CANUSB_OPEN_SUBSYSTEM:
                 AddToCanTrace("Message failed to send: ERROR_CANUSB_OPEN_SUBSYSTEM");
                 break;
             case LAWICEL.ERROR_CANUSB_TX_FIFO_FULL:
                 AddToCanTrace("Message failed to send: ERROR_CANUSB_TX_FIFO_FULL");
                 break;
             default:
                 AddToCanTrace("Message failed to send: " + writeResult.ToString());
                 break;
         }
         return false;
     }
 }
예제 #5
0
 /// <summary>
 /// readMessages is the "run" method of this class. It reads all incomming messages
 /// and publishes them to registered ICANListeners.
 /// </summary>
 public void readMessages()
 {
     int readResult = 0;
     LAWICEL.CANMsg r_canMsg = new LAWICEL.CANMsg();
     CANMessage canMessage = new CANMessage();
     while (true)
     {
         lock (m_synchObject)
         {
             if (m_endThread)
                 return;
         }
         readResult = LAWICEL.canusb_Read(m_deviceHandle, out r_canMsg);
         if (readResult == LAWICEL.ERROR_CANUSB_OK)
         {
             canMessage.setID(r_canMsg.id);
             canMessage.setLength(r_canMsg.len);
             canMessage.setTimeStamp(r_canMsg.timestamp);
             canMessage.setFlags(r_canMsg.flags);
             canMessage.setData(r_canMsg.data);
             lock (m_listeners)
             {
                 foreach (ICANListener listener in m_listeners)
                 {
                     listener.handleMessage(canMessage);
                 }
             }
         }
         else if (readResult == LAWICEL.ERROR_CANUSB_NO_MESSAGE)
         {
             Thread.Sleep(1);
         }
     }
 }
예제 #6
0
        //-------------------------------------------------------------------------
        /**
        Tries to connect to CAN bus using the specified bitrate.

        @param      bitrate     bitrate

        @return                 succ / fail
        */
        private bool try_bitrate(uint bitrate)
        {
            try
            {
            // try connecting
            this.combi.CAN_SetBitrate(bitrate);
            this.combi.CAN_Open(true);

            // look for bus activity
            CANMessage msg = new CANMessage();
            Debug.Assert(msg != null);

            if (this.waitForMessage(0, 1000, out msg) < 1)
            {
                throw new Exception("No traffic at given bitrate");
            }

            return true;
            }

            catch
            {
            // failed
            this.combi.CAN_Open(false);
            return false;
            }
        }
예제 #7
0
        //-------------------------------------------------------------------------
        /**
        Waits for arrival of a specific CAN message or any message if ID = 0.

        @param      a_canID     message ID
        @param      timeout     timeout, ms
        @param      canMsg      message

        @return                 message ID
        */
        public uint waitForMessage(uint a_canID, uint timeout,
        out CANMessage canMsg)
        {
            canMsg = new CANMessage();
            Debug.Assert(canMsg != null);
            canMsg.setID(0);

            caCombiAdapter.caCANFrame frame = new caCombiAdapter.caCANFrame();
            if (this.combi.CAN_GetMessage(ref frame, timeout) &&
            (frame.id == a_canID || a_canID == 0))
            {
            // message received
            canMsg.setID(frame.id);
            canMsg.setLength(frame.length);
            canMsg.setData(frame.data);

            return frame.id;
            }

            // timed out
            return 0;
        }
예제 #8
0
        //-------------------------------------------------------------------------
        /**
        Sends a 11 bit CAN data frame.

        @param      msg         CAN message

        @return                 success (true/false)
        */
        public override bool sendMessage(CANMessage msg)
        {
            this.AddToCanTrace("Sending message: " + msg.getID().ToString("X4") +
            " " + msg.getData().ToString("X16"));

            try
            {
            Combi.caCombiAdapter.caCANFrame frame;
            frame.id = msg.getID();
            frame.length = msg.getLength();
            frame.data = msg.getData();
            frame.is_extended = 0;
            frame.is_remote = 0;

            this.combi.CAN_SendMessage(ref frame);

            this.AddToCanTrace("Message sent successfully");
            return true;
            }

            catch (Exception e)
            {
            this.AddToCanTrace("Message failed to send: " + e.Message);
            return false;
            }
        }
예제 #9
0
 /// <summary>
 /// This method is called by ICANDevices where derived objects of this class
 /// are registered. The method is called for each received CANMessage.
 /// What this method does is application dependent.
 /// </summary>
 /// <param name="a_canMessage">The CANMessage to be handled by this method.</param>
 public abstract void handleMessage(CANMessage a_canMessage);
예제 #10
0
 /// <summary>
 /// Send an acknowledgement message.
 /// </summary>
 /// <param name="a_rowNr">The row number that should be acknowledged.</param>
 private void sendAck(uint a_rowNr)
 {
     CANMessage msg = new CANMessage(0x266,0,8);
     uint i = 0;
     ulong data = 0;
     data = setCanData(data, (byte)0x40, i++);
     data = setCanData(data, (byte)0xA1, i++);
     data = setCanData(data, (byte)0x3F, i++);
     data = setCanData(data, (byte)(0x80 | (int)(a_rowNr)), i++);
     msg.setData(data);
     if (!m_canDevice.sendMessage(msg))
         throw new Exception("Error sending ack");
 }
예제 #11
0
        /// <summary>
        /// Start a KWP session.
        /// </summary>
        /// <remarks>
        /// A KWP session must be started before any requests can be sent.
        /// </remarks>
        /// <returns>True if the session was started, otherwise false.</returns>
        public bool startSession()
        {
            CANMessage msg = new CANMessage(0x220, 0, 8);
            msg.setData(0x000040021100813F);
            AddToCanTrace("Sending 0x000040021100813F message");

            m_kwpCanListener.setupWaitMessage(0x238);

            if (!m_canDevice.sendMessage(msg))
            {
                AddToCanTrace("Unable to send 0x000040021100813F message");
                return false;
            }
            Console.WriteLine("Init msg sent");
            if (m_kwpCanListener.waitMessage(timeoutPeriod).getID() == 0x238)
            {
                AddToCanTrace("Successfully sent 0x000040021100813F message and received reply 0x238");
                return true;
            }
            else
            {
                AddToCanTrace("Didn't receive 0x238 message as reply on 0x000040021100813F message");
                return false;
            }

            /*          if (!m_canDevice.sendMessage(msg))
            {
                AddToCanTrace("Unable to send 0x000040021100813F message");
                return false;
            }
            Console.WriteLine("Init msg sent");
            if (m_kwpCanListener.waitForMessage(0x238, timeoutPeriod).getID() == 0x238)
            {
                AddToCanTrace("Successfully sent 0x000040021100813F message and received reply 0x238");
                return true;
            }
            else
            {
                AddToCanTrace("Didn't receive 0x238 message as reply on 0x000040021100813F message");
                return false;
            }
            */
        }
예제 #12
0
        /// <summary>
        /// Send a KWP request.
        /// </summary>
        /// <param name="a_request">A KWP request.</param>
        /// <param name="r_reply">A KWP reply.</param>
        /// <returns>The status of the request.</returns>
        public RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply)
        {
            CANMessage msg = new CANMessage(0x240, 0, 8);
            uint row = nrOfRowsToSend(a_request.getData());

            m_kwpCanListener.setupWaitMessage(0x258);

            // Send one or several request messages.
            for (; row > 0; row--)
            {
                msg.setData(createCanMessage(a_request.getData(), row - 1));
                if (!m_canDevice.sendMessage(msg))
                {
                    r_reply = new KWPReply();
                    return RequestResult.ErrorSending;
                }
            }

            msg = m_kwpCanListener.waitMessage(timeoutPeriod);
             //         msg = m_kwpCanListener.waitForMessage(0x258, timeoutPeriod);

            // Receive one or several replys and send an ack for each reply.
            if (msg.getID() == 0x258)
            {
                uint nrOfRows = (uint)(msg.getCanData(0) & 0x3F)+ 1;
                row = 0;
                if (nrOfRows == 0)
                    throw new Exception("Wrong nr of rows");
                //Assume that no KWP reply contains more than 0x200 bytes
                byte[] reply = new byte[0x200];
                reply = collectReply(reply, msg.getData(), row);
                sendAck(nrOfRows - 1);
                nrOfRows--;

                m_kwpCanListener.setupWaitMessage(0x258);

                while (nrOfRows > 0)
                {
            //                    msg = m_kwpCanListener.waitForMessage(0x258, timeoutPeriod);
                    msg = m_kwpCanListener.waitMessage(timeoutPeriod);
                    if (msg.getID() == 0x258)
                    {
                        row++;
                        reply = collectReply(reply, msg.getData(), row);
                        sendAck(nrOfRows - 1);
                        nrOfRows--;
                    }
                    else
                    {
                        r_reply = new KWPReply();
                        return RequestResult.Timeout;
                    }

                }
                r_reply = new KWPReply(reply, a_request.getNrOfPID());
                return RequestResult.NoError;
            }
            else
            {
                r_reply = new KWPReply();
                return RequestResult.Timeout;
            }
        }
예제 #13
0
 /// <summary>
 /// This message sends a CANMessage to the CAN device.
 /// The open method must have been called and returned possitive result
 /// before this method is called.
 /// </summary>
 /// <param name="a_message">The CANMessage</param>
 /// <returns>true on success, otherwise false.</returns>
 abstract public bool sendMessage(CANMessage a_message);
예제 #14
0
 /// <summary>
 /// This method is called by ICANDevices where derived objects of this class
 /// are registered. The method is called for each received CANMessage.
 /// What this method does is application dependent.
 /// </summary>
 /// <param name="a_canMessage">The CANMessage to be handled by this method.</param>
 public abstract void handleMessage(CANMessage a_canMessage);