/// <summary>
        /// Read a complete memory page with CRC verification provided by the
        /// device with extra information.  Not supported by all devices.
        /// If not extra information available then just call with extraLength=0.
        /// </summary>
        /// <param name="page">          page number to read </param>
        /// <param name="readContinue">  if 'true' then device read is continued without
        ///                       re-selecting.  This can only be used if the new
        ///                       readPagePacket() continious where the last one
        ///                       stopped and it is inside a
        ///                       'beginExclusive/endExclusive' block. </param>
        /// <param name="readBuf">       byte array to put data read. Must have at least
        ///                       'getMaxPacketDataLength()' elements. </param>
        /// <param name="offset">        offset into readBuf to place data </param>
        /// <param name="extraInfo">     byte array to put extra info read into </param>
        /// <param name="extraLength">   length of extra information
        /// </param>
        /// <exception cref="OneWireIOException"> </exception>
        /// <exception cref="OneWireException"> </exception>
        protected internal override void readPageCRC(int page, bool readContinue, byte[] readBuf, int offset, byte[] extraInfo, int extraLength)
        {
            int last_crc = 0;

            byte[] raw_buf;
            byte   temp;

            // only needs to be implemented if supported by hardware
            if (!pageAutoCRC)
            {
                throw new OneWireException("Read page with CRC not supported in this memory bank");
            }

            // attempt to put device at max desired speed
            if (!readContinue)
            {
                sp.checkSpeed();
            }

            // check if read exceeds memory
            if (page > numberPages)
            {
                throw new OneWireException("Read exceeds memory bank end");
            }

            // see if need to access the device
            if (!readContinue || !readContinuePossible)
            {
                // select the device
                if (!ib.adapter.select(ib.address))
                {
                    sp.forceVerify();

                    throw new OneWireIOException("Device select failed");
                }

                // build start reading memory block
                raw_buf    = new byte[11];
                raw_buf[0] = READ_MEMORY_CRC_PW_COMMAND;

                int addr = page * pageLength + startPhysicalAddress;

                raw_buf[1] = unchecked ((byte)(addr & 0xFF));
                raw_buf[2] = unchecked ((byte)(((int)((uint)(addr & 0xFFFF) >> 8)) & 0xFF));

                if (ibPass.ContainerReadWritePasswordSet)
                {
                    ibPass.getContainerReadWritePassword(raw_buf, 3);
                }
                else
                {
                    ibPass.getContainerReadOnlyPassword(raw_buf, 3);
                }

                // perform CRC16 on first part (without the password)
                last_crc = CRC16.compute(raw_buf, 0, 3, last_crc);

                // do the first block for command, TA1, TA2, and password

                if (enablePower)
                {
                    ib.adapter.dataBlock(raw_buf, 0, 10);

                    ib.adapter.startPowerDelivery(DSPortAdapter.CONDITION_AFTER_BYTE);

                    ib.adapter.putByte(raw_buf[10]);
                }
                else
                {
                    ib.adapter.dataBlock(raw_buf, 0, 11);
                }
            }
            else
            {
                if (enablePower)
                {
                    ib.adapter.startPowerDelivery(DSPortAdapter.CONDITION_AFTER_BYTE);
                    temp = (byte)ib.adapter.Byte;
                }
            }

            if (enablePower)
            {
                msWait(3);

                ib.adapter.setPowerNormal();
            }

            // pre-fill with 0xFF
            raw_buf = new byte[pageLength + extraLength + 2 + numVerifyBytes];

            Array.Copy(ffBlock, 0, raw_buf, 0, raw_buf.Length);

            // send block to read data + extra info? + crc
            if (enablePower)
            {
                ib.adapter.dataBlock(raw_buf, 0, (raw_buf.Length - 1));
                last_crc = CRC16.compute(raw_buf, 0, raw_buf.Length - numVerifyBytes - 2, last_crc);

                if ((last_crc & 0x0FF) != ((~raw_buf[raw_buf.Length - 2]) & 0x0FF))
                {
                    sp.forceVerify();
                    throw new OneWireIOException("Invalid CRC16 read from device.  Password may be incorrect.");
                }
            }
            else
            {
                ib.adapter.dataBlock(raw_buf, 0, raw_buf.Length);

                // check the CRC
                if (CRC16.compute(raw_buf, 0, raw_buf.Length - numVerifyBytes, last_crc) != 0x0000B001)
                {
                    sp.forceVerify();
                    throw new OneWireIOException("Invalid CRC16 read from device.  Password may be incorrect.");
                }
            }

            // extract the page data
            Array.Copy(raw_buf, 0, readBuf, offset, pageLength);

            // optional extract the extra info
            if (extraInfo != null)
            {
                Array.Copy(raw_buf, pageLength, extraInfo, 0, extraLength);
            }
        }
