diff --git a/.gitignore b/.gitignore index f218698c..5ab36f45 100644 --- a/.gitignore +++ b/.gitignore @@ -7,23 +7,20 @@ __pycache__/ # Sphinx documentation docs/_build/ -# Telemetry Application -Applications/Telemetry/telemetry.ini -Applications/Telemetry/*.db -Applications/Telemetry/*.db-journal - -# APRS Application -Applications/APRS/aprs.ini - -# Device Configuration -Applications/deviceconfiguration/deviceconfiguration.ini -Applications/deviceconfiguration/faraday_config.ini +# Application Configuration files +etc/faraday/telemetry.ini +etc/faraday/aprs.ini +etc/faraday/deviceconfiguration.ini +etc/faraday/faraday_config.ini +etc/faraday/simpleui.ini +etc/faraday/proxy.ini +etc/faraday/bsl.ini +etc/faraday/firmware.txt # Hermes Application Applications/Hermes/hermes.ini # SimpleUI Application -Applications/SimpleUI/simpleui.ini Applications/SimpleUI/node_modules/ #IDE (Pycharm) @@ -31,13 +28,16 @@ Applications/SimpleUI/node_modules/ .idea/* Tutorials/Tutorials/2-Advanced_Proxy_Programs/Simple_Text_Messaging/Engineering_Documents/~$Packets.xlsx -# Proxy -proxy/proxy.ini -proxy/*.db - #Virtualenv faradayenv/ # Developer Tutorials Tutorials\Python_Developer_Tutorials\foundation\Commanding-Local\command_local.ini -Tutorials\Python_Developer_Tutorials\foundation\Commanding-Remote-RF\commanding-remote.ini \ No newline at end of file +Tutorials\Python_Developer_Tutorials\foundation\Commanding-Remote-RF\commanding-remote.ini + +# Bootstrap Loader +etc/faraday/faradayFirmwareUpgradeScript.txt + +#Setuptools +build/ +dist/ diff --git a/Firmware_Bootstrap_Loader/faradaybsl/FaradayFirmwareUpgradeScript.txt b/Firmware_Bootstrap_Loader/faradaybsl/FaradayFirmwareUpgradeScript.txt deleted file mode 100644 index 10bb1e45..00000000 --- a/Firmware_Bootstrap_Loader/faradaybsl/FaradayFirmwareUpgradeScript.txt +++ /dev/null @@ -1,9 +0,0 @@ -MODE 6xx UART 9600 COM112 PARITY -CHANGE_BAUD_RATE 115200 -VERBOSE -RX_PASSWORD pass32_wrong.txt -RX_PASSWORD pass32_default.txt -RX_DATA_BLOCK ../Faraday_D1_Release.txt -CRC_CHECK 0x8000 0x4999 0x88b2 -CRC_CHECK 0xc99a 0x60 0x1ca6 -CRC_CHECK 0xffda 0x26 0xbc88 diff --git a/Firmware_Bootstrap_Loader/faradaybsl/Program_CRC_Calculations.txt b/Firmware_Bootstrap_Loader/faradaybsl/Program_CRC_Calculations.txt deleted file mode 100644 index 73046ff8..00000000 --- a/Firmware_Bootstrap_Loader/faradaybsl/Program_CRC_Calculations.txt +++ /dev/null @@ -1,15 +0,0 @@ -Memory Address: 0x8000 -Data Length: 0x4999 -CRC: 0x88b2 -CRC_CHECK 0x8000 0x4999 0x88b2 - -Memory Address: 0xc99a -Data Length: 0x60 -CRC: 0x1ca6 -CRC_CHECK 0xc99a 0x60 0x1ca6 - -Memory Address: 0xffda -Data Length: 0x26 -CRC: 0xbc88 -CRC_CHECK 0xffda 0x26 0xbc88 - diff --git a/Firmware_Bootstrap_Loader/faradaybsl/bsl-scripter-windows.exe b/etc/faraday/bsl-scripter-windows.exe similarity index 100% rename from Firmware_Bootstrap_Loader/faradaybsl/bsl-scripter-windows.exe rename to etc/faraday/bsl-scripter-windows.exe diff --git a/etc/faraday/bsl.sample.ini b/etc/faraday/bsl.sample.ini new file mode 100644 index 00000000..d46aece4 --- /dev/null +++ b/etc/faraday/bsl.sample.ini @@ -0,0 +1,7 @@ +[BOOTSTRAP] +FILENAME = master.txt +COM = REPLACEME +OUTPUTFILENAME = programCRCCalculations.txt +FIRMWAREUPGRADESCRIPT = faradayFirmwareUpgradeScript.txt +BSLEXECUTABLE = bsl-scripter-windows.exe +MASTERURL = https://raw.githubusercontent.com/FaradayRF/Faraday-Firmware/master/Debug/Faraday_D1_Release.txt diff --git a/Firmware_Bootstrap_Loader/faradaybsl/pass32_default.txt b/etc/faraday/pass32_default.txt similarity index 100% rename from Firmware_Bootstrap_Loader/faradaybsl/pass32_default.txt rename to etc/faraday/pass32_default.txt diff --git a/Firmware_Bootstrap_Loader/faradaybsl/pass32_wrong.txt b/etc/faraday/pass32_wrong.txt similarity index 100% rename from Firmware_Bootstrap_Loader/faradaybsl/pass32_wrong.txt rename to etc/faraday/pass32_wrong.txt diff --git a/etc/faraday/programCRCCalculations.txt b/etc/faraday/programCRCCalculations.txt new file mode 100644 index 00000000..1c9ebd22 --- /dev/null +++ b/etc/faraday/programCRCCalculations.txt @@ -0,0 +1,15 @@ +Memory Address: 0x8000 +Data Length: 0x4b51 +CRC: 0xbef +CRC_CHECK 0x8000 0x4b51 0xbef + +Memory Address: 0xcb52 +Data Length: 0x60 +CRC: 0x4068 +CRC_CHECK 0xcb52 0x60 0x4068 + +Memory Address: 0xffda +Data Length: 0x26 +CRC: 0x5c7d +CRC_CHECK 0xffda 0x26 0x5c7d + diff --git a/faraday/bootstrap.py b/faraday/bootstrap.py new file mode 100644 index 00000000..8f4c316a --- /dev/null +++ b/faraday/bootstrap.py @@ -0,0 +1,194 @@ +#------------------------------------------------------------------------------- +# Name: /faraday/bootstrap.py +# Purpose: Bootstrap loads firmware onto the Faraday Wireless Node via USB +# +# Author: Bryce Salmi +# +# Created: 7/18/2017 +# Licence: GPLv3 +#------------------------------------------------------------------------------- + +import logging.config +import ConfigParser +import os +import sys +import argparse +import shutil +import subprocess +import urllib2 + +from classes import createtiscript +from classes import faradayFTDI + +# Start logging after importing modules +relpath1 = os.path.join('etc', 'faraday') +relpath2 = os.path.join('..', 'etc', 'faraday') +setuppath = os.path.join(sys.prefix, 'etc', 'faraday') +userpath = os.path.join(os.path.expanduser('~'), '.faraday') +path = '' + +for location in os.curdir, relpath1, relpath2, setuppath, userpath: + try: + logging.config.fileConfig(os.path.join(location, "loggingConfig.ini")) + path = location + break + except ConfigParser.NoSectionError: + pass + +logger = logging.getLogger('BSL') + +#Create bsl configuration file path +bslConfigPath = os.path.join(path, "bsl.ini") +logger.debug('bsl.ini PATH: ' + bslConfigPath) + +bslConfig = ConfigParser.RawConfigParser() +bslConfig.read(bslConfigPath) + +# Command line input +parser = argparse.ArgumentParser(description='BSL will Boostrap load firmware onto Faraday via USB connection. Requires http://www.ftdichip.com/Drivers/D2XX.htm') +parser.add_argument('--init-config', dest='init', action='store_true', help='Initialize BSL configuration file') +parser.add_argument('--start', action='store_true', help='Start Boostrap loader') +parser.add_argument('--getmaster', action='store_true', help='Download newest firmware from master firmware repository') +parser.add_argument('--port', help='Set UART port to bootstrap load firmware') + +# Parse the arguments +args = parser.parse_args() + + +def initializeBSLConfig(): + ''' + Initialize BSL configuration file from bsl.sample.ini + + :return: None, exits program + ''' + + logger.info("Initializing BSL") + shutil.copy(os.path.join(path, "bsl.sample.ini"), os.path.join(path, "bsl.ini")) + logger.info("Initialization complete") + sys.exit(0) + + +def configureBSL(args, bslConfigPath): + ''' + Configure BSL configuration file from command line + + :param args: argparse arguments + :param bslConfigPath: Path to bsl.ini file + :return: None + ''' + + config = ConfigParser.RawConfigParser() + config.read(os.path.join(path, "bsl.ini")) + + if args.port is not None: + config.set('BOOTSTRAP', 'COM', args.port) + + with open(bslConfigPath, 'wb') as configfile: + config.write(configfile) + + +def getMaster(): + ''' + Downloads latest firmware from master github repo, save to userspace + + :return: None, exits program + ''' + + try: + url = bslConfig.get("BOOTSTRAP", "MASTERURL") + + except ConfigParser.Error as e: + logger.error(e) + logger.error("You must initialize faraday-bsl with --init-config!") + sys.exit(1) + + logger.info("Downloading latest Master firmware...") + + # Download latest firmware from url + response = urllib2.urlopen(url) + data = response.read() + logger.debug(data) + + # Save to file, create folders if not present + firmwarePath = os.path.join(os.path.expanduser('~'), '.faraday', 'firmware') + try: + os.makedirs(firmwarePath) + except: + pass + + # Create master.txt if it doesn't exist, otherwise write over it + firmware = os.path.join(firmwarePath, 'master.txt') + f = open(firmware, 'w+') + f.write(data) + f.close() + + logger.info("Download complete") + + +# Now act upon the command line arguments +# Initialize and configure bsl +if args.init: + initializeBSLConfig() +configureBSL(args, bslConfigPath) + +# Read in BSL configuration parameters +bslFile = bslConfig.read(bslConfigPath) + +# Check for --getmaster +if args.getmaster: + getMaster() + +# Check for --start option and exit if not present +if not args.start: + logger.warning("--start option not present, exiting BSL server!") + sys.exit(0) + + +def main(): + """ + Main function which starts the Boostrap Loader. + + :return: None + """ + + logger.info('Starting Faraday Bootstrap Loader application') + + # Read in configuration parameters + try: + filename = bslConfig.get("BOOTSTRAP", "FILENAME") + outputFilename = bslConfig.get("BOOTSTRAP", "OUTPUTFILENAME") + upgradeScript = bslConfig.get("BOOTSTRAP", "FIRMWAREUPGRADESCRIPT") + bslExecutable = bslConfig.get("BOOTSTRAP", "BSLEXECUTABLE") + port = bslConfig.get("BOOTSTRAP", "COM") + + except ConfigParser.Error as e: + logger.error(e) + logger.error("You must initialize faraday-bsl with --init-config!") + sys.exit(1) + + if port == "REPLACEME": + logger.error("You must set the UART port with --port PORT!") + sys.exit(1) + + # Create TI BSL script + script = createtiscript.CreateTiBslScript(path, + filename, + port, + outputFilename, + upgradeScript, + logger) + script.createscript() + + # Enable BSL Mode using FTDI drivers + try: + device_bsl = faradayFTDI.FtdiD2xxCbusControlObject() + device_bsl.EnableBslMode() + subprocess.call([os.path.join(path, bslExecutable), os.path.join(path, upgradeScript)]) + device_bsl.DisableBslMode() + + except: + logger.error("FTDI driver failure, make sure FTDI drivers are installed!") + + +if __name__ == '__main__': + main() diff --git a/faraday/classes/__init__.py b/faraday/classes/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Firmware_Bootstrap_Loader/faradaybsl/createtiscripter.py b/faraday/classes/createtiscript.py similarity index 53% rename from Firmware_Bootstrap_Loader/faradaybsl/createtiscripter.py rename to faraday/classes/createtiscript.py index 54505baa..e0c729d4 100644 --- a/Firmware_Bootstrap_Loader/faradaybsl/createtiscripter.py +++ b/faraday/classes/createtiscript.py @@ -1,63 +1,88 @@ #------------------------------------------------------------------------------- -# Name: module1 -# Purpose: +# Name: /faraday/classes/createtiscript.py +# Purpose: Texas Instruments bootloader script creation class # -# Author: Brent +# Author: Brenton Salmi, Bryce Salmi # # Created: 03/08/2016 -# Copyright: (c) Brent 2016 -# Licence: +# Licence: GPLv3 #------------------------------------------------------------------------------- -import array -#filename = sys.argv[1] -# filename = 'RF_Test_Firmware_1-17-17.txt' -# device_com_port = 32 -# -# f = open(filename, 'r') -# -# mem_addr_index = [] -# section_data_index = [] -# file_program_hex = f.read() - -#print "Arguement 0:", argument1 +import array +import os +import sys class CreateTiBslScript(object): + """ + This class creates a TI Bootstrap Loader script file from a text file of Faraday firmware + """ - def __init__(self, filename, comport): - self.filename = filename + def __init__(self, path, filename, comport, outputfilename, upgradeScript, logger): + """ + initialize the class and variables + """ + + self.path = path + self._filename = os.path.join(os.path.expanduser('~'), '.faraday', 'firmware', filename) self.comport = comport self.mem_addr_index = [] self.section_data_index = [] + self._outputfilename = outputfilename + self._upgradeScript = upgradeScript + self.logger = logger def createscript(self): - f = open(self.filename, 'r') - file_program_hex = f.read() - self.ParseTiTxtHexFile(file_program_hex) - self.CreateOutputFile() - self.CreateBslScript() + """ + Create the TI Boostrap loader script + + :return: None + """ + + try: + f = open(os.path.join(self.path, self._filename), 'r') + file_program_hex = f.read() + + except: + # File likely doesn't exist, warn user and exit + self.logger.error('{0} doesn\'t exist!'.format(self._filename)) + self.logger.error('try --getmaster') + sys.exit(1) - # ParseTiTxtHexFile(file_program_hex) - # CreateOutputFile() - # CreateBslScript() + self.ParseTiTxtHexFile(file_program_hex) + self.CreateOutputFile(self._outputfilename) + self.CreateBslScript(self._upgradeScript) def ParseTiTxtHexFile(self, input_file): + """ + Parse the hex text file properly + + :param input_file: File object to parse + :return: None + """ + datasections = input_file.split('@') datasections.pop(0) #remove empty first index - #remove memory addresses and separate data in each section + # Remove memory addresses and separate data in each section for i in range(0, len(datasections)): - #Parse and strip TI-TXT format + # Parse and strip TI-TXT format a = datasections[i].replace('\n', '') a = a.replace(' ', '') mem_addr = str(a[0:4]).decode('hex') section_data = str(a[4:]).replace('q', '') #remove end of file - #Ouput + # Output self.mem_addr_index.append(mem_addr) self.section_data_index.append(section_data.decode('hex')) def CalcTiTxtCrc16(self, databytes): + """ + Check text file CRC16 value + + :param databytes: data to perform CRC on + :return: CRC value + """ + data_array = array.array('B', databytes) chk = 0xffff for item in data_array: @@ -70,8 +95,15 @@ def CalcTiTxtCrc16(self, databytes): crc_script_index = [] - def CreateOutputFile(self): - textfile = open("faradaybsl/Program_CRC_Calculations.txt", 'w') + def CreateOutputFile(self, filename): + """ + Create output TI bootstrap loader file from firmware text data + + :param filename: Bootstrap loader output data filename + :return: CRC value + """ + + textfile = open(os.path.join(self.path, filename), 'w') for i in range(0, len(self.mem_addr_index)): final_addr = self.mem_addr_index[i].encode('hex') final_len = hex(len(self.section_data_index[i])) @@ -87,20 +119,20 @@ def CreateOutputFile(self): textfile.writelines(('\n', script_index_crc)) textfile.writelines('\n\n') - def CreateBslScript(self): - #global device_com_port - #com_string = 'MODE 6xx UART 9600 COM%d PARITY' % device_com_port - textfile = open("faradaybsl/FaradayFirmwareUpgradeScript.txt", 'w') + def CreateBslScript(self, filename): + """ + Create output TI bootstrap loader script from firmware text data + + :param filename: Bootstrap loader update script filename + :return: CRC value + """ + + textfile = open(os.path.join(self.path, filename), 'w') textfile.writelines(("MODE 6xx UART 9600 ", str(self.comport), " PARITY", '\n')) textfile.writelines(("CHANGE_BAUD_RATE 115200", '\n')) textfile.writelines(("VERBOSE", '\n')) textfile.writelines(("RX_PASSWORD pass32_wrong.txt", '\n')) #gives the wrong password to mass erase the memory textfile.writelines(("RX_PASSWORD pass32_default.txt", '\n')) - print "Script file:", self.filename - textfile.writelines(("RX_DATA_BLOCK ", "../", self.filename, '\n')) + textfile.writelines(("RX_DATA_BLOCK ", self._filename, '\n')) for i in range(0, len(self.crc_script_index)): textfile.writelines((str(self.crc_script_index[i]), '\n')) - -#ParseTiTxtHexFile(file_program_hex) -#CreateOutputFile() -#CreateBslScript() diff --git a/Firmware_Bootstrap_Loader/faradaybsl/faradayftdi.py b/faraday/classes/faradayFTDI.py similarity index 72% rename from Firmware_Bootstrap_Loader/faradaybsl/faradayftdi.py rename to faraday/classes/faradayFTDI.py index 17140b9f..17d45ab2 100644 --- a/Firmware_Bootstrap_Loader/faradaybsl/faradayftdi.py +++ b/faraday/classes/faradayFTDI.py @@ -1,10 +1,27 @@ +#------------------------------------------------------------------------------- +# Name: /faraday/classes/faradayFTDI.py +# Purpose: Control FTDI chip during Bootstrap Loader operation +# +# Author: Brenton Salmi, Bryce Salmi +# +# Created: 07/19/2017 +# Licence: GPLv3 +#------------------------------------------------------------------------------- + import ctypes import ctypes.wintypes import time class FtdiD2xxCbusControlObject(object): + """ + This class controls the FTDI FT230X during bootloading + """ + def __init__(self): + """ + initialize the class and variables + """ self.BITMASK_IO_OUTPUTS = 0xF0 self.BITMASK_IO_OUTPUTS_RESET = 0x40 self.BITMASK_IO_INPUTS = 0x00 @@ -15,14 +32,22 @@ def __init__(self): self.ftd2xxDll = '' def ResetToggle(self): - #Currently Not working? + """ + Toggle reset IO + + :return: None + """ ##RESET LOW self.ftd2xxDll.FT_SetBitMode(self.handle, self.BITMASK_IO_OUTPUTS_RESET | self.BITMASK_RST, 0x20) ##Wait x time.sleep(10) def BslModeToggle(self): - #Toggle CBUS to enter BSL mode + """ + Toggle CBUS to enter BSL mode + + :return: None + """ ##RESET LOW self.ftd2xxDll.FT_SetBitMode(self.handle, self.BITMASK_IO_OUTPUTS, 0x20) ##Wait x @@ -48,13 +73,27 @@ def BslModeToggle(self): time.sleep(self.DELAY_TIME) def NominalModeToggle(self): + """ + Toggle FTDI IC into nominal mode + + :return: None + """ self.ftd2xxDll.FT_SetBitMode(self.handle, self.BITMASK_IO_INPUTS, 0x20) def NominalForcedToggle(self): + """ + Force FTDI IC into nominal mode + + :return: None + """ self.ftd2xxDll.FT_SetBitMode(self.handle, self.BITMASK_IO_OUTPUTS | self.BITMASK_RST, 0x20) def DisableBslToggle(self): - #Toggle CBUS to leave BSL mode per Errata (Reset won't work) + """ + Disable FTDI IC Bootstrap loader toggling. Toggle CBUS to leave BSL mode per Errata (Reset won't work) + + :return: None + """ ##RESET HIGH TEST LOW self.ftd2xxDll.FT_SetBitMode(self.handle, self.BITMASK_IO_OUTPUTS | self.BITMASK_RST, 0x20) ##Wait x @@ -83,6 +122,11 @@ def DisableBslToggle(self): self.ftd2xxDll.FT_SetBitMode(self.handle, self.BITMASK_IO_OUTPUTS | self.BITMASK_RST, 0x20) def Connect(self): + """ + Use FTDI dll files to connect to IC + + :return: None + """ self.ftd2xxDll = ctypes.windll.LoadLibrary('ftd2xx.dll') self.handle = ctypes.wintypes.DWORD() assert self.ftd2xxDll.FT_Open(0, ctypes.byref(self.handle)) == 0 @@ -94,6 +138,11 @@ def Connect(self): assert self.ftd2xxDll.FT_Purge(self.handle, 3) == 0 def Disconnect(self): + """ + Use FTDI dll files to disconnect from IC + + :return: None + """ self.ftd2xxDll.FT_Close(self.handle) try: ctypes.windll.kernel32.FreeLibrary(self.ftd2xxDll._handle) @@ -103,6 +152,11 @@ def Disconnect(self): return True def EnableBslMode(self): + """ + Enable FTDI IC bootstrap loader mode + + :return: None + """ self.Connect() self.BslModeToggle() self.NominalModeToggle() @@ -110,6 +164,11 @@ def EnableBslMode(self): return True def DisableBslMode(self): + """ + Disable FTDI IC bootstrap loader mode + + :return: None + """ self.Connect() self.DisableBslToggle() self.NominalModeToggle() @@ -117,23 +176,22 @@ def DisableBslMode(self): return True def PerformStandardReset(self): + """ + Perform reset with FTDI IC + + :return: None + """ self.Connect() self.ResetToggle() self.NominalModeToggle() self.Disconnect() return True - def SetResetHigh(self): - ##RESET HIGH TEST LOW - self.ftd2xxDll.FT_SetBitMode(self.handle, self.BITMASK_IO_OUTPUTS | self.BITMASK_RST, 0x20) + def SetResetHigh(self): + """ + Set FTDI IC reset pin to high -#Action -#BslMode() -#NominalMode() -#NominalForced() -#DisableBsl() - -#writeBuffer = ctypes.create_string_buffer("abcdefghijklmnopqrstuvwxyz") -#bytesWritten = ctypes.wintypes.DWORD() -#assert self.ftd2xxDll.FT_Write(self.handle, writeBuffer, len(writeBuffer)-1, ctypes.byref(bytesWritten)) == 0 -#print bytesWritten.value + :return: None + """ + ##RESET HIGH TEST LOW + self.ftd2xxDll.FT_SetBitMode(self.handle, self.BITMASK_IO_OUTPUTS | self.BITMASK_RST, 0x20) diff --git a/setup.cfg b/setup.cfg index e8f2f137..02a5ccfa 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,7 +51,9 @@ data_files = etc/faraday/deviceconfiguration.sample.ini etc/faraday/faraday_config.sample.ini etc/faraday/data.sample.ini - + etc/faraday/programCRCCalculations.txt + etc/faraday/bsl.sample.ini + [entry_points] console_scripts = faraday-proxy = faraday.proxy:main @@ -60,4 +62,5 @@ console_scripts = faraday-simpleui = faraday.simpleui:main faraday-deviceconfiguration = faraday.deviceconfiguration:main faraday-simpleconfig = faraday.simpleconfig:main - faraday-data = faraday.data:main \ No newline at end of file + faraday-data = faraday.data:main + faraday-bsl = faraday.bootstrap:main