Merge remote-tracking branch 'BohdanBuinich/xvf3510-rpi5-compatibility' into fix/gpio

This commit is contained in:
j1nx 2024-02-10 10:36:48 +00:00
commit 75479afcfd
21 changed files with 290 additions and 185 deletions

View File

@ -136,6 +136,7 @@ endmenu
menu "Additional external python modules" menu "Additional external python modules"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adafruit-blinka/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adafruit-blinka/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adafruit-circuitpython-neopixel/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adafruit-circuitpython-neopixel/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adafruit-circuitpython-typing/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adafruit-platformdetect/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adafruit-platformdetect/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adafruit-pureio/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adafruit-pureio/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adapt-parser/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-adapt-parser/Config.in"
@ -173,6 +174,7 @@ menu "Additional external python modules"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-google-auth-httplib2/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-google-auth-httplib2/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-google-auth/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-google-auth/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-google-trans-new/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-google-trans-new/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-gpiod/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-gpsdclient/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-gpsdclient/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-gtts/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-gtts/Config.in"
source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-gtts_token/Config.in" source "$BR2_EXTERNAL_OPENVOICEOS_PATH/package/python-gtts_token/Config.in"

View File

@ -333,3 +333,5 @@ BR2_PACKAGE_USERLAND_TOOLS=y
BR2_PACKAGE_VOCALFUSION=y BR2_PACKAGE_VOCALFUSION=y
BR2_PACKAGE_WIFI_CONNECT=y BR2_PACKAGE_WIFI_CONNECT=y
BR2_PACKAGE_PYTHON_SMBUS2=y BR2_PACKAGE_PYTHON_SMBUS2=y
BR2_PACKAGE_PYTHON_ADAFRUIT_BLINKA=y
BR2_PACKAGE_PYTHON_GPIOD=y

View File

@ -333,3 +333,5 @@ BR2_PACKAGE_USERLAND_TOOLS=y
BR2_PACKAGE_VOCALFUSION=y BR2_PACKAGE_VOCALFUSION=y
BR2_PACKAGE_WIFI_CONNECT=y BR2_PACKAGE_WIFI_CONNECT=y
BR2_PACKAGE_PYTHON_SMBUS2=y BR2_PACKAGE_PYTHON_SMBUS2=y
BR2_PACKAGE_PYTHON_ADAFRUIT_BLINKA=y
BR2_PACKAGE_PYTHON_GPIOD=y

View File

@ -1,11 +1,14 @@
config BR2_PACKAGE_PYTHON_ADAFRUIT_BLINKA config BR2_PACKAGE_PYTHON_ADAFRUIT_BLINKA
bool "python-adafruit-blinka" bool "python-adafruit-blinka"
select BR2_PACKAGE_PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING # runtime select BR2_PACKAGE_PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING
select BR2_PACKAGE_PYTHON_ADAFRUIT_PLATFORMDETECT # runtime select BR2_PACKAGE_PYTHON_ADAFRUIT_PLATFORMDETECT
select BR2_PACKAGE_PYTHON_ADAFRUIT_PUREIO # runtime select BR2_PACKAGE_PYTHON_ADAFRUIT_PUREIO
select BR2_PACKAGE_PYTHON_PYFTDI # runtime select BR2_PACKAGE_PYTHON_PYFTDI
select BR2_PACKAGE_PYTHON_RPI_GPIO
select BR2_PACKAGE_PYTHON_SYSV_IPC
select BR2_PACKAGE_PYTHON_GPIOD
help help
CircuitPython APIs for non-CircuitPython versions of Python CircuitPython APIs for non-CircuitPython versions of Python such as
such as CPython on Linux and MicroPython. CPython on Linux and MicroPython.
https://github.com/adafruit/Adafruit_Blinka https://pypi.org/project/Adafruit-Blinka

View File

@ -1,5 +1,5 @@
# md5, sha256 from https://pypi.org/pypi/adafruit-blinka/json # md5, sha256 from https://pypi.org/pypi/adafruit-blinka/json
md5 b15a11eb7e0910af0d5825ed386b71d6 Adafruit-Blinka-8.6.0.tar.gz md5 835cabd601befbe78dc64720f7efacd6 Adafruit-Blinka-8.31.0.tar.gz
sha256 b05f03468edc898aa07af59bafa88ca78e1b50f7d263a53e6573ace0050f64eb Adafruit-Blinka-8.6.0.tar.gz sha256 720edca821066022e912dffcb364ea04bd3e3f208132b975876a21b2a2daa850 Adafruit-Blinka-8.31.0.tar.gz
# Locally computed sha256 checksums # Locally computed sha256 checksums
sha256 50e0c3b5b4486be0ed420639f8a1f6f115f29101feee6bcd954a4b81db04d0f3 LICENSE sha256 50e0c3b5b4486be0ed420639f8a1f6f115f29101feee6bcd954a4b81db04d0f3 LICENSE

