GithubHelp home page GithubHelp logo

pyspiflash's Introduction

pyspiflash

Python package build status

SPI data flash device drivers (pure Python)

SPI flash devices, also known as DataFlash are commonly found in embedded products, to store firmware, microcode or configuration parameters.

PySpiFlash comes with several pure Python drivers for those flash devices, that demonstrate use of SPI devices with PyFtdi. It could also be useful to dump flash contents or recover from a bricked devices.

Supported SPI flash devices

Vendor Atmel Atmel Macronix SST Winbond Micron Adesto
DataFlash AT45 AT25 MX25L SST25 W25Q N25Q AT25XE041B
Status Tested Tested Tested Tested Tested Tested Tested
Sizes (MiB) 2,4 2,4,8 2,4,8,16 2,4 2,4 8 0.5
Read (KiB/s) 1278 1279 1329 642 1252 1315 1695
Write (KiB/s) 56 64 71 2 63 107 32
Erase (KiB/s) 60 63 31 500 60 84 28

Notes about performances

  • Read operation is synchronous with SPI bus clock: it therefore only depends on the achievable frequency on the SPI bus, which is bound to the highest supported frequency of the flash device.
  • Write operation depends mostly on the flash device performance, whose upper limit comes mostly from the maximum write packet size of the device, as the device needs to be polled for completion after each packet: the shorter the packet, the higher traffic on the SPI and associated overhead.
  • Erase operation depends mostly on the flash device performance, whose fully depends on the flash device internal technology, as very few and short packets are exchanged over the SPI bus.

Supporting new flash devices of series '25'

Many flash devices support a common subset to for read/write/erase operations. Critical differences appear with lock and protection features, and with security features. An NDA is often required to obtain details about the advanced security features of these devices.

It should be nevertheless quite easy to add support for new flash device variants:

  • match method in the PyFtdi flash device API should be the first to look at to detect more compatible flash devices.

Supported SPI flash commands

Identification
The SPI device driver is automatically selected based on the detected SPI flash device
Read
Read byte sequences of any size, starting at any location from the SPI flash device
Write
Write arbitrary byte sequences of any size, starting at any location to the SPI flash device
Erase
Erase SPI flash device blocks, whose size depend on the capabilities of the flash device, typically 4KiB and/or 64KiB.
Unlock
Unlock any protected flash device sectors

Dependencies

  • Python 3.5 or above is required.
  • PyFTDI 0.42 or above is required.

Note about previous releases

If you have no choice but using previous releases of Python (including Python 2.x) or PyFTDI , please checkout the latest PySpiFlash 0.4.1 which provides support for these deprecated environmement, but is no longer actively maintained.

PySpiFlash heavily relies on PyFtdi module to access the SPI flash device. The PyFtdi API has been changed several times, see the compatibility matrix below.

The setup.py script should take care of those dependencies.

PySpiFlash version PyFtdi version
0.2.* 0.9 .. 0.10
0.3.* 0.11+
0.4.* 0.13.2+
0.5.* 0.20.0+
0.6.* 0.42.0+

pyspiflash's People

Contributors

bakibakis avatar eblot avatar mrbell321 avatar pu-cc avatar sifive-eblot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyspiflash's Issues

chip erase function should be improved

The chip erase functionality is using only one pair of timeout values (typical, maximum) even when a whole family of devices is supported (e.g. W25xFlashDevice). While the pair for W25xFlashDevice seems to have been taken from a the data sheet of 4 MBit device (4, 11), those values are much too low for devices with a larger memory size (e.g for 128MBit the data sheet says the pair is (40, 200)). That is because chip erase time is approx. proportional to memory size.

I think that either there has to be such a pair for each supported size or - if the code for waiting is not going to be changed - one could stick with just one pair and set 'typical' value to the typical value of the smallest device and set the 'maximum' value to the maximum value of the largest device.

FYI: I am writing this, because trying to erase a Winbond W25Q128JV with pyspiflash fails, because 11 seconds is not enough for this chip.

Support for MX25L6406E (8MB)

Please add support for the MX25L6406E (8MB), data sheet at http://www.macronix.com/Lists/DataSheet/Attachments/3223/MX25L6406E,%203V,%2064Mb,%20v1.9.pdf

