Skip to content

Commit

Permalink
make configs without sensors working again
Browse files Browse the repository at this point in the history
  • Loading branch information
andreas committed Nov 5, 2023
1 parent a9fc00c commit d0018c6
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 107 deletions.
1 change: 0 additions & 1 deletion lib/iictask/GwIicTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ static SensorList sensors;
void initIicTask(GwApi *api){
GwLog *logger=api->getLogger();
#ifndef _GWIIC
vTaskDelete(NULL);
return;
#else
bool addTask=false;
Expand Down
240 changes: 134 additions & 106 deletions tools/flashtool/flashtool.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,130 @@
from tkinter import filedialog as FileDialog

import builtins
import esptool

VERSION="Version 2.0"
class Flasher():
def getVersion(self):
return ("Version %s, esptool %s"%(VERSION,str(esptool.__version__)))

UPDATE_ADDR = 0x10000
HDROFFSET = 288
VERSIONOFFSET = 16
NAMEOFFSET = 48
IDOFFSET=12 #2 byte chipid
MINSIZE = HDROFFSET + NAMEOFFSET + 32
CHECKBYTES = {
288: 0x32, # app header magic
289: 0x54,
290: 0xcd,
291: 0xab
}
#flash addresses for full images based on chip id
FLASH_ADDR={
0: 0x1000,
9: 0
}
def getString(self,buffer, offset, len):
return buffer[offset:offset + len].rstrip(b'\0').decode('utf-8')
def getFirmwareInfo(self,filename,isFull):
with open(filename,"rb") as ih:
buffer = ih.read(self.MINSIZE)
if len(buffer) != self.MINSIZE:
return self.setErr("invalid image file %s, to short"%filename)
if buffer[0] != 0xe9:
return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0])
chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1]
flashoffset=self.FLASH_ADDR.get(chipid)
if flashoffset is None:
return self.setErr("unknown chip id in image %d",chipid);
if isFull:
offset=self.UPDATE_ADDR-flashoffset;
offset-=self.MINSIZE
ih.seek(offset,os.SEEK_CUR)
buffer=ih.read(self.MINSIZE)
if len(buffer) != self.MINSIZE:
return self.setErr("invalid image file %s, to short"%filename)
if buffer[0] != 0xe9:
return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0])
for k, v in self.CHECKBYTES.items():
if buffer[k] != v:
return self.setErr("invalid magic at %d, expected %d got %d"
% (k+offset, v, buffer[k]))
name = self.getString(buffer, self.HDROFFSET + self.NAMEOFFSET, 32)
version = self.getString(buffer, self.HDROFFSET + self.VERSIONOFFSET, 32)
chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1]
flashoffset=flashoffset if isFull else self.UPDATE_ADDR
return {
'error':False,
'info':"%s:%s"%(name,version),
'chipid':chipid,
'flashbase':flashoffset
}
def setErr(self,err):
return {'error':True,'info':err}
def checkImageFile(self,filename,isFull):
if not os.path.exists(filename):
return self.setErr("file %s not found"%filename)
return self.getFirmwareInfo(filename,isFull)

def checkSettings(self,port,fileName,isFull):
if port is None:
print("ERROR: no com port selected")
return
if fileName is None or fileName == '':
print("ERROR: no filename selected")
return
info = self.checkImageFile(fileName, isFull)
if info['error']:
print("ERROR: %s" % info['info'])
return
return {'fileName': fileName,'port':port,'isFull':isFull,'info':info}
def runEspTool(self,command):
print("run esptool: %s" % " ".join(command))
try:
esptool.main(command)
print("esptool done")
return True
except Exception as e:
print("Exception in esptool %s" % e)
def verifyChip(self,param):
if not param:
print("check failed")
return
imageChipId=param['info']['chipid']
chip=esptool.ESPLoader.detect_chip(param['port'])
print("Detected chip %s, id=%d"%(chip.CHIP_NAME,chip.IMAGE_CHIP_ID))
if (chip.IMAGE_CHIP_ID != imageChipId):
print("##Error: chip id in image %d does not match detected chip"%imageChipId)
return
print("Checks OK")
param['chipname']=chip.CHIP_NAME
return param
def runCheck(self,port,fileName,isFull):
param = self.checkSettings(port,fileName,isFull)
if not param:
return
print("Settings OK")
param=self.verifyChip(param)
if not param:
print("Check Failed")
return
print("flashbase=0x%x"%param['info']['flashbase'])
return param
def runFlash(self,param):
if not param:
return
if param['isFull']:
command=['--chip',param['chipname'],'--port',param['port'],'write_flash',str(param['info']['flashbase']),param['fileName']]
self.runEspTool(command)
else:
command=['--chip',param['chipname'],'--port',param['port'],'erase_region','0xe000','0x2000']
self.runEspTool(command)
command = ['--chip', param['chipname'], '--port', param['port'], 'write_flash', str(param['info']['flashbase']), param['fileName']]
self.runEspTool(command)

def main():
VERSION="Version 2.0, esptool 3.2"

oldprint=builtins.print
def print(*args, **kwargs):
Expand All @@ -32,6 +153,7 @@ def print(*args, **kwargs):

