Merge branch 'main' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts into i2smic-nonint-patch-2
This commit is contained in:
commit
45dc7155b2
18 changed files with 1315 additions and 220 deletions
545
adafruit-pitft-mipi.py
Executable file
545
adafruit-pitft-mipi.py
Executable file
|
|
@ -0,0 +1,545 @@
|
|||
"""
|
||||
Adafruit PiTFT Installer Script
|
||||
(C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
|
||||
"""
|
||||
|
||||
import time
|
||||
import os
|
||||
try:
|
||||
import click
|
||||
except ImportError:
|
||||
raise RuntimeError("The library 'Click' was not found. To install, try typing: sudo pip3 install Click")
|
||||
try:
|
||||
from adafruit_shell import Shell
|
||||
except ImportError:
|
||||
raise RuntimeError("The library 'adafruit_shell' was not found. To install, try typing: sudo pip3 install adafruit-python-shell")
|
||||
|
||||
shell = Shell()
|
||||
shell.group = 'PITFT-MIPI'
|
||||
|
||||
__version__ = "1.0.0"
|
||||
|
||||
"""
|
||||
This is the main configuration. Displays should be placed in the order
|
||||
they are to appear in the menu.
|
||||
"""
|
||||
config = [
|
||||
{
|
||||
"type": "28r",
|
||||
"menulabel": "PiTFT 2.4\", 2.8\" or 3.2\" resistive (240x320)",
|
||||
"product": "2.8\" resistive, PID 1601",
|
||||
"touchscreen": {
|
||||
"identifier": "STMPE Touchscreen Calibration",
|
||||
"product": "stmpe",
|
||||
"transforms": {
|
||||
"0": "0.988809 -0.023645 0.060523 -0.028817 1.003935 0.034176 0 0 1",
|
||||
"90": "0.014773 -1.132874 1.033662 1.118701 0.009656 -0.065273 0 0 1",
|
||||
"180": "-1.115235 -0.010589 1.057967 -0.005964 -1.107968 1.025780 0 0 1",
|
||||
"270": "-0.033192 1.126869 -0.014114 -1.115846 0.006580 1.050030 0 0 1",
|
||||
},
|
||||
"calibrations": {
|
||||
"0": "4232 11 -879396 1 5786 -752768 65536",
|
||||
"90": "33 -5782 21364572 4221 35 -1006432 65536",
|
||||
"180": "-4273 61 16441290 4 -5772 21627524 65536",
|
||||
"270": "-9 5786 -784608 -4302 19 16620508 65536",
|
||||
},
|
||||
"overlay": "touch-stmpe",
|
||||
},
|
||||
"mipi_data": {
|
||||
"command_bin": "adafruit_ili9341_drm",
|
||||
"gpio": "dc-gpio=25",
|
||||
"viewport": {
|
||||
"90": "width=320,height=240",
|
||||
"180": "width=240,height=320",
|
||||
"270": "width=320,height=240",
|
||||
"0": "width=240,height=320",
|
||||
},
|
||||
},
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
},
|
||||
{
|
||||
"type": "22",
|
||||
"menulabel": "PiTFT 2.2\" no touch",
|
||||
"product": "2.2\" no touch",
|
||||
"mipi_data": {
|
||||
"command_bin": "adafruit_ili9341_drm",
|
||||
"gpio": "dc-gpio=25",
|
||||
"viewport": {
|
||||
"90": "width=320,height=240",
|
||||
"180": "width=240,height=320",
|
||||
"270": "width=320,height=240",
|
||||
"0": "width=240,height=320",
|
||||
},
|
||||
},
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
},
|
||||
{
|
||||
"type": "28c",
|
||||
"menulabel": "PiTFT 2.8\" capacitive touch",
|
||||
"product": "2.8\" capacitive, PID 1983",
|
||||
"touchscreen": {
|
||||
"identifier": "FocalTech Touchscreen Calibration",
|
||||
"product": "EP0110M09",
|
||||
"transforms": {
|
||||
"0": "-1 0 1 0 -1 1 0 0 1",
|
||||
"90": "0 1 0 -1 0 1 0 0 1",
|
||||
"180": "1 0 0 0 1 0 0 0 1",
|
||||
"270": "0 -1 1 1 0 0 0 0 1",
|
||||
},
|
||||
"calibrations": "320 65536 0 -65536 0 15728640 65536",
|
||||
"overlay": "touch-ft6236",
|
||||
},
|
||||
"mipi_data": {
|
||||
"command_bin": "adafruit_ili9341_drm",
|
||||
"gpio": "dc-gpio=25",
|
||||
"viewport": {
|
||||
"90": "width=320,height=240",
|
||||
"180": "width=240,height=320",
|
||||
"270": "width=320,height=240",
|
||||
"0": "width=240,height=320",
|
||||
},
|
||||
},
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
},
|
||||
{
|
||||
"type": "35r",
|
||||
"menulabel": "PiTFT 3.5\" resistive touch",
|
||||
"product": "3.5\" Resistive",
|
||||
"touchscreen": {
|
||||
"identifier": "STMPE Touchscreen Calibration",
|
||||
"product": "stmpe",
|
||||
"transforms": {
|
||||
"0": "-1.098388 0.003455 1.052099 0.005512 -1.093095 1.026309 0 0 1",
|
||||
"90": "-0.000087 1.094214 -0.028826 -1.091711 -0.004364 1.057821 0 0 1",
|
||||
"180": "1.102807 0.000030 -0.066352 0.001374 1.085417 -0.027208 0 0 1",
|
||||
"270": "0.003893 -1.087542 1.025913 1.084281 0.008762 -0.060700 0 0 1",
|
||||
},
|
||||
"calibrations": {
|
||||
"0": "5724 -6 -1330074 26 8427 -1034528 65536",
|
||||
"90": "5 8425 -978304 -5747 61 22119468 65536",
|
||||
"180": "-5682 -1 22069150 13 -8452 32437698 65536",
|
||||
"270": "3 -8466 32440206 5703 -1 -1308696 65536",
|
||||
},
|
||||
"overlay": "touch-stmpe",
|
||||
},
|
||||
"mipi_data": {
|
||||
"command_bin": "adafruit_hx8357_drm",
|
||||
"gpio": "dc-gpio=25",
|
||||
"viewport": {
|
||||
"90": "width=480,height=320",
|
||||
"180": "width=320,height=480",
|
||||
"270": "width=480,height=320",
|
||||
"0": "width=320,height=480",
|
||||
},
|
||||
},
|
||||
"width": 480,
|
||||
"height": 320,
|
||||
"x11_scale": 1.5,
|
||||
},
|
||||
{
|
||||
"type": "st7789_240x240",
|
||||
"menulabel": "PiTFT Mini 1.3\" or 1.54\" display",
|
||||
"product": "1.54\" or 1.3\" no touch",
|
||||
"mipi_data": {
|
||||
"command_bin": "adafruit_st7789_drm",
|
||||
"gpio": "dc-gpio=25,backlight-gpio=22",
|
||||
"viewport": {
|
||||
"0": "width=240,height=240",
|
||||
"90": "width=240,height=240,x-offset=80",
|
||||
"180": "width=240,height=240,y-offset=80",
|
||||
"270": "width=240,height=240",
|
||||
},
|
||||
},
|
||||
"width": 240,
|
||||
"height": 240,
|
||||
},
|
||||
{
|
||||
"type": "st7789_240x320",
|
||||
"menulabel": "ST7789V 2.0\" no touch",
|
||||
"product": "2.0\" no touch",
|
||||
"mipi_data": {
|
||||
"command_bin": "adafruit_st7789_drm",
|
||||
"gpio": "dc-gpio=25,backlight-gpio=22",
|
||||
"viewport": {
|
||||
"0": "width=320,height=240",
|
||||
"90": "width=240,height=320",
|
||||
"180": "width=320,height=240",
|
||||
"270": "width=240,height=320",
|
||||
},
|
||||
},
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
},
|
||||
{
|
||||
"type": "st7789_240x135",
|
||||
"menulabel": "MiniPiTFT 1.14\" display",
|
||||
"product": "1.14\" no touch",
|
||||
"mipi_data": {
|
||||
"command_bin": "adafruit_st7789_drm",
|
||||
"gpio": "dc-gpio=25,backlight-gpio=22",
|
||||
"viewport": {
|
||||
"0": "width=136,height=240,x-offset=52,y-offset=40",
|
||||
"90": "width=240,height=136,y-offset=52,x-offset=40",
|
||||
"180": "width=136,height=240,x-offset=52,y-offset=40",
|
||||
"270": "width=240,height=136,y-offset=52,x-offset=40",
|
||||
},
|
||||
},
|
||||
"width": 240,
|
||||
"height": 135,
|
||||
},
|
||||
{
|
||||
"type": "st7789v_bonnet_240x240",
|
||||
"menulabel": "TFT 1.3\" Bonnet + Joystick",
|
||||
"product": "1.3\" Joystick",
|
||||
"mipi_data": {
|
||||
"command_bin": "adafruit_st7789_drm",
|
||||
"gpio": "dc-gpio=25,backlight-gpio=22",
|
||||
"viewport": {
|
||||
"0": "width=240,height=240",
|
||||
"90": "width=240,height=240,x-offset=80",
|
||||
"180": "width=240,height=240,y-offset=80",
|
||||
"270": "width=240,height=240",
|
||||
},
|
||||
},
|
||||
"width": 240,
|
||||
"height": 240,
|
||||
},
|
||||
]
|
||||
|
||||
# default mipi data
|
||||
mipi_data = {
|
||||
"speed": 40000000,
|
||||
"spi": "spi0-0",
|
||||
}
|
||||
|
||||
PITFT_ROTATIONS = ("90", "180", "270", "0")
|
||||
UPDATE_DB = False
|
||||
SYSTEMD = None
|
||||
MIPI_MINIMUM_KERNEL = 5.15
|
||||
pitft_config = None
|
||||
pitftrot = None
|
||||
auto_reboot = None
|
||||
|
||||
def warn_exit(message):
|
||||
shell.warn(message)
|
||||
shell.exit(1)
|
||||
|
||||
def print_version(ctx, param, value):
|
||||
if not value or ctx.resilient_parsing:
|
||||
return
|
||||
print("Adafruit PiTFT Helper v{}".format(__version__))
|
||||
shell.exit(1)
|
||||
|
||||
def progress(ellipsis_count):
|
||||
for i in range(ellipsis_count):
|
||||
print("...", end='')
|
||||
time.sleep(1)
|
||||
print("")
|
||||
|
||||
def sysupdate():
|
||||
global UPDATE_DB
|
||||
if not UPDATE_DB:
|
||||
print("Updating apt indexes...", end='')
|
||||
progress(3)
|
||||
if not shell.run_command('sudo apt update', True):
|
||||
warn_exit("Apt failed to update indexes!")
|
||||
if not shell.run_command('sudo apt-get update', True):
|
||||
warn_exit("Apt failed to update indexes!")
|
||||
print("Reading package lists...")
|
||||
progress(3)
|
||||
UPDATE_DB = True
|
||||
return True
|
||||
|
||||
############################ Sub-Scripts ############################
|
||||
|
||||
def softwareinstall():
|
||||
print("Installing Pre-requisite Software...This may take a few minutes!")
|
||||
if not shell.run_command("apt-get install -y libts0", True):
|
||||
if not shell.run_command("apt-get install -y tslib"):
|
||||
if not shell.run_command("apt-get install -y libts-dev"):
|
||||
warn_exit("Apt failed to install TSLIB!")
|
||||
if not shell.run_command("apt-get install -y bc fbi git python3-dev python3-pip python3-smbus python3-spidev evtest libts-bin device-tree-compiler libraspberrypi-dev build-essential"):
|
||||
warn_exit("Apt failed to install software!")
|
||||
if not shell.run_command("pip3 install evdev"):
|
||||
warn_exit("Pip failed to install software!")
|
||||
return True
|
||||
|
||||
def uninstall_bootconfigtxt():
|
||||
"""Remove any old flexfb/fbtft stuff"""
|
||||
if shell.pattern_search("/boot/config.txt", "adafruit-pitft-helper"):
|
||||
print("Already have an adafruit-pitft-helper section in /boot/config.txt.")
|
||||
print("Removing old section...")
|
||||
shell.run_command("cp /boot/config.txt /boot/configtxt.bak")
|
||||
shell.pattern_replace("/boot/config.txt", '\n# --- added by adafruit-pitft-helper.*?\n# --- end adafruit-pitft-helper.*?\n', multi_line=True)
|
||||
return True
|
||||
def update_configtxt():
|
||||
"""update /boot/config.txt with appropriate values"""
|
||||
uninstall_bootconfigtxt()
|
||||
# Driver does not work if hdmi_force_hotplug=1 is present
|
||||
shell.pattern_replace("/boot/config.txt", "hdmi_force_hotplug=1", "hdmi_force_hotplug=0")
|
||||
display_overlay = f"dtoverlay=mipi-dbi-spi,{mipi_data['spi']},speed=40000000"
|
||||
display_overlay += f"\ndtparam=compatible={mipi_data['command_bin']}\\0panel-mipi-dbi-spi"
|
||||
viewport = ""
|
||||
if mipi_data['viewport'][pitftrot] is not None:
|
||||
viewport = mipi_data['viewport'][pitftrot]
|
||||
display_overlay += f"\ndtparam={viewport}"
|
||||
if "gpio" in mipi_data:
|
||||
display_overlay += f"\ndtparam={mipi_data['gpio']}"
|
||||
|
||||
# Touch Overlay
|
||||
touch_overlay = ""
|
||||
if "touchscreen" in pitft_config and "overlay" in pitft_config["touchscreen"]:
|
||||
# use dtc to compile and copy overlay
|
||||
touch_overlay = pitft_config["touchscreen"]["overlay"]
|
||||
shell.run_command(f"dtc -I dts -O dtb -o /boot/overlays/{touch_overlay}.dtbo overlays/{touch_overlay}.dts")
|
||||
touch_overlay = f"\ndtoverlay={touch_overlay}"
|
||||
date = shell.date()
|
||||
shell.write_text_file("/boot/config.txt", f"""
|
||||
# --- added by adafruit-pitft-helper {date} ---
|
||||
[all]
|
||||
dtparam=spi=on
|
||||
dtparam=i2c1=on
|
||||
dtparam=i2c_arm=on
|
||||
|
||||
{display_overlay}
|
||||
{touch_overlay}
|
||||
# --- end adafruit-pitft-helper {date} ---
|
||||
""")
|
||||
return True
|
||||
|
||||
def update_udev():
|
||||
shell.write_text_file("/etc/udev/rules.d/95-touchmouse.rules", """
|
||||
SUBSYSTEM=="input", ATTRS{name}=="touchmouse", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
|
||||
""", append=False)
|
||||
shell.write_text_file("/etc/udev/rules.d/95-ftcaptouch.rules", """
|
||||
SUBSYSTEM=="input", ATTRS{name}=="EP0110M09", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
|
||||
SUBSYSTEM=="input", ATTRS{name}=="generic ft5x06*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
|
||||
""", append=False)
|
||||
shell.write_text_file("/etc/udev/rules.d/95-stmpe.rules", """
|
||||
SUBSYSTEM=="input", ATTRS{name}=="*stmpe*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
|
||||
""", append=False)
|
||||
return True
|
||||
|
||||
def compile_display_fw():
|
||||
command_src = "mipi/panel.txt"
|
||||
|
||||
# We could just copy the file to panel.txt, edit that, then remove it after
|
||||
shell.copy(f"mipi/{mipi_data['command_bin']}.txt", command_src)
|
||||
|
||||
# Make sure each of the lines with "# rotation" starts with exactly 1 # and no more
|
||||
shell.pattern_replace(command_src, "^#*(.*?# rotation.*?$)", "#\\1")
|
||||
# Uncomment the one for the rotation we are going for
|
||||
shell.pattern_replace(command_src, "^#(.*?# rotation " + pitftrot + ".*?$)", "\\1")
|
||||
# Download the mipi-dbi-cmd script if it doesn't exist
|
||||
if not shell.exists("mipi-dbi-cmd"):
|
||||
shell.run_command("wget https://github.com/notro/panel-mipi-dbi/raw/main/mipi-dbi-cmd")
|
||||
shell.run_command("chmod +x mipi-dbi-cmd")
|
||||
# Run the mipi-dbi-script and output directly to the /lib/firmware folder
|
||||
shell.run_command(f"./mipi-dbi-cmd /lib/firmware/{mipi_data['command_bin']}.bin mipi/panel.txt")
|
||||
shell.remove(command_src)
|
||||
return True
|
||||
|
||||
def update_pointercal():
|
||||
if "calibrations" in pitft_config["touchscreen"]:
|
||||
if isinstance(pitft_config["touchscreen"]["calibrations"], dict):
|
||||
shell.write_text_file("/etc/pointercal", pitft_config["touchscreen"]["calibrations"][pitftrot])
|
||||
else:
|
||||
shell.write_text_file("/etc/pointercal", pitft_config["touchscreen"]["calibrations"])
|
||||
return True
|
||||
|
||||
def install_mipi():
|
||||
global mipi_data
|
||||
|
||||
if "mipi_data" in pitft_config:
|
||||
mipi_data.update(pitft_config['mipi_data'])
|
||||
if not compile_display_fw():
|
||||
shell.bail("Unable to compile MIPI firmware")
|
||||
# if there's X11 installed...
|
||||
if shell.exists("/etc/lightdm"):
|
||||
print("Setting raspi-config to boot to desktop w/o login...")
|
||||
shell.run_command("raspi-config nonint do_boot_behaviour B4")
|
||||
|
||||
# Disable overscan compensation (use full screen):
|
||||
shell.run_command("raspi-config nonint do_overscan 1")
|
||||
|
||||
shell.pattern_replace("/boot/config.txt", "^[^#]*dtoverlay=vc4-kms-v3d.*$", "#dtoverlay=vc4-kms-v3d")
|
||||
shell.pattern_replace("/boot/config.txt", "^[^#]*dtoverlay=vc4-fkms-v3d.*$", "#dtoverlay=vc4-fkms-v3d")
|
||||
|
||||
if not update_configtxt():
|
||||
shell.bail("Unable to update /boot/config.txt")
|
||||
return True
|
||||
|
||||
def update_xorg():
|
||||
if "touchscreen" in pitft_config:
|
||||
transform = "Option \"TransformationMatrix\" \"{}\"".format(pitft_config["touchscreen"]["transforms"][pitftrot])
|
||||
shell.write_text_file("/usr/share/X11/xorg.conf.d/20-calibration.conf", f"""
|
||||
Section "InputClass"
|
||||
Identifier "{pitft_config["touchscreen"]["identifier"]}"
|
||||
MatchProduct "{pitft_config["touchscreen"]["product"]}"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
Driver "libinput"
|
||||
{transform}
|
||||
EndSection
|
||||
""",
|
||||
append=False,
|
||||
)
|
||||
return True
|
||||
|
||||
def get_config_types():
|
||||
types = []
|
||||
for item in config:
|
||||
types.append(item["type"])
|
||||
return types
|
||||
|
||||
def get_config(type):
|
||||
for item in config:
|
||||
if item["type"] == type:
|
||||
return item
|
||||
return None
|
||||
|
||||
def success():
|
||||
global auto_reboot
|
||||
shell.info("Success!")
|
||||
print("""
|
||||
Settings take effect on next boot.
|
||||
""")
|
||||
if auto_reboot is None:
|
||||
auto_reboot = shell.prompt("REBOOT NOW?", default="y")
|
||||
if not auto_reboot:
|
||||
print("Exiting without reboot.")
|
||||
shell.exit()
|
||||
print("Reboot started...")
|
||||
shell.reboot()
|
||||
shell.exit()
|
||||
|
||||
####################################################### MAIN
|
||||
target_homedir = "/home/pi"
|
||||
@click.command()
|
||||
@click.option('-v', '--version', is_flag=True, callback=print_version, expose_value=False, is_eager=True, help="Print version information")
|
||||
@click.option('-u', '--user', nargs=1, default="/home/pi", type=str, help="Specify path of primary user's home directory", show_default=True)
|
||||
@click.option('--display', nargs=1, default=None, help="Specify a display option (1-{}) or type {}".format(len(config), get_config_types()))
|
||||
@click.option('--rotation', nargs=1, default=None, type=int, help="Specify a rotation option (1-4) or degrees {}".format(tuple(sorted([int(x) for x in PITFT_ROTATIONS]))))
|
||||
@click.option('--reboot', nargs=1, default=None, type=click.Choice(['yes', 'no']), help="Specify whether to reboot after the script is finished")
|
||||
def main(user, display, rotation, reboot):
|
||||
global target_homedir, pitft_config, pitftrot, auto_reboot
|
||||
shell.clear()
|
||||
if user != target_homedir:
|
||||
target_homedir = user
|
||||
print("Homedir = {}".format(target_homedir))
|
||||
|
||||
print("""This script downloads and installs
|
||||
PiTFT Support using userspace touch
|
||||
controls and a DTO for display drawing.
|
||||
one of several configuration files.
|
||||
Run time of up to 5 minutes. Reboot required!
|
||||
""")
|
||||
if reboot is not None:
|
||||
auto_reboot = reboot.lower() == 'yes'
|
||||
|
||||
# Check that the user is running the minimum kernel on this device
|
||||
if not shell.kernel_minimum(MIPI_MINIMUM_KERNEL):
|
||||
shell.warn(f"In order to continue, you will need to update your kernel to a minimum of {MIPI_MINIMUM_KERNEL}. ")
|
||||
if shell.get_os() == "Raspbian":
|
||||
shell.info("It looks like you are running this on a Raspberry Pi. You can update it to the latest version by running 'sudo rpi-update'.")
|
||||
shell.exit()
|
||||
|
||||
if display in [str(x) for x in range(1, len(config) + 1)]:
|
||||
pitft_config = config[int(display) - 1]
|
||||
print("Display Type: {}".format(pitft_config["menulabel"]))
|
||||
elif display in get_config_types():
|
||||
pitft_config = get_config(display)
|
||||
print("Display Type: {}".format(pitft_config["menulabel"]))
|
||||
else:
|
||||
# Build menu from config
|
||||
selections = []
|
||||
for item in config:
|
||||
option = "{} ({}x{})".format(item['menulabel'], item['width'], item['height'])
|
||||
selections.append(option)
|
||||
selections.append("Quit without installing")
|
||||
|
||||
PITFT_SELECT = shell.select_n("Select configuration:", selections)
|
||||
if PITFT_SELECT == len(config) + 1:
|
||||
shell.exit(1)
|
||||
pitft_config = config[PITFT_SELECT - 1]
|
||||
|
||||
if rotation is not None and 1 <= rotation <= 4:
|
||||
pitftrot = PITFT_ROTATIONS[rotation - 1]
|
||||
print("Rotation: {}".format(pitftrot))
|
||||
elif str(rotation) in PITFT_ROTATIONS:
|
||||
pitftrot = str(rotation)
|
||||
print("Rotation: {}".format(pitftrot))
|
||||
else:
|
||||
PITFT_ROTATE = shell.select_n(
|
||||
"Select rotation:", (
|
||||
"90 degrees (landscape)",
|
||||
"180 degrees (portrait)",
|
||||
"270 degrees (landscape)",
|
||||
"0 degrees (portrait)"
|
||||
))
|
||||
pitftrot = PITFT_ROTATIONS[PITFT_ROTATE - 1]
|
||||
|
||||
if 'rotations' in pitft_config and isinstance(pitft_config['rotations'], dict) and pitftrot in pitft_config['rotations'] and pitft_config['rotations'][pitftrot] is None:
|
||||
shell.bail("""Unfortunately {rotation} degrees for the {display} is not working at this time. Please
|
||||
restart the script and choose a different orientation.""".format(rotation=pitftrot, display=pitft_config["menulabel"]))
|
||||
|
||||
# check init system (technique borrowed from raspi-config):
|
||||
shell.info('Checking init system...')
|
||||
if shell.run_command("which systemctl", True) and shell.run_command("systemctl | grep '\-\.mount'", True):
|
||||
SYSTEMD = True
|
||||
print("Found systemd")
|
||||
elif os.path.isfile("/etc/init.d/cron") and not os.path.islink("/etc/init.d/cron"):
|
||||
SYSTEMD = False
|
||||
print("Found sysvinit")
|
||||
else:
|
||||
shell.bail("Unrecognised init system")
|
||||
|
||||
if shell.grep("boot", "/proc/mounts"):
|
||||
print("/boot is mounted")
|
||||
else:
|
||||
print("/boot must be mounted. if you think it's not, quit here and try: sudo mount /dev/mmcblk0p1 /boot")
|
||||
if shell.prompt("Continue?"):
|
||||
print("Proceeding.")
|
||||
else:
|
||||
shell.bail("Aborting.")
|
||||
|
||||
if not shell.isdir(target_homedir):
|
||||
shell.bail("{} must be an existing directory (use -u /home/foo to specify)".format(target_homedir))
|
||||
|
||||
shell.info("System update")
|
||||
if not sysupdate():
|
||||
shell.bail("Unable to apt-get update")
|
||||
|
||||
shell.info("Installing Python libraries & Software...")
|
||||
if not softwareinstall():
|
||||
shell.bail("Unable to install software")
|
||||
|
||||
shell.info("Adding MIPI support...")
|
||||
if not install_mipi():
|
||||
shell.bail("Unable to configure mipi")
|
||||
|
||||
shell.info("Updating /boot/config.txt...")
|
||||
if not update_configtxt():
|
||||
shell.bail("Unable to update /boot/config.txt")
|
||||
|
||||
if "touchscreen" in pitft_config:
|
||||
shell.info("Updating SysFS rules for Touchscreen...")
|
||||
if not update_udev():
|
||||
shell.bail("Unable to update /etc/udev/rules.d")
|
||||
|
||||
shell.info("Updating TSLib default calibration...")
|
||||
if not update_pointercal():
|
||||
shell.bail("Unable to update /etc/pointercal")
|
||||
|
||||
if shell.exists("/etc/lightdm"):
|
||||
shell.info("Updating X11 default calibration...")
|
||||
if not update_xorg():
|
||||
shell.bail("Unable to update calibration")
|
||||
success()
|
||||
|
||||
# Main function
|
||||
if __name__ == "__main__":
|
||||
shell.require_root()
|
||||
main()
|
||||
|
|
@ -4,10 +4,11 @@ Adafruit PiTFT Installer Script
|
|||
"""
|
||||
|
||||
import time
|
||||
import os
|
||||
try:
|
||||
import click
|
||||
except ImportError:
|
||||
raise RuntimeError("The library 'Click' was not found. To install, try typing: sudo pip3 install Click==7.0")
|
||||
raise RuntimeError("The library 'Click' was not found. To install, try typing: sudo pip3 install Click")
|
||||
try:
|
||||
from adafruit_shell import Shell
|
||||
except ImportError:
|
||||
|
|
@ -16,7 +17,7 @@ except ImportError:
|
|||
shell = Shell()
|
||||
shell.group = 'PITFT'
|
||||
|
||||
__version__ = "3.1.1"
|
||||
__version__ = "3.3.0"
|
||||
|
||||
"""
|
||||
This is the main configuration. Displays should be placed in the order
|
||||
|
|
@ -116,8 +117,8 @@ dtoverlay=pitft28-capacitive,{rotation}""",
|
|||
"product": "1.54\" or 1.3\" no touch",
|
||||
"kernel_upgrade": True,
|
||||
"overlay_src": "overlays/minipitft13-overlay.dts",
|
||||
"overlay_dest": "/boot/overlays/drm-minipitft13.dtbo",
|
||||
"overlay": "dtoverlay=drm-minipitft13,rotate={pitftrot},fps=60",
|
||||
"overlay_dest": "{boot_dir}/overlays/drm-minipitft13.dtbo",
|
||||
"overlay": "dtoverlay=drm-minipitft13,rotation={pitftrot},fps=60",
|
||||
"width": 240,
|
||||
"height": 240,
|
||||
"fbcp_rotations": {
|
||||
|
|
@ -133,7 +134,7 @@ dtoverlay=pitft28-capacitive,{rotation}""",
|
|||
"product": "2.0\" no touch",
|
||||
"kernel_upgrade": True,
|
||||
"overlay_src": "overlays/st7789v_240x320-overlay.dts",
|
||||
"overlay_dest": "/boot/overlays/drm-st7789v_240x320.dtbo",
|
||||
"overlay_dest": "{boot_dir}/overlays/drm-st7789v_240x320.dtbo",
|
||||
"overlay": "dtoverlay=drm-st7789v_240x320,rotate={pitftrot},fps=30",
|
||||
"width": 320,
|
||||
"height": 240,
|
||||
|
|
@ -144,8 +145,8 @@ dtoverlay=pitft28-capacitive,{rotation}""",
|
|||
"product": "1.14\" no touch",
|
||||
"kernel_upgrade": True,
|
||||
"overlay_src": "overlays/minipitft114-overlay.dts",
|
||||
"overlay_dest": "/boot/overlays/drm-minipitft114.dtbo",
|
||||
"overlay": "dtoverlay=drm-minipitft114,rotate={pitftrot},fps=60",
|
||||
"overlay_dest": "{boot_dir}/overlays/drm-minipitft114.dtbo",
|
||||
"overlay": "dtoverlay=drm-minipitft114,rotation={pitftrot},fps=60",
|
||||
"rotations": {
|
||||
"0": None,
|
||||
"90": "90",
|
||||
|
|
@ -167,8 +168,8 @@ dtoverlay=pitft28-capacitive,{rotation}""",
|
|||
"product": "1.3\" Joystick",
|
||||
"kernel_upgrade": True,
|
||||
"overlay_src": "overlays/tftbonnet13-overlay.dts",
|
||||
"overlay_dest": "/boot/overlays/drm-tftbonnet13.dtbo",
|
||||
"overlay": "dtoverlay=drm-tftbonnet13,rotate={pitftrot},fps=60",
|
||||
"overlay_dest": "{boot_dir}/overlays/drm-tftbonnet13.dtbo",
|
||||
"overlay": "dtoverlay=drm-tftbonnet13,rotation={pitftrot},fps=60",
|
||||
"width": 240,
|
||||
"height": 240,
|
||||
"fbcp_rotations": {
|
||||
|
|
@ -223,9 +224,9 @@ def sysupdate():
|
|||
print("Updating apt indexes...", end='')
|
||||
progress(3)
|
||||
if not shell.run_command('sudo apt update', True):
|
||||
warn_exit("Apt failed to update indexes!")
|
||||
warn_exit("Apt failed to update indexes! Try running 'sudo apt update' manually.")
|
||||
if not shell.run_command('sudo apt-get update', True):
|
||||
warn_exit("Apt failed to update indexes!")
|
||||
warn_exit("Apt failed to update indexes! Try running 'sudo apt-get update' manually.")
|
||||
print("Reading package lists...")
|
||||
progress(3)
|
||||
UPDATE_DB = True
|
||||
|
|
@ -237,7 +238,8 @@ def softwareinstall():
|
|||
print("Installing Pre-requisite Software...This may take a few minutes!")
|
||||
if not shell.run_command("apt-get install -y libts0", True):
|
||||
if not shell.run_command("apt-get install -y tslib"):
|
||||
warn_exit("Apt failed to install TSLIB!")
|
||||
if not shell.run_command("apt-get install -y libts-dev"):
|
||||
warn_exit("Apt failed to install TSLIB!")
|
||||
if not shell.run_command("apt-get install -y bc fbi git python3-dev python3-pip python3-smbus python3-spidev evtest libts-bin device-tree-compiler libraspberrypi-dev build-essential"):
|
||||
warn_exit("Apt failed to install software!")
|
||||
if not shell.run_command("pip3 install evdev"):
|
||||
|
|
@ -246,11 +248,11 @@ def softwareinstall():
|
|||
|
||||
def uninstall_bootconfigtxt():
|
||||
"""Remove any old flexfb/fbtft stuff"""
|
||||
if shell.pattern_search("/boot/config.txt", "adafruit-pitft-helper"):
|
||||
print("Already have an adafruit-pitft-helper section in /boot/config.txt.")
|
||||
if shell.pattern_search(f"{boot_dir}/config.txt", "adafruit-pitft-helper"):
|
||||
print(f"Already have an adafruit-pitft-helper section in {boot_dir}/config.txt.")
|
||||
print("Removing old section...")
|
||||
shell.run_command("cp /boot/config.txt /boot/configtxt.bak")
|
||||
shell.pattern_replace("/boot/config.txt", '\n# --- added by adafruit-pitft-helper.*?\n# --- end adafruit-pitft-helper.*?\n', multi_line=True)
|
||||
shell.run_command(f"cp {boot_dir}/config.txt {boot_dir}/configtxt.bak")
|
||||
shell.pattern_replace(f"{boot_dir}/config.txt", '\n# --- added by adafruit-pitft-helper.*?\n# --- end adafruit-pitft-helper.*?\n', multi_line=True)
|
||||
return True
|
||||
|
||||
def uninstall_etc_modules():
|
||||
|
|
@ -265,7 +267,8 @@ def install_drivers():
|
|||
"""Compile display driver and overlay if required"""
|
||||
if "overlay_src" in pitft_config and "overlay_dest" in pitft_config:
|
||||
print("Compiling Device Tree Overlay")
|
||||
shell.run_command("dtc --warning no-unit_address_vs_reg -I dts -O dtb -o {dest} {src}".format(dest=pitft_config['overlay_dest'], src=pitft_config['overlay_src']))
|
||||
destination = pitft_config['overlay_dest'].format(boot_dir=boot_dir)
|
||||
shell.run_command("dtc --warning no-unit_address_vs_reg -I dts -O dtb -o {dest} {src}".format(dest=destination, src=pitft_config['overlay_src']))
|
||||
|
||||
if pitft_config['kernel_upgrade']:
|
||||
print("############# UPGRADING KERNEL ###############")
|
||||
|
|
@ -290,7 +293,7 @@ def install_drivers():
|
|||
return True
|
||||
|
||||
def update_configtxt(rotation_override=None):
|
||||
"""update /boot/config.txt with appropriate values"""
|
||||
"""update /boot/config.txt (or equivalent folder) with appropriate values"""
|
||||
uninstall_bootconfigtxt()
|
||||
uninstall_etc_modules()
|
||||
overlay = pitft_config['overlay']
|
||||
|
|
@ -300,8 +303,9 @@ def update_configtxt(rotation_override=None):
|
|||
if "{rotation}" in overlay and isinstance(pitft_config['rotations'], dict) and pitft_config['rotations'][pitftrot] is not None:
|
||||
overlay = overlay.format(rotation=pitft_config['rotations'][pitftrot])
|
||||
|
||||
shell.write_text_file("/boot/config.txt", """
|
||||
shell.write_text_file(f"{boot_dir}/config.txt", """
|
||||
# --- added by adafruit-pitft-helper {date} ---
|
||||
[all]
|
||||
hdmi_force_hotplug=1 # required for cases when HDMI is not plugged in!
|
||||
dtparam=spi=on
|
||||
dtparam=i2c1=on
|
||||
|
|
@ -334,11 +338,11 @@ def update_pointercal():
|
|||
|
||||
def install_console():
|
||||
print("Set up main console turn on")
|
||||
if not shell.pattern_search("/boot/cmdline.txt", 'fbcon=map:10 fbcon=font:VGA8x8'):
|
||||
print("Updating /boot/cmdline.txt")
|
||||
shell.pattern_replace("/boot/cmdline.txt", "rootwait", "rootwait fbcon=map:10 fbcon=font:VGA8x8")
|
||||
if not shell.pattern_search(f"{boot_dir}/cmdline.txt", 'fbcon=map:10 fbcon=font:VGA8x8'):
|
||||
print(f"Updating {boot_dir}/cmdline.txt")
|
||||
shell.pattern_replace(f"{boot_dir}/cmdline.txt", "rootwait", "rootwait fbcon=map:10 fbcon=font:VGA8x8")
|
||||
else:
|
||||
print("/boot/cmdline.txt already updated")
|
||||
print(f"{boot_dir}/cmdline.txt already updated")
|
||||
|
||||
print("Turning off console blanking")
|
||||
|
||||
|
|
@ -364,11 +368,11 @@ def install_console():
|
|||
return True
|
||||
|
||||
def uninstall_console():
|
||||
print("Removing console fbcon map from /boot/cmdline.txt")
|
||||
shell.pattern_replace("/boot/cmdline.txt", 'rootwait fbcon=map:10 fbcon=font:VGA8x8', 'rootwait')
|
||||
print(f"Removing console fbcon map from {boot_dir}/cmdline.txt")
|
||||
shell.pattern_replace(f"{boot_dir}/cmdline.txt", 'rootwait fbcon=map:10 fbcon=font:VGA8x8', 'rootwait')
|
||||
print("Screen blanking time reset to 10 minutes")
|
||||
if shell.exists("/etc/kbd/config"):
|
||||
shell.pattern_replace("/boot/cmdline.txt", 'BLANK_TIME=0', 'BLANK_TIME=10')
|
||||
shell.pattern_replace(f"{boot_dir}/cmdline.txt", 'BLANK_TIME=0', 'BLANK_TIME=10')
|
||||
shell.pattern_replace("/etc/rc.local", '^# disable console blanking.*')
|
||||
shell.pattern_replace("/etc/rc.local", '^sudo sh -c "TERM=linux.*')
|
||||
return True
|
||||
|
|
@ -429,10 +433,11 @@ def install_fbcp():
|
|||
shell.run_command("raspi-config nonint do_overscan 1")
|
||||
# Set up HDMI parameters:
|
||||
print("Configuring boot/config.txt for forced HDMI")
|
||||
shell.reconfig("/boot/config.txt", "^.*hdmi_force_hotplug.*$", "hdmi_force_hotplug=1")
|
||||
shell.reconfig("/boot/config.txt", "^.*hdmi_group.*$", "hdmi_group=2")
|
||||
shell.reconfig("/boot/config.txt", "^.*hdmi_mode.*$", "hdmi_mode=87")
|
||||
shell.pattern_replace("/boot/config.txt", "^[^#]*dtoverlay=vc4-fkms-v3d.*$", "#dtoverlay=vc4-fkms-v3d")
|
||||
shell.reconfig(f"{boot_dir}/config.txt", "^.*hdmi_force_hotplug.*$", "hdmi_force_hotplug=1")
|
||||
shell.reconfig(f"{boot_dir}/config.txt", "^.*hdmi_group.*$", "hdmi_group=2")
|
||||
shell.reconfig(f"{boot_dir}/config.txt", "^.*hdmi_mode.*$", "hdmi_mode=87")
|
||||
shell.pattern_replace(f"{boot_dir}/config.txt", "^[^#]*dtoverlay=vc4-kms-v3d.*$", "#dtoverlay=vc4-kms-v3d")
|
||||
shell.pattern_replace(f"{boot_dir}/config.txt", "^[^#]*dtoverlay=vc4-fkms-v3d.*$", "#dtoverlay=vc4-fkms-v3d")
|
||||
|
||||
# if there's X11 installed...
|
||||
scale = 1
|
||||
|
|
@ -444,7 +449,7 @@ def install_fbcp():
|
|||
WIDTH = int(pitft_config['width'] * scale)
|
||||
HEIGHT = int(pitft_config['height'] * scale)
|
||||
|
||||
shell.reconfig("/boot/config.txt", "^.*hdmi_cvt.*$", "hdmi_cvt={} {} 60 1 0 0 0".format(WIDTH, HEIGHT))
|
||||
shell.reconfig(f"{boot_dir}/config.txt", "^.*hdmi_cvt.*$", "hdmi_cvt={} {} 60 1 0 0 0".format(WIDTH, HEIGHT))
|
||||
|
||||
try:
|
||||
default_orientation = int(list(fbcp_rotations.keys())[list(fbcp_rotations.values()).index("0")])
|
||||
|
|
@ -453,13 +458,13 @@ def install_fbcp():
|
|||
|
||||
if fbcp_rotations[pitftrot] == "0":
|
||||
# dont rotate HDMI on default orientation
|
||||
shell.reconfig("/boot/config.txt", "^.*display_hdmi_rotate.*$", "")
|
||||
shell.reconfig(f"{boot_dir}/config.txt", "^.*display_hdmi_rotate.*$", "")
|
||||
else:
|
||||
display_rotate = fbcp_rotations[pitftrot]
|
||||
shell.reconfig("/boot/config.txt", "^.*display_hdmi_rotate.*$", "display_hdmi_rotate={}".format(display_rotate))
|
||||
shell.reconfig(f"{boot_dir}/config.txt", "^.*display_hdmi_rotate.*$", "display_hdmi_rotate={}".format(display_rotate))
|
||||
# Because we rotate HDMI we have to 'unrotate' the TFT by overriding pitftrot!
|
||||
if not update_configtxt(default_orientation):
|
||||
shell.bail("Unable to update /boot/config.txt")
|
||||
shell.bail(f"Unable to update {boot_dir}/config.txt")
|
||||
return True
|
||||
|
||||
def install_fbcp_unit():
|
||||
|
|
@ -485,11 +490,12 @@ def uninstall_fbcp():
|
|||
# Set up HDMI parameters:
|
||||
shell.run_command("raspi-config nonint do_overscan 0")
|
||||
print("Configuring boot/config.txt for default HDMI")
|
||||
shell.reconfig("/boot/config.txt", "^.*hdmi_force_hotplug.*$", "hdmi_force_hotplug=0")
|
||||
shell.pattern_replace("/boot/config.txt", "^.*#.*dtoverlay=vc4-fkms-v3d.*$", "dtoverlay=vc4-fkms-v3d")
|
||||
shell.pattern_replace("/boot/config.txt", '^hdmi_group=2.*$')
|
||||
shell.pattern_replace("/boot/config.txt", '^hdmi_mode=87.*$')
|
||||
shell.pattern_replace("/boot/config.txt", '^hdmi_cvt=.*$')
|
||||
shell.reconfig(f"{boot_dir}/config.txt", "^.*hdmi_force_hotplug.*$", "hdmi_force_hotplug=0")
|
||||
shell.pattern_replace(f"{boot_dir}/config.txt", "^.*#.*dtoverlay=vc4-kms-v3d.*$", "dtoverlay=vc4-kms-v3d")
|
||||
shell.pattern_replace(f"{boot_dir}/config.txt", "^.*#.*dtoverlay=vc4-fkms-v3d.*$", "dtoverlay=vc4-fkms-v3d")
|
||||
shell.pattern_replace(f"{boot_dir}/config.txt", '^hdmi_group=2.*$')
|
||||
shell.pattern_replace(f"{boot_dir}/config.txt", '^hdmi_mode=87.*$')
|
||||
shell.pattern_replace(f"{boot_dir}/config.txt", '^hdmi_cvt=.*$')
|
||||
return True
|
||||
|
||||
def uninstall_fbcp_rclocal():
|
||||
|
|
@ -556,19 +562,32 @@ Settings take effect on next boot.
|
|||
|
||||
####################################################### MAIN
|
||||
target_homedir = "/home/pi"
|
||||
username = os.environ["SUDO_USER"]
|
||||
user_homedir = os.path.expanduser(f"~{username}")
|
||||
if shell.isdir(user_homedir):
|
||||
target_homedir = user_homedir
|
||||
|
||||
boot_dir = "/boot"
|
||||
@click.command()
|
||||
@click.option('-v', '--version', is_flag=True, callback=print_version, expose_value=False, is_eager=True, help="Print version information")
|
||||
@click.option('-u', '--user', nargs=1, default="/home/pi", type=str, help="Specify path of primary user's home directory", show_default=True)
|
||||
@click.option('-u', '--user', nargs=1, default=target_homedir, type=str, help="Specify path of primary user's home directory", show_default=True)
|
||||
@click.option('--display', nargs=1, default=None, help="Specify a display option (1-{}) or type {}".format(len(config), get_config_types()))
|
||||
@click.option('--rotation', nargs=1, default=None, type=int, help="Specify a rotation option (1-4) or degrees {}".format(tuple(sorted([int(x) for x in PITFT_ROTATIONS]))))
|
||||
@click.option('--install-type', nargs=1, default=None, type=click.Choice(['fbcp', 'console', 'uninstall']), help="Installation Type")
|
||||
@click.option('--reboot', nargs=1, default=None, type=click.Choice(['yes', 'no']), help="Specify whether to reboot after the script is finished")
|
||||
def main(user, display, rotation, install_type, reboot):
|
||||
global target_homedir, pitft_config, pitftrot, auto_reboot
|
||||
@click.option('--boot', nargs=1, default="/boot", type=str, help="Specify the boot directory", show_default=True)
|
||||
def main(user, display, rotation, install_type, reboot, boot):
|
||||
global target_homedir, pitft_config, pitftrot, auto_reboot, boot_dir
|
||||
shell.clear()
|
||||
if user != target_homedir:
|
||||
target_homedir = user
|
||||
print("Homedir = {}".format(target_homedir))
|
||||
print(f"Homedir = {target_homedir}")
|
||||
if boot != boot_dir:
|
||||
if shell.isdir(boot):
|
||||
boot_dir = boot
|
||||
print(f"Boot dir = {boot_dir}")
|
||||
else:
|
||||
print(f"{boot} not found or not a directory. Using {boot_dir} instead.")
|
||||
|
||||
print("""This script downloads and installs
|
||||
PiTFT Support using userspace touch
|
||||
|
|
@ -581,7 +600,7 @@ Run time of up to 5 minutes. Reboot required!
|
|||
|
||||
if install_type == "uninstall":
|
||||
uninstall()
|
||||
|
||||
|
||||
if display in [str(x) for x in range(1, len(config) + 1)]:
|
||||
pitft_config = config[int(display) - 1]
|
||||
print("Display Type: {}".format(pitft_config["menulabel"]))
|
||||
|
|
@ -674,9 +693,9 @@ restart the script and choose a different orientation.""".format(rotation=pitftr
|
|||
if not install_drivers():
|
||||
shell.bail("Unable to install display drivers")
|
||||
|
||||
shell.info("Updating /boot/config.txt...")
|
||||
shell.info(f"Updating {boot_dir}/config.txt...")
|
||||
if not update_configtxt():
|
||||
shell.bail("Unable to update /boot/config.txt")
|
||||
shell.bail(f"Unable to update {boot_dir}/config.txt")
|
||||
|
||||
if "touchscreen" in pitft_config:
|
||||
shell.info("Updating SysFS rules for Touchscreen...")
|
||||
|
|
|
|||
19
i2samp.sh
19
i2samp.sh
|
|
@ -31,10 +31,10 @@ forcesudo="no" # whether the script requires to be ran with root privileges
|
|||
promptreboot="no" # whether the script should always prompt user to reboot
|
||||
mininstall="no" # whether the script enforces minimum install routine
|
||||
customcmd="yes" # whether to execute commands specified before exit
|
||||
armhfonly="yes" # whether the script is allowed to run on other arch
|
||||
armv6="yes" # whether armv6 processors are supported
|
||||
armv7="yes" # whether armv7 processors are supported
|
||||
armv8="yes" # whether armv8 processors are supported
|
||||
arm64="yes" # whether arm64 processors are supported
|
||||
raspbianonly="no" # whether the script is allowed to run on other OSes
|
||||
osreleases=( "Raspbian" ) # list os-releases supported
|
||||
oswarning=( "Debian" "Kano" "Mate" "PiTop" "Ubuntu" ) # list experimental os-releases
|
||||
|
|
@ -139,9 +139,13 @@ sysreboot() {
|
|||
}
|
||||
|
||||
arch_check() {
|
||||
IS_ARM64=false
|
||||
IS_ARMHF=false
|
||||
IS_ARMv6=false
|
||||
|
||||
if uname -m | grep "aarch64" > /dev/null; then
|
||||
IS_ARM64=true
|
||||
fi
|
||||
if uname -m | grep "armv.l" > /dev/null; then
|
||||
IS_ARMHF=true
|
||||
if uname -m | grep "armv6l" > /dev/null; then
|
||||
|
|
@ -228,10 +232,12 @@ raspbian_check() {
|
|||
if [ -f /etc/os-release ]; then
|
||||
if cat /etc/os-release | grep "/sid" > /dev/null; then
|
||||
IS_SUPPORTED=false && IS_EXPERIMENTAL=true
|
||||
elif cat /etc/os-release | grep "bullseye" > /dev/null; then
|
||||
IS_SUPPORTED=false && IS_EXPERIMENTAL=true
|
||||
elif cat /etc/os-release | grep "buster" > /dev/null; then
|
||||
IS_SUPPORTED=false && IS_EXPERIMENTAL=true
|
||||
IS_SUPPORTED=false && IS_EXPERIMENTAL=false
|
||||
elif cat /etc/os-release | grep "stretch" > /dev/null; then
|
||||
IS_SUPPORTED=false && IS_EXPERIMENTAL=true
|
||||
IS_SUPPORTED=false && IS_EXPERIMENTAL=false
|
||||
elif cat /etc/os-release | grep "jessie" > /dev/null; then
|
||||
IS_SUPPORTED=true && IS_EXPERIMENTAL=false
|
||||
elif cat /etc/os-release | grep "wheezy" > /dev/null; then
|
||||
|
|
@ -263,13 +269,16 @@ if [ $debugmode != "no" ]; then
|
|||
newline
|
||||
fi
|
||||
|
||||
if ! $IS_ARMHF; then
|
||||
if ! $IS_ARMHF && ! $IS_ARM64; then
|
||||
warning "This hardware is not supported, sorry!"
|
||||
warning "Config files have been left untouched"
|
||||
newline && exit 1
|
||||
fi
|
||||
|
||||
if $IS_ARMv8 && [ $armv8 == "no" ]; then
|
||||
if $IS_ARM64 && [ $arm64 == "no" ]; then
|
||||
warning "Sorry, your CPU is not supported by this installer"
|
||||
newline && exit 1
|
||||
elif $IS_ARMv8 && [ $armv8 == "no" ]; then
|
||||
warning "Sorry, your CPU is not supported by this installer"
|
||||
newline && exit 1
|
||||
elif $IS_ARMv7 && [ $armv7 == "no" ]; then
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ I2S microphone support.
|
|||
print("{} detected.\n".format(pi_model))
|
||||
if pi_model in ("RASPBERRY_PI_ZERO", "RASPBERRY_PI_ZERO_W"):
|
||||
pimodel_select = 0
|
||||
elif pi_model in ("RASPBERRY_PI_2B", "RASPBERRY_PI_3B", "RASPBERRY_PI_3B_PLUS", "RASPBERRY_PI_3A_PLUS"):
|
||||
elif pi_model in ("RASPBERRY_PI_2B", "RASPBERRY_PI_3B", "RASPBERRY_PI_3B_PLUS", "RASPBERRY_PI_3A_PLUS", "RASPBERRY_PI_ZERO_2_W"):
|
||||
pimodel_select = 1
|
||||
elif pi_model in ("RASPBERRY_PI_4B", "RASPBERRY_PI_CM4"):
|
||||
elif pi_model in ("RASPBERRY_PI_4B", "RASPBERRY_PI_CM4", "RASPBERRY_PI_400"):
|
||||
pimodel_select = 2
|
||||
else:
|
||||
shell.bail("Unsupported Pi board detected.")
|
||||
|
|
|
|||
36
mipi/adafruit_hx8357_drm.txt
Normal file
36
mipi/adafruit_hx8357_drm.txt
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Adafruit HX8257 PiTFT Plus TFT LCD Screen
|
||||
# width=480,height=320
|
||||
|
||||
command 0x01 # _SWRESET and Delay 100ms
|
||||
delay 100
|
||||
|
||||
command 0xB9 0xFF 0x83 0x57 # _SETC and delay 500ms
|
||||
delay 250
|
||||
delay 250
|
||||
|
||||
command 0xB3 0x80 0x00 0x06 0x06 # _SETRGB 0x80 enables SDO pin (0x00 disables)
|
||||
command 0xB6 0x25 # _SETCOM -1.52V
|
||||
command 0xB0 0x68 # _SETOSC Normal mode 70Hz, Idle mode 55 Hz
|
||||
command 0xCC 0x05 # _SETPANEL BGR, Gate direction swapped
|
||||
command 0xB1 0x00 0x15 0x1C 0x1C 0x83 0xAA # _SETPWR1 Not deep standby BT VSPR VSNR AP
|
||||
command 0xC0 0x50 0x50 0x01 0x3C 0x1E 0x08 # _SETSTBA OPON normal OPON idle STBA GEN
|
||||
command 0xB4 0x02 0x40 0x00 0x2A 0x2A 0x0D 0x78 # _SETCYC NW 0x02 RTN DIV DUM DUM GDON GDOFF
|
||||
|
||||
# _SETGAMMA
|
||||
command 0xE0 0x02 0x0A 0x11 0x1d 0x23 0x35 0x41 0x4b 0x4b 0x42 0x3A 0x27 0x1B 0x08 0x09 0x03 0x02 0x0A 0x11 0x1d 0x23 0x35 0x41 0x4b 0x4b 0x42 0x3A 0x27 0x1B 0x08 0x09 0x03 0x00 0x01
|
||||
command 0x3A 0x55 # _COLMOD 16 bit
|
||||
|
||||
# Command 36h sets the read order from frame memory to the display panel
|
||||
# Remember to swap width/height on 90/270 rotations
|
||||
command 0x36 0x00 # rotation 0
|
||||
#command 0x36 0xA0 # rotation 90
|
||||
#command 0x36 0xC0 # rotation 180
|
||||
#command 0x36 0x60 # rotation 270
|
||||
|
||||
command 0x35 0x00 # _TEON TW off
|
||||
command 0x44 0x00 0x02 # _TEARLINE
|
||||
command 0x11 # _SLPOUT
|
||||
delay 150
|
||||
|
||||
command 0x29 # _DISPON
|
||||
delay 50
|
||||
48
mipi/adafruit_ili9341_drm.txt
Normal file
48
mipi/adafruit_ili9341_drm.txt
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Adafruit ILI9341 PiTFT TFT LCD Screen
|
||||
# width=320,height=240
|
||||
|
||||
command 0x01 # Software reset
|
||||
delay 128
|
||||
|
||||
command 0xEF 0x03 0x80 0x02
|
||||
command 0xCF 0x00 0xC1 0x30
|
||||
command 0xED 0x64 0x03 0x12 0x81
|
||||
command 0xE8 0x85 0x00 0x78
|
||||
command 0xCB 0x39 0x2C 0x00 0x34 0x02
|
||||
command 0xF7 0x20
|
||||
command 0xEA 0x00 0x00
|
||||
command 0xc0 0x23 # Power control VRH[5:0]
|
||||
command 0xc1 0x10 # Power control SAP[2:0];BT[3:0]
|
||||
command 0xc5 0x3e 0x28 # VCM control
|
||||
command 0xc7 0x86 # VCM control2
|
||||
|
||||
#define MADCTL_MY 0x80 ///< Bottom to top
|
||||
#define MADCTL_MX 0x40 ///< Right to left
|
||||
#define MADCTL_MV 0x20 ///< Reverse Mode
|
||||
#define MADCTL_ML 0x10 ///< LCD refresh Bottom to top
|
||||
#define MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order
|
||||
#define MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order
|
||||
#define MADCTL_MH 0x04 ///< LCD refresh right to left
|
||||
|
||||
# Command 36h sets the read order from frame memory to the display panel
|
||||
# Remember to swap width/height on 90/270 rotations
|
||||
command 0x36 0x88 # rotation 0
|
||||
#command 0x36 0xE8 # rotation 90
|
||||
#command 0x36 0x48 # rotation 180
|
||||
#command 0x36 0x28 # rotation 270
|
||||
|
||||
|
||||
command 0x37 0x00 # Vertical scroll zero
|
||||
command 0x3a 0x55 # COLMOD: Pixel Format Set
|
||||
command 0xb1 0x00 0x18 # Frame Rate Control (In Normal Mode/Full Colors)
|
||||
command 0xb6 0x08 0x82 0x27 # Display Function Control
|
||||
command 0xF2 0x00 # 3Gamma Function Disable
|
||||
command 0x26 0x01 # Gamma curve selected
|
||||
|
||||
# Set Gamma
|
||||
command 0xe0 0x0F 0x31 0x2B 0x0C 0x0E 0x08 0x4E 0xF1 0x37 0x07 0x10 0x03 0x0E 0x09 0x00
|
||||
command 0xe1 0x00 0x0E 0x14 0x03 0x11 0x07 0x31 0xC1 0x48 0x08 0x0F 0x0C 0x31 0x36 0x0F
|
||||
command 0x11 # Exit Sleep
|
||||
delay 120
|
||||
command 0x29 # Display on
|
||||
delay 120
|
||||
29
mipi/adafruit_st7789_drm.txt
Normal file
29
mipi/adafruit_st7789_drm.txt
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Adafruit ST7789 MiniPiTFT LCD and TFT Bonnet
|
||||
# width=240,height=240
|
||||
|
||||
command 0x01 # _SWRESET and Delay 150ms
|
||||
delay 150
|
||||
|
||||
command 0x11 # _SLPOUT and Delay 10ms
|
||||
delay 10
|
||||
|
||||
command 0x3A 0x55 # _COLMOD and Delay 10ms
|
||||
delay 10
|
||||
|
||||
command 0x36 0x08 # _MADCTL Botton->Top Refresh
|
||||
command 0x21 # _INVON Hack and Delay 10ms
|
||||
delay 10
|
||||
|
||||
command 0x13 # _NORON and Delay 10ms
|
||||
delay 10
|
||||
|
||||
# Command 36h sets the read order from frame memory to the display panel
|
||||
# Remember to swap width/height on 90/270 rotations if required
|
||||
command 0x36 0x00 # rotation 0
|
||||
#command 0x36 0xA0 # rotation 90
|
||||
#command 0x36 0xC0 # rotation 180
|
||||
#command 0x36 0x60 # rotation 270
|
||||
|
||||
command 0x29 # _DISPON and Delay 500ms
|
||||
delay 250
|
||||
delay 250
|
||||
|
|
@ -51,6 +51,7 @@
|
|||
rotate = <270>;
|
||||
width = <135>;
|
||||
height = <240>;
|
||||
txbuflen = <32768>;
|
||||
buswidth = <8>;
|
||||
dc-gpios = <&gpio 25 0>;
|
||||
led-gpios = <&gpio 26 0>;
|
||||
|
|
@ -59,7 +60,6 @@
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
__overrides__ {
|
||||
speed = <&pitft>,"spi-max-frequency:0";
|
||||
rotate = <&pitft>,"rotate:0";
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
rotate = <0>;
|
||||
width = <240>;
|
||||
height = <240>;
|
||||
txbuflen = <32768>;
|
||||
buswidth = <8>;
|
||||
dc-gpios = <&gpio 25 0>;
|
||||
led-gpios = <&gpio 26 0>;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
rotate = <0>;
|
||||
width = <240>;
|
||||
height = <320>;
|
||||
txbuflen = <32768>;
|
||||
buswidth = <8>;
|
||||
dc-gpios = <&gpio 25 0>;
|
||||
led-gpios = <&gpio 12 0>;
|
||||
|
|
|
|||
53
overlays/touch-ft6236.dts
Normal file
53
overlays/touch-ft6236.dts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Device Tree overlay for the Focaltech FT6236 capacitive
|
||||
* touch screen controller on the Adafruit PiTFT
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/ {
|
||||
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
|
||||
|
||||
fragment@0 {
|
||||
target = <&gpio>;
|
||||
__overlay__ {
|
||||
pitft_pins: pitft_pins {
|
||||
brcm,pins = <24>;
|
||||
brcm,function = <0>; /* in out */
|
||||
brcm,pull = <2>; /* pullup none */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fragment@1 {
|
||||
target = <&i2c1>;
|
||||
__overlay__ {
|
||||
/* needed to avoid dtc warning */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ft6236: ft6236@38 {
|
||||
compatible = "focaltech,ft6236";
|
||||
reg = <0x38>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pitft_pins>;
|
||||
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <24 2>;
|
||||
touchscreen-size-x = <240>;
|
||||
touchscreen-size-y = <320>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
__overrides__ {
|
||||
touch-sizex = <&ft6236>,"touchscreen-size-x?";
|
||||
touch-sizey = <&ft6236>,"touchscreen-size-y?";
|
||||
touch-invx = <&ft6236>,"touchscreen-inverted-x?";
|
||||
touch-invy = <&ft6236>,"touchscreen-inverted-y?";
|
||||
touch-swapxy = <&ft6236>,"touchscreen-swapped-x-y?";
|
||||
};
|
||||
};
|
||||
81
overlays/touch-stmpe.dts
Normal file
81
overlays/touch-stmpe.dts
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Device Tree overlay for the STMPE resistive
|
||||
* touch screen controller on the Adafruit PiTFT
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/ {
|
||||
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
|
||||
|
||||
fragment@0 {
|
||||
target = <&spi0>;
|
||||
__overlay__ {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
fragment@1 {
|
||||
target = <&spidev1>;
|
||||
__overlay__ {
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
fragment@2 {
|
||||
target = <&gpio>;
|
||||
__overlay__ {
|
||||
pitft_pins: pitft_pins {
|
||||
brcm,pins = <24>;
|
||||
brcm,function = <0>; /* in out */
|
||||
brcm,pull = <2>; /* pullup none */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fragment@3 {
|
||||
target = <&spi0>;
|
||||
__overlay__ {
|
||||
/* needed to avoid dtc warning */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pitft: pitft_ts@1 {
|
||||
compatible = "st,stmpe610";
|
||||
reg = <1>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pitft_pins>;
|
||||
|
||||
spi-max-frequency = <500000>;
|
||||
irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */
|
||||
interrupts = <24 2>; /* high-to-low edge triggered */
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupt-controller;
|
||||
|
||||
stmpe_touchscreen {
|
||||
compatible = "st,stmpe-ts";
|
||||
st,sample-time = <4>;
|
||||
st,mod-12b = <1>;
|
||||
st,ref-sel = <0>;
|
||||
st,adc-freq = <2>;
|
||||
st,ave-ctrl = <3>;
|
||||
st,touch-det-delay = <4>;
|
||||
st,settling = <2>;
|
||||
st,fraction-z = <7>;
|
||||
st,i-drive = <0>;
|
||||
};
|
||||
|
||||
stmpe_gpio: stmpe_gpio {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "st,stmpe-gpio";
|
||||
/*
|
||||
* only GPIO2 is wired/available
|
||||
* and it is wired to the backlight
|
||||
*/
|
||||
st,norequest-mask = <0x7b>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
357
pi-eyes.sh
357
pi-eyes.sh
|
|
@ -1,30 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ $(id -u) -ne 0 ]; then
|
||||
echo "Installer must be run as root."
|
||||
echo "Try 'sudo bash $0'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
clear
|
||||
|
||||
# smbus and ads1x15 Python libs are installed regardless whether ADC
|
||||
echo "This script installs software for the Adafruit"
|
||||
echo "Snake Eyes Bonnet for Raspberry Pi. Steps include:"
|
||||
echo "- Update package index files (apt-get update)"
|
||||
echo "- Install Python libraries: numpy, pi3d, svg.path,"
|
||||
echo " rpi-gpio, python3-dev, python3-pil"
|
||||
echo "- Install Adafruit eye code and data in /boot"
|
||||
echo "- Enable SPI0 and SPI1 peripherals if needed"
|
||||
echo "- Set HDMI resolution, disable overscan"
|
||||
echo "Run time ~25 minutes. Reboot required."
|
||||
echo "EXISTING INSTALLATION, IF ANY, WILL BE OVERWRITTEN."
|
||||
echo
|
||||
echo -n "CONTINUE? [y/N] "
|
||||
read
|
||||
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
|
||||
echo "Canceled."
|
||||
exit 0
|
||||
echo "Installer must be run as root."
|
||||
echo "Try 'sudo bash $0'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# FEATURE PROMPTS ----------------------------------------------------------
|
||||
|
|
@ -38,21 +17,60 @@ INSTALL_GADGET=0
|
|||
# preceded by a number (1 to N), display a prompt, check input until
|
||||
# a valid number within the selection range is entered.
|
||||
selectN() {
|
||||
for ((i=1; i<=$#; i++)); do
|
||||
echo $i. ${!i}
|
||||
done
|
||||
echo
|
||||
REPLY=""
|
||||
while :
|
||||
do
|
||||
echo -n "SELECT 1-$#: "
|
||||
read
|
||||
if [[ $REPLY -ge 1 ]] && [[ $REPLY -le $# ]]; then
|
||||
return $REPLY
|
||||
fi
|
||||
done
|
||||
for ((i=1; i<=$#; i++)); do
|
||||
echo $i. ${!i}
|
||||
done
|
||||
echo
|
||||
REPLY=""
|
||||
while :
|
||||
do
|
||||
echo -n "SELECT 1-$#: "
|
||||
read
|
||||
if [[ $REPLY -ge 1 ]] && [[ $REPLY -le $# ]]; then
|
||||
return $REPLY
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
clear
|
||||
|
||||
echo "This script installs Adafruit Snake Eyes Bonnet"
|
||||
echo "software for Raspberry Pi. It's best to dedicate"
|
||||
echo "a card to this, not for systems in regular use."
|
||||
echo
|
||||
echo "Target system (may be different than current host):"
|
||||
selectN "Raspberry Pi 4, Pi 400, or Compute Module 4" "All other models"
|
||||
#if [[ $? -eq "1" ]]; then
|
||||
if [ $? -eq "1" ]; then
|
||||
IS_PI4=1
|
||||
fi
|
||||
|
||||
if [ $IS_PI4 ]; then
|
||||
# Verify this is Raspbian Desktop OS (X11 should exist)
|
||||
if [ ! -d "/usr/bin/X11" ]; then
|
||||
echo "Target system is Pi 4/400/CM4 but this appears to"
|
||||
echo "be a \"Lite\" OS. \"Desktop\" OS is required."
|
||||
echo -n "Continue anyway? [y/N]"
|
||||
read
|
||||
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
|
||||
echo "Canceled."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Verify this is Raspbian Lite OS (X11 should NOT exist)
|
||||
if [ -d "/usr/bin/X11" ]; then
|
||||
echo "Target system is not Pi 4/400/CM4 yet this appears to"
|
||||
echo "be a \"Desktop\" OS. \"Lite\" OS (Legacy) is required."
|
||||
echo -n "Continue anyway? [y/N]"
|
||||
read
|
||||
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
|
||||
echo "Canceled."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
SCREEN_VALUES=(-o -t -i)
|
||||
SCREEN_NAMES=("OLED (128x128)" "TFT (128x128)" "IPS (240x240)" HDMI)
|
||||
RADIUS_VALUES=(128 128 240)
|
||||
|
|
@ -68,40 +86,56 @@ SCREEN_SELECT=$?
|
|||
echo -n "Install GPIO-halt utility? [y/N] "
|
||||
read
|
||||
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
|
||||
INSTALL_HALT=1
|
||||
echo -n "GPIO pin for halt: "
|
||||
read
|
||||
HALT_PIN=$REPLY
|
||||
INSTALL_HALT=1
|
||||
echo -n "GPIO pin for halt: "
|
||||
read
|
||||
HALT_PIN=$REPLY
|
||||
fi
|
||||
|
||||
echo -n "Install ADC support? [y/N] "
|
||||
echo -n "Install Bonnet ADC support? [y/N] "
|
||||
read
|
||||
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
|
||||
INSTALL_ADC=1
|
||||
INSTALL_ADC=1
|
||||
fi
|
||||
|
||||
echo -n "Install USB Ethernet gadget support? (Pi Zero) [y/N] "
|
||||
read
|
||||
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
|
||||
INSTALL_GADGET=1
|
||||
INSTALL_GADGET=1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Screen type: ${SCREEN_NAMES[$SCREEN_SELECT-1]}"
|
||||
if [ $INSTALL_HALT -eq 1 ]; then
|
||||
echo "Install GPIO-halt: YES (GPIO$HALT_PIN)"
|
||||
echo "Install GPIO-halt: YES (GPIO$HALT_PIN)"
|
||||
else
|
||||
echo "Install GPIO-halt: NO"
|
||||
echo "Install GPIO-halt: NO"
|
||||
fi
|
||||
echo "ADC support: ${OPTION_NAMES[$INSTALL_ADC]}"
|
||||
echo "Bonnet ADC support: ${OPTION_NAMES[$INSTALL_ADC]}"
|
||||
echo "Ethernet USB gadget support: ${OPTION_NAMES[$INSTALL_GADGET]}"
|
||||
if [ $SCREEN_SELECT -eq 3 ]; then
|
||||
echo "Video resolution will be set to 1280x720, no overscan"
|
||||
echo "Video resolution will be set to 1280x720, no overscan"
|
||||
else
|
||||
echo "Video resolution will be set to 640x480, no overscan"
|
||||
echo "Video resolution will be set to 640x480, no overscan"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo -n "CONTINUE? [y/N] "
|
||||
echo "Installation steps include:"
|
||||
echo "- Update package index files (apt-get update)"
|
||||
echo "- Install Python libraries: numpy, pi3d, svg.path,"
|
||||
echo " rpi-gpio, python3-dev, python3-pil"
|
||||
echo "- Install Adafruit eye code and data in /boot"
|
||||
echo "- Set HDMI resolution, GPU RAM, disable overscan"
|
||||
if [ $IS_PI4 ]; then
|
||||
echo "- Disable desktop, configure video driver"
|
||||
fi
|
||||
echo "- Enable SPI0 and SPI1 peripherals if needed"
|
||||
echo
|
||||
echo "THIS IS A ONE-WAY OPERATION, NO UNINSTALL PROVIDED."
|
||||
echo "EXISTING INSTALLATION, IF ANY, WILL BE OVERWRITTEN."
|
||||
echo "Run time ~10 minutes. Reboot required."
|
||||
echo
|
||||
echo -n "Do you understand and want to proceed? [y/N]"
|
||||
read
|
||||
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
|
||||
echo "Canceled."
|
||||
|
|
@ -115,26 +149,26 @@ fi
|
|||
# perform replacement if found, else append replacement to end of file.
|
||||
# (# $1 = filename, $2 = pattern to match, $3 = replacement)
|
||||
reconfig() {
|
||||
grep $2 $1 >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# Pattern found; replace in file
|
||||
sed -i "s/$2/$3/g" $1 >/dev/null
|
||||
else
|
||||
# Not found; append (silently)
|
||||
echo $3 | sudo tee -a $1 >/dev/null
|
||||
fi
|
||||
grep $2 $1 >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# Pattern found; replace in file
|
||||
sed -i "s/$2/$3/g" $1 >/dev/null
|
||||
else
|
||||
# Not found; append (silently)
|
||||
echo $3 | sudo tee -a $1 >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# Same as above, but appends to same line rather than new line
|
||||
reconfig2() {
|
||||
grep $2 $1 >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# Pattern found; replace in file
|
||||
sed -i "s/$2/$3/g" $1 >/dev/null
|
||||
else
|
||||
# Not found; append to line (silently)
|
||||
sed -i "s/$/ $3/g" $1 >/dev/null
|
||||
fi
|
||||
grep $2 $1 >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# Pattern found; replace in file
|
||||
sed -i "s/$2/$3/g" $1 >/dev/null
|
||||
else
|
||||
# Not found; append to line (silently)
|
||||
sed -i "s/$/ $3/g" $1 >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
echo
|
||||
|
|
@ -145,8 +179,8 @@ apt-get update
|
|||
echo "Installing Python libraries..."
|
||||
# WAS: apt-get install -y --force-yes python-pip python-dev python-imaging python-smbus
|
||||
apt-get install -y python3-pip python3-dev python3-pil python3-smbus libatlas-base-dev
|
||||
# WAS: pip3 install numpy pi3d svg.path rpi-gpio adafruit-ads1x15
|
||||
pip3 install numpy pi3d==2.34 svg.path rpi-gpio adafruit-blinka adafruit-circuitpython-ads1x15
|
||||
# WAS: pip3 install numpy pi3d==2.34 svg.path rpi-gpio adafruit-ads1x15
|
||||
pip3 install numpy pi3d svg.path rpi-gpio adafruit-blinka adafruit-circuitpython-ads1x15
|
||||
# smbus and Blinka+ADC libs are installed regardless whether ADC is
|
||||
# enabled; simplifies the Python code a little (no "uncomment this")
|
||||
|
||||
|
|
@ -158,110 +192,165 @@ unzip master.zip
|
|||
cp -r Pi_Eyes-master /boot/Pi_Eyes
|
||||
rm -rf master.zip Pi_Eyes-master
|
||||
if [ $INSTALL_HALT -ne 0 ]; then
|
||||
echo "Installing gpio-halt in /usr/local/bin..."
|
||||
curl -LO https://github.com/adafruit/Adafruit-GPIO-Halt/archive/master.zip
|
||||
unzip master.zip
|
||||
cd Adafruit-GPIO-Halt-master
|
||||
make
|
||||
mv gpio-halt /usr/local/bin
|
||||
cd ..
|
||||
rm -rf Adafruit-GPIO-Halt-master
|
||||
echo "Installing gpio-halt in /usr/local/bin..."
|
||||
curl -LO https://github.com/adafruit/Adafruit-GPIO-Halt/archive/master.zip
|
||||
unzip master.zip
|
||||
cd Adafruit-GPIO-Halt-master
|
||||
make
|
||||
mv gpio-halt /usr/local/bin
|
||||
cd ..
|
||||
rm -rf Adafruit-GPIO-Halt-master
|
||||
fi
|
||||
|
||||
# CONFIG -------------------------------------------------------------------
|
||||
|
||||
echo "Configuring system..."
|
||||
|
||||
if [ $IS_PI4 ]; then
|
||||
# Make desktop system to boot to console (from raspi-config script):
|
||||
systemctl set-default multi-user.target
|
||||
ln -fs /lib/systemd/system/getty@.service /etc/systemd/system/getty.target.wants/getty@tty1.service
|
||||
rm -f /etc/systemd/system/getty@tty1.service.d/autologin.conf
|
||||
|
||||
# Pi3D requires "fake" KMS overlay to work. Check /boot/config.txt for
|
||||
# vc4-fkms-v3d overlay present and active. If so, nothing to do here,
|
||||
# module's already configured.
|
||||
grep '^dtoverlay=vc4-fkms-v3d' /boot/config.txt >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
# fkms overlay not present, or is commented out. Check if vc4-kms-v3d
|
||||
# (no 'f') is present and active. That's normally the default.
|
||||
grep '^dtoverlay=vc4-kms-v3d' /boot/config.txt >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# It IS present. Comment out that line for posterity, and insert the
|
||||
# 'fkms' item on the next line.
|
||||
sed -i "s/^dtoverlay=vc4-kms-v3d/#&\ndtoverlay=vc4-fkms-v3d/g" /boot/config.txt >/dev/null
|
||||
else
|
||||
# It's NOT present. Silently append 'fkms' overlay to end of file.
|
||||
echo dtoverlay=vc4-fkms-v3d | sudo tee -a /boot/config.txt >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# Disable screen blanking in X config
|
||||
echo "Section \"ServerFlags\"
|
||||
Option \"BlankTime\" \"0\"
|
||||
Option \"StandbyTime\" \"0\"
|
||||
Option \"SuspendTime\" \"0\"
|
||||
Option \"OffTime\" \"0\"
|
||||
Option \"dpms\" \"false\"
|
||||
EndSection" > /etc/X11/xorg.conf
|
||||
|
||||
fi
|
||||
|
||||
# Disable overscan compensation (use full screen):
|
||||
raspi-config nonint do_overscan 1
|
||||
|
||||
# Dedicate 128 MB to the GPU:
|
||||
sudo raspi-config nonint do_memory_split 128
|
||||
|
||||
# HDMI settings for Pi eyes
|
||||
reconfig /boot/config.txt "^.*hdmi_force_hotplug.*$" "hdmi_force_hotplug=1"
|
||||
reconfig /boot/config.txt "^.*hdmi_group.*$" "hdmi_group=2"
|
||||
reconfig /boot/config.txt "^.*hdmi_mode.*$" "hdmi_mode=87"
|
||||
if [ $SCREEN_SELECT -eq 3 ]; then
|
||||
# IPS display - set HDMI to 1280x720
|
||||
reconfig /boot/config.txt "^.*hdmi_cvt.*$" "hdmi_cvt=1280 720 60 1 0 0 0"
|
||||
# IPS display - set HDMI to 1280x720
|
||||
reconfig /boot/config.txt "^.*hdmi_cvt.*$" "hdmi_cvt=1280 720 60 1 0 0 0"
|
||||
else
|
||||
# All others - set HDMI to 640x480
|
||||
reconfig /boot/config.txt "^.*hdmi_cvt.*$" "hdmi_cvt=640 480 60 1 0 0 0"
|
||||
# All others - set HDMI to 640x480
|
||||
reconfig /boot/config.txt "^.*hdmi_cvt.*$" "hdmi_cvt=640 480 60 1 0 0 0"
|
||||
fi
|
||||
|
||||
|
||||
# Enable I2C for ADC
|
||||
if [ $INSTALL_ADC -ne 0 ]; then
|
||||
raspi-config nonint do_i2c 0
|
||||
raspi-config nonint do_i2c 0
|
||||
fi
|
||||
|
||||
if [ $INSTALL_HALT -ne 0 ]; then
|
||||
# Add gpio-halt to /rc.local:
|
||||
grep gpio-halt /etc/rc.local >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# gpio-halt already in rc.local, but make sure correct:
|
||||
sed -i "s/^.*gpio-halt.*$/\/usr\/local\/bin\/gpio-halt $HALT_PIN \&/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
# Insert gpio-halt into rc.local before final 'exit 0'
|
||||
sed -i "s/^exit 0/\/usr\/local\/bin\/gpio-halt $HALT_PIN \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
# Add gpio-halt to /rc.local:
|
||||
grep gpio-halt /etc/rc.local >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# gpio-halt already in rc.local, but make sure correct:
|
||||
sed -i "s/^.*gpio-halt.*$/\/usr\/local\/bin\/gpio-halt $HALT_PIN \&/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
# Insert gpio-halt into rc.local before final 'exit 0'
|
||||
sed -i "s/^exit 0/\/usr\/local\/bin\/gpio-halt $HALT_PIN \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# If using OLED, TFT or IPS, enable SPI and install fbx2 and eyes.py,
|
||||
# else (HDMI) skip SPI, fbx2 and install cyclops.py (single eye)
|
||||
if [ $SCREEN_SELECT -ne 4 ]; then
|
||||
|
||||
# Enable SPI0 using raspi-config
|
||||
raspi-config nonint do_spi 0
|
||||
# Enable SPI0 using raspi-config
|
||||
raspi-config nonint do_spi 0
|
||||
|
||||
# Enable SPI1 by adding overlay to /boot/config.txt
|
||||
reconfig /boot/config.txt "^.*dtparam=spi1.*$" "dtparam=spi1=on"
|
||||
reconfig /boot/config.txt "^.*dtoverlay=spi1.*$" "dtoverlay=spi1-3cs"
|
||||
# Enable SPI1 by adding overlay to /boot/config.txt
|
||||
reconfig /boot/config.txt "^.*dtparam=spi1.*$" "dtparam=spi1=on"
|
||||
reconfig /boot/config.txt "^.*dtoverlay=spi1.*$" "dtoverlay=spi1-3cs"
|
||||
|
||||
# Adjust spidev buffer size to 8K (default is 4K)
|
||||
reconfig2 /boot/cmdline.txt "spidev\.bufsiz=.*" "spidev.bufsiz=8192"
|
||||
# Adjust spidev buffer size to 8K (default is 4K)
|
||||
reconfig2 /boot/cmdline.txt "spidev\.bufsiz=.*" "spidev.bufsiz=8192"
|
||||
|
||||
SCREEN_OPT=${SCREEN_VALUES[($SCREEN_SELECT-1)]}
|
||||
SCREEN_OPT=${SCREEN_VALUES[($SCREEN_SELECT-1)]}
|
||||
|
||||
# Auto-start fbx2 on boot
|
||||
grep fbx2 /etc/rc.local >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# fbx2 already in rc.local, but make sure correct:
|
||||
sed -i "s/^.*fbx2.*$/\/boot\/Pi_Eyes\/fbx2 $SCREEN_OPT \&/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
# Insert fbx2 into rc.local before final 'exit 0'
|
||||
sed -i "s/^exit 0/\/boot\/Pi_Eyes\/fbx2 $SCREEN_OPT \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
# Auto-start fbx2 on boot
|
||||
grep fbx2 /etc/rc.local >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# fbx2 already in rc.local, but make sure correct:
|
||||
sed -i "s/^.*fbx2.*$/\/boot\/Pi_Eyes\/fbx2 $SCREEN_OPT \&/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
# Insert fbx2 into rc.local before final 'exit 0'
|
||||
sed -i "s/^exit 0/\/boot\/Pi_Eyes\/fbx2 $SCREEN_OPT \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
|
||||
RADIUS=${RADIUS_VALUES[($SCREEN_SELECT-1)]}
|
||||
# Auto-start eyes.py on boot
|
||||
grep eyes.py /etc/rc.local >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# eyes.py already in rc.local, but make sure correct:
|
||||
sed -i "s/^.*eyes.py.*$/cd \/boot\/Pi_Eyes;python3 eyes.py --radius $RADIUS \&/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
# Insert eyes.py into rc.local before final 'exit 0'
|
||||
sed -i "s/^exit 0/cd \/boot\/Pi_Eyes;python3 eyes.py --radius $RADIUS \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
RADIUS=${RADIUS_VALUES[($SCREEN_SELECT-1)]}
|
||||
# Auto-start eyes.py on boot
|
||||
grep eyes.py /etc/rc.local >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# eyes.py already in rc.local, but make sure correct:
|
||||
if [ $IS_PI4 ]; then
|
||||
sed -i "s/^.*eyes.py.*$/cd \/boot\/Pi_Eyes;xinit \/usr\/bin\/python3 eyes.py --radius $RADIUS \:0 \&/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
sed -i "s/^.*eyes.py.*$/cd \/boot\/Pi_Eyes;python3 eyes.py --radius $RADIUS \&/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
else
|
||||
# Insert eyes.py into rc.local before final 'exit 0'
|
||||
if [ $IS_PI4 ]; then
|
||||
sed -i "s/^exit 0/cd \/boot\/Pi_Eyes;xinit \/usr\/bin\/python3 eyes.py --radius $RADIUS \:0 \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
sed -i "s/^exit 0/cd \/boot\/Pi_Eyes;python3 eyes.py --radius $RADIUS \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
# Auto-start cyclops.py on boot
|
||||
grep cyclops.py /etc/rc.local >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# cyclops.py already in rc.local, but make sure correct:
|
||||
sed -i "s/^.*cyclops.py.*$/cd \/boot\/Pi_Eyes;python3 cyclops.py \&/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
# Insert cyclops.py into rc.local before final 'exit 0'
|
||||
sed -i "s/^exit 0/cd \/boot\/Pi_Eyes;python3 cyclops.py \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
# Auto-start cyclops.py on boot
|
||||
grep cyclops.py /etc/rc.local >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
# cyclops.py already in rc.local, but make sure correct:
|
||||
if [ $IS_PI4 ]; then
|
||||
sed -i "s/^.*cyclops.py.*$/cd \/boot\/Pi_Eyes;xinit \/usr\/bin\/python3 cyclops.py \:0 \&/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
sed -i "s/^.*cyclops.py.*$/cd \/boot\/Pi_Eyes;python3 cyclops.py \&/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
else
|
||||
# Insert cyclops.py into rc.local before final 'exit 0'
|
||||
if [ $IS_PI4 ]; then
|
||||
sed -i "s/^exit 0/cd \/boot\/Pi_Eyes;xinit \/usr\/bin\/python3 cyclops.py \:0 \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
else
|
||||
sed -i "s/^exit 0/cd \/boot\/Pi_Eyes;python3 cyclops.py \&\\nexit 0/g" /etc/rc.local >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [ $INSTALL_GADGET -ne 0 ]; then
|
||||
reconfig /boot/config.txt "^.*dtoverlay=dwc2.*$" "dtoverlay=dwc2"
|
||||
grep "modules-load=dwc2,g_ether" /boot/cmdline.txt >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
# Insert ethernet gadget into config.txt after 'rootwait'
|
||||
sed -i "s/rootwait/rootwait modules-load=dwc2,g_ether/g" /boot/cmdline.txt >/dev/null
|
||||
fi
|
||||
reconfig /boot/config.txt "^.*dtoverlay=dwc2.*$" "dtoverlay=dwc2"
|
||||
grep "modules-load=dwc2,g_ether" /boot/cmdline.txt >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
# Insert ethernet gadget into config.txt after 'rootwait'
|
||||
sed -i "s/rootwait/rootwait modules-load=dwc2,g_ether/g" /boot/cmdline.txt >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# PROMPT FOR REBOOT --------------------------------------------------------
|
||||
|
|
@ -273,8 +362,8 @@ echo
|
|||
echo -n "REBOOT NOW? [y/N] "
|
||||
read
|
||||
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
|
||||
echo "Exiting without reboot."
|
||||
exit 0
|
||||
echo "Exiting without reboot."
|
||||
exit 0
|
||||
fi
|
||||
echo "Reboot started..."
|
||||
reboot
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@ blinka_minimum_python_version = 3.6
|
|||
def default_python_version(numeric=True):
|
||||
version = shell.run_command("python -c 'import platform; print(platform.python_version())'", suppress_message=True, return_output=True)
|
||||
if numeric:
|
||||
return float(version[0:version.rfind(".")])
|
||||
try:
|
||||
return float(version[0:version.rfind(".")])
|
||||
except ValueError:
|
||||
return None
|
||||
return version
|
||||
|
||||
def get_python3_version(numeric=True):
|
||||
|
|
@ -33,10 +36,10 @@ def check_blinka_python_version():
|
|||
print("Making sure the required version of Python is installed")
|
||||
if get_python3_version() < blinka_minimum_python_version:
|
||||
shell.bail("Blinka requires a minimum of Python version {} to install. Please update your OS!".format(blinka_minimum_python_version))
|
||||
|
||||
|
||||
def sys_update():
|
||||
print("Updating System Packages")
|
||||
if not shell.run_command("sudo apt-get update"):
|
||||
if not shell.run_command("sudo apt-get update --allow-releaseinfo-change"):
|
||||
shell.bail("Apt failed to update indexes!")
|
||||
print("Upgrading packages...")
|
||||
if not shell.run_command("sudo apt-get -y upgrade"):
|
||||
|
|
@ -74,7 +77,7 @@ def update_pip():
|
|||
|
||||
def install_blinka():
|
||||
print("Installing latest version of Blinka locally")
|
||||
shell.run_command("sudo apt-get install -y i2c-tools")
|
||||
shell.run_command("sudo apt-get install -y i2c-tools libgpiod-dev")
|
||||
shell.run_command("pip3 install --upgrade RPi.GPIO")
|
||||
shell.run_command("pip3 install --upgrade adafruit-blinka")
|
||||
|
||||
|
|
@ -89,12 +92,19 @@ Raspberry Pi and installs Blinka
|
|||
print("{} detected.\n".format(pi_model))
|
||||
if not shell.is_raspberry_pi():
|
||||
shell.bail("Non-Raspberry Pi board detected. This must be run on a Raspberry Pi")
|
||||
if shell.get_os() != "Raspbian":
|
||||
shell.bail("Sorry. This script currently only runs on Raspberry Pi OS.")
|
||||
os_identifier = shell.get_os()
|
||||
if os_identifier != "Raspbian":
|
||||
shell.bail("Sorry, the OS detected was {}. This script currently only runs on Raspberry Pi OS.".format(os_identifier))
|
||||
if not shell.is_python3():
|
||||
shell.bail("You must be running Python 3. Older versions have now been deprecated.")
|
||||
shell.check_kernel_update_reboot_required()
|
||||
if default_python_version() < 3:
|
||||
python_version = default_python_version()
|
||||
if not python_version:
|
||||
shell.warn("WARNING No Default System python tied to the `python` command. It will be set to Version 3.")
|
||||
default_python = 0
|
||||
if not shell.prompt("Continue?"):
|
||||
shell.exit()
|
||||
elif default_python_version() < 3:
|
||||
shell.warn("WARNING Default System python version is {}. It will be updated to Version 3.".format(default_python_version(False)))
|
||||
default_python = 2
|
||||
if not shell.prompt("Continue?"):
|
||||
|
|
|
|||
144
raspi-spi-reassign.py
Normal file
144
raspi-spi-reassign.py
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
"""
|
||||
Adafruit Raspberry Pi SPI Chip Enable Reassignment Script
|
||||
(C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
|
||||
"""
|
||||
|
||||
try:
|
||||
import click
|
||||
except ImportError:
|
||||
raise RuntimeError("The library 'Click' was not found. To install, try typing: sudo pip3 install Click")
|
||||
try:
|
||||
from adafruit_shell import Shell
|
||||
except ImportError:
|
||||
raise RuntimeError("The library 'adafruit_shell' was not found. To install, try typing: sudo pip3 install adafruit-python-shell")
|
||||
import os
|
||||
|
||||
shell = Shell()
|
||||
shell.group="SPI Reassign"
|
||||
|
||||
allowed_gpios = (4, 5, 6, 7, 8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27)
|
||||
spi0_default_pins = (8, 7)
|
||||
|
||||
"""
|
||||
For now this will only ask about SPI0, but we can later add SPI1
|
||||
"""
|
||||
|
||||
def valid_pins(ce0_pin, ce1_pin):
|
||||
if ce0_pin is None or ce1_pin is None:
|
||||
return False
|
||||
if ce0_pin == ce1_pin:
|
||||
return False
|
||||
if int(ce0_pin) not in allowed_gpios:
|
||||
return False
|
||||
if int(ce1_pin) not in allowed_gpios:
|
||||
return False
|
||||
return True
|
||||
|
||||
def disable_spi():
|
||||
print("Disabling SPI")
|
||||
shell.run_command("sudo raspi-config nonint do_spi 1")
|
||||
|
||||
def enable_spi():
|
||||
print("Enabling SPI")
|
||||
shell.run_command("sudo raspi-config nonint do_spi 0")
|
||||
|
||||
def remove_custom():
|
||||
shell.pattern_replace("/boot/config.txt", 'dtoverlay=spi0-2cs,cs.*?\n', multi_line=True)
|
||||
|
||||
def write_new_custom(ce0_pin, ce1_pin):
|
||||
if (ce0_pin, ce1_pin) == spi0_default_pins:
|
||||
enable_spi()
|
||||
else:
|
||||
overlay_command = "dtoverlay=spi0-2cs"
|
||||
if ce0_pin != spi0_default_pins[0]:
|
||||
overlay_command += ",cs0_pin={}".format(ce0_pin)
|
||||
if ce1_pin != spi0_default_pins[1]:
|
||||
overlay_command += ",cs1_pin={}".format(ce1_pin)
|
||||
shell.write_text_file("/boot/config.txt", overlay_command + "\n")
|
||||
|
||||
@click.command()
|
||||
@click.option('--ce0', nargs=1, default=None, help="Specify a GPIO for CE0")
|
||||
@click.option('--ce1', nargs=1, default=None, help="Specify a GPIO for CE1")
|
||||
@click.option('--reboot', nargs=1, default=None, type=click.Choice(['yes', 'no']), help="Specify whether to reboot after the script is finished")
|
||||
def main(ce0, ce1, reboot):
|
||||
ask_reboot = True
|
||||
auto_reboot = False
|
||||
if reboot is not None:
|
||||
ask_reboot = False
|
||||
auto_reboot = reboot.lower() == 'yes'
|
||||
if valid_pins(ce0, ce1):
|
||||
remove_custom()
|
||||
disable_spi()
|
||||
write_new_custom(ce0, ce1)
|
||||
if auto_reboot:
|
||||
shell.reboot()
|
||||
if ask_reboot:
|
||||
shell.prompt_reboot()
|
||||
exit(0)
|
||||
else:
|
||||
print("Invalid ce0 or ce1", ce0, ce1)
|
||||
#shell.clear()
|
||||
# Check Raspberry Pi and Bail
|
||||
pi_model = shell.get_board_model()
|
||||
print("""This script allows you
|
||||
to easily reassign the SPI Chip Enable
|
||||
pins so the OS automatic handling of the
|
||||
lines doesn't interfere with CircuitPython.
|
||||
Run time of < 1 minute. Reboot required for
|
||||
changes to take effect!
|
||||
""")
|
||||
shell.info("{} detected.\n".format(pi_model))
|
||||
if not shell.is_raspberry_pi():
|
||||
shell.bail("Non-Raspberry Pi board detected. This must be run on a Raspberry Pi")
|
||||
os_identifier = shell.get_os()
|
||||
if os_identifier != "Raspbian":
|
||||
shell.bail("Sorry, the OS detected was {}. This script currently only runs on Raspberry Pi OS.".format(os_identifier))
|
||||
menu_selection = shell.select_n(
|
||||
"Select an option:", (
|
||||
"Reassign SPI Chip Enable Pins",
|
||||
"Reset to Defaults Pins",
|
||||
"Disable SPI",
|
||||
"Exit",
|
||||
)
|
||||
)
|
||||
if menu_selection == 1:
|
||||
while True:
|
||||
# Reassign
|
||||
gpio_pool = list(allowed_gpios)
|
||||
# Ask for pin for CE0
|
||||
ce0_selection = shell.select_n("Select a new GPIO for CE0", ["GPIO {}".format(x) for x in gpio_pool])
|
||||
ce0_pin = gpio_pool[ce0_selection - 1]
|
||||
gpio_pool.remove(ce0_pin)
|
||||
# Ask for pin for CE1
|
||||
ce1_selection = shell.select_n("Select a new GPIO for CE1", ["GPIO {}".format(x) for x in gpio_pool])
|
||||
ce1_pin = gpio_pool[ce1_selection - 1]
|
||||
if shell.prompt("The new GPIO {} for CE0 and GPIO {} for CE1. Is this correct?".format(ce0_pin, ce1_pin)):
|
||||
break
|
||||
remove_custom()
|
||||
disable_spi()
|
||||
write_new_custom(ce0_pin, ce1_pin)
|
||||
elif menu_selection == 2:
|
||||
# Reset to Defaults
|
||||
remove_custom()
|
||||
enable_spi()
|
||||
elif menu_selection == 3:
|
||||
# Disable
|
||||
remove_custom()
|
||||
disable_spi()
|
||||
elif menu_selection == 4:
|
||||
# Exit
|
||||
shell.exit(0)
|
||||
# Done
|
||||
print("""DONE.
|
||||
|
||||
Settings take effect on next boot.
|
||||
""")
|
||||
if auto_reboot:
|
||||
shell.reboot()
|
||||
if ask_reboot:
|
||||
shell.prompt_reboot()
|
||||
|
||||
# Main function
|
||||
if __name__ == "__main__":
|
||||
shell.require_root()
|
||||
main()
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "NEWS: see https://learn.adafruit.com/read-only-raspberry-pi"
|
||||
echo "This script is deprecated, with better functionality now in"
|
||||
echo "the OS without hacks. It's being kept temporarily for reference."
|
||||
echo "You can edit this part out if you really need to run it."
|
||||
exit 0
|
||||
|
||||
# CREDIT TO THESE TUTORIALS:
|
||||
# petr.io/en/blog/2015/11/09/read-only-raspberry-pi-with-jessie
|
||||
# hallard.me/raspberry-pi-read-only
|
||||
|
|
@ -284,18 +290,23 @@ replace /usr/lib/tmpfiles.d/var.conf "spool\s*0755" "spool 1777"
|
|||
touch /tmp/dhcpcd.resolv.conf
|
||||
rm /etc/resolv.conf
|
||||
ln -s /tmp/dhcpcd.resolv.conf /etc/resolv.conf
|
||||
# systemd-ntp must use systemwide /tmp to access /tmp/dhcpcd.resolv.conf
|
||||
replace /lib/systemd/system/ntp.service "PrivateTmp=true" "PrivateTmp=false"
|
||||
|
||||
# Make edits to fstab
|
||||
# make / ro
|
||||
# tmpfs /var/log tmpfs nodev,nosuid 0 0
|
||||
# tmpfs /var/tmp tmpfs nodev,nosuid 0 0
|
||||
# tmpfs /tmp tmpfs nodev,nosuid 0 0
|
||||
replace /etc/fstab "vfat\s*defaults\s" "vfat defaults,ro "
|
||||
replace /etc/fstab "ext4\s*defaults,noatime\s" "ext4 defaults,noatime,ro "
|
||||
replace /etc/fstab "vfat\s*defaults\s.*" "vfat defaults,ro\t0\t0"
|
||||
replace /etc/fstab "ext4\s*defaults,noatime\s.*" "ext4 defaults,noatime,ro\t0\t0"
|
||||
append1 /etc/fstab "/var/log" "tmpfs /var/log tmpfs nodev,nosuid 0 0"
|
||||
append1 /etc/fstab "/var/tmp" "tmpfs /var/tmp tmpfs nodev,nosuid 0 0"
|
||||
append1 /etc/fstab "\s/tmp" "tmpfs /tmp tmpfs nodev,nosuid 0 0"
|
||||
|
||||
# Stop vim creating tmp files in ~/.viminfo (ro)
|
||||
echo 'set viminfo=""' >>/etc/vim/vimrc.local
|
||||
|
||||
# PROMPT FOR REBOOT --------------------------------------------------------
|
||||
|
||||
echo "Done."
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
# we reference a specific commit (update this as needed):
|
||||
GITUSER=https://github.com/hzeller
|
||||
REPO=rpi-rgb-led-matrix
|
||||
COMMIT=21410d2b0bac006b4a1661594926af347b3ce334
|
||||
COMMIT=45d3ab5d6cff6e0c14da58930d662822627471fc #needs updated if This is merged/Released
|
||||
# Previously: COMMIT=21410d2b0bac006b4a1661594926af347b3ce334
|
||||
# Previously: COMMIT=e3dd56dcc0408862f39cccc47c1d9dea1b0fb2d2
|
||||
|
||||
if [ $(id -u) -ne 0 ]; then
|
||||
|
|
@ -16,6 +17,9 @@ if [ $(id -u) -ne 0 ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
HAS_PYTHON2=$( [ ! $(which python2) ] ; echo $?)
|
||||
HAS_PYTHON3=$( [ ! $(which python3) ] ; echo $?)
|
||||
|
||||
clear
|
||||
|
||||
echo "This script installs software for the Adafruit"
|
||||
|
|
@ -28,10 +32,10 @@ echo "- Configure boot options"
|
|||
echo "Run time ~15 minutes. Some options require reboot."
|
||||
echo "EXISTING INSTALLATION, IF ANY, WILL BE OVERWRITTEN."
|
||||
echo
|
||||
echo -n "CONTINUE? [y/N] "
|
||||
echo -n "CONTINUE? [y/n] "
|
||||
read
|
||||
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
|
||||
echo "Canceled."
|
||||
echo "Canceled. "
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
|
@ -111,7 +115,7 @@ INTERFACE_TYPE=$?
|
|||
if [ $INTERFACE_TYPE -eq 1 ]; then
|
||||
# For matrix HAT, ask about RTC install
|
||||
echo
|
||||
echo -n "Install realtime clock support? [y/N] "
|
||||
echo -n "Install realtime clock support? [y/n] "
|
||||
read
|
||||
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
|
||||
INSTALL_RTC=1
|
||||
|
|
@ -174,10 +178,10 @@ if [ $QUALITY_MOD -eq 0 ]; then
|
|||
echo "and GPIO18, and internal sound is DISABLED!"
|
||||
fi
|
||||
echo
|
||||
echo -n "CONTINUE? [y/N] "
|
||||
echo -n "CONTINUE? [y/n] "
|
||||
read
|
||||
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
|
||||
echo "Canceled."
|
||||
echo "Canceled. "
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
|
@ -204,7 +208,12 @@ echo "Updating package index files..."
|
|||
apt-get update
|
||||
|
||||
echo "Downloading prerequisites..."
|
||||
apt-get install -y --force-yes python2.7-dev python-pillow python3-dev python3-pillow
|
||||
if [ $HAS_PYTHON2 ]; then
|
||||
apt-get install -y --force-yes python2.7-dev python-pillow
|
||||
fi
|
||||
if [ $HAS_PYTHON3 ]; then
|
||||
apt-get install -y --force-yes python3-dev python3-pillow
|
||||
fi
|
||||
|
||||
echo "Downloading RGB matrix software..."
|
||||
curl -L $GITUSER/$REPO/archive/$COMMIT.zip -o $REPO-$COMMIT.zip
|
||||
|
|
@ -222,20 +231,28 @@ USER_DEFINES=""
|
|||
# USER_DEFINES+=" -DLED_ROWS=${MATRIX_HEIGHTS[$MATRIX_SIZE]}"
|
||||
#fi
|
||||
if [ $QUALITY_MOD -eq 0 ]; then
|
||||
# Build and install for Python 2.7...
|
||||
make clean
|
||||
make install-python HARDWARE_DESC=adafruit-hat-pwm USER_DEFINES="$USER_DEFINES" PYTHON=$(which python2)
|
||||
# Do over for Python 3...
|
||||
make clean
|
||||
make install-python HARDWARE_DESC=adafruit-hat-pwm USER_DEFINES="$USER_DEFINES" PYTHON=$(which python3)
|
||||
if [ $HAS_PYTHON2 ]; then
|
||||
# Build and install for Python 2.7...
|
||||
make clean
|
||||
make install-python HARDWARE_DESC=adafruit-hat-pwm USER_DEFINES="$USER_DEFINES" PYTHON=$(which python2)
|
||||
fi
|
||||
if [ $HAS_PYTHON3 ]; then
|
||||
# Do over for Python 3...
|
||||
make clean
|
||||
make install-python HARDWARE_DESC=adafruit-hat-pwm USER_DEFINES="$USER_DEFINES" PYTHON=$(which python3)
|
||||
fi
|
||||
else
|
||||
# Build then install for Python 2.7...
|
||||
USER_DEFINES+=" -DDISABLE_HARDWARE_PULSES"
|
||||
make clean
|
||||
make install-python HARDWARE_DESC=adafruit-hat USER_DEFINES="$USER_DEFINES" PYTHON=$(which python2)
|
||||
# Do over for Python 3...
|
||||
make clean
|
||||
make install-python HARDWARE_DESC=adafruit-hat USER_DEFINES="$USER_DEFINES" PYTHON=$(which python3)
|
||||
if [ $HAS_PYTHON2 ]; then
|
||||
# Build then install for Python 2.7...
|
||||
make clean
|
||||
make install-python HARDWARE_DESC=adafruit-hat USER_DEFINES="$USER_DEFINES" PYTHON=$(which python2)
|
||||
fi
|
||||
if [ $HAS_PYTHON3 ]; then
|
||||
# Do over for Python 3...
|
||||
make clean
|
||||
make install-python HARDWARE_DESC=adafruit-hat USER_DEFINES="$USER_DEFINES" PYTHON=$(which python3)
|
||||
fi
|
||||
fi
|
||||
# Change ownership to user calling sudo
|
||||
chown -R $SUDO_USER:$(id -g $SUDO_USER) `pwd`
|
||||
|
|
@ -272,14 +289,15 @@ echo "Settings take effect on next boot."
|
|||
if [ $INSTALL_RTC -ne 0 ]; then
|
||||
echo "RTC will be enabled then but time must be set"
|
||||
echo "up using the 'date' and 'hwclock' commands."
|
||||
echo "ref: https://learn.adafruit.com/adding-a-real-time-clock-to-raspberry-pi/set-rtc-time#sync-time-from-pi-to-rtc"
|
||||
fi
|
||||
echo
|
||||
echo -n "REBOOT NOW? [y/N] "
|
||||
echo -n "REBOOT NOW? [y/n] "
|
||||
read
|
||||
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
|
||||
echo "Exiting without reboot."
|
||||
exit 0
|
||||
fi
|
||||
echo "Reboot started..."
|
||||
echo "Reboot process started..."
|
||||
reboot
|
||||
sleep infinity
|
||||
|
|
|
|||
|
|
@ -22,12 +22,13 @@ if [ `id -u` -ne 0 ]; then
|
|||
fi
|
||||
|
||||
version=$1
|
||||
fileversion=$(echo $version | cut -d':' -f 2)
|
||||
base=http://archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/
|
||||
packagelist="libraspberrypi0 libraspberrypi-bin libraspberrypi-dev libraspberrypi-doc raspberrypi-bootloader raspberrypi-kernel raspberrypi-kernel-headers"
|
||||
|
||||
set --
|
||||
for package in $packagelist; do
|
||||
filename="${package}_${version}_armhf.deb"
|
||||
filename="${package}_${fileversion}_armhf.deb"
|
||||
set -- "$@" "$filename"
|
||||
wget --continue -O "$filename" "$base/$filename"
|
||||
done
|
||||
|
|
@ -35,5 +36,5 @@ done
|
|||
dpkg -i "$@"
|
||||
|
||||
for package in $packagelist; do
|
||||
/usr/bin/printf "Package: $package\nPin: version 1.20201126-1\nPin-Priority:999\n\n"
|
||||
/usr/bin/printf "Package: $package\nPin: version ${version}\nPin-Priority:999\n\n"
|
||||
done > /etc/apt/preferences.d/99-adafruit-pin-kernel
|
||||
|
|
|
|||
Loading…
Reference in a new issue