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 Nov 28, 2021
1 parent d3ab231 commit 1bc1116
Show file tree
Hide file tree
Showing 9 changed files with 91 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 @@ -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 1bc1116

Please sign in to comment.