Beispiel #2
0
        /// <summary> Copy the scratchpad page to memory.
        ///
        /// </summary>
        /// <param name="startAddr">    starting address
        /// </param>
        /// <param name="len">          length in bytes that was written already
        ///
        /// </param>
        /// <throws>  OneWireIOException </throws>
        /// <throws>  OneWireException </throws>
        public override void  copyScratchpad(int startAddr, int len)
        {
            if (!enablePower)
            {
                if (((startAddr + len) & 0x1F) != 0)
                {
                    throw new OneWireException("CopyScratchpad failed: Ending Offset must go to end of page");
                }
            }

            // select the device
            if (!ib.adapter.select(ib.address))
            {
                forceVerify();
                throw new OneWireIOException("Device select failed");
            }

            // build block to send (1 cmd, 3 data, 8 password, 4 verification)
            int raw_buf_length = 16;

            byte[] raw_buf = new byte[raw_buf_length];

            raw_buf[0] = COPY_SCRATCHPAD_COMMAND;
            raw_buf[1] = (byte)(startAddr & 0xFF);
            raw_buf[2] = (byte)((SupportClass.URShift((startAddr & 0xFFFF), 8)) & 0xFF);
            if (enablePower)
            {
                raw_buf[3] = (byte)((startAddr + len - 1) & 0x3F);
            }
            else
            {
                raw_buf[3] = (byte)((startAddr + len - 1) & 0x1F);
            }

            if (ibPass.ContainerReadWritePasswordSet)
            {
                ibPass.getContainerReadWritePassword(raw_buf, 4);
            }

            Array.Copy(ffBlock, 0, raw_buf, raw_buf_length - 4, 4);

            // send block (check copy indication complete)
            if (enablePower)
            {
                ib.adapter.dataBlock(raw_buf, 0, (raw_buf_length - 5));

                ib.adapter.startPowerDelivery(DSPortAdapter.CONDITION_AFTER_BYTE);

                ib.adapter.putByte(raw_buf[11]);

                msWait(23);

                ib.adapter.setPowerNormal();

                raw_buf[12] = (byte)ib.adapter.Byte;

                if (((raw_buf[12] & (byte)SupportClass.Identity(0xF0)) != (byte)SupportClass.Identity(0xA0)) && ((raw_buf[12] & (byte)SupportClass.Identity(0xF0)) != (byte)0x50))
                {
                    throw new OneWireIOException("Copy scratchpad complete not found");
                }
            }
            else
            {
                ib.adapter.dataBlock(raw_buf, 0, raw_buf_length);

                byte verifyByte = (byte)(raw_buf[raw_buf_length - 1] & 0x0F);
                if (verifyByte != 0x0A && verifyByte != 0x05)
                {
                    //forceVerify();
                    if (verifyByte == 0x0F)
                    {
                        throw new OneWireIOException("Copy scratchpad failed - invalid password");
                    }
                    else
                    {
                        throw new OneWireIOException("Copy scratchpad complete not found");
                    }
                }
            }
        }