Esempio n. 1
0
  /**
   * Read memory in the current bank with no CRC checking (device or data). The resulting data from
   * this API may or may not be what is on the 1-Wire device. It is recommends that the data contain
   * some kind of checking (CRC) like in the readPagePacket() method or have the 1-Wire device
   * provide the CRC as in readPageCRC(). readPageCRC() however is not supported on all memory
   * types, see 'hasPageAutoCRC()'. If neither is an option then this method could be called more
   * then once to at least verify that the same thing is read consistantly.
   *
   * @param startAddr starting physical address
   * @param readContinue if 'true' then device read is continued without re-selecting. This can only
   *     be used if the new read() continious where the last one led off and it is inside a
   *     'beginExclusive/endExclusive' block.
   * @param readBuf byte array to place read data into
   * @param offset offset into readBuf to place data
   * @param len length in bytes to read
   * @throws OneWireIOException
   * @throws OneWireException
   */
  public void read(int startAddr, boolean readContinue, byte[] readBuf, int offset, int len)
      throws OneWireIOException, OneWireException {
    int i;
    byte[] raw_buf = new byte[64];

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

    // check if read exceeds memory
    if ((startAddr + len) > size) throw new OneWireException("Read exceeds memory bank end");

    // see if need to access the device
    if (!readContinue) {

      // select the device
      if (!ib.adapter.select(ib.address)) {
        sp.forceVerify();

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

      // build start reading memory block
      int addr = startAddr + startPhysicalAddress;

      raw_buf[0] = READ_MEMORY_CRC_PW_COMMAND;

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

      if (ibPass.isContainerReadWritePasswordSet())
        ibPass.getContainerReadWritePassword(raw_buf, 3);
      else ibPass.getContainerReadOnlyPassword(raw_buf, 3);

      // do the first block for command, address. password
      if (enablePower) {
        ib.adapter.dataBlock(raw_buf, 0, 10);
        ib.adapter.startPowerDelivery(DSPortAdapter.CONDITION_AFTER_BYTE);
        ib.adapter.putByte(raw_buf[10]);

        msWait(10);

        ib.adapter.setPowerNormal();
      } else {
        ib.adapter.dataBlock(raw_buf, 0, 11);
      }
    }

    // pre-fill readBuf with 0xFF
    int startOffset = startAddr % pageLength;

    // First, count how many bytes are leftover from the
    // whole page reads.
    int bytesLeftover = (len % pageLength);

    // Second, account for the whole number of pages
    int pgs = (len / pageLength);

    // Third, if read starts in middle, go ahead and count
    // that whole page as 1 more page.
    if (startOffset > 0) {
      pgs += 1;
      // subtract the bytes from this extra page from our
      // leftover bytes, since we just accounted for each
      // byte to the end of this first page.
      bytesLeftover -= (pageLength - startOffset);
    }

    // Finally, account for 1 more page read if there are
    // any more left over bytes
    if (bytesLeftover > 0) pgs += 1;

    int startPage = startAddr / pageLength;

    for (i = 0; i < pgs; i++) {
      readPageCRC(startPage + i, false, raw_buf, 0, null, 0);

      if (i == 0) {
        System.arraycopy(raw_buf, startOffset, readBuf, offset, (pageLength - startOffset));
      } else if ((i == (pgs - 1)) && (bytesLeftover != 0)) {
        System.arraycopy(
            raw_buf,
            0,
            readBuf,
            (offset + (pageLength - startOffset) + ((i - 1) * pageLength)),
            bytesLeftover);
      } else {
        System.arraycopy(
            raw_buf,
            0,
            readBuf,
            (offset + (pageLength - startOffset) + ((i - 1) * pageLength)),
            pageLength);
      }
    }
  }
Esempio n. 2
0
  /**
   * Write memory in the current bank. It is recommended that when writing data that some structure
   * in the data is created to provide error free reading back with read(). Or the method
   * 'writePagePacket()' could be used which automatically wraps the data in a length and CRC.
   *
   * <p>When using on Write-Once devices care must be taken to write into into empty space. If
   * write() is used to write over an unlocked page on a Write-Once device it will fail. If write
   * verification is turned off with the method 'setWriteVerification(false)' then the result will
   * be an 'AND' of the existing data and the new data.
   *
   * @param startAddr starting address
   * @param writeBuf byte array containing data to write
   * @param offset offset into writeBuf to get data
   * @param len length in bytes to write
   * @throws OneWireIOException
   * @throws OneWireException
   */
  public void write(int startAddr, byte[] writeBuf, int offset, int len)
      throws OneWireIOException, OneWireException {
    // find the last (non-inclusive) address for this write
    int endingOffset = (startAddr + len);
    if (((endingOffset & 0x1F) > 0) && (!enablePower)) {
      // find the number of bytes left until the end of the page
      int numBytes = pageLength - (endingOffset & 0x1F);
      if ( // endingOffset == 0x250 ???? why??
      (ibPass.hasReadWritePassword()
              && (0xFFE0 & endingOffset) == (0xFFE0 & ibPass.getReadWritePasswordAddress())
              && endingOffset
                  < (ibPass.getReadWritePasswordAddress() + ibPass.getReadWritePasswordLength()))
          || (ibPass.hasReadOnlyPassword()
              && (0xFFE0 & endingOffset) == (0xFFE0 & ibPass.getReadOnlyPasswordAddress())
              && endingOffset
                  < (ibPass.getReadOnlyPasswordAddress() + ibPass.getReadOnlyPasswordLength()))
          || (ibPass.hasWriteOnlyPassword()
              && (0xFFE0 & endingOffset) == (0xFFE0 & ibPass.getWriteOnlyPasswordAddress())
              && endingOffset
                  < (ibPass.getWriteOnlyPasswordAddress() + ibPass.getWriteOnlyPasswordLength()))) {

        // password block would be written to with potentially bad data
        throw new OneWireException(
            "Executing write would overwrite password control registers with "
                + "potentially invalid data.  Please ensure write does not occur over"
                + "password control register page, or the password control data is "
                + "specified exactly in the write buffer.");
      }

      byte[] tempBuf = new byte[len + numBytes];
      System.arraycopy(writeBuf, offset, tempBuf, 0, len);
      read(endingOffset, false, tempBuf, len, numBytes);

      super.write(startAddr, tempBuf, 0, tempBuf.length);
    } else {
      // write does extend to end of page
      super.write(startAddr, writeBuf, offset, len);
    }
  }
Esempio n. 3
0
  /**
   * 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.
   *
   * @param page page number to read
   * @param 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 readBuf byte array to put data read. Must have at least 'getMaxPacketDataLength()'
   *     elements.
   * @param offset offset into readBuf to place data
   * @param extraInfo byte array to put extra info read into
   * @param extraLength length of extra information
   * @throws OneWireIOException
   * @throws OneWireException
   */
  protected void readPageCRC(
      int page, boolean readContinue, byte[] readBuf, int offset, byte[] extraInfo, int extraLength)
      throws OneWireIOException, OneWireException {
    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] = (byte) (addr & 0xFF);
      raw_buf[2] = (byte) (((addr & 0xFFFF) >>> 8) & 0xFF);

      if (ibPass.isContainerReadWritePasswordSet())
        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.getByte();
      }
    }

    if (enablePower) {
      msWait(3);

      ib.adapter.setPowerNormal();
    }

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

    System.arraycopy(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
    System.arraycopy(raw_buf, 0, readBuf, offset, pageLength);

    // optional extract the extra info
    if (extraInfo != null) System.arraycopy(raw_buf, pageLength, extraInfo, 0, extraLength);
  }