Extend RAK4631 support
This commit is contained in:
parent
09d9285104
commit
c230eceaa6
|
@ -128,6 +128,10 @@ class ROM():
|
|||
MCU_ESP32 = 0x81
|
||||
MCU_NRF52 = 0x71
|
||||
|
||||
PRODUCT_RAK4631 = 0x10
|
||||
MODEL_11 = 0x11
|
||||
MODEL_12 = 0x12
|
||||
|
||||
PRODUCT_RNODE = 0x03
|
||||
MODEL_A1 = 0xA1
|
||||
MODEL_A6 = 0xA6
|
||||
|
@ -196,7 +200,7 @@ class ROM():
|
|||
BOARD_GENERIC_ESP32 = 0x35
|
||||
BOARD_LORA32_V2_0 = 0x36
|
||||
BOARD_LORA32_V2_1 = 0x37
|
||||
BOARD_RAK4630 = 0x51
|
||||
BOARD_RAK4631 = 0x51
|
||||
|
||||
mapped_product = ROM.PRODUCT_RNODE
|
||||
products = {
|
||||
|
@ -208,6 +212,7 @@ products = {
|
|||
ROM.PRODUCT_T32_21: "LilyGO LoRa32 v2.1",
|
||||
ROM.PRODUCT_H32_V2: "Heltec LoRa32 v2",
|
||||
ROM.PRODUCT_H32_V3: "Heltec LoRa32 v3",
|
||||
ROM.PRODUCT_RAK4631: "RAK4631",
|
||||
}
|
||||
|
||||
platforms = {
|
||||
|
@ -220,10 +225,12 @@ mcus = {
|
|||
ROM.MCU_1284P: "ATmega1284P",
|
||||
ROM.MCU_2560:"ATmega2560",
|
||||
ROM.MCU_ESP32:"Espressif Systems ESP32",
|
||||
ROM.MCU_NRF52:"Nordic nRF52840",
|
||||
ROM.MCU_NRF52: "Nordic Semiconductor nRF52840",
|
||||
}
|
||||
|
||||
models = {
|
||||
0x11: [430000000, 510000000, 22, "430 - 510 MHz", "rnode_firmware_rak4631.zip", "SX1262"],
|
||||
0x12: [779000000, 928000000, 22, "779 - 928 MHz", "rnode_firmware_rak4631.zip", "SX1262"],
|
||||
0xA4: [410000000, 525000000, 14, "410 - 525 MHz", "rnode_firmware.hex", "SX1278"],
|
||||
0xA9: [820000000, 1020000000, 17, "820 - 1020 MHz", "rnode_firmware.hex", "SX1276"],
|
||||
0xA1: [410000000, 525000000, 22, "410 - 525 MHz", "rnode_firmware_t3s3.zip", "SX1268"],
|
||||
|
@ -306,6 +313,7 @@ class RNode():
|
|||
self.bandwidth = None
|
||||
|
||||
self.detected = None
|
||||
self.usb_serial_id = None
|
||||
|
||||
self.platform = None
|
||||
self.mcu = None
|
||||
|
@ -734,6 +742,10 @@ class RNode():
|
|||
if written != len(kiss_command):
|
||||
raise IOError("An IO error occurred while wiping EEPROM")
|
||||
sleep(13);
|
||||
# Due to the current janky emulated EEPROM implementation for the
|
||||
# RAK4631, extra time must be given to allow for writing.
|
||||
if self.board == ROM.BOARD_RAK4631:
|
||||
sleep(10)
|
||||
|
||||
def hard_reset(self):
|
||||
kiss_command = bytes([KISS.FEND, KISS.CMD_RESET, 0xf8, KISS.FEND])
|
||||
|
@ -1384,6 +1396,7 @@ def main():
|
|||
exit()
|
||||
|
||||
rnode = RNode(rnode_serial)
|
||||
rnode.usb_serial_id = port_serialno
|
||||
thread = threading.Thread(target=rnode.readLoop, daemon=True).start()
|
||||
try:
|
||||
rnode.device_probe()
|
||||
|
@ -1396,6 +1409,7 @@ def main():
|
|||
else:
|
||||
RNS.log("Could not detect a connected RNode")
|
||||
|
||||
if rnode.platform == ROM.PLATFORM_ESP32:
|
||||
if rnode.provisioned:
|
||||
if not rnode.signature_valid:
|
||||
print("\nThe device signature in this RNode is unknown and cannot be verified. It is still")
|
||||
|
@ -1444,6 +1458,9 @@ def main():
|
|||
|
||||
print("\nRNode firmware extraction failed")
|
||||
exit(180)
|
||||
else:
|
||||
print("\nFirmware extraction is currently only supported on ESP32-based RNodes.")
|
||||
exit(170)
|
||||
|
||||
if args.autoinstall:
|
||||
clear()
|
||||
|
@ -1517,6 +1534,7 @@ def main():
|
|||
exit()
|
||||
|
||||
rnode = RNode(rnode_serial)
|
||||
rnode.usb_serial_id = port_serialno
|
||||
thread = threading.Thread(target=rnode.readLoop, daemon=True).start()
|
||||
try:
|
||||
rnode.device_probe()
|
||||
|
@ -1561,6 +1579,7 @@ def main():
|
|||
print("[7] Heltec LoRa32 v2")
|
||||
print("[8] Heltec LoRa32 v3")
|
||||
#print("[9] LilyGO LoRa T3S3")
|
||||
print("[10] RAK4631")
|
||||
print(" .")
|
||||
print(" / \\ Select one of these options if you want to easily turn")
|
||||
print(" | a supported development board into an RNode.")
|
||||
|
@ -1572,7 +1591,7 @@ def main():
|
|||
try:
|
||||
c_dev = int(input())
|
||||
c_mod = False
|
||||
if c_dev < 1 or c_dev > 9:
|
||||
if c_dev < 1 or c_dev > 10:
|
||||
raise ValueError()
|
||||
elif c_dev == 1:
|
||||
selected_product = ROM.PRODUCT_RNODE
|
||||
|
@ -1701,6 +1720,15 @@ def main():
|
|||
print("")
|
||||
print("Please note that Bluetooth is currently not implemented on this board.")
|
||||
print("")
|
||||
elif c_dev == 10:
|
||||
selected_product = ROM.PRODUCT_RAK4631
|
||||
clear()
|
||||
print("")
|
||||
print("---------------------------------------------------------------------------")
|
||||
print(" RAK4631 RNode Installer")
|
||||
print("")
|
||||
print("Important! Using RNode firmware on RAKwireless devices should currently be")
|
||||
print("considered experimental. It is not intended for production or critical use.")
|
||||
print("The currently supplied firmware is provided AS-IS as a courtesey to those")
|
||||
print("who would like to experiment with it. Hit enter to continue.")
|
||||
print("---------------------------------------------------------------------------")
|
||||
|
@ -1953,11 +1981,6 @@ def main():
|
|||
elif selected_product == ROM.PRODUCT_H32_V3:
|
||||
selected_mcu = ROM.MCU_ESP32
|
||||
print("\nWhat band is this Heltec LoRa32 V3 for?\n")
|
||||
print("[1] 433 MHz")
|
||||
print("[2] 868 MHz")
|
||||
print("[3] 915 MHz")
|
||||
print("[4] 923 MHz")
|
||||
print("\n? ", end="")
|
||||
try:
|
||||
c_model = int(input())
|
||||
if c_model < 1 or c_model > 4:
|
||||
|
@ -1971,6 +1994,27 @@ def main():
|
|||
except Exception as e:
|
||||
print("That band does not exist, exiting now.")
|
||||
exit()
|
||||
elif selected_product == ROM.PRODUCT_RAK4631:
|
||||
selected_mcu = ROM.MCU_NRF52
|
||||
print("\nWhat band is this RAK4631 for?\n")
|
||||
print("[1] 433 MHz")
|
||||
print("[2] 868 MHz")
|
||||
print("[3] 915 MHz")
|
||||
print("[4] 923 MHz")
|
||||
print("\n? ", end="")
|
||||
try:
|
||||
c_model = int(input())
|
||||
if c_model < 1 or c_model > 4:
|
||||
raise ValueError()
|
||||
elif c_model == 1:
|
||||
selected_model = ROM.MODEL_11
|
||||
selected_platform = ROM.PLATFORM_NRF52
|
||||
elif c_model > 1:
|
||||
selected_model = ROM.MODEL_12
|
||||
selected_platform = ROM.PLATFORM_NRF52
|
||||
except Exception as e:
|
||||
print("That band does not exist, exiting now.")
|
||||
exit()
|
||||
|
||||
if selected_model != ROM.MODEL_FF and selected_model != ROM.MODEL_FE:
|
||||
fw_filename = models[selected_model][4]
|
||||
|
@ -2157,9 +2201,12 @@ def main():
|
|||
if not args.autoinstall:
|
||||
exit()
|
||||
|
||||
def get_partition_hash(partition_file):
|
||||
def get_partition_hash(platform, partition_file):
|
||||
try:
|
||||
if platform == ROM.PLATFORM_ESP32 or platform == ROM.PLATFORM_AVR:
|
||||
firmware_data = open(partition_file, "rb").read()
|
||||
# Calculate the digest manually and see if it matches the
|
||||
# SHA256 digest included in the ESP32 image.
|
||||
calc_hash = hashlib.sha256(firmware_data[0:-32]).digest()
|
||||
part_hash = firmware_data[-32:]
|
||||
|
||||
|
@ -2167,6 +2214,13 @@ def main():
|
|||
return part_hash
|
||||
else:
|
||||
return None
|
||||
|
||||
elif platform == ROM.PLATFORM_NRF52:
|
||||
# Calculate digest manually, as it is not included in the image.
|
||||
firmware_data = open(partition_file, "rb")
|
||||
hash = hashlib.file_digest(firmware_data, 'sha256').digest()
|
||||
firmware_data.close()
|
||||
return hash
|
||||
except Exception as e:
|
||||
RNS.log("Could not calculate firmware partition hash. The contained exception was:")
|
||||
RNS.log(str(e))
|
||||
|
@ -2667,6 +2721,20 @@ def main():
|
|||
RNS.log("")
|
||||
RNS.log("Please install \""+flasher+"\" and try again.")
|
||||
exit()
|
||||
elif platform == ROM.PLATFORM_NRF52:
|
||||
flasher = "adafruit-nrfutil"
|
||||
if which(flasher) is not None:
|
||||
return [flasher, "dfu", "serial", "--package", UPD_DIR+"/"+selected_version+"/"+fw_filename, "-p", args.port, "-b", "115200", "-t", "1200"]
|
||||
else:
|
||||
RNS.log("")
|
||||
RNS.log("You do not currently have the \""+flasher+"\" program installed on your system.")
|
||||
RNS.log("Unfortunately, that means we can't proceed, since it is needed to flash your")
|
||||
RNS.log("board. You can install it via your package manager, for example:")
|
||||
RNS.log("")
|
||||
RNS.log(" pip3 install --user adafruit-nrfutil")
|
||||
RNS.log("")
|
||||
RNS.log("Please install \""+flasher+"\" and try again.")
|
||||
exit()
|
||||
|
||||
if args.port:
|
||||
wants_fw_provision = False
|
||||
|
@ -2729,6 +2797,11 @@ def main():
|
|||
wants_fw_provision = True
|
||||
RNS.log("Waiting for ESP32 reset...")
|
||||
time.sleep(7)
|
||||
if args.platform == ROM.PLATFORM_NRF52:
|
||||
wants_fw_provision = True
|
||||
RNS.log("Waiting for NRF52 reset...")
|
||||
# Don't need to wait as long this time.
|
||||
time.sleep(5)
|
||||
else:
|
||||
RNS.log("Error from flasher ("+str(flash_status)+") while writing.")
|
||||
RNS.log("Some boards have trouble flashing at high speeds, and you can")
|
||||
|
@ -2754,6 +2827,11 @@ def main():
|
|||
exit()
|
||||
|
||||
rnode = RNode(rnode_serial)
|
||||
ports = list_ports.comports()
|
||||
for port in ports:
|
||||
if port.device == args.port:
|
||||
rnode.usb_serial_id = port.serial_number
|
||||
break
|
||||
thread = threading.Thread(target=rnode.readLoop, daemon=True).start()
|
||||
|
||||
try:
|
||||
|
@ -2772,7 +2850,6 @@ def main():
|
|||
if args.eeprom_wipe:
|
||||
RNS.log("WARNING: EEPROM is being wiped! Power down device NOW if you do not want this!")
|
||||
rnode.wipe_eeprom()
|
||||
rnode.hard_reset()
|
||||
exit()
|
||||
|
||||
RNS.log("Reading EEPROM...")
|
||||
|
@ -2795,8 +2872,12 @@ def main():
|
|||
fw_filename = "rnode_firmware_featheresp32.zip"
|
||||
elif rnode.board == ROM.BOARD_GENERIC_ESP32:
|
||||
fw_filename = "rnode_firmware_esp32_generic.zip"
|
||||
elif rnode.platform == ROM.PLATFORM_NRF52:
|
||||
if rnode.board == ROM.BOARD_RAK4631:
|
||||
fw_filename = "rnode_firmware_rak4631.zip"
|
||||
else:
|
||||
fw_filename = None
|
||||
|
||||
if args.update:
|
||||
RNS.log("ERROR: No firmware found for this board. Cannot update.")
|
||||
exit()
|
||||
|
@ -2877,12 +2958,16 @@ def main():
|
|||
partition_full_path = EXT_DIR+"/extracted_rnode_firmware.bin"
|
||||
else:
|
||||
partition_full_path = UPD_DIR+"/"+selected_version+"/"+partition_filename
|
||||
partition_hash = get_partition_hash(partition_full_path)
|
||||
partition_hash = get_partition_hash(rnode.platform, partition_full_path)
|
||||
if partition_hash != None:
|
||||
rnode.set_firmware_hash(partition_hash)
|
||||
rnode.indicate_firmware_update()
|
||||
sleep(1)
|
||||
|
||||
if rnode.platform == ROM.PLATFORM_NRF52:
|
||||
# Allow extra time for writing to EEPROM on NRF52. Current implementation is slow.
|
||||
sleep(14)
|
||||
|
||||
rnode.disconnect()
|
||||
flash_status = call(get_flasher_call(rnode.platform, fw_filename))
|
||||
if flash_status == 0:
|
||||
|
@ -3074,6 +3159,27 @@ def main():
|
|||
if rnode.platform == ROM.PLATFORM_ESP32:
|
||||
RNS.log("Waiting for ESP32 reset...")
|
||||
time.sleep(6)
|
||||
elif rnode.platform == ROM.PLATFORM_NRF52:
|
||||
rnode_serial.close()
|
||||
RNS.log("Waiting for NRF52 reset...")
|
||||
time.sleep(14)
|
||||
selected_port = None
|
||||
ports = list_ports.comports()
|
||||
for port in ports:
|
||||
if port.serial_number == rnode.usb_serial_id:
|
||||
selected_port = port
|
||||
break
|
||||
if selected_port is None:
|
||||
RNS.log("Could not detect new port for NRF52...")
|
||||
else:
|
||||
try:
|
||||
rnode_serial = rnode_open_serial(selected_port.device)
|
||||
rnode.serial = rnode_serial
|
||||
thread = threading.Thread(target=rnode.readLoop, daemon=True).start()
|
||||
except Exception as e:
|
||||
RNS.log("Could not open the specified serial port. The contained exception was:")
|
||||
RNS.log(str(e))
|
||||
exit()
|
||||
else:
|
||||
time.sleep(3)
|
||||
|
||||
|
@ -3098,6 +3204,8 @@ def main():
|
|||
if args.product != None:
|
||||
if args.product == "03":
|
||||
mapped_product = ROM.PRODUCT_RNODE
|
||||
elif args.product == "10":
|
||||
mapped_product = ROM.PRODUCT_RAK4631
|
||||
elif args.product == "f0":
|
||||
mapped_product = ROM.PRODUCT_HMBRW
|
||||
elif args.product == "e0":
|
||||
|
@ -3114,7 +3222,11 @@ def main():
|
|||
else:
|
||||
model = mapped_model
|
||||
else:
|
||||
if args.model == "a4":
|
||||
if args.model == "11":
|
||||
model = ROM.MODEL_11
|
||||
elif args.model == "12":
|
||||
model = ROM.MODEL_12
|
||||
elif args.model == "a4":
|
||||
model = ROM.MODEL_A4
|
||||
elif args.model == "a9":
|
||||
model = ROM.MODEL_A9
|
||||
|
@ -3227,7 +3339,9 @@ def main():
|
|||
time.sleep(0.006)
|
||||
|
||||
rnode.write_eeprom(ROM.ADDR_INFO_LOCK, ROM.INFO_LOCK_BYTE)
|
||||
|
||||
if rnode.platform == ROM.PLATFORM_NRF52:
|
||||
# Allow extra time for writing to EEPROM on NRF52. Current implementation is slow.
|
||||
sleep(3)
|
||||
RNS.log("EEPROM written! Validating...")
|
||||
|
||||
if wants_fw_provision:
|
||||
|
@ -3241,18 +3355,58 @@ def main():
|
|||
vf.close()
|
||||
else:
|
||||
partition_filename = fw_filename.replace(".zip", ".bin")
|
||||
partition_hash = get_partition_hash(UPD_DIR+"/"+selected_version+"/"+partition_filename)
|
||||
partition_hash = get_partition_hash(rnode.platform, UPD_DIR+"/"+selected_version+"/"+partition_filename)
|
||||
|
||||
if partition_hash != None:
|
||||
time.sleep(0.75)
|
||||
RNS.log("Setting firmware checksum...")
|
||||
rnode.set_firmware_hash(partition_hash)
|
||||
|
||||
rnode.hard_reset()
|
||||
if rnode.platform == ROM.PLATFORM_ESP32:
|
||||
rnode.hard_reset()
|
||||
RNS.log("Waiting for ESP32 reset...")
|
||||
time.sleep(6.5)
|
||||
|
||||
elif rnode.platform == ROM.PLATFORM_NRF52:
|
||||
rnode.hard_reset()
|
||||
# The hard reset on this platform is different
|
||||
# to that of the ESP32 platform, it causes
|
||||
# disruption to the serial connection.
|
||||
# Therefore, we have to reestablish the serial
|
||||
# connection after the reset.
|
||||
rnode_serial.close()
|
||||
RNS.log("Waiting for NRF52 reset...")
|
||||
|
||||
# Give plenty of time for to allow for
|
||||
# potential e-ink display refresh too.
|
||||
time.sleep(14)
|
||||
|
||||
# After the hard reset, the port number will
|
||||
# change. We need to find the new port number,
|
||||
# which can be done non-interactively by
|
||||
# comparing the USB serial numbers of the
|
||||
# original port and the one we are currently
|
||||
# iterating.
|
||||
selected_port = None
|
||||
ports = list_ports.comports()
|
||||
for port in ports:
|
||||
if port.serial_number == rnode.usb_serial_id:
|
||||
selected_port = port
|
||||
break
|
||||
if selected_port is None:
|
||||
RNS.log("Could not detect new port for NRF52...")
|
||||
else:
|
||||
try:
|
||||
rnode_serial = rnode_open_serial(selected_port.device)
|
||||
rnode.serial = rnode_serial
|
||||
thread = threading.Thread(target=rnode.readLoop, daemon=True).start()
|
||||
except Exception as e:
|
||||
RNS.log("Could not open the specified serial port. The contained exception was:")
|
||||
RNS.log(str(e))
|
||||
exit()
|
||||
else:
|
||||
rnode.hard_reset()
|
||||
|
||||
rnode.download_eeprom()
|
||||
if rnode.provisioned:
|
||||
RNS.log("EEPROM Bootstrapping successful!")
|
||||
|
|
Loading…
Reference in New Issue