class App:
def __init__(self, root):
self.flasher=Flasher()
root.title("ESP32 NMEA2000 Flash Tool")
root.geometry("800x600")
root.resizable(width=True, height=True)
Expand All @@ -47,7 +169,7 @@ def __init__(self, root):
frame.columnconfigure(1, weight=3)
tk.Label(frame,text="ESP32 NMEA2000 Flash Tool").grid(row=row,column=0,columnspan=2,sticky='ew')
row+=1
tk.Label(frame, text=VERSION).grid(row=row,column=0,columnspan=2,sticky="ew",pady=10)
tk.Label(frame, text=self.flasher.getVersion()).grid(row=row,column=0,columnspan=2,sticky="ew",pady=10)
row+=1
self.mode=tk.IntVar()
self.mode.set(1)
Expand Down Expand Up @@ -108,7 +230,7 @@ def fileDialog(self,ev):
fn=FileDialog.askopenfilename()
if fn:
self.filename.set(fn)
info=self.checkImageFile(fn,self.mode.get() == 1)
info=self.flasher.checkImageFile(fn,self.mode.get() == 1)
if info['error']:
self.fileInfo.set("***ERROR: %s"%info['info'])
else:
Expand Down Expand Up @@ -141,68 +263,6 @@ def addText(self,*args,**kwargs):
self.interrupt=False
raise Exception("User cancel")

UPDATE_ADDR = 0x10000
HDROFFSET = 288
VERSIONOFFSET = 16
NAMEOFFSET = 48
IDOFFSET=12 #2 byte chipid
MINSIZE = HDROFFSET + NAMEOFFSET + 32
CHECKBYTES = {
288: 0x32, # app header magic
289: 0x54,
290: 0xcd,
291: 0xab
}
#flash addresses for full images based on chip id
FLASH_ADDR={
0: 0x1000,
9: 0
}

def getString(self,buffer, offset, len):
return buffer[offset:offset + len].rstrip(b'\0').decode('utf-8')

def getFirmwareInfo(self,filename,isFull):
with open(filename,"rb") as ih:
buffer = ih.read(self.MINSIZE)
if len(buffer) != self.MINSIZE:
return self.setErr("invalid image file %s, to short"%filename)
if buffer[0] != 0xe9:
return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0])
chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1]
flashoffset=self.FLASH_ADDR.get(chipid)
if flashoffset is None:
return self.setErr("unknown chip id in image %d",chipid);
if isFull:
offset=self.UPDATE_ADDR-flashoffset;
offset-=self.MINSIZE
ih.seek(offset,os.SEEK_CUR)
buffer=ih.read(self.MINSIZE)
if len(buffer) != self.MINSIZE:
return self.setErr("invalid image file %s, to short"%filename)
if buffer[0] != 0xe9:
return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0])
for k, v in self.CHECKBYTES.items():
if buffer[k] != v:
return self.setErr("invalid magic at %d, expected %d got %d"
% (k+offset, v, buffer[k]))
name = self.getString(buffer, self.HDROFFSET + self.NAMEOFFSET, 32)
version = self.getString(buffer, self.HDROFFSET + self.VERSIONOFFSET, 32)
chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1]
return {
'error':False,
'info':"%s:%s"%(name,version),
'chipid':chipid,
'flashbase':flashoffset if isFull else self.UPDATE_ADDR
}

def setErr(self,err):
return {'error':True,'info':err}
def checkImageFile(self,filename,isFull):
if not os.path.exists(filename):
return self.setErr("file %s not found"%filename)
return self.getFirmwareInfo(filename,isFull)

def runCheck(self):
self.text_widget.delete("1.0", "end")
idx = self.port.current()
Expand All @@ -212,63 +272,31 @@ def runCheck(self):
return
port = self.serialDevices[idx]
fn = self.filename.get()
if fn is None or fn == '':
self.addText("ERROR: no filename selected")
return
info = self.checkImageFile(fn, isFull)
if info['error']:
print("ERROR: %s" % info['info'])
return
return {'port':port,'isFull':isFull,'info':info}
param = self.flasher.runCheck(port,fn,isFull)
return param

def runEspTool(self,command):
def runFlash(self,param):
for b in self.actionButtons:
b.configure(state=tk.DISABLED)
self.cancelButton.configure(state=tk.NORMAL)
print("run esptool: %s" % " ".join(command))
root.update()
root.update_idletasks()
try:
esptool.main(command)
print("esptool done")
except Exception as e:
print("Exception in esptool %s" % e)
self.flasher.runFlash(param)
for b in self.actionButtons:
b.configure(state=tk.NORMAL)
self.cancelButton.configure(state=tk.DISABLED)
def verifyChip(self):
param = self.runCheck()
if not param:
print("check failed")
return
imageChipId=param['info']['chipid']
chip=esptool.ESPLoader.detect_chip(param['port'])
print("Detected chip %s, id=%d"%(chip.CHIP_NAME,chip.IMAGE_CHIP_ID))
if (chip.IMAGE_CHIP_ID != imageChipId):
print("##Error: chip id in image %d does not match detected chip"%imageChipId)
return
print("Checks OK")
param['chipname']=chip.CHIP_NAME
return param

def buttonCheck(self):
param = self.verifyChip()
param = self.runCheck()



def buttonFlash(self):
param=self.verifyChip()
param=self.runCheck()
if not param:
return
if param['isFull']:
command=['--chip',param['chipname'],'--port',param['port'],'write_flash',str(param['info']['flashbase']),self.filename.get()]
self.runEspTool(command)
else:
command=['--chip',param['chipname'],'--port',param['port'],'erase_region','0xe000','0x2000']
self.runEspTool(command)
command = ['--chip', param['chipname'], '--port', param['port'], 'write_flash', str(param['info']['flashbase']), self.filename.get()]
self.runEspTool(command)


self.runFlash(param)

def buttonCancel(self):
self.interrupt=True

Expand Down

0 comments on commit d0018c6

Please sign in to comment.