View File

@ -4,11 +4,13 @@
# #
################################################################################ ################################################################################
PYTHON_ADAFRUIT_BLINKA_VERSION = 8.6.0 PYTHON_ADAFRUIT_BLINKA_VERSION = 8.31.0
PYTHON_ADAFRUIT_BLINKA_SOURCE = Adafruit-Blinka-$(PYTHON_ADAFRUIT_BLINKA_VERSION).tar.gz PYTHON_ADAFRUIT_BLINKA_SOURCE = Adafruit-Blinka-$(PYTHON_ADAFRUIT_BLINKA_VERSION).tar.gz
PYTHON_ADAFRUIT_BLINKA_SITE = https://files.pythonhosted.org/packages/76/29/541a6a22d923fbe0d4cf52f953a2c737370cb717f8df1cbd95ab97fe2fba PYTHON_ADAFRUIT_BLINKA_SITE = https://files.pythonhosted.org/packages/74/ed/e51689be726338ba16f2a88373ad4690702c5ddf8668be1b0289cb279840
PYTHON_ADAFRUIT_BLINKA_SETUP_TYPE = setuptools PYTHON_ADAFRUIT_BLINKA_SETUP_TYPE = setuptools
PYTHON_ADAFRUIT_BLINKA_LICENSE = MIT PYTHON_ADAFRUIT_BLINKA_LICENSE = MIT
PYTHON_ADAFRUIT_BLINKA_LICENSE_FILES = LICENSE PYTHON_ADAFRUIT_BLINKA_LICENSE_FILES = LICENSE
PYTHON_ADAFRUIT_BLINKA_BIN_ARCH_EXCLUDE = usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages/adafruit_blinka/microcontroller/bcm283x/pulseio
PYTHON_ADAFRUIT_BLINKA_BIN_ARCH_EXCLUDE += usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages/adafruit_blinka/microcontroller/amlogic/a311d/pulseio
$(eval $(python-package)) $(eval $(python-package))

View File

@ -0,0 +1,6 @@
config BR2_PACKAGE_PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING
bool "python-adafruit-circuitpython-typing"
help
Types needed for type annotation that are not in `typing`
https://pypi.org/project/adafruit-circuitpython-typing

View File

@ -0,0 +1,5 @@
# md5, sha256 from https://pypi.org/pypi/adafruit-circuitpython-typing/json
md5 3ff67f52cdb0ece5df86a477b1be5572 adafruit-circuitpython-typing-1.9.6.tar.gz
sha256 dc69ed6362dcb890f7103d4da0db94b7d1849bc66804598d34508f413724d152 adafruit-circuitpython-typing-1.9.6.tar.gz
# Locally computed sha256 checksums
sha256 50e0c3b5b4486be0ed420639f8a1f6f115f29101feee6bcd954a4b81db04d0f3 LICENSE

View File

@ -0,0 +1,14 @@
################################################################################
#
# python-adafruit-circuitpython-typing
#
################################################################################
PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING_VERSION = 1.9.6
PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING_SOURCE = adafruit-circuitpython-typing-$(PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING_VERSION).tar.gz
PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING_SITE = https://files.pythonhosted.org/packages/c7/2e/acfeeed27e42cfcb0450bc4afe0746e4d8ddd5d9081b7d7cec01705149e1
PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING_SETUP_TYPE = setuptools
PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING_LICENSE = MIT
PYTHON_ADAFRUIT_CIRCUITPYTHON_TYPING_LICENSE_FILES = LICENSE LICENSES/CC-BY-4.0.txt LICENSES/MIT.txt LICENSES/Unlicense.txt
$(eval $(python-package))

View File

