Documentation for “Zerocat Chipflasher” as of Tue, 11 Feb 2025 14:22:20 +0100
Repository:
Version: v2.1.1-0-7ab6f93df
Branch: master

../../firmware2/src/SPI-PASM.spin.flashrom.html

Propeller Spin/PASM Compiler 'OpenSpin' (c)2012-2016 Parallax Inc. DBA Parallax Semiconductor.
Version 1.00.78
Compiling...
../../firmware2/src/SPI-PASM.spin
|-pins.spin
  |-time.spin
Done.
Program size is 2784 bytes

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

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

File serprog-SPI-PASM.spin --- access chip via SPI using PASM

This file is part of Zerocat Chipflasher.

See end of file for terms of use.

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


# SPI Modes

    Mode#     CPOL (Clock Polarity)     CPHA (Clock Phase)
    -----     ---------------------     ------------------
    0         0                         0
    1         0                         1
    2         1                         0
    3         1                         1


## Mode Descriptions

Mode 0 --- The clock is active when HIGH. Data is written on the rising edge
of the clock. Data is read on the falling edge of the clock. (Default mode
for most SPI applications and chips.)

Mode 3 --- The clock is active when LOW. Data is written on the falling edge
of the clock.  Data is read on the rising edge of the clock.



# Interface Description

Object "../../firmware2/src/SPI-PASM" Interface:

PUB  go(mask_SPI, mask_CEn)
PUB  stop
PUB  init(cfg)
PUB  power_on(cfg, freq)
PUB  power_off
PUB  final_trigger
PUB  chip_enable
PUB  chip_disable
PUB  WPn_low
PUB  WPn_high
PUB  in(bitlength, bitmask, freq, fid)
PUB  out(data_out, msbit, freq, fid)

Program:  692 Longs
Variable: 15 Longs


# Loaded Objects

* Load pin configuration object.


# Constants

* Pin Configuration
  SPI_GATE_PMOSFETn
  SPI_MISO
  SPI_MOSI
  SPI_WPn
  SPI_HOLDn
  SPI_TRG_FSEL

* SPI Bitmasks
  BITMASK_CLK

* SPI Power Up Timings in Milliseconds

  __CLKFREQ (80_000_000):
    fixed to 80MHz operation,
    should be set according to CLKFREQ value instead
  Measurements with Cin=10uF Tantalum, Cout=1000uF

  Model         |  POWERUP  |  Repetitive?  |  Decay?  |  POWERDOWN
  --------------|-----------|---------------|----------|-------------
  T60/MX        |  5.0ms    |  no           |  yes     |  2.0ms
  T60/SST       |  1.8ms    |  yes          |  yes     |  4.5ms
  T60/Atmel     |  1.6ms    |  no           |  yes     |  2.0ms
  T500/MX       |  2.0ms    |  no           |  no      | 50.0ms
  X230 64Mbit   |  instant  |  no           |  no      |  instant

  Measurements with Cin=10uF Tantalum, Cout=100uF + 100nF

  Model         |  POWERUP  |  Repetitive?  |  Decay?  |  POWERDOWN
  --------------|-----------|---------------|----------|-------------
  GA-G41M-ES2L  |  > 8ms    |  no           |  ?       |  ?

  POWERUP_SPI (10ms):
    let voltage rise up on target board

  POWERUP_SPILINES (1ms):
    give lines some time to settle
      Is this required?? A value of 100us is fine for GA-G41M-ES2L.
      LetM-bM-^@M-^?s keep this value otherwise a chain of new tests is needed.

  POWERDOWN_SPI (50ms):
    a) blind out spikes on net Vcc_SPI (100us)
    b) let voltage come down on target board

  REPETITIVE_POWERUP (1)

* ENUM t_FUNCID
  FUNCID__READY, must be zero
  FUNCID__init1
  FUNCID__poweron
  FUNCID__poweroff
  FUNCID__trigger
  FUNCID__lo_CEn
  FUNCID__hi_CEn
  FUNCID__lo_WPn
  FUNCID__hi_WPn
  FUNCID__read
  FUNCID__write
  FUNCID__setspifrq


# Globals

* stack[]         --- Provide some stack space


# Functions

___________________________
PUB  go(mask_SPI, mask_CEn)

 Set static configuration, launch PASM code into new cog: SPI_PASM

_________
PUB  stop

 Stop cog.

______________
PUB  init(cfg)

 Set runtime configuration, launch PASM routine: init1

________________________
PUB  power_on(cfg, freq)

 Repetitive power on.

______________
PUB  power_off

 Launch PASM routine: poweroff

__________________
PUB  final_trigger

 Launch a final trigger to break endless loop.

________________
PUB  chip_enable

 Launch PASM routine: lo_CEn

_________________
PUB  chip_disable

 Launch PASM routine: hi_CEn

____________
PUB  WPn_low

 Launch PASM routine: lo_WPn

_____________
PUB  WPn_high

 Launch PASM routine: hi_WPn

