Skip to content

Commit

Permalink
Merge pull request #32 from adafruit/pylint-update
Browse files Browse the repository at this point in the history
Ran black, updated to pylint 2.x
  • Loading branch information
kattni committed Mar 17, 2020
2 parents b8c2d10 + a8e8cfa commit 2d25f4b
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 155 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
source actions-ci/install.sh
- name: Pip install pylint, black, & Sphinx
run: |
pip install --force-reinstall pylint==1.9.2 black==19.10b0 Sphinx sphinx-rtd-theme
pip install --force-reinstall pylint black==19.10b0 Sphinx sphinx-rtd-theme
- name: Library version
run: git describe --dirty --always --tags
- name: PyLint
Expand Down
3 changes: 2 additions & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ spelling-store-unknown-words=no
[MISCELLANEOUS]

# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
# notes=FIXME,XXX,TODO
notes=FIXME,XXX


[TYPECHECK]
Expand Down
150 changes: 81 additions & 69 deletions adafruit_sdcard.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,17 @@
_CMD_TIMEOUT = const(200)

_R1_IDLE_STATE = const(1 << 0)
#R1_ERASE_RESET = const(1 << 1)
# R1_ERASE_RESET = const(1 << 1)
_R1_ILLEGAL_COMMAND = const(1 << 2)
#R1_COM_CRC_ERROR = const(1 << 3)
#R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
#R1_ADDRESS_ERROR = const(1 << 5)
#R1_PARAMETER_ERROR = const(1 << 6)
_TOKEN_CMD25 = const(0xfc)
_TOKEN_STOP_TRAN = const(0xfd)
_TOKEN_DATA = const(0xfe)

#pylint: disable-msg=superfluous-parens
# R1_COM_CRC_ERROR = const(1 << 3)
# R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
# R1_ADDRESS_ERROR = const(1 << 5)
# R1_PARAMETER_ERROR = const(1 << 6)
_TOKEN_CMD25 = const(0xFC)
_TOKEN_STOP_TRAN = const(0xFD)
_TOKEN_DATA = const(0xFE)

# pylint: disable-msg=superfluous-parens
class SDCard:
"""Controls an SD card over SPI.
Expand All @@ -100,6 +100,7 @@ class SDCard:
os.listdir('/')
"""

def __init__(self, spi, cs, baudrate=1320000):
# This is the init baudrate.
# We create a second device with the target baudrate after card initialization.
Expand All @@ -125,7 +126,7 @@ def _clock_card(self, cycles=8):
self._spi.spi.configure(baudrate=self._spi.baudrate)
self._spi.chip_select.value = True

self._single_byte[0] = 0xff
self._single_byte[0] = 0xFF
for _ in range(cycles // 8 + 1):
self._spi.spi.write(self._single_byte)
self._spi.spi.unlock()
Expand All @@ -145,7 +146,7 @@ def _init_card(self, baudrate):

# CMD8: determine card version
rb7 = bytearray(4)
r = self._cmd(card, 8, 0x01aa, 0x87, rb7, data_block=False)
r = self._cmd(card, 8, 0x01AA, 0x87, rb7, data_block=False)
if r == _R1_IDLE_STATE:
self._init_card_v2(card)
elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND):
Expand All @@ -156,18 +157,18 @@ def _init_card(self, baudrate):
# get the number of sectors
# CMD9: response R2 (R1 byte + 16-byte block read)
csd = bytearray(16)
if self._cmd(card, 9, 0, 0xaf, response_buf=csd) != 0:
if self._cmd(card, 9, 0, 0xAF, response_buf=csd) != 0:
raise OSError("no response from SD card")
#self.readinto(csd)
csd_version = (csd[0] & 0xc0) >> 6
# self.readinto(csd)
csd_version = (csd[0] & 0xC0) >> 6
if csd_version >= 2:
raise OSError("SD card CSD format not supported")

