Reflow to max 70 characters

This commit is contained in:
Matt Mets 2023-03-02 18:37:11 +01:00 committed by Michael Cardell Widerkrantz
parent 84d020e3c0
commit acdc900b3b
No known key found for this signature in database
GPG Key ID: D3DB3DDF57E704E5
3 changed files with 80 additions and 73 deletions

View File

@ -1,8 +1,5 @@
lint: lint:
autopep8 --in-place --aggressive --aggressive usb_test.py autopep8 --in-place --max-line-length 70 --aggressive --aggressive usb_test.py icenvcm.py
mypy --disallow-untyped-defs usb_test.py mypy --disallow-untyped-defs usb_test.py icenvcm.py
#pycodestyle usb_test.py pycodestyle --max-line-length 70 usb_test.py icenvcm.py
autopep8 --in-place --aggressive --aggressive icenvcm.py
mypy --disallow-untyped-defs icenvcm.py
#pycodestyle icenvcm.py

View File

@ -6,17 +6,19 @@
# * Matthew Mets https://github.com/cibomahto # * Matthew Mets https://github.com/cibomahto
# * Peter Lawrence https://github.com/majbthrd # * Peter Lawrence https://github.com/majbthrd
# #
# Permission to use, copy, modify, and/or distribute this software for any # Permission to use, copy, modify, and/or distribute this software
# purpose with or without fee is hereby granted, provided that the above # for any purpose with or without fee is hereby granted, provided
# copyright notice and this permission notice appear in all copies. # that the above copyright notice and this permission notice
# appear in all copies.
# #
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# #
import usb_test import usb_test
@ -80,7 +82,7 @@ class Nvcm():
self.flasher.gpio_put(self.pins['crst'], reset) self.flasher.gpio_put(self.pins['crst'], reset)
def sendhex(self, s: str) -> int: def sendhex(self, s: str) -> int:
if self.debug and not s == "0500": # supress status check messages if self.debug and not s == "0500": # suppress status_wait
print("TX", s) print("TX", s)
x = bytes.fromhex(s) x = bytes.fromhex(s)
@ -159,7 +161,11 @@ class Nvcm():
# SMCInstruction[1] = 0x70807E99557E; # SMCInstruction[1] = 0x70807E99557E;
self.command("7eaa997e010e") self.command("7eaa997e010e")
def read(self, address: int, length: int = 8, cmd: int = 0x03) -> int: def read(
self,
address: int,
length: int = 8,
cmd: int = 0x03) -> int:
"""Returns a big integer""" """Returns a big integer"""
# enable(0) # enable(0)
# sendhex("%02x%06x" % (cmd, address)) # sendhex("%02x%06x" % (cmd, address))
@ -182,7 +188,11 @@ class Nvcm():
def read_bytes(self, address: int, length: int = 8) -> bytes: def read_bytes(self, address: int, length: int = 8) -> bytes:
"""Returns a byte array of the contents""" """Returns a byte array of the contents"""
return self.read(address, length).to_bytes(length, byteorder="big") return self.read(
address,
length).to_bytes(
length,
byteorder="big")
def write(self, address: int, data: str, cmd: int = 0x02) -> None: def write(self, address: int, data: str, cmd: int = 0x02) -> None:
self.sendhex_cs("%02x%06x" % (cmd, address) + data) self.sendhex_cs("%02x%06x" % (cmd, address) + data)
@ -190,8 +200,9 @@ class Nvcm():
try: try:
self.status_wait() self.status_wait()
except Exception as e: except Exception as e:
raise Exception("WRITE FAILED: cmd=%02x address=%06x data=%s" % raise Exception(
(cmd, address, data)) "WRITE FAILED: cmd=%02x address=%06x data=%s" %
(cmd, address, data))
self.tck(8) self.tck(8)
@ -264,7 +275,9 @@ class Nvcm():
self.select_nvcm() self.select_nvcm()
if x != 0: if x != 0:
print("NVCM Trim_Parameter_OTP Block is not blank. (%02x)" % x) print(
"NVCM Trim_Parameter_OTP Block is not blank. (%02x)" %
x)
return False return False
return True return True
@ -344,7 +357,8 @@ class Nvcm():
lock_bits_int = int(lock_bits, 16) lock_bits_int = int(lock_bits, 16)
if x & lock_bits_int != lock_bits_int: if x & lock_bits_int != lock_bits_int:
raise Exception( raise Exception(
"Failed to write trim lock bits: %016x != expected %016x" % "Failed to write trim lock bits: " +
"%016x != expected %016x" %
(x, lock_bits_int)) (x, lock_bits_int))
print("New state %016x" % (x)) print("New state %016x" % (x))
@ -353,7 +367,9 @@ class Nvcm():
print("NVCM Secure") print("NVCM Secure")
trim = self.read_trim() trim = self.read_trim()
if (trim >> 60) & 0x3 != 0: if (trim >> 60) & 0x3 != 0:
print("NVCM already secure? trim=%016x" % (trim), file=sys.stderr) print(
"NVCM already secure? trim=%016x" %
(trim), file=sys.stderr)
self.write_trim_pages("3000000100000000") self.write_trim_pages("3000000100000000")
@ -418,7 +434,9 @@ class Nvcm():
contents += self.read_bytes(offset, 8) contents += self.read_bytes(offset, 8)
if filename == '-': if filename == '-':
with os.fdopen(sys.stdout.fileno(), "wb", closefd=False) as f: with os.fdopen(sys.stdout.fileno(),
"wb",
closefd=False) as f:
f.write(contents) f.write(contents)
f.flush() f.flush()
else: else:
@ -504,8 +522,8 @@ def sleep_flash(pins: dict) -> None:
['{:02x}'.format(b) for b in data])) ['{:02x}'.format(b) for b in data]))
assert (data == bytes([0xff, 0xef, 0x40])) assert (data == bytes([0xff, 0xef, 0x40]))
# Test that the flash will ignore a sleep command that doesn't start on # Test that the flash will ignore a sleep command that doesn't
# the first byte # start on the first byte
flasher.spi_bitbang(bytes([0, 0xb9])) flasher.spi_bitbang(bytes([0, 0xb9]))
# Confirm we can talk to flash # Confirm we can talk to flash
@ -537,17 +555,19 @@ if __name__ == "__main__":
default='ftdi://::/1', default='ftdi://::/1',
help='FTDI port of the form ftdi://::/1') help='FTDI port of the form ftdi://::/1')
parser.add_argument('-v', '--verbose', parser.add_argument(
dest='verbose', '-v',
action='store_true', '--verbose',
help='Show debug information and serial read/writes') dest='verbose',
action='store_true',
help='Show debug information and serial read/writes')
parser.add_argument( parser.add_argument(
'-f', '-f',
'--sleep_flash', '--sleep_flash',
dest='sleep_flash', dest='sleep_flash',
action='store_true', action='store_true',
help='Put an attached SPI flash chip in deep sleep before programming FPGA') help='Put an attached SPI flash chip in deep sleep')
parser.add_argument( parser.add_argument(
'-b', '-b',
@ -572,7 +592,8 @@ if __name__ == "__main__":
dest='write_file', dest='write_file',
type=str, type=str,
default=None, default=None,
help='bitstream file to write to NVCM (warning: not reversable!)') help='bitstream file to write to NVCM ' +
'(warning: not reversable!)')
parser.add_argument('--ignore-blank', parser.add_argument('--ignore-blank',
dest='ignore_blank', dest='ignore_blank',
@ -583,7 +604,8 @@ if __name__ == "__main__":
'--secure', '--secure',
dest='set_secure', dest='set_secure',
action='store_true', action='store_true',
help='Set security bits to prevent modification (warning: not reversable!') help='Set security bits to prevent modification ' +
'(warning: not reversable!)')
parser.add_argument( parser.add_argument(
'--my-design-is-good-enough', '--my-design-is-good-enough',
@ -595,32 +617,11 @@ if __name__ == "__main__":
if not args.good_enough \ if not args.good_enough \
and (args.write_file or args.set_secure): and (args.write_file or args.set_secure):
print("Are you sure your design is good enough?", file=sys.stderr) print(
"Are you sure your design is good enough?",
file=sys.stderr)
exit(1) exit(1)
# Instantiate a SPI controller, with separately managed CS line
# spi = SpiController()
# Configure the first interface (IF/1) of the FTDI device as a SPI controller
# spi.configure(args.port)
# Get a port to a SPI device w/ /CS on A*BUS3 and SPI mode 0 @ 12MHz
# the CS line is not used in this case
# dev = spi.get_port(cs=0, freq=12E6, mode=0)
# reset_pin = 7
# cs_pin = 4
# Get GPIO port to manage the CS and RESET pins
# gpio = spi.get_gpio()
# gpio.set_direction(1 << reset_pin | 1 << cs_pin, 1 << reset_pin | 1 << cs_pin)
# Enable power to the FPGA, then set both reset and CS pins high
# # Reset pin values
# for pin in tp1_pins:
# flasher.gpio_set_direction(tp1_pins[pin], False)
tp1_pins = { tp1_pins = {
'5v_en': 7, '5v_en': 7,
'sck': 10, 'sck': 10,

View File

@ -17,7 +17,8 @@ class ice40_flasher:
FLASHER_REQUEST_BOOTLOADRE = 0xFF FLASHER_REQUEST_BOOTLOADRE = 0xFF
def __init__(self) -> None: def __init__(self) -> None:
# See: https://github.com/pyusb/pyusb/blob/master/docs/tutorial.rst # See:
# https://github.com/pyusb/pyusb/blob/master/docs/tutorial.rst
self.dev = usb.core.find(idVendor=0xcafe, idProduct=0x4010) self.dev = usb.core.find(idVendor=0xcafe, idProduct=0x4010)
if self.dev is None: if self.dev is None:
@ -35,9 +36,11 @@ class ice40_flasher:
self.dev.write(0x01, data) self.dev.write(0x01, data)
def _read(self, request_id: int, length: int) -> bytes: def _read(self, request_id: int, length: int) -> bytes:
# ctrl_transfer(self, bmRequestType, bRequest, wValue=0, wIndex=0, data_or_wLength = None, timeout = None): # ctrl_transfer(self, bmRequestType, bRequest, wValue=0,
# wIndex=0, data_or_wLength = None, timeout = None):
# Request type: # Request type:
# bit 7: direction 0:host to device (OUT), 1: device to host (IN) # bit 7: direction 0:host to device (OUT),
# 1: device to host (IN)
# bits 5-6: type: 0:standard 1:class 2:vendor 3:reserved # bits 5-6: type: 0:standard 1:class 2:vendor 3:reserved
# bits 0-4: recipient: 0:device 1:interface 2:endpoint 3:other # bits 0-4: recipient: 0:device 1:interface 2:endpoint 3:other
ret = self.dev.ctrl_transfer(0xC0, request_id, 0, 0, length) ret = self.dev.ctrl_transfer(0xC0, request_id, 0, 0, length)
@ -58,9 +61,12 @@ class ice40_flasher:
# self._write_bulk(self.FLASHER_REQUEST_PIN_DIRECTION_SET, msg) # self._write_bulk(self.FLASHER_REQUEST_PIN_DIRECTION_SET, msg)
self._write(self.FLASHER_REQUEST_PIN_DIRECTION_SET, msg) self._write(self.FLASHER_REQUEST_PIN_DIRECTION_SET, msg)
def gpio_set_pulls(self, pin: int, pullup: bool, pulldown: bool) -> None: def gpio_set_pulls(
""" True: Enable pullup/pulldown, False: Disable pullup/pulldown """ self,
"""Configure the pullup and pulldown resistors for a single GPIO pin pin: int,
pullup: bool,
pulldown: bool) -> None:
"""Configure the pullup/down resistors for a single GPIO pin
Keyword arguments: Keyword arguments:
pin -- GPIO pin number pin -- GPIO pin number
@ -137,7 +143,8 @@ class ice40_flasher:
"""Bitbang a SPI transfer """Bitbang a SPI transfer
Keyword arguments: Keyword arguments:
buf -- Byte buffer to send. If the bit_count is smaller than the buffer size, some data will not be sent. buf -- Byte buffer to send. If the bit_count is smaller than
the buffer size, some data will not be sent.
toggle_cs: (Optional) If true, toggle the CS line toggle_cs: (Optional) If true, toggle the CS line
""" """
@ -160,12 +167,12 @@ class ice40_flasher:
toggle_cs: bool = True) -> bytes: toggle_cs: bool = True) -> bytes:
"""Bitbang a SPI transfer using the specificed GPIO pins """Bitbang a SPI transfer using the specificed GPIO pins
Note that this command does not handle setting a CS pin, that must be accomplished
separately, for instance by calling gpio_set() on the pin controlling the CS line.
Keyword arguments: Keyword arguments:
buf -- Byte buffer to send. If the bit_count is smaller than the buffer size, some data will not be sent. buf -- Byte buffer to send. If the bit_count is smaller than
bit_count -- (Optional) Number of bits (not bytes) to bitbang. If left unspecificed, defaults to the size of buf. the buffer size, some data will not be sent.
bit_count -- (Optional) Number of bits (not bytes) to
bitbang. If left unspecificed, defaults to the size
of buf.
toggle_cs: (Optional) If true, toggle the CS line toggle_cs: (Optional) If true, toggle the CS line
""" """
if bit_count == -1: if bit_count == -1:
@ -174,12 +181,13 @@ class ice40_flasher:
byte_length = (bit_count + 7) // 8 byte_length = (bit_count + 7) // 8
if byte_length > (1024 - 8): if byte_length > (1024 - 8):
print('Message too large, bit_count:{:}'.format(bit_count)) print(
'Message too large, bit_count:{:}'.format(bit_count))
exit(1) exit(1)
if byte_length != len(buf): if byte_length != len(buf):
print( print(
'Bit count size mismatch, bit_count:{:} len(buf):{:}'.format( 'Size mismatch, bit_count:{:} len(buf):{:}'.format(
bit_count, len(buf) * 8)) bit_count, len(buf) * 8))
exit(1) exit(1)
@ -205,7 +213,8 @@ class ice40_flasher:
def adc_read_all(self) -> tuple[float, float, float]: def adc_read_all(self) -> tuple[float, float, float]:
"""Read the voltage values of ADC 0, 1, and 2 """Read the voltage values of ADC 0, 1, and 2
The firmware will read the values for each input multiple times, and return averaged values for each input. The firmware will read the values for each input multiple
times, and return averaged values for each input.
""" """
msg_in = self._read(self.FLASHER_REQUEST_ADC_READ, 3 * 4) msg_in = self._read(self.FLASHER_REQUEST_ADC_READ, 3 * 4)
[ch0, ch1, ch2] = struct.unpack('>III', msg_in) [ch0, ch1, ch2] = struct.unpack('>III', msg_in)