Using a FTDI UM232H it works nicely. I've added: 0x20 : 'MX25L' at:

class Mx25lFlashDevice(_Gen25FlashDevice):
    """Macronix MX25L flash device implementation"""
    JEDEC_ID = 0xC2
    DEVICES = { 0x9E : 'MX25D', 0x26 : 'MX25E', 0x20 : 'MX25L' }

any my test app produced this:

JDEC ID: c22017
Flash device: Macronix MX25L64 8 MiB @ SPI freq 30.0 MHz
speed test: read full flash, 8 MiB (8388608 byte)
reading took 2.56 secs, 3.13 MiB/sec

I'm wondering, the class name and the comment indicates this chip should be supported already? Did you see any problems with this chip? Reading seem to work fine do far, I've not tried writing so far.

Adesto AT25SF041(formerly atmel) with chip erase

I'm adding support for AT25SF041 which is an Adesto product. Formerly Atmel. We you prefer this under the AT25 heading since it's not officially Atmel? Or create a new class for Adesto?
I'm also working with Winbond W25X4 and both chips support chip_erase, but I"m not immediately seeing a clean way to implement this with the existing structure. It's a different command w/ different parameters and operating requirements. I have added a separate 'erase_chip' method as a POC, but if you have any ideas on how to integrate this into the existing erase() methods, I'm all ears.

Raspberry Pi 4

Is possible to use pyspiflash on a Raspberry Pi 4 with its' GPIO acting as SPI?

I tried looking at the documentary of pyftdi but it didn't make me any wiser.

Installation failure

I was attempting to install this in Python 3.6 (Windows 7 x64) with the following command.

python -m pip install pyspiflash

This resulted in an installation failure.

Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-i4aiebiz/pyspiflash/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmpp1oz4q8cpip-wheel- --python-tag cp36:
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib
  creating build/lib/spiflash
  copying ./spiflash/__init__.py -> build/lib/spiflash
  copying ./spiflash/serialflash.py -> build/lib/spiflash
  copying ./spiflash/README.rst -> build/lib/spiflash
  installing to build/bdist.linux-x86_64/wheel
  running install
  running install_lib
  creating build/bdist.linux-x86_64
  creating build/bdist.linux-x86_64/wheel
  creating build/bdist.linux-x86_64/wheel/spiflash
  copying build/lib/spiflash/README.rst -> build/bdist.linux-x86_64/wheel/spiflash
  copying build/lib/spiflash/__init__.py -> build/bdist.linux-x86_64/wheel/spiflash
  copying build/lib/spiflash/serialflash.py -> build/bdist.linux-x86_64/wheel/spiflash
  running install_egg_info
  running egg_info
  writing pyspiflash.egg-info/PKG-INFO
  writing dependency_links to pyspiflash.egg-info/dependency_links.txt
  writing requirements to pyspiflash.egg-info/requires.txt
  writing top-level names to pyspiflash.egg-info/top_level.txt
  reading manifest file 'pyspiflash.egg-info/SOURCES.txt'
  writing manifest file 'pyspiflash.egg-info/SOURCES.txt'
  Copying pyspiflash.egg-info to build/bdist.linux-x86_64/wheel/pyspiflash-0.5.2-py3.6.egg-info
  running install_scripts
  error: [Errno 2] No such file or directory: 'spiflash/LICENSE'
  
  ----------------------------------------
  Failed building wheel for pyspiflash
  Running setup.py clean for pyspiflash

Could this be because of the switch from egg to wheel?

Add a cleanup method for SpiController

First of all thank you for publishing pyspiflash. I'm using it for my project https://gitlab.com/expliot_framework/expliot

I was not able to find a cleanup method in serialflash.py for the SpiController. If there is already one, it would help of you can point me to the code.
My program will run continuously and needs to close the ftdi interface after each operation. Right now I'm doing it in my code:
def close(device):
if device:
device._spi._controller.terminate()
It would be nice to have a clean way to do it instead of using "_members" directly.
If you want I can send a merge request with similar code as above in SerialFlashManager or preferably _SpiFlashDevice.

Fix possibility to select different chipselect with pyftdi>=0.40