@ -1,5 +1,5 @@
# md5, sha256 from https://pypi.org/pypi/Adafruit-PlatformDetect/json # md5, sha256 from https://pypi.org/pypi/Adafruit-PlatformDetect/json
md5 7e7b10a48f6e6a7c650bb6bd432ec613 Adafruit-PlatformDetect-3.32.0.tar.gz md5 4e80a7d7200a67d4528d580b16d3ca98 Adafruit-PlatformDetect-3.60.0.tar.gz
sha256 31bad17fb91c3cd61bd62fb9712902bcef5225bbeb3c078a196c6d7e2d4599a4 Adafruit-PlatformDetect-3.32.0.tar.gz sha256 644deb113c00ba1bfba4703fcd80cab52b5638d4a1146f2d58378df4af09746f Adafruit-PlatformDetect-3.60.0.tar.gz
# Locally computed sha256 checksums # Locally computed sha256 checksums
sha256 50e0c3b5b4486be0ed420639f8a1f6f115f29101feee6bcd954a4b81db04d0f3 LICENSE sha256 50e0c3b5b4486be0ed420639f8a1f6f115f29101feee6bcd954a4b81db04d0f3 LICENSE

View File

@ -4,9 +4,9 @@
# #
################################################################################ ################################################################################
PYTHON_ADAFRUIT_PLATFORMDETECT_VERSION = 3.32.0 PYTHON_ADAFRUIT_PLATFORMDETECT_VERSION = 3.60.0
PYTHON_ADAFRUIT_PLATFORMDETECT_SOURCE = Adafruit-PlatformDetect-$(PYTHON_ADAFRUIT_PLATFORMDETECT_VERSION).tar.gz PYTHON_ADAFRUIT_PLATFORMDETECT_SOURCE = Adafruit-PlatformDetect-$(PYTHON_ADAFRUIT_PLATFORMDETECT_VERSION).tar.gz
PYTHON_ADAFRUIT_PLATFORMDETECT_SITE = https://files.pythonhosted.org/packages/15/42/2192f64a9732878ddb39bb4359864d1398849e90f39f5591a23005e65d8e PYTHON_ADAFRUIT_PLATFORMDETECT_SITE = https://files.pythonhosted.org/packages/e5/e3/71ba7ff4cbcecf40783613c192bd0ec6c69a70053915567a998ce41050bc
PYTHON_ADAFRUIT_PLATFORMDETECT_SETUP_TYPE = setuptools PYTHON_ADAFRUIT_PLATFORMDETECT_SETUP_TYPE = setuptools
PYTHON_ADAFRUIT_PLATFORMDETECT_LICENSE = MIT PYTHON_ADAFRUIT_PLATFORMDETECT_LICENSE = MIT
PYTHON_ADAFRUIT_PLATFORMDETECT_LICENSE_FILES = LICENSE PYTHON_ADAFRUIT_PLATFORMDETECT_LICENSE_FILES = LICENSE

View File

@ -1,5 +1,5 @@
# md5, sha256 from https://pypi.org/pypi/Adafruit-PureIO/json # md5, sha256 from https://pypi.org/pypi/Adafruit-PureIO/json
md5 f7d2f93db567333321b4097b4858bea5 Adafruit_PureIO-1.1.9.tar.gz md5 f9ddf83f2166ce69522a25f82d1fcdf7 Adafruit_PureIO-1.1.11.tar.gz
sha256 2caf22fb07c7f771d83267f331a76cde314723f884a9570ea6f768730c87a879 Adafruit_PureIO-1.1.9.tar.gz sha256 c4cfbb365731942d1f1092a116f47dfdae0aef18c5b27f1072b5824ad5ea8c7c Adafruit_PureIO-1.1.11.tar.gz
# Locally computed sha256 checksums # Locally computed sha256 checksums
sha256 aa5e54136c840ed2e333f65d43fecbc6c0e8fff62ebaece4ff281cd2a6672088 LICENSE sha256 aa5e54136c840ed2e333f65d43fecbc6c0e8fff62ebaece4ff281cd2a6672088 LICENSE

View File

