📄 lserialadapter.java
字号:
} /** * Get a block of data from the 1-Wire Network and write it into * the provided array. * * @param arr array in which to write the received bytes * @param off offset into the array to start * @param len length of data bytes to receive * * @throws OneWireIOException on a 1-Wire communication error * @throws OneWireException on a setup error with the 1-Wire adapter */ public void getBlock(byte[] arr, int off, int len) throws OneWireIOException, OneWireException { // set block to read 0xFF for (int i = off; i < len; i++) arr [i] = (byte) 0xFF; dataBlock(arr, off, len); } /** * Sends a block of data and returns the data received in the same array. * This method is used when sending a block that contains reads and writes. * The 'read' portions of the data block need to be pre-loaded with 0xFF's. * It starts sending data from the index at offset 'off' for length 'len'. * * @param dataBlock array of data to transfer to and from the 1-Wire Network. * @param off offset into the array of data to start * @param len length of data to send / receive starting at 'off' * * @throws OneWireIOException on a 1-Wire communication error * @throws OneWireException on a setup error with the 1-Wire adapter */ public void dataBlock(byte dataBlock [], int off, int len) throws OneWireIOException, OneWireException { try { // acquire exclusive use of the port beginLocalExclusive(); // make sure adapter is present if (adapterDetected()) { int t_off, t_len; t_off = off; t_len = len; // break up large blocks to not exceed 128 bytes at a time do { if (t_len > 128) t_len = 128; char[] send_block = constructSendBlock(dataBlock, t_off, t_len); serial.flush(); serial.write(send_block); char[] raw_recv = serial.readWithTimeout(send_block.length); byte[] recv = interpretRecvBlock(raw_recv); System.arraycopy(recv, 0, dataBlock, t_off, t_len); t_off += t_len; t_len = off + len - t_off; } while (t_len > 0); } else { throw new OneWireIOException("Error communicating with adapter"); } } catch (IOException ioe) { throw new OneWireIOException(ioe.toString()); } finally { // release local exclusive use of port endLocalExclusive(); } } /** * Sends a Reset to the 1-Wire Network. * * @return the result of the reset. Potential results are: * <ul> * <li> 0 (RESET_NOPRESENCE) no devices present on the 1-Wire Network. * <li> 1 (RESET_PRESENCE) normal presence pulse detected on the 1-Wire * Network indicating there is a device present. * <li> 2 (RESET_ALARM) alarming presence pulse detected on the 1-Wire * Network indicating there is a device present and it is in the * alarm condition. This is only provided by the DS1994/DS2404 * devices. * <li> 3 (RESET_SHORT) inticates 1-Wire appears shorted. This can be * transient conditions in a 1-Wire Network. Not all adapter types * can detect this condition. * </ul> * * @throws OneWireIOException on a 1-Wire communication error * @throws OneWireException on a setup error with the 1-Wire adapter */ public int reset() throws OneWireIOException, OneWireException { try { // acquire exclusive use of the port beginLocalExclusive(); // make sure adapter is present if (adapterDetected()) { serial.flush(); // send a break to reset 1-Wire serial.sendBreak(1); // get the result char[] c = serial.readWithTimeout(1); // does not work: return ((c.length > 1) ? RESET_PRESENCE : RESET_NOPRESENCE); return RESET_PRESENCE; } else return RESET_NOPRESENCE; } catch (IOException ioe) { return RESET_NOPRESENCE; } catch (OneWireIOException e) { if (doDebugMessages) System.err.println("DS9097EAdapter: Not detected " + e); return RESET_NOPRESENCE; } finally { // release local exclusive use of port endLocalExclusive(); } } //-------- //-------- Support methods //-------- /** * Single search. Take into account reset and alarm options. * * @param resetSearch - true to start search over (like first) * * @return true if device found of false if end of search * * @throws OneWireException * @throws OneWireIOException */ private boolean search(boolean resetSearch) throws OneWireIOException, OneWireException { int bit_test, bit_number; int last_zero, serial_byte_number; int serial_byte_mask; int lastcrc8; boolean next_result, search_direction; // initialize for search bit_number = 1; last_zero = 0; serial_byte_number = 0; serial_byte_mask = 1; next_result = false; lastcrc8 = 0; // check for a force reset of the search if (resetSearch) { LastDiscrepancy = 0; LastDevice = false; LastFamilyDiscrepancy = 0; } // if the last call was not the last one if (!LastDevice) { // check if reset first is requested if (!skipResetOnSearch) { // reset the 1-wire // if there are no parts on 1-wire, return false if (reset() != RESET_PRESENCE) { // reset the search LastDiscrepancy = 0; LastFamilyDiscrepancy = 0; return false; } } // If finding alarming devices issue a different command if (searchOnlyAlarmingButtons) putByte(ALARM_SEARCH_CMD); // issue the alarming search command else putByte(NORMAL_SEARCH_CMD); // issue the search command // loop to do the search do { // read a bit and its compliment bit_test = (getBit() ? 1 : 0) << 1; bit_test |= (getBit() ? 1 : 0); // check for no devices on 1-wire if (bit_test == 3) break; else { // all devices coupled have 0 or 1 if (bit_test > 0) search_direction = !((bit_test & 0x01) == 0x01); // bit write value for search else { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if (bit_number < LastDiscrepancy) search_direction = ((CurrentDevice[serial_byte_number] & serial_byte_mask) > 0); else // if equal to last pick 1, if not then pick 0 search_direction = (bit_number == LastDiscrepancy); // if 0 was picked then record its position in LastZero if (!search_direction) last_zero = bit_number; // check for Last discrepancy in family if (last_zero < 9) LastFamilyDiscrepancy = last_zero; } // set or clear the bit in the CurrentDevice byte serial_byte_number // with mask serial_byte_mask if (search_direction) CurrentDevice[serial_byte_number] |= serial_byte_mask; else CurrentDevice[serial_byte_number] &= ~serial_byte_mask; // serial number search direction write bit putBit(search_direction); // increment the byte counter bit_number // and shift the mask serial_byte_mask bit_number++; serial_byte_mask = (serial_byte_mask <<= 1) & 0x00FF; // if the mask is 0 then go to new CurrentDevice byte serial_byte_number // and reset mask if (serial_byte_mask == 0) { // accumulate the CRC lastcrc8 = CRC8.compute(CurrentDevice[serial_byte_number], lastcrc8); serial_byte_number++; serial_byte_mask = 1; } } } while(serial_byte_number < 8); // loop until through all CurrentDevice bytes 0-7 // if the search was successful then if (!((bit_number < 65) || (lastcrc8 != 0))) { // search successful so set LastDiscrepancy,LastDevice,next_result LastDiscrepancy = last_zero; LastDevice = (LastDiscrepancy == 0); next_result = true; } } // if no device found then reset counters so next 'next' will be // like a first if (!next_result || (CurrentDevice[0] == 0)) { LastDiscrepancy = 0; LastDevice = false; LastFamilyDiscrepancy = 0; next_result = false; } return next_result; } /** * Attempt to detect prense of DS9097 style adapter. Mostly just * checks to make sure it is NOT a DS2480 or an AT modem. * * @return true if adapter likely present */ private boolean adapterPresent() { if (!adapterPresent) { char[] test_buf = { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0xC1, 'A', 'T', 'E', '0', 0x0D, 'A' }; try { // do reset serial.flush(); // send a break to reset 1-Wire serial.sendBreak(1); // get the result char[] c = serial.readWithTimeout(1); // send the test message serial.flush(); serial.write(test_buf); // get echo char[] result = serial.readWithTimeout(test_buf.length); serial.flush(); // if get entire echo then must be OK adapterPresent = true; } catch (IOException ioe) { // DRAIN } } return adapterPresent; } /** * Translate a data block to a DS9097 style block where every * byte represent one bit timeslot. * * @param data byte array * @param off offset into data array * @param len length of data array to send * * @return character array send block */ private char[] constructSendBlock(byte[] data, int off, int len) { int shift_byte, cnt=0; char[] send_block = new char[len * 8]; for (int i = 0; i < len; i++) { shift_byte = data[i + off]; for (int j = 0; j < 8; j++) { if ((shift_byte & 0x01) == 0x01) send_block[cnt++] = 0x00FF; else send_block[cnt++] = 0x00; shift_byte >>>= 1; } } return send_block; } /** * Inerpret a response communication block from a DS9097 * adapter and translate it into a byte array of data. * * @param rawBlock character array of raw communication * * @return byte array of data recieved */ private byte[] interpretRecvBlock(char[] rawBlock) { int shift_byte = 0, bit_cnt = 0, byte_cnt = 0; byte[] recv_block = new byte[rawBlock.length / 8]; for (int i = 0; i < rawBlock.length; i++) { shift_byte >>>= 1; if (rawBlock[i] == 0x00FF) shift_byte |= 0x80; bit_cnt++; if (bit_cnt == 8) { bit_cnt = 0; recv_block[byte_cnt++] = (byte)shift_byte; shift_byte = 0; } } return recv_block; } //-------- //-------- Static //-------- /** * Static method called before instance is created. Attempt * to create a hash of SerialService's and get the max baud rate. */ /*static { // create a SerialServices instance for each port available and put in hash Enumeration com_enum = CommPortIdentifier.getPortIdentifiers(); CommPortIdentifier port_id; SerialService serial_instance; // loop throught all of the serial port elements while (com_enum.hasMoreElements()) { // get the next com port port_id = (CommPortIdentifier) com_enum.nextElement(); // only collect the names of the serial ports if (port_id.getPortType() == CommPortIdentifier.PORT_SERIAL) { serial_instance = new SerialService(port_id.getName()); serialServiceHash.put(port_id.getName(), serial_instance); if (doDebugMessages) System.out.println("DEBUG: Serial port: " + port_id.getName()); } } }*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -