Documentation for “Zerocat Chipflasher: Kick2”
Generated on: Wed, 27 Jul 2022 12:09:31 +0200
Repository: git://zerocat.org/zerocat/projects/chipflasher
Version: v0.6.9-632-7d693973
Branch: flashrom-interface

Zerocat Chipflasher: Kick2
– The second firmware, and its interface to flashrom.

../images/IMG_0947.JPG

Ready to fly: Chipflasher has an Interface to Flashrom!

Copyright (C) 2020, 2021, 2022 Kai Mertens kmx@posteo.net

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

Section #../../firmware2/doc/NEWS.md

NEWS

2022/07/27

2022/07/21

2022/07/14

2022/07/11

2022/06/29

2022/06/11

2022/05/18

2022/05/10

2022/04/19

2022/15/01

2021/12/26

2021/11/27

2021/10/01

2021/06/28

Interface configuration has been put under user’s control, via make -C ../../firmware2/src/ <config-target>. Per default, the kick2 firmware has no interface enabled, just the bare program skeleton will be compiled and documented.

2021/06/27

Firmware kick2 now comes with improved read operations for the connect utility, however still using fake data. File ../../firmware2/doc/TODO.md lists related things that should be addressed next.

2021/04/29

2021/04/04

2021/03/31

2020/11/14

2020/10/09

2020/10/07

January 2020 (as of)

Branch ‘flashrom-interface’ is dedicated to enrich the chipflasher with an interface for the widely used flashrom utility.

Flashrom carries its own protocol specification for devices attached to the serial port of your computer. See Documentation/serprog-protocol.txt within the flashrom source tree for detailed information.

Coding the interface goes along with the chipflasher’s firmware review. This work is done on branch firmware2-wip, and – as a side effect – will offer results on branches flashrom-interface and firmware1-wip as well.

The final results will merge into branch master.

Section #../../firmware2/doc/README.md

README

Project Goal

The Chipflasher’s second firmware kick2 is going to be enriched by an interface for the external flashrom utility: Zerocat Chipflasher Flashrom Interface

While maintaining the menu interface for the project’s own connect utility on branch firmware2-wip, the integration of an interface for flashrom will be set up on branch flashrom-interface.

Code Review

The firmware review process is done by transforming the original firmware written in C, into Spin code. Spin code is loaded into controller’s RAM, and then interpreted by one cog who is running the on-chip Spin Interpreter. As a result, the controller’s RAM is used in an efficient way, but execution speed is slow. In order to speed up important loops, parts of the Spin code will be replaced by PASM code later on, which is then executed by additional cogs fromout their faster cog-RAM. As a proof of concept, this has been done for Spin objects txline_HEXD and txline_SREC. In the end, the overall execution speed will hopefully reach that of the fast PASM code compiled from C sources.

Coding in Spin/PASM gives us some main benefits:

Hardware Requirements

Requirements are frugal:

Paths

All paths within this document are relative in respect to the original location of this source file, which is located in the project’s firmware2/doc/ folder, e.g.: ../../firmware2/doc/

Prerequisites

This is additional software and documentation.

It is assumed, that you have started with the project’s main README file ../../doc/README.md to learn how to set up requirements and how to generate the project’s root documentation ../../doc/index.html. Your current directory is ../../doc/.

Now change into this project’s second documentation folder ../../firmware2/doc/:

    cd ../firmware2/doc/

P8X32A Documents and Application Notes

The Propeller Chip is well documented, let’s take a bunch of documents as a common starting point. See ../../firmware2/doc/Makefile for targets P1-Documents and P1-Application-Notes. They will help us to get files downloaded, e.g.:

    make -C ../../firmware2/doc P1-Documents

Interfaces

Interfacing the Connect Utility

This project comes with its own PC utility called connect, which is supported via the menu Spin/PASM object:

../../firmware2/images/screenshot-20211224-140916.png

Interface to `connect`, coded in Spin/PASM

Interfacing the Flashrom Utility

The flashrom utility comes with its own protocol specification, made for external flasher devices attached to the serial port of your computer. See Documentation/serprog-protocol.txt within the flashrom source tree. This protocol is/will be supported via the serprog Spin/PASM object. Once the serprog object is more elaborated, we will switch the default interface.

Interfacing a Terminal

In case flashrom or connect are not available, you might still start a propeller terminal and use it with a terminal on the host side. However, features are heavily stripped, you cannot do something real. Again, use the menu Spin/PASM object.

Interface Configuration