@ -4,9 +4,9 @@
# #
################################################################################ ################################################################################
PYTHON_ADAFRUIT_PUREIO_VERSION = 1.1.9 PYTHON_ADAFRUIT_PUREIO_VERSION = 1.1.11
PYTHON_ADAFRUIT_PUREIO_SOURCE = Adafruit_PureIO-$(PYTHON_ADAFRUIT_PUREIO_VERSION).tar.gz PYTHON_ADAFRUIT_PUREIO_SOURCE = Adafruit_PureIO-$(PYTHON_ADAFRUIT_PUREIO_VERSION).tar.gz
PYTHON_ADAFRUIT_PUREIO_SITE = https://files.pythonhosted.org/packages/df/ca/9162d4648669d12af16d5a66d808bdef6967eb684cbed9b1a3ebc19b361a PYTHON_ADAFRUIT_PUREIO_SITE = https://files.pythonhosted.org/packages/e5/b7/f1672435116822079bbdab42163f9e6424769b7db778873d95d18c085230
PYTHON_ADAFRUIT_PUREIO_SETUP_TYPE = setuptools PYTHON_ADAFRUIT_PUREIO_SETUP_TYPE = setuptools
PYTHON_ADAFRUIT_PUREIO_LICENSE = MIT PYTHON_ADAFRUIT_PUREIO_LICENSE = MIT
PYTHON_ADAFRUIT_PUREIO_LICENSE_FILES = LICENSE PYTHON_ADAFRUIT_PUREIO_LICENSE_FILES = LICENSE

View File

@ -0,0 +1,14 @@
config BR2_PACKAGE_PYTHON_GPIOD
bool "python-gpiod"
depends on !BR2_PACKAGE_LIBGPIOD
help
This is a C library that abstracts the GPIO character
device operations on linux.
https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/
This package is the continuation of the libgpiod package
for versions 2.0 and above.
Note that a kernel of 5.10 or above is required for the
ioctls to work.

View File

@ -0,0 +1,5 @@
# md5, sha256 from https://pypi.org/pypi/gpiod/json
md5 faf8736f9584a28426e4832fe22f38f4 gpiod-2.1.3.tar.gz
sha256 a33193d6cab79d252329f71666a35a3668e04f1f82bf9b93ee2c9ae852398b20 gpiod-2.1.3.tar.gz
# Locally computed sha256 checksums
sha256 50e0c3b5b4486be0ed420639f8a1f6f115f29101feee6bcd954a4b81db04d0f3 LICENSE

View File

@ -0,0 +1,13 @@
################################################################################
#
# python-gpiod
#
################################################################################
PYTHON_GPIOD_VERSION = 2.1.3
PYTHON_GPIOD_SOURCE = gpiod-$(PYTHON_GPIOD_VERSION).tar.gz
PYTHON_GPIOD_SITE = https://files.pythonhosted.org/packages/a8/56/730573fe8d03c4d32a31e7182d27317b0cef298c9170b5a2994e2248986f
PYTHON_GPIOD_SETUP_TYPE = setuptools
#PYTHON_LIBGPIOD_DEPENDENCIES = libgpiod
$(eval $(python-package))

View File

@ -1,5 +1,5 @@
# md5, sha256 from https://pypi.org/pypi/pyftdi/json # md5, sha256 from https://pypi.org/pypi/pyftdi/json
md5 d8969beb9cd11c123f1249963bf8c0d8 pyftdi-0.54.0.tar.gz md5 fa9feda5b80db51d538ed9b98e25504e pyftdi-0.55.0.tar.gz
sha256 8df9af22077d17533d2f95b508b1d87959877627ea5dc2369056e90a3b5a232d pyftdi-0.54.0.tar.gz sha256 a747bbbccc4eeea26cefa2c8bd3d2b8bef8c94ecb6969bb9c75a63640887519a pyftdi-0.55.0.tar.gz
# Locally computed sha256 checksums # Locally computed sha256 checksums
sha256 7342c9ccf3ec21eee9a23c6c74af15fb08ac1b79ddbccb4e063ddeaa6ef7c52d pyftdi/doc/license.rst sha256 7342c9ccf3ec21eee9a23c6c74af15fb08ac1b79ddbccb4e063ddeaa6ef7c52d pyftdi/doc/license.rst

View File

@ -4,9 +4,9 @@
# #
################################################################################ ################################################################################
PYTHON_PYFTDI_VERSION = 0.54.0 PYTHON_PYFTDI_VERSION = 0.55.0
PYTHON_PYFTDI_SOURCE = pyftdi-$(PYTHON_PYFTDI_VERSION).tar.gz PYTHON_PYFTDI_SOURCE = pyftdi-$(PYTHON_PYFTDI_VERSION).tar.gz
PYTHON_PYFTDI_SITE = https://files.pythonhosted.org/packages/49/a3/6cd09c0493662b285b2ba87a08b1378a5b13e5cab44eb6a3f740c801c804 PYTHON_PYFTDI_SITE = https://files.pythonhosted.org/packages/da/db/b900789a154e32dba50f132a2a76837331801f8b521b7e1bcbb852b01a35
PYTHON_PYFTDI_SETUP_TYPE = setuptools PYTHON_PYFTDI_SETUP_TYPE = setuptools
PYTHON_PYFTDI_LICENSE = FIXME: please specify the exact BSD version PYTHON_PYFTDI_LICENSE = FIXME: please specify the exact BSD version
PYTHON_PYFTDI_LICENSE_FILES = pyftdi/doc/license.rst PYTHON_PYFTDI_LICENSE_FILES = pyftdi/doc/license.rst