pyftdi>=0.40 changes default number of chipselects from 4 to 1. Chipselect number can be passed to method SerialFlashManager.get_flash_device(), but it no longer works for cs>0, because SpiController must be initialised with propper number of available chipselects, which cant be done.

May be related to #1

SPI mode 3

how can I change the spi mode to 3?
it's mentions that it was verify on Micron N25Q, but it required spi mode = 3
I see any option to change the spi mode

A question about SerialFlashUnknownJedec exception when using W25Q256

Hi.

I am a bit stuck and would really appreciate any hint related to my issue:

  1. I have a script for FLASH programming through FTDI (FT2232H) and it works without any problem with W25Q32
  2. But when I try it with W25Q256, I get:
  File "/home/admin/.local/lib/python3.9/site-packages/spiflash/serialflash.py", line 228, in get_from_controller
    flash = SerialFlashManager._get_flash(spi, jedec)
  File "/home/admin/.local/lib/python3.9/site-packages/spiflash/serialflash.py", line 271, in _get_flash
    raise SerialFlashUnknownJedec(jedec)
spiflash.serialflash.SerialFlashUnknownJedec: Unknown flash device: b'ef4019'

My code looks something like (FTDI_URL=ftdi://0x0403:0x6010:FT6CCSY8/1):

spi_master = SpiController()
spi_master.configure(FTDI_URL, cs_count=1, debug=False)
spi_slave = spi_master.get_port(cs=0, freq=6E6, mode=0)

spi_master.set_gpio_direction(0b11010000, 0b11010000)
sleep(0.001)

# Send init value.
spi_master.write_gpio(64)
sleep(0.5)

# Soft reset.
# Enable reset.
spi_cmd = array('B', (0x66,))
spi_slave.exchange(spi_cmd)
# Reset device.
spi_cmd = array('B', (0x99,))
spi_slave.exchange(spi_cmd)

try:
    flash = SerialFlashManager.get_from_controller(spi_master, 0, 6E6)
...
...

Does that mean this device is not supported or I am doing something wrong?

Thank you in advance for any suggestion.

Winbond W25Q128 flash (16 MiB)

Please add the Winbond W25Q128 flash (16 MiB). It works nicely with the existing code, so it's
basically just extending one line

class W25xFlashDevice(_Gen25FlashDevice):
    ...
    SIZES = { ... 0x18:  16 << 20  #  16 MiB }

Support constructor that take an SPI object

Please add a constructor that takes an "spi" object (ie an SPI Controller port) , so the calling application can take care of creating this and finding the proper FTDI device is kept out of scope. Currently I'm using this code to implement this:

def getFtdiSpiFlash(spi):
jedec = pyspiflash.serialflash.SerialFlashManager.read_jedec_id(spi)
if not jedec:
raise AssertionError("Unable to read JEDEC ID")
flash = pyspiflash.serialflash.SerialFlashManager._get_flash(spi, jedec)

However, It would be nice to keep the jedec part internal to pyspiflash again and drop this helper.

The background for this request is, that is improves usage in environment where multiple FTDI devices are used. In the bigger picture, certain USB ports are assigned to certain devices/boards/TestSockets..., so devices are selected by the "USB port-path". Any fallback to VID/PID/Serial works, but it suffers from practical problem like people borrowing and thus accidentally (ex)changing devices, as they all look the same....

Unable to run setup.py

I'm getting the following error

`File "./setup.py", line 119
print(str(exc), file=stderr)

SyntaxError: invalid syntax`

Examples, please

Hello guys :)

I stumbled upon this interesting project because I'm experimenting a bit with flash memories (MX25L12835F). I'd like to make it work and then to make a pull request to add the support of this IC (in case I succed, I mean ^^").

I would be really grateful if you could share a basic example of how to use this library.
Thank you in advance!

Incorrect parameter for SerialFlashUnknownJedec

SerialFlashUnknownJedec constructor expects a bytes-like parameter jedec (since it is passed in hexlify()), however in some places a str is passed into the constructor instead (lines 227 and 249 of pyspiflash/serialflash.py):

raise SerialFlashUnknownJedec("Unable to read JEDEC Id")

Add support for GigaDevice

Hello, do you think that you could add support for GigaDevice based SPI flashes? I have been having a heck of a time getting anything to touch GD25LB128 SPI flashes. Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.