Project home: https://bues.ch/h/toprammer Original repository at: https://git.bues.ch/git/toprammer.git https://bues.ch/h/toprammer

Michael Buesch 4f40cd5e8c Bump version 4 months ago
libtoprammer 4f40cd5e8c Bump version 4 months ago
reverse-engineering ec9d2f184a Remove obsolete qemu patches 1 year ago
tests 837a992744 Add tests/top2049/m24c01.test 4 months ago
.gitignore dfa3c5fe71 Add setup.py 7 years ago
01-toprammer-udev.rules 1231d30f9c Add udev rules example file 1 year ago
COPYING d0d03673d2 Initial commit 7 years ago
MANIFEST.in 9250373500 Add missing package info 1 year ago
README-DEVELOPERS.lyx 5982f338f6 Move .bit files to libtoprammer/fpga/bin/ 5 years ago
README-DEVELOPERS.ps 5982f338f6 Move .bit files to libtoprammer/fpga/bin/ 5 years ago
README.lyx 536bc6a738 Update documentation 1 year ago
README.ps 536bc6a738 Update documentation 1 year ago
RUNTIME_IDS 3479b3013e Add support for pic24f 3 years ago
makerelease.sh 8ca82d58bd Add support for building python packages 1 year ago
setup.py 9250373500 Add missing package info 1 year ago
toprammer 30389ab2bb Port to latest PyUSB 1 year ago
toprammer-gui 41e1c1fa5b gui: Show chip maintainer 3 years ago
toprammer-layout 1fb4a7959d Fix toprammer-layout chipid based generator 5 years ago

README-DEVELOPERS.lyx

#LyX 2.0 created this file. For more info see http://www.lyx.org/
\lyxformat 413
\begin_document
\begin_header
\textclass article
\use_default_options false
\maintain_unincluded_children false
\language english
\language_package default
\inputencoding auto
\fontencoding global
\font_roman default
\font_sans default
\font_typewriter default
\font_default_family default
\use_non_tex_fonts false
\font_sc false
\font_osf false
\font_sf_scale 100
\font_tt_scale 100

\graphics default
\default_output_format default
\output_sync 0
\bibtex_command default
\index_command default
\paperfontsize default
\use_hyperref false
\papersize default
\use_geometry false
\use_amsmath 1
\use_esint 1
\use_mhchem 1
\use_mathdots 1
\cite_engine basic
\use_bibtopic false
\use_indices false
\paperorientation portrait
\suppress_date false
\use_refstyle 0
\index Index
\shortcut idx
\color #008000
\end_index
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\paragraph_indentation default
\quotes_language english
\papercolumns 1
\papersides 1
\paperpagestyle default
\tracking_changes false
\output_changes false
\html_math_output 0
\html_css_as_file 0
\html_be_strict false
\end_header

\begin_body

\begin_layout Title
Toprammer - Developers guide
\end_layout

\begin_layout Section
Definitions
\end_layout

\begin_layout Description
DUT Device Under Test.
The device put into the ZIF socket of the programmer
\end_layout

\begin_layout Description
VPP Programming voltage for the DUT (usually 12V)
\end_layout

\begin_layout Description
VCC Supply voltage for the DUT
\end_layout

\begin_layout Description
GND Ground for the DUT
\end_layout

\begin_layout Description
ZIF Zero Insert Force socket of the programmer.
\end_layout

\begin_layout Section
TOP2049 device hardware
\end_layout

\begin_layout Standard
The TOP2049 consists of four basic hardware parts
\end_layout

\begin_layout Itemize
USB interface (PDIUSBD12 chip)
\end_layout

\begin_layout Itemize
Microcontroller (Megawin MPC89E52A)
\end_layout

\begin_layout Itemize
FPGA (Xilinx Spartan2 XC2S15)
\end_layout

\begin_layout Itemize
VCC/GND/VPP supply circuitry
\end_layout

\begin_layout Standard
The microcontroller's job is to initialize and communicate to the FPGA and
set up the VCC/GND/VPP supply circuitry.
The microcontroller can receive commands via USB interface to do these
things.
\end_layout

\begin_layout Section
Communicating with the programmer via USB
\end_layout

\begin_layout Standard
In the
\begin_inset Quotes eld
\end_inset

main
\begin_inset Quotes erd
\end_inset

module there is the
\begin_inset Quotes eld
\end_inset