if csd_version == 1:
self._sectors = ((csd[8] << 8 | csd[9]) + 1) * 1024
else:
block_length = 2 ** (csd[5] & 0xf)
c_size = ((csd[6] & 0x3) << 10) | (csd[7] << 2) | ((csd[8] & 0xc) >> 6)
block_length = 2 ** (csd[5] & 0xF)
c_size = ((csd[6] & 0x3) << 10) | (csd[7] << 2) | ((csd[8] & 0xC) >> 6)
mult = 2 ** (((csd[9] & 0x3) << 1 | (csd[10] & 0x80) >> 7) + 2)
self._sectors = block_length // 512 * mult * (c_size + 1)

Expand All @@ -176,34 +177,35 @@ def _init_card(self, baudrate):
raise OSError("can't set 512 block size")

# set to high data rate now that it's initialised
self._spi = spi_device.SPIDevice(self._spi.spi, self._spi.chip_select,
baudrate=baudrate, extra_clocks=8)
self._spi = spi_device.SPIDevice(
self._spi.spi, self._spi.chip_select, baudrate=baudrate, extra_clocks=8
)

def _init_card_v1(self, card):
"""Initialize v1 SDCards which use byte addressing."""
for _ in range(_CMD_TIMEOUT):
self._cmd(card, 55, 0, 0)
if self._cmd(card, 41, 0, 0) == 0:
#print("[SDCard] v1 card")
# print("[SDCard] v1 card")
return
raise OSError("timeout waiting for v1 card")

def _init_card_v2(self, card):
"""Initialize v2 SDCards which use 512-byte block addressing."""
ocr = bytearray(4)
for _ in range(_CMD_TIMEOUT):
time.sleep(.050)
self._cmd(card, 58, 0, 0xfd, response_buf=ocr, data_block=False)
time.sleep(0.050)
self._cmd(card, 58, 0, 0xFD, response_buf=ocr, data_block=False)
self._cmd(card, 55, 0, 0x65)
# On non-longint builds, we cannot use 0x40000000 directly as the arg
# so break it into bytes, which are interpreted by self._cmd().
if self._cmd(card, 41, b'\x40\x00\x00\x00', 0x77) == 0:
self._cmd(card, 58, 0, 0xfd, response_buf=ocr, data_block=False)
if self._cmd(card, 41, b"\x40\x00\x00\x00", 0x77) == 0:
self._cmd(card, 58, 0, 0xFD, response_buf=ocr, data_block=False)

# Check for block addressing
if (ocr[0] & 0x40) != 0:
self._cdv = 1
#print("[SDCard] v2 card")
# print("[SDCard] v2 card")
return
raise OSError("timeout waiting for v2 card")

