18
18
allowed_gpios = (4 , 5 , 6 , 7 , 8 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 )
19
19
spi0_default_pins = (8 , 7 )
20
20
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
+
21
27
"""
22
28
For now this will only ask about SPI0, but we can later add SPI1
23
29
"""
24
30
25
31
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 :
27
33
return False
28
34
if ce0_pin == ce1_pin :
29
35
return False
@@ -41,19 +47,35 @@ def enable_spi():
41
47
print ("Enabling SPI" )
42
48
shell .run_command ("sudo raspi-config nonint do_spi 0" )
43
49
50
+ def spi_disabled ():
51
+ return shell .run_command ("sudo raspi-config nonint get_spi" , suppress_message = True , return_output = True ).strip () == "1"
52
+
44
53
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
46
66
47
67
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 :
51
69
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 :
53
75
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 :
55
77
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 " )
57
79
58
80
@click .command ()
59
81
@click .option ('--ce0' , nargs = 1 , default = None , help = "Specify a GPIO for CE0" )
@@ -67,7 +89,6 @@ def main(ce0, ce1, reboot):
67
89
auto_reboot = reboot .lower () == 'yes'
68
90
if valid_pins (ce0 , ce1 ):
69
91
remove_custom ()
70
- disable_spi ()
71
92
write_new_custom (ce0 , ce1 )
72
93
if auto_reboot :
73
94
shell .reboot ()
@@ -86,44 +107,56 @@ def main(ce0, ce1, reboot):
86
107
Run time of < 1 minute. Reboot required for
87
108
changes to take effect!
88
109
""" )
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
+
89
120
shell .info ("{} detected.\n " .format (pi_model ))
90
121
if not shell .is_raspberry_pi ():
91
122
shell .bail ("Non-Raspberry Pi board detected. This must be run on a Raspberry Pi" )
92
123
os_identifier = shell .get_os ()
93
124
if os_identifier != "Raspbian" :
94
125
shell .bail ("Sorry, the OS detected was {}. This script currently only runs on Raspberry Pi OS." .format (os_identifier ))
95
126
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
102
128
)
103
129
if menu_selection == 1 :
104
130
while True :
105
131
# Reassign
106
132
gpio_pool = list (allowed_gpios )
133
+ gpio_pool .append (None )
107
134
# 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 ) )
109
136
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?" ):
115
145
break
116
146
remove_custom ()
117
- disable_spi ()
118
147
write_new_custom (ce0_pin , ce1_pin )
148
+ if spi_disabled ():
149
+ enable_spi ()
119
150
elif menu_selection == 2 :
120
151
# Reset to Defaults
121
152
remove_custom ()
122
- enable_spi ()
123
153
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 ()
127
160
elif menu_selection == 4 :
128
161
# Exit
129
162
shell .exit (0 )
0 commit comments