diff --git a/readthedocs.yml b/.readthedocs.yml similarity index 100% rename from readthedocs.yml rename to .readthedocs.yml diff --git a/.travis.yml b/.travis.yml index 9bf0498..203ff6e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,15 +16,17 @@ deploy: provider: releases api_key: $GITHUB_TOKEN file_glob: true - file: bundles/* + file: $TRAVIS_BUILD_DIR/bundles/* skip_cleanup: true + overwrite: true on: tags: true install: - - pip install pylint circuitpython-build-tools + - pip install pylint circuitpython-build-tools Sphinx sphinx-rtd-theme script: - pylint adafruit_sdcard.py - ([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name examples/*.py) - circuitpython-build-bundles --filename_prefix adafruit-circuitpython-sd --library_location . + - cd docs && sphinx-build -E -W -b html . _build/html diff --git a/README.rst b/README.rst index 55e9b26..fbc080d 100644 --- a/README.rst +++ b/README.rst @@ -6,10 +6,6 @@ Introduction :target: https://circuitpython.readthedocs.io/projects/sdcard/en/latest/ :alt: Documentation Status -.. image :: https://badges.gitter.im/adafruit/circuitpython.svg - :target: https://gitter.im/adafruit/circuitpython?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge - :alt: Gitter - .. image :: https://img.shields.io/discord/327254708534116352.svg :target: https://adafru.it/discord :alt: Discord @@ -64,10 +60,49 @@ Contributions are welcome! Please read our `Code of Conduct `_ before contributing to help this project stay welcoming. -API Reference -============= +Building locally +================ + +To build this library locally you'll need to install the +`circuitpython-build-tools `_ package. + +.. code-block:: shell + + python3 -m venv .env + source .env/bin/activate + pip install circuitpython-build-tools + +Once installed, make sure you are in the virtual environment: + +.. code-block:: shell + + source .env/bin/activate + +Then run the build: + +.. code-block:: shell + + circuitpython-build-bundles --filename_prefix adafruit-circuitpython-sd --library_location . + +Sphinx documentation +----------------------- + +Sphinx is used to build the documentation based on rST files and comments in the code. First, +install dependencies (feel free to reuse the virtual environment from above): + +.. code-block:: shell + + python3 -m venv .env + source .env/bin/activate + pip install Sphinx sphinx-rtd-theme + +Now, once you have the virtual environment activated: + +.. code-block:: shell -.. toctree:: - :maxdepth: 2 + cd docs + sphinx-build -E -W -b html . _build/html - api +This will output the documentation to ``docs/_build/html``. Open the index.html in your browser to +view them. It will also (due to -W) error out on any warning like Travis will. This is a good way to +locally verify it will pass. \ No newline at end of file diff --git a/adafruit_sdcard.py b/adafruit_sdcard.py index dac853f..1863bc1 100644 --- a/adafruit_sdcard.py +++ b/adafruit_sdcard.py @@ -29,23 +29,30 @@ Requires an SPI bus and a CS pin. Provides readblocks and writeblocks methods so the device can be mounted as a filesystem. -Example usage: +* Author(s): Scott Shawcroft -.. code-block:: python +Implementation Notes +-------------------- - import busio - import storage - import adafruit_sdcard - import os - import board +**Hardware:** - spi = busio.SPI(SCK, MOSI, MISO) - sd = adafruit_sdcard.SDCard(spi, board.SD_CS) - vfs = storage.VfsFat(sdcard) - storage.mount(vfs, '/sd') - os.listdir('/') +* Adafruit `MicroSD card breakout board+ + `_ (Product ID: 254) -* Author(s): Scott Shawcroft +* Adafruit `Assembled Data Logging shield for Arduino + `_ (Product ID: 1141) + +* Adafruit `Feather M0 Adalogger + `_ (Product ID: 2796) + +* Adalogger `FeatherWing - RTC + SD Add-on For All Feather Boards + `_ (Product ID: 2922) + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the ESP8622 and M0-based boards: + https://github.com/adafruit/circuitpython/releases +* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice """ import time @@ -73,7 +80,25 @@ class SDCard: """Controls an SD card over SPI. :param ~busio.SPI spi: The SPI bus - :param ~digitalio.DigitalInOut cs: The chip select connected to the card""" + :param ~digitalio.DigitalInOut cs: The chip select connected to the card + + Example usage: + + .. code-block:: python + + import busio + import storage + import adafruit_sdcard + import os + import board + + spi = busio.SPI(SCK, MOSI, MISO) + sd = adafruit_sdcard.SDCard(spi, board.SD_CS) + vfs = storage.VfsFat(sdcard) + storage.mount(vfs, '/sd') + os.listdir('/') + + """ def __init__(self, spi, cs): # This is the init baudrate. We create a second device for high speed. self._spi = spi_device.SPIDevice(spi, cs, baudrate=250000, extra_clocks=8) @@ -88,9 +113,10 @@ def __init__(self, spi, cs): self._init_card() def _clock_card(self, cycles=8): - """Clock the bus a minimum of `cycles` with the chip select high. + """ + Clock the bus a minimum of `cycles` with the chip select high. - :param int cycles: The minimum number of clock cycles to cycle the bus. + :param int cycles: The minimum number of clock cycles to cycle the bus. """ while not self._spi.spi.try_lock(): pass @@ -177,10 +203,12 @@ def _init_card_v2(self): raise OSError("timeout waiting for v2 card") def _wait_for_ready(self, spi, timeout=0.3): - """Wait for the card to clock out 0xff to indicate its ready. + """ + Wait for the card to clock out 0xff to indicate its ready. - :param busio.SPI spi: The locked SPI bus. - :param float timeout: Maximum time to wait in seconds.""" + :param busio.SPI spi: The locked SPI bus. + :param float timeout: Maximum time to wait in seconds. + """ start_time = time.monotonic() self._single_byte[0] = 0x00 while time.monotonic() - start_time < timeout and self._single_byte[0] != 0xff: @@ -188,13 +216,15 @@ def _wait_for_ready(self, spi, timeout=0.3): #pylint: disable-msg=too-many-arguments def _cmd(self, cmd, arg=0, crc=0, response_buf=None, data_block=True, wait=True): - """Issue a command to the card and read an optional data response. + """ + Issue a command to the card and read an optional data response. - :param int cmd: The command number. - :param int arg: The command argument. - :param int crc: The crc to allow the card to verify the command and argument. - :param bytearray response_buf: Buffer to read a data block response into. - :param bool data_block: True if the response data is in a data block.""" + :param int cmd: The command number. + :param int arg: The command argument. + :param int crc: The crc to allow the card to verify the command and argument. + :param bytearray response_buf: Buffer to read a data block response into. + :param bool data_block: True if the response data is in a data block. + """ # create and send the command buf = self._cmdbuf buf[0] = 0x40 | cmd @@ -229,11 +259,13 @@ def _cmd(self, cmd, arg=0, crc=0, response_buf=None, data_block=True, wait=True) #pylint: enable-msg=too-many-arguments def _block_cmd(self, cmd, block, crc, response_buf=None): - """Issue a command to the card with a block argument. + """ + Issue a command to the card with a block argument. - :param int cmd: The command number. - :param int block: The relevant block. - :param int crc: The crc to allow the card to verify the command and argument.""" + :param int cmd: The command number. + :param int block: The relevant block. + :param int crc: The crc to allow the card to verify the command and argument. + """ if self._cdv == 1: return self._cmd(cmd, block, crc, response_buf=response_buf) @@ -268,9 +300,11 @@ def _block_cmd(self, cmd, block, crc, response_buf=None): return result def _cmd_nodata(self, cmd, response=0xff): - """Issue a command to the card with no argument. + """ + Issue a command to the card with no argument. - :param int cmd: The command number.""" + :param int cmd: The command number. + """ buf = self._cmdbuf buf[0] = cmd buf[1] = 0xff @@ -284,11 +318,13 @@ def _cmd_nodata(self, cmd, response=0xff): return 1 # timeout def _readinto(self, buf, start=0, end=None): - """Read a data block into buf. + """ + Read a data block into buf. - :param bytearray buf: The buffer to write into - :param int start: The first index to write data at - :param int end: The index after the last byte to write to""" + :param bytearray buf: The buffer to write into + :param int start: The first index to write data at + :param int end: The index after the last byte to write to. + """ if end is None: end = len(buf) with self._spi as spi: @@ -303,12 +339,14 @@ def _readinto(self, buf, start=0, end=None): spi.readinto(self._cmdbuf, end=2, write_value=0xff) def _write(self, token, buf, start=0, end=None): - """Write a data block to the card. + """ + Write a data block to the card. - :param int token: The start token - :param bytearray buf: The buffer to write from - :param int start: The first index to read data from - :param int end: The index after the last byte to read from""" + :param int token: The start token + :param bytearray buf: The buffer to write from + :param int start: The first index to read data from + :param int end: The index after the last byte to read from. + """ cmd = self._cmdbuf if end is None: end = len(buf) @@ -340,17 +378,21 @@ def _write(self, token, buf, start=0, end=None): return 0 # worked def count(self): - """Returns the total number of sectors. + """ + Returns the total number of sectors. - :return: The number of 512-byte blocks - :rtype: int""" + :return: The number of 512-byte blocks + :rtype: int + """ return self._sectors def readblocks(self, start_block, buf): - """Read one or more blocks from the card + """ + Read one or more blocks from the card - :param int start_block: The block to start reading from - :param bytearray buf: The buffer to write into. Length must be multiple of 512.""" + :param int start_block: The block to start reading from + :param bytearray buf: The buffer to write into. Length must be multiple of 512. + """ nblocks, err = divmod(len(buf), 512) assert nblocks and not err, 'Buffer length is invalid' if nblocks == 1: @@ -372,10 +414,12 @@ def readblocks(self, start_block, buf): return 0 def writeblocks(self, start_block, buf): - """Write one or more blocks to the card + """ + Write one or more blocks to the card - :param int start_block: The block to start writing to - :param bytearray buf: The buffer to write into. Length must be multiple of 512.""" + :param int start_block: The block to start writing to + :param bytearray buf: The buffer to write into. Length must be multiple of 512. + """ nblocks, err = divmod(len(buf), 512) assert nblocks and not err, 'Buffer length is invalid' if nblocks == 1: diff --git a/docs/_static/favicon.ico b/docs/_static/favicon.ico new file mode 100644 index 0000000..5aca983 Binary files /dev/null and b/docs/_static/favicon.ico differ diff --git a/api.rst b/docs/api.rst similarity index 100% rename from api.rst rename to docs/api.rst diff --git a/conf.py b/docs/conf.py similarity index 90% rename from conf.py rename to docs/conf.py index ece8035..1d991d1 100644 --- a/conf.py +++ b/docs/conf.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('..')) # -- General configuration ------------------------------------------------ @@ -28,7 +28,7 @@ source_suffix = '.rst' # The master toctree document. -master_doc = 'README' +master_doc = 'index' # General information about the project. project = u'Adafruit SD Card Library' @@ -54,7 +54,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.env', 'CODE_OF_CONDUCT.md'] # The reST default role (used for this markup: `text`) to use for all # documents. @@ -71,6 +71,9 @@ # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False +# If this is True, todo emits a warning for each TODO entries. The default is False. +todo_emit_warnings = True + # -- Options for HTML output ---------------------------------------------- @@ -95,6 +98,12 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] +# The name of an image file (relative to this directory) to use as a favicon of +# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# +html_favicon = '_static/favicon.ico' + # Output file base name for HTML help builder. htmlhelp_basename = 'AdafruitSD CardLibrarydoc' diff --git a/docs/examples.rst b/docs/examples.rst new file mode 100644 index 0000000..1ee39df --- /dev/null +++ b/docs/examples.rst @@ -0,0 +1,8 @@ +Simple test +------------ + +Ensure your device works with this simple test. + +.. literalinclude:: ../examples/sd_read_simpletest.py + :caption: examples/sd_read_simpletest.py + :linenos: diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..59e3094 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,53 @@ +.. include:: ../README.rst + +Table of Contents +================= + +.. toctree:: + :maxdepth: 4 + :hidden: + + self + +.. toctree:: + :caption: Examples + + examples + +.. toctree:: + :caption: API Reference + :maxdepth: 3 + + api + +.. toctree:: + :caption: Tutorials + +.. toctree:: + :caption: Related Products + + Adafruit MicroSD card breakout board+ + + Adafruit Assembled Data Logging shield for Arduino + + Adafruit Feather M0 Adalogger + + Adalogger FeatherWing - RTC + SD Add-on For All Feather Boards + +.. toctree:: + :caption: Other Links + + Download + CircuitPython Reference Documentation + CircuitPython Support Forum + Discord Chat + Adafruit Learning System + Adafruit Blog + Adafruit Store + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/examples/read_directory.py b/examples/sd_read_simpletest.py similarity index 100% rename from examples/read_directory.py rename to examples/sd_read_simpletest.py