📄 jibcomm.java
字号:
* may need a retry */ } } int POR_ADJUST = 0; private int my_min_read_runtime = 0; long time1=0; long time2=0; /** * Transfers data to and from this Java iButton. * * @param data byte array with data to be written to this Java iButton * @param runTime a <code>4</code> bit value <code>(0 -15)</code> * that represents the expected run time of the device. * * Actual run time is calculated as followed: * <code><pre> * runTime * 250 + 62.5 mS <BR> * Therefore, 0 -> 0 * 250 + 62.5 = 62.5 mS * 1 -> 1 * 250 + 62.5 = 312.5 mS </pre></code> * and so on. * * @return byte array containing data read back from this Java iButton. * * @throws IllegalArgumentException Invalid run time value * @throws OneWireException Part could not be found [ fatal ] * @throws OneWireIOException Data wasn't transferred properly [ recoverable ] * */ public synchronized byte[] transferJibData (byte[] data, int runTime) throws OneWireException, OneWireIOException, IllegalArgumentException { POR_ADJUST = 0; OneWireException exc = null; boolean reading = false; my_min_read_runtime = min_read_runtime; //try this only twice. If it fails the first time, we // POR the part through a normal speed reset, kick it up to // overdrive, then try to re-send the APDU. This usually works. //We have to do this because of a bug in the 1-Wire micro (not // the JiB micro) that won't let us communicate in certain // situations, so we can't even get to the status registers. if (doDebugMessages) { System.out.println("TRANSFER JIB DATA:\r\n"+toHexString(data)); time1 = System.currentTimeMillis(); } for (int i=0;i<3;i++) { reading = false; try { if (runTime > 15) runTime = 15; if (runTime < 0) runTime = 0; //BlockDataFragmenter frag = new BlockDataFragmenter(data); fragger.initialize(data); // Set correction of the POR to true to clear the first POR. shouldCorrectPOR = true; if (adapter.getSpeed() != adapter.SPEED_OVERDRIVE) throw new OneWireIOException("Adapter not in overdrive mode."); if (doDebugMessages) System.out.println("Sending data to Java iButton."); // Send all data and headers to the iButton. while (true) { checkStatus(MIN_RUNTIME, SEND, transfer_jib_status, 0); setHeader(fragger.getNextHeaderToSend()); // Send Header setData(fragger.getNextDataToSend()); // Send Data if (doDebugMessages) System.out.println("Data has been written."); // NOTE: // The 'more' Variable in the BlockDataFragmenter is updated in // the getNextHeaderToSend function. // If this is the final block of data, then the full requested // runtime needs to be sent to this Java iButton instead of the // minimum one. if (fragger.hasMore()) { setStatus(MIN_RUNTIME); interrupt(MIN_RUNTIME); } else { // all data sent setStatus(runTime); interrupt(runTime); break; } } // End of Data loading loop. // retrieve the data. do { reading = true; // wait for iButton reply checkStatus(runTime, RECEIVE, transfer_jib_status, 0); getHeader(transfer_jib_header,0); // retrieve header byte[] datatemp = getData(( int ) transfer_jib_header [1]); // retrieve data if (doDebugMessages) System.out.println("Data read back successfully."); // Check data CRC and build the return data array. fragger.checkBlock(transfer_jib_header, datatemp); // for Java iButton, just checking the COMMAND_NOT_COMPLETE flag is // not sufficient as it may send data back in multiple blocks. // Block number 0x80 does not necessary means the last block. if (transfer_jib_status [2] == COMMAND_COMPLETE) break; // last block received setStatus(my_min_read_runtime); run(my_min_read_runtime); } while (true); reading = false; // Retrieve the data array from the BlockDataFragmenter. if (doDebugMessages) { time2 = System.currentTimeMillis(); System.out.println("Full time for that transaction: "+(time2-time1)); } return fragger.getDataFromRead(); } catch(OneWireException owe) { //DEBUG!!! TAKE THIS OUT!!! //System.out.println("This exception occurred: "+owe); exc = owe; if (doDebugMessages) { System.out.println("This exception occurred: "+owe+", Retrying to send the apdu after POR..."); } container.doSpeed(); runTime++; POR_ADJUST++; if (reading && (owe instanceof OneWireIOException)) { //System.out.println("FAILED WHILE READING DATA OUT...QUE LATA! INCREASING TIME TO READ"); my_min_read_runtime++; } } } throw exc; } /** * Corrects the device from a Power-On-Reset (POR) error. * * @throws OneWireException Part could not be found [ fatal ] * @throws OneWireIOException Data wasn't transferred properly [ recoverable ] */ public void correctPOR () throws OneWireException, OneWireIOException { if (doDebugMessages) System.out.println("Attempting to correct the POR!"); reset(); setStatus(MIN_RUNTIME+POR_ADJUST); run(MIN_RUNTIME+POR_ADJUST); } /** * Gets the status from this Java iButton. * * @return status byte array read from this Java iButton. * The contents of the status array is as follows: * * <pre> * Byte 0 - number of free bytes in the Input Buffer. * Byte 1 - number of used bytes in the Output Buffer. * Byte 2 - contents of the OWMS Register. * Byte 3 - contents of the CPST register.</pre> * * @throws OneWireException Part could not be found [ fatal ] * @throws OneWireIOException Data wasn't transferred properly [ recoverable ] * * @see #checkStatus * @see #setStatus */ public synchronized void getStatus (byte[] status, int start) throws OneWireException, OneWireIOException { if (adapter.getSpeed()!=DSPortAdapter.SPEED_OVERDRIVE) { if (doDebugMessages) System.out.println("FIXING SPEED!"); container.doSpeed(); } // Set up the command block //first put in the select command System.arraycopy(select_buffer,0,command_buffer,0,9); //now put in the read status command, and the ff's for reading command_buffer [9] = READ_STATUS_COMMAND; System.arraycopy(ffBlock, 0, command_buffer, 10, 6); datablock(command_buffer,0,16); // Fix Andreas Bug in read Status with cap on One-Wire. // Mask off the last bit of the Free bytes command_buffer [10] &= ( byte ) 0xFE; int crc = CRC16.compute(command_buffer, 9, 7, 0); if (crc != 0xB001) { int correction = getCRC16Correction(7); if ((correction ^ crc) != 0xB001) { if (doDebugMessages) { for (int i=0;i<16;i++) System.out.print(Integer.toHexString(command_buffer[i] & 0x0ff)+" "); System.out.println(); } throw new OneWireIOException("Bad CRC on data returned in Read Status method."); } } // retrieve status System.arraycopy(command_buffer, 10, status, start, 4); } /** * Checks the status of this Java iButton. * * @param runTime a <code>4</code> bit value <code>(0 -15)</code> * that represents the expected run time of the device. * Actual run time is calculated as followed: * <code><pre> * runTime * 250 + 62.5 mS <BR> * Therefore, 0 -> 0 * 250 + 62.5 = 62.5 mS * 1 -> 1 * 250 + 62.5 = 312.5 mS </pre></code> * and so on. * @param dir <code>SEND</code> if sending data to this Java iButton, * <code>RECEIVE</code> if receiving * * @throws OneWireException Part could not be found [ fatal ] * @throws OneWireIOException Data wasn't transferred properly [ recoverable ] * * @see #getStatus * @see #setStatus */ public synchronized void checkStatus (int runTime, int dir, byte[] status, int start) throws OneWireIOException, OneWireException { int loopCount = 0; // loop until the conditions are satisfied which implies that the // coprocesser is not running, and the previous command has finished. int myRunTime = runTime; while (true) { loopCount++; // Keeps from having a infinate loop. if (loopCount > 200) // Value can be ajusted. throw new OneWireException("Unrecoverable error. Fail."); getStatus(check_status,0); // get current status int owms_code = check_status[2] & 0x1f; /* means that the button wants more time...so let it run. This could be a keyset generation */ if (owms_code == 0x1f) loopCount = 0; if (doDebugMessages) { System.out.print("<"+Integer.toHexString(check_status[0]&0x0ff)+" "+ Integer.toHexString(check_status[1]&0x0ff)+" "+ Integer.toHexString(check_status[2]&0x0ff)+" "+ Integer.toHexString(check_status[3]&0x0ff)+">"); System.out.print("["+owms_code+"]"); } // First error checking POR bit. if ((check_status [2] & POWER_ON_RESET) != 0) { if (shouldCorrectPOR) correctPOR(); else throw new OneWireException("POR of Device is set."); shouldCorrectPOR = false; } else { // check CPST bit for Co-procsesser status. if ((check_status [3] & COPROCESSOR_ACCELERATOR_RUNNING) != 0) { if (doDebugMessages) System.out.println("Coprocessor still running."); // give it time to finish. myRunTime = myRunTime + 6; if (myRunTime > 15) myRunTime = 15; run(myRunTime); } else if (((check_status [2] & MASTER_ERASE_PROBLEM) == FIRST_BIRTHDAY) || ((check_status [2] & MASTER_ERASE_PROBLEM) == MASTER_ERASE_PROBLEM)) { // Device is in first-birthday initialization // Occurrence: if a master erase command has been sent // that has not yet been completed //if its not first birthday, it indicates that a load just occurred, //and we don't need to wait that long for it to come back, //so we save ourselves 400+ ms by doing this shortcut if ((check_status [2] & MASTER_ERASE_PROBLEM) != FIRST_BIRTHDAY) { myRunTime++; if (myRunTime > 15) myRunTime = 15; } else { myRunTime = 6; //optimum time for first birthday } if (doDebugMessages) { if ((check_status [2] & MASTER_ERASE_PROBLEM) == FIRST_BIRTHDAY) System.out.println("FirstBirth identified."); else System.out.println("FirstBirth-like occurrance"); } setStatus(myRunTime); run(myRunTime); } else if ((check_status [2] & COMMAND_NOT_COMPLETE) != 0) { if (myRunTime == MIN_RUNTIME) myRunTime = 2; else if (myRunTime < 8) myRunTime *= 2; else myRunTime = 15; if (doDebugMessages) System.out.println("Command Not Complete."); setStatus(myRunTime); run(myRunTime); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -