-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathoakdevtech_icepython.py
108 lines (90 loc) · 3.54 KB
/
oakdevtech_icepython.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2023 Seth Kerr for Oak Development Technologies
#
# SPDX-License-Identifier: MIT
"""
`oakdevtech_icepython`
================================================================================
A library for programming iCE40 FPGA from Lattice Semi
* Author(s): Seth Kerr
Implementation Notes
--------------------
**Hardware:**
.. todo:: Add links to any specific hardware product page(s), or category page(s).
Use unordered list & hyperlink rST inline format: "* `Link Text <url>`_"
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://circuitpython.org/downloads
.. todo:: Uncomment or remove the Bus Device and/or the Register library dependencies
based on the library's use of either.
# * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
# * Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
"""
# imports
import time
import io
import digitalio
__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/skerr92/Oakdevtech_CircuitPython_IcePython.git"
class Oakdevtech_icepython:
"""Driver for programming Lattice Semiconductor iCE40 FPGA over SPI"""
def __init__(self, spi, chip_sel, reset, filename=None):
self._spi = spi
self._filename = filename
self._reset = digitalio.DigitalInOut(reset)
self._reset.direction = digitalio.Direction.OUTPUT
self._chip_sel = digitalio.DigitalInOut(chip_sel)
self._chip_sel.direction = digitalio.Direction.OUTPUT
self._reset.value = True
self._chip_sel.value = True
try:
self._file = io.open(filename, mode="rb") # pylint: disable=R1732
except: # pylint: disable=W0133,W0702
Exception("\nNo such file: ") # pylint: disable=W0702
finally:
print("\nfinished init...")
def set_bin_file(self, filename) -> None:
"""Change the current binary file to load"""
self._filename = filename
def reset_fpga(self) -> None:
"""Reset the FPGA"""
self._reset.value = False
time.sleep(0.1)
self._reset.value = True
def program_fpga(self) -> None:
"""
Write the binary to the FPGA.
If the file has a zero length, print an error.
Otherwise we continue with programming the FPGA.
"""
filecontents = self._file.read()
if len(filecontents) > 0:
print("in the write of my life!")
while not self._spi.try_lock():
pass
self._spi.configure(baudrate=1000000, phase=1, polarity=1)
self._reset.value = False
time.sleep(0.1)
self._chip_sel.value = False
self._reset.value = True
time.sleep(0.1)
self._chip_sel.value = True
i = 0
while i < 8:
self._spi.write(bytes(0))
i = i + 1
self._spi.write(filecontents)
self._chip_sel.value = True
i = 0
while i < 100:
self._spi.write(bytes(0))
i = i + 1
self._chip_sel.value = False
temp_buf = bytearray(2)
self._spi.readinto(temp_buf)
self._spi.unlock()
else:
raise Exception( # pylint: disable=W0719
"No file contents '%d' size.." # pylint: disable=C0209
% (len(filecontents))
)