The kick2 top object might be configured to run one of the following interfaces:

  1. Connect

        make -C ../../firmware2/src config-connect
    
  2. Flashrom (Default)

        make -C ../../firmware2/src config-flashrom
    

    You can try RS232 baudrates, different to the default value of 57600baud:

        make -C ../../firmware2/src config-serprog-baud115200
    

    or

        make -C ../../firmware2/src config-serprog-baud38400
    

    Please note that, up to now, 115200baud is too fast for write operations.

    The interface to flashrom will talk to SPI devices in “SPI Mode 0” as default. However, you might switch between SPI modes explicitly like so:

        make -C ../../firmware2/src config-SPIMODE0
    

    or

        make -C ../../firmware2/src config-SPIMODE3
    
  3. Propeller Terminal

        make -C ../../firmware2/src config-propterm
    
  4. No Interface

        make -C ../../firmware2/src config-none
    

The configuration will not only affect the compiled output, but the generated documentation as well.

You can get an overview of targets with:

    make -C ../../firmware2/src help

Code

To build the firmware, type:

    make -C ../../firmware2/src

You can get an overview of targets with:

    make -C ../../firmware2/src help

Code Upload

To load the firmware onto the controller board, see options of ../../firmware2/start/Makefile:

    make -C ../../firmware2/start help

It might be a good idea to upload into Free-design RAM:

    make -C ../../firmware2/start loadram

Operate the Device

To operate the device, see options of ../../firmware2/start/Makefile:

    make -C ../../firmware2/start help

The Makefile promotes usage of the interface to the connect utility and offers a bunch of targets, e.g.:

    make -C ../../firmware2/start start

Testing the interface to flashrom can be done with target flashrom-probe, which has been added as a proof of concept: Synchronization, initialization and probing do work fine:

    make -C ../../firmware2/start flashrom-probe

Finally, the interface to the Propeller Terminal can get uploaded and started:

    make -C ../../firmware2/start terminal

Operate the Device with Flashrom

Instead of using the Makefile, feel free to operate the chipflasher with the flashrom utility. Here are some invocation examples as executed in ../../firmware2/start/:

Probe

    flashrom -p serprog:dev=tty_port_pointer:57600