class TOP
\begin_inset Quotes erd
\end_inset

which is used for communication with the programmer device.
The class has various methods for hardware access:
\end_layout

\begin_layout Subsection
cmdRequestVersion()
\end_layout

\begin_layout Standard
Reads the programmer identification and versioning string and returns it.
\end_layout

\begin_layout Subsection
getOscillatorHz()
\end_layout

\begin_layout Standard
Returns the frequency (in Hz) of the oscillator connected to the FPGA clk
pin.
\end_layout

\begin_layout Subsection
getBufferRegSize()
\end_layout

\begin_layout Standard
Returns the size of the
\begin_inset Quotes eld
\end_inset

buffer register
\begin_inset Quotes erd
\end_inset

.
\end_layout

\begin_layout Subsection
cmdReadBufferReg(nrBytes=all)
\end_layout

\begin_layout Standard
Reads the
\begin_inset Quotes eld
\end_inset

buffer register
\begin_inset Quotes erd
\end_inset

from the microcontroller.
That register is used for buffering of data fetched from the FPGA.
If nrBytes is not specified, it reads the whole register.
\end_layout

\begin_layout Subsection
cmdReadBufferReg8()
\end_layout

\begin_layout Standard
Same as cmdReadBufferReg(), but just returns a 8bit int which was formed
by the first 1 byte of the register.
\end_layout

\begin_layout Subsection
cmdReadBufferReg16()
\end_layout

\begin_layout Standard
Same as cmdReadBufferReg(), but just returns a 16bit int which was formed
by the first 2 bytes of the register (little endian).
\end_layout

\begin_layout Subsection
cmdReadBufferReg32()
\end_layout

\begin_layout Standard
Same as cmdReadBufferReg(), but just returns a 32bit int which was formed
by the first 4 bytes of the register (little endian).
\end_layout

\begin_layout Subsection
cmdReadBufferReg48()
\end_layout

\begin_layout Standard
Same as cmdReadBufferReg(), but just returns a 48bit int which was formed
by the first 6 bytes of the register (little endian).
\end_layout

\begin_layout Subsection
cmdSetVPPVoltage(voltage)
\end_layout

\begin_layout Standard
Set VPP (programming voltage) to the specified voltage.
Voltage is a floating point number.
\end_layout

\begin_layout Subsection
cmdSetVCCVoltage(voltage)
\end_layout

\begin_layout Standard
Set VCC (DUT supply voltage) to the specified voltage.
Voltage is a floating point number.
\end_layout

\begin_layout Subsection
cmdLoadGNDLayout(layoutID)
\end_layout

\begin_layout Standard
Load a ZIF-socket GND-layout.
You usually don't want to call this directly.
Use an autogenerated layout instead.
\end_layout

\begin_layout Subsection
cmdLoadVPPLayout(layoutID)
\end_layout

\begin_layout Standard
Load a ZIF-socket VPP-layout.
You usually don't want to call this directly.
Use an autogenerated layout instead.
\end_layout

\begin_layout Subsection
cmdLoadVCCLayout(layoutID)
\end_layout

\begin_layout Standard
Load a ZIF-socket VCC-layout.
You usually don't want to call this directly.
Use an autogenerated layout instead.
\end_layout

\begin_layout Subsection
cmdEnableZifPullups(enable)
\end_layout

\begin_layout Standard
Enable (True) or disable (False) the pullups for all signals on the ZIF
socket.
Default is disabled.
\end_layout

\begin_layout Subsection
cmdFPGAWrite(address, byte)
\end_layout

\begin_layout Standard
Writes a byte to the FPGA using
\begin_inset Quotes eld
\end_inset

address
\begin_inset Quotes erd
\end_inset

for address latching and
\begin_inset Quotes eld
\end_inset

byte
\begin_inset Quotes erd
\end_inset

as payload data.
Note that address 0x10 is fast-tracked and uses one byte less on the USB
bus.
So it is potentially faster.
\end_layout

\begin_layout Subsection
cmdFPGARead(address)
\end_layout

\begin_layout Standard
Reads a byte from the FPGA and puts it into the buffer register.

\begin_inset Quotes eld
\end_inset

address
\begin_inset Quotes erd
\end_inset

