Skip to content

Commit

Permalink
Use hardware bootloader reset if necessary
Browse files Browse the repository at this point in the history
  • Loading branch information
t-8ch committed Dec 1, 2021
1 parent d3ab231 commit 93514d1
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,14 @@ public boolean open(int baudRate, FlowControl flowControl) {
public void purgeRxBuffer() {
}

@Override
public void setDtr(boolean state) {
}

@Override
public void setRts(boolean state) {
}

public byte[] getOutput() {
return Arrays.copyOfRange(output, 0, cnt);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ public boolean open(int baudRate, FlowControl flowControl) {
public void purgeRxBuffer() {
}

@Override
public void setDtr(boolean state) {
}

@Override
public void setRts(boolean state) {
}

public List<Integer> getOutputData() {
return outputData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,5 +354,13 @@ public boolean open(int baudRate, FlowControl flowControl) {
@Override
public void purgeRxBuffer() {
}

@Override
public void setDtr(boolean state) {
}

@Override
public void setRts(boolean state) {
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,5 +151,13 @@ public boolean open(int baudRate, FlowControl flowControl) {
@Override
public void purgeRxBuffer() {
}

@Override
public void setDtr(boolean state) {
}

@Override
public void setRts(boolean state) {
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ public ZigBeeStatus initialize() {
ZstackNetworkInitialisation netInitialiser = new ZstackNetworkInitialisation(frameHandler);
netInitialiser.setMagicNumber(magicNumber);

netInitialiser.initializeNcp(false);
netInitialiser.initializeNcp(false, serialPort);

ZstackNcp ncp = getZstackNcp();

Expand Down Expand Up @@ -296,7 +296,7 @@ public ZigBeeStatus startup(boolean reinitialize) {
netInitialiser.setMagicNumber(magicNumber);
if (reinitialize) {
logger.debug("Reinitialising ZStack NCP network.");
netInitialiser.initializeNcp(true);
netInitialiser.initializeNcp(true, serialPort);

if (deviceType == DeviceType.COORDINATOR) {
netInitialiser.formNetwork();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,23 @@
*/
package com.zsmartsystems.zigbee.dongle.zstack.internal;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zsmartsystems.zigbee.ZigBeeStatus;
import com.zsmartsystems.zigbee.dongle.zstack.ZstackNcp;
import com.zsmartsystems.zigbee.dongle.zstack.api.ZstackFrameResponse;
import com.zsmartsystems.zigbee.dongle.zstack.api.ZstackResponseCode;
import com.zsmartsystems.zigbee.dongle.zstack.api.sys.ZstackResetType;
import com.zsmartsystems.zigbee.dongle.zstack.api.sys.ZstackSysResetIndAreq;
import com.zsmartsystems.zigbee.dongle.zstack.api.sys.ZstackZdoState;
import com.zsmartsystems.zigbee.dongle.zstack.api.util.ZstackUtilGetDeviceInfoSrsp;
import com.zsmartsystems.zigbee.dongle.zstack.api.zdo.ZstackZdoStateChangeIndAreq;
import com.zsmartsystems.zigbee.transport.DeviceType;
import com.zsmartsystems.zigbee.transport.ZigBeePort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
* This class provides utility functions to establish a ZStack ZigBee network
Expand Down Expand Up @@ -91,20 +90,16 @@ public void setMagicNumber(int magicNumber) {
* The dongle is not reset completely, thus allowing it to be placed back into the previous network.
*
* @param initialize set to true to reset the dongle and erase all current network settings
* @param serialPort
*/
public ZigBeeStatus initializeNcp(boolean initialize) {
public ZigBeeStatus initializeNcp(boolean initialize, ZigBeePort serialPort) {
logger.debug("ZStack Initialisation: Initialise");
ZstackNcp ncp = new ZstackNcp(protocolHandler);

ZstackSysResetIndAreq resetResponse = ncp.resetNcp(ZstackResetType.SERIAL_BOOTLOADER);
logger.debug("ZStack Initialisation: Reset response {}", resetResponse);

if (resetResponse == null) {
// The reset failed - assume we're in the bootloader and try and exit
if (exitBootloader() == false) {
logger.debug("ZStack Initialisation: Failed to exit bootloader");
return ZigBeeStatus.COMMUNICATION_ERROR;
}
// The reset failed - assume we're in the bootloader and try and exit
if (exitBootloader(serialPort) == false) {
logger.debug("ZStack Initialisation: Failed to exit bootloader");
return ZigBeeStatus.COMMUNICATION_ERROR;
}

if (initialize) {
Expand Down Expand Up @@ -194,20 +189,38 @@ public ZigBeeStatus startNetwork() {
* Attempts to exit the bootloader by sending the "magic number" and waiting for the {@link ZstackSysResetIndAreq}
* to be received to confirm that the NCP application firmware has started.
*
* https://www.ti.com/lit/an/swra466d/swra466d.pdf
* https://www.ti.com/lit/ug/swcu185d/swcu185d.pdf
*
* @return true if the {@link ZstackSysResetIndAreq} was received, otherwise false
* @param serialPort Serial port
*/
private boolean exitBootloader() {
Future<ZstackFrameResponse> waiter = protocolHandler.waitForEvent(ZstackSysResetIndAreq.class);
private boolean exitBootloader(ZigBeePort serialPort) {
// FIXME this does not work in the OpenHAB binding, as it seems their write() implementation blocks
/*
protocolHandler.sendRaw(magicNumber);
if (waitForBoot("Magicnumber")) {
return true;
}
*/

serialPort.setDtr(false);

serialPort.setRts(false);
serialPort.setRts(true);
serialPort.setRts(false);

return waitForBoot("Hardware reset");
}

private boolean waitForBoot(String resetMode) {
Future<ZstackFrameResponse> waiter = protocolHandler.waitForEvent(ZstackSysResetIndAreq.class);
try {
ZstackFrameResponse response = waiter.get(BOOTLOAD_TIMEOUT, TimeUnit.MILLISECONDS);
logger.debug("ZStack Initialisation: Bootloader reset response {}", response);

logger.debug("ZStack Initialisation: Bootloader reset via {} response {}", resetMode, response);
return true;
} catch (InterruptedException | ExecutionException | TimeoutException e) {
logger.debug("ZStack Initialisation: Bootloader reset failed");

logger.debug("ZStack Initialisation: Bootloader reset via {} failed", resetMode, e);
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ public ZstackTransaction sendTransaction(ZstackTransaction transaction) {
futureResponse.get(TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException | TimeoutException | ExecutionException e) {
futureResponse.cancel(true);
logger.debug("ZSTACK interrupted in sendTransaction for {}", transaction);
logger.debug("ZSTACK interrupted in sendTransaction for {}", transaction, e);
}

return transaction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ public boolean open(int baudRate, FlowControl flowControl) {
public void purgeRxBuffer() {
}

@Override
public void setDtr(boolean state) {
}

@Override
public void setRts(boolean state) {
}

public List<Integer> getOutputData() {
return outputData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,19 +273,21 @@ public void purgeRxBuffer() {
}
}

public boolean setDtr(boolean state) {
@Override
public void setDtr(boolean state) {
try {
return serialPort.setDTR(state);
serialPort.setDTR(state);
} catch (SerialPortException e) {
return false;
logger.warn("Could not set DTR to {} on {}", state, this.portName, e);
}
}

public boolean setRts(boolean state) {
@Override
public void setRts(boolean state) {
try {
return serialPort.setRTS(state);
serialPort.setRTS(state);
} catch (SerialPortException e) {
return false;
logger.warn("Could not set RTS to {} on {}", state, this.portName, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ public interface ZigBeePort {
*/
void purgeRxBuffer();

/**
* Set DTR on Port
*/
void setDtr(boolean state);

/**
* Set DTS on Port
*/
void setRts(boolean state);

/**
* Enumeration of flow control options
*/
Expand Down

0 comments on commit 93514d1

Please sign in to comment.