Expand All @@ -216,13 +218,15 @@ def _wait_for_ready(self, card, timeout=0.3):
"""
start_time = time.monotonic()
self._single_byte[0] = 0x00
while time.monotonic() - start_time < timeout and self._single_byte[0] != 0xff:
card.readinto(self._single_byte, write_value=0xff)
while time.monotonic() - start_time < timeout and self._single_byte[0] != 0xFF:
card.readinto(self._single_byte, write_value=0xFF)

# pylint: disable-msg=too-many-arguments
# pylint: disable=no-member
# no-member disable should be reconsidered when it can be tested
def _cmd(self, card, cmd, arg=0, crc=0, response_buf=None, data_block=True, wait=True):
def _cmd(
self, card, 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.
Expand All @@ -237,17 +241,17 @@ def _cmd(self, card, cmd, arg=0, crc=0, response_buf=None, data_block=True, wait
buf = self._cmdbuf
buf[0] = 0x40 | cmd
if isinstance(arg, int):
buf[1] = (arg >> 24) & 0xff
buf[2] = (arg >> 16) & 0xff
buf[3] = (arg >> 8) & 0xff
buf[4] = arg & 0xff
buf[1] = (arg >> 24) & 0xFF
buf[2] = (arg >> 16) & 0xFF
buf[3] = (arg >> 8) & 0xFF
buf[4] = arg & 0xFF
elif len(arg) == 4:
# arg can be a 4-byte buf
buf[1:5] = arg
else:
raise ValueError()

if (crc == 0):
if crc == 0:
buf[5] = calculate_crc(buf[:-1])
else:
buf[5] = crc
Expand All @@ -259,21 +263,22 @@ def _cmd(self, card, cmd, arg=0, crc=0, response_buf=None, data_block=True, wait

# wait for the response (response[7] == 0)
for _ in range(_CMD_TIMEOUT):
card.readinto(buf, end=1, write_value=0xff)
card.readinto(buf, end=1, write_value=0xFF)
if not (buf[0] & 0x80):
if response_buf:
if data_block:
# Wait for the start block byte
buf[1] = 0xff
while buf[1] != 0xfe:
card.readinto(buf, start=1, end=2, write_value=0xff)
card.readinto(response_buf, write_value=0xff)
buf[1] = 0xFF
while buf[1] != 0xFE:
card.readinto(buf, start=1, end=2, write_value=0xFF)
card.readinto(response_buf, write_value=0xFF)
if data_block:
# Read the checksum
card.readinto(buf, start=1, end=3, write_value=0xff)
card.readinto(buf, start=1, end=3, write_value=0xFF)
return buf[0]
return -1
#pylint: enable-msg=too-many-arguments

# pylint: enable-msg=too-many-arguments

# pylint: disable-msg=too-many-arguments
def _block_cmd(self, card, cmd, block, crc, response_buf=None):
Expand All @@ -294,12 +299,12 @@ def _block_cmd(self, card, cmd, block, crc, response_buf=None):
# We address by byte because cdv is 512. Instead of multiplying, shift
# the data to the correct spot so that we don't risk creating a long
# int.
buf[1] = (block >> 15) & 0xff
buf[2] = (block >> 7) & 0xff
buf[3] = (block << 1) & 0xff
buf[1] = (block >> 15) & 0xFF
buf[2] = (block >> 7) & 0xFF
buf[3] = (block << 1) & 0xFF
buf[4] = 0

if (crc == 0):
if crc == 0:
buf[5] = calculate_crc(buf[:-1])
else:
buf[5] = crc
Expand All @@ -311,7 +316,7 @@ def _block_cmd(self, card, cmd, block, crc, response_buf=None):

# wait for the response (response[7] == 0)
for _ in range(_CMD_TIMEOUT):
card.readinto(buf, end=1, write_value=0xff)
card.readinto(buf, end=1, write_value=0xFF)
if not (buf[0] & 0x80):
result = buf[0]
break
Expand All @@ -322,9 +327,10 @@ def _block_cmd(self, card, cmd, block, crc, response_buf=None):
self._readinto(card, response_buf)

return result

# pylint: enable-msg=too-many-arguments

def _cmd_nodata(self, card, cmd, response=0xff):
def _cmd_nodata(self, card, cmd, response=0xFF):
"""
Issue a command to the card with no argument.
Expand All @@ -333,14 +339,14 @@ def _cmd_nodata(self, card, cmd, response=0xff):
"""
buf = self._cmdbuf
buf[0] = cmd
buf[1] = 0xff
buf[1] = 0xFF

card.write(buf, end=2)
for _ in range(_CMD_TIMEOUT):
card.readinto(buf, end=1, write_value=0xff)
card.readinto(buf, end=1, write_value=0xFF)
if buf[0] == response:
return 0 # OK
return 1 # timeout
return 0 # OK
return 1 # timeout

def _readinto(self, card, buf, start=0, end=None):
"""
Expand All @@ -355,14 +361,14 @@ def _readinto(self, card, buf, start=0, end=None):
end = len(buf)

# read until start byte (0xfe)
buf[start] = 0xff #busy
while buf[start] != 0xfe:
card.readinto(buf, start=start, end=start+1, write_value=0xff)
buf[start] = 0xFF # busy
while buf[start] != 0xFE:
card.readinto(buf, start=start, end=start + 1, write_value=0xFF)

card.readinto(buf, start=start, end=end, write_value=0xff)
card.readinto(buf, start=start, end=end, write_value=0xFF)