is used for address latching on the FPGA.
The microcontroller's buffer register has an automagically incrementing
pointer.
So issueing several cmdFPGARead() in a row will result in all the bytes
being put one after another into the buffer register.
The buffer register does have a limited size.
Overflowing it crashes the programmer, requireing a physical USB disconnect
to recover.
Call getBufferRegSize() to get the size of the buffer register.
Reading the buffer register (cmdReadBufferReg()) will reset the automagic
pointer to zero.
Note that address 0x10 is fast-tracked and uses one byte less on the USB
bus.
So it is potentially faster.
\end_layout

\begin_layout Subsection
cmdDelay(seconds)
\end_layout

\begin_layout Standard
Send a delay command to the programmer.
The Programmer will perform the delay.
A value up to 0.5 seconds is possible.
Note that the actual value will be rounded up to the next possible wait
interval value.
Use this for short (microsecond or low millisecond) delays.
Note that this does _not_ flush the command queue.
\end_layout

\begin_layout Subsection
hostDelay(seconds)
\end_layout

\begin_layout Standard
Sends all queued commands to the device and waits for
\begin_inset Quotes eld
\end_inset

seconds
\begin_inset Quotes erd
\end_inset

.

\begin_inset Quotes eld
\end_inset

seconds
\begin_inset Quotes erd
\end_inset

is a floating point number.
The delay is performed on the host computer by simply not sending commands
to the programmer for the time specified after flushing the command queue.
\end_layout

\begin_layout Section
TX command queueing
\end_layout

\begin_layout Standard
All commands transmitted to the device are not sent immediately, but queued
in software and sent later.
This is done to speed up device access significantly.
The command transmission queue has several flushing conditions:
\end_layout

\begin_layout Itemize
Commands can be flushed explicitely using the
\begin_inset Quotes eld
\end_inset

flushCommands()
\begin_inset Quotes erd
\end_inset

method of
\begin_inset Quotes eld
\end_inset

class TOP
\begin_inset Quotes erd
\end_inset

.

\end_layout

\begin_layout Itemize
Commands are automatically flushed on cmdReadBufferReg() before reading
the data from the device.
This is to ensure sequential consistency of the commands.
\end_layout

\begin_layout Itemize
Commands are flushed on various voltage-layout operations.
\end_layout

\begin_layout Standard
You usually do not need to flush commands explicitely.
\end_layout

\begin_layout Section
Implementing a new chip (DUT) algorithm
\end_layout

\begin_layout Standard
The reading and programming algorithms for the chips (DUTs) are separated
into two parts:
\end_layout

\begin_layout Itemize
Low level FPGA bottom-half
\end_layout

\begin_layout Itemize
High level Python code top-half
\end_layout

\begin_layout Standard
The FPGA bottom-half implements the basic operations (fetching data from
DUT.
Writing data to DUT.
etc...).
It may also implement timingcritical parts of the algorithm.
Everything else is implemented in the high level Python code, that lives
on the other end of the USB line.
\end_layout

\begin_layout Subsection
Python top-half implementation
\end_layout

\begin_layout Standard
The DUT specific top-half lives in the
\begin_inset Quotes eld
\end_inset

libtoprammer/chips
\begin_inset Quotes erd
\end_inset

module.
The files in that module contain the top-half algorithm implementation.
The files are named after the chip ID.
Make sure to update the __init__.py of the module when adding algorithm
implementations.
The top-half files contain a class derived from the
\begin_inset Quotes eld
\end_inset

Chip
\begin_inset Quotes erd
\end_inset

class.
The
\begin_inset Quotes eld
\end_inset

Chip
\begin_inset Quotes erd
\end_inset

class defines the interface that is to be re-implemented in the derived
subclass.
This interface consists of the following methods:
\end_layout

\begin_layout Description
shutdownChip() Called once on chip shutdown.
The default implementation turns off all voltages.
There's usually no need to override that.
\end_layout

\begin_layout Description
readSignature() Read the DUT signature and return it.
Reimplement this, if your DUT supports signature reading.
\end_layout

\begin_layout Description
erase() Erase the DUT.
Reimplement this, if your DUT supports electrical erasing.
\end_layout

\begin_layout Description
test() Run an optional unit-test on the chip.
The generic algorithm GenericAlgorithms.simpleTest may be used to implement
this method.
\end_layout

\begin_layout Description
readProgmem() Read the program memory and return it.
Reimplement this, if your DUT has program memory and supports reading it.
\end_layout

\begin_layout Description
writeProgmem(image) Write the program memory.
Reimplement this, if your DUT has program memory and supports writing it.
\end_layout

