Documentation for “Zerocat Chipflasher” as of Wed, 24 Jun 2026 07:28:36 +0200
Repository: git://zerocat.org/zerocat/projects/chipflasher.git
Version: v3.0.0-0-b445ef922
Branch: master

menu.spin.connect.html

Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.78
Compiling...
menu.spin
|-protocol.spin
|-pcb.spin
  |-time.spin
|-spi-io.spin
  |-spi-clock8.spin
|-spi-flashbase.spin
|-time.spin
|-status.spin
  |-time.spin
|-linespec.spin
|-txline.spin
  |-linespec.spin
|-adc.spin
|-FullDuplexSerial.spin
Done.
Program size is 28164 bytes

______________________________________________________________________________
********************************************************* File starts here ***
Zerocat Chipflasher --- Flash free firmware, kick the Management Engine.

Copyright (C) 2020, 2021, 2022, 2024, 2025, 2026  Kai Mertens 

File menu.spin --- provide a basic menu

This file is part of Zerocat Chipflasher.

See end of file for terms of use.

******************************************************************************


# Compiler Switches


# Object Summary

Object "menu" Interface:

PUB  start(vboard, cfg, baudrate, mode) : 

Program:  7037 Longs
Variable: 522 Longs


# Loaded Objects

* protocol connect <-> kick2
* pcb
* spi-io
* spi-flashbase
* time
* program status codes
* linespec
* txline
* ADC object to supervise VSPI (VSPI')
* FullDuplexSerial by Parallax


# Included Files


## ./blocksizes.spin


### Constants

* Common Flash Block Sizes


## ./identifier.spin.cfg


### Data


# Constants

## Pins

* LED Pins
* Pins RS232

## Sizes

* Menu Width
* Size of KEYMSG Records
* Size of PROMPT Records
* Blocksize Suspend Trigger during read
* Blocksize Suspend Trigger during write
* Size of stack for service_rxfile()
* Size of stack for RS232 service routine
* Block Sizes

## Special Characters

* Protocol Control Characters
* CLIM Characters (Might be changed for debugging purposes.)
* Parallax Terminal Exit Characters

## Bit Definitions

* Status Register Bits, most common, but names vary.
* Protection Scheme Bits and Flags

## Modes, Flags, Masks

* FDS Mode
* Line Modes
* SINFO_by_id(), SINFO_by_name() Masks
* Index Mask for doubled buffer size
* Flag Values
* JOBLEVEL bits
* KEYCHAR list

## Enumerations

* ENUM DUTYCYCLE_type
* ENUM ARRAY_type
* ENUM REGISTER_type
* ENUM ERRCODE_type
* ENUM PSCHEME_type
* ENUM IFC_type
* ENUM VTRACK_type
* ENUM MENU_type
* ENUM KEYID_type
* ENUM BUSPOWER_type
* ENUM BUSY_type
* ENUM SPIPWR_type
* ENUM ADDR_type
* ENUM RX_type
* ENUM RXHEXD_type
* ENUM RXSREC_type
* ENUM STYPE_type
* ENUM COMMAND_type
* ENUM X_type
* ENUM TXMODE_type

## Timings

* Suspend Duty Cycle
* Watchdog Count Value for File to Chip operation

    The value results in a timeout of approx. 3 seconds.
    We need to be faster than connect's fatal timeout counter!

* Byte Transmission Timings for File to Chip Action
* Additional SPI Power Up Pulses
* SPI Power Up/Down Timings (milliseconds)

    T_SPI_UP = Power-up time 0 to Vcc_min
    T_SPI_WRITE = Further delay until device is fully accessible (write access)

    Combined ramp up time on GA-G41M-ES2L seems to be 25ms, indeed.
    According to AMIC A25L080 datasheet, T_SPI_WRITE (aka T_PU) is 10ms!

* SPI WIP Timings (1/10 milliseconds)
* Keypress Timings (milliseconds)
* FDS Stop Timing (milliseconds)
* FDS RX Timing (milliseconds)


# Globals

* Longs for service_rxfile() <-> write_chip()
* File and data transfer buffer pointer
* RS232 service
* Global chip ID
* Stack space for service_rxfile() and service_txbuffer() -- they share same space!
* Job voltages
* Byte buffer linebuf[] -- Holds a full line
* Byte buffer linedat[] -- Holds binary data of a line
* Toggle index for linebuf[]
* Cog ID for service_rxfile()
* Cog ID for service_txbuffer()
* Menu configuration
* Global Pscheme


# Functions

__________________________________________
PUB  start(vboard, cfg, baudrate, mode) : 

 Start:

  Retrieve PCB configuration (version, DIP switches, set baudrate).
  Start full duplex serial driver.
   Handshake (30 seconds timeout), send `THIS_IS_KICK2_CONNECT'.
    Start services.
    Initialize SPI.
    Greeter.
    Start Counter B.
    Start the menu (for `connect' or `propeller-load' terminal).
    Stop Counter B.
    Display end-of-program.
    Switch SPI off.
    Stop services.
    Send `GOOD_BYE' to `connect' utility or exit `propeller-load' terminal.
    Drive status LEDs off.
  Stop serial driver.

 Handshake with `connect':

  Send `THIS_IS_KICK2_CONNECT' to `connect' and wait for ACK for specified number of seconds.

 The Menu:

  Initialization of line specs and SPI flash data.
  Set valid keys.
  Display configuration and prompt:

  - Line type, payload, and visibility
  - flash chip set and slot data
  - SPI status
  - PCB configuration
  - Input prompt -- the menu is stopped by user input `q'

 Display VSPI (VSPI') Job Voltages:

  The Chipflasher PCBs of version 2 have an ADC circuit on board.
  This circuit measures the voltage level that is provided to the target SPI flash chip.
  A strong DC power supply is a precondition to have reliable level measurements.
  The Y-USB power cable might not be usable for all kind of targets.

  PCBs of board-v2.0 measure that voltage (VSPI) *before* the switching MOSFET,
  whereas PCBs of board-v2.2 measure that voltage (VSPI') *behind* the switching MOSFET
  -- and are thus more precise.

  Some target mainboards have their SPI flash chips poorly isolated and demand in excess current.
  However, Chipflasher PCBs use current-limiting voltage regulators.
  As a result, the voltage will drop over time.
  Voltages reported for `job start', `job stop' and `job min' should help you to estimate the job quality.

  If levels are too low, choose a cold environment with low ambient temperature.

 Menu Job Keys:

  The menu offers the following job keys, if appropriate for the detected/selected chip:

  d - probe (detect) chip
  a - previous match/reset
  f - next match
  r - read status and configuration registers
  y - display chip protection
  z - display chip quick scan
  g - read security arrays
  i - read SFDP register

  c - chip to file operation

  m - 64K block batch read
  k - 32K block batch read
  s - 4K block batch read
  p - page batch read
  n - read random byte range

  W - write register bits
  Y - protection batch set
  X - protection batch clear
  O - write security arrays
  Z - erase security arrays

  E - chip erase

  M - 64K block batch erase
  K - 32K block batch erase
  S - 4K block batch erase

  I - file to chip operation

  l - list slots
  t - toggle line type
  $ - decrease/reset payload
  % - toggle line visibility
  / - toggle WPn level
  ! - toggle wip check mode
  w - set PCB configuration
  u - update PCB configuration from DIP switches
  q - cancel job / switch SPI off / quit program

  ? - display full menu


 Job Key `O: write security arrays':

  For chips that support the ENSO/EXSO instructions, 'O: write security arrays' is supported via file.
  A Hex-Dump file has previously been retrieved per Job Key 'g', then modified:

   Job started:    write security arrays

   3>: Sure to proceed? [Ynq]: Y
   Reading file2chip.txt, sending data ...
   #header: Zerocat Chipflasher (https://www.zerocat.org/) | MX25L6405D -- Security Array 0, not locked
   00000000: 5A 65 72 6F 63 61 74 20 4F 54 50 20 54 65 73 74
   00000010: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
   00000020: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
   00000030: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
   #lines: 4

   OK: Transmission complete, please verify
   Time: This procedure took 0.192023036 seconds

   ... job done:   write security arrays


 Job Key `g: read security arrays':

  For chips that support the ENSO/EXSO instructions, 'g: read security arrays' is supported.
  The previously flashed example file would create this readout:

   Job started:    read security arrays

   Size of block:   $00000040
   3>: Sure to proceed? [Ynq]: Y
   Receiving Security Array 0 data, writing chip2file-security0.txt ...
   #header: Zerocat Chipflasher (https://www.zerocat.org/) | MX25L6405D -- Security Array 0, not locked
   00000000: 5A 65 72 6F 63 61 74 20 4F 54 50 20 54 65 73 74  #Zerocat OTP Test
   00000010: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  #................
   00000020: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  #................
   00000030: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  #................
   #lines: 4

   OK: Transmission complete, please verify
   Time: This procedure took 0.116883426 seconds

   ... job done:   read security arrays


  Job Key `W: write register bits':

   Chips that support the ENSO/EXSO commands are likely to have a Security Register.
   A write to bit LDSO would permanently lock (secure) the above OTP array.

 Update PCB Configuration:

  If you change DIP switches 2 to 6, hit key 'u' to make changes take effect.

 Probe Chip:

  Probing the SPI flash should be one of your first menu actions.

  Access to the SPI is designed to be as short as possible, as we do not know how much current will be taken away.
  Voltage indicator LEDs are enabled -- watch out for a flicker on alert indicator!
  If critical voltage level is detected, the SPI is switched off straight away.

  Chip replies for SPI commands ES, EMS, ESM, ID, and ID4 are provided.
  Results are partway checked for consistency (manufacurer ID, devise ID).
  Upon failure, select different PCB settings and try again.
  This could be a time demanding process - once PCB settings are adjusted, write them down an share!

  A reproducable probe is a precondition for safe operation on the SPI flash chip.

  See this sample output of a Winbond W25Q32BV:

   Job started:    probe chip

   ID:     $EF4016
   ID4:    $EF401600
   ES:     $15
   EMS:    $EF15
   ESM:    $15EF
   Mfr:    Winbond

   Scanning chip set ZEROCAT ...
   Match:  Slot 9, W25Q32BV
   Slot:   9, W25Q32BV
   UID:    $C662A404474F3534

   ... job done:    probe chip

  The ID output is known as JEDEC ID.
  If it matches one of the chip definitions in RAM, menu keys are enabled according to known chip features.
  If it matches multiple chip definitions (slots), the last one will be enabled if not another valid one is enabled, yet.
  If it does not match, try a different chip set.
  Eventually, create a new one.

  See this sample output of a Macronix MX25L6405D for chip set MACRONIX:

   Job started:    probe chip

   ID:     $C22017
   ID4:    $C22017C2
   ES:     $16
   EMS:    $C216
   ESM:    $16C2
   Mfr:    Macronix

   Scanning chip set MACRONIX ...
   Match:  Slot 3, MX25L6405D
   Match:  Slot 7, MX25L6406E
   Match:  Slot 8, MX25L6445E
   Slot:   8, MX25L6445E

   ... job done:    probe chip

  The 'probe chip' screen output provides keys to find an appropriate chip definition file on disc, if any.
  For the above case, it would be: 'ID4_0xC22017XX_Macronix_MX25L6405D.spin'
  This file is available as 'Slot 3'.
  Use menu keys 'a' or 'f' to adjust the slot from 8 to 3.

  (The fact that the least sigificant byte of ID4 is `$C2' points to the specific behaviour of
   this chip from Macronix: It is cycling around. Other chips would provide $00, or, a valid
   number specifying more bytes to come. These bytes are not yet supported by the flasher.
   However, according to JEDEC standard, modern chips provide an extra SFDP register of
   significant size instead -- a readout of this register *is* supported by the firmware,
   use job key `i: read SFDP register'. The data of the register will be written to
   file `chip2file-sfdp.txt'. If provided as Hex-Dump, it should be easy enough to manually
   compare byte values to datasheet tables in order to verify that you indeed selected the
   correct chip slot.)

 Block Batch Erase:

  Versatile block erase function, which allows erasure of multiple
  blocks in one go. Interruption not possible.

  A block size can be 4K (sectors), 32K and 64K, or the full chip size.

  Each erasure per block displays the chip busy times, which are either a number of microseconds
  or a timeout tag, depending on the global menu configuration with job key `!: toggle WIP check'.

  In case of `0 times busy', the erasure has failed most likely.
  This is of course a good message when acting across multiple blocks, with some of them being protected.

  For blocks that you indeed want to see erased, a reasonable number (and delay) should be listed.
  When acting on 4K granularity, the busy times (zero versus several thousands of microseconds) must exactly
  correspond to the chip protection chart, as received with menu job key `y: display chip protection'.

  On old and probably mistreated hardware, flash chips might got damaged and disabled to report busy status bits, reliably.
  Using the timeout rather than the ready status polling feature might help to get the chip erased in such a case.

  The erase method checks failure flags like EPE, E_FAIL or E_ERR, if available.

  In any case, it might be of good practice to use menu job key `z: display quick scan' afterwards in order to get
   some kind of job confirmation.

 Set Line Payload:

  The payload of an S-Record data line that is to be sent to `connect' is set to its maximum by default.
  This results in highest data throughput when operation with USB-to-Serial adapters.
  These are transmitting bytes in bulk mode, buffering an amount of 256 bytes or more.

  The payload can be decreased in steps of 16 bytes, down to a minimum of 16 bytes.
  With USB-to-Serial adapters, this results in a significantly lower transmission speed.
  If decreased further, it will wrap around to maximum again.

  A line of Hex-Dump uses a fixed payload of 16 bytes, though.

  Equally, the payload is fixed to 16 bytes for other array transmissions,
  e.g. Security Arrays, SFDP Array -- no matter which line type.

 Program Status LEDs:

  LEDs D1, D2 and D3 provide feedback of the menu input level and of job status.
  If SPI-power-off is user-controlled, D2 serves as voltage alert indicator.

  D1 on                       Menu enabled
  D1 and D3 on                Data input in progress
  D1 and D2 on                Sure-to-proceed-level of input
  D3 on                       Job active
  LEDs off for 0.1s           Job done

  For some jobs D1 and D2 are enabled as voltage good and voltage alert indicators.
  If these indicators are both off, the voltage is in range of 3.2V ... 2.7V.

  For some jobs D3 serves as RS232-transmission-in-progress indicator.

 Yes/No/Cancel:

  Accepts simple input only.
  The prompt shows valid keys in squared brackets: [Ynq]
  Y = yes, n = no, q = quit/cancel, or timeout after some seconds.

 Menu Job Key Configuration:

  Keys are configured according to SPI flash chip features.
  However, a basic set of keys is enabled, always.

 Check Register 1 for protected blocks of memory:

  If the first register of the SPI flash chip has some block protection bits enabled, write actions might fail.
  A generic message is provided in that case.
  A detailed check for the exact protected regions -- and for the usefulness of the respective write job -- is not implemented.

 The prompt:

  It displays the menu input level with numbers:
    1>: (enter job key), 2>: (enter more data) and 3>: (sure to proceed)

  The set of enabled keys is listed in squared brackets, e.g.:
    1>: [adfqtuw/%!?]:

 Receive a file from `connect':

  The reception of a file is done line by line in a service routine.

  The minimal average process time of a byte is collected across lines.
  The delay per byte for the next line is decreased until no more improvement in speed can be measured.

 Receive an S-Record line from host:

  The payload of a line is parsed as binary payload, if compiler switch `USE__SRECORD__BINARY__PAYLOAD' is enabled.
  The average number of cycles per byte is gathered to help adjust delay values for a next line.

 Receive a Hex-Dump line from host:

  The payload of a line is parsed as a pair of hexadecimal characters, separated with space.
  The average number of cycles of a character is gathered to help adjust delay values for a next line.
  The Hex-Dump format is that of `srec_cat -hexd' output -- which differs from default output of the `hexdump' utility.
  According to `man srec_input', this format is not 100% usable as an input file to `srec_cat' -- use with care!

 Write to chip:

  Three SPI write commands are supported:
  Page Program, Word Program with Auto Address Increment (AAI), Byte Program
  For Page Program, a page size of 256 bytes is the default.
  However, a page size of 64 bytes is used for chips with 16 bit address width.

  Chips with static and with volatile block protection bits can both be used.
  These with volatile register bits are harder to manage, especially when voltage levels decay over time.

  During the chip write process, VSPI (VSPI') voltage levels are monitored.
  If the voltage drops below alert level (2.7V), the write is suspended for a few seconds.
  However, a minimal block of bytes as defined with `BLOCKSIZE_SUSPEND_TRIGGER_WRITE' is written before suspending.

  AAI programming of a chip with volatile register bits and these difficult voltage conditions
   can be tested on ThinkPad X60 motherboards with SST25VF016B flash chip and Byte Program disabled.
  Here, the write-suspend-cycle results into a 33% duty cycle, and a minimal job voltage of not less than 2.64V.

  The write process depends on a service routine which is running in parallel.
  It receives data from `connect', line by line.
  This service could freeze if line transmission is done too fast.
  A watchdog timer in the write method would stop writing by switching the SPI off after some seconds.
  See `SEC_WATCHDOG' for the exact number.

 Load SPI flash page with data:

  Many flash chips provide pages of 256 bytes in size to speed up write cycles.
  These pages are loaded as fast as possible, sending 32 bits out to SPI at once, if applicable.

  The code for this load loop *was buggy for years* :-/
  It is now fixed to run as intended, fast and correct.

 Repetitive SPI Power-up:

  This helps to establish proper power on some boards,
   e.g.: ThinkPad T60 or X60 with chip from Microchip

  The repetitive (or pulsed) power-up can be enabled per hardware or virtual DIP switch.

 SPI Power-up:

  Initialize Propeller pins attached to SPI lines:

  - enable P-channel MOSFET and power chip on (#CE goes low)
  - PIN_MISO is always tristate, for it is used as input
  - set clock level according to SPI mode (OUTA is prepared)
  - enable selected clock pins (DIRA is configured)

  Entry condition:

  - all SPI pins are tristate (DIRA bits cleared)
  - output latches cleared (OUTA bits cleared)
  - P-Channel MOSFET disabled (OUTA bit set)

  The SPI Power-up Sequence uses two timings, basically:

   a) Allow power to rise from zero to V_alert (or V_critical if configured)
   b) Allow power to rise even more from V_alert (V_critical) to V_full_access

   For case a), the measurements of VSPI (VSPI') are used.
   If the voltage does not reach V_alert (V_critical) within T_SPI_UP (15ms),
    the method returns with voltage error code.
   If no ADC available on board, the timing is fixed to T_SPI_UP (15ms), and
    no failure can be reported.

   For case b), the timing is T_SPI_WRITE (10ms).

   SPI chip datasheets provide ramp-up figures -- please consult for better understanding.
   In datasheets, T_SPI_WRITE ranges from few microseconds to 10ms, the highest value seen.

 Chip Chart:

  A chip chart is drawn with 4K block resolution and is based on either:

  a) quick sector samples of main array (IFC_QUICKSCAN)
  b) individual block register values (IFC_PSCHEME_INDIVIDUAL)
  c) protection bits of status registers (IFC_PSCHEME_GLOBAL)

  If available per chip, bits WPSEL and WPS will be checked to confirm IFC_PSCHEME_INDIVIDUAL action.

  The chart is a graphical representation of data, giving kind of an 'image'.
  This is considered helpful to quickly recognize data, visually.

 Quick Scan Sector Samples:

  A sector (4K) is divided into 16 pages of 256 bytes,
  each page is sampled at its start, its end, and in center.
  At start and end, sample size is 2 bytes,
  in center, sample size is 4 bytes.
  However, the sample size at start of a first sector page is 4 bytes,
  same as the sample size at end of a last sector page.
  This results in 33 x 4 = 132 byte samples across each sector at well defined
  locations.

  Samples help to estimate whether a sector is untouched (all bytes $FF),
  is programmed (some bytes < $FF), or is nullificated (all bytes $00).

  If you need rely on estimations, always check data in detail per
   job key `s: 4K block batch read'.


# Data: Key Lookup Tables


# Data: Strings

* Spaces
* Strings
* Units
* Menu Key Descriptions


******************************************************************************
Terms of Use:

Zerocat Chipflasher is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Zerocat Chipflasher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License along
with Zerocat Chipflasher.  If not, see <http://www.gnu.org/licenses/>.

************************************************************** End of File ***