Put bunch of notes in Readme.txt on how to update device firmware to
v2.3 using dfusedemo. Anyone with a device currently in their hands
will want to update to this latest version using the dfusedemo
instructions there. Or the AVR instructions if you have an old kazzo.
For devices shipping after Dec 1st 2018 I will be flashing this latest
v2.3 firmware which has it's own firmware updater so the INLretro host
software can easily and seamlessly update the firmware for you without
any external software, switch or jumper operation on the PCB.
This update also includes some power functions in the bootloader
dictionary. Can now make direct read/write access to the entire ARM
memory space. Maybe I'll add this to the AVR someday..?
Having this previously would have actually allowed me to bootstrap
a switchless bootloader without dfuse.. ahh well...
Also turned the watchdog timer on for the STM32 build finally.
Requires refreshing every ~1sec, currently only done in the main.
Added application versioning to address 0x08000800 in the binary.
Couldn't get the linker script to do this for me for some reason.
So for now I just manually put it in the binary file.
The fwupdate.lua script has a lot more checks now. Uses the new
bootloader dict functions to dump device firmware and make sure
all looks good before it starts erasing firmware.
Haven't done much testing with the current AVR build. Got a report
there was a problem with UNROM flashing, will have to check that out.
Done with the firmware for awhile now hopefully. Need to clean up some
things with the main program & inlretro.lua script. Start making better
use of some recent contributions by several gracious people.
Maybe I'll get going on gameboy, GBA, & sega soon.. Got a ton of
NESmaker devices to push out the door now with this latest build. So
might be slow for a bit..
on it's own!!!
It flashes pretty quickly too. The STlink takes about 8sec to erase and
write. I'm guessing it's erasing the whole 128KByte though. My own
fwupdater takes ~3sec to flash, ~1.5sec to erase. So there might not
even be that much room for speed up. 3sec is hard to beat signficantly
anyway and it comes at the cost of bytes. Perhaps even complexity and
risk of OUT packet errors/loss on the device side. So kinda like
leaving it as is.
Have basic testing complete of erasing application/main code, flashing
data, and reading it back for verification.
This ended up being pretty big task to get working. Some previous
efforts helped out quite a bit though. The first thing needed was a
path out of the main application and this was done in bootload.c by
calling PREP_FWUPDATE. That jumps to the fwupdate area (first 2KByte)
of flash.
There the 'fwupate main' takes over. It updates the usbFunction
Setup/Write ram function pointers to fwupdate's own setup function.
Then it must hijack the processor's execution so once the PREP_UPDATE
exception is complete the processor returns to the fwupdater instead of
the main. This is done by snooping back through the stack and finding
the stack frame keying off of xPSR and valid PC address. It then stomps
the PC & LR in the stack frame to steal execution from the main thread.
After that, all usb transfers are handled by the fwupdater.
Able to get buy without the write so far since setup packets provide
data but are also IN transfers to give path for sending data back to
host. So to keep things small and simple this is all that's handled so
far. Once I get tired of it being so slow I can implement the
usbFunctionWrite and speed things up quite a bit. Haven't actually
timed it yet, but for only 20KByte of data it and not being very
frequent it shouldn't be a big deal. The more I say this the more I'm
thinking I'll add that next because I'll be using it myself so much for
development.. Less time in that state is less likely for ppl to
'semi-brick' their device.
There is of course always the stmicro dfuse demo that can always unbrick
the device. I tried really hard to jump to their bootloader but no
matter what I did I couldn't get it working. It was never recognized by
USB. I half way wonder now if I needed to disable the bootpin which I
never would want to do anyway..
Created separate build_stm folders for INL6 & INL_NES which is what all
the NESmaker kits use. Also update the make files to be more accurate
about what chip their using since fwupdate tries to prevent a hardfault
from flash access beyond what's available.
This update doesn't include a means of updating the first 2KByte of
firmware updater space itself. But the application code should be able
to take care of that for us in a future update. It's only 2KByte so
just temporarily storing the fresh build in SRAM will probably work.
Although will have to be careful about any calls from application code
to fwupdater. Plus there's always dfuse..
Other problem I ran into was erasing the application code. It worked
fine early on for all 30KByte. But as my fwupdater function grew it
crashed when page 18 was erased. Realized my bigger switch/case
statement was calling a gcc library function that resided in the
application code. It was only 50Bytes, so moved it to fwupdate section.
Brought 2 of similar library functions over as well, but one of them
disappeared with update to latest version of arm-none-eabi-gcc.
Not a commit really, but this is the release where I updated gcc. Was
previously:
gcc version 6.2.1 20161205 (release)
[ARM/embedded-6-branch revision 243739]
is now:
gcc version 7.3.1 20180622 (release) [ARM/embedded-7-branch revision
261907] (GNU Tools for Arm Embedded Processors 7-2018-q2-update)
Updating gcc provided a smaller build size of ~250 Bytes from the tail
end. But it also freed up ~50Bytes in fwupdate space as well.
with large number of updates to the linker script (nokeep.ld)
The first 2KByte is dedicated for vector table, usb driver, usb desc
tables, hardfault, dummy handler, and firmware update routines. There
is currently ~700Bytes of free space in that first 2KB. Should be
plenty of space for firmware update routines and other advanced future
features.
The 070RB has 2KByte pages, and 070C6 has 1KB pages, which is the
smallest erase granularity size. So we can't really have anything
smaller than 2KByte on the RB. This leaves 30Kbyte for the
main/application code on the C6 which should be more than enough.
That 30KByte starts with the reset handler fixed to 0x0800_0800 because
we don't want to have to update the vector table.
After the reset handler is the usbFunctionWrite, then Setup routines
which the usb driver calls for incoming/outgoing data. These need to be
in first 64KByte of flash as a 16bit pointer is kept in usb_buff RAM.
Write was put first as it's less likely to change, with Setup following
which is quite large due to all the inlining that's happening inside it
thanks to the compiler.
Perhaps these function locations could be kept at a fixed location. Or
we could make a 'vector table' of our own just before the reset handler.
This may speed things up a bit, but for now it works. Also like the
ability to change these pointers which may be useful for the next update
as the firmware update code will effectively need it's own Setup/Write
functions. So the current pointers can just be updated to call them
instead, and restore originals/new ones through reset.?
This leaves 96KByte of unused flash on the 070RB, don't have any plans
for this yet. Perhaps future updates for all the connectors and
features will require it.
Also added definition for fast ram functions to .data section. Got that
working but not sure when it may be needed..
Need to physically separate them now. Then can focus on erasing &
flashing ourselves.
Added some speed checks to bnrom.lua script that I was testing usb code
with. Was able to verify read/write speeds were no affected by changes
in this commit. Did some testing against older firmware v2.2 though
there does seem to have been a slight slow down on write speeds.
Although, perhaps that's because of the nrom flash verifications that
are also included in this build (but not commited)..?
Deleted shared_usb.h because it was a copy of shared_dict_usb.h
This build_stm .hex does include some NROM flash updates to allow
checking if the last byte programmed successfully because was having
weird problems with that. But not ready to commit all those changes and
they're highly unrelated to this commit.
Now that usb code doesn't use any .data nor .bss need to fully separate
the USB firmware code from the application. Main way to do this will be
to have usb code be effectively entirely interrupt driven.
Thinking the best way to initialize usb will to have the application
code jump to the USB ISR and maybe use some messaging system with the 2
unused usb_buff indexes (4Bytes).
The USB code will include the vector table, so it will point to the
reset handler, but that will point to the application code's reset
handler, just need to make sure that's at a fixed location.
The USB code is just over 1KByte last I checked, so dedicating 2KByte
should be good. Erase granularity is 1 page (1KB on C6, 2KB on RB). So
that will work well. Write protection granularity is 4KByte, but really
we shouldn't need to use write protection as there will always be the
built in bootloader to save a bricked device.
In effort to remove USB firmware driver's dependance on .data/.bss
Started by fixing bug that wasn't allowing USB_BTABLE to be relocatable
Was neglecting byte addressing vs usb_buff[] array indexing of 16bit
half words.
Still have 4 bytes of .bss for usbMsgPtr, need to modify the
communication protocol between application code and usb code to
move/remove this pointer out of .bss there are 4 bytes of usb_buff
ram available for it to be moved into but need to ensure only 16bit
access is made.
Once that's done can separate usb code from application code and have
usb code only interrupt driven, with application code polling.
Then the usb code can sniff out firmware update packets and update
application code behind it's back.
Removed logging of transfer count since it wasn't being used
num_bytes_expecting isn't used but breaks device descriptors if cut for
some reason... so I just moved it and kept it...
Another weird issue is after reflashing the mcu via stlink the first
inlretro.exe excecution fails due to some usb error. Not sure if it's
related to the usb code changes I just made, or possibly some other
recent updates to inlretro executable..? I think this issue has existed
forever, but was hard to pin down and always went away after a reset.
definitions. Still work left on the expansion port though..
Created *_CONN definitions so code doesn't get included for connectors
that aren't present.
Added a NES CPU write that doesn't toggle M2 but not sure if this will
really be needed for MMC2 or not..
NES scripts to use new dump/flash methodology that MMC3 started.
Includes BNROM, UNROM, MMC1, and new scripts for FME7 & MMC4 (SOP flash).
Adding more general support to SNES with v2proto_hirom that script is
actually becoming more of a master script supporting both LoROM and
HiROM including flash, dump, and save backups.
SNES Rd/Wr now designate the state of /ROMSEL so have to manually
determine if access should be in /ROMSEL space of the SNES memory map or
not. (ie all SNES cart memories are /ROMSEL space except HiROM SRAM).
I made a commit earlier this week but messed things up by not pulling
from the master and things weren't updated... Here's the notes from
that commit:
Author: Paul XPS <paul@infiniteneslives.com>
Date: Tue Nov 6 22:45:52 2018 -0600
Large commit biggest feature add is NES MMC3 support including Save RAM
(aka WRAM/PRGRAM) support including dumping and writing save files.
The MMC3 script & method of dumping/flashing is the most forward
thinking script/firmware so far. Finally starting to form a clear
vision of how I want to handle flashing/dumping variations with mappers.
Biggest thing is having the host handle the mapper init & banking
control. In the view of the firmware, it's only responsible for knowing
how to flash a bank. And dumping is even more generic with the host
just telling what address range to read. Things will get more complex
with support of mappers with bus conflicts. But ready to start
converting these old hacked methods to be more like the MMC3 means.
Have some early support for dumping gameboy using the snes script as the
pinouts are nearly identical. Along with testing of toggling between 3v
GBA and 5v DMG.
Have some early support for INLretro NES only version which uses a
smaller mcu because it doesn't need to support large 16bit carts. Still
have to get this completed.
Added support for CNROM, but I'm not sure if it's actually working. Going
to restart with NROM and start updating the currently supported
mappers to be more like MMC3.
But this also includes some new updates from the second half of the week:
Started updating existing NES scripts to use new MMC3 methodology. Got
NROM, CNROM, BNROM, & Color Dreams working. On the host side only
needed to add nes.c functions for specific flash algos. Able to delete
significant amounts of mapper specific code from flash.c
Got some basic SNES script support with new methodology for Catskull
elect 5v PLCC SNES LoROM board. And INL SNES HI/LO-ROM 3v board as
well. These don't yet use buffer writes, just single byte writes.
Also having issues with Mirroring test/sensing again. Driving me crazy,
but don't really care about it at the moment and not sure what's wrong..
So just committing that broken for now. Looking to remove this
functionality from the firmware side as the host should be controlling
most of this.
Looking to add SNES RAM & buffered writes. Also need to test some of
the HIROM code as I just added it in there while I did the LOROM stuff..
Added windows driver package, just have to run InstallDriver.exe to
get drivers installed on windows 10 (and others I believe)
Created dictionaries for all remaining cart connectors.
Nothing useful there yet, just wanted to get the files created
and dictionaries working.
Added bunch of notes to shared_dictionaries to explain how to go
about creating new dictionaries and some opcode details.
Have STM8 cic communications working "CICCOM" to change between H/V
mirroring on new discrete boards. Currently these operations are handled
entirely from the host scripts and opcode/operands are mostly hard coded.
Need to move these to more generic functions in the ciccom dictionary
which will also speed things up moving to the firmware which will speed
things up.
Some changes to mapper 30 script to eat the ines header, and test CHR-RAM
banking.
Some updates to snes flashing operations, still a work in progress to
fully support prior SNES board designs.
Mostly adding support for mappers as I needed it for my own hardware
builds:
-MMC1
-mapper 30
-easy NSF (still need to update for mapper verilog fix)
-action53 (still need to update for mapper verilog fix)
-dual port board flashing
-colordreams, not sure if I actually got this working
-color ninja, just a special CPLD version of colordreams for ninja boards
Just started working on SNES code. slowly getting things up and working
outside of main inlretro.lua script similar to how NES has been handling
everything with it's own script. Able to flash v3 boards fine. v1 boards
flash without errors, but still having some mapping problems where it
verifies but won't boot. v2 prototype flashes most bytes but not all,
seems v2 boards are much slower to output valid data.. But that may just
be the manufacturer ID codes..?
TODO next:
-bootloader dictionary that jumps to bootloader so don't have to manually
close jumper on the board.
-turn on the watchdog timer for stm32
-create some sort of host timeout so reset button on programmer isn't as
useful
-allow firmware programing algos to be uploaded and executed from SRAM for
faster code that also doesn't require specific firmware builds to support
new mapers.
-Finish JTAG to simplify programing NES & SNES CPLDs
-Sort out swim issue with stm8s001 CICs
-add SWIM support for avr
Dumped/flashed MMX on SNES v3 boards.
created discrete_exp0_mapper_wr to try and write to mapper but not flash
for discrete boards but doesn't seem to work for some reason so commented
out for now.
Also the current build assumes that the mcu is able to over drive the
PRG-ROM output to select bank zero for initial bank table writting.
Seems to work, but may need to come up with write that applies to mapper
only and doesn't enable the PRG-ROM by keeping EXP0 low.
Need to work on having the scripts find the bank table.
Also added swim reading of stack bottom for CICOp signature.
Starting to add scripts for different mappers.
Need to clean things up quite a bit as everything was a bit of a hack just
so I could start building lizards and A53.
Need to add back NROM, and add UNROM as well.
Need to have program find bank table for itself both in the program and in
a cartridge.
Having problems with SWIM on new discrete NES boards for some reason.
Some boards are flakey and I march right in and start writting to config
bytes which will brick the device if communications are failing (and
there's no reset pin...) as is with the stm8s001
Realizing much of my problems with discrete boards on original kazzos was
that I completely ignored the fact that most discretes are subject to bus
conflicts. This makes writes to the mapper bank selecting uber flakey...
Created routine in bnrom.lua script to start flash operation by writing
the bank table to where Lizard puts it. Need to write routine to find the
bank table in a provided rom for flashing. And dumping needs to find the
bank table prior to making mapper writes and then use it for bank
switching!
Tested and working on AVR, stm adapter, and inl6
Lizard 512KB flash/dump:
AVR decrepit old firmware & app: 7.9KBps flash
AVR new firmware and app (this build) F:12.1KBps D:14.6KBps
STM adapter: F:31KBps D:114KBps
INL6: F:40KBps D:120KBps
Modified flash/dump scripts to be more generic accepting mapper/memory
args and file names. Then they only handle the buffer and file
operations.
Created scripts/nes folder for holding all mapper scripts. Currently only
nrom.lua is working and verified with inlretro6. Found issue where the
very first byte read from PRG-ROM was garbage. Narrowed it down to lower
address byte not settling in time, added NOP and resolved issue.
Still need to test on original kazzo and stm adapter, planning to do that
after this commit.
Next task is to get BNROM working so I can start getting to work on lizard
builds while taking advantage of speed boost!
Most progress was on jtag lua statemachine code. From what I recall I
tested and verified most state change possibilities with logic analyzer.
So they should be fairly good. Possible I didn't test all later ones,
or things are partly unfinished, but my best guess is they're good.
Appears was able to erase MachXO CPLD. Added time delay for run test.
Did some basic testing for gameboy power switching circuit.
Also just got STM8S001 CIC programming working for discrete boards via
A0. Pretty sure I broke EXP0 in the process for SNES boards.. So need
to go back and fix that I think due to new means of changing swim pin.
Various changes to STM8 SWIM code to make more versatile allowing SWIM
pin to be located effectively on any STM32 GPIO pin. Still haven't
touched an AVR implementation, but made place holders so it can compile
for AVR at least. These SWIM changes aren't heavily tested, mostly just
made sure could flash SOIC-8 STM8 CIC via CIC CLK.
Beginings of JTAG code to configure CPLDs. Currently only tested state
change and scan out reading MachXO-256, 4032/64v, & XC9572/36XL CPLDs
Tested and working on inlretro6 v1.0p, stm adapter, & avr kazzos.
Older devices with flipflops will apply 5v signals to JTAG pins but time
is mostly minimized by keeping signals defaulted low unless actively
changing states or scanning data.
Still need to verify scan in working, probably move TDI/TDO long strings
to buffers instead of 32byte PBJE data array. Also need smarter PBJE
host code to keep track of current state and come up with PBJE register
values without hard coding them..
But things are working fairly well so far with SWIM & JTAG
implementations. Had some issues where I thought jtag pin toggling was
getting optimized out, but I must have simply had the logic analyzer
speed set too low and was missing pin changes that can be as quick as
40nsec with space optimized code. Current inl6 code is ~4400Bytes,
without optimization it's nearly 50% larger at ~6550Bytes..!
Optimizations seem fine in testing and with logic analyzer running at
50Mhz which is good because the GPIO registers are set as volatile so
they better not be getting optimized away!
boards for SF2 builds. Not necessarily the most clean, but it was
stable and worked well.
Need to get swim comms working on other board designs.
Need to come up with better swim activation with more exact timing.
Still need to implement swim comms on avr, hopefully that doesn't prove
to be too much of a PITA... Not looking forward to that. Can probably
only handle low speed, and faking pullup may not work as well without
time on it's side @ 16Mhz...
direction for stm32 ARM cortex-M0 building. Also adding more explicit
error message if VID/PID of device found, but unable to open due to
drivers not being installed.
Got quite a bit done since last commit, and never committed all the
changes. Most should be fine but need to review a little more before
I'm ready to commit those. Mostly was in a rush to get SF2 working and
then took a break before cleaning up and committing progress.
Once old SF2/SNES STM8 updates committed, need to move on to supporting
NES mappers. Also in a bit of a rush to verify new STM8S001 can be
programmed via CIC CLK on inl6 devices. Also need to get JTAG up and
running to make progress on SNES v2 board design.
Figured out problem with STM32F070 bootloader, basically broken for
16Mhz crystals because ST doesn't do adequate testing on their
bootloader code to verify datasheet and AN specs of allows xtal
frequencies. 4, 8, 12, & 24Mhz tested and working, also STM32F072
works. Have dumped bootloader and started analysis. STmicro isn't
offering any help to fix issue, bunch of jackasses! Oh well, plan is to
establish my own bootloader means which has benefit of allowing me to
define however I'd like. Planning on LED pin held high triggering
bootloader which would require smallest erase/write protected sector to
be devoted to my bootloader similar to how things were done for AVR.
After detecting bootloader, initialize HSE and jump to ST's bootloader
code so don't have to write my own USB drivers for the bootloader alone.
-Updated STM devices to always run @ 48MHz
Doesn't seem to cause any problems with SNES flashing couple thousand SF2
boards have been flashed with this build without issues
-Added note to usb_operations.c as manf/prod ID can't be read if drivers
aren't installed. Caused issues for Todd as he hadn't installed drivers
for new hardware.
-STM swim operations are working pretty well for SNES v2 and v3 boards
Haven't even touched SWIM on AVR core yet...
SWIM is pretty pin independent but only implemented on EXP0 so far
Reads "ROTF" aren't bullet proof but they're pretty good. Biggest
room for improvement aside from adding a legit pullup would be to have
an interrupt trigger the device header bit falling edge instead of the
current polling method which has decent amount of jitter.
Implementing interrupts would also probably allow for more easily
supporing reads longer than a single byte...
Only reads one byte, but good enough.. to get things done.
Code should actually work for low and high speed, but have only tested
high speed on writes so far.
Having issue where reads can fail at times. Esp with long strings of
'0'.. Perhaps operating at high speed would improve matters..
Although I'm also realizing maybe I'm not waiting for the device to reset
and reload HSI trim factory value, need to check that..
The new assembly file/function does everything needed so can start cutting
out inline assembly from swim_out function.
Swim code needs to run at 48Mhz. Realizing this is pretty vital to having
enough time to handle high speed. And timing of artificial pull-up
requires high trimmability..
Able to enter active mode and Write on the fly.
Simple test to toggle LED on STM8 GPIO works!
Still quite far from ideal setup. Some things needed:
-defines for ACK/NAK/NO_RESP in dictionary to report inteligbly to lua
-move test SWIM code into separate lua script
-define STM8-CIC registers for easier calling from lua
-entering active mode is too board dependent, need to use swim_base
-Need to make better use of device timers for entering active mode
-arm assembly is quite a mess, unaware of calling convention when writting
-stopping more than just r0-4, r5+ need to be restored if used
-thinking I'd like a full out assmebly file that gets compiled separately
-nothing is done to support SWIM with AVR
-hacking lack of powerful enough pullup on SWIM pin
not much that can be done to get around this...
don't want to add resistors to programmer for every pin I 'might' use
don't want to add resistors to each board that's made
-seems to work well enough, but reads will prob prove challenging
-currently only running at slow speed with ton of NOPs
AVR not yet working, performing low level SWIM operations will require
decent amount of core specific code due to differences in pin driver
styles, timers, cycles per instruction, etc. The fact that SWIM pin
changes based on the board ADDR0, DATA0, EXP0, etc multiplies this low
level code... Thinking about executing SWIM low level drivers from SRAM.
Initialization could include loading these routines to SRAM.
For now just focusing on supporting SWIM on STM cores for SNES boards.
set as other things may trigger off of this.
Also forgot firmware size report:
AVR KAZZO:
avr-size build_avr/avr_kazzo.elf
text data bss dec hex filename
6952 6 674 7632 1dd0 build_avr/avr_kazzo.elf
INL6:
arm-none-eabi-size -t build_stm/inlretro_stm.elf
text data bss dec hex filename
8408 0 684 9092 2384 build_stm/inlretro_stm.elf
STM adapter:
arm-none-eabi-size -t build_stm/inlretro_stm.elf
text data bss dec hex filename
9212 0 684 9896 26a8 build_stm/inlretro_stm.elf
Also the more I get into these flashing routines, maybe the original kazzo
wasn't so bad.. It just takes awhile to flash these chips... I'm not
sure it makes much sense to offer/support stm32 adapter. While it is less
work to cut it out, it's brought out bugs in my code just due to having
different platforms with their quirks manifest bugs.
prototype which has STM8 CIC driving flash /OE with inversion of SYS /RST.
STM8 CIC is running at 16Mhz, and doesn't actually function as CIC. Still
need to come up with special way to signal to CIC that it's plugged into a
programmer and not a console.
Things aren't as fast as they could be, but they're good for now and
proved working on all kazzo versions. Expecting decent speedup could be
aquired by optimizing the flash routine, not changing address unless
needed, or only changing low byte of address, etc. Could also let the
host put the flash chip in unlock bypass mode and keep it there until done
with flashing.
Current speeds:
INL6: 42.2 KBps flashing, 92KBps dumping
stm adapter: 25.3 KBps flashing, 96KBps dumping
AVR kazzo: 18.0KBps flashing, 14.3KBps dumping
Was able to get the inl6 up to 59KBps flashing. Which was 35sec total
flash time for 16mbit chip which has typical flash time of 22s plus
overhead. This got slowed down when supporting stm adapter as checks for
buffer status were required from what I recall. Also fixing flash polling
routine AVR found slowed things down.
Was able to get 140KBps dump time on inl6 with 16mbit SNES flash. This
was slowed when supporting stm adapter which brought out issue with stm32
usb driver. Locks up the device if the buffer isn't fully dumped prior to
calling. Need to get driver to support sending NAKs until data is dumped.
Current fix for checking buffer status slows things down for all devices.
AVR brought out issue with SNES v3 design where we can't rely on flash
poll data to toggle between reads as /OE and /CE are stuck low. Have to
toggle /RESET slowly to toggle /OE and ensure we don't move on to next
byte until previous is fully flashed.
STM32 found initial issue where /WR should be set low first to set
direction of data level shifter, then set /ROMSEL low to enable level
shifter output. Not doing this caused bus conflicts between the two
causing flakey writes where not all bits were getting cleared.
lua scripts currently force SNES, need to add smart check that identifies
SNES flash board if vector data is 0xFFFF. Also funky order where it
always erases after flashing as this was more convient for testing.
While this commit is far from ideal, it's stable and I've done my best to
not commit junk that will cause problems later. Just make sure to always
verify dumping algo before assuming something is wrong with writes!
works on both inl6 and original kazzo just fine. Dumping v3 prototype has
a few byte corruptions on inl6, but is fine on original kazzo. The same
bytes often fail, but not consistently. Tinkered with adding delay, but
that didn't help. Also have issue with adapter not dumping properly.
Prob bug with HIGH ADDR on that board need to sort out still. Going to
focus on erasing and dumping next then come back to some of these issues.