Skip to content

Improve Ref Docs #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
53 changes: 44 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -64,10 +60,49 @@ Contributions are welcome! Please read our `Code of Conduct
<https://github.com/adafruit/Adafruit_CircuitPython_sdcard/blob/master/CODE_OF_CONDUCT.md>`_
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 <https://github.com/adafruit/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.
142 changes: 93 additions & 49 deletions adafruit_sdcard.py
Original file line number Diff line number Diff line change
Expand Up @@ -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+
<https://www.adafruit.com/product/254>`_ (Product ID: 254)

* Author(s): Scott Shawcroft
* Adafruit `Assembled Data Logging shield for Arduino
<https://www.adafruit.com/product/1141>`_ (Product ID: 1141)

* Adafruit `Feather M0 Adalogger
<https://www.adafruit.com/product/2796>`_ (Product ID: 2796)

* Adalogger `FeatherWing - RTC + SD Add-on For All Feather Boards
<https://www.adafruit.com/product/2922>`_ (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
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -177,24 +203,28 @@ 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:
spi.readinto(self._single_byte, write_value=0xff)

#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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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)
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down
Binary file added docs/_static/favicon.ico
Binary file not shown.
File renamed without changes.
15 changes: 12 additions & 3 deletions conf.py → docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import os
import sys
sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('..'))

# -- General configuration ------------------------------------------------

Expand All @@ -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'
Expand All @@ -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.
Expand All @@ -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 ----------------------------------------------

Expand All @@ -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'

Expand Down
8 changes: 8 additions & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
@@ -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:
Loading