\begin_layout Description
readEEPROM() Read the (E)EPROM memory and return it.
Reimplement this, if your DUT has (E)EPROM memory and supports reading
it.
\end_layout

\begin_layout Description
writeEEPROM() Write the (E)EPROM memory.
Reimplement this, if your DUT has (E)EPROM memory and supports writing
it.
\end_layout

\begin_layout Description
readFuse() Read the Fuse memory and return it.
Reimplement this, if your DUT has Fuses and supports reading them.
\end_layout

\begin_layout Description
writeFuse() Write the Fuse memory.
Reimplement this, if your DUT has Fuses and supports writing them.
\end_layout

\begin_layout Description
readLockbits() Read the Lockbit memory and return it.
Reimplement this, if your DUT has Lockbits and supports reading them.
\end_layout

\begin_layout Description
writeLockbits() Write the Lockbit memory.
Reimplement this, if your DUT has Lockbits and supports writing them.
\end_layout

\begin_layout Description
readRAM() Read the Random Access Memory.
Reimplement this, if your DUT has RAM and supports reading it.
\end_layout

\begin_layout Description
writeRAM() Write the Random Access Memory.
Reimplement this, if your DUT has RAM and supports writing to it.
\end_layout

\begin_layout Standard
After defining your
\begin_inset Quotes eld
\end_inset

Chip
\begin_inset Quotes erd
\end_inset

-derived class you need to register it.
This is done by defining a ChipDescription():
\end_layout

\begin_layout LyX-Code
ChipDescription(Chip_MyDevice, bitfile =
\begin_inset Quotes eld
\end_inset

bitfileID
\begin_inset Quotes erd
\end_inset

, chipID =
\begin_inset Quotes eld
\end_inset

myChipID
\begin_inset Quotes erd
\end_inset

)
\end_layout

\begin_layout Standard
The chip class (_not_ an instance of it) is passed as first parameter.
The ID string of the required bitfile is past as second parameter.
A chipID might also be passed.
If the chipID is omitted, the bitfileID is used as chipID.
There are more optional parameters to ChipDescription().
See the inline sourcecode documentation for details.
\end_layout

\begin_layout Subsection
Generic top-half algorithms
\end_layout

\begin_layout Standard
The Python class
\begin_inset Quotes eld
\end_inset

GenericAlgorithms
\begin_inset Quotes erd
\end_inset

in the generic_algorithms.py file provides several generic chip access algorithm
s that can be used in the
\begin_inset Quotes eld
\end_inset

Chip
\begin_inset Quotes erd
\end_inset

methods.
\end_layout

\begin_layout Subsection
FPGA bottom-half implementation
\end_layout

\begin_layout Standard
For the FPGA part you need to get the Xilinx development suite (ISE) version
10.1 service pack 3.
The "WebPACK", which is sufficient for our purposes, can be downloaded
for free (as in beer) from the Xilinx homepage:
\end_layout

\begin_layout LyX-Code
http://www.xilinx.com/support/download/index.htm
\end_layout

\begin_layout Standard
To create a new sourcecode template fileset for a new chip, go to the libtopramm
er/fpga/src/ subdirectory and execute the "create.sh" script:
\end_layout

\begin_layout LyX-Code
./create.sh bitfile_name
\end_layout

\begin_layout Standard
Where "bitfile_name" is the name of the new chip's bitfile.
(That often matches the chip-ID).
Now go to libtoprammer/fpga/src/bitfile_name/ and implement the bottom-half
algorithm in the bitfile_name.v Verilog file.
To build the .BIT file from the Verilog sources, go to the libtoprammer/fpga/
directory and execute:
\end_layout

\begin_layout LyX-Code
./build.sh bitfile_name
\end_layout

\begin_layout Standard
If you omit the
\begin_inset Quotes eld
\end_inset

bitfile_name
\begin_inset Quotes erd
\end_inset

, all bitfiles will be rebuilt.
The resulting .BIT file will be copied to the libtoprammer/fpga/bin/ directory,
after build finished successfully.
\end_layout

\begin_layout Section
Automatic layout generator
\end_layout

\begin_layout Standard
The automatic layout generator (layout_generator.py) can be used to automatically
generate a VCC/VPP/GND layout.
The generator will then tell you how to insert the chip into the ZIF socket.
The advantage of using the autogenerator instead of hardcoding the VCC/VPP/GND
connections in the chip implementation is that the autogenerated layout
is portable between TOPxxxx programmers and it is much easier to implement.
You do not have to search for a chip position in the ZIF socket that fits
the device constraints.
The autogenerator will do it for you.
\end_layout