______________________________________
PUB  in(bitlength, bitmask, freq, fid)

 Launch PASM routine: read
 Return value.

____________________________________
PUB  out(data_out, msbit, freq, fid)

 Launch PASM routine: write


# Data

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  SPI_PASM --- PASM code entry

  Parameter:

  * stack[0] = function ID / Ready Flag
  * stack[6] = _mask_SPI
  * stack[7] = _mask_CEn


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  hi_WPn --- deassert WPn

  Description:

  Sets #WP high, disables hardware write protection (if any).
  Note timing.

  Parameter:

  * stack[0] = function ID, will be set to 'ready' when done


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  lo_WPn --- assert WPn

  Description:

  Sets #WP low, enables hardware write protection (if configured).
  Note timing.

  Parameter:

  * stack[0] = function ID, will be set to 'ready' when done


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  lo_CEn --- chip enable/select

  Description:

  Activates output, CE# goes low.
  Note timing.

  Parameter:

  * stack[0] = function ID, will be set to 'ready' when done


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  hi_CEn --- chip disable/deselect

  Description:

  Uses tristate pin, as CE# goes high via pull-up.
  Note timing.

  Parameter:

  * stack[0] = function ID, will be set to 'ready' when done


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  init1 --- initialize SPI

  Description:

  * load configuration that changes during runtime
  * set up free wheeling counter modules to provide high frequency clock rates
  * initialize SPI pins to be in tristate mode
  * clear SPI latches
  * disable hold function
  * initialize clock pins

  Parameter:

  * stack[0] = function ID, will be set to 'ready' when done
  * stack[4] = mask_SPI_SEL
  * stack[5] = mode_SPI


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  poweron --- power SPI on

  Entry condition:

  * all SPI pins are in tristate mode
  * output latches are initialized
  * P-Channel MOSFET disabled, thus chip and #CE pull-up are not powered

  Power-up SPI:

  * activate P-Channel MOSFET, thus power chip on, with delay
  * activate SPI pins, with delay
  * the number of SPI clock driver pins is reduced for high frequencies

  Parameter:

  * stack[2] = targeted SPI frequency
  * stack[0] = function ID, will be set to 'ready' when done


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  poweroff --- power SPI off

  Description:

  Leaves Propeller pins in tristate condition,
  as they might be used by other cogs.

  Parameter:

  * stack[0] = function ID, will be set to 'ready' when done


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  trigger --- trigger a final, dummy pulse train


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  write --- send a value over SPI

  Description:

  This routine starts with HUB instructions, which might take odd numbers
  of cycles. Are we just lucky that the code for high speed data transfer
  is in sync with the free wheeling clock modules? Do we have to expect an
  out-of-sync exception at some point in future??

  * Case msbit == 128 has been rolled out to speed up byte transfer.
  * Cases $00 and $ff have been rolled out to speed up byte transfer even
    more.

  Parameter:

  * stack[3] = freqSPI
  * stack[2] = most significant bit, i.e. 128 for a byte to transfer
  * stack[1] = data to transmit
  * stack[0] = function ID, will be set to 'ready' when done


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  read --- read a value from SPI, apply bitmask

  Description:

  This routine starts with HUB instructions, which might take odd numbers
  of cycles. Are we just lucky that the code for high speed data transfer
  is in sync with the free wheeling clock modules? Do we have to expect an
  out-of-sync exception at some point in future??

  Bit length 8 has been rolled out to speed up transfer, using a higher
  frequency.

  Parameter:

  * stack[5] = SPI mode
  * stack[3] = freqSPI
  * stack[2] = bitmask / return value
  * stack[1] = bitlength
  * stack[0] = function ID, will be set to 'ready' when done

  The return value is not cleared upon entry.
  Therefore, bitmask should correspond to bitlength,
  as higher bits are not neccessarily zero.


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  Named registers, initialized

  ready                   --- used to flag valid data or end of function
  mask_TRIGGER            --- pin bit mask
  mask_CLK                --- compound bit mask
  mask_PMOSFETn           --- pin bit mask
  mask_MOSI               --- pin bit mask
  mask_MISO               --- pin bit mask
  mask_HOLDn              --- pin bit mask
  mask_WPn                --- pin bit mask
  time_LINESUP
  time_POWERDOWN
  t_powerup       --- give SPI voltage some time to rise


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

  Named registers, reserved space, not initialized

  funcID          --- PASM function to call
  freqSPI         --- targeted SPI frequency
  p               --- pointer into stack
  mask_SPI_SEL    --- selected pins of SPI, i.e. different sets of clock pins
  mode_SPI        --- SPI mode 0 or 3
  mbit            --- most significant bit / bit mask
  nbit            --- number of bit
  value           --- in/out data
  timetarget      --- temporary future time stamp
  _mask           --- temporary mask
  _mask_SPI       --- compound bitmask, configured at runtime
  _mask_CEn       --- compound bitmask, configured at runtime
  registers, unused: 15


******************************************************************************
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 ***