mirror of https://github.com/arendst/Tasmota.git
Merge pull request #16420 from s-hadinger/zigbee_znp_timeout
ZIgbee extend ZNP timeout
This commit is contained in:
commit
dea49dfbc5
|
@ -0,0 +1,176 @@
|
|||
|
||||
#################################################################################
|
||||
#
|
||||
# class `sonoff_zb_pro_flasher`
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
class tubezb_cc2652_flasher
|
||||
static CCFG_address = 0x057FD8
|
||||
static CCFG_reference = 0xC5FE0FC5 # DIO 15 for BSL
|
||||
|
||||
#################################################################################
|
||||
# Flashing from Intel HEX files
|
||||
#################################################################################
|
||||
var filename # filename of hex file
|
||||
var f # file object
|
||||
var file_checked # was the file already parsed. It cannot be flashed if not previously parsed and validated
|
||||
var file_validated # was the file already validated. It cannot be flashed if not previously parsed and validated
|
||||
var file_hex # intelhex object
|
||||
var flasher # low-level flasher object (cc2652_flasher instance)
|
||||
|
||||
def init()
|
||||
self.file_checked = false
|
||||
self.file_validated = false
|
||||
end
|
||||
|
||||
def load(filename)
|
||||
import intelhex
|
||||
|
||||
if type(filename) != 'string' raise "value_error", "invalid file name" end
|
||||
self.filename = filename
|
||||
self.file_hex = intelhex(filename) # prepare the parser object
|
||||
self.file_checked = false
|
||||
self.file_validated = false
|
||||
end
|
||||
|
||||
#################################################################################
|
||||
# check that the HEX file is valid
|
||||
# parse it completely once, and verify some values
|
||||
#################################################################################
|
||||
def check()
|
||||
self.file_hex.parse(/ -> self._check_pre(),
|
||||
/ address, len, data, offset -> self._check_cb(address, len, data, offset),
|
||||
/ -> self._check_post()
|
||||
)
|
||||
end
|
||||
|
||||
#################################################################################
|
||||
# Flash the firmware to the device
|
||||
#
|
||||
#################################################################################
|
||||
def flash()
|
||||
if !self.file_checked
|
||||
print("FLH: firmware not checked, use `cc.check()`")
|
||||
raise "flash_error", "firmware not checked"
|
||||
end
|
||||
if !self.file_validated
|
||||
print("FLH: firmware not validated, use `cc.check()`")
|
||||
raise "flash_error", "firmware not validated"
|
||||
end
|
||||
|
||||
import cc2652_flasher # this stops zigbee and configures serial
|
||||
self.flasher = cc2652_flasher
|
||||
|
||||
try
|
||||
self.file_hex.parse(/ -> self._flash_pre(),
|
||||
/ address, len, data, offset -> self._flash_cb(address, len, data, offset),
|
||||
/ -> self._flash_post()
|
||||
)
|
||||
except .. as e, m
|
||||
self.file_checked = false
|
||||
self.file_validated = false
|
||||
raise e, m
|
||||
end
|
||||
end
|
||||
|
||||
#################################################################################
|
||||
# Dump firmware to local file
|
||||
#
|
||||
#################################################################################
|
||||
def dump_to_file(filename)
|
||||
import cc2652_flasher # this stops zigbee and configures serial
|
||||
self.flasher = cc2652_flasher
|
||||
print("FLH: Dump started (takes 3 minutes during which Tasmota is unresponsive)")
|
||||
self.flasher.start()
|
||||
self.flasher.ping()
|
||||
self.flasher.flash_dump_to_file(filename, 0x000000, 0x58000)
|
||||
print("FLH: Dump completed")
|
||||
end
|
||||
|
||||
#################################################################################
|
||||
# low-level
|
||||
#################################################################################
|
||||
def _flash_pre()
|
||||
print("FLH: Flashing started (takes 5 minutes during which Tasmota is unresponsive)")
|
||||
self.flasher.start()
|
||||
self.flasher.ping()
|
||||
# erase flash
|
||||
self.flasher.flash_erase()
|
||||
end
|
||||
|
||||
def _flash_post()
|
||||
print("FLH: Flashing completed: OK")
|
||||
var flash_crc = self.flasher.cmd_crc32(0x0,0x30000)
|
||||
print("FLH: Flash crc32 0x000000 - 0x2FFFF = " + str(flash_crc));
|
||||
# tasmota.log("FLH: Verification of HEX file OK", 2)
|
||||
end
|
||||
|
||||
def _flash_cb(addr, sz, data, offset)
|
||||
var payload = data[offset .. offset + sz - 1]
|
||||
|
||||
# final check
|
||||
if size(payload) != sz raise "flash_error", "incomplete payload" end
|
||||
|
||||
self.flasher.flash_write(addr, payload)
|
||||
end
|
||||
|
||||
|
||||
# start verification (log only)
|
||||
def _check_pre()
|
||||
print("FLH: Starting verification of HEX file")
|
||||
# tasmota.log("FLH: Starting verification of HEX file", 2)
|
||||
end
|
||||
|
||||
# don't flash so ignore data
|
||||
# check CCFG at location 0x57FD8 (4 bytes)
|
||||
def _check_cb(addr, sz, data, offset)
|
||||
# import string
|
||||
|
||||
# check than sz is a multiple of 4
|
||||
if (sz % 4 != 0)
|
||||
import string
|
||||
raise "value_error", string.format("size of payload is not a mutliple of 4: 0x%06X", addr)
|
||||
end
|
||||
|
||||
# print(string.format("> addr=0x%06X sz=0x%02X data=%s", addr, sz, data[offset..offset+sz-1]))
|
||||
var CCFG = self.CCFG_address
|
||||
if addr <= CCFG && addr+sz > CCFG+4
|
||||
# we have CCFG in the buffer
|
||||
var ccfg_bytes = data.get(4 + CCFG - addr, 4)
|
||||
|
||||
if ccfg_bytes != self.CCFG_reference
|
||||
import string
|
||||
raise "value_error", string.format("incorrect CCFG, BSL is not set to DIO_8 LOW (0x%08X expected 0x%08X)", ccfg_bytes, self.CCFG_reference) end
|
||||
self.file_validated = true # if we are here, it means that the file looks correct
|
||||
end
|
||||
end
|
||||
|
||||
def _check_post()
|
||||
print("FLH: Verification of HEX file OK")
|
||||
# tasmota.log("FLH: Verification of HEX file OK", 2)
|
||||
self.file_checked = true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return tubezb_cc2652_flasher()
|
||||
|
||||
|
||||
#-
|
||||
# Flash local firmware
|
||||
|
||||
import sonoff_zb_pro_flasher as cc
|
||||
cc.load("SonoffZBPro_coord_20220219.hex")
|
||||
cc.check()
|
||||
cc.flash()
|
||||
|
||||
-#
|
||||
|
||||
#-
|
||||
# Dump local firmware
|
||||
|
||||
import sonoff_zb_pro_flasher as cc
|
||||
cc.dump_to_file("SonoffZBPro_dump.bin")
|
||||
|
||||
-#
|
|
@ -473,7 +473,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
|
|||
ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredCoord)
|
||||
ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) // set any failure to ABORT
|
||||
ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator
|
||||
ZI_WAIT_RECV(5000, ZBR_STARTUPFROMAPP) // wait for sync ack of command
|
||||
ZI_WAIT_RECV(10000, ZBR_STARTUPFROMAPP) // wait for sync ack of command
|
||||
ZI_WAIT_UNTIL_FUNC(20000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started, max 20s
|
||||
ZI_GOTO(ZIGBEE_LABEL_COORD_STARTED)
|
||||
|
||||
|
@ -493,7 +493,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = {
|
|||
ZI_WAIT_RECV(2000, ZBR_W_BDB_CHANN_OK)
|
||||
// all is good, we can start
|
||||
ZI_SEND(ZBS_BDB_START_COMMIS) // start coordinator
|
||||
ZI_WAIT_RECV(5000, ZBR_BDB_START_COMMIS) // wait for sync ack of command
|
||||
ZI_WAIT_RECV(10000, ZBR_BDB_START_COMMIS) // wait for sync ack of command
|
||||
ZI_WAIT_UNTIL_FUNC(20000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started, max 20s
|
||||
|
||||
// ======================================================================
|
||||
|
|
Loading…
Reference in New Issue