# read checksum and throw it away
card.readinto(self._cmdbuf, end=2, write_value=0xff)
card.readinto(self._cmdbuf, end=2, write_value=0xFF)

# pylint: disable-msg=too-many-arguments
def _write(self, card, token, buf, start=0, end=None):
Expand All @@ -385,27 +391,28 @@ def _write(self, card, token, buf, start=0, end=None):
cmd[0] = token
card.write(cmd, end=1)
card.write(buf, start=start, end=end)
cmd[0] = 0xff
cmd[1] = 0xff
cmd[0] = 0xFF
cmd[1] = 0xFF
card.write(cmd, end=2)

# check the response
# pylint: disable=no-else-return
# Disable should be removed when refactor can be tested
for _ in range(_CMD_TIMEOUT):
card.readinto(cmd, end=1, write_value=0xff)
card.readinto(cmd, end=1, write_value=0xFF)
if not (cmd[0] & 0x80):
if (cmd[0] & 0x1f) != 0x05:
if (cmd[0] & 0x1F) != 0x05:
return -1
else:
break

# wait for write to finish
card.readinto(cmd, end=1, write_value=0xff)
card.readinto(cmd, end=1, write_value=0xFF)
while cmd[0] == 0:
card.readinto(cmd, end=1, write_value=0xff)
card.readinto(cmd, end=1, write_value=0xFF)

return 0 # worked

return 0 # worked
# pylint: enable-msg=too-many-arguments

def count(self):
Expand All @@ -425,7 +432,7 @@ def readblocks(self, start_block, buf):
: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'
assert nblocks and not err, "Buffer length is invalid"
with self._spi as card:
if nblocks == 1:
# CMD17: set read address for single block
Expand All @@ -445,7 +452,7 @@ def readblocks(self, start_block, buf):
ret = self._cmd(card, 12, 0, 0x61, wait=False)
# return first status 0 or last before card ready (0xff)
while ret != 0:
card.readinto(self._single_byte, write_value=0xff)
card.readinto(self._single_byte, write_value=0xFF)
if self._single_byte[0] & 0x80:
return ret
ret = self._single_byte[0]
Expand All @@ -459,7 +466,7 @@ def writeblocks(self, start_block, buf):
: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'
assert nblocks and not err, "Buffer length is invalid"
with self._spi as card:
if nblocks == 1:
# CMD24: set write address for single block
Expand All @@ -475,12 +482,15 @@ def writeblocks(self, start_block, buf):
# send the data
offset = 0
while nblocks:
self._write(card, _TOKEN_CMD25, buf, start=offset, end=(offset + 512))
self._write(
card, _TOKEN_CMD25, buf, start=offset, end=(offset + 512)
)
offset += 512
nblocks -= 1
self._cmd_nodata(card, _TOKEN_STOP_TRAN, 0x0)
return 0


def _calculate_crc_table():
"""Precompute the table used in calculate_crc."""
# Code converted from https://github.com/hazelnusse/crc7/blob/master/crc7.cc by devoh747
Expand All @@ -492,18 +502,20 @@ def _calculate_crc_table():

# generate a table value for all 256 possible byte values
for i in range(256):
if (i & 0x80):
if i & 0x80:
crc_table[i] = i ^ crc_poly
else:
crc_table[i] = i
for _ in range(1, 8):
crc_table[i] = crc_table[i] << 1
if (crc_table[i] & 0x80):
if crc_table[i] & 0x80:
crc_table[i] = crc_table[i] ^ crc_poly
return crc_table


CRC_TABLE = _calculate_crc_table()


def calculate_crc(message):
"""
Calculate the CRC of message[0:5], using a precomputed table in CRC_TABLE.
Expand All @@ -515,4 +527,4 @@ def calculate_crc(message):
for i in range(0, 5):
crc = CRC_TABLE[(crc << 1) ^ message[i]]

return ((crc << 1) | 1)
return (crc << 1) | 1

0 comments on commit 2d25f4b

Please sign in to comment.