Skip to content

Commit 4663279

Browse files
authored
Merge pull request #279 from makermelissa/main
Update SPI reassignment script for Bookworm
2 parents 4e477c8 + 2bb0a8c commit 4663279

File tree

1 file changed

+59
-26
lines changed

1 file changed

+59
-26
lines changed

raspi-spi-reassign.py

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@
1818
allowed_gpios = (4, 5, 6, 7, 8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27)
1919
spi0_default_pins = (8, 7)
2020

21+
DISABLE_GPIO_TEXT = "Disabled"
22+
23+
boot_dir = "/boot/firmware"
24+
if not shell.exists(boot_dir) or not shell.isdir(boot_dir):
25+
boot_dir = "/boot"
26+
2127
"""
2228
For now this will only ask about SPI0, but we can later add SPI1
2329
"""
2430

2531
def valid_pins(ce0_pin, ce1_pin):
26-
if ce0_pin is None or ce1_pin is None:
32+
if ce0_pin is None and ce1_pin is not None:
2733
return False
2834
if ce0_pin == ce1_pin:
2935
return False
@@ -41,19 +47,35 @@ def enable_spi():
4147
print("Enabling SPI")
4248
shell.run_command("sudo raspi-config nonint do_spi 0")
4349

50+
def spi_disabled():
51+
return shell.run_command("sudo raspi-config nonint get_spi", suppress_message=True, return_output=True).strip() == "1"
52+
4453
def remove_custom():
45-
shell.pattern_replace("/boot/config.txt", 'dtoverlay=spi0-2cs,cs.*?\n', multi_line=True)
54+
shell.pattern_replace(f"{boot_dir}/config.txt", 'dtoverlay=spi0-[0-2]cs,cs.*?\n', multi_line=True)
55+
56+
def format_gpio(gpio):
57+
if gpio is None:
58+
return DISABLE_GPIO_TEXT
59+
return f"GPIO {gpio}"
60+
61+
def gpio_options(pool):
62+
options = []
63+
for gpio in pool:
64+
options.append(format_gpio(gpio))
65+
return options
4666

4767
def write_new_custom(ce0_pin, ce1_pin):
48-
if (ce0_pin, ce1_pin) == spi0_default_pins:
49-
enable_spi()
50-
else:
68+
if (ce0_pin, ce1_pin) != spi0_default_pins:
5169
overlay_command = "dtoverlay=spi0-2cs"
52-
if ce0_pin != spi0_default_pins[0]:
70+
if ce0_pin is None and ce1_pin is None:
71+
overlay_command = "dtoverlay=spi0-0cs"
72+
elif ce1_pin is None:
73+
overlay_command = "dtoverlay=spi0-1cs"
74+
if ce0_pin != spi0_default_pins[0] and ce0_pin is not None:
5375
overlay_command += ",cs0_pin={}".format(ce0_pin)
54-
if ce1_pin != spi0_default_pins[1]:
76+
if ce1_pin != spi0_default_pins[1] and ce1_pin is not None:
5577
overlay_command += ",cs1_pin={}".format(ce1_pin)
56-
shell.write_text_file("/boot/config.txt", overlay_command + "\n")
78+
shell.write_text_file(f"{boot_dir}/config.txt", overlay_command + "\n")
5779

5880
@click.command()
5981
@click.option('--ce0', nargs=1, default=None, help="Specify a GPIO for CE0")
@@ -67,7 +89,6 @@ def main(ce0, ce1, reboot):
6789
auto_reboot = reboot.lower() == 'yes'
6890
if valid_pins(ce0, ce1):
6991
remove_custom()
70-
disable_spi()
7192
write_new_custom(ce0, ce1)
7293
if auto_reboot:
7394
shell.reboot()
@@ -86,44 +107,56 @@ def main(ce0, ce1, reboot):
86107
Run time of < 1 minute. Reboot required for
87108
changes to take effect!
88109
""")
110+
menu_options = [
111+
"Reassign SPI Chip Enable Pins",
112+
"Reset to Defaults Pins",
113+
"Disable SPI",
114+
"Exit",
115+
]
116+
117+
if spi_disabled():
118+
menu_options[2] = "Enable SPI"
119+
89120
shell.info("{} detected.\n".format(pi_model))
90121
if not shell.is_raspberry_pi():
91122
shell.bail("Non-Raspberry Pi board detected. This must be run on a Raspberry Pi")
92123
os_identifier = shell.get_os()
93124
if os_identifier != "Raspbian":
94125
shell.bail("Sorry, the OS detected was {}. This script currently only runs on Raspberry Pi OS.".format(os_identifier))
95126
menu_selection = shell.select_n(
96-
"Select an option:", (
97-
"Reassign SPI Chip Enable Pins",
98-
"Reset to Defaults Pins",
99-
"Disable SPI",
100-
"Exit",
101-
)
127+
"Select an option:", menu_options
102128
)
103129
if menu_selection == 1:
104130
while True:
105131
# Reassign
106132
gpio_pool = list(allowed_gpios)
133+
gpio_pool.append(None)
107134
# Ask for pin for CE0
108-
ce0_selection = shell.select_n("Select a new GPIO for CE0", ["GPIO {}".format(x) for x in gpio_pool])
135+
ce0_selection = shell.select_n("Select a new GPIO for CE0", gpio_options(gpio_pool))
109136
ce0_pin = gpio_pool[ce0_selection - 1]
110-
gpio_pool.remove(ce0_pin)
111-
# Ask for pin for CE1
112-
ce1_selection = shell.select_n("Select a new GPIO for CE1", ["GPIO {}".format(x) for x in gpio_pool])
113-
ce1_pin = gpio_pool[ce1_selection - 1]
114-
if shell.prompt("The new GPIO {} for CE0 and GPIO {} for CE1. Is this correct?".format(ce0_pin, ce1_pin)):
137+
if ce0_pin is not None:
138+
gpio_pool.remove(ce0_pin)
139+
# Ask for pin for CE1
140+
ce1_selection = shell.select_n("Select a new GPIO for CE1", gpio_options(gpio_pool))
141+
ce1_pin = gpio_pool[ce1_selection - 1]
142+
else:
143+
ce1_pin = None
144+
if shell.prompt(f"The new settings will be {format_gpio(ce0_pin)} for CE0 and {format_gpio(ce1_pin)} for CE1. Is this correct?"):
115145
break
116146
remove_custom()
117-
disable_spi()
118147
write_new_custom(ce0_pin, ce1_pin)
148+
if spi_disabled():
149+
enable_spi()
119150
elif menu_selection == 2:
120151
# Reset to Defaults
121152
remove_custom()
122-
enable_spi()
123153
elif menu_selection == 3:
124-
# Disable
125-
remove_custom()
126-
disable_spi()
154+
# Enable/Disable SPI
155+
if spi_disabled():
156+
enable_spi()
157+
else:
158+
disable_spi()
159+
remove_custom()
127160
elif menu_selection == 4:
128161
# Exit
129162
shell.exit(0)

0 commit comments

Comments
 (0)