\begin_layout Standard
The chip interface of the autogenerator is embedded into
\begin_inset Quotes eld
\end_inset

class Chip
\begin_inset Quotes erd
\end_inset

.
So you don't have to work with
\begin_inset Quotes eld
\end_inset

class LayoutGenerator
\begin_inset Quotes erd
\end_inset

directly.
You'll do it through
\begin_inset Quotes eld
\end_inset

class Chip
\begin_inset Quotes erd
\end_inset

instead.
So let's look at
\begin_inset Quotes eld
\end_inset

class Chip
\begin_inset Quotes erd
\end_inset

s autogenerator interface.
\end_layout

\begin_layout Standard
The constructor (__init__()) has some autogenerator related parameters:
\end_layout

\begin_layout Description
chipPackage This parameter is a string identifying the package type of the
DUT chip.
It is something like
\begin_inset Quotes eld
\end_inset

DIP28
\begin_inset Quotes erd
\end_inset

or
\begin_inset Quotes eld
\end_inset

DIP40
\begin_inset Quotes erd
\end_inset

, etc...
.
If this parameter is passed to the constructor, the autogenerator is enabled.
\end_layout

\begin_layout Description
chipPinVCC This parameter is an integer specifying the VCC pin on the chip
package.
Note that it specifies the VCC pin on the chip package and _not_ on the
ZIF socket.
So if your chip datasheet tells you that VCC is on pin 8, you pass an 8
here.
\end_layout

\begin_layout Description
chipPinsVPP This parameter is an integer or a list of integers specifying
the VPP pin(s) on the chip package.
Note that it specifies the VPP pin on the chip package and _not_ on the
ZIF socket.
So if your chip datasheet tells you that VPP is on pin 1, you pass a 1
here.
If your chip needs multiple VPP voltages, just pass a list of pins.
Specify all possible VPP pins here.
Which pin is actually activated is decided later in applyVPP().
\end_layout

\begin_layout Description
chipPinGND This parameter is an integer specifying the GND pin on the chip
package.
Note that it specifies the GND pin on the chip package and _not_ on the
ZIF socket.
So if your chip datasheet tells you that GND is on pin 5, you pass a 5
here.
\end_layout

\begin_layout Standard
After passing all parameters to the
\begin_inset Quotes eld
\end_inset

class Chip
\begin_inset Quotes erd
\end_inset

constructor, the autogenerator is initialized and ready to be used.
The following
\begin_inset Quotes eld
\end_inset

class Chip
\begin_inset Quotes erd
\end_inset

methods can be used to enable or disable a layout:
\end_layout

\begin_layout Description
applyVCC(on) This method enables or disables (depending on the
\begin_inset Quotes eld
\end_inset

on
\begin_inset Quotes erd
\end_inset

parameter) the VCC layout.
Enabling the layout means that the VCC pin will be actively driven by the
configured VCC voltage.
Disabling the layout will tristate the driver.
\end_layout

\begin_layout Description
applyVPP(on,packagePinsToTurnOn) This method enables or disables (depending
on the
\begin_inset Quotes eld
\end_inset

on
\begin_inset Quotes erd
\end_inset

parameter) the VPP layout.
Enabling the layout means that the VPP pins will be actively driven by
the configured VPP voltage.
Disabling the layout will tristate the driver.
The first parameter
\begin_inset Quotes eld
\end_inset

on
\begin_inset Quotes erd
\end_inset

is a boolean to turn ON or OFF the VPP layout.
The second parameter is an optional list of package-pin-numbers specifying
which VPP is turned on.
If the second parameter is not passed, all possible VPPs that were specified
in the constructor are turned on.
The second parameter is unused, if
\begin_inset Quotes eld
\end_inset

on=False
\begin_inset Quotes erd
\end_inset

.
\end_layout

\begin_layout Description
applyGND(on) This method enables or disables (depending on the
\begin_inset Quotes eld
\end_inset

on
\begin_inset Quotes erd
\end_inset

parameter) the GND layout.
Enabling the layout means that the GND pins will be actively driven by
GND.
Disabling the layout will tristate the driver.
\end_layout

\end_body
\end_document