Probe MX25L6405D (as found on ThinkPad X230, Chip #1)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L6405D" -V
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    flashrom was built with libpci 3.7.0, GCC 7.5.0, little endian
    Command line (5 args): flashrom -p serprog:dev=tty_port_pointer:57600 -c MX25L6405D -V
    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    Initializing serprog programmer
    serprog: connected - attempting to synchronize
    .
    serprog: Synchronized
    serprog: Interface version ok.
    serprog: Bus support: parallel=off, LPC=off, FWH=off, SPI=on
    serprog: Maximum write-n length is 256
    serprog: Maximum read-n length is 4096
    serprog: Programmer name is "Zerocat!"
    serprog: Serial buffer size is 16
    serprog: operation buffer size is 300
    serprog: Output drivers enabled
    The following protocols are supported: SPI.
    Probing for Macronix MX25L6405D, 8192 kB: probe_spi_rdid_generic: id1 0xc2, id2 0x2017
    Found Macronix flash chip "MX25L6405D" (8192 kB, SPI) on serprog.
    Chip status register is 0x00.
    Chip status register: Status Register Write Disable (SRWD, SRP, ...) is not set
    Chip status register: Bit 6 is not set
    Chip status register: Block Protect 3 (BP3) is not set
    Chip status register: Block Protect 2 (BP2) is not set
    Chip status register: Block Protect 1 (BP1) is not set
    Chip status register: Block Protect 0 (BP0) is not set
    Chip status register: Write Enable Latch (WEL) is not set
    Chip status register: Write In Progress (WIP/BUSY) is not set
    This chip may contain one-time programmable memory. flashrom cannot read
    and may never be able to write it, hence it may not be able to completely
    clone the contents of this chip (see man page for details).
    No operations were specified.
    serprog: Output drivers disabled

Read MX25L6405D (as found on ThinkPad X230, Chip #1)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L6405D" -r chip1.bin
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    serprog: Programmer name is "Zerocat!"
    Found Macronix flash chip "MX25L6405D" (8192 kB, SPI) on serprog.
    Reading flash... done.

Verify MX25L6405D (as found on ThinkPad X230, Chip #1)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L6405D" -v chip1.bin
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    serprog: Programmer name is "Zerocat!"
    Found Macronix flash chip "MX25L6405D" (8192 kB, SPI) on serprog.
    Verifying flash... VERIFIED.

Erase MX25L6405D (as found on ThinkPad X230, Chip #1)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L6405D" -E
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    serprog: Programmer name is "Zerocat!"
    Found Macronix flash chip "MX25L6405D" (8192 kB, SPI) on serprog.
    Erasing and writing flash chip... Erase/write done.

Write MX25L6405D (as found on ThinkPad X230, Chip #1)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L6405D" -w chip1.bin
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    serprog: Programmer name is "Zerocat!"
    Found Macronix flash chip "MX25L6405D" (8192 kB, SPI) on serprog.
    Reading old flash chip contents... done.
    Erasing and writing flash chip...
    Erase/write done.
    Verifying flash... VERIFIED.

Probe MX25L3205D (as found on ThinkPad X230, Chip #2)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L3205D/MX25L3208D" -V
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    flashrom was built with libpci 3.7.0, GCC 7.5.0, little endian
    Command line (5 args): flashrom -p serprog:dev=tty_port_pointer:57600 -c MX25L3205D/MX25L3208D -V
    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    Initializing serprog programmer
    serprog: connected - attempting to synchronize
    .
    serprog: Synchronized
    serprog: Interface version ok.
    serprog: Bus support: parallel=off, LPC=off, FWH=off, SPI=on
    serprog: Maximum write-n length is 256
    serprog: Maximum read-n length is 4096
    serprog: Programmer name is "Zerocat!"
    serprog: Serial buffer size is 16
    serprog: operation buffer size is 300
    serprog: Output drivers enabled
    The following protocols are supported: SPI.
    Probing for Macronix MX25L3205D/MX25L3208D, 4096 kB: probe_spi_rdid_generic: id1 0xc2, id2 0x2016
    Found Macronix flash chip "MX25L3205D/MX25L3208D" (4096 kB, SPI) on serprog.
    Chip status register is 0x00.
    Chip status register: Status Register Write Disable (SRWD, SRP, ...) is not set
    Chip status register: Bit 6 is not set
    Chip status register: Block Protect 3 (BP3) is not set
    Chip status register: Block Protect 2 (BP2) is not set
    Chip status register: Block Protect 1 (BP1) is not set
    Chip status register: Block Protect 0 (BP0) is not set
    Chip status register: Write Enable Latch (WEL) is not set
    Chip status register: Write In Progress (WIP/BUSY) is not set
    This chip may contain one-time programmable memory. flashrom cannot read
    and may never be able to write it, hence it may not be able to completely
    clone the contents of this chip (see man page for details).
    No operations were specified.
    serprog: Output drivers disabled

Read MX25L3205D (as found on ThinkPad X230, Chip #2)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L3205D/MX25L3208D" -r chip2.bin
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    serprog: Programmer name is "Zerocat!"
    Found Macronix flash chip "MX25L3205D/MX25L3208D" (4096 kB, SPI) on serprog.
    Reading flash... done.

Verify MX25L3205D (as found on ThinkPad X230, Chip #2)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L3205D/MX25L3208D" -v chip2.bin
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    serprog: Programmer name is "Zerocat!"
    Found Macronix flash chip "MX25L3205D/MX25L3208D" (4096 kB, SPI) on serprog.
    Verifying flash... VERIFIED.

Erase MX25L3205D (as found on ThinkPad X230, Chip #2)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L3205D/MX25L3208D" -E
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    serprog: Programmer name is "Zerocat!"
    Found Macronix flash chip "MX25L3205D/MX25L3208D" (4096 kB, SPI) on serprog.
    Erasing and writing flash chip... Erase/write done.

Write MX25L3205D (as found on ThinkPad X230, Chip #2)

    flashrom -p serprog:dev=tty_port_pointer:57600 -c "MX25L3205D/MX25L3208D" -w chip2.bin
    ---------------------------------------------------------------------------------------------
    flashrom v1.2 on Linux 5.17.14-gnu (x86_64)
    flashrom is free software, get the source code at https://flashrom.org

    Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
    serprog: Programmer name is "Zerocat!"
    Found Macronix flash chip "MX25L3205D/MX25L3208D" (4096 kB, SPI) on serprog.
    Reading old flash chip contents... done.
    Erasing and writing flash chip... Erase/write done.
    Verifying flash... VERIFIED.
Section #../../firmware2/doc/TODO.md

TODO

While working on the kick2 Spin/PASM code, these things should be fixed, soon:

Section #../../firmware2/doc/Software-Bill-of-Material.md

Software Bill of Material

Note this branch is developed on a GNU Guix System, which helps to list up exact package names, software versions and brief descriptions via guix show.

In addition to the project’s initial software requirements listed in ../../doc/software-tools.md, this branch will focus on Spin/PASM related tools, that ship with package propeller-development-suite@4.6.1-2.4c46ecbe7:

Furthermore, the flashrom utility is required:

The documentation is supplemented by zipped files, downloaded with the wget utility:

Section #../../firmware2/doc/SPI-clock-speed-with-flashrom.md

SPI Clock Speed with Flashrom

Workbench

SPI clock speed development is done with the RYF-certified Chipflasher “board-edition-1”, driven by a Zerocat T60, targeting a modified ThinkPad X230 with SPI flash connector. Code execution is montitored via oscilloscope:

../../firmware2/images/IMG_1281.JPG

SPI Clock Speed Development Setup

Spin Code (e.g. commit 808341ea)

The serprog-SPI.spin object offers optimized SPI bus routines, coded in slow Spin. Byte transfer speed is 2.2kHz, clock speed is estimated to 25kHz:

../../firmware2/images/IMG<em>1215.JPG

SPI Byte Transfer Speed (read access) of Spin Code (1V/50µs per div)

../../firmware2/images/IMG</em>1208.JPG

SPI Clock Speed (8bit read access) of Spin Code (1V/5µs per div)

PASM Code (e.g. commit f8919500)

Optimized PASM routines provide much higher clock rates. Object serprog-SPI-PASM.spin achieves a clock rate of 5MHz (8bit read/write), 4MHz (24bit read) and 3.33MHz (24bit write). If using RS232 with 57600baud (default), the Spin code processes bytes with 5.2KHz.

../../firmware2/images/IMG_1237.JPG

SPI Clock Speed (8bit read access) of PASM Code (1V/50ns per div)

Code snippet, as executed above:

    :read8
                ...
                ...
                ...
                or OUTA, mask_SCLK
                andn OUTA, mask_SCLK

                'bit 6
                test mask_MISO, INA             wc
                rcl value, #1
                or OUTA, mask_SCLK
                andn OUTA, mask_SCLK

                'bit 5
                test mask_MISO, INA             wc
                rcl value, #1
                or OUTA, mask_SCLK
                andn OUTA, mask_SCLK

                'bit 4
                ...
                ...

../../firmware2/images/IMG<em>1240.JPG

SPI Byte Transfer Speed (read access) of PASM Code (1V/200ns per div)

../../firmware2/images/IMG</em>1243.JPG

Byte Process Speed (read access) at 57600baud with SPI PASM Code (1V/20µs per div)

PASM Code with Counter Modules (e.g. commit d59dad40)

Object serprog-SPI-PASM.spin achieves even higher clock rates by using free wheeling counters in the background. If the code stays in sync with counter pin outputs, it is freed from generating the pulses itself. That technique allows us to clock data bytes with 10MHz. Values like $00 and $ff do not require to toggle bit values and can be clocked with up to 80MHz. However, that frequency turned out to be too high for the device under test, that is why 40MHz is used instead.

The PASM code supports the spispeed option of the serprog protocol. Three values give you control about the SPI clock frequency according to the following table:

    spispeed  |    8bit read  |      8bit write  |     24bit read  |    24bit write  |   clock driver
    ==========|===============|==================|=================|=================|=================
          5M  |         5MHz  |            5MHz  |           4MHz  |        3.33MHz  |     full power
    ----------|---------------|------------------|-----------------|-----------------|-----------------
         10M  |         5MHz  | $00, $ff: 10MHz  |           4MHz  |        3.33MHz  |     full power
              |               | $01..$fe:  5MHz  |                 |                 |
    ----------|---------------|------------------|-----------------|-----------------|-----------------
         40M  |        10MHz  | $00, $ff: 40MHz  |           4MHz  |        3.33MHz  |     half power
              |               | $01..$fe: 10MHz  |                 |                 |

You can pass the spispeed value via command line, e.g.:

    flashrom -p serprog:dev=tty_port_pointer:57600,spispeed=40M

If you don't specify the SPI speed initially, a default value of 10M will be used. However, once specified, the speed value is not reset if not provided on the command line.

High Frequency Clock in Mode 0

../../firmware2/images/IMG<em>1321.JPG

Mode 0: 8bit read with 10MHz clock (2V/200ns per div)

../../firmware2/images/IMG</em>1336.JPG

Mode 0: 8bit write with 10MHz clock (2V/200ns per div)

../../firmware2/images/IMG<em>1349.JPG

Mode 0: Switching to 8bit write ($00, $ff) with 40MHz clock (2V/200ns per div)

../../firmware2/images/IMG</em>1384.JPG

Mode 0: in Detail: 8bit write ($00, $ff) with 40MHz clock (1V/50ns per div)

High Frequency Clock in Mode 3

../../firmware2/images/IMG<em>1389.JPG

Mode 3: 8bit read/write with 10MHz clock (2V/200ns per div)

../../firmware2/images/IMG</em>1421.JPG

Mode 3: in Detail: 8bit read/write with 10MHz clock (1V/100ns per div)

../../firmware2/images/IMG<em>1392.JPG

Mode 3: 8bit write ($00, $ff) with 40MHz clock (2V/200ns per div)

../../firmware2/images/IMG</em>1416.JPG

Mode 3: in Detail: 8bit write ($00, $ff) with 40MHz clock (1V/50ns per div)