Пример #1
0
        /// <summary>
        /// Request to read bytes from memory map
        /// </summary>
        /// <param name="serial">A double precision number.</param>
        /// <param name="addres">A double precision number.</param>
        /// <param name="bytesToRead">A double precision number.</param>
        /// <param name="timeut">A double precision number.</param>
        /// <returns>
        /// Memory Map values from read address request
        /// </returns>
        /// <example>
        /// <code>
        /// lx.Read(new USBSerial("COM5"), 0, 1, 400)
        /// </code>
        /// </example>
        /// <exception cref="System.TimeoutException">Thrown response Timeout is reached </exception>
        /// <exception cref="System.IO.InvalidDataException">Thrown when response data or CRC is not valid </exception>
        /// See <see cref="Read(UInt32 addres, uint data)"/> to add doubles.
        /// <seealso cref="Write(byte addres, byte[] data)"/>
        /// <seealso cref="Write(ISerial serial, UInt32 addres, byte[] data, int timeout)"/>
        private async Task <byte[]> Read(ISerial serial, UInt32 address, uint bytesToRead, int timeout)
        {
            int TEST = new Random().Next(0, 999);

            Utils.PrintDeep(Environment.NewLine + "--------LEXI_READ-------| " + TEST + " |--");
            Utils.PrintDeep("Lexi.Read = Write + UpdateBuffer + Read");

            try
            {
                byte[] stream;
                var    info = GeneratePackage(LexiAction.Read, out stream, address, null, bytesToRead);

                Utils.PrintDeep("Lexi.Read.. " +
                                "Stream = " +
                                "0x" + info.header + " ( " + Convert.ToInt32(info.header, 16) + " ) + " +
                                "WriteCmd 0x" + info.cmd + " ( " + Convert.ToInt32(info.cmd, 16) + " ) + " +
                                "Address 0x" + info.startAddress + " ( " + Convert.ToInt32(info.startAddress, 16) + " ) + " +
                                "Checksum 0x" + info.checksum + " ( " + Convert.ToInt32(info.checksum, 16) + " )");

                Utils.PrintDeep("Lexi.Read.. " + Utils.ByteArrayToString(stream).Trim() + " [ Length " + stream.Length + " ]");

                // Send Lexi Read command
                await serial.Write(stream, 0, stream.Length);

                Utils.PrintDeep("------BUFFER_START-------");

                //define response buffer size
                byte[] rawBuffer    = new byte[0];
                int    headerOffset = (serial.isEcho()) ? stream.Length : 0;
                Array.Resize(ref rawBuffer, headerOffset + ( int )bytesToRead + 2);    // Package + Data + ACK

                Utils.PrintDeep("Lexi.Read -> Array.Resize.." +
                                " Echo " + serial.isEcho() +
                                " [ " + rawBuffer.Length + " = " + bytesToRead + " + Header " + headerOffset + " + CRC 2 ]");

                // Whait untill the response buffer data is available or timeout limit is reached
                long timeout_limit = DateTimeOffset.Now.ToUnixTimeMilliseconds() + (timeout);
                await Task.Run(() =>
                {
                    while (checkResponseOk(serial, rawBuffer))
                    {
                        if (DateTimeOffset.Now.ToUnixTimeMilliseconds() > timeout_limit)
                        {
                            int num = serial.BytesReadCount();

                            Utils.PrintDeep("Lexi.Read -> BytesToRead: " + num);

                            if (num <= headerOffset)
                            {
                                Utils.PrintDeep("Lexi.Read -> CheckResponseOk IOException");

                                throw new IOException();
                            }
                            else
                            {
                                Utils.PrintDeep("Lexi.Read -> CheckResponseOk TimeoutException");

                                throw new TimeoutException();
                            }
                        }
                        Thread.Sleep(10);
                    }
                });

                Utils.PrintDeep("------BUFFER_FINISH------");

                //read the response buffer
                serial.Read(rawBuffer, 0, rawBuffer.Length);

                /*
                 * +------------+-------+---------------+--------------------------------------------------------+
                 * | Byte Index | Field |   Value(s)    |                         Notes                          |
                 * +------------+-------+---------------+--------------------------------------------------------+
                 * | 0..N-1     | Data  | Read from RAM | N = number of bytes specified in Data field of Request |
                 * | N..N+1     | CRC   | Calculated    | CRC over all data bytes.  See section 7.2              |
                 * +------------+-------+---------------+--------------------------------------------------------+
                 */

                // Removes header and get only the ACK
                byte[] response = new byte[2];
                Array.Resize(ref response, response.Length + ( int )bytesToRead);
                Array.Copy(rawBuffer, headerOffset, response, 0, response.Length);

                Utils.PrintDeep("Lexi.Read ->" +
                                " CheckCRC " + Utils.ByteArrayToString(response) +
                                " [ " + response.Length + " = BytesToRead " + bytesToRead + " + ACK 2 ]");

                // Validates CRC and if everything is ok, returns recovered data
                return(validateReadResponse(response, bytesToRead));
            }
            catch (Exception e)
            {
                throw new LexiReadingException();
            }
            finally
            {
                Utils.PrintDeep("----LEXI_READ_FINISH----| " + TEST + " |--" + Environment.NewLine);
            }
        }