View File

@ -1,5 +1,5 @@
# md5, sha256 from https://pypi.org/pypi/smbus2/json # md5, sha256 from https://pypi.org/pypi/smbus2/json
md5 ea4bba25b43863aecd6ec33b2252fdae smbus2-0.4.1.tar.gz md5 ab83d83e9eb3bd1d0bef8d6fd64b1398 smbus2-0.4.3.tar.gz
sha256 6276eb599b76c4e74372f2582d2282f03b4398f0da16bc996608e4f21557ca9b smbus2-0.4.1.tar.gz sha256 36f2288a8e1a363cb7a7b2244ec98d880eb5a728a2494ac9c71e9de7bf6a803a smbus2-0.4.3.tar.gz
# Locally computed sha256 checksums # Locally computed sha256 checksums
sha256 6ee9cf18c3a75dd76fb549a4b607ae34eedc31a796c48157895e2ad28d66ce79 LICENSE sha256 6ee9cf18c3a75dd76fb549a4b607ae34eedc31a796c48157895e2ad28d66ce79 LICENSE

View File

@ -4,9 +4,9 @@
# #
################################################################################ ################################################################################
PYTHON_SMBUS2_VERSION = 0.4.1 PYTHON_SMBUS2_VERSION = 0.4.3
PYTHON_SMBUS2_SOURCE = smbus2-$(PYTHON_SMBUS2_VERSION).tar.gz PYTHON_SMBUS2_SOURCE = smbus2-$(PYTHON_SMBUS2_VERSION).tar.gz
PYTHON_SMBUS2_SITE = https://files.pythonhosted.org/packages/d9/33/787448c69603eec96af07d36f7ae3a7e3fce4020632eddb55152dc903233 PYTHON_SMBUS2_SITE = https://files.pythonhosted.org/packages/98/17/9663936e52a348b3ad1c85e6ca6071d2abf00a5f64f2df50bec8dcca6e16
PYTHON_SMBUS2_SETUP_TYPE = setuptools PYTHON_SMBUS2_SETUP_TYPE = setuptools
PYTHON_SMBUS2_LICENSE = MIT PYTHON_SMBUS2_LICENSE = MIT
PYTHON_SMBUS2_LICENSE_FILES = LICENSE PYTHON_SMBUS2_LICENSE_FILES = LICENSE

View File

@ -3,146 +3,196 @@
# requires dtparam=spi=on in /boot/config.txt # requires dtparam=spi=on in /boot/config.txt
""" """
This script configures the XVF3510 board in boot from SPI slave and load a This script configures the XVF3510 board to boot from SPI slave and loads a
binary file. It requires a bin file as input parameter. binary file. It requires a bin file as an input parameter.
""" """
import sys import sys
import os
import time import time
import argparse import argparse
import spidev from smbus2 import SMBus
import RPi.GPIO as GPIO import digitalio
from smbus import SMBus import busio
from pathlib import Path from pathlib import Path
import board
from typing import Optional
if sys.version[0] != '3': # Global variables for GPIO pins
print("Run this script with Python 3") BOOT_SEL_PIN = digitalio.DigitalInOut(board.D26) # GPIO pin used for boot selection (PIN 37)
RST_N_PIN = digitalio.DigitalInOut(board.D27) # GPIO pin used for reset (PIN 13)
I2C_ADDRESS = 0x2C # I2C address for the I/O expander. TODO: 0x20 was in original code, misstake?
if sys.version_info[0] < 3:
print("This script requires Python 3.")
sys.exit(1) sys.exit(1)
def bit_reversed_byte(byte_to_reverse): def bit_reversed_byte(byte_to_reverse: int) -> int:
""" """
Function to reverse the bit-order of a byte Reverse the bits of a byte.
Args: Args:
byte_to_reverse: byte to process byte_to_reverse (int): The byte to reverse.
Retruns:
byte in reversed order
"""
return int('{:08b}'.format(byte_to_reverse)[::-1], 2)
def set_boot_sel():
"""
Function to set XVF3510 board in SPI slave boot mode
Args:
None
Returns: Returns:
None int: The reversed byte.
""" """
return int("{:08b}".format(byte_to_reverse)[::-1], 2)
bus = SMBus(1)
# reset BOOT_SEL def set_boot_sel() -> None:
bus.write_byte_data(0x20, 3, 0xFE) """
bus.write_byte_data(0x20, 7, 0xFF) Set XVF3510 board in SPI slave boot mode using I2C to manipulate BOOT_SEL pin.
"""
try:
with SMBus(1) as bus:
# Reset BOOT_SEL to default
bus.write_byte_data(I2C_ADDRESS, 3, 0xFE)
bus.write_byte_data(I2C_ADDRESS, 7, 0xFF)
state = {} # Preserve other settings while manipulating BOOT_SEL
state = {i: bus.read_byte_data(I2C_ADDRESS, i) for i in [2, 6]}
# Start reset sequence
for i in [2, 6]: for i in [2, 6]:
state[i] = bus.read_byte_data(0x20, i) bus.write_byte_data(I2C_ADDRESS, i, 0x00 | (state[i] & 0xDF))
# Set BOOT_SEL high
# start reset bus.write_byte_data(I2C_ADDRESS, 3, 0x01)
data_to_write = 0x00 | (state[2] & 0xDF) bus.write_byte_data(I2C_ADDRESS, 7, 0xFE)
bus.write_byte_data(0x20, 2, data_to_write) # End reset sequence
data_to_write = 0x00 | (state[6] & 0xDF) for i in [2, 6]:
bus.write_byte_data(0x20, 6, data_to_write) bus.write_byte_data(I2C_ADDRESS, i, 0x20 | (state[i] & 0xDF))
# set BOOT_SEL high except Exception as e:
data_to_write = 0x01 print(f"Error setting BOOT_SEL via I2C: {e}")
bus.write_byte_data(0x20, 3, data_to_write) sys.exit(1)
data_to_write = 0xFE
bus.write_byte_data(0x20, 7, data_to_write)
# stop reset
data_to_write = 0x20 | (state[2] & 0xDF)
bus.write_byte_data(0x20, 2, data_to_write)
data_to_write = 0x20 | (state[6] & 0xDF)
bus.write_byte_data(0x20, 6, data_to_write)
def send_image(
def send_image(bin_filename, verbose=False, max_spi_speed_mhz = 5, block_transfer_pause_ms = 1, direct = False, delay = False): bin_filename: str,
verbose: bool = False,
max_spi_speed_mhz: float = 5,
block_transfer_pause_ms: float = 1,
direct: bool = False,
delay: bool = False,
) -> None:
""" """
Function to send the given image to the device via SPI slave Send the given image to the device via SPI slave.
Args: Args:
bin_filename: binary file containing the image to boot bin_filename (str): Binary file name.
verbose: flag to print debug printouts verbose (bool, optional): Enable verbose output. Defaults to False.
direct: Use Pi GPIO outputs rather than the XVF3510 Pi HAT max_spi_speed_mhz (float, optional): Max SPI speed in MHz. Defaults to 5.
delay: Release BootSel early to delay startup on version 4.0.0 onwards block_transfer_pause_ms (float, optional): Pause between blocks in milliseconds. Defaults to 1.
direct (bool, optional): Direct mode flag. Defaults to False.
Returns: delay (bool, optional): Delay startup flag. Defaults to False.
None
""" """
binary_size = Path(bin_filename).stat().st_size
print(f'Read file "{bin_filename}" size: {binary_size} Bytes')
if direct: if direct:
#setup GPIO BOOT_SEL_PIN.switch_to_input()
GPIO.setmode(GPIO.BOARD) RST_N_PIN.switch_to_output(value=True)
GPIO.setwarnings(False)
#boot_sel = 8 spi = setup_spi(max_spi_speed_mhz)
#rst_n = 10
'''
Mycroft board update
'''
#GPIO.setmode(GPIO.BCM)
boot_sel = 37 #26 #= 25 # fix these numbers to be Wiring Pi
rst_n = 13 #27 #= 2
GPIO.setup(boot_sel, GPIO.IN) # Normally, the Pi should not drive this
GPIO.setup(rst_n, GPIO.OUT, initial=GPIO.HIGH)
#setup SPI
spi = spidev.SpiDev()
bus_spi = 0
device = 0
spi.open(bus_spi, device)
#SPI Settings
spi.max_speed_hz = int(max_spi_speed_mhz * 1000000)
spi.mode = 0b00 #XMOS supports 00 or 11
spi_block_size = 4096 #Limitation in spidev and xfer2 doesn't work!
if direct: if direct:
GPIO.output(rst_n, 0) RST_N_PIN.value=False
GPIO.setup(boot_sel, GPIO.OUT, initial=GPIO.HIGH) BOOT_SEL_PIN.switch_to_output(value=True)
GPIO.output(rst_n, 1) RST_N_PIN.value=True
else: else:
set_boot_sel() set_boot_sel()
# Create a table to map byte values to their bit-reversed values
reverse_table = [bit_reversed_byte(byte) for byte in range(256)] reverse_table = [bit_reversed_byte(byte) for byte in range(256)]
data = [] try:
with open(bin_filename, "rb") as f: with open(bin_filename, "rb") as f:
bytes_read = f.read() data = list(f.read())
data = list(bytes_read) except Exception as e:
binary_size = len(data) print(f"Error reading binary file: {e}")
block_count = 0 sys.exit(1)
print('Read file "{0}" size: {1} Bytes'.format(args.bin_filename, binary_size))
if binary_size % spi_block_size != 0:
print("Warning - binary file not a multiple of {} - {} remainder".format( \
spi_block_size, binary_size % spi_block_size))
while binary_size > 0:
block = [reverse_table[byte] for byte in data[:spi_block_size]]
del data[:spi_block_size]
binary_size = len(data)
if verbose:
print("Sending {} Bytes in block {} checksum 0x{:X}".format( \
len(block), block_count, sum(block)))
spi.xfer(block)
send_data_over_spi(data, spi, reverse_table, verbose, block_transfer_pause_ms, direct, delay)
print("Sending complete")
if direct:
# Once booted, the Pi should not need to drive boot_sel and reset
BOOT_SEL_PIN.switch_to_input()
RST_N_PIN.value=True
else:
# Reset BOOT_SEL to default state
with SMBus(1) as bus:
bus.write_byte_data(I2C_ADDRESS, 3, 0xFE)
bus.write_byte_data(I2C_ADDRESS, 7, 0xFF)
def setup_spi(max_spi_speed_mhz: float) -> busio.SPI:
"""
Set up the SPI bus.
Args:
max_spi_speed_mhz (float): Max SPI speed in MHz.
Returns:
busio.SPI: Configured SPI bus.
"""
spi = busio.SPI(board.SCLK, MOSI=board.MOSI, MISO=board.MISO)
while not spi.try_lock():
pass
spi.configure(baudrate=max_spi_speed_mhz * 1_000_000)
return spi
def send_data_over_spi(
data: list,
spi: busio.SPI,
reverse_table: list,
verbose: bool,
pause_ms: float,
direct: bool,
delay: bool,
) -> None:
"""
Send data over SPI, handling block transfers and optional delays.
Args:
data (list): Data to send.
spi (busio.SPI): Configured SPI bus.
reverse_table (list): Table of bit-reversed byte values.
verbose (bool): Enable verbose output.
pause_ms (float): Pause between blocks in milliseconds.
direct (bool): Direct mode flag.
delay (bool): Delay startup flag.
"""
spi_block_size = 4096
block_count = 0
total_data_length = len(data)
for i in range(0, total_data_length, spi_block_size):
block = [reverse_table[byte] for byte in data[i : i + spi_block_size]]
if verbose:
print(f"Sending {len(block)} Bytes in block {block_count} checksum 0x{sum(block):X}")
spi.write(block)
# Update the remaining data length after each block transfer
remaining_data_length = total_data_length - (i + len(block))
handle_block_transfer(
block_count, delay, direct, pause_ms, remaining_data_length
)
block_count += 1
def handle_block_transfer(
block_count: int, delay: bool, direct: bool, pause_ms: float, remaining_data_length: int
) -> None:
"""
Handle specifics of block transfer, including initial delays and conditional logic for direct mode.
Args:
block_count (int): Number of blocks sent.
delay (bool): Delay startup flag.
direct (bool): Direct mode flag.
pause_ms (float): Pause between blocks in milliseconds.
remaining_data_length (int): Length of remaining data to send.
"""
if block_count == 0: if block_count == 0:
# Long delay for PLL reboot # Long delay for PLL reboot
time.sleep(0.1) time.sleep(0.1)
@ -150,60 +200,47 @@ def send_image(bin_filename, verbose=False, max_spi_speed_mhz = 5, block_transfe
if delay: if delay:
# release boot_sel early to prevent startup # release boot_sel early to prevent startup
if direct: if direct:
GPIO.setup(boot_sel, GPIO.IN) # release boot_sel early to prevent startup
BOOT_SEL_PIN.switch_to_input()
else: else:
#bus = smbus.SMBus(1) # Reset BOOT_SEL to default state
bus = SMBus(1) with SMBus(1) as bus:
data_to_write = 0xFE bus.write_byte_data(I2C_ADDRESS, 3, 0xFE)
bus.write_byte_data(0x20, 3, data_to_write) bus.write_byte_data(I2C_ADDRESS, 7, 0xFF)
data_to_write = 0xFF
bus.write_byte_data(0x20, 7, data_to_write)
elif binary_size > 0:
time.sleep(block_transfer_pause_ms / 1000)
block_count += 1
print("Sending complete")
if direct:
GPIO.setup(boot_sel, GPIO.IN) # Once booted, the Pi should not need to drive boot_sel
GPIO.setup(rst_n, GPIO.OUT, initial=GPIO.HIGH) # Once booted, the Pi should not need to drive reset
#GPIO.cleanup()
else:
#bus = smbus.SMBus(1)
bus = SMBus(1)
# reset BOOT_SEL
data_to_write = 0xFE
bus.write_byte_data(0x20, 3, data_to_write)
data_to_write = 0xFF
bus.write_byte_data(0x20, 7, data_to_write)
elif remaining_data_length > 0:
time.sleep(pause_ms / 1000)
if __name__ == "__main__": if __name__ == "__main__":
start_time = time.time() parser = argparse.ArgumentParser(description="Load an image via SPI slave from an RPi")
parser = argparse.ArgumentParser(description='Load an image via SPI slave from an RPi') parser.add_argument("bin_filename", help="binary file name")
parser.add_argument('bin_filename', help='binary file name') parser.add_argument("--direct", action="store_true", help="Use direct GPIO outputs rather than the XVF3510 Development Kit Pi HAT")
parser.add_argument('--direct', action='store_true', \ parser.add_argument("--delay", action="store_true", help="Delay xvf3510 device start")
help='Use just direct GPIO outputs rather than using the XVF3510 Development Kit Pi HAT') parser.add_argument("--max-spi-speed-mhz", type=float, default=5, help="Max SPI speed in MHz")
parser.add_argument('--delay', action='store_true', \ parser.add_argument("--block-transfer-pause-ms", type=float, default=1, help="Pause between SPI transfers in milliseconds")
help='Delay xvf3510 device start. Release the BootSel pin early to prevent the XVF3510 (V4.0.0 onwards) from starting with the default I2S configuration. This gives AP a chance to configure and start the XVF3510 device.') parser.add_argument("--verbose", action="store_true", help="Print debug information")
parser.add_argument('--max-spi-speed-mhz', type=float, default=5, \
help='Max SPI speed in MHz')
parser.add_argument('--block-transfer-pause-ms', type=float, default=1, \
help='pause between SPI transfers in milliseconds, default 1ms')
parser.add_argument('--verbose', action='store_true', \
help='print debug information')
args = parser.parse_args() args = parser.parse_args()
if not Path(args.bin_filename).is_file(): bin_path = Path(args.bin_filename)
print("Error: input file {} not found".format(args.bin_filename)) if not bin_path.is_file():
exit(1) print(f"Error: input file {bin_path} not found")
sys.exit(1)
send_image(args.bin_filename, args.verbose, args.max_spi_speed_mhz, args.block_transfer_pause_ms, args.direct, args.delay)
start_time = time.time()
send_image(
bin_path,
args.verbose,
args.max_spi_speed_mhz,
args.block_transfer_pause_ms,
args.direct,
args.delay,
)
end_time = time.time() end_time = time.time()
BOOT_SEL_PIN.deinit()
RST_N_PIN.deinit()
if args.verbose: if args.verbose:
print("Sending image took {:.3} seconds".format(end_time - start_time)) print(f"Sending image took {end_time - start_time:.3f} seconds")