Compare commits

...

360 commits
st7789 ... main

Author SHA1 Message Date
Limor "Ladyada" Fried
48a6ea9f86
Merge pull request #355 from makermelissa/main
Fix the con2fbmap helper in adafruit-pitft to work with all displays
2025-08-27 09:27:49 -04:00
Melissa LeBlanc-Williams
c87a354258 Fix the con2fbmap helper to work with all displays 2025-08-26 15:44:18 -07:00
Melissa LeBlanc-Williams
aa955c4376
Merge pull request #353 from makermelissa/main
Update i2samp.py to provide i2s volume control
2025-08-20 12:44:32 -07:00
Melissa LeBlanc-Williams
b4ce00a899 Uncomment /dev/zero stuff 2025-08-16 14:06:10 -07:00
Melissa LeBlanc-Williams
88467546ee Update i2samp.py to provide i2s volume control 2025-08-16 14:00:18 -07:00
Limor "Ladyada" Fried
5547ffd352
Merge pull request #352 from makermelissa/main
Host the lgpio package
2025-08-15 21:56:14 -04:00
Melissa LeBlanc-Williams
57cca7fd7d Host the lgpio package 2025-08-15 14:59:49 -07:00
Melissa LeBlanc-Williams
adcb740a19
Merge pull request #348 from makermelissa/pitft-updates
Added PiTFT V2 and stripping out old stuff
2025-08-11 11:49:04 -07:00
Melissa LeBlanc-Williams
2bbb0844ea Remove unused import 2025-08-06 15:04:46 -07:00
Melissa LeBlanc-Williams
e2af79a70b Remove old file 2025-08-06 15:02:40 -07:00
Melissa LeBlanc-Williams
7ba3f50d36 Add labwc support 2025-08-06 14:59:03 -07:00
Melissa LeBlanc-Williams
d14339d748 Fixed console mode, touch now working 2025-07-26 12:18:38 -07:00
Melissa LeBlanc-Williams
292185d7b9 Removed old stuff and updated so it's now in a working state 2025-07-18 15:22:46 -07:00
foamyguy
ae88fed18c
Merge pull request #349 from FoamyGuy/quality_notes
update quality info about triple matrix
2025-07-15 08:12:30 -05:00
foamyguy
10dd2cd969 update quality info about triple matrix 2025-07-14 10:51:13 -05:00
Melissa LeBlanc-Williams
160bf98cff Added PiTFT V2 and stripping out old stuff 2025-07-09 14:52:51 -07:00
Melissa LeBlanc-Williams
923d409ffd
Merge pull request #347 from makermelissa/main
Apply Pi 5 requirement changes to Blinka Installer
2025-06-24 08:08:47 -07:00
Melissa LeBlanc-Williams
fccc7ebe48 Use the recommended lgpio setup procedure 2025-06-23 10:18:25 -07:00
Melissa LeBlanc-Williams
e55fd74098 Apply Pi 5 requirement changes 2025-06-23 09:37:22 -07:00
Carter Nelson
cc13749b5e
Merge pull request #346 from caternuson/rgb_matrix_update
Update rgb-matrix.sh
2025-06-17 07:33:51 -07:00
caternuson
a29743d6af update rgb-matrix.sh 2025-06-17 06:57:46 -07:00
Melissa LeBlanc-Williams
47308a7f1a
Merge pull request #345 from makermelissa/main
Add user to hardware groups in Blinka installer
2025-05-26 11:45:19 -07:00
Melissa LeBlanc-Williams
14c7b7d931 Add user to hardware groups in Blinka installer 2025-05-26 11:22:08 -07:00
Limor "Ladyada" Fried
a29da80873
Merge pull request #344 from makermelissa/main
Add some checks to remove displaying errors
2025-05-21 13:57:38 -04:00
Melissa LeBlanc-Williams
908629430e Add some checks to remove displaying errors 2025-05-20 15:34:36 -07:00
Melissa LeBlanc-Williams
3448db64f0
Merge pull request #342 from makermelissa/main
Fix expected get_boot_config to return folder
2025-04-09 12:52:17 -07:00
Melissa LeBlanc-Williams
242d1275ac Fix expected get_boot_config to return folder 2025-04-07 11:15:29 -07:00
Melissa LeBlanc-Williams
5bb26d8d98
Merge pull request #339 from makermelissa/main
Add working voice bonnet installer and service
2025-03-19 12:28:19 -07:00
Melissa LeBlanc-Williams
7a508dce22 Add working voice bonnet installer and service 2025-03-18 15:28:30 -07:00
Limor "Ladyada" Fried
d7109fa827
Merge pull request #338 from mikeysklar/bootdir-configtxt
adafruit-pitft.py boot_dir
2025-03-10 10:35:21 -04:00
Mikey Sklar
94b83cbef9 adafruit-pitft.py boot_dir
fix for  /boot/firmware vs /boot logic for the config.txt location
2025-03-08 17:28:45 -08:00
Melissa LeBlanc-Williams
d18a31bfec
Merge pull request #337 from makermelissa/main
Update python scripts with new shell features
2025-03-05 14:46:13 -08:00
Melissa LeBlanc-Williams
3cc46f8bdb Update python scripts with new shell features 2025-03-05 13:17:12 -08:00
Melissa LeBlanc-Williams
7fa847b6b8
Merge pull request #332 from mikeysklar/pitft-raspi-config-args
bookworm update effects adafruit-pitft.py
2025-01-30 11:32:57 -08:00
Mikey Sklar
ff822bf77c bookworm update effects adafruit-pitft.py
Minor argument change to rapsi-config do_wayland setting.
2025-01-29 10:46:40 -08:00
Limor "Ladyada" Fried
a68ef4b415
Merge pull request #330 from makermelissa/main
Update blinka installer to handle unsupported Pis
2025-01-15 15:58:20 -05:00
Melissa LeBlanc-Williams
1c3435509f Merge branch 'main' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts 2025-01-15 12:40:15 -08:00
Melissa LeBlanc-Williams
faac4e8be3
Merge pull request #327 from riktam/adafruit#326
Fix enable and disable of Wayland.
2025-01-15 12:40:09 -08:00
Melissa LeBlanc-Williams
3dc39067e8 Update blinka installer to handle unsupported Pis 2025-01-15 12:38:32 -08:00
Limor "Ladyada" Fried
bbeb37b210
Merge pull request #329 from makermelissa/main
Updated Blinka installer to at least install the correct packages
2024-11-20 13:27:12 -05:00
Melissa LeBlanc-Williams
b997ee5a0d Updated Blinka installer to at least install the correct packages 2024-11-18 12:49:40 -08:00
Riktam
e240b61dd0 Fix enable and disable of Wayland. 2024-09-24 00:04:14 +02:00
Limor "Ladyada" Fried
ad19b39863
Merge pull request #324 from mikeysklar/pi5-blinkatest-fix
pi5 GPIO packages fix
2024-09-22 16:46:42 -04:00
Mikey Sklar
3a16bf08c0 pi5 GPIO packages fix
Necessary for blinkatest.py to run without errors on a Pi 5.
2024-09-20 13:01:54 -07:00
Melissa LeBlanc-Williams
9e85cf0c8e
Merge pull request #317 from arrio464/patch-1
upstream: no longer use asoc_xxx() compatible macro
2024-06-07 10:23:36 -07:00
arrio464
a51231a067
upstream: no longer use asoc_xxx() compatible macro
After linux 6.10-rc2, kernel remove asoc_xxx() compatible macro.
So use original prototypes instead.
2024-06-07 15:39:07 +08:00
Melissa LeBlanc-Williams
7b6fced70c
Merge pull request #311 from mikeysklar/pitft35r-drm
drm added for PiTFT 3.5" resistive
2024-05-22 09:08:41 -07:00
Mikey Sklar
2309e7b8ea remove drm hardcode
switch to tinydrm_install logic
2024-05-03 12:11:25 -07:00
Mikey Sklar
fb589e49b7 drm added for PiTFT 3.5" resistive
The PiTFT 3.5" resistive display requires a drm flag to work with Pi Zero and 3B versions of Bookworm. Tested on Pi4 and Pi5 as well.
2024-05-03 09:28:12 -07:00
Melissa LeBlanc-Williams
bf97fa1b88
Merge pull request #309 from makermelissa/main
Update script to use X11 for PiTFT Touch displays
2024-04-30 10:26:02 -07:00
Melissa LeBlanc-Williams
8c9862e1c5 Update script to use X11 for PiTFT Touch displays 2024-04-30 09:47:28 -07:00
Melissa LeBlanc-Williams
1417285467
Merge pull request #305 from makermelissa/main
Updated and converted i2samp script
2024-04-26 19:56:26 -07:00
Melissa LeBlanc-Williams
06deceb470 Updated and converted i2samp script 2024-04-17 13:58:27 -07:00
Melissa LeBlanc-Williams
db8e46f7c5
Merge pull request #304 from makermelissa/main
Don't comment out kms driver for mipi display
2024-04-16 11:18:04 -07:00
Melissa LeBlanc-Williams
163fc2ff2f Don't comment out kms driver for mipi display 2024-04-15 16:14:45 -07:00
Melissa LeBlanc-Williams
3942f2cbd7
Merge pull request #303 from LostNulide/patch-1
Fix #274
2024-04-15 15:11:55 -07:00
LostNulide
d7d1417be5
Update i2smic.py to a more futureproof design 2024-04-15 23:19:02 +02:00
LostNulide
b5c25be3bf
Fix #274
This Commit depends on the Merge-Request #23 for the Adafruit_Python_Shell https://github.com/adafruit/Adafruit_Python_Shell/pull/23
2024-04-15 19:24:02 +02:00
Melissa LeBlanc-Williams
02c6b18f1c
Merge pull request #300 from makermelissa/main
Add Kippah ar1100.py script updated for latest pi
2024-04-03 08:44:13 -07:00
Melissa LeBlanc-Williams
6ecf6252b5 Add Kippah ar1100.py script updated for latest pi 2024-04-02 15:34:39 -07:00
Melissa LeBlanc-Williams
b204f2b4b5
Merge pull request #298 from makermelissa/main
Fix bullseye compatibility with pitft script
2024-02-28 08:24:24 -08:00
Melissa LeBlanc-Williams
bfafc77e36 Fix bullseye compatibility with pitft script 2024-02-27 16:13:40 -08:00
Melissa LeBlanc-Williams
ff79220c58
Merge pull request #297 from makermelissa/main
Add blinka installer backwards compatibility with bullseye
2024-02-27 10:37:05 -08:00
Melissa LeBlanc-Williams
103b133885 Add blinka installer backwards compatibility with bullseye 2024-02-27 08:47:56 -08:00
Melissa LeBlanc-Williams
0173a1f2cd
Merge pull request #294 from makermelissa/st7789
Integrate ST7789 MIPI Script into main PiTFT Script
2024-01-31 09:57:13 -08:00
Melissa LeBlanc-Williams
219781e115 Integrate ST7789 MIPI Script into main PiTFT Script 2024-01-30 16:53:18 -08:00
Melissa LeBlanc-Williams
c8b097bdb4
Merge pull request #293 from makermelissa/PiTFTs
Update PiTFT overlays and add resistive PiTFTs
2024-01-30 12:27:21 -08:00
Melissa LeBlanc-Williams
e406acfa31 Update PiTFT overlays and add resistive PiTFTs 2024-01-30 10:13:48 -08:00
Melissa LeBlanc-Williams
a6c6d5dc16
Merge pull request #291 from makermelissa/main
Update 2.8-inch Capacitive PiTFT
2024-01-26 11:39:14 -08:00
Melissa LeBlanc-Williams
34817dcd3a Fix capacitive touch rotations 2024-01-26 11:38:50 -08:00
Melissa LeBlanc-Williams
5eb36455d7 Add script updates too 2024-01-22 17:34:05 -08:00
Melissa LeBlanc-Williams
5532bfc5fb Update 2.8-inch Capacitive PiTFT 2024-01-22 17:33:36 -08:00
Melissa LeBlanc-Williams
da7d04a3a7
Merge pull request #290 from makermelissa/main
Update PiTFT Script and 2.2 inch overlay for Bookworm/Pi 5
2024-01-22 17:32:15 -08:00
Melissa LeBlanc-Williams
001096d826 Merge branch 'main' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts 2024-01-22 15:11:13 -08:00
Melissa LeBlanc-Williams
4ba53896e2 Update PiTFT Script and 2.2 inch overlay for Bookworm/Pi 5 2024-01-22 15:11:03 -08:00
Melissa LeBlanc-Williams
243a52d4b6
Merge pull request #288 from makermelissa/main
Fix mipi script from messing with kms and fkms drivers
2024-01-17 12:22:43 -08:00
Melissa LeBlanc-Williams
ed6e75053e Merge branch 'main' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts 2024-01-17 11:11:38 -08:00
Melissa LeBlanc-Williams
f728f7638b Fix mipi script from messing with kms and fkms drivers 2024-01-17 11:11:28 -08:00
Limor "Ladyada" Fried
b8d16b01e0
Merge pull request #285 from makermelissa/main
Add voice bonnet/braincraft hat script to ensure DTOs are enabled
2024-01-05 17:39:52 -05:00
Melissa LeBlanc-Williams
0706b27819 Add /boot/config.txt symlink fix 2024-01-05 10:29:02 -08:00
Melissa LeBlanc-Williams
27ac7a9614 Add voice bonnet/braincraft hat script to ensure DTOs are enabled 2024-01-05 10:08:38 -08:00
Melissa LeBlanc-Williams
8f6c615f1c
Merge pull request #283 from makermelissa/main
Update i2samp to work on bookworm
2023-12-27 10:15:42 -08:00
Melissa LeBlanc-Williams
e6fec6078a Add fallback location to i2samp 2023-12-27 09:59:14 -08:00
Melissa LeBlanc-Williams
a59177c897 Update i2samp to work on bookworm 2023-12-27 09:53:34 -08:00
Melissa LeBlanc-Williams
caba9aa589
Merge pull request #282 from makermelissa/i2smic
Add Pi B Rev 2 to i2smic board list
2023-12-26 14:26:39 -08:00
Melissa LeBlanc-Williams
fc6ff17730 Add Pi B Rev 2 2023-12-26 13:55:12 -08:00
Melissa LeBlanc-Williams
30b4c740b9
Merge pull request #281 from makermelissa/main
Allow 'disabled' to be passed in via command line in spi-reassign script
2023-12-22 11:20:53 -08:00
Melissa LeBlanc-Williams
f5cfbca4c6 Bug fix for when both are disabled 2023-12-22 10:15:01 -08:00
Melissa LeBlanc-Williams
011ede8124 Allow 'disabled' to be passed in via command line in reassign script 2023-12-22 10:09:30 -08:00
Melissa LeBlanc-Williams
46632797b5
Merge pull request #279 from makermelissa/main
Update SPI reassignment script for Bookworm
2023-12-20 10:27:00 -08:00
Melissa LeBlanc-Williams
2bb0a8c447 Update SPI reassignment script for Bookworm 2023-12-20 10:14:09 -08:00
Melissa LeBlanc-Williams
4e477c8ba6
Merge pull request #278 from makermelissa/main
Fix mipi script bug
2023-12-19 15:31:56 -08:00
Melissa LeBlanc-Williams
a122af2e43 Fix mipi script bug 2023-12-19 15:30:36 -08:00
Melissa LeBlanc-Williams
9391a10c30
Merge pull request #272 from makermelissa/main
New /boot/config.txt fix
2023-11-06 16:22:24 -08:00
Melissa LeBlanc-Williams
64b9fd8bf4 New /boot/config.txt fix 2023-11-06 15:00:36 -08:00
Melissa LeBlanc-Williams
9710557648
Merge pull request #269 from ziyadedher/patch-1
Bump `rpi-rgb-led-matrix` commit to `a3eea9`
2023-11-02 08:22:09 -07:00
Ziyad Edher
1370f9e5c3
Bump rpi-rgb-led-matrix commit to a3eea9 2023-10-31 17:23:18 -07:00
Melissa LeBlanc-Williams
a282edbda5
Merge pull request #267 from makermelissa/main
Add libgpiod to Blinak installer for Pi 5
2023-10-23 10:11:31 -07:00
Melissa LeBlanc-Williams
117ca53fce Add libgpiod to Blinak installer for Pi 5 2023-10-23 10:10:39 -07:00
Melissa LeBlanc-Williams
b0028ac12c
Merge pull request #265 from makermelissa/main 2023-10-20 18:21:34 -07:00
Melissa LeBlanc-Williams
8ab58b59ed Change some py packages to be installed via apt-get 2023-10-20 14:21:48 -07:00
Melissa LeBlanc-Williams
4c4f24a076 Merge branch 'main' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts 2023-10-20 14:17:10 -07:00
Melissa LeBlanc-Williams
2c73c400fa
Merge pull request #266 from caternuson/rpiconfig_update
Update raspi-config serial enable
2023-10-20 13:38:28 -07:00
caternuson
bde69a70be update serial enable 2023-10-20 13:34:13 -07:00
Melissa LeBlanc-Williams
def7058ee9 Update script version number 2023-10-20 13:13:25 -07:00
Melissa LeBlanc-Williams
ebcc4936f7 Update pitft to run in venv 2023-10-20 11:06:44 -07:00
Melissa LeBlanc-Williams
a113de6afb
Merge pull request #262 from Paulpanther/main
Fix bug in python version check in raspi-blinka.py
2023-10-13 13:16:47 -07:00
Paul Methfessel
26404d7674
Fix bug in python version check in raspi-blinka.py
The file checked the python version by comparing the major and minor versions. However, the variables compared were strings, making '11' > '8' -> False, when in fact it should have been true.
I converted the versions to integers before comparing, so that versions 10 and above are accepted
2023-10-13 21:51:29 +02:00
Melissa LeBlanc-Williams
4d091776d4
Merge pull request #260 from makermelissa/blinka-install-fix
Fix issue where blinka installs as root
2023-09-14 12:39:08 -07:00
Melissa LeBlanc-Williams
0b17bc3964
Merge pull request #258 from makermelissa/main
Update python version checking for versions > 3.9
2023-09-13 12:43:40 -07:00
Melissa LeBlanc-Williams
9a97fa0b40 Merge branch 'main' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts 2023-09-13 08:54:23 -07:00
Melissa LeBlanc-Williams
92766ff60f
Merge pull request #261 from makermelissa/libgpiod-fix 2023-09-12 18:07:28 -07:00
Melissa LeBlanc-Williams
4996d5b48d make more readable 2023-09-12 15:00:25 -07:00
Melissa LeBlanc-Williams
2772ebb1f3 Fix outdated libgpiod script 2023-09-12 14:56:54 -07:00
Melissa LeBlanc-Williams
0aba7ce7fd Remove extra code 2023-09-12 12:55:55 -07:00
Melissa LeBlanc-Williams
189997aae8 Fix issue where blinka installs as root 2023-09-12 12:53:17 -07:00
Melissa LeBlanc-Williams
f9a67937b5 Merge branch 'main' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts 2023-09-11 08:27:53 -07:00
Melissa LeBlanc-Williams
472040cf8f Update python version checking for versions > 3.9 2023-09-11 08:27:43 -07:00
Limor "Ladyada" Fried
43914b6163
Merge pull request #257 from mifi/main-1
fix `click` install
2023-08-20 18:08:49 -04:00
Mikael Finstad
63377adde5
fix click install
currently:

```
sudo apt-get install python3-pip click
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package click
```
2023-08-16 13:54:58 +02:00
Melissa LeBlanc-Williams
2e3f8e6dc3
Merge pull request #255 from Lovmong/main
Please restore i2samp.h support for Raspbian buster system.
2023-08-11 08:15:05 -07:00
Lovmong
04509fac88
restore support for Raspbian buster 2023-08-11 15:59:24 +08:00
Melissa LeBlanc-Williams
339cccfbdd
Merge pull request #252 from makermelissa/main
Fix Capacitive 2.8-inch PiTFT touch
2023-05-31 13:13:12 -07:00
Melissa LeBlanc-Williams
b73b9d51a2 Fix Capacitive 2.8-inch PiTFT touch 2023-05-31 09:16:14 -07:00
Melissa LeBlanc-Williams
866f780c55
Merge pull request #251 from makermelissa/pitft114_offset
Updated and fixed ST7789v driver
2023-05-30 08:16:55 -07:00
Melissa LeBlanc-Williams
97a7d43e85 Updated and fixed ST7789v driver 2023-05-26 17:06:41 -07:00
Melissa LeBlanc-Williams
d49b6e9d95
Merge pull request #250 from makermelissa/fix_i2smic
Fix i2smic
2023-05-19 16:23:43 -07:00
Melissa LeBlanc-Williams
e078e2723f
Merge pull request #249 from makermelissa/fix_rotation
Change rotation to rotate for ST7789 displays
2023-05-19 16:23:28 -07:00
Melissa LeBlanc-Williams
169377cc43 Fix i2smic by checking if userspace and kernel space are the same 2023-05-12 11:25:59 -07:00
Melissa LeBlanc-Williams
4c85441000 Change rotation to rotate for ST7789 displays 2023-05-12 09:12:05 -07:00
Melissa LeBlanc-Williams
b3e3a1ad66
Merge pull request #246 from makermelissa/main
Only compile st7789 driver if necessary
2023-04-05 08:15:34 -07:00
Melissa LeBlanc-Williams
5c5fb7995a Only compile st7789 driver if necessary 2023-04-04 16:03:12 -07:00
Melissa LeBlanc-Williams
59958b8774
Merge pull request #245 from wise-introvert/patch-1
docs: add an alternative package if original fails
2023-03-23 15:59:19 -07:00
Fardeen Panjwani
108f4e381b
docs(libgpiod): fix typo 2023-03-23 18:24:12 -04:00
Fardeen Panjwani
16054b3687
docs: add an alternative package if original fails
The old instructions mentioned adafruit-python**3**-shell as a dependency but when I tried to install the package I found out that the package didn't exist ( or deprecated I think ) and I was able to use adafruit-python-shell instead. So, I thought I might add the package to the instructions in case anyone else runs into the same issue as me.
2023-03-23 18:10:54 -04:00
Melissa LeBlanc-Williams
f9928f941f
Merge pull request #240 from BasdeWinter/BasdeWinter-patch-1
Update raspi-blinka.py
2023-02-13 08:25:44 -08:00
BasdeWinter
d262dedd1f
Update raspi-blinka.py
fixes a "< operator cannot be used to compare NonType with int" error on a RPI-Zero-W
2023-02-07 18:52:45 +01:00
Phillip Burgess
0445056459 Remove Arcade Bonnet test (moved to Retrogame repo instead) 2023-01-03 14:59:31 -08:00
Phillip Burgess
3355934bb1 Add Arcade Bonnet tester 2023-01-03 13:30:51 -08:00
Melissa LeBlanc-Williams
3a6a8f7b5c
Merge pull request #237 from adafruit/pb-arcade-bonnet-python3
Arcade Bonnet: update to use python3
2022-12-28 09:50:13 -08:00
Phillip Burgess
46ef973fbb Arcade Bonnet: python3-dev not needed in apt-get line 2022-12-28 09:05:48 -08:00
Phillip Burgess
9e48166f87 Arcade Bonnet: python3-ify 2022-12-27 18:40:14 -08:00
Melissa LeBlanc-Williams
60950ddddd Fix bug report YAML 2022-11-30 11:50:27 -08:00
Melissa LeBlanc-Williams
a3532a8961
Merge pull request #236 from makermelissa/main
Add Bug report template and additional conversions
2022-11-30 11:45:03 -08:00
Melissa LeBlanc-Williams
de02991724 Add Bug report template to reduce asking for additional details 2022-11-30 09:25:30 -08:00
Melissa LeBlanc-Williams
2ebeece160
Merge pull request #234 from makermelissa/main
Update readme, move scripts, bug fixes
2022-11-11 17:11:36 -08:00
Melissa LeBlanc-Williams
bc4b07e658 Update readme, move scripts, bug fixes 2022-11-11 17:04:12 -08:00
Melissa LeBlanc-Williams
501435743e
Merge pull request #180 from beasteers/i2smic-nonint-patch-2
Make i2smic.py noninteractive
2022-11-09 10:36:38 -08:00
Melissa LeBlanc-Williams
08283cf58a Remove unused import os 2022-11-09 10:32:56 -08:00
Melissa LeBlanc-Williams
bc463b1099 Simplified code 2022-11-09 10:31:57 -08:00
Melissa LeBlanc-Williams
45dc7155b2 Merge branch 'main' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts into i2smic-nonint-patch-2 2022-11-09 09:54:37 -08:00
Melissa LeBlanc-Williams
18ab65af41
Merge pull request #233 from makermelissa/main
Fix rotation parameter for ST7789 displays
2022-11-04 08:04:28 -07:00
Melissa LeBlanc-Williams
2f8e05b9fc Fix rotation parameter for ST7789 displays 2022-11-03 17:25:46 -07:00
Melissa LeBlanc-Williams
2971dd189d
Merge pull request #231 from makermelissa/i2samp-update
Updated i2samp to run on 64-bit Raspberry Pi OS
2022-10-31 10:00:21 -07:00
Melissa LeBlanc-Williams
62a7515f84 Updated i2samp to run on 64-bit Raspberry Pi OS 2022-10-06 14:20:44 -07:00
Melissa LeBlanc-Williams
a779800e50
Merge pull request #229 from Kingfrankbob/main
Update rgb-matrix.sh With Spelling and some other useful things
2022-08-22 08:03:54 -07:00
Kingfrankbob
f5f8189b9b
Update rgb-matrix.sh 2022-08-19 17:59:52 -05:00
Melissa LeBlanc-Williams
5c21b388c5
Merge pull request #223 from makermelissa/main
Use user's home directory by default
2022-06-06 09:20:49 -06:00
Melissa LeBlanc-Williams
4188dec3f9 Use user's home directory by default 2022-06-03 09:05:03 -07:00
Melissa LeBlanc-Williams
8cfa5451a4
Merge pull request #222 from makermelissa/main
Added ability to specify boot directory as parameter
2022-06-03 09:06:16 -06:00
Melissa LeBlanc-Williams
6b60331f91 Added ability to specify boot directory as parameter 2022-06-01 13:45:14 -07:00
Melissa LeBlanc-Williams
95b2af2be8
Merge pull request #221 from makermelissa/main
Add initial working MIPI installer script and touch drivers
2022-04-26 14:51:46 -07:00
Melissa LeBlanc-Williams
4848a15557 Add initial working MIPI installer script and touch drivers 2022-04-26 14:14:45 -07:00
Melissa LeBlanc-Williams
b9438288ed
Merge pull request #220 from NickEngmann/main
fix(adafruit-pitft.py): libts dependency
2022-04-14 12:25:28 -07:00
Cyril "Nick" Engmann
9a03fea228
fix(adafruit-pitft.py): libts dependency 2022-04-14 15:18:25 -04:00
Melissa LeBlanc-Williams
ee839aa276
Merge pull request #218 from makermelissa/main
Added Raspberry Pi 400 support to i2smic
2022-03-21 13:46:28 -07:00
Melissa LeBlanc-Williams
23179eafe9 Added Raspberry Pi 400 support to i2smic 2022-03-21 10:16:57 -07:00
Melissa LeBlanc-Williams
5ed76a329e
Merge pull request #216 from makermelissa/main
Updated backlight to be on for latest kernel
2022-03-10 13:44:38 -08:00
Melissa LeBlanc-Williams
95b56a005c Updated backlight to be on for latest kernel 2022-03-10 09:40:03 -08:00
Paint Your Dragon
d25d137daf
Merge pull request #214 from adafruit/pb-matrix-python2or3
rgb-matrix.sh: add checks for Python 2 & 3, only install what’s right
2022-03-04 18:10:44 -08:00
Phillip Burgess
e75bbd339a rgb-matrix.sh: add checks for Python 2 & 3, only install what’s right
Latest Raspberry Pi OS does not have Python 2 installed by default. Script would fail as it’s trying to install things for both 2 & 3. Now checks which are present, acts accordingly.
2022-03-04 18:09:33 -08:00
Paint Your Dragon
f1060654ca
Merge pull request #94 from SkyperTHC/ntp_fix_etc
Ntp fix etc
2022-02-18 09:42:40 -08:00
Melissa LeBlanc-Williams
a23e745c48
Merge pull request #213 from makermelissa/main
Fix raspi-blinka script when `python` command is non-existent
2022-02-10 21:53:26 -08:00
Melissa LeBlanc-Williams
e946996f3f Fix raspi-blinka script when python command is non-existent 2022-02-10 14:03:49 -08:00
Melissa LeBlanc-Williams
9112e121d7
Merge pull request #212 from makermelissa/main
Add [all] for Pi config.txt
2022-02-10 11:55:40 -08:00
Melissa LeBlanc-Williams
0967b4f870 Add [all] for Pi config.txt 2022-02-10 11:28:52 -08:00
Melissa LeBlanc-Williams
379c8d3610
Merge pull request #211 from makermelissa/main
Install libgpiod-dev so pulsein works on blinka
2022-02-10 10:19:15 -08:00
Melissa LeBlanc-Williams
7393941132 Install libgpiod-dev so pulsein works on blinka 2022-02-10 10:09:07 -08:00
Paint Your Dragon
d83cd7b273
Merge pull request #210 from adafruit/pb-pi-read-only
read-only-fs.sh: exit with message, only keeping this temporarily
2022-02-07 15:04:43 -08:00
Phillip Burgess
6092030e8d read-only-fs.sh: exit with message, only keeping this temporarily 2022-02-07 15:02:23 -08:00
Paint Your Dragon
eb87a2206c
Merge pull request #207 from adafruit/pb-pi-4-eyes
pi-eyes.sh rewrite, allows Pi 4 use (corresponding code fixes in Pi_Eyes repo)
2022-01-11 09:03:16 -08:00
Phillip Burgess
d620d9bbcb pi-eyes.sh rewrite, allows Pi 4 use (corresponding code fixes in Pi_Eyes repo) 2022-01-11 09:02:03 -08:00
Melissa LeBlanc-Williams
eb56a34456
Merge pull request #205 from caternuson/iss204
Update rgb-matrix to latest hzeller commit hash
2021-12-16 09:26:27 -08:00
caternuson
b2a3d97895 update rgb-matrix hzeller commit 2021-12-15 17:43:42 -08:00
Melissa LeBlanc-Williams
622cfa430c
Merge pull request #202 from makermelissa/main
Updated Blinka Installer to not error when release info changed
2021-11-19 12:38:54 -08:00
Melissa LeBlanc-Williams
28aab54c0f Updated Blinka Installer to not error when release info changed 2021-11-19 12:36:14 -08:00
Melissa LeBlanc-Williams
288b439fd2
Merge pull request #200 from Margu86/pi_zero_2_w_update
Added Pi Zero 2 w model
2021-11-11 08:01:34 -08:00
Margu
ba7406516e
added RASPBERRY_PI_ZERO_2_W model 2021-11-11 15:09:54 +01:00
Melissa LeBlanc-Williams
a9c0da65b0
Merge pull request #199 from makermelissa/main
Add bullseye to i2samp version check
2021-11-10 11:07:41 -08:00
Melissa LeBlanc-Williams
99535aa278 Add bullseye to i2samp version check 2021-11-10 09:54:14 -08:00
Melissa LeBlanc-Williams
67b8103437
Merge pull request #197 from makermelissa/main 2021-11-09 18:53:37 -08:00
Melissa LeBlanc-Williams
1a78aab247 PiTFT fix for bullseye 2021-11-09 17:13:06 -08:00
Margu
a0a9ec62c2
added RASPBERRY_PI_ZERO_2_W to pi_model 0 2021-11-04 18:38:47 +01:00
Melissa LeBlanc-Williams
fa45350c9f
Merge pull request #126 from jessa0/geogriff/txbufflen
increase txbuflen to 32k to accomodate bcm2835
2021-09-09 14:35:04 -07:00
Melissa LeBlanc-Williams
d792adfc76
Merge branch 'main' into geogriff/txbufflen 2021-09-09 14:33:22 -07:00
Melissa LeBlanc-Williams
0355e7cc2d
Merge pull request #192 from makermelissa/main
Change backlight on ST7789 displays to be on by default
2021-09-09 10:33:27 -07:00
Melissa LeBlanc-Williams
db7808592b Change backlight on ST7789 displays to be on by default 2021-09-09 09:40:19 -07:00
Melissa LeBlanc-Williams
b06eecc58a
Merge pull request #191 from makermelissa/main
Fix pinning script to work on recent versions of kernel
2021-09-08 14:31:06 -07:00
Melissa LeBlanc-Williams
d980054dbd Fix pinning script to work on recent versions of kernel 2021-09-08 14:28:35 -07:00
Melissa LeBlanc-Williams
d97f80af23
Merge pull request #182 from makermelissa/main
Added script to handle reassigning CE0/CE1 for SPI
2021-06-15 17:15:27 -07:00
Melissa LeBlanc-Williams
c4108750c5 Added script to handle reassigning CE0/CE1 for SPI 2021-06-15 17:02:01 -07:00
Melissa LeBlanc-Williams
b5aeeec3b1
Merge pull request #181 from makermelissa/master
Display which OS was detected
2021-06-02 08:41:43 -07:00
Melissa LeBlanc-Williams
022e67421c Display which OS was detected 2021-06-01 09:22:31 -07:00
Bea Steers
16de141786
make i2smic noninteractive 2021-05-27 14:10:11 -04:00
Melissa LeBlanc-Williams
5d80647722
Merge pull request #177 from maziarzamani/patch-1
Update i2smic.py with support for RPi CM4
2021-05-11 07:40:40 -07:00
maziarzamani
e51fb55bf0
Update i2smic.py
Added support for RPI CM4
2021-05-11 12:36:56 +02:00
Melissa LeBlanc-Williams
3464d3b2f9
Merge pull request #167 from badcf00d/master
Improve framerate, add joystick + buttons for 1.3" TFT bonnet
2021-03-16 11:10:36 -07:00
Melissa LeBlanc-Williams
ef00e56b61
Merge pull request #170 from makermelissa/master
Add a check for Blinka's minimum required python version
2021-03-16 09:19:09 -07:00
Melissa LeBlanc-Williams
572e2aa874 Add a check for Blinka's minimum required python version 2021-03-16 08:53:42 -07:00
Melissa LeBlanc-Williams
da8a0e82bc
Merge pull request #168 from ezraholm50/patch-1
Fix for FBCP fail on various debian based OS
2021-03-15 16:43:03 -07:00
Ezra
b321ed165c
Fix for FBCP fail on various debian based OS
Fix for DietPI armv6 image
Ubuntu mentioned, not heard back from issue owner https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/issues/89
2021-03-15 21:14:36 +01:00
Peter Frost
242247c1f3 Add TFT 1.3" Bonnet + Joystick as a new device 2021-03-13 23:55:48 +00:00
Peter Frost
4136b91069 Revert "Add TFT bonnet keys & joystick to the device tree"
This reverts commit ca58673271.
2021-03-13 23:52:14 +00:00
Peter Frost
ba9f793277
Specify fps for st7789 based displays 2021-03-13 23:11:32 +00:00
Peter Frost
ca58673271
Add TFT bonnet keys & joystick to the device tree 2021-03-13 22:40:48 +00:00
Melissa LeBlanc-Williams
f8564631a4
Merge pull request #165 from makermelissa/master
Updated scripts to use new shell functions
2021-03-03 13:45:40 -08:00
Melissa LeBlanc-Williams
d40f66a409 Updated scripts to use new shell functions 2021-03-03 11:20:35 -08:00
Melissa LeBlanc-Williams
745f13e4c3
Merge pull request #164 from makermelissa/master
Added variable to control if kernel pinning is removed
2021-03-03 10:08:09 -08:00
Melissa LeBlanc-Williams
5821682048 Added a variable to control if kernel pinning is removed defaulting False. 2021-03-03 10:00:37 -08:00
Melissa LeBlanc-Williams
9f78e9b6a8
Merge pull request #163 from makermelissa/master
Fix error in fan service script
2021-03-02 09:46:46 -08:00
Melissa LeBlanc-Williams
9a0b4995d2 Fix error in fan service script 2021-03-02 09:35:19 -08:00
Melissa LeBlanc-Williams
d4fa6b7ca7
Merge pull request #161 from makermelissa/master
Updated Fan Service to use Raspi fan service on Raspberry Pis
2021-03-01 09:50:25 -08:00
Melissa LeBlanc-Williams
4c0dec3b10 Updated Fan Service to use Raspi fan service on Raspberry Pis 2021-03-01 09:00:22 -08:00
Melissa LeBlanc-Williams
caa4c95459
Merge pull request #160 from makermelissa/master
Fix script crashing on non st7789 displays
2021-03-01 08:38:23 -08:00
Melissa LeBlanc-Williams
d9285cffa5 Fix script crashing on non st7789 displays 2021-03-01 08:20:10 -08:00
Melissa LeBlanc-Williams
f9704fc473
Merge pull request #157 from makermelissa/driver-fix
ST7789 Driver fix
2021-02-26 11:00:19 -08:00
Melissa LeBlanc-Williams
0a514301a3 Added kernel pin checking and removal 2021-02-26 10:49:33 -08:00
Melissa LeBlanc-Williams
e237196448 Remove old driver again. It crashes. 2021-02-26 09:33:17 -08:00
Melissa LeBlanc-Williams
f2958a312a Put old 1.14 driver back in place 2021-02-26 08:37:53 -08:00
Melissa LeBlanc-Williams
f7513e009a Fix rotate parameter 2021-02-25 16:00:14 -08:00
Melissa LeBlanc-Williams
290ea02e24 Use 0 instead of None for consistency 2021-02-25 15:09:23 -08:00
Melissa LeBlanc-Williams
59c3fd0a91 Fix dict colons 2021-02-25 14:08:34 -08:00
Melissa LeBlanc-Williams
268b88c890 Fix another missing comma 2021-02-25 14:07:51 -08:00
Melissa LeBlanc-Williams
163ec88b2b Fix missing comma 2021-02-25 14:07:09 -08:00
Melissa LeBlanc-Williams
5cdf2f862c Update script to have flexible rotation sets 2021-02-25 14:05:41 -08:00
Melissa LeBlanc-Williams
5c00ae3e0a Overlay touchups 2021-02-25 11:11:29 -08:00
Melissa LeBlanc-Williams
8136d03488 Updated the Display driver and changed scripting to use single driver 2021-02-25 11:00:34 -08:00
Jessa
5f3468fce2 increase txbuflen to 32k to accomodate bcm2835
According to the fbtft wiki: "To maximize throughput, make sure txbuflen is 16k
or 32k (default is usually 4k). This is needed because of the DMA mapping/engine
overhead per transfer that spi-bcm2835 has."
2021-02-18 14:13:32 -08:00
Melissa LeBlanc-Williams
1d979b9e84
Merge pull request #154 from eternaltinkering/gpio-dependency
Dependency check for RPi.GPIO
2021-02-12 13:20:26 -08:00
pat
5ae7756391 check for RPi.GPIO which is a dependancy for:
Adafruit_Blinka/src/adafruit_blinka/microcontroller/bcm283x/pin.py
2021-02-12 14:04:17 -07:00
Melissa LeBlanc-Williams
626db3e1ff
Merge pull request #153 from makermelissa/master
Script fixes and updates
2021-02-12 12:55:22 -08:00
Melissa LeBlanc-Williams
ca07602e8d Merge branch 'master' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts 2021-02-11 19:10:04 -08:00
Melissa LeBlanc-Williams
e1c4f810d1 Script fixes 2021-02-11 19:09:52 -08:00
Melissa LeBlanc-Williams
60524f5831
Merge pull request #152 from makermelissa/master
Make pinning script output visible
2021-02-10 09:12:37 -08:00
Melissa LeBlanc-Williams
88781715d8 Make pinning script output visible 2021-02-10 09:09:20 -08:00
Limor "Ladyada" Fried
0427954aa5
Merge pull request #151 from makermelissa/master
Add pinning to pitft and fix driver
2021-02-08 18:56:41 -05:00
Melissa LeBlanc-Williams
1c88521146 Add pinning to pitft and fix driver 2021-02-08 15:00:10 -08:00
Melissa LeBlanc-Williams
7ff0364ee8
Merge pull request #150 from nekuneko/patch-1
just a little fix
2021-02-08 11:43:25 -08:00
Neku
01b8c3dafc
just a little fix
route to printf must be /usr/bin/printf instead of /bin/printf
2021-02-08 20:20:55 +01:00
Melissa LeBlanc-Williams
f2c3475d9f
Merge pull request #144 from makermelissa/master
Converted libgpiod script
2021-01-26 15:22:56 -08:00
Melissa LeBlanc-Williams
2cdc1c3f27 Merge branch 'master' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts 2021-01-26 15:10:30 -08:00
Melissa LeBlanc-Williams
210dcee138 Converted libgpiod script 2021-01-26 15:09:21 -08:00
Melissa LeBlanc-Williams
a644569d77
Merge pull request #143 from makermelissa/master
Old script cleanup and converted joy-bonnet
2021-01-26 13:47:44 -08:00
Melissa LeBlanc-Williams
aef5f7bdb6 Moved converted scripts and converted joy-bonnet 2021-01-26 13:20:46 -08:00
Melissa LeBlanc-Williams
fb47ecfa2c
Merge pull request #140 from makermelissa/master
Added jepler's kernel pinning script
2021-01-12 12:20:17 -07:00
Melissa LeBlanc-Williams
517637efbd Added jepler's kernel pinning script 2021-01-12 11:09:27 -08:00
Jeff Epler
b38b27e877
Merge pull request #137 from makermelissa/master
Use hdmi rotation for 270 degrees
2021-01-08 11:09:51 -06:00
Melissa LeBlanc-Williams
b2ebc27c57 Use hdmi rotation for 270 degrees 2021-01-07 17:11:36 -08:00
Melissa LeBlanc-Williams
a606044552
Merge pull request #136 from makermelissa/master
Fixed issue with 2.2-inch PiTFT and touchscreen param
2021-01-05 10:26:23 -07:00
Melissa LeBlanc-Williams
bea05b9490 Fixed issue with 2.2-inch PiTFT and touchscreen param 2021-01-05 09:19:12 -08:00
Limor "Ladyada" Fried
715a6bda9e
Merge pull request #130 from makermelissa/master
Roll back driver + couple small script fixes
2020-11-25 13:25:16 -05:00
Melissa LeBlanc-Williams
c4f2a384b4 Roll back driver + couple small script fixes 2020-11-25 10:20:24 -08:00
Melissa LeBlanc-Williams
e064d0d286
Merge pull request #129 from makermelissa/master
Fix 80 row offset issue for 1.3" display
2020-11-16 16:21:44 -07:00
Melissa LeBlanc-Williams
5627377cce Fix 80 row offset issue for 1.3" display 2020-11-16 15:16:08 -08:00
Limor "Ladyada" Fried
2521c7574e
Update raspi-blinka.py 2020-11-14 23:25:54 -05:00
Melissa LeBlanc-Williams
fcdb78d315
Merge pull request #125 from edmcdonagh/master
Corrected location of options
2020-10-10 20:33:13 -06:00
edmcdonagh
441e5881d4
Corrected location of options
Refs issue #124
2020-10-10 16:21:09 +01:00
Melissa LeBlanc-Williams
4dff4a305e
Merge pull request #123 from makermelissa/master
Bug fix for running pitft script interactively
2020-10-08 11:34:22 -06:00
Melissa LeBlanc-Williams
f0845e36bf Bug fix for running script interactively 2020-10-08 11:32:29 -06:00
Melissa LeBlanc-Williams
cfced2cb31
Merge pull request #121 from makermelissa/master
Update Fan Service Messages
2020-10-06 08:48:42 -06:00
Melissa LeBlanc-Williams
7c1719d67c Update Fan Service Messages 2020-10-06 08:43:58 -06:00
Limor "Ladyada" Fried
5c9a4cc0e0
Merge pull request #120 from makermelissa/master
Setting reboot prompt to Yes as default
2020-10-05 12:34:55 -04:00
Melissa LeBlanc-Williams
bbcad0bd0b Setting reboot prompt to Yes as default 2020-10-05 10:29:45 -06:00
Melissa LeBlanc-Williams
f8e3d34caf
Merge pull request #119 from makermelissa/master
Added initial Raspberry Pi Blinka Install/Config script
2020-10-01 14:06:42 -06:00
Melissa LeBlanc-Williams
74189e5324 Removed click since it's not currently used 2020-10-01 14:02:19 -06:00
Melissa LeBlanc-Williams
7e8515bf70 Added initial Raspberry Pi Config script 2020-10-01 13:59:07 -06:00
Limor "Ladyada" Fried
53a1672188
Merge pull request #118 from makermelissa/master
Fix auto reboot issue with pitft script
2020-09-30 08:04:26 -04:00
Melissa LeBlanc-Williams
c3f299956e Removed accidentally included file 2020-09-29 16:24:54 -06:00
Melissa LeBlanc-Williams
5b5a200c71 Fix auto reboot issue with pitft script 2020-09-29 16:22:21 -06:00
Limor "Ladyada" Fried
5988dab792
Merge pull request #117 from makermelissa/master
Added PyTFT script
2020-09-27 21:25:29 -04:00
Melissa LeBlanc-Williams
6a96118081 Fixed prompting of install type only if not specified 2020-09-27 08:45:26 -06:00
Melissa LeBlanc-Williams
35821306d3 Added PyTFT script 2020-09-27 08:39:25 -06:00
Melissa LeBlanc-Williams
245992f1fc
Merge pull request #115 from makermelissa/master
Changed positional to keyword argument
2020-09-22 14:56:58 -07:00
Melissa LeBlanc-Williams
1b02b83650 Changed positional to keyword argument 2020-09-22 15:43:20 -06:00
Limor "Ladyada" Fried
93fdfb8ae4
Merge pull request #114 from makermelissa/master
Added board autodetection for i2smic
2020-09-21 19:52:35 -04:00
Melissa LeBlanc-Williams
c803af1ae7 Added board autodetection for i2smic 2020-09-21 17:43:28 -06:00
Limor "Ladyada" Fried
8459250b8e
Merge pull request #113 from makermelissa/master
Updated both python scripts to use new Shell library
2020-08-30 12:34:58 -04:00
Melissa LeBlanc-Williams
d3c76a3e1a Updated both python scripts to use new Shell library 2020-08-27 15:10:46 -07:00
Phillip Burgess
9234544490 spectro.sh: remove deprecated --force-yes args to apt-get 2020-08-24 12:35:55 -07:00
Phillip Burgess
4aa0b9c354 Tweak Spectro script, don't mention single-core boards 2020-08-24 12:18:52 -07:00
Melissa LeBlanc-Williams
86ff8202b9
Merge pull request #112 from makermelissa/master
Converted i2smic to Python
2020-08-17 08:50:44 -07:00
Melissa LeBlanc-Williams
0996221e73 Converted i2smic to Python 2020-08-17 08:42:33 -07:00
Phillip Burgess
021db693ad Spectro: add RPi.GPIO to pip/pip3 installs 2020-08-14 17:00:17 -07:00
Limor "Ladyada" Fried
d596ff960d
Merge pull request #111 from makermelissa/master
Converted adafruit_fanservice to python
2020-08-14 17:21:25 -04:00
Melissa LeBlanc-Williams
bce0876471 Added check for clint 2020-08-14 13:57:33 -07:00
Melissa LeBlanc-Williams
0cba038922 Made some requested changes 2020-08-14 10:46:26 -07:00
Melissa LeBlanc-Williams
b7f04d58d7 Converted adafruit_fanservice to python 2020-08-14 10:20:14 -07:00
Melissa LeBlanc-Williams
450b38e10a
Merge pull request #110 from makermelissa/master
Added legacy option for systems with older linux headers
2020-08-12 08:12:24 -07:00
Melissa LeBlanc-Williams
fe48a15f6c Added legacy option for systems with older linux headers 2020-08-11 18:47:07 -07:00
Limor "Ladyada" Fried
30c45ecef3
Merge pull request #107 from makermelissa/master
Fix touch on capacitive 2.8 display for portrait modes
2020-08-04 09:52:14 -04:00
Melissa LeBlanc-Williams
fde1c0f526 Fix typos in rotation selection 2020-08-03 21:34:09 -07:00
Melissa LeBlanc-Williams
a581a7745c Fix touch on capacitive 2.8 display for portrait modes 2020-08-03 19:04:02 -07:00
Melissa LeBlanc-Williams
1ffb79a37f
Merge pull request #106 from makermelissa/master
Fix for Pi 4 portrait rotation
2020-08-03 14:19:34 -07:00
Melissa LeBlanc-Williams
533d6e60eb Fix for Pi 4 portrait rotation 2020-08-03 13:49:01 -07:00
lady ada
96eaee4493 simple fan service for gpio controlled fan 2020-08-03 14:42:58 -04:00
Limor "Ladyada" Fried
ce6bbbcc3e
Merge pull request #104 from adafruit/5.4_fixfbcp
5.4 fixfbcp
2020-08-03 11:43:14 -04:00
lady ada
77489b423b manual addition of
https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/pull/79
plus fix for
https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/issues/102
2020-08-03 10:13:38 -04:00
lady ada
8bc1771bb2 put backlight on pin 12 2020-08-02 22:41:35 -04:00
lady ada
a904ca8ca8 fix 1.3" tft backlight 2020-08-02 22:40:01 -04:00
lady ada
07a8bb9339 make 240x320 display use fbtft driver too 2020-08-02 22:18:54 -04:00
lady ada
ccf996aef7 remove unused offsets 2020-08-02 21:57:19 -04:00
lady ada
6fe27305d4 1.3/1.5" overlay to use fbtft staging driver 2020-08-02 21:40:59 -04:00
lady ada
3973bcdc3c add staging fbtft driver version 2020-08-02 21:38:01 -04:00
lady ada
4fe5212f64 undo hdmi mirroring 2020-08-02 14:28:40 -04:00
lady ada
1d717ab82e uninstall if service 2020-08-02 14:18:17 -04:00
lady ada
a69c9c7efb pi 4b no longer audo-switches to composite when no HDMI, so there's no /dev/fb0 - this forces HDMI out so we can fbcp something 2020-08-02 14:05:35 -04:00
Limor "Ladyada" Fried
340d2566fe
Merge pull request #103 from adafruit/st7789redux
St7789 redux
2020-07-31 11:19:05 -04:00
lady ada
a3ea15cfd9 fix the widths/heights 2020-07-29 18:23:16 -04:00
lady ada
4b41f91736 add comments 2020-07-29 18:05:33 -04:00
lady ada
bf049e9e92 this is a terrible hack but couldnt figure out why the backlight pin was not attaching to gpio 26 :/ 2020-07-29 17:45:37 -04:00
lady ada
d046e3fd42 fix backlight pins 2020-07-28 13:03:20 -04:00
lady ada
45802ac9a6 fix selection menu to not break existing examples 2020-07-28 11:25:09 -04:00
lady ada
57cf3adc62 add test overlay for fullscreen st7789v 2020-07-28 11:00:21 -04:00
lady ada
e2fe053c31 fix up installer for all st7789's 2020-07-28 00:15:15 -04:00
lady ada
72596df87c lessdebug 2020-07-27 23:59:55 -04:00
lady ada
cd981e348b renames + good math 2020-07-27 23:58:57 -04:00
lady ada
72002bc814 fix 240x240 rotations 2020-07-27 19:15:57 -04:00
lady ada
861299c18a add dirty rectangle handler 2020-07-27 16:14:19 -04:00
lady ada
fc8dcd7ffb start process of re-porting st7789 driver. currently working for 240x240 display with overlay. need to redo dirty function 2020-07-27 15:14:11 -04:00
Carter Nelson
55539a84a1
Merge pull request #97 from caternuson/remove_dkms
Remove I2S mic driver DKMS
2020-07-08 13:48:17 -07:00
caternuson
6598ace123 remove dkms 2020-07-08 13:30:16 -07:00
SkyperTHC
d514547880 fixed NTPD in systemctl ntp.services to use non-private tmpfs 2020-06-07 07:03:19 +01:00
SkyperTHC
6ccbc2e73b 1. See https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/issues/92
ntpd started from 'systemctl' (via dhcpcd hook) can not follow symlink
from /etc/resolv.conf to /tmp/dhcpcd.resolv.conf. For now should remain
in /etc/resolv.conf (hard coded).
stat64("/etc/resolv.conf", 0xbea7af80) = -1 ENOENT (No such file or
directory)
2. Never fsck on any volumne. Linux runs a fsck every 6 month even on
ro-volumnes. Any fs corruption makes fsck stall during bootup and
requires user to confirm to continue.
3. Disable viminfo to stop vim from complaining about ~/.viminfo not
writeable.
2020-06-07 06:32:21 +01:00
Melissa LeBlanc-Williams
673a7cfd5a
Merge pull request #90 from makermelissa/master
Added uninstall option to PiTFT
2020-05-15 18:49:48 -07:00
Melissa LeBlanc-Williams
6336cf1a73 Added uninstall option to PiTFT 2020-05-15 17:09:57 -07:00
Melissa LeBlanc-Williams
c94fe6a1de
Merge pull request #86 from makermelissa/master
Added 2.0" TFT to PiTFT script
2020-04-23 13:17:31 -07:00
Melissa LeBlanc-Williams
e5f40f93d0 Added 2.0" TFT to PiTFT script 2020-04-23 11:03:43 -07:00
Melissa LeBlanc-Williams
b5a6cce854
Merge pull request #84 from caternuson/iss83
Update udev rule for cap touch
2020-04-20 09:56:00 -07:00
Carter Nelson
5537cfc6d2
Merge pull request #82 from caternuson/i2s_mic
Add I2S mic setup
2020-04-19 12:35:46 -07:00
caternuson
94f147b64f update udev for cap touch 2020-04-16 15:32:47 -07:00
caternuson
0de6e91c1a add i2s mic setup 2020-04-16 10:02:03 -07:00
Phillip Burgess
3342bb2bc3 Merge branch 'master' of https://github.com/adafruit/Raspberry-Pi-Installer-Scripts 2020-03-20 15:55:16 -07:00
Phillip Burgess
3987110b87 pi-eyes.sh: specify pi3d version 2020-03-20 15:55:13 -07:00
Melissa LeBlanc-Williams
b946a8065f
Merge pull request #76 from makermelissa/master
Fixes Capacitive screen rotation in buster
2020-03-09 09:04:19 -07:00
Melissa LeBlanc-Williams
9af17f1d2b Fixes Capacitive screen rotation in buster 2020-03-09 08:45:42 -07:00
Phillip Burgess
a3e70cb2d2 Add Blinka stuff to Pi Eyes installer 2020-02-07 22:07:19 -08:00
Phillip Burgess
58cca634ac pi-eyes.sh: initial pass at Python3ification (more to follow) 2020-02-06 14:46:06 -08:00
Melissa LeBlanc-Williams
c9d0ee84ef
Merge pull request #73 from makermelissa/master
Added 240x240 MADCTL injection based on rotation selection
2020-02-05 17:49:42 -08:00
Melissa LeBlanc-Williams
1ccd4d3453 Added unshifted setting for 0 and 90 degrees 2020-02-05 15:57:18 -08:00
Melissa LeBlanc-Williams
1b999b095f Added 240x240 MADCTL injection based on rotation selection 2020-02-05 15:40:30 -08:00
Limor "Ladyada" Fried
0d345d09de
Merge pull request #72 from makermelissa/master
Moved spi-bcm2835 to be first in /etc/modules
2020-02-05 14:16:20 -05:00
Melissa LeBlanc-Williams
6d09eaa8b2 Moved spi-bcm2835 to be first in /etc/modules 2020-02-05 11:07:34 -08:00
Lady Ada
ab167175f2 clarify 1.3" display option! 2020-01-25 17:31:25 -05:00
Phillip Burgess
fb2b5ccf27 Spectro installer, plus other minor fixes 2020-01-16 20:27:46 -08:00
Phillip Burgess
204d71afc7 rgb-matrix.sh: remove slowdown opts, simplify build steps
Baked-in slowdown options aren't acknowledged by Python bindings, no point having that added installation complexity.
2020-01-01 22:03:27 -08:00
Phillip Burgess
a03767c759 rgb-matrix.sh: add GPIO slowdown options 2020-01-01 21:12:49 -08:00
Phillip Burgess
8c3f5dd7b6 Add spectro.sh 2019-12-17 20:55:40 -08:00
Paint Your Dragon
2b541cf370
Merge pull request #65 from adafruit/update-rgb-matrix
rgb-matrix.sh: use current hzeller commit (tested & verified on Pi 4)
2019-12-10 17:23:44 -08:00
Phillip Burgess
d3ea424289 rgb-matrix.sh: use current hzeller commit (tested & verified on Pi 4) 2019-12-10 17:23:16 -08:00
Limor "Ladyada" Fried
a76596aa98
Merge pull request #63 from adafruit/st7789
St7789 mini pitft support
2019-10-23 15:27:55 -04:00
70 changed files with 7334 additions and 972 deletions

68
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View file

@ -0,0 +1,68 @@
name: 🐞 Bug Report
description: Create a bug report to help us improve
labels:
- bug
body:
- type: markdown
attributes:
value: >-
Thanks! for using the installer scripts. Now that you have encountered a
bug... you can file a report for it.
- type: textarea
id: script
attributes:
label: Script Command
description: >-
Include the exact command you're running with any parameters. There are quite
a handful of scripts and knowing which one is helpful. :)
placeholder: sudo python3 adafruit-pitft.py --display=28r --rotation=90 --install-type=console
render: shell
validations:
required: true
- type: textarea
id: os
attributes:
label: Operating System
description: >-
Which OS was the script running under? Include details such as if it
was 32 or 64-bit, Whether it was the Lite of Full Desktop version. If it's on an older or newer
kernel, include that as well.
placeholder: |
64-bit Raspberry Pi OS Lite with Bullseye
validations:
required: true
- type: textarea
id: hardware
attributes:
label: Hardware
description: This is the board or computer you are running the script on.
placeholder: |
Raspberry Pi 4B
validations:
required: true
- type: textarea
id: behavior
attributes:
label: Behavior
description: What happens when you run the script above? Include error messages (if any).
placeholder: |
An error occurs at line 459 with this message...
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: Optionally, describe the bug in more detail.
placeholder: |
- I selected options 1, then 3, then 4...
- Only happens when...
- might be related to #123...
- type: textarea
id: more-info
attributes:
label: Additional information
description: >-
Optionally, add any other information like hardware connection, scope
output etc. If you have already done some debugging, mention it here.
placeholder: Removing [this](url) line resolves the issue.

7
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1,7 @@
contact_links:
- name: 🔗 Adafruit Forum
url: https://forums.adafruit.com/
about: Official Adafruit technical support forum. Good for getting help on getting a project working.
- name: 🔗 Adafruit Discord
url: https://adafru.it/discord
about: Unofficial chat with many helpful folks and normally prompt replies.

View file

@ -0,0 +1,11 @@
---
name: 🚀 Feature Request
about: Suggest an idea for this project
title: ''
labels: 'enhancement'
assignees: ''
---
<!-- If you have an idea for any new features and enhancements to any of our scripts 🚀
and would love ❤ to see what ideas you have for us... 🙂 -->

16
.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2019 Adafruit Industries
#
# SPDX-License-Identifier: Unlicense
*.mpy
.idea
__pycache__
_build
*.pyc
.env
build*
bundles
*.DS_Store
.eggs
dist
**/*.egg-info

View file

@ -2,6 +2,36 @@
Some scripts for helping install Adafruit HATs, bonnets, add-on's, & friends!
Based heavily on get.pimoroni.com scripts!
Many scripts are based heavily on get.pimoroni.com scripts!
* Install i2s amplifier with: curl -sS https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/i2samp.sh | bash
## Python Scripts
We are in the process of converting our Shell Scripts to Python. Instructions for running specific scripts are available in the [Adafruit Learning System](https://learn.adafruit.com/). Here are the general setup instructions.
### Dependencies
- Python 3
- [Adafruit_Python_Shell](https://github.com/adafruit/Adafruit_Python_Shell)
- [Click](https://pypi.org/project/click/)
### Prepare your system
To install the dependencies for the python scripts, run the following commands:
```bash
sudo apt-get install python3-pip
sudo pip3 install --upgrade click
sudo pip3 install --upgrade setuptools
sudo pip3 install --upgrade adafruit-python-shell
```
Then to run the python script, type the following replacing "scriptname.py" with the actual script name:
```bash
sudo python3 scriptname.py
```
## Old Shell Scripts
If you were directed here from an external site and the script you were looking for appears to be missing, you can either use the newer python script or check the [converted_shell_scripts](https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/tree/main/converted_shell_scripts) folder to use the old shell scripts.

1054
adafruit-pitft.py Normal file

File diff suppressed because it is too large Load diff

93
adafruit_fanservice.py Normal file
View file

@ -0,0 +1,93 @@
"""
Adafruit Raspberry Pi Fan Service Setup Script
(C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
Converted to Python by Melissa LeBlanc-Williams for Adafruit Industries
"""
import os
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 = 'ADAFRUIT'
def main():
shell.clear()
if shell.is_raspberry_pi():
print("""This script will enable the Raspberry Pi
fan service, which will turn on an
external fan controlled by a given pin
Operations performed include:
- Enable Fan Service
Run time < 1 minute. Reboot required.""")
else:
print("""This script will install Adafruit
fan service, which will turn on an
external fan controlled by a given pin
Operations performed include:
- Create a Fan Service File
- Enable Fan Service
- Automatically Start Fan Service
on System startup
Run time < 1 minute. Reboot not required.""")
if not shell.argument_exists('y'):
if not shell.prompt("CONTINUE?", default='n'):
print("Canceled.")
shell.exit()
print("Continuing...")
# check init system (technique borrowed from raspi-config):
shell.group = 'FAN'
shell.info('Checking init system...')
if shell.run_command("which systemctl", suppress_message=True) and shell.run_command("systemctl | grep '\-\.mount'", suppress_message=True):
print("Found systemd, OK!")
elif os.path.isfile("/etc/init.d/cron") and not os.path.islink("/etc/init.d/cron"):
shell.bail("Found sysvinit, but we require systemd")
else:
shell.bail("Unrecognised init system")
if shell.is_raspberry_pi():
shell.info('Enabling Raspberry Pi Fan Service on GPIO 4')
shell.run_command("sudo raspi-config nonint do_fan 0 4")
shell.info('Done!')
shell.prompt_reboot()
else:
shell.info('Adding adafruit_fan.service')
contents = """[Unit]
Description=Fan service for some Adafruit boards
After=network.target
[Service]
Type=oneshot
ExecStartPre=-/bin/bash -c 'echo 4 >/sys/class/gpio/export'
ExecStartPre=/bin/bash -c 'echo out >/sys/class/gpio/gpio4/direction'
ExecStart=/bin/bash -c 'echo 1 >/sys/class/gpio/gpio4/value'
RemainAfterExit=true
ExecStop=/bin/bash -c 'echo 0 >/sys/class/gpio/gpio4/value'
StandardOutput=journal
[Install]
WantedBy=multi-user.target"""
shell.write_text_file("/etc/systemd/system/adafruit_fan.service", contents, append=False)
shell.info('Enabling adafruit_fan.service')
shell.run_command("sudo systemctl enable adafruit_fan.service")
shell.run_command("sudo systemctl start adafruit_fan.service")
shell.info('Done!')
print("You can stop the fan service with 'sudo systemctl stop adafruit_fan.service'")
print("You can start the fan service with 'sudo systemctl start adafruit_fan.service'")
# Main function
if __name__ == "__main__":
shell.require_root()
main()

237
ar1100.py Normal file
View file

@ -0,0 +1,237 @@
#!/usr/bin/python
import usb.core
import usb.util
import time
import os
import pygame
from pygame.locals import *
def mapnum(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
CALIBRATED_5IN_800x480 = [
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x55, 0x80, 0x05, 0x05, 0x40, 0x03, 0x00, 0x20, 0x00, 0x50, 0x00, 0x80, 0x00, 0xb0, 0x00, 0xe0,
0x00, 0x20, 0x00, 0x50, 0x00, 0x80, 0x00, 0xb0, 0x00, 0xe0, 0x4d, 0x2a, 0x3a, 0x2b, 0xcb, 0x56,
0xb5, 0x29, 0x18, 0x82, 0xe9, 0x29, 0x41, 0xad, 0x06, 0x2b, 0x16, 0xd9, 0x42, 0x2a, 0x45, 0x29,
0x82, 0x53, 0x10, 0x56, 0xda, 0x54, 0x99, 0x81, 0xcf, 0x55, 0x5e, 0xac, 0xec, 0x55, 0x83, 0xd8,
0xcf, 0x55, 0xf1, 0x29, 0x3d, 0x82, 0xa0, 0x55, 0x11, 0x82, 0x22, 0x81, 0x4b, 0x81, 0x47, 0xad,
0xc2, 0x82, 0x06, 0xd9, 0xc8, 0x82, 0x65, 0x2a, 0xda, 0xac, 0xc1, 0x55, 0xa3, 0xac, 0xeb, 0x80,
0x26, 0xae, 0x27, 0xac, 0xd9, 0xad, 0x8e, 0xd8, 0xd9, 0xae, 0x8b, 0x28, 0xb9, 0xda, 0x9a, 0x54,
0x59, 0xdb, 0x1e, 0x7f, 0x78, 0xdc, 0x0f, 0xad, 0xdd, 0xdc, 0x88, 0xd8, 0xde, 0xdb, 0x00, 0x00,
]
CALIBRATED_7IN_800x480 = [
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x55, 0x80, 0x03, 0x03, 0x40, 0x02, 0x00, 0x20, 0x00, 0x80, 0x00, 0xe0, 0x00, 0xb0, 0x00, 0xe0,
0x00, 0x20, 0x00, 0x80, 0x00, 0xe0, 0x00, 0xb0, 0x00, 0xe0, 0x7f, 0x22, 0x5c, 0x2d, 0xbf, 0x7d,
0xdd, 0x2a, 0xaf, 0xdc, 0xf3, 0x2b, 0x21, 0x23, 0xb2, 0x82, 0xb4, 0x80, 0x4c, 0x82, 0x40, 0xde,
0xe7, 0x85, 0x42, 0x23, 0xcc, 0xd6, 0xda, 0x7e, 0x7d, 0xd7, 0xd9, 0xdc, 0x8b, 0xd8, 0x83, 0xd8,
0xcf, 0x55, 0xf1, 0x29, 0x3d, 0x82, 0xa0, 0x55, 0x11, 0x82, 0x22, 0x81, 0x4b, 0x81, 0x47, 0xad,
0xc2, 0x82, 0x06, 0xd9, 0xc8, 0x82, 0x65, 0x2a, 0xda, 0xac, 0xc1, 0x55, 0xa3, 0xac, 0xeb, 0x80,
0x26, 0xae, 0x27, 0xac, 0xd9, 0xad, 0x8e, 0xd8, 0xd9, 0xae, 0x8b, 0x28, 0xb9, 0xda, 0x9a, 0x54,
0x59, 0xdb, 0x1e, 0x7f, 0x78, 0xdc, 0x0f, 0xad, 0xdd, 0xdc, 0x88, 0xd8, 0xde, 0xdb, 0x00, 0x00,
]
writeeeprom = CALIBRATED_5IN_800x480;
USB_MODE_GENERIC = [0x55, 0x01, 0x70]
USB_MODE_MOUSE = [0x55, 0x01, 0x71]
MCP_VID = 0x04D8
MOUSE_PID = 0x0C02
GENERIC_PID = 0x0C01
# Try to locate it as a mouse:
dev = usb.core.find(idVendor=MCP_VID, idProduct=MOUSE_PID)
if dev:
# first endpoint
interface = 0
endpoint = dev[0][(0,0)][0]
# if the OS kernel already claimed the device, which is most likely true
# thanks to http://stackoverflow.com/questions/8218683/pyusb-cannot-set-configuration
if dev.is_kernel_driver_active(interface) is True:
# tell the kernel to detach
dev.detach_kernel_driver(interface)
# claim the device
usb.util.claim_interface(dev, interface)
# try to send it command to swap to generic HID
try:
# turn into HID
# bReq, wVal, wIndex, data
ret = dev.ctrl_transfer(0x21, 0x09, 0x0003, 0x0000, [0x55, 0x01, 0x70])
if (ret == 3):
print("Turned into HID!")
except:
# failed to get data for this request
print("Failed to turn into HID")
exit(-1)
# Try to locate it as a mouse:
dev = usb.core.find(idVendor=MCP_VID, idProduct=GENERIC_PID)
if (not dev):
print("Couldn't find generic either :/")
exit(-1)
print("Found Generic!")
interface = 0
endpoint = dev[0][(0,0)][1]
while True:
#try:
if dev.is_kernel_driver_active(interface) is True:
# tell the kernel to detach
dev.detach_kernel_driver(interface)
# claim the device
usb.util.claim_interface(dev, interface)
time.sleep(1)
dev.set_configuration()
break
#except:
# print("retrying set config...")
print("Writing EEPROM...")
for addr in range (0x60, 0xFF, 8):
msg = [0x55, 0x04 + 8, 0x29, 0x00, addr, 8]
msg.extend(writeeeprom[addr-0x60:addr-0x60+8])
#print(msg)
#print(', '.join([hex(i) for i in msg]))
ret = dev.write(1, msg)
#print("Wrote : ", ret)
ret = dev.read(0x81, 64)
#print("Read : ", readeeprom.extend(ret[4:20]))
#print(', '.join([hex(i) for i in ret[0:4]]))
if ret[2] != 0:
print("Failed to write")
exit(-1)
print("Reading EEPROM...")
readeeprom = []
for addr in range (0x60, 0xF8 , 16):
msg = [0x55, 0x04, 0x28, 0x00, addr, 16]
ret = dev.write(1, msg)
#print("Wrote :", ret)
ret = dev.read(0x81, 64)
#print("Read :",ret)
readeeprom.extend(ret[4:20])
#print(', '.join([hex(i) for i in ret[4:20]]))
for i in range(len(readeeprom)):
print(("0x%02x," % readeeprom[i]), end='')
if (i % 16 == 15):
print("")
#print(", 0x%2X".join([hex (i) for i in readeeprom]))
# compare eeproms
if (writeeeprom != readeeprom):
print("Failed to write eeprom correctly (verification fail)")
exit(-1)
print("EEPROM verified OK!")
# try to send it command to swap to generic HID
try:
# turn into Mouse
# bReq, wVal, wIndex, data
ret = dev.ctrl_transfer(0x21, 0x09, 0x0003, 0x0000, [0x55, 0x01, 0x71])
if (ret == 3):
print("Turned into Mouse!")
except:
# failed to get data for this request
print("Failed to turn into Mouse")
exit(-1)
try:
# release the device
usb.util.release_interface(dev, interface)
# reattach the device to the OS kernel
dev.attach_kernel_driver(interface)
except:
pass
time.sleep(3)
# Try to locate it as a mouse:
dev = usb.core.find(idVendor=MCP_VID, idProduct=MOUSE_PID)
if not dev:
print("No mouse :(")
exit(-1)
# first endpoint
interface = 0
endpoint = dev[0][(0,0)][0]
# if the OS kernel already claimed the device, which is most likely true
# thanks to http://stackoverflow.com/questions/8218683/pyusb-cannot-set-configuration
if dev.is_kernel_driver_active(interface) is True:
# tell the kernel to detach
dev.detach_kernel_driver(interface)
# claim the device
usb.util.claim_interface(dev, interface)
# set up pygame
white = (255, 255, 255)
w = 800
h = 480
# Output to the LCD instead of the console
os.putenv("DISPLAY", ":0")
pygame.init()
screen = pygame.display.set_mode((w, h))
running = 1
img = pygame.image.load('gradient800x480.jpg')
screen.fill((white))
screen.blit(img,(0,0))
pygame.display.flip()
while running:
for event in pygame.event.get():
print(event)
if event.type == QUIT:
exit(0)
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
exit(0)
try:
data = dev.read(endpoint.bEndpointAddress,endpoint.wMaxPacketSize)
#print(data)
x = data[1] + (data[2] << 8)
y = data[3] + (data[4] << 8)
#print(x, y)
x = mapnum(x, 0, 4096, 0, w)
y = mapnum(y, 0, 4096, 0, h)
print(x, y)
pygame.draw.circle(screen, white, (x,y), 10)
pygame.display.flip()
except usb.core.USBError as e:
data = None
if e.args == ('Operation timed out',):
continue
# release the device
usb.util.release_interface(dev, interface)
# reattach the device to the OS kernel
dev.attach_kernel_driver(interface)

View file

@ -110,8 +110,8 @@ echo "Updating package index files..."
apt-get update
echo "Installing Python libraries..."
apt-get install -y --force-yes python-pip python-dev python-smbus
pip install evdev
apt-get install -y python3-pip
pip3 install evdev smbus
echo "Installing Adafruit code in /boot..."
cd /tmp
@ -158,10 +158,10 @@ fi
grep arcadeBonnet.py /etc/rc.local >/dev/null
if [ $? -eq 0 ]; then
# arcadeBonnet.py already in rc.local, but make sure correct:
sed -i "s/^.*arcadeBonnet.py.*$/cd \/boot;python arcadeBonnet.py \&/g" /etc/rc.local >/dev/null
sed -i "s/^.*arcadeBonnet.py.*$/cd \/boot;python3 arcadeBonnet.py \&/g" /etc/rc.local >/dev/null
else
# Insert arcadeBonnet.py into rc.local before final 'exit 0'
sed -i "s/^exit 0/cd \/boot;python arcadeBonnet.py \&\\nexit 0/g" /etc/rc.local >/dev/null
sed -i "s/^exit 0/cd \/boot;python3 arcadeBonnet.py \&\\nexit 0/g" /etc/rc.local >/dev/null
fi
# Add udev rule (will overwrite if present)

View file

@ -15,7 +15,7 @@ fi
UPDATE_DB=false
UNINSTALL=false
############################ CALIBRATIONS ############################
# For TSLib
@ -47,6 +47,10 @@ TRANSFORM_28c90="0 1 0 -1 0 1 0 0 1"
TRANSFORM_28c180="1 0 0 0 1 0 0 0 1"
TRANSFORM_28c270="0 -1 1 1 0 0 0 0 1"
ROTATE_28c0="rotate=90,touch-invx=true,touch-invy=true"
ROTATE_28c90="rotate=90,touch-swapxy=true,touch-invx=true"
ROTATE_28c180="rotate=90"
ROTATE_28c270="rotate=270,touch-swapxy=true,touch-invy=true"
warning() {
echo WARNING : $1
@ -196,20 +200,28 @@ function softwareinstall() {
pip install evdev 1> /dev/null || { warning "Pip failed to install software!" && exit 1; }
}
# update /boot/config.txt with appropriate values
function update_configtxt() {
# Remove any old flexfb/fbtft stuff
function uninstall_bootconfigtxt() {
if grep -q "adafruit-pitft-helper" "/boot/config.txt"; then
echo "Already have an adafruit-pitft-helper section in /boot/config.txt."
echo "Removing old section..."
cp /boot/config.txt /boot/configtxt.bak
sed -i -e "/^# --- added by adafruit-pitft-helper/,/^# --- end adafruit-pitft-helper/d" /boot/config.txt
fi
}
# remove any old flexfb/fbtft stuff
# Remove any old flexfb/fbtft stuff
function uninstall_etc_modules() {
rm -f /etc/modprobe.d/fbtft.conf
sed -i 's/spi-bcm2835//g' "/etc/modules"
sed -i 's/flexfb//g' "/etc/modules"
sed -i 's/fbtft_device//g' "/etc/modules"
sed -i 's/spi-bcm2835//g' "/etc/modules"
}
# update /boot/config.txt with appropriate values
function update_configtxt() {
uninstall_bootconfigtxt
uninstall_etc_modules
if [ "${pitfttype}" == "22" ]; then
overlay="dtoverlay=pitft22,rotate=${pitftrot},speed=64000000,fps=30"
@ -220,44 +232,50 @@ function update_configtxt() {
fi
if [ "${pitfttype}" == "28c" ]; then
overlay="dtoverlay=pitft28-capacitive,rotate=${pitftrot},speed=64000000,fps=30"
rotateparams=$(eval echo "\$ROTATE_$pitfttype$touchrot")
overlay=$(printf "dtoverlay=pitft28-capacitive,speed=64000000,fps=30\ndtoverlay=pitft28-capacitive,${rotateparams}")
fi
if [ "${pitfttype}" == "35r" ]; then
overlay="dtoverlay=pitft35-resistive,rotate=${pitftrot},speed=20000000,fps=20"
fi
if [ "${pitfttype}" == "st7789_240x320" ]; then
dtc -@ -I dts -O dtb -o /boot/overlays/drm-st7789v_240x320.dtbo overlays/st7789v_240x320-overlay.dts
overlay="dtoverlay=drm-st7789v_240x320,rotate=${pitftrot}"
fi
if [ "${pitfttype}" == "st7789_240x240" ]; then
cat >> /etc/modprobe.d/fbtft.conf <<EOF
# --- added by adafruit-pitft-helper $date ---
options fbtft_device name=flexfb gpios=dc:25,cs:8,led:26 speed=40000000 bgr=1 fps=60
options flexfb setaddrwin=0 width=240 height=240 init=-1,0x11,-2,120,-1,0x36,0x00,-1,0x3A,0x05,-1,0xB2,0x0C,0x0C,0x00,0x33,0x33,-1,0xB7,0x35,-1,0xBB,0x1A,-1,0xC0,0x2C,-1,0xC2,0x01,-1,0xC3,0x0B,-1,0xC4,0x20,-1,0xC6,0x0F,-1,0xD0,0xA4,0xA1,-1,0x21,-1,0xE0,0x00,0x19,0x1E,0x0A,0x09,0x15,0x3D,0x44,0x51,0x12,0x03,0x00,0x3F,0x3F,-1,0xE1,0x00,0x18,0x1E,0x0A,0x09,0x25,0x3F,0x43,0x52,0x33,0x03,0x00,0x3F,0x3F,-1,0x29,-3
# --- end adafruit-pitft-helper $date ---
EOF
echo "flexfb" >> /etc/modules
echo "fbtft_device" >> /etc/modules
echo "spi-bcm2835" >> /etc/modules
overlay=""
dtc -@ -I dts -O dtb -o /boot/overlays/drm-minipitft13.dtbo overlays/minipitft13-overlay.dts
overlay="dtoverlay=drm-minipitft13,rotate=${pitftrot}"
fi
if [ "${pitfttype}" == "st7789_240x135" ]; then
dtc -@ -I dts -O dtb -o /boot/overlays/drm-minipitft114.dtbo overlays/minipitft114-overlay.dts
overlay="dtoverlay=drm-minipitft114,rotation=${pitftrot}"
fi
# any/all st7789's need their own kernel driver
if [ "${pitfttype}" == "st7789_240x240" ] || [ "${pitfttype}" == "st7789_240x320" ] || [ "${pitfttype}" == "st7789_240x135" ]; then
echo "############# UPGRADING KERNEL ###############"
sudo apt update || { warning "Apt failed to update itself!" && exit 1; }
sudo apt-get upgrade || { warning "Apt failed to install software!" && exit 1; }
apt-get install -y raspberrypi-kernel-headers 1> /dev/null || { warning "Apt failed to install software!" && exit 1; }
[ -d /lib/modules/$(uname -r)/build ] || { warning "Kernel was updated, please reboot now and re-run script!" && exit 1; }
cd st7789_module
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules || { warning "Apt failed to compile ST7789V driver!" && exit 1; }
mv /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tinydrm/mi0283qt.ko /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tinydrm/mi0283qt.BACK
mv st7789v_ada.ko /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tinydrm/mi0283qt.ko
overlay="dtoverlay=drm-minipitft114,rotation=${pitftrot}"
pushd st7789_module
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules || { warning "Apt failed to compile ST7789V drivers!" && exit 1; }
mv /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tiny/mi0283qt.ko /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tiny/mi0283qt.BACK
mv /lib/modules/$(uname -r)/kernel/drivers/staging/fbtft/fb_st7789v.ko /lib/modules/$(uname -r)/kernel/drivers/staging/fbtft/fb_st7789v.BACK
mv st7789v_ada.ko /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tiny/mi0283qt.ko
mv fb_st7789v.ko /lib/modules/$(uname -r)/kernel/drivers/staging/fbtft/fb_st7789v.ko
popd
fi
date=`date`
cat >> /boot/config.txt <<EOF
# --- added by adafruit-pitft-helper $date ---
hdmi_force_hotplug=1 # required for cases when HDMI is not plugged in!
dtparam=spi=on
dtparam=i2c1=on
dtparam=i2c_arm=on
@ -272,6 +290,7 @@ SUBSYSTEM=="input", ATTRS{name}=="touchmouse", ENV{DEVNAME}=="*event*", SYMLINK+
EOF
cat > /etc/udev/rules.d/95-ftcaptouch.rules <<EOF
SUBSYSTEM=="input", ATTRS{name}=="EP0110M09", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
SUBSYSTEM=="input", ATTRS{name}=="generic ft5x06*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
EOF
cat > /etc/udev/rules.d/95-stmpe.rules <<EOF
SUBSYSTEM=="input", ATTRS{name}=="*stmpe*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
@ -334,9 +353,9 @@ function uninstall_console() {
function install_fbcp() {
echo "Installing cmake..."
apt-get --yes --force-yes install cmake 1> /dev/null || { warning "Apt failed to install software!" && exit 1; }
apt-get --yes --allow-downgrades --allow-remove-essential --allow-change-held-packages install cmake 1> /dev/null || { warning "Apt failed to install software!" && exit 1; }
echo "Downloading rpi-fbcp..."
cd /tmp
pushd /tmp
#curl -sLO https://github.com/tasanakorn/rpi-fbcp/archive/master.zip
curl -sLO https://github.com/adafruit/rpi-fbcp/archive/master.zip
echo "Uncompressing rpi-fbcp..."
@ -351,7 +370,7 @@ function install_fbcp() {
make 1> /dev/null || { warning "Failed to make fbcp!" && exit 1; }
echo "Installing rpi-fbcp..."
install fbcp /usr/local/bin/fbcp
cd ~
popd
rm -rf /tmp/rpi-fbcp-master
# Start fbcp in the appropriate place, depending on init system:
@ -387,6 +406,7 @@ function install_fbcp() {
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"
reconfig /boot/config.txt "^[^#]*dtoverlay=vc4-fkms-v3d.*$" "#dtoverlay=vc4-fkms-v3d"
# if there's X11 installed...
if [ -e /etc/lightdm ]; then
@ -401,11 +421,14 @@ function install_fbcp() {
echo "Using native resolution"
SCALE=1
fi
WIDTH=`python -c "print(int(${WIDTH_VALUES[PITFT_SELECT-1]} * ${SCALE}))"`
HEIGHT=`python -c "print(int(${HEIGHT_VALUES[PITFT_SELECT-1]} * ${SCALE}))"`
reconfig /boot/config.txt "^.*hdmi_cvt.*$" "hdmi_cvt=${WIDTH} ${HEIGHT} 60 1 0 0 0"
if [ "${pitftrot}" == "90" ] || [ "${pitftrot}" == "270" ]; then
if [ "${pitftrot}" == "90" ] || [ "${pitftrot}" == "270" ] || [ "${pitfttype}" == "st7789_240x320" ]; then
# dont rotate HDMI on 90 or 270
reconfig /boot/config.txt "^.*display_hdmi_rotate.*$" ""
fi
@ -445,11 +468,13 @@ EOF
function uninstall_fbcp() {
uninstall_fbcp_rclocal
sudo systemctl disable fbcp.service
# Enable overscan compensation
raspi-config nonint do_overscan 0
# Set up HDMI parameters:
echo "Configuring boot/config.txt for default HDMI"
reconfig /boot/config.txt "^.*hdmi_force_hotplug.*$" "hdmi_force_hotplug=0"
reconfig /boot/config.txt "^.*#.*dtoverlay=vc4-fkms-v3d.*$" "dtoverlay=vc4-fkms-v3d"
sed -i -e '/^hdmi_group=2.*$/d' /boot/config.txt
sed -i -e '/^hdmi_mode=87.*$/d' /boot/config.txt
sed -i -e '/^hdmi_cvt=.*$/d' /boot/config.txt
@ -508,29 +533,38 @@ selectN "PiTFT 2.4\", 2.8\" or 3.2\" resistive (240x320)" \
"PiTFT 2.2\" no touch (240x320)" \
"PiTFT 2.8\" capacitive touch (240x320)" \
"PiTFT 3.5\" resistive touch (320x480)" \
"Braincraft 1.54\" display (240x240)" \
"MiniPiTFT 1.14\" display (240x135) - WARNING! CUTTING EDGE! WILL UPGRADE YOUR KERNEL TO LATEST" \
"PiTFT Mini 1.3\" or 1.54\" display (240x240) - WARNING! WILL UPGRADE YOUR KERNEL TO LATEST" \
"MiniPiTFT 1.14\" display (240x135) - WARNING! WILL UPGRADE YOUR KERNEL TO LATEST" \
"ST7789V 2.0\" no touch (240x320) - WARNING! WILL UPGRADE YOUR KERNEL TO LATEST" \
"Uninstall PiTFT" \
"Quit without installing"
PITFT_SELECT=$?
if [ $PITFT_SELECT -gt 6 ]; then
if [ $PITFT_SELECT -gt 8 ]; then
exit 1
fi
echo "Select rotation:"
selectN "90 degrees (landscape)" \
"180 degrees (portait)" \
if [ $PITFT_SELECT -eq 8 ]; then
UNINSTALL=true
fi
if ! $UNINSTALL; then
echo "Select rotation:"
selectN "90 degrees (landscape)" \
"180 degrees (portrait)" \
"270 degrees (landscape)" \
"0 degrees (portait)"
PITFT_ROTATE=$?
if [ $PITFT_ROTATE -gt 4 ]; then
"0 degrees (portrait)"
PITFT_ROTATE=$?
if [ $PITFT_ROTATE -gt 4 ]; then
exit 1
fi
fi
PITFT_ROTATIONS=("90" "180" "270" "0")
PITFT_TYPES=("28r" "22" "28c" "35r" "st7789_240x240" "st7789_240x135")
WIDTH_VALUES=(320 320 320 480 240)
HEIGHT_VALUES=(240 240 240 320 240)
HZ_VALUES=(64000000 64000000 64000000 32000000 64000000)
PITFT_TYPES=("28r" "22" "28c" "35r" "st7789_240x240" "st7789_240x135" "st7789_240x320")
WIDTH_VALUES=(320 320 320 480 240 240 320)
HEIGHT_VALUES=(240 240 240 320 240 135 240)
HZ_VALUES=(64000000 64000000 64000000 32000000 64000000 64000000)
@ -584,45 +618,48 @@ if [[ ! -e "$target_homedir" || ! -d "$target_homedir" ]]; then
bail "$target_homedir must be an existing directory (use -u /home/foo to specify)"
fi
pitfttype=${PITFT_TYPES[$PITFT_SELECT-1]}
pitftrot=${PITFT_ROTATIONS[$PITFT_ROTATE-1]}
if ! $UNINSTALL;
then
pitfttype=${PITFT_TYPES[$PITFT_SELECT-1]}
pitftrot=${PITFT_ROTATIONS[$PITFT_ROTATE-1]}
touchrot=$pitftrot
if [ "${pitfttype}" != "28r" ] && [ "${pitfttype}" != "28c" ] && [ "${pitfttype}" != "35r" ] && [ "${pitfttype}" != "22" ] && [ "${pitfttype}" != "st7789_240x240" ] && [ "${pitfttype}" != "st7789_240x135" ]; then
if [ "${pitfttype}" != "28r" ] && [ "${pitfttype}" != "28c" ] && [ "${pitfttype}" != "35r" ] && [ "${pitfttype}" != "22" ] && [ "${pitfttype}" != "st7789_240x240" ] && [ "${pitfttype}" != "st7789_240x320" ] && [ "${pitfttype}" != "st7789_240x135" ]; then
echo "Type must be one of:"
echo " '28r' (2.8\" resistive, PID 1601)"
echo " '28c' (2.8\" capacitive, PID 1983)"
echo " '35r' (3.5\" Resistive)"
echo " '22' (2.2\" no touch)"
echo " 'st7789_240x240' (1.54\" or 1.3\" no touch)"
echo " 'st7789_240x135' 1.14\" no touch)"
echo " 'st7789_320x240' (2.0\" no touch)"
echo " 'st7789_240x135' (1.14\" no touch)"
echo
print_help
fi
fi
info PITFT "System update"
sysupdate || bail "Unable to apt-get update"
info PITFT "System update"
sysupdate || bail "Unable to apt-get update"
info PITFT "Installing Python libraries & Software..."
softwareinstall || bail "Unable to install software"
info PITFT "Installing Python libraries & Software..."
softwareinstall || bail "Unable to install software"
info PITFT "Updating /boot/config.txt..."
update_configtxt || bail "Unable to update /boot/config.txt"
info PITFT "Updating /boot/config.txt..."
update_configtxt || bail "Unable to update /boot/config.txt"
if [ "${pitfttype}" == "28r" ] || [ "${pitfttype}" == "35r" ] || [ "${pitfttype}" == "28c" ] ; then
if [ "${pitfttype}" == "28r" ] || [ "${pitfttype}" == "35r" ] || [ "${pitfttype}" == "28c" ] ; then
info PITFT "Updating SysFS rules for Touchscreen..."
update_udev || bail "Unable to update /etc/udev/rules.d"
info PITFT "Updating TSLib default calibration..."
update_pointercal || bail "Unable to update /etc/pointercal"
fi
fi
# ask for console access
if ask "Would you like the console to appear on the PiTFT display?"; then
# ask for console access
if ask "Would you like the console to appear on the PiTFT display?"; then
info PITFT "Updating console to PiTFT..."
uninstall_fbcp || bail "Unable to uninstall fbcp"
install_console || bail "Unable to configure console"
else
else
info PITFT "Making sure console doesn't use PiTFT"
uninstall_console || bail "Unable to configure console"
@ -634,10 +671,20 @@ else
info PITFT "Updating X11 default calibration..."
update_xorg || bail "Unable to update calibration"
fi
else
# remove fbcp
uninstall_fbcp || bail "Unable to uninstall fbcp"
fi
fi
else
info PITFT "Uninstalling PiTFT"
uninstall_bootconfigtxt
uninstall_console
uninstall_fbcp
uninstall_fbcp_rclocal
uninstall_etc_modules
fi
#info PITFT "Updating X11 setup tweaks..."
#update_x11profile || bail "Unable to update X11 setup"

View file

@ -0,0 +1,91 @@
#!/bin/bash
if [ $(id -u) -ne 0 ]; then
echo "Installer must be run as root."
echo "Try 'sudo bash $0'"
exit 1
fi
clear
echo "This script will install Adafruit"
echo "fan service, which will turn on an"
echo "external fan controlled by a given pin"
echo
echo "Operations performed include:"
echo "- Create a Fan Service File"
echo "- Enable Fan Service"
echo "- Automatically Start Fan Service"
echo " on System startup"
echo
echo "Run time < 1 minute. Reboot not required."
echo
group=ADAFRUIT
function info() {
system="$1"
group="${system}"
shift
FG="1;32m"
BG="40m"
echo -e "[\033[${FG}\033[${BG}${system}\033[0m] $*"
}
function bail() {
FG="1;31m"
BG="40m"
echo -en "[\033[${FG}\033[${BG}${group}\033[0m] "
if [ -z "$1" ]; then
echo "Exiting due to error"
else
echo "Exiting due to error: $*"
fi
exit 1
}
if [ "$1" != '-y' ]; then
echo -n "CONTINUE? [y/N]"
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Canceled."
exit 0
fi
fi
echo "Continuing..."
# check init system (technique borrowed from raspi-config):
info FAN 'Checking init system...'
if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
echo "Found systemd, OK!"
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
bail "Found sysvinit, but we require systemd"
else
bail "Unrecognised init system"
fi
info FAN 'Adding adafruit_fan.service'
cat > /etc/systemd/system/adafruit_fan.service <<EOF
[Unit]
Description=Fan service for some Adafruit boards
After=network.target
[Service]
Type=oneshot
ExecStartPre=-/bin/bash -c 'echo 4 >/sys/class/gpio/export'
ExecStartPre=/bin/bash -c 'echo out >/sys/class/gpio/gpio4/direction'
ExecStart=/bin/bash -c 'echo 1 >/sys/class/gpio/gpio4/value'
RemainAfterExit=true
ExecStop=/bin/bash -c 'echo 0 >/sys/class/gpio/gpio4/value'
StandardOutput=journal
[Install]
WantedBy=multi-user.target
EOF
info FAN 'Enabling adafruit_fan.service'
sudo systemctl enable adafruit_fan.service
sudo systemctl start adafruit_fan.service
info FAN 'Done!'
echo "You can stop the fan service with 'sudo systemctl stop adafruit_fan.service'"
echo "You can start the fan service with 'sudo systemctl start adafruit_fan.service'"

View file

@ -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
@ -46,14 +46,19 @@ ASK_TO_REBOOT=false
CURRENT_SETTING=false
UPDATE_DB=false
BOOTCMD=/boot/cmdline.txt
CONFIG=/boot/config.txt
BOOTCMD=/boot/firmware/cmdline.txt
CONFIG=/boot/firmware/config.txt
APTSRC=/etc/apt/sources.list
INITABCONF=/etc/inittab
BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
LOADMOD=/etc/modules
DTBODIR=/boot/overlays
# Fall back to old location
if ! test -f $CONFIG; then
CONFIG=/boot/config.txt
fi
# function define
confirm() {
@ -139,9 +144,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 +237,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
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 +274,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

View file

@ -0,0 +1,119 @@
#!/bin/bash
#-------------------------------------------------------------------------
# Installer script for I2S microphone support on Raspberry Pi
#
# 2020/04/15
# 2020/07/08 remove DKMS
#-------------------------------------------------------------------------
############################ Script assisters ############################
# Given a list of strings representing options, display each option
# 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
}
function ask() {
# http://djm.me/ask
while true; do
if [ "${2:-}" = "Y" ]; then
prompt="Y/n"
default=Y
elif [ "${2:-}" = "N" ]; then
prompt="y/N"
default=N
else
prompt="y/n"
default=
fi
# Ask the question
read -p "$1 [$prompt] " REPLY
# Default?
if [ -z "$REPLY" ]; then
REPLY=$default
fi
# Check if the reply is valid
case "$REPLY" in
Y*|y*) return 0 ;;
N*|n*) return 1 ;;
esac
done
}
####################################################### MAIN
clear
echo "This script downloads and installs"
echo "I2S microphone support."
echo
echo "Select Pi Model:"
selectN "Pi 0 or 0W" \
"Pi 2 or 3" \
"Pi 4"
PIMODEL_SELECT=$(($?-1))
ask "Auto load module at boot?"
AUTO_LOAD=$?
echo
echo "Installing..."
# Get needed packages
apt-get -y install git raspberrypi-kernel-headers
# Clone the repo
git clone https://github.com/adafruit/Raspberry-Pi-Installer-Scripts.git
# Build and install the module
cd Raspberry-Pi-Installer-Scripts/i2s_mic_module
make clean
make
make install
# Setup auto load at boot if selected
if [ $AUTO_LOAD = 0 ]; then
cat > /etc/modules-load.d/snd-i2smic-rpi.conf<<EOF
snd-i2smic-rpi
EOF
cat > /etc/modprobe.d/snd-i2smic-rpi.conf<<EOF
options snd-i2smic-rpi rpi_platform_generation=$PIMODEL_SELECT
EOF
fi
# Enable I2S overlay
sed -i -e 's/#dtparam=i2s/dtparam=i2s/g' /boot/config.txt
# Done
echo "DONE."
echo
echo "Settings take effect on next boot."
echo
echo -n "REBOOT NOW? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Exiting without reboot."
exit 0
fi
echo "Reboot started..."
reboot
exit 0

View file

@ -6,6 +6,21 @@
# chmod +x libgpiod.sh
# ./libgpiod.sh
is_legacy=0
# Loop through arguments and process them
for arg in "$@"
do
case $arg in
-l|--legacy)
is_legacy=1
shift
;;
*)
shift
;;
esac
done
echo "Installing build requirements - this may take a few minutes!"
echo
@ -35,6 +50,11 @@ echo
cd "$build_dir"
git clone git://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git .
if test $is_legacy = 1; then
git checkout v1.4.2 -b v1.4.2
fi
echo "Building libgpiod"
echo

View file

@ -0,0 +1,40 @@
#!/bin/sh
# rpi-pin-kernel-firmware: Pin a specific version of the rpi kernel and firmware
set -e
if [ $# -ne 1 ]; then
echo "Usage: $0 kernel-version"
echo
echo "e.g., $0 1.20201126-1"
exit 1
fi
if ! dpkg -l raspberrypi-kernel:armhf > /dev/null 2>&1; then
echo "This command is designed to run only on Raspbian with the armhf kernel"
echo 99
fi
if [ `id -u` -ne 0 ]; then
echo "If necessary, enter your password to run this script as root"
exec sudo sh "$0" "$1"
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}_${fileversion}_armhf.deb"
set -- "$@" "$filename"
wget --continue -O "$filename" "$base/$filename"
done
dpkg -i "$@"
for package in $packagelist; do
/usr/bin/printf "Package: $package\nPin: version ${version}\nPin-Priority:999\n\n"
done > /etc/apt/preferences.d/99-adafruit-pin-kernel

54
i2s_mic_module/Makefile Normal file
View file

@ -0,0 +1,54 @@
MOD_NAME := snd-i2smic-rpi
ifneq ($(KERNELRELEASE),)
# call from kernel build system
all:
@echo "Building from the kernel build system"
@echo "Module build: $(CONFIG_SND_I2S_RPI)"
@echo "Name: $(MOD_NAME)"
obj-$(CONFIG_SND_I2S_RPI) := $(MOD_NAME).o
else
# external module build
EXTRA_FLAGS += -I$(PWD)
#
# KDIR is a path to a directory containing kernel source.
# It can be specified on the command line passed to make to enable the module to
# be built and installed for a kernel other than the one currently running.
# By default it is the path to the symbolic link created when
# the current kernel's modules were installed, but
# any valid path to the directory in which the target kernel's source is located
# can be provided on the command line.
#
KDIR ?= /lib/modules/$(shell uname -r)/build
MDIR ?= /lib/modules/$(shell uname -r)
PWD := $(shell pwd)
export CONFIG_SND_I2S_RPI := m
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
help:
$(MAKE) -C $(KDIR) M=$(PWD) help
install: snd-i2smic-rpi.ko
rm -f ${MDIR}/kernel/sound/drivers/$(MOD_NAME).ko
install -m644 -b -D $(MOD_NAME).ko ${MDIR}/kernel/sound/drivers/$(MOD_NAME).ko
depmod -a
uninstall:
rm -rf ${MDIR}/kernel/sound/drivers/$(MOD_NAME).ko
depmod -a
endif
.PHONY : all clean install uninstall

114
i2s_mic_module/README.md Normal file
View file

@ -0,0 +1,114 @@
**Driver for the Adafruit I2S MEMS Microphone**
[Product learn page on Adafruit](https://learn.adafruit.com/adafruit-i2s-mems-microphone-breakout/overview).
Known problems with this driver: Low vol level. While you can use the alsa magic socery to make an alsa softvol input, that approach won't work out of the box with anything that uses Pulseaudio. If you have any idea how to make this work with Pulse, please drop me a line.
Installing the I2S microphone driver the easy way
====================================
If you use Raspbian or any Debian-derived distribution, [go to the releases tab](https://github.com/htruong/snd-i2s_rpi/releases) and download the newest deb version.
Then do the following
```bash
# Installing raspberrypi-kernel-headers works only if you haven't messed with
# the rpi-update thing.
# If you did, then you would have to do the rpi-source method
# to get the kernel headers. See:
# https://learn.adafruit.com/adafruit-i2s-mems-microphone-breakout/raspberry-pi-wiring-and-test#kernel-compiling
$ sudo apt install dkms raspberrypi-kernel-headers
$ sudo dpkg -i snd-i2s-rpi-dkms_0.0.2_all.deb
# For this to work, remember to modify these first:
# /boot/firmware/config.txt -> dtparam=i2s=on
# and
# /etc/modules -> snd-bcm2835
# remember to reboot
$ sudo modprobe snd-i2s_rpi rpi_platform_generation=0
# rpi_platform_generation=0 for Raspberry Pi 1 B/A/A+, 0
# do not add anything for everything else (2/3).
# see if it works
$ dmesg | grep i2s
# it should say blah.i2s mapping OK
# [ 3.519017] snd_i2s_rpi: loading out-of-tree module taints kernel.
# [ 3.519881] snd-i2s_rpi: Version 0.0.2
# [ 3.519889] snd-i2s_rpi: Setting platform to 20203000.i2s
# [ 7.624559] asoc-simple-card asoc-simple-card.0: ASoC: CPU DAI 20203000.i2s not registered - will retry
# ... snip ...
# [ 9.507142] asoc-simple-card asoc-simple-card.0: snd-soc-dummy-dai <-> 20203000.i2s mapping ok
$ arecord -l
# it should list your mic
# note that the default vol level is very low, you need
# to follow the ladyada's guide to make it hearable
# If you want it to load automatically at startup
# 1. Add to /etc/modules
# snd-i2s_rpi
# 2. If you have a Pi old-gen, you need to do this:
# create file called /etc/modprobe.d/snd-i2s_rpi.conf
# add this line
# options snd-i2s_rpi rpi_platform_generation=0
```
Installing as a stand-alone module
====================================
make
sudo make install
To load the driver manually, run this as root:
modprobe snd-i2s_rpi
You may also specify custom toolchains by using the `CROSS_COMPILE` flag:
CROSS_COMPILE=/usr/local/bin/arm-eabi-
Installing as a part of the kernel
======================================
Instructions to come later. Who would ever want to do that?
Installing as a DKMS module
=================================
You can have even more fun with snd-i2s\_rpi by installing it as a DKMS module has the main advantage of being auto-compiled (and thus, possibly surviving) between kernel upgrades.
First, get dkms. On Raspbian this should be:
sudo apt install dkms
Then copy the root of this repository to `/usr/share`:
sudo cp -R . /usr/src/snd-i2s_rpi-0.0.2 (or whatever version number declared on dkms.conf is)
sudo dkms add -m snd-i2s_rpi -v 0.0.2
Build and load the module:
sudo dkms build -m snd-i2s_rpi -v 0.0.2
sudo dkms install -m snd-i2s_rpi -v 0.0.2
Now you have a proper dkms module that will work for a long time... hopefully.

7
i2s_mic_module/dkms.conf Normal file
View file

@ -0,0 +1,7 @@
PACKAGE_NAME="snd-i2smic-rpi"
PACKAGE_VERSION="0.1.0"
MAKE="KDIR=/lib/modules/$kernelver/build MDIR=/lib/modules/$kernelver make"
CLEAN="make clean"
BUILT_MODULE_NAME[0]="snd-i2smic-rpi"
AUTOINSTALL="yes"
DEST_MODULE_LOCATION="/kernel/sound/drivers"

View file

@ -0,0 +1,151 @@
/*
* =====================================================================================
*
* Filename: snd-i2smic-rpi
*
* Description: I2S microphone kernel module
*
* Version: 0.1.0
* Created: 2020-04-14
* Revision: none
* Compiler: gcc
*
* Pi4 Mods: Carter Nelson
* Orig Author: Huan Truong (htruong@tnhh.net), originally written by Paul Creaser
*
* =====================================================================================
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/platform_device.h>
#include <sound/simple_card.h>
#include <linux/delay.h>
#include "snd-i2smic-rpi.h"
/*
* modified for linux 4.1.5
* inspired by https://github.com/msperl/spi-config
* with thanks for https://github.com/notro/rpi-source/wiki
* as well as Florian Meier for the rpi i2s and dma drivers
*
* to use a differant (simple-card compatible) codec
* change the codec name string in two places and the
* codec_dai name string. (see codec's source file)
*
*
* N.B. playback vs capture is determined by the codec choice
* */
static struct simple_card_info card_info;
static struct platform_device card_device;
/*
* Setup command line parameter
*/
static short rpi_platform_generation;
module_param(rpi_platform_generation, short, 0);
MODULE_PARM_DESC(rpi_platform_generation, "Raspberry Pi generation: 0=Pi0, 1=Pi2/3, 2=Pi4");
/*
* Dummy callback for release
*/
void device_release_callback(struct device *dev) { /* do nothing */ };
/*
* Setup the card info
*/
static struct simple_card_info default_card_info = {
.card = "snd_rpi_i2s_card", // -> snd_soc_card.name
.name = "simple-card_codec_link", // -> snd_soc_dai_link.name
.codec = "snd-soc-dummy", // "dmic-codec", // -> snd_soc_dai_link.codec_name
.platform = "not-set.i2s",
.daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS,
.cpu_dai = {
.name = "not-set.i2s", // -> snd_soc_dai_link.cpu_dai_name
.sysclk = 0
},
.codec_dai = {
.name = "snd-soc-dummy-dai", //"dmic-codec", // -> snd_soc_dai_link.codec_dai_name
.sysclk = 0
},
};
/*
* Setup the card device
*/
static struct platform_device default_card_device = {
.name = "asoc-simple-card", //module alias
.id = 0,
.num_resources = 0,
.dev = {
.release = &device_release_callback,
.platform_data = &default_card_info, // *HACK ALERT*
},
};
/*
* Callback for module initialization
*/
int i2s_mic_rpi_init(void)
{
const char *dmaengine = "bcm2708-dmaengine"; //module name
static char *card_platform;
int ret;
printk(KERN_INFO "snd-i2smic-rpi: Version %s\n", SND_I2SMIC_RPI_VERSION);
// Set platform
switch (rpi_platform_generation) {
case 0:
// Pi Zero
card_platform = "20203000.i2s";
break;
case 1:
// Pi 2 and 3
card_platform = "3f203000.i2s";
break;
case 2:
default:
// Pi 4
card_platform = "fe203000.i2s";
break;
}
printk(KERN_INFO "snd-i2smic-rpi: Setting platform to %s\n", card_platform);
// request DMA engine module
ret = request_module(dmaengine);
pr_alert("request module load '%s': %d\n",dmaengine, ret);
// update info
card_info = default_card_info;
card_info.platform = card_platform;
card_info.cpu_dai.name = card_platform;
card_device = default_card_device;
card_device.dev.platform_data = &card_info;
// register the card device
ret = platform_device_register(&card_device);
pr_alert("register platform device '%s': %d\n",card_device.name, ret);
return 0;
}
/*
* Callback for module exit
*/
void i2s_mic_rpi_exit(void)
{
platform_device_unregister(&card_device);
pr_alert("i2s mic module unloaded\n");
}
// Plumb it up
module_init(i2s_mic_rpi_init);
module_exit(i2s_mic_rpi_exit);
MODULE_DESCRIPTION("ASoC simple-card I2S Microphone");
MODULE_AUTHOR("Carter Nelson");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,6 @@
#ifndef _SND_I2SMIC_RPI_H_
#define _SND_I2SMIC_RPI_H_
#define SND_I2SMIC_RPI_VERSION "0.1.0"
#endif

136
i2samp.py Normal file
View file

@ -0,0 +1,136 @@
import os
try:
from adafruit_shell import Shell
from clint.textui import colored
except ImportError:
raise RuntimeError("The library 'adafruit_shell' was not found. To install, try typing: sudo pip3 install adafruit-python-shell")
shell = Shell()
BLACKLIST = "/etc/modprobe.d/raspi-blacklist.conf"
PRODUCT_NAME = "I2S Amplifier"
OVERLAY = "googlevoicehat-soundcard"
def driver_loaded(driver_name):
return shell.run_command(f"lsmod | grep -q '{driver_name}'", suppress_message=True)
def main():
reboot = False
shell.clear()
if not shell.is_raspberry_pi():
shell.bail("Non-Raspberry Pi board detected.")
print("\nThis script will install everything needed to use\n"
f"{PRODUCT_NAME}.\n")
print(colored.red("--- Warning ---"))
print("\nAlways be careful when running scripts and commands\n"
"copied from the internet. Ensure they are from a\n"
"trusted source.\n")
if not shell.prompt("Do you wish to continue?"):
print("\nAborting...")
shell.exit()
print("\nChecking hardware requirements...")
# Enable I2S overlay
config = shell.get_boot_config()
if config is None:
shell.bail("No Device Tree Detected, not supported")
print(f"\nAdding Device Tree Entry to {config}")
if shell.pattern_search(config, f"^dtoverlay={OVERLAY}$"):
print("dtoverlay already active")
else:
shell.write_text_file(config, f"dtoverlay={OVERLAY}")
reboot = True
if os.path.exists(BLACKLIST):
print("\nCommenting out Blacklist entry in", BLACKLIST)
shell.pattern_replace(BLACKLIST, "^blacklist[[:space:]]*snd_soc_max98357a.*", "#blacklist snd_soc_max98357a")
shell.pattern_replace(BLACKLIST, "^blacklist[[:space:]]*snd_soc_max98357a_i2c.*", "#blacklist snd_soc_max98357a_i2c")
shell.pattern_replace(BLACKLIST, "^blacklist[[:space:]]*snd_soc_max98357a.*", "#blacklist snd_soc_max98357a")
print("Configuring sound output")
if os.path.exists("/etc/asound.conf"):
if os.path.exists("/etc/asound.conf.old"):
shell.remove("/etc/asound.conf.old")
shell.move("/etc/asound.conf", "/etc/asound.conf.old")
shell.write_text_file("~/asound.conf",
"""
pcm.speakerbonnet {
type hw card 0
}
pcm.dmixer {
type dmix
ipc_key 1024
ipc_perm 0666
slave {
pcm "speakerbonnet"
period_time 0
period_size 1024
buffer_size 8192
rate 44100
channels 2
}
}
ctl.dmixer {
type hw card 0
}
pcm.softvol {
type softvol
slave.pcm "dmixer"
control.name "PCM"
control.card 0
}
ctl.softvol {
type hw card 0
}
pcm.!default {
type plug
slave.pcm "softvol"
}
""")
shell.move("~/asound.conf", "/etc/asound.conf")
print("Installing aplay systemd unit")
shell.write_text_file("/etc/systemd/system/aplay.service", """
[Unit]
Description=Invoke aplay from /dev/zero at system start.
[Service]
ExecStart=/usr/bin/aplay -D default -t raw -r 44100 -c 2 -f S16_LE /dev/zero
[Install]
WantedBy=multi-user.target""", append=False)
shell.run_command("sudo systemctl daemon-reload")
shell.run_command("sudo systemctl disable aplay")
print("\nYou can optionally activate '/dev/zero' playback in\n"
"the background at boot. This will remove all\n"
"popping/clicking but does use some processor time.\n\n")
if shell.prompt("Activate '/dev/zero' playback in background? [RECOMMENDED]\n", default="y"):
shell.run_command("sudo systemctl enable aplay")
reboot = True
if driver_loaded("max98357a"):
print(f"\nWe can now test your {PRODUCT_NAME}")
shell.warn("Set your speakers at a low volume if possible!")
if shell.prompt("Do you wish to test your system now?"):
print("Testing...")
shell.run_command("speaker-test -l5 -c2 -t wav")
print("\n" + colored.green("All done!"))
print("\nEnjoy your new $productname!")
if reboot:
shell.prompt_reboot()
# Main function
if __name__ == "__main__":
shell.require_root()
main()

77
i2smic.py Normal file
View file

@ -0,0 +1,77 @@
import os
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()
def main():
shell.clear()
boot_config = shell.get_boot_config()
print("""This script downloads and installs
I2S microphone support.
""")
if not shell.is_raspberry_pi():
shell.bail("Non-Raspberry Pi board detected.")
pi_model = shell.get_board_model()
print("{} detected.\n".format(pi_model))
if pi_model in ("RASPBERRY_PI_ZERO", "RASPBERRY_PI_ZERO_W", "RASPBERRY_PI_B_REV2"):
pimodel_select = 0
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", "RASPBERRY_PI_400"):
pimodel_select = 2
else:
shell.bail("Unsupported Pi board detected.")
auto_load = (
not shell.argument_exists('noautoload') and
shell.prompt("Auto load module at boot?", force_arg="autoload"))
print("""
Installing...""")
# Get needed packages
shell.run_command("apt-get -y install git raspberrypi-kernel-headers")
# Clone the repo
shell.run_command("git clone https://github.com/adafruit/Raspberry-Pi-Installer-Scripts.git")
# Build and install the module
shell.chdir("Raspberry-Pi-Installer-Scripts/i2s_mic_module")
shell.run_command("make clean")
shell.run_command("make")
shell.run_command("make install")
# Setup auto load at boot if selected
if auto_load:
shell.write_text_file(
"/etc/modules-load.d/snd-i2smic-rpi.conf",
"snd-i2smic-rpi"
)
shell.write_text_file(
"/etc/modprobe.d/snd-i2smic-rpi.conf",
"options snd-i2smic-rpi rpi_platform_generation={}".format(pimodel_select)
)
# Enable I2S overlay
shell.run_command(f"sed -i -e 's/#dtparam=i2s/dtparam=i2s/g' {boot_config}")
# Done
print("""DONE.
Settings take effect on next boot.
""")
if not shell.argument_exists('noreboot'):
shell.prompt_reboot(force_arg="reboot")
# Main function
if __name__ == "__main__":
shell.require_root()
# Probably not necessary for now because the Pi 5 doesn't work anyway
if shell.is_raspberry_pi_os() and shell.is_kernel_userspace_mismatched() and shell.is_pi5_or_newer():
shell.bail("Unable to proceed on Pi 5 or newer boards with a with a 32-bit OS. Please reinstall with a 64-bit OS.")
shell.check_kernel_userspace_mismatch()
main()

114
install_wm8960.sh Normal file
View file

@ -0,0 +1,114 @@
#!/usr/bin/env bash
set -o xtrace
set -o errexit
set -o pipefail
set -o nounset
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root (use sudo)" 1>&2
exit 1
fi
if [ ! -f /etc/rpi-issue ]; then
echo "Sorry, this drivers only works on raspberry pi"
exit 1
fi
#download the archive
rm -rf WM8960-Audio-HAT
git clone https://github.com/waveshare/WM8960-Audio-HAT
cd WM8960-Audio-HAT
apt-get -y update
apt-get -y install raspberrypi-kernel-headers --no-install-recommends --no-install-suggests
apt-get -y install dkms git i2c-tools libasound2-plugins --no-install-recommends --no-install-suggests
apt-get -y clean
# locate currently installed kernels (may be different to running kernel if
# it's just been updated)
kernels=$(ls /lib/modules)
function install_module {
ver="1.0"
# we create a dir with this version to ensure that 'dkms remove' won't delete
# the sources during kernel updates
marker="0.0.0"
src=$1
mod=$2
if [[ -d /var/lib/dkms/$mod/$ver/$marker ]]; then
rmdir /var/lib/dkms/$mod/$ver/$marker
fi
if [[ -e /usr/src/$mod-$ver || -e /var/lib/dkms/$mod/$ver ]]; then
dkms remove --force -m $mod -v $ver --all || true
rm -rf /usr/src/$mod-$ver
fi
mkdir -p /usr/src/$mod-$ver
cp -a $src/* /usr/src/$mod-$ver/
dkms add -m $mod -v $ver
for kernel in $kernels
do
# It works for kernels greater than or equal 6.5
if [ $(echo "$kernel 6.5" | awk '{if ($1 >= $2) print 1; else print 0}') -eq 0 ]; then
continue
fi
dkms build "$kernel" -k "$kernel" --kernelsourcedir "/lib/modules/$kernel/build" -m $mod -v $ver &&
dkms install --force "$kernel" -k "$kernel" -m $mod -v $ver
done
mkdir -p /var/lib/dkms/$mod/$ver/$marker
}
install_module "./" "wm8960-soundcard"
# install dtbos
cp wm8960-soundcard.dtbo /boot/overlays
#set kernel modules
grep -q "^i2c-dev$" /etc/modules || \
echo "i2c-dev" >> /etc/modules
grep -q "^snd-soc-wm8960$" /etc/modules || \
echo "snd-soc-wm8960" >> /etc/modules
grep -q "^snd-soc-wm8960-soundcard$" /etc/modules || \
echo "snd-soc-wm8960-soundcard" >> /etc/modules
# set modprobe blacklist
grep -q "^blacklist snd_bcm2835$" /etc/modprobe.d/raspi-blacklist.conf || \
echo "blacklist snd_bcm2835" >> /etc/modprobe.d/raspi-blacklist.conf
#set dtoverlays
sed -i -e 's:#dtparam=i2s=on:dtparam=i2s=on:g' /boot/firmware/config.txt || true
sed -i -e 's:#dtparam=i2c_arm=on:dtparam=i2c_arm=on:g' /boot/firmware/config.txt || true
grep -q "^dtoverlay=i2s-mmap$" /boot/firmware/config.txt || \
echo "dtoverlay=i2s-mmap" >> /boot/firmware/config.txt
grep -q "^dtparam=i2s=on$" /boot/firmware/config.txt || \
echo "dtparam=i2s=on" >> /boot/firmware/config.txt
grep -q "^dtoverlay=wm8960-soundcard$" /boot/firmware/config.txt || \
echo "dtoverlay=wm8960-soundcard" >> /boot/firmware/config.txt
#install config files
mkdir -p /etc/wm8960-soundcard
cp *.conf /etc/wm8960-soundcard
cp *.state /etc/wm8960-soundcard
#set service
cp wm8960-soundcard /usr/bin/
chmod -x wm8960-soundcard.service
cp wm8960-soundcard.service /lib/systemd/system/
systemctl enable wm8960-soundcard.service
#cleanup
cd ..
rm -rf WM8960-Audio-HAT
echo "------------------------------------------------------"
echo "Please reboot your raspberry pi to apply all settings"
echo "Enjoy!"
echo "------------------------------------------------------"

121
joy-bonnet.py Executable file
View file

@ -0,0 +1,121 @@
"""
Adafruit Raspberry Pi Joy Bonnet Setup Script
(C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
Converted to Python by Melissa LeBlanc-Williams for Adafruit Industries
"""
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 = "JOY"
def main():
shell.clear()
print("""This script installs software for the Adafruit
Joy Bonnet for Raspberry Pi. Steps include:
- Update package index files (apt-get update).
- Install Python libraries: smbus, evdev.
- Install joyBonnet.py in /boot and
configure /etc/rc.local to auto-start script.
- Enable I2C bus.
- OPTIONAL: disable overscan.
Run time ~10 minutes. Reboot required.
EXISTING INSTALLATION, IF ANY, WILL BE OVERWRITTEN.
""")
if not shell.prompt("CONTINUE?", default='n'):
print("Canceled.")
shell.exit()
print("Continuing...")
disable_overscan = shell.prompt("Disable overscan?", default='n')
install_halt = shell.prompt("Install GPIO-halt utility?", default='n')
if install_halt:
#halt_pin = shell.prompt("Install GPIO-halt utility?"
halt_pin = input("GPIO pin for halt: ").strip()
print("\n")
if disable_overscan:
print("Overscan: disable.")
else:
print("Overscan: keep current setting.")
if install_halt:
print("Install GPIO-halt: YES (GPIO{})".format(halt_pin))
else:
print("Install GPIO-halt: NO")
if not shell.prompt("CONTINUE?", default='n'):
print("Canceled.")
shell.exit()
# START INSTALL ------------------------------------------------------------
# All selections are validated at this point...
print("""
Starting installation...
Updating package index files...""")
shell.run_command('sudo apt-get update', suppress_message=True)
print("Installing Python libraries...")
shell.run_command('sudo apt-get install -y python3-pip python3-dev python3-smbus')
shell.run_command('pip3 install evdev --upgrade')
print("Installing Adafruit code in /boot...")
shell.chdir("/tmp")
shell.run_command("curl -LO https://raw.githubusercontent.com/adafruit/Adafruit-Retrogame/master/joyBonnet.py")
# Moving between filesystems requires copy-and-delete:
shell.copy("joyBonnet.py", "/boot")
shell.remove("joyBonnet.py")
if install_halt:
print("Installing gpio-halt in /usr/local/bin...")
shell.run_command("curl -LO https://github.com/adafruit/Adafruit-GPIO-Halt/archive/master.zip")
shell.run_command("unzip -u master.zip")
shell.chdir("Adafruit-GPIO-Halt-master")
shell.run_command("make")
shell.move("gpio-halt", "/usr/local/bin")
shell.chdir("..")
shell.remove("Adafruit-GPIO-Halt-master")
# CONFIG -------------------------------------------------------------------
print("Configuring system...")
# Enable I2C using raspi-config
shell.run_command("sudo raspi-config nonint do_i2c 0")
# Disable overscan compensation (use full screen):
if disable_overscan:
shell.run_command("sudo raspi-config nonint do_overscan 1")
if install_halt:
if shell.pattern_search("/etc/rc.local", "gpio-halt"):
# gpio-halt already in rc.local, but make sure correct:
shell.pattern_replace("/etc/rc.local", "^.*gpio-halt.*$", "/usr/local/bin/gpio-halt {} &".format(halt_pin))
else:
# Insert gpio-halt into rc.local before final 'exit 0'
shell.pattern_replace("/etc/rc.local", "^exit 0", "/usr/local/bin/gpio-halt {} &\\nexit 0".format(halt_pin))
# Auto-start joyBonnet.py on boot
if shell.pattern_search("/etc/rc.local", "joyBonnet.py"):
# joyBonnet.py already in rc.local, but make sure correct:
shell.pattern_replace("/etc/rc.local", "^.*joyBonnet.py.*$", "cd /boot;python3 joyBonnet.py &")
else:
# Insert joyBonnet.py into rc.local before final 'exit 0'
shell.pattern_replace("/etc/rc.local", "^exit 0", "cd /boot;python3 joyBonnet.py &\\nexit 0")
# Add udev rule (will overwrite if present)
shell.write_text_file("/etc/udev/rules.d/10-retrogame.rules", "SUBSYSTEM==\"input\", ATTRS{name}==\"retrogame\", ENV{ID_INPUT_KEYBOARD}=\"1\"", append=False)
# PROMPT FOR REBOOT --------------------------------------------------------
print("""DONE.
Settings take effect on next boot.
""")
shell.prompt_reboot()
# Main function
if __name__ == "__main__":
shell.require_root()
main()

60
libgpiod.py Executable file
View file

@ -0,0 +1,60 @@
# Instructions!
# cd ~
# sudo apt-get install python3-pip
# sudo pip3 install --upgrade adafruit-python-shell click
# wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/libgpiod.py
# sudo python3 libgpiod.py
import sys
try:
import click
except ImportError:
raise RuntimeError("The library 'Click' was not found. To install, try typing: sudo pip3 install --upgrade 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 = 'LIBGPIOD'
@click.command()
@click.option('-l', '--legacy', is_flag=True, help="Install a legacy version of libgpiod for systems with older libraries")
def main(legacy):
print("Installing build requirements - this may take a few minutes!\n")
# install generic linux packages required
shell.run_command("sudo apt-get update")
shell.run_command("sudo apt-get install -y autoconf autoconf-archive automake build-essential git libtool pkg-config python3-dev python3-setuptools swig4.0 wget")
# for raspberry pi we need...
shell.run_command("sudo apt-get install -y raspberrypi-kernel-headers")
build_dir = shell.run_command("mktemp -d /tmp/libgpiod.XXXX", return_output=True).strip()
print(f"Cloning libgpiod repository to {build_dir}\n")
shell.chdir(build_dir)
shell.run_command("git clone git://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git .")
if legacy:
shell.run_command("git checkout v1.4.2 -b v1.4.2")
print("Building libgpiod\n")
include_path = shell.run_command("python3 -c \"from sysconfig import get_paths; print(get_paths()['include'])\"", return_output=True)
shell.run_command("export PYTHON_VERSION=3")
shell.run_command("./autogen.sh --enable-tools=yes --prefix=/usr/local/ --enable-bindings-python CFLAGS=\"-I/{}\" && make && sudo make install && sudo ldconfig".format(include_path))
if shell.exists("bindings/python/.libs"):
version = sys.version_info
python_folder = f"python{version.major}.{version.minor}"
shell.run_command(f"sudo cp bindings/python/.libs/gpiod.so /usr/local/lib/{python_folder}/dist-packages/")
shell.run_command(f"sudo cp bindings/python/.libs/gpiod.la /usr/local/lib/{python_folder}/dist-packages/")
shell.run_command(f"sudo cp bindings/python/.libs/gpiod.a /usr/local/lib/{python_folder}/dist-packages/")
shell.exit()
# Main function
if __name__ == "__main__":
shell.require_root()
main()

View 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

View 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

View 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

View file

@ -0,0 +1,559 @@
"""
Adafruit PiTFT MIPI Display Installer Script
(C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
Written by Melissa LeBlanc-Williams for Adafruit Industries
"""
import time
import os
try:
import click
except ImportError:
raise RuntimeError("The library 'Click' was not found. To install, try typing: pip3 install Click")
try:
from adafruit_shell import Shell
except ImportError:
raise RuntimeError("The library 'adafruit_shell' was not found. To install, try typing: pip3 install adafruit-python-shell")
shell = Shell()
shell.group = 'PITFT-MIPI'
__version__ = "1.0.1"
"""
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": "BrainCraft HAT or TFT 1.3\" Bonnet + Joystick",
"product": "1.3\" Joystick",
"mipi_data": {
"command_bin": "adafruit_st7789_drm",
"gpio": "dc-gpio=25,backlight-gpio=26",
"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', suppress_message=True):
warn_exit("Apt failed to update indexes!")
if not shell.run_command('sudo apt-get update', suppress_message=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", suppress_message=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 python3-evdev"):
warn_exit("Apt failed to install software!")
return True
def uninstall_bootconfigtxt():
"""Remove any old flexfb/fbtft stuff"""
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(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 update_configtxt():
f"""update {boot_dir}/config.txt with appropriate values"""
uninstall_bootconfigtxt()
# Driver does not work if hdmi_force_hotplug=1 is present
shell.pattern_replace(f"{boot_dir}/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_dir}/overlays/{touch_overlay}.dtbo overlays/{touch_overlay}.dts")
touch_overlay = f"\ndtoverlay={touch_overlay}"
date = shell.date()
shell.write_text_file(f"{boot_dir}/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://raw.githubusercontent.com/notro/panel-mipi-dbi/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")
if not update_configtxt():
shell.bail(f"Unable to update {boot_dir}/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"
username = os.environ["SUDO_USER"]
user_homedir = os.path.expanduser(f"~{username}")
if shell.isdir(user_homedir):
target_homedir = user_homedir
boot_dir = "/boot/firmware"
if not shell.exists(boot_dir) or not shell.isdir(boot_dir):
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=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('--reboot', nargs=1, default=None, type=click.Choice(['yes', 'no']), help="Specify whether to reboot after the script is finished")
@click.option('--boot', nargs=1, default=boot_dir, type=str, help="Specify the boot directory", show_default=True)
def main(user, display, rotation, reboot, boot):
global target_homedir, pitft_config, pitftrot, auto_reboot, boot_dir
shell.clear()
if user != target_homedir:
target_homedir = user
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
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", suppress_message=True) and shell.run_command("systemctl | grep '\-\.mount'", suppress_message=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(f"Updating {boot_dir}/config.txt...")
if not update_configtxt():
shell.bail(f"Unable to update {boot_dir}/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()

View file

@ -1,5 +1,5 @@
/*
* Device Tree overlay for Adafruit Mini PiTFT 1.14" Display
* Device Tree overlay for Adafruit Mini PiTFT 1.14" 135x240 Display
*
*/
@ -18,6 +18,9 @@
status = "disabled";
};
spidev@1{
status = "disabled";
};
};
};
@ -25,9 +28,9 @@
target = <&gpio>;
__overlay__ {
pitft_pins: pitft_pins {
brcm,pins = <25>; /* dc pin */
brcm,pins = <25>;
brcm,function = <1>; /* out */
brcm,pull = <0>; /* no pull */
brcm,pull = <0>; /* none */
};
};
};
@ -40,39 +43,29 @@
#size-cells = <0>;
pitft: pitft@0{
compatible = "multi-inno,mi0283qt";
compatible = "fbtft,minipitft13";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pitft_pins>;
spi-max-frequency = <32000000>;
rotation = <90>;
width = <136>;
rotate = <270>;
width = <135>;
height = <240>;
col_offset = <53>;
row_offset = <40>;
txbuflen = <32768>;
buswidth = <8>;
dc-gpios = <&gpio 25 0>;
backlight = <&backlight>;
};
};
};
fragment@3 {
target-path = "/soc";
__overlay__ {
backlight: backlight {
compatible = "gpio-backlight";
gpios = <&gpio 22 0>;
led-gpios = <&gpio 26 0>;
debug = <0>;
};
};
};
__overrides__ {
speed = <&pitft>,"spi-max-frequency:0";
rotation = <&pitft>,"rotation:0";
rotate = <&pitft>,"rotate:0";
width = <&pitft>,"width:0";
height = <&pitft>,"height:0";
col_offset = <&pitft>,"col_offset:0";
row_offset = <&pitft>,"row_offset:0";
fps = <&pitft>,"fps:0";
debug = <&pitft>,"debug:0";
};
};

View file

@ -0,0 +1,72 @@
/*
* Device Tree overlay for Adafruit Mini PiTFT 1.3" and 1.5" 240x240 Display
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
spidev@0{
status = "disabled";
};
spidev@1{
status = "disabled";
};
};
};
fragment@1 {
target = <&gpio>;
__overlay__ {
pitft_pins: pitft_pins {
brcm,pins = <25>;
brcm,function = <1>; /* out */
brcm,pull = <0>; /* none */
};
};
};
fragment@2 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
pitft: pitft@0{
compatible = "fbtft,minipitft13";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pitft_pins>;
spi-max-frequency = <32000000>;
rotate = <0>;
width = <240>;
height = <240>;
txbuflen = <32768>;
buswidth = <8>;
dc-gpios = <&gpio 25 0>;
led-gpios = <&gpio 26 0>;
debug = <0>;
};
};
};
__overrides__ {
speed = <&pitft>,"spi-max-frequency:0";
rotate = <&pitft>,"rotate:0";
width = <&pitft>,"width:0";
height = <&pitft>,"height:0";
fps = <&pitft>,"fps:0";
debug = <&pitft>,"debug:0";
};
};

View file

@ -0,0 +1,71 @@
/*
* Device Tree overlay for pitft by Adafruit
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spidev0>;
__overlay__ {
status = "disabled";
};
};
fragment@1 {
target = <&spidev1>;
__overlay__ {
status = "disabled";
};
};
fragment@2 {
target = <&gpio>;
__overlay__ {
pitft_pins: pitft_pins {
brcm,pins = <25>;
brcm,function = <1>; /* out */
brcm,pull = <0>; /* none */
};
};
};
fragment@3 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
pitft: pitft@0{
compatible = "ilitek,ili9340";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pitft_pins>;
spi-max-frequency = <32000000>;
rotate = <90>;
fps = <25>;
bgr;
buswidth = <8>;
dc-gpios = <&gpio 25 0>;
debug = <0>;
};
};
};
__overrides__ {
speed = <&pitft>,"spi-max-frequency:0";
rotate = <&pitft>,"rotate:0", /* fbtft */
<&pitft>,"rotation:0"; /* drm */
fps = <&pitft>,"fps:0";
debug = <&pitft>,"debug:0";
drm = <&pitft>,"compatible=adafruit,yx240qv29";
};
};

View file

@ -0,0 +1,114 @@
/*
* Device Tree overlay for Adafruit PiTFT 2.4" resistive touch screen with tsc2007
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <&spidev0>;
__overlay__ {
status = "disabled";
};
};
fragment@3 {
target = <&spidev1>;
__overlay__ {
status = "disabled";
};
};
fragment@4 {
target = <&gpio>;
__overlay__ {
adafruit_2_4_tft_pins: adafruit_2_4_tft_pins {
brcm,pins = <25 24 18>;
brcm,function = <1 0 1>; /* out in out*/
brcm,pull = <0 2 2>; /* none up up */
};
};
};
fragment@5 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio 8 1>;
adafruit_2_4_tft: adafruit_2_4_tft@0{
compatible = "adafruit,yx240qv29";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&adafruit_2_4_tft_pins>;
spi-max-frequency = <32000000>;
rotation = <90>;
reset-gpios = <&gpio 23 0>;
dc-gpios = <&gpio 25 0>;
};
};
};
fragment@7 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
tsc2007: tsc2007@48 {
compatible = "ti,tsc2007";
reg = <0x48>;
ti,fuzzx = <4>;
ti,fuzzy = <4>;
ti,max-rt = <3700>;
ti,fuzzz = <4>;
ti,x-plate-ohms = <180>;
panel = <&adafruit_2_4_tft>;
pinctrl-0 = <&adafruit_2_4_tft_pins>;
interrupt-parent = <&gpio>;
interrupts = <24 2>;
gpios = <&gpio 24 1>;
};
};
};
fragment@8 {
target-path = "/soc";
__overlay__ {
backlight: backlight {
compatible = "gpio-backlight";
pinctrl-0 = <&adafruit_2_4_tft_pins>;
gpios = <&gpio 18 2>;
default-on;
};
};
};
__overrides__ {
speed = <&adafruit_2_4_tft>,"spi-max-frequency:0";
rotate = <&adafruit_2_4_tft>,"rotation:0";
fps = <&adafruit_2_4_tft>,"fps:0";
debug = <&adafruit_2_4_tft>,"debug:0";
// xohms = <&tsc2007>,"touchscreen-x-plate-ohms;0";
// swapxy = <&tsc2007>,"touchscreen-swapped-x-y?";
};
};

View file

@ -0,0 +1,93 @@
/*
* Device Tree overlay for Adafruit PiTFT 2.8" capacitive touch screen
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&spidev0>;
__overlay__ {
status = "disabled";
};
};
fragment@2 {
target = <&gpio>;
__overlay__ {
pitft_pins: pitft_pins {
brcm,pins = <24 25>;
brcm,function = <0 1>; /* in out */
brcm,pull = <2 0>; /* pullup none */
};
};
};
fragment@3 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
pitft: pitft@0{
compatible = "ilitek,ili9340";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pitft_pins>;
spi-max-frequency = <32000000>;
rotate = <90>;
fps = <25>;
bgr;
buswidth = <8>;
dc-gpios = <&gpio 25 0>;
debug = <0>;
};
};
};
fragment@4 {
target = <&i2c1>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
ft6236: ft6236@38 {
compatible = "focaltech,ft6236";
reg = <0x38>;
interrupt-parent = <&gpio>;
interrupts = <24 2>;
touchscreen-size-x = <240>;
touchscreen-size-y = <320>;
};
};
};
__overrides__ {
speed = <&pitft>,"spi-max-frequency:0";
rotate = <&pitft>,"rotate:0", /* fbtft */
<&pitft>,"rotation:0"; /* drm */
fps = <&pitft>,"fps:0";
debug = <&pitft>,"debug:0";
drm = <&pitft>,"compatible=adafruit,yx240qv29";
touch-sizex = <&ft6236>,"touchscreen-size-x:0";
touch-sizey = <&ft6236>,"touchscreen-size-y:0";
touch-invx = <&ft6236>,"touchscreen-inverted-x?";
touch-invy = <&ft6236>,"touchscreen-inverted-y?";
touch-swapxy = <&ft6236>,"touchscreen-swapped-x-y?";
};
};

View file

@ -0,0 +1,126 @@
/*
* Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&spidev0>;
__overlay__ {
status = "disabled";
};
};
fragment@2 {
target = <&spidev1>;
__overlay__ {
status = "disabled";
};
};
fragment@3 {
target = <&gpio>;
__overlay__ {
pitft_pins: pitft_pins {
brcm,pins = <24 25>;
brcm,function = <0 1>; /* in out */
brcm,pull = <2 0>; /* pullup none */
};
};
};
fragment@4 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
pitft: pitft@0{
compatible = "ilitek,ili9340";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pitft_pins>;
spi-max-frequency = <32000000>;
rotate = <90>;
fps = <25>;
bgr;
buswidth = <8>;
dc-gpios = <&gpio 25 0>;
debug = <0>;
};
pitft_ts@1 {
/* needed to avoid dtc warning */
#address-cells = <1>;
#interrupt-cells = <1>;
compatible = "st,stmpe610";
reg = <1>;
spi-max-frequency = <500000>;
interrupts = <24 2>; /* high-to-low edge triggered */
interrupt-parent = <&gpio>;
interrupt-controller;
stmpe_touchscreen: 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>;
};
};
};
};
fragment@5 {
target-path = "/soc";
__overlay__ {
backlight {
compatible = "gpio-backlight";
gpios = <&stmpe_gpio 2 0>;
default-on;
};
};
};
__overrides__ {
speed = <&pitft>,"spi-max-frequency:0";
rotate = <&pitft>,"rotate:0", /* fbtft */
<&pitft>,"rotation:0"; /* drm */
fps = <&pitft>,"fps:0";
debug = <&pitft>,"debug:0";
drm = <&pitft>,"compatible=adafruit,yx240qv29";
touch-invx = <&stmpe_touchscreen>,"touchscreen-inverted-x?";
touch-invy = <&stmpe_touchscreen>,"touchscreen-inverted-y?";
touch-swapxy = <&stmpe_touchscreen>,"touchscreen-swapped-x-y?";
};
};

View file

@ -0,0 +1,127 @@
/*
* Device Tree overlay for Adafruit PiTFT 3.5" resistive touch screen
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&spidev0>;
__overlay__ {
status = "disabled";
};
};
fragment@2 {
target = <&spidev1>;
__overlay__ {
status = "disabled";
};
};
fragment@3 {
target = <&gpio>;
__overlay__ {
pitft_pins: pitft_pins {
brcm,pins = <24 25>;
brcm,function = <0 1>; /* in out */
brcm,pull = <2 0>; /* pullup none */
};
};
};
fragment@4 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
pitft: pitft@0{
compatible = "himax,hx8357d";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pitft_pins>;
spi-max-frequency = <32000000>;
rotate = <90>;
fps = <25>;
bgr;
buswidth = <8>;
dc-gpios = <&gpio 25 0>;
debug = <0>;
};
pitft_ts@1 {
/* needed to avoid dtc warning */
#address-cells = <1>;
#interrupt-cells = <1>;
compatible = "st,stmpe610";
reg = <1>;
spi-max-frequency = <500000>;
interrupts = <24 2>; /* high-to-low edge triggered */
interrupt-parent = <&gpio>;
interrupt-controller;
stmpe_touchscreen: 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>;
};
};
};
};
fragment@5 {
target-path = "/soc";
__overlay__ {
backlight: backlight {
compatible = "gpio-backlight";
gpios = <&stmpe_gpio 2 0>;
default-on;
};
};
};
__overrides__ {
speed = <&pitft>,"spi-max-frequency:0";
rotate = <&pitft>,"rotate:0", /* fbtft */
<&pitft>,"rotation:0"; /* drm */
fps = <&pitft>,"fps:0";
debug = <&pitft>,"debug:0";
drm = <&pitft>,"compatible=adafruit,yx350hv15",
<&pitft>,"backlight:0=",<&backlight>;
touch-invx = <&stmpe_touchscreen>,"touchscreen-inverted-x?";
touch-invy = <&stmpe_touchscreen>,"touchscreen-inverted-y?";
touch-swapxy = <&stmpe_touchscreen>,"touchscreen-swapped-x-y?";
};
};

View file

@ -0,0 +1,71 @@
/*
* Device Tree overlay for Adafruit Mini PiTFT 2.0" 240x320 Display
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
spidev@0{
status = "disabled";
};
spidev@1{
status = "disabled";
};
};
};
fragment@1 {
target = <&gpio>;
__overlay__ {
pitft_pins: pitft_pins {
brcm,pins = <25>;
brcm,function = <1>; /* out */
brcm,pull = <0>; /* none */
};
};
};
fragment@2 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
pitft: pitft@0{
compatible = "sitronix,st7789v";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pitft_pins>;
spi-max-frequency = <32000000>;
rotate = <0>;
width = <240>;
height = <320>;
txbuflen = <32768>;
buswidth = <8>;
dc-gpios = <&gpio 25 0>;
led-gpios = <&gpio 12 0>;
debug = <0>;
};
};
};
__overrides__ {
speed = <&pitft>,"spi-max-frequency:0";
rotate = <&pitft>,"rotate:0";
width = <&pitft>,"width:0";
height = <&pitft>,"height:0";
fps = <&pitft>,"fps:0";
debug = <&pitft>,"debug:0";
};
};

View file

@ -0,0 +1,115 @@
/*
* Device Tree overlay for Adafruit TFT Bonnet 1.3" 240x240 Display + Joystick
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
spidev@0{
status = "disabled";
};
spidev@1{
status = "disabled";
};
};
};
fragment@1 {
target = <&gpio>;
__overlay__ {
pitft_pins: pitft_pins {
brcm,pins = <25>;
brcm,function = <1>; /* out */
brcm,pull = <0>; /* none */
};
};
};
fragment@2 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
pitft: pitft@0{
compatible = "fbtft,minipitft13";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pitft_pins>;
spi-max-frequency = <32000000>;
rotate = <0>;
width = <240>;
height = <240>;
buswidth = <8>;
dc-gpios = <&gpio 25 0>;
led-gpios = <&gpio 26 0>;
debug = <0>;
};
};
};
fragment@3 {
target-path = "/";
__overlay__ {
keypad: tft_bonnet_keys {
compatible = "gpio-keys";
button@17 {
label = "Controller Up";
linux,code = <103>;
gpios = <&gpio 17 1>;
};
button@22 {
label = "Controller Down";
linux,code = <108>;
gpios = <&gpio 22 1>;
};
button@27 {
label = "Controller Left";
linux,code = <105>;
gpios = <&gpio 27 1>;
};
button@23 {
label = "Controller Right";
linux,code = <106>;
gpios = <&gpio 23 1>;
};
button@4 {
label = "Controller Center";
linux,code = <28>;
gpios = <&gpio 4 1>;
};
button@5 {
label = "Controller B";
linux,code = <48>;
gpios = <&gpio 5 1>;
};
button@6 {
label = "Controller A";
linux,code = <30>;
gpios = <&gpio 6 1>;
};
};
};
};
__overrides__ {
speed = <&pitft>,"spi-max-frequency:0";
rotate = <&pitft>,"rotate:0";
width = <&pitft>,"width:0";
height = <&pitft>,"height:0";
fps = <&pitft>,"fps:0";
debug = <&pitft>,"debug:0";
};
};

53
overlays/touch-ft6236.dts Normal file
View 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
View 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>;
};
};
};
};
};

BIN
packages/lgpio.zip Normal file

Binary file not shown.

View file

@ -6,26 +6,6 @@ if [ $(id -u) -ne 0 ]; then
exit 1
fi
clear
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 " python-dev, python-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
fi
# FEATURE PROMPTS ----------------------------------------------------------
# Installation doesn't begin until after all user input is taken.
@ -52,6 +32,45 @@ selectN() {
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)
@ -73,7 +92,7 @@ if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
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
@ -92,15 +111,31 @@ if [ $INSTALL_HALT -eq 1 ]; then
else
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"
else
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."
@ -133,7 +168,6 @@ reconfig2() {
else
# Not found; append to line (silently)
sed -i "s/$/ $3/g" $1 >/dev/null
fi
}
@ -144,10 +178,11 @@ 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 python-pip python-dev python-pil python-smbus
pip install numpy pi3d svg.path adafruit-ads1x15
# smbus and ads1x15 Python libs are installed regardless whether ADC
# is enabled; simplifies the Python code a little (no "uncomment this")
apt-get install -y python3-pip python3-dev python3-pil python3-smbus libatlas-base-dev
# 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")
echo "Installing Adafruit code and data in /boot..."
cd /tmp
@ -171,9 +206,47 @@ fi
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"
@ -186,6 +259,7 @@ else
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
@ -234,10 +308,18 @@ if [ $SCREEN_SELECT -ne 4 ]; then
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;python eyes.py --radius $RADIUS \&/g" /etc/rc.local >/dev/null
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'
sed -i "s/^exit 0/cd \/boot\/Pi_Eyes;python eyes.py --radius $RADIUS \&\\nexit 0/g" /etc/rc.local >/dev/null
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
@ -246,10 +328,18 @@ else
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;python cyclops.py \&/g" /etc/rc.local >/dev/null
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'
sed -i "s/^exit 0/cd \/boot\/Pi_Eyes;python cyclops.py \&\\nexit 0/g" /etc/rc.local >/dev/null
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

129
pi-touch-cam.py Executable file
View file

@ -0,0 +1,129 @@
"""
Adafruit Pi Touch Cam Setup Script
(C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
Converted to Python by Melissa LeBlanc-Williams for Adafruit Industries
Note: Currently Untested
"""
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="Retrogame"
def main():
shell.clear()
print("""This script will install and/or modify
packages needed for the Adafruit Pi
Camera project. It requires that the
adafruit-pitft.sh installer script (for
PiTFT display support) was run first.
Operations performed include:
- In /boot/firmware/config.txt, enable camera
- apt-get update
- Install Python libraries:
picamera, pygame, PIL
- Downgrade SDL library for pygame
touch compatibility
- Download Dropbox Updater and
Adafruit Pi Cam software
Run time 5+ minutes. Reboot required.
""")
boot_config = shell.get_boot_config()
if not shell.prompt("CONTINUE?", default='n'):
print("Canceled.")
shell.exit()
print("Continuing...")
if shell.grep("dtoverlay=pitft", boot_config):
shell.bail(f"PiTFT overlay not in {boot_config}.\n"
"Download & run adafruit-pitft.py first.\n"
"Canceling.")
print("Configuring camera + PiTFT settings...")
# Set PiTFT speed to 80 MHz, 60 Hz
shell.pattern_replace(boot_config, "speed=.*,fps=.*", "speed=80000000,fps=60")
# Check if Pi camera is enabled. If not, add it...
shell.reconfig(boot_config, "^start_x=.*", "start_x=1")
# gpu_mem must be >= 128 MB for camera to work
result = shell.pattern_search(boot_config, "^gpu_mem=", return_match=True)
if not result:
# gpu_mem isn't set. Add to config
shell.write_text_file(boot_config, "\ngpu_mem=128", append=True)
elif result.group(1) < 128:
# gpu_mem present but too small; increase to 128MB
shell.reconfig(boot_config, "^gpu_mem=.*", "gpu_mem=128")
print("Installing prerequisite packages...")
# Enable Wheezy package sources (for SDL downgrade)
shell.write_text_file("/etc/apt/sources.list.d/wheezy.list", "deb http://archive.raspbian.org/raspbian wheezy main\n", append=True)
# Set 'stable' as default package source (current OS)
shell.write_text_file("/etc/apt/apt.conf.d/10defaultRelease", "APT::Default-release \"stable\";\n", append=True)
# Set priority for libsdl from Wheezy higher than current package
shell.write_text_file("/etc/apt/preferences.d/libsdl", (
"Package: libsdl1.2debian\n"
"Pin: release n=stretch\n"
"Pin-Priority: -10\n"
"Pin: release n=jessie\n"
"Pin-Priority: -10\n"
"Package: libsdl1.2debian\n"
"Pin: release n=wheezy\n"
"Pin-Priority:900\n"
))
# Update the APT package index files, install Python libraries
print("Updating System Packages")
if not shell.run_command("sudo apt-get update"):
shell.bail("Apt failed to update indexes!")
print("Installing packages...")
if not shell.run_command("sudo apt-get -y --force-yes install python-picamera python-pygame python-imaging"):
shell.bail("Apt failed to install software!")
print("Downgrading SDL library...")
if not shell.run_command("apt-get -y --force-yes install libsdl1.2debian/wheezy"):
shell.bail("Apt failed to downgrade SDL library!")
print("Downloading Dropbox uploader and")
print("Adafruit Pi Cam to home directory...")
shell.chdir("~pi")
shell.run_command("wget https://github.com/andreafabrizi/Dropbox-Uploader/archive/master.zip")
shell.run_command("unzip master.zip")
shell.remove("master.zip")
shell.move("Dropbox-Uploader-master", "Dropbox-Uploader")
shell.run_command("wget https://github.com/adafruit/adafruit-pi-cam/archive/master.zip")
shell.run_command("unzip master.zip")
shell.remove("master.zip")
shell.chown("Dropbox-Uploader", "pi", recursive=True)
shell.chown("adafruit-pi-cam-master", "pi", recursive=True)
# Add lines to /etc/rc.local (commented out by default):
shell.pattern_replace("/etc/rc.local", "^exit 0", "# Enable this line to run camera at startup:\n# cd /home/pi/adafruit-pi-cam-master ; sudo python cam.py\n\nexit 0")
# Prompt to reboot!
print("\nCamera and PiTFT settings won't take")
print("effect until next boot.")
shell.prompt_reboot()
# Main function
if __name__ == "__main__":
shell.require_root()
main()

181
raspi-blinka.py Normal file
View file

@ -0,0 +1,181 @@
"""
Adafruit Raspberry Pi Blinka Setup Script
(C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
Written by Melissa LeBlanc-Williams for Adafruit Industries
"""
import os
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="Blinka"
default_python = 3
blinka_minimum_python_version = 3.8
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:
try:
return float(version[0:version.rfind(".")])
except ValueError:
return None
return version
def get_python3_version(numeric=True):
version = shell.run_command("python3 -c 'import platform; print(platform.python_version())'", suppress_message=True, return_output=True)
if numeric:
return float(version[0:version.rfind(".")])
return version
def check_blinka_python_version():
"""
Check the Python 3 version for Blinka (which may be a later version than we're running this script with)
"""
print("Making sure the required version of Python is installed")
current = get_python3_version(False)
current_major, current_minor = current.split(".")[0:2]
required_major, required_minor = str(blinka_minimum_python_version).split(".")[0:2]
if int(current_major) >= int(required_major) and int(current_minor) >= int(required_minor):
return
shell.bail("Blinka requires a minimum of Python version {} to install, current one is {}. Please update your OS!".format(blinka_minimum_python_version, current))
def sys_update():
print("Updating System Packages")
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"):
shell.bail("Apt failed to install software!")
def set_raspiconfig():
"""
Enable various Raspberry Pi interfaces
"""
print("Enabling I2C")
shell.run_command("sudo raspi-config nonint do_i2c 0")
print("Enabling SPI")
shell.run_command("sudo raspi-config nonint do_spi 0")
print("Enabling Serial")
if not shell.run_command("sudo raspi-config nonint do_serial_hw 0", suppress_message=True):
shell.run_command("sudo raspi-config nonint do_serial 0")
print("Enabling SSH")
shell.run_command("sudo raspi-config nonint do_ssh 0")
print("Enabling Camera")
shell.run_command("sudo raspi-config nonint do_camera 0")
print("Disable raspi-config at Boot")
shell.run_command("sudo raspi-config nonint disable_raspi_config_at_boot 0")
def update_python():
print("Making sure Python 3 is the default")
if default_python < 3:
shell.run_command("sudo apt-get install -y python3 git python3-pip")
shell.run_command("sudo update-alternatives --install /usr/bin/python python $(which python2) 1")
shell.run_command("sudo update-alternatives --install /usr/bin/python python $(which python3) 2")
shell.run_command("sudo update-alternatives --skip-auto --config python")
def update_pip():
print("Making sure PIP and setuptools is installed")
shell.run_command("sudo apt-get install --upgrade -y python3-pip python3-setuptools")
def install_blinka(user=False):
print("Installing latest version of Blinka locally")
shell.run_command("sudo apt-get install -y i2c-tools libgpiod-dev python3-libgpiod")
pip_command = "pip3 install --upgrade"
username = None
if user:
username = os.environ["SUDO_USER"]
shell.run_command(f"{pip_command} adafruit-blinka", run_as_user=username)
# Custom function to run additional commands for Pi 5
def check_and_install_for_pi5(pi_model, user=False):
if shell.is_pi5_or_newer():
username = None
if user:
# Username should be used for PIP install commands
username = os.environ["SUDO_USER"]
print("Detected Raspberry Pi 5, applying additional fixes...")
if shell.exists("lg"):
shell.remove("lg")
shell.run_command("sudo apt-get install -y wget swig python3-dev python3-setuptools")
# Temporarily install setuptools to as root for the build process
shell.run_command("sudo pip3 install -U setuptools", run_as_user=username)
shell.run_command("wget https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/raw/refs/heads/main/packages/lgpio.zip")
shell.run_command("unzip lgpio.zip")
if shell.exists("lgpio.zip"):
shell.remove("lgpio.zip")
shell.chdir("lgpio")
shell.run_command("make")
shell.run_command("sudo make install")
# Remove setuptools after the build process is complete
shell.run_command("sudo pip3 uninstall -y setuptools", run_as_user=username)
else:
print(f"Detected {pi_model}, no additional fixes needed.")
def check_user_groups():
# Check if the user has the groups i2c, spi, gpio, input, and video. If the user is not in a group, then they need to be added.
groups = shell.run_command("groups", suppress_message=True, return_output=True).split()
required_groups = ["i2c", "spi", "gpio", "input", "video"]
for group in required_groups:
if group not in groups:
print(f"Adding user to the group: {group}.")
shell.run_command(f"sudo usermod -aG {group} {os.environ['SUDO_USER']}")
def main():
global default_python
shell.clear()
# Check Raspberry Pi and Bail
pi_model = shell.get_board_model()
if not shell.is_raspberry_pi():
shell.bail("This model of Raspberry Pi is not currently supported by Blinka")
print("""This script configures your
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")
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()
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 int(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?"):
shell.exit()
sys_update()
check_blinka_python_version()
set_raspiconfig()
update_python()
update_pip()
install_blinka(True)
check_user_groups()
# Check and install any Pi 5 fixes if detected
check_and_install_for_pi5(pi_model, True)
# Done
print("""DONE.
Settings take effect on next boot.
""")
shell.prompt_reboot()
# Main function
if __name__ == "__main__":
shell.require_root()
main()

188
raspi-spi-reassign.py Normal file
View file

@ -0,0 +1,188 @@
"""
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 --upgrade 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="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)
DISABLE_GPIO_TEXT = "Disabled"
boot_dir = "/boot/firmware"
if not shell.exists(boot_dir) or not shell.isdir(boot_dir):
boot_dir = "/boot"
"""
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 and ce1_pin is not None:
return False
if ce0_pin is not None and ce0_pin == ce1_pin:
return False
if ce0_pin is not None and int(ce0_pin) not in allowed_gpios:
return False
if ce1_pin is not None and int(ce1_pin) not in allowed_gpios:
return False
return True
def convert_option(pin):
if pin == "disabled":
return None
return int(pin)
def valid_options(ce0_option, ce1_option):
if ce0_option is None or ce1_option is None:
return False
return valid_pins(convert_option(ce0_option), convert_option(ce1_option))
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 spi_disabled():
return shell.run_command("sudo raspi-config nonint get_spi", suppress_message=True, return_output=True).strip() == "1"
def remove_custom():
shell.pattern_replace(f"{boot_dir}/config.txt", 'dtoverlay=spi0-[0-2]cs,cs.*?\n', multi_line=True)
def format_gpio(gpio):
if gpio is None:
return DISABLE_GPIO_TEXT
return f"GPIO {gpio}"
def gpio_options(pool):
options = []
for gpio in pool:
options.append(format_gpio(gpio))
return options
def write_new_custom(ce0_pin, ce1_pin):
if (ce0_pin, ce1_pin) != spi0_default_pins:
overlay_command = "dtoverlay=spi0-2cs"
if ce0_pin is None and ce1_pin is None:
overlay_command = "dtoverlay=spi0-0cs"
elif ce1_pin is None:
overlay_command = "dtoverlay=spi0-1cs"
if ce0_pin != spi0_default_pins[0] and ce0_pin is not None:
overlay_command += ",cs0_pin={}".format(ce0_pin)
if ce1_pin != spi0_default_pins[1] and ce1_pin is not None:
overlay_command += ",cs1_pin={}".format(ce1_pin)
shell.write_text_file(f"{boot_dir}/config.txt", overlay_command + "\n")
@click.command()
@click.option('--ce0', nargs=1, default=None, help="Specify a GPIO for CE0 or 'disabled' to disable", type=str)
@click.option('--ce1', nargs=1, default=None, help="Specify a GPIO for CE1 or 'disabled' to disable", type=str)
@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_options(ce0, ce1):
ce0 = convert_option(ce0)
ce1 = convert_option(ce1)
remove_custom()
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!
""")
menu_options = [
"Reassign SPI Chip Enable Pins",
"Reset to Defaults Pins",
"Disable SPI",
"Exit",
]
if spi_disabled():
menu_options[2] = "Enable SPI"
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:", menu_options
)
if menu_selection == 1:
while True:
# Reassign
gpio_pool = list(allowed_gpios)
gpio_pool.append(None)
# Ask for pin for CE0
ce0_selection = shell.select_n("Select a new GPIO for CE0", gpio_options(gpio_pool))
ce0_pin = gpio_pool[ce0_selection - 1]
if ce0_pin is not None:
gpio_pool.remove(ce0_pin)
# Ask for pin for CE1
ce1_selection = shell.select_n("Select a new GPIO for CE1", gpio_options(gpio_pool))
ce1_pin = gpio_pool[ce1_selection - 1]
else:
ce1_pin = None
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?"):
break
remove_custom()
write_new_custom(ce0_pin, ce1_pin)
if spi_disabled():
enable_spi()
elif menu_selection == 2:
# Reset to Defaults
remove_custom()
elif menu_selection == 3:
# Enable/Disable SPI
if spi_disabled():
enable_spi()
else:
disable_spi()
remove_custom()
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()

View file

@ -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."

98
retrogame.py Executable file
View file

@ -0,0 +1,98 @@
"""
Adafruit Retrogame Setup Script
(C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
Converted to Python by Melissa LeBlanc-Williams for Adafruit Industries
Note: Currently Untested
"""
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="Retrogame"
def main():
shell.clear()
print("""This script downloads and installs
retrogame, a GPIO-to-keypress utility
for adding buttons and joysticks, plus
one of several configuration files.
Run time <1 minute. Reboot recommended.
""")
# Grouped by config name and menu label
config = {
"pigrrl2": "PiGRRL 2 controls",
"pocket": "Pocket PiGRRL",
"zero": "PiGRRL Zero",
"super": "Super Game Pi",
"2button": "Two buttons + joystick",
"6button": "Six buttons + joystick",
"bonnet": "Adafruit Arcade Bonnet",
"cupcade-orig": "Cupcade (gen 1 & 2 only)"
}
RETROGAME_SELECT = shell.select_n(
"Select configuration:", list(config.values()) + ["Quit without installing"]
)
if RETROGAME_SELECT <= len(config):
CONFIG_NAME = list(config.keys())[RETROGAME_SELECT-1]
if shell.exists("/boot/retrogame.cfg"):
print("/boot/retrogame.cfg already exists.\n"
"Continuing will overwrite file.\n")
if not shell.prompt("CONTINUE?", default='n'):
print("Canceled.")
shell.exit()
print("Downloading, installing retrogame...", end="")
# Download to tmpfile because might already be running
if shell.run_command("curl -f -s -o /tmp/retrogame https://raw.githubusercontent.com/adafruit/Adafruit-Retrogame/master/retrogame"):
shell.move("/tmp/retrogame", "/usr/local/bin/")
os.chmod("/usr/local/bin/retrogame", 0o755)
print("OK")
else:
print("ERROR")
print("Downloading, installing retrogame.cfg...", end="")
if shell.run_command(f"curl -f -s -o /boot/retrogame.cfg https://raw.githubusercontent.com/adafruit/Adafruit-Retrogame/master/configs/retrogame.cfg.{CONFIG_NAME}"):
print("OK")
else:
print("ERROR")
print("Performing other system configuration...", end="")
# Add udev rule (will overwrite if present)
shell.write_text_file("/etc/udev/rules.d/10-retrogame.rules", (
r"SUBSYSTEM==\"input\", ATTRS{name}==\"retrogame\", "
r"ENV{ID_INPUT_KEYBOARD}=\"1\""
))
if CONFIG_NAME == "bonnet":
# If Bonnet, make sure I2C is enabled. Call the I2C
# setup function in raspi-config (noninteractive):
shell.run_command("raspi-config nonint do_i2c 0")
# Start on boot
if shell.run_command("grep retrogame /etc/rc.local", suppress_message=True):
# retrogame already in rc.local, but make sure correct:
shell.pattern_replace("/etc/rc.local", "^.*retrogame.*$", "/usr/local/bin/retrogame &")
else:
# Insert retrogame into rc.local before final 'exit 0'
shell.pattern_replace("/etc/rc.local", "^exit 0", "/usr/local/bin/retrogame &\nexit 0")
print("OK")
shell.prompt_reboot()
print("Done")
# Main function
if __name__ == "__main__":
shell.require_root()
main()

View file

@ -7,7 +7,11 @@
# we reference a specific commit (update this as needed):
GITUSER=https://github.com/hzeller
REPO=rpi-rgb-led-matrix
COMMIT=e3dd56dcc0408862f39cccc47c1d9dea1b0fb2d2
COMMIT=7a503494378a67f3baa4ac680cecbae2703cc58f
# Previously: COMMIT=a3eea997a9254b83ab2de97ae80d83588f696387
# Previously: COMMIT=45d3ab5d6cff6e0c14da58930d662822627471fc
# Previously: COMMIT=21410d2b0bac006b4a1661594926af347b3ce334
# Previously: COMMIT=e3dd56dcc0408862f39cccc47c1d9dea1b0fb2d2
if [ $(id -u) -ne 0 ]; then
echo "Installer must be run as root."
@ -15,6 +19,14 @@ if [ $(id -u) -ne 0 ]; then
exit 1
fi
HAS_PYTHON2=$(which python2)
HAS_PYTHON3=$(which python3)
if [ $HAS_PYTHON2 ] && ! [ $HAS_PYTHON3 ]; then
"Python 2 not supported. Must use Python 3."
exit 0
fi
clear
echo "This script installs software for the Adafruit"
@ -27,10 +39,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
@ -40,24 +52,32 @@ fi
INTERFACE_TYPE=0
INSTALL_RTC=0
QUALITY_MOD=0
#SLOWDOWN_GPIO=5
#MATRIX_SIZE=3
# Given a list of strings representing options, display each option
# preceded by a number (1 to N), display a prompt, check input until
# a valid number within the selection range is entered.
# Can we pass an array?
selectN() {
args=("${@}")
if [[ ${args[0]} = "0" ]]; then
OFFSET=0
else
OFFSET=1
fi
for ((i=0; i<$#; i++)); do
echo $((i+1)). ${args[$i]}
echo $((i+$OFFSET)). ${args[$i]}
done
echo
REPLY=""
let LAST=$#+$OFFSET-1
while :
do
echo -n "SELECT 1-$#: "
echo -n "SELECT $OFFSET-$LAST: "
read
if [[ $REPLY -ge 1 ]] && [[ $REPLY -le $# ]]; then
return $REPLY
if [[ $REPLY -ge $OFFSET ]] && [[ $REPLY -le $LAST ]]; then
let RESULT=$REPLY-$OFFSET
return $RESULT
fi
done
}
@ -70,35 +90,78 @@ INTERFACES=( \
)
QUALITY_OPTS=( \
"Quality (disables sound, requires soldering)" \
"Quality (disables sound, requires soldering on single matrix Bonnet/HAT)" \
"Convenience (sound on, no soldering)" \
)
#SLOWDOWN_OPTS=( \
# "0" \
# "1" \
# "2" \
# "3" \
# "4" \
# "None -- specify at runtime with --led-slowdown-gpio" \
#)
# Default matrix dimensions are currently fixed at 32x32 in RGB matrix lib.
# If that's compile-time configurable in the future, it'll happen here...
#MATRIX_WIDTHS=(32 32 64)
#MATRIX_HEIGHTS=(16 32 32)
#SIZE_OPTS=( \
# "${MATRIX_WIDTHS[0]} x ${MATRIX_HEIGHTS[0]}" \
# "${MATRIX_WIDTHS[1]} x ${MATRIX_HEIGHTS[1]}" \
# "${MATRIX_WIDTHS[2]} x ${MATRIX_HEIGHTS[2]}" \
# "None/other -- specify at runtime with --led-cols and --led-rows" \
#)
echo
echo "Select interface board type:"
selectN "${INTERFACES[@]}"
INTERFACE_TYPE=$?
if [ $INTERFACE_TYPE -eq 2 ]; then
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
fi
fi
#echo
#echo "OPTIONAL: GPIO throttling can be compiled-in so"
#echo "there's no need to specify this every time."
#echo "For Raspberry Pi 4, it's usually 4, sometimes 3."
#echo "Smaller values work for earlier, slower Pi models."
#echo "If unsure, test different settings with the"
#echo "--led-slowdown-gpio flag at runtime, then re-run"
#echo "this installer, selecting the minimum slowdown value"
#echo "that works reliably with your Pi and matrix."
#echo "GPIO slowdown setting:"
#selectN "${SLOWDOWN_OPTS[@]}"
#SLOWDOWN_GPIO=$?
#echo
#echo "OPTIONAL: matrix size can be compiled-in so"
#echo "there's no need to specify this every time."
#echo "Some common Adafruit matrix sizes:"
#selectN "${SIZE_OPTS[@]}"
#MATRIX_SIZE=$?
echo
echo "Now you must choose between QUALITY and CONVENIENCE."
echo
echo "QUALITY: best output from the LED matrix requires"
echo "commandeering hardware normally used for sound, plus"
echo "some soldering. If you choose this option, there will"
echo "some soldering on the single matrix Bonnet/HAT. If"
echo "you choose this option, there will"
echo "be NO sound from the audio jack or HDMI (USB audio"
echo "adapters will work and sound best anyway), AND you"
echo "must SOLDER a wire between GPIO4 and GPIO18 on the"
echo "Bonnet or HAT board."
echo "single matrix Bonnet or HAT board. For the Triple LED"
echo "Matrix Bonnet choose QUALITY, and No soldering is"
echo "required."
echo
echo "CONVENIENCE: sound works normally, no extra soldering."
echo "Images on the LED matrix are not quite as steady, but"
@ -113,20 +176,22 @@ QUALITY_MOD=$?
# VERIFY SELECTIONS BEFORE CONTINUING --------------------------------------
echo
echo "Interface board type: ${INTERFACES[$INTERFACE_TYPE-1]}"
if [ $INTERFACE_TYPE -eq 2 ]; then
echo "Interface board type: ${INTERFACES[$INTERFACE_TYPE]}"
if [ $INTERFACE_TYPE -eq 1 ]; then
echo "Install RTC support: ${OPTION_NAMES[$INSTALL_RTC]}"
fi
echo "Optimize: ${QUALITY_OPTS[$QUALITY_MOD-1]}"
if [ $QUALITY_MOD -eq 1 ]; then
#echo "GPIO slowdown: ${SLOWDOWN_OPTS[$SLOWDOWN_GPIO]}"
#echo "Matrix size: ${SIZE_OPTS[$MATRIX_SIZE]}"
echo "Optimize: ${QUALITY_OPTS[$QUALITY_MOD]}"
if [ $QUALITY_MOD -eq 0 ]; then
echo "Reminder: you must SOLDER a wire between GPIO4"
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
@ -153,7 +218,7 @@ 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
apt-get install -y python3-dev python3-pillow cython3
echo "Downloading RGB matrix software..."
curl -L $GITUSER/$REPO/archive/$COMMIT.zip -o $REPO-$COMMIT.zip
@ -162,23 +227,13 @@ rm $REPO-$COMMIT.zip
mv $REPO-$COMMIT rpi-rgb-led-matrix
echo "Building RGB matrix software..."
cd rpi-rgb-led-matrix
USER_DEFINES=""
if [ $QUALITY_MOD -eq 1 ]; then
# Build then install for Python 2.7...
make build-python HARDWARE_DESC=adafruit-hat-pwm
make install-python HARDWARE_DESC=adafruit-hat-pwm
# Do over for Python 3...
make clean
make build-python HARDWARE_DESC=adafruit-hat-pwm PYTHON=$(which python3)
make install-python HARDWARE_DESC=adafruit-hat-pwm PYTHON=$(which python3)
else
# Build then install for Python 2.7...
make build-python HARDWARE_DESC=adafruit-hat USER_DEFINES="-DDISABLE_HARDWARE_PULSES"
make install-python HARDWARE_DESC=adafruit-hat USER_DEFINES="-DDISABLE_HARDWARE_PULSES"
# Do over for Python 3...
make clean
make build-python HARDWARE_DESC=adafruit-hat USER_DEFINES="-DDISABLE_HARDWARE_PULSES" PYTHON=$(which python3)
make install-python HARDWARE_DESC=adafruit-hat USER_DEFINES="-DDISABLE_HARDWARE_PULSES" PYTHON=$(which python3)
USER_DEFINES+=" -DDISABLE_HARDWARE_PULSES"
fi
make clean
make build-python USER_DEFINES="$USER_DEFINES"
# Change ownership to user calling sudo
chown -R $SUDO_USER:$(id -g $SUDO_USER) `pwd`
@ -191,19 +246,18 @@ if [ $INSTALL_RTC -ne 0 ]; then
# Enable I2C for RTC
raspi-config nonint do_i2c 0
# Do additional RTC setup for DS1307
reconfig /boot/config.txt "^.*dtoverlay=i2c-rtc.*$" "dtoverlay=i2c-rtc,ds1307"
reconfig /boot/firmware/config.txt "^.*dtoverlay=i2c-rtc.*$" "dtoverlay=i2c-rtc,ds1307"
apt-get -y remove fake-hwclock
update-rc.d -f fake-hwclock remove
sudo sed --in-place '/if \[ -e \/run\/systemd\/system \] ; then/,+2 s/^#*/#/' /lib/udev/hwclock-set
sed --in-place '/if \[ -e \/run\/systemd\/system \] ; then/,+2 s/^#*/#/' /lib/udev/hwclock-set
fi
if [ $QUALITY_MOD -eq 1 ]; then
# Disable sound ('easy way' -- kernel module not blacklisted)
reconfig /boot/config.txt "^.*dtparam=audio.*$" "dtparam=audio=off"
if [ $QUALITY_MOD -eq 0 ]; then
# Disable sound via blacklist
echo "blacklist snd_bcm2835" > /etc/modprobe.d/blacklist-rgb-matrix.conf
else
# Enable sound (ditto)
reconfig /boot/config.txt "^.*dtparam=audio.*$" "dtparam=audio=on"
# Remove from blacklist
rm -f /etc/modprobe.d/blacklist-rgb-matrix.conf
fi
# PROMPT FOR REBOOT --------------------------------------------------------
@ -214,14 +268,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
exit 0
sleep infinity

View file

@ -1,220 +0,0 @@
#!/bin/bash
# INSTALLER SCRIPT FOR ADAFRUIT RGB MATRIX BONNET OR HAT
# hzeller/rpi-rgb-led-matrix sees lots of active development!
# That's cool and all, BUT, to avoid tutorial breakage,
# we reference a specific commit (update this as needed):
GITUSER=https://github.com/hzeller
REPO=rpi-rgb-led-matrix
COMMIT=58830f7bb5dfb47fc24f1fd26cd7c4e3a20f13f7
if [ $(id -u) -ne 0 ]; then
echo "Installer must be run as root."
echo "Try 'sudo bash $0'"
exit 1
fi
clear
echo "This script installs software for the Adafruit"
echo "RGB Matrix Bonnet or HAT for Raspberry Pi."
echo "Steps include:"
echo "- Update package index files (apt-get update)"
echo "- Install prerequisite software"
echo "- Install RGB matrix driver software"
echo "- Configure boot options"
echo "Run time ~10 minutes. Some options require reboot."
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
fi
# FEATURE PROMPTS ----------------------------------------------------------
# Installation doesn't begin until after all user input is taken.
INTERFACE_TYPE=0
INSTALL_RTC=0
QUALITY_MOD=0
# Given a list of strings representing options, display each option
# preceded by a number (1 to N), display a prompt, check input until
# a valid number within the selection range is entered.
# Can we pass an array?
selectN() {
args=("${@}")
for ((i=0; i<$#; i++)); do
echo $((i+1)). ${args[$i]}
done
echo
REPLY=""
while :
do
echo -n "SELECT 1-$#: "
read
if [[ $REPLY -ge 1 ]] && [[ $REPLY -le $# ]]; then
return $REPLY
fi
done
}
OPTION_NAMES=(NO YES)
INTERFACES=( \
"Adafruit RGB Matrix Bonnet" \
"Adafruit RGB Matrix HAT + RTC" \
)
QUALITY_OPTS=( \
"Quality (disables sound, requires soldering)" \
"Convenience (sound on, no soldering)" \
)
echo
echo "Select interface board type:"
selectN "${INTERFACES[@]}"
INTERFACE_TYPE=$?
if [ $INTERFACE_TYPE -eq 2 ]; then
# For matrix HAT, ask about RTC install
echo
echo -n "Install realtime clock support? [y/N] "
read
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
INSTALL_RTC=1
fi
fi
echo
echo "Now you must choose between QUALITY and CONVENIENCE."
echo
echo "QUALITY: best output from the LED matrix requires"
echo "commandeering hardware normally used for sound, plus"
echo "some soldering. If you choose this option, there will"
echo "be NO sound from the audio jack or HDMI (USB audio"
echo "adapters will work and sound best anyway), AND you"
echo "must SOLDER a wire between GPIO4 and GPIO18 on the"
echo "Bonnet or HAT board."
echo
echo "CONVENIENCE: sound works normally, no extra soldering."
echo "Images on the LED matrix are not quite as steady, but"
echo "maybe OK for most uses. If eager to get started, use"
echo "'CONVENIENCE' for now, you can make the change and"
echo "reinstall using this script later!"
echo
echo "What is thy bidding?"
selectN "${QUALITY_OPTS[@]}"
QUALITY_MOD=$?
# VERIFY SELECTIONS BEFORE CONTINUING --------------------------------------
echo
echo "Interface board type: ${INTERFACES[$INTERFACE_TYPE-1]}"
if [ $INTERFACE_TYPE -eq 2 ]; then
echo "Install RTC support: ${OPTION_NAMES[$INSTALL_RTC]}"
fi
echo "Optimize: ${QUALITY_OPTS[$QUALITY_MOD-1]}"
if [ $QUALITY_MOD -eq 1 ]; then
echo "Reminder: you must SOLDER a wire between GPIO4"
echo "and GPIO18, and internal sound is DISABLED!"
fi
echo
echo -n "CONTINUE? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Canceled."
exit 0
fi
# START INSTALL ------------------------------------------------------------
# All selections are validated at this point...
# Given a filename, a regex pattern to match and a replacement string,
# 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
}
echo
echo "Starting installation..."
echo "Updating package index files..."
apt-get update
echo "Downloading prerequisites..."
apt-get install -y --force-yes python-dev python-imaging
echo "Downloading RGB matrix software..."
curl -L $GITUSER/$REPO/archive/$COMMIT.zip -o $REPO-$COMMIT.zip
unzip -q $REPO-$COMMIT.zip
rm $REPO-$COMMIT.zip
mv $REPO-$COMMIT rpi-rgb-led-matrix
echo "Building RGB matrix software..."
cd rpi-rgb-led-matrix
if [ $QUALITY_MOD -eq 1 ]; then
HARDWARE_DESC=adafruit-hat-pwm make
cd bindings/python
python setup.py install
else
HARDWARE_DESC=adafruit-hat make USER_DEFINES="-DDISABLE_HARDWARE_PULSES"
cd bindings/python
python setup.py install
fi
# Change ownership to user calling sudo
cd ../../..
chown -R $SUDO_USER:$(id -g $SUDO_USER) rpi-rgb-led-matrix
# CONFIG -------------------------------------------------------------------
echo "Configuring system..."
if [ $INSTALL_RTC -ne 0 ]; then
# Enable I2C for RTC
raspi-config nonint do_i2c 0
# Do additional RTC setup for DS1307
reconfig /boot/config.txt "^.*dtoverlay=i2c-rtc.*$" "dtoverlay=i2c-rtc,ds1307"
apt-get -y remove fake-hwclock
update-rc.d -f fake-hwclock remove
sudo sed --in-place '/if \[ -e \/run\/systemd\/system \] ; then/,+2 s/^#*/#/' /lib/udev/hwclock-set
fi
if [ $QUALITY_MOD -eq 1 ]; then
# Disable sound ('easy way' -- kernel module not blacklisted)
reconfig /boot/config.txt "^.*dtparam=audio.*$" "dtparam=audio=off"
else
# Enable sound (ditto)
reconfig /boot/config.txt "^.*dtparam=audio.*$" "dtparam=audio=on"
fi
# PROMPT FOR REBOOT --------------------------------------------------------
echo "Done."
echo
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."
fi
echo
echo -n "REBOOT NOW? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Exiting without reboot."
exit 0
fi
echo "Reboot started..."
reboot
exit 0

View file

@ -0,0 +1,60 @@
"""
Adafruit Raspberry Pi Script to Pin a specific version of the rpi kernel and firmware
(C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
Converted to Python by Melissa LeBlanc-Williams for Adafruit Industries
"""
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 = 'PINNING'
def main():
shell.clear()
# Check Raspberry Pi and Bail
pi_model = shell.get_board_model()
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":
print("OS Detected:" + shell.get_os())
shell.bail("Sorry. This script currently only runs on Raspberry Pi OS.")
if len(shell.args) == 1:
print("Usage: sudo python3 {} kernel-version\n".format(shell.script()))
print("e.g., {} 1.20201126-1".format(shell.script()))
shell.exit(1)
version = shell.args[1]
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"
]
new_packages = []
for package in packagelist:
filename = f"{package}_{version}_armhf.deb"
new_packages.append(filename)
shell.run_command("wget --continue -O {} {}".format(filename, base + filename))
shell.run_command("dpkg -i " + " ".join(new_packages))
for package in packagelist:
shell.write_text_file("/etc/apt/preferences.d/99-adafruit-pin-kernel", (
f"Package: {package}\n"
f"Pin: version {version}\n"
f"Pin-Priority:999\n\n"
))
shell.prompt_reboot()
# Main function
if __name__ == "__main__":
shell.require_root()
main()

163
rtc.py Executable file
View file

@ -0,0 +1,163 @@
"""
Adafruit Raspberry Pi Real Time Clock Setup Script
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
This script is licensed under the terms of the MIT license.
Unless otherwise noted, code reproduced herein
was written for this script.
Originally written by the - The Pimoroni Crew -
Converted to Python by Melissa LeBlanc-Williams for Adafruit Industries
Note: Currently Untested
"""
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()
productname = "Real Time Clock module" # the name of the product to install
rtcsubtype = "ds1307"
baseurl = "http://www.adafru.it"
scriptname = "rtc.py" # the name of this script
spacereq = 1 # minimum size required on root partition in MB
debugmode = False # whether the script should use debug routines
debuguser = None # optional test git user to use in debug mode
debugpoint = None # optional git repo branch or tag to checkout
forcesudo = True # whether the script requires to be ran with root privileges
promptreboot = False # whether the script should always prompt user to reboot
customcmd = True # whether to execute commands specified before exit
i2creq = True # whether the i2c interface is required
i2sreq = False # whether the i2s interface is required
spireq = False # whether the spi interface is required
uartreq = False # whether uart communication is required
armhfonly = True # whether the script is allowed to run on other arch
armv6 = True # whether armv6 processors are supported
armv7 = True # whether armv7 processors are supported
armv8 = True # whether armv8 processors are supported
raspbianonly = True # whether the script is allowed to run on other OSes
macosxsupport = False # whether Mac OS X is supported by the script
osreleases = ( "Raspbian" ) # list os-releases supported
oswarning = ( "Debian", "Ubuntu", "Mate" ) # list experimental os-releases
squeezesupport = False # whether Squeeze is supported
wheezysupport = False # whether Wheezy is supported
jessiesupport = True # whether Jessie is supported
DEVICE_TREE = True
ASK_TO_REBOOT = False
CURRENT_SETTING = False
UPDATED_DB = False
BOOTCMD = "/boot/cmdline.txt"
CONFIG = shell.get_boot_config()
APTSRC = "/etc/apt/sources.list"
INITABCONF = "/etc/inittab"
BLACKLIST = "/etc/modprobe.d/raspi-blacklist.conf"
LOADMOD = "/etc/modules"
DTBODIR = "/boot/overlays"
def raspbian_old():
return shell.get_raspbian_version() in ("wheezy", "squeeze")
def dt_check():
# Check if /boot/firmware/config.txt exists and de
return shell.exists(CONFIG) and not shell.pattern_search(CONFIG, "^device_tree=$")
#Perform all global variables declarations as well as function definition
#above this section for clarity, thanks!
def main():
os_release = shell.get_raspbian_version()
IS_SUPPORTED = os_release in osreleases
IS_EXPERIMENTAL = os_release in oswarning
if not shell.is_armhf() or shell.is_arm64():
shell.bail("This hardware is not supported, sorry!\n"
"Config files have been left untouched")
if shell.is_raspberry_pi_os():
if not wheezysupport and raspbian_old():
shell.bail(
"\n--- Warning ---\n"
f"The {productname} installer\n"
"does not work on this version of Raspbian.\n"
r"Check https://github.com/{gitusername}/{gitreponame}"
"\nfor additional information and support")
elif raspbianonly:
shell.bail("This script is intended for Raspbian on a Raspberry Pi!")
else:
if not IS_SUPPORTED and not IS_EXPERIMENTAL:
shell.bail(
"Your operating system is not supported, sorry!\n"
"Config files have been left untouched")
if forcesudo:
shell.require_root()
print(f"\nThis script will install everything needed to use {productname}\n")
shell.warn(
"--- Warning ---\n"
"Always be careful when running scripts and commands\n"
"copied from the internet. Ensure they are from a\n"
"trusted source.\n"
"\n"
"If you want to see what this script does before\n"
"running it, you should run:\n"
" \curl -sS $baseurl/$scriptname\n"
"\n"
)
if shell.prompt("Do you wish to continue?", force_arg="y", default="n"):
print("\nChecking hardware requirements...")
if i2creq == "yes":
print()
if shell.prompt("Hardware requires I2C, enable now?", force_arg="y", default="n"):
shell.run_command("sudo raspi-config nonint do_i2c 0")
if not dt_check():
shell.bail(
"Device Tree support required!\n"
"Config files have been left untouched\n"
)
rtc_values = ("ds1307", "ds3231", "pcf8523")
rtcsubtype = rtc_values[shell.select_n("What RTC would you like to install?", rtc_values) - 1]
print("Disabling any current RTC")
shell.run_command(f"sudo sed --in-place '/dtoverlay[[:space:]]*=[[:space:]]*i2c-rtc/d' {CONFIG}")
print(f"Adding DT overlay for {rtcsubtype}")
shell.write_text_file(CONFIG, f"dtoverlay=i2c-rtc,{rtcsubtype}", append=True)
print("Removing fake-hwclock")
shell.run_command("sudo apt-get -y remove fake-hwclock")
shell.run_command("sudo update-rc.d -f fake-hwclock remove")
if not shell.exists("/lib/udev/hwclock-set"):
shell.bail("Couldn't find /lib/udev/hwclock-set")
shell.warn("Configuring HW Clock")
shell.run_command("sudo sed --in-place '/if \[ -e \/run\/systemd\/system \] ; then/,+2 s/^#*/#/' /lib/udev/hwclock-set")
shell.prompt_reboot()
else:
shell.warn("\nAborting...")
# Main function
if __name__ == "__main__":
main()

273
spectro.sh Normal file
View file

@ -0,0 +1,273 @@
#!/bin/bash
# INSTALLER SCRIPT FOR ADAFRUIT SPECTRO PROJECT
if [ $(id -u) -ne 0 ]; then
echo "Installer must be run as root."
echo "Try 'sudo bash $0'"
exit 1
fi
clear
echo "This script installs software for the Adafruit"
echo "Spectro project for Raspberry Pi."
echo "Steps include:"
echo "- Update package index files (apt-get update)"
echo "- Install prerequisite software"
echo "- Install Spectro software"
echo "- Configure hardware and boot options"
echo "Run time ~10 minutes."
echo
echo "EXISTING INSTALLATION, IF ANY, WILL BE OVERWRITTEN."
echo "If you've edited any Spectro-related files, cancel"
echo "the installation and back up those files first."
echo
echo -n "CONTINUE? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Canceled."
exit 0
fi
# FEATURE PROMPTS ----------------------------------------------------------
# Installation doesn't begin until after all user input is taken.
MATRIX_SIZE=0
SLOWDOWN_GPIO=0
ENABLE_MIC=0
ENABLE_ACCEL=0
HDMI_SIZE=0
OPTION_NAMES=(NO YES)
MATRIX_WIDTHS=(64 32)
MATRIX_HEIGHTS=(32 16)
SIZE_OPTS=( \
"${MATRIX_WIDTHS[0]} x ${MATRIX_HEIGHTS[0]}" \
"${MATRIX_WIDTHS[1]} x ${MATRIX_HEIGHTS[1]}" \
)
SLOWDOWN_OPTS=( \
"0" \
"1" \
"2" \
"3" \
"4" \
)
HDMI_OPTS=( \
"640x480" \
"320x240" \
)
# Given a list of strings representing options, display each option
# preceded by a number (1 to N), display a prompt, check input until
# a valid number within the selection range is entered.
selectN() {
args=("${@}")
# If first item in list is the literal number '0', make the list
# indexed from 0 rather than 1. This is to avoid confusion when
# entering the GPIO slowdown setting (e.g. entering '1' for a
# value of '0' is awkward). In all other cases, list is indexed
# from 1 as this is more human.
if [[ ${args[0]} = "0" ]]; then
OFFSET=0
else
OFFSET=1
fi
for ((i=0; i<$#; i++)); do
echo $((i+$OFFSET)). ${args[$i]}
done
echo
REPLY=""
let LAST=$#+$OFFSET-1
while :
do
echo -n "SELECT $OFFSET-$LAST: "
read
if [[ $REPLY -ge $OFFSET ]] && [[ $REPLY -le $LAST ]]; then
let RESULT=$REPLY-$OFFSET
return $RESULT
fi
done
}
echo
echo "What size LED matrix are you using with Spectro?"
selectN "${SIZE_OPTS[@]}"
MATRIX_SIZE=$?
echo
echo "Faster Pi boards require dialing back GPIO speed"
echo "to work with the LED matrix. For Raspberry Pi 4,"
echo "this usually means the max '4' slowdown setting."
echo "For Pi 2 or 3, try the '1' or '2' settings. There"
echo "is no hard-set rule to this, it can vary with"
echo "matrix and cabling as well. If the Spectro display"
echo "is glitchy, just re-run this installer, selecting"
echo "a higher setting until you find a stable value."
echo "GPIO slowdown setting:"
selectN "${SLOWDOWN_OPTS[@]}"
SLOWDOWN_GPIO=$?
echo
echo -n "OPTIONAL: Enable USB microphone support? [y/N] "
read
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
ENABLE_MIC=1
fi
echo
echo -n "OPTIONAL: Enable LIS3DH accelerometer support? [y/N] "
read
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
ENABLE_ACCEL=1
fi
# HDMI resolution selection might be handled later; right now nothing
# requires it. But in the future if anything relies on fb2matrix.py,
# HDMI resolution ultimately determines the frame rate that's possible,
# flipside being that some monitors can't handle extremely low resolutions.
# So an option might be presented here, set to 320x240 or 640x480 (the
# latter being the minimum resolution some displays can support).
# VERIFY SELECTIONS BEFORE CONTINUING --------------------------------------
echo
echo "LED matrix size: ${SIZE_OPTS[$MATRIX_SIZE]}"
echo "GPIO slowdown: ${SLOWDOWN_OPTS[$SLOWDOWN_GPIO]}"
echo "Enable USB microphone support: ${OPTION_NAMES[$ENABLE_MIC]}"
echo "Enable LIS3DH support: ${OPTION_NAMES[$ENABLE_ACCEL]}"
#echo "HDMI resolution: ${HDMI_OPTS[$HDMI_SIZE]}"
echo
echo -n "CONTINUE? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Canceled."
exit 0
fi
# Check whether RGB matrix library is present.
# If not, offer to download and run that script first (then return here).
echo
echo "Updating package index files..."
apt-get update
apt-get -qq install python3-pip python-pip
echo -n "Checking for RGB matrix library..."
pip3 freeze | grep rgbmatrix > /dev/null
if [ $? -eq 0 ]; then
echo "OK."
else
echo "not present."
echo "Would you like to download and install the RGB matrix"
echo "library (required by Spectro) first? If so, DO NOT REBOOT"
echo "when prompted. Youll return to this script for more"
echo "Spectro configuration."
echo -n "Run RGB matrix installer? [y/N] "
read
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/rgb-matrix.sh -O rgb-matrix.sh
bash rgb-matrix.sh
echo
echo "You are now back in the main Spectro installer script."
echo "When prompted about reboot again, now it's OK!"
fi
fi
# START INSTALL ------------------------------------------------------------
# All selections are validated at this point...
# Given a filename, a regex pattern to match and a replacement string,
# 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
}
# Same as above, but skips if pattern not found
reconfig2() {
grep $2 $1 >/dev/null
if [ $? -eq 0 ]; then
# Pattern found; replace in file
sed -i "s/$2/$3/g" $1 >/dev/null
fi
}
echo
echo "Starting installation..."
# Although Spectro is all Python3-ready, user additions might rely on
# Python2, so we'll install the prerequisite libraries for both 2 and 3...
echo "Downloading prerequisites..."
pip3 install psutil RPi.GPIO
pip install psutil RPi.GPIO
apt-get install -y --allow-unauthenticated python3-dev python3-pillow python2.7-dev python-pillow
if [ $ENABLE_MIC -ne 0 ]; then
apt-get install -y --allow-unauthenticated python3-pyaudio python3-numpy python-pyaudio python-numpy
fi
if [ $ENABLE_ACCEL -ne 0 ]; then
pip3 install adafruit-circuitpython-busdevice adafruit-circuitpython-lis3dh
pip install adafruit-circuitpython-busdevice adafruit-circuitpython-lis3dh
fi
echo "Downloading Spectro software..."
curl -L https://github.com/adafruit/Adafruit_Spectro_Pi/archive/master.zip -o Adafruit_Spectro_Pi.zip
unzip -q -o Adafruit_Spectro_Pi.zip
rm Adafruit_Spectro_Pi.zip
mv Adafruit_Spectro_Pi-master Adafruit_Spectro_Pi
chown -R pi:pi Adafruit_Spectro_Pi
# CONFIG -------------------------------------------------------------------
echo "Configuring system..."
if [ $ENABLE_MIC -ne 0 ]; then
# Change ALSA settings to allow USB mic use
reconfig2 /usr/share/alsa/alsa.conf "^defaults.ctl.card.*0" "defaults.ctl.card 1"
reconfig2 /usr/share/alsa/alsa.conf "^defaults.pcm.card.*0" "defaults.pcm.card 1"
fi
if [ $ENABLE_ACCEL -ne 0 ]; then
# Enable I2C for accelerometer
raspi-config nonint do_i2c 0
fi
# Make default GIFs directory
mkdir /boot/gifs
# Set up LED columns, rows and slowdown in selector.py script
reconfig2 ./Adafruit_Spectro_Pi/selector.py "^FLAGS.*$" "FLAGS\ =\ [\"--led-cols=${MATRIX_WIDTHS[$MATRIX_SIZE]}\",\ \"--led-rows=${MATRIX_HEIGHTS[$MATRIX_SIZE]}\",\ \"--led-slowdown-gpio=${SLOWDOWN_OPTS[$SLOWDOWN_GPIO]}\"]"
# Force HDMI out so /dev/fb0 exists
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"
# Auto-start selector.py on boot
grep selector.py /etc/rc.local >/dev/null
if [ $? -ne 0 ]; then
# Insert selector.py into rc.local before final 'exit 0'
sed -i "s/^exit 0/cd \/home\/pi\/Adafruit_Spectro_Pi\;python3 selector.py \&\\nexit 0/g" /etc/rc.local >/dev/null
fi
# PROMPT FOR REBOOT --------------------------------------------------------
echo "Done."
echo
echo "Settings take effect on next boot."
echo "For proper clock time, set the time zone with raspi-config."
echo
echo -n "REBOOT NOW? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Exiting without reboot."
exit 0
fi
echo "Reboot started..."
reboot
sleep infinity

View file

@ -1,14 +1,13 @@
obj-m+=st7789v_ada.o
obj-m += fb_st7789v.o
KDIR ?= /lib/modules/`uname -r`/build
default:
$(MAKE) -C $(KDIR) M=$(pwd) modules
$(MAKE) -C $(KDIR) M=$(shell pwd) modules
install:
$(MAKE) -C $(KDIR) M=$(PWD) modules_install
$(MAKE) -C $(KDIR) M=$(shell pwd) modules_install
$(DEPMOD)
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
$(MAKE) -C $(KDIR) M=$(shell pwd) clean

448
st7789_module/fb_st7789v.c Normal file
View file

@ -0,0 +1,448 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* FB driver for the ST7789V LCD Controller
*
* Copyright (C) 2015 Dennis Menschel
*/
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/module.h>
#include <video/mipi_display.h>
#include "fbtft.h"
#define DRVNAME "fb_st7789v"
#define DEFAULT_GAMMA \
"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25\n" \
"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25"
#define HSD20_IPS_GAMMA \
"D0 05 0A 09 08 05 2E 44 45 0F 17 16 2B 33\n" \
"D0 05 0A 09 08 05 2E 43 45 0F 16 16 2B 33"
#define HSD20_IPS 1
/**
* enum st7789v_command - ST7789V display controller commands
*
* @PORCTRL: porch setting
* @GCTRL: gate control
* @VCOMS: VCOM setting
* @VDVVRHEN: VDV and VRH command enable
* @VRHS: VRH set
* @VDVS: VDV set
* @VCMOFSET: VCOM offset set
* @PWCTRL1: power control 1
* @PVGAMCTRL: positive voltage gamma control
* @NVGAMCTRL: negative voltage gamma control
*
* The command names are the same as those found in the datasheet to ease
* looking up their semantics and usage.
*
* Note that the ST7789V display controller offers quite a few more commands
* which have been omitted from this list as they are not used at the moment.
* Furthermore, commands that are compliant with the MIPI DCS have been left
* out as well to avoid duplicate entries.
*/
enum st7789v_command {
PORCTRL = 0xB2,
GCTRL = 0xB7,
VCOMS = 0xBB,
VDVVRHEN = 0xC2,
VRHS = 0xC3,
VDVS = 0xC4,
VCMOFSET = 0xC5,
PWCTRL1 = 0xD0,
PVGAMCTRL = 0xE0,
NVGAMCTRL = 0xE1,
};
#define MADCTL_BGR BIT(3) /* bitmask for RGB/BGR order */
#define MADCTL_MV BIT(5) /* bitmask for page/column order */
#define MADCTL_MX BIT(6) /* bitmask for column address order */
#define MADCTL_MY BIT(7) /* bitmask for page address order */
/* 60Hz for 16.6ms, configured as 2*16.6ms */
#define PANEL_TE_TIMEOUT_MS 33
static struct completion panel_te; /* completion for panel TE line */
static int irq_te; /* Linux IRQ for LCD TE line */
static u32 col_start_offset = 0;
static u32 col_end_offset = 0;
static u32 row_start_offset = 0;
static u32 row_end_offset = 0;
static short x_offset = 0;
static short y_offset = 0;
static irqreturn_t panel_te_handler(int irq, void *data)
{
complete(&panel_te);
return IRQ_HANDLED;
}
/*
* init_tearing_effect_line() - init tearing effect line.
* @par: FBTFT parameter object.
*
* Return: 0 on success, or a negative error code otherwise.
*/
static int init_tearing_effect_line(struct fbtft_par *par)
{
struct device *dev = par->info->device;
struct gpio_desc *te;
int rc, irq;
te = gpiod_get_optional(dev, "te", GPIOD_IN);
if (IS_ERR(te))
return dev_err_probe(dev, PTR_ERR(te), "Failed to request te GPIO\n");
/* if te is NULL, indicating no configuration, directly return success */
if (!te) {
irq_te = 0;
return 0;
}
irq = gpiod_to_irq(te);
/* GPIO is locked as an IRQ, we may drop the reference */
gpiod_put(te);
if (irq < 0)
return irq;
irq_te = irq;
init_completion(&panel_te);
/* The effective state is high and lasts no more than 1000 microseconds */
rc = devm_request_irq(dev, irq_te, panel_te_handler,
IRQF_TRIGGER_RISING, "TE_GPIO", par);
if (rc)
return dev_err_probe(dev, rc, "TE IRQ request failed.\n");
disable_irq_nosync(irq_te);
return 0;
}
/**
* init_display() - initialize the display controller
*
* @par: FBTFT parameter object
*
* Most of the commands in this init function set their parameters to the
* same default values which are already in place after the display has been
* powered up. (The main exception to this rule is the pixel format which
* would default to 18 instead of 16 bit per pixel.)
* Nonetheless, this sequence can be used as a template for concrete
* displays which usually need some adjustments.
*
* Return: 0 on success, < 0 if error occurred.
*/
static int init_display(struct fbtft_par *par)
{
int rc;
par->fbtftops.reset(par);
rc = init_tearing_effect_line(par);
if (rc)
return rc;
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
/* set pixel format to RGB-565 */
write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
if (HSD20_IPS)
write_reg(par, PORCTRL, 0x05, 0x05, 0x00, 0x33, 0x33);
else
write_reg(par, PORCTRL, 0x08, 0x08, 0x00, 0x22, 0x22);
/*
* VGH = 13.26V
* VGL = -10.43V
*/
if (HSD20_IPS)
write_reg(par, GCTRL, 0x75);
else
write_reg(par, GCTRL, 0x35);
/*
* VDV and VRH register values come from command write
* (instead of NVM)
*/
write_reg(par, VDVVRHEN, 0x01, 0xFF);
/*
* VAP = 4.1V + (VCOM + VCOM offset + 0.5 * VDV)
* VAN = -4.1V + (VCOM + VCOM offset + 0.5 * VDV)
*/
if (HSD20_IPS)
write_reg(par, VRHS, 0x13);
else
write_reg(par, VRHS, 0x0B);
/* VDV = 0V */
write_reg(par, VDVS, 0x20);
/* VCOM = 0.9V */
if (HSD20_IPS)
write_reg(par, VCOMS, 0x22);
else
write_reg(par, VCOMS, 0x20);
/* VCOM offset = 0V */
write_reg(par, VCMOFSET, 0x20);
/*
* AVDD = 6.8V
* AVCL = -4.8V
* VDS = 2.3V
*/
write_reg(par, PWCTRL1, 0xA4, 0xA1);
/* TE line output is off by default when powering on */
if (irq_te)
write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
if (HSD20_IPS)
write_reg(par, MIPI_DCS_ENTER_INVERT_MODE);
return 0;
}
/*
* write_vmem() - write data to display.
* @par: FBTFT parameter object.
* @offset: offset from screen_buffer.
* @len: the length of data to be writte.
*
* Return: 0 on success, or a negative error code otherwise.
*/
static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
{
struct device *dev = par->info->device;
int ret;
if (irq_te) {
enable_irq(irq_te);
reinit_completion(&panel_te);
ret = wait_for_completion_timeout(&panel_te,
msecs_to_jiffies(PANEL_TE_TIMEOUT_MS));
if (ret == 0)
dev_err(dev, "wait panel TE timeout\n");
disable_irq(irq_te);
}
switch (par->pdata->display.buswidth) {
case 8:
ret = fbtft_write_vmem16_bus8(par, offset, len);
break;
case 9:
ret = fbtft_write_vmem16_bus9(par, offset, len);
break;
case 16:
ret = fbtft_write_vmem16_bus16(par, offset, len);
break;
default:
dev_err(dev, "Unsupported buswidth %d\n",
par->pdata->display.buswidth);
ret = 0;
break;
}
return ret;
}
static void minipitft13_set_addr_win(struct fbtft_par *par, int xs, int ys,
int xe, int ye)
{
xs += x_offset;
xe += x_offset;
ys += y_offset;
ye += y_offset;
write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
}
/**
* set_var() - apply LCD properties like rotation and BGR mode
*
* @par: FBTFT parameter object
*
* Return: 0 on success, < 0 if error occurred.
*/
static int set_var(struct fbtft_par *par)
{
u8 madctl_par = 0;
struct fbtft_display *display = &par->pdata->display;
u32 width = display->width;
u32 height = display->height;
if (par->bgr)
madctl_par |= MADCTL_BGR;
if (width < 240) {
// Smaller displays are centered
row_start_offset = row_end_offset = (int)((320 - height + 1) / 2);
col_start_offset = (int)((240 - width) / 2);
col_end_offset = (int)((240 - width + 1) / 2); // Account for extra pixel
} else {
// Larger displays are left-aligned
row_start_offset = 0;
row_end_offset = (320 - height);
col_start_offset = col_end_offset = 0;
}
switch (par->info->var.rotate) {
case 0:
x_offset = col_start_offset;
y_offset = row_start_offset;
break;
case 90:
madctl_par |= (MADCTL_MV | MADCTL_MY);
x_offset = row_start_offset;
y_offset = col_start_offset;
break;
case 180:
madctl_par |= (MADCTL_MX | MADCTL_MY);
x_offset = col_end_offset;
y_offset = row_end_offset;
break;
case 270:
madctl_par |= (MADCTL_MV | MADCTL_MX);
x_offset = row_end_offset;
y_offset = col_end_offset;
break;
default:
return -EINVAL;
}
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, madctl_par);
return 0;
}
/**
* set_gamma() - set gamma curves
*
* @par: FBTFT parameter object
* @curves: gamma curves
*
* Before the gamma curves are applied, they are preprocessed with a bitmask
* to ensure syntactically correct input for the display controller.
* This implies that the curves input parameter might be changed by this
* function and that illegal gamma values are auto-corrected and not
* reported as errors.
*
* Return: 0 on success, < 0 if error occurred.
*/
static int set_gamma(struct fbtft_par *par, u32 *curves)
{
int i;
int j;
int c; /* curve index offset */
/*
* Bitmasks for gamma curve command parameters.
* The masks are the same for both positive and negative voltage
* gamma curves.
*/
static const u8 gamma_par_mask[] = {
0xFF, /* V63[3:0], V0[3:0]*/
0x3F, /* V1[5:0] */
0x3F, /* V2[5:0] */
0x1F, /* V4[4:0] */
0x1F, /* V6[4:0] */
0x3F, /* J0[1:0], V13[3:0] */
0x7F, /* V20[6:0] */
0x77, /* V36[2:0], V27[2:0] */
0x7F, /* V43[6:0] */
0x3F, /* J1[1:0], V50[3:0] */
0x1F, /* V57[4:0] */
0x1F, /* V59[4:0] */
0x3F, /* V61[5:0] */
0x3F, /* V62[5:0] */
};
for (i = 0; i < par->gamma.num_curves; i++) {
c = i * par->gamma.num_values;
for (j = 0; j < par->gamma.num_values; j++)
curves[c + j] &= gamma_par_mask[j];
write_reg(par, PVGAMCTRL + i,
curves[c + 0], curves[c + 1], curves[c + 2],
curves[c + 3], curves[c + 4], curves[c + 5],
curves[c + 6], curves[c + 7], curves[c + 8],
curves[c + 9], curves[c + 10], curves[c + 11],
curves[c + 12], curves[c + 13]);
}
return 0;
}
/**
* blank() - blank the display
*
* @par: FBTFT parameter object
* @on: whether to enable or disable blanking the display
*
* Return: 0 on success, < 0 if error occurred.
*/
static int blank(struct fbtft_par *par, bool on)
{
if (on)
write_reg(par, MIPI_DCS_SET_DISPLAY_OFF);
else
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
return 0;
}
static struct fbtft_display display = {
.regwidth = 8,
.width = 240,
.height = 320,
.gamma_num = 2,
.gamma_len = 14,
.gamma = HSD20_IPS_GAMMA,
.fbtftops = {
.init_display = init_display,
.write_vmem = write_vmem,
.set_var = set_var,
.set_gamma = set_gamma,
.blank = blank,
},
};
int variant_minipitft13(struct fbtft_display *display)
{
display->fbtftops.set_addr_win = minipitft13_set_addr_win;
return 0;
}
FBTFT_REGISTER_DRIVER_START(&display)
FBTFT_COMPATIBLE("sitronix,st7789v")
FBTFT_VARIANT_COMPATIBLE("fbtft,minipitft13", variant_minipitft13)
FBTFT_REGISTER_DRIVER_END(DRVNAME, &display);
MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:st7789v");
MODULE_ALIAS("platform:st7789v");
MODULE_DESCRIPTION("FB driver for the ST7789V LCD Controller");
MODULE_AUTHOR("Dennis Menschel");
MODULE_LICENSE("GPL");

480
st7789_module/fbtft.h Normal file
View file

@ -0,0 +1,480 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (C) 2013 Noralf Tronnes */
#ifndef __LINUX_FBTFT_H
#define __LINUX_FBTFT_H
#include <linux/fb.h>
#include <linux/spinlock.h>
#include <linux/spi/spi.h>
#include <linux/platform_device.h>
#define FBTFT_ONBOARD_BACKLIGHT 2
#define FBTFT_GPIO_NO_MATCH 0xFFFF
#define FBTFT_GPIO_NAME_SIZE 32
#define FBTFT_MAX_INIT_SEQUENCE 512
#define FBTFT_GAMMA_MAX_VALUES_TOTAL 128
#define FBTFT_OF_INIT_CMD BIT(24)
#define FBTFT_OF_INIT_DELAY BIT(25)
/**
* struct fbtft_gpio - Structure that holds one pinname to gpio mapping
* @name: pinname (reset, dc, etc.)
* @gpio: GPIO number
*
*/
struct fbtft_gpio {
char name[FBTFT_GPIO_NAME_SIZE];
struct gpio_desc *gpio;
};
struct fbtft_par;
/**
* struct fbtft_ops - FBTFT operations structure
* @write: Writes to interface bus
* @read: Reads from interface bus
* @write_vmem: Writes video memory to display
* @write_reg: Writes to controller register
* @set_addr_win: Set the GRAM update window
* @reset: Reset the LCD controller
* @mkdirty: Marks display lines for update
* @update_display: Updates the display
* @init_display: Initializes the display
* @blank: Blank the display (optional)
* @request_gpios_match: Do pinname to gpio matching
* @request_gpios: Request gpios from the kernel
* @free_gpios: Free previously requested gpios
* @verify_gpios: Verify that necessary gpios is present (optional)
* @register_backlight: Used to register backlight device (optional)
* @unregister_backlight: Unregister backlight device (optional)
* @set_var: Configure LCD with values from variables like @rotate and @bgr
* (optional)
* @set_gamma: Set Gamma curve (optional)
*
* Most of these operations have default functions assigned to them in
* fbtft_framebuffer_alloc()
*/
struct fbtft_ops {
int (*write)(struct fbtft_par *par, void *buf, size_t len);
int (*read)(struct fbtft_par *par, void *buf, size_t len);
int (*write_vmem)(struct fbtft_par *par, size_t offset, size_t len);
void (*write_register)(struct fbtft_par *par, int len, ...);
void (*set_addr_win)(struct fbtft_par *par,
int xs, int ys, int xe, int ye);
void (*reset)(struct fbtft_par *par);
void (*mkdirty)(struct fb_info *info, int from, int to);
void (*update_display)(struct fbtft_par *par,
unsigned int start_line, unsigned int end_line);
int (*init_display)(struct fbtft_par *par);
int (*blank)(struct fbtft_par *par, bool on);
unsigned long (*request_gpios_match)(struct fbtft_par *par,
const struct fbtft_gpio *gpio);
int (*request_gpios)(struct fbtft_par *par);
int (*verify_gpios)(struct fbtft_par *par);
void (*register_backlight)(struct fbtft_par *par);
void (*unregister_backlight)(struct fbtft_par *par);
int (*set_var)(struct fbtft_par *par);
int (*set_gamma)(struct fbtft_par *par, u32 *curves);
};
/**
* struct fbtft_display - Describes the display properties
* @width: Width of display in pixels
* @height: Height of display in pixels
* @regwidth: LCD Controller Register width in bits
* @buswidth: Display interface bus width in bits
* @backlight: Backlight type.
* @fbtftops: FBTFT operations provided by driver or device (platform_data)
* @bpp: Bits per pixel
* @fps: Frames per second
* @txbuflen: Size of transmit buffer
* @init_sequence: Pointer to LCD initialization array
* @gamma: String representation of Gamma curve(s)
* @gamma_num: Number of Gamma curves
* @gamma_len: Number of values per Gamma curve
* @debug: Initial debug value
*
* This structure is not stored by FBTFT except for init_sequence.
*/
struct fbtft_display {
unsigned int width;
unsigned int height;
unsigned int regwidth;
unsigned int buswidth;
unsigned int backlight;
struct fbtft_ops fbtftops;
unsigned int bpp;
unsigned int fps;
int txbuflen;
const s16 *init_sequence;
char *gamma;
int gamma_num;
int gamma_len;
unsigned long debug;
};
/**
* struct fbtft_platform_data - Passes display specific data to the driver
* @display: Display properties
* @gpios: Pointer to an array of pinname to gpio mappings
* @rotate: Display rotation angle
* @bgr: LCD Controller BGR bit
* @fps: Frames per second (this will go away, use @fps in @fbtft_display)
* @txbuflen: Size of transmit buffer
* @startbyte: When set, enables use of Startbyte in transfers
* @gamma: String representation of Gamma curve(s)
* @extra: A way to pass extra info
*/
struct fbtft_platform_data {
struct fbtft_display display;
unsigned int rotate;
bool bgr;
unsigned int fps;
int txbuflen;
u8 startbyte;
char *gamma;
void *extra;
};
/**
* struct fbtft_par - Main FBTFT data structure
*
* This structure holds all relevant data to operate the display
*
* See sourcefile for documentation since nested structs is not
* supported by kernel-doc.
*
*/
/* @spi: Set if it is a SPI device
* @pdev: Set if it is a platform device
* @info: Pointer to framebuffer fb_info structure
* @pdata: Pointer to platform data
* @ssbuf: Not used
* @pseudo_palette: Used by fb_set_colreg()
* @txbuf.buf: Transmit buffer
* @txbuf.len: Transmit buffer length
* @buf: Small buffer used when writing init data over SPI
* @startbyte: Used by some controllers when in SPI mode.
* Format: 6 bit Device id + RS bit + RW bit
* @fbtftops: FBTFT operations provided by driver or device (platform_data)
* @dirty_lock: Protects dirty_lines_start and dirty_lines_end
* @dirty_lines_start: Where to begin updating display
* @dirty_lines_end: Where to end updating display
* @gpio.reset: GPIO used to reset display
* @gpio.dc: Data/Command signal, also known as RS
* @gpio.rd: Read latching signal
* @gpio.wr: Write latching signal
* @gpio.latch: Bus latch signal, eg. 16->8 bit bus latch
* @gpio.cs: LCD Chip Select with parallel interface bus
* @gpio.db[16]: Parallel databus
* @gpio.led[16]: Led control signals
* @gpio.aux[16]: Auxiliary signals, not used by core
* @init_sequence: Pointer to LCD initialization array
* @gamma.lock: Mutex for Gamma curve locking
* @gamma.curves: Pointer to Gamma curve array
* @gamma.num_values: Number of values per Gamma curve
* @gamma.num_curves: Number of Gamma curves
* @debug: Pointer to debug value
* @current_debug:
* @first_update_done: Used to only time the first display update
* @update_time: Used to calculate 'fps' in debug output
* @bgr: BGR mode/\n
* @extra: Extra info needed by driver
*/
struct fbtft_par {
struct spi_device *spi;
struct platform_device *pdev;
struct fb_info *info;
struct fbtft_platform_data *pdata;
u16 *ssbuf;
u32 pseudo_palette[16];
struct {
void *buf;
size_t len;
} txbuf;
u8 *buf;
u8 startbyte;
struct fbtft_ops fbtftops;
spinlock_t dirty_lock;
unsigned int dirty_lines_start;
unsigned int dirty_lines_end;
struct {
struct gpio_desc *reset;
struct gpio_desc *dc;
struct gpio_desc *rd;
struct gpio_desc *wr;
struct gpio_desc *latch;
struct gpio_desc *cs;
struct gpio_desc *db[16];
struct gpio_desc *led[16];
struct gpio_desc *aux[16];
} gpio;
const s16 *init_sequence;
struct {
struct mutex lock;
u32 *curves;
int num_values;
int num_curves;
} gamma;
unsigned long debug;
bool first_update_done;
ktime_t update_time;
bool bgr;
void *extra;
bool polarity;
};
#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
#define write_reg(par, ...) \
((par)->fbtftops.write_register(par, NUMARGS(__VA_ARGS__), __VA_ARGS__))
/* fbtft-core.c */
int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc);
__printf(5, 6)
void fbtft_dbg_hex(const struct device *dev, int groupsize,
const void *buf, size_t len, const char *fmt, ...);
struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
struct device *dev,
struct fbtft_platform_data *pdata);
void fbtft_framebuffer_release(struct fb_info *info);
int fbtft_register_framebuffer(struct fb_info *fb_info);
int fbtft_unregister_framebuffer(struct fb_info *fb_info);
void fbtft_register_backlight(struct fbtft_par *par);
void fbtft_unregister_backlight(struct fbtft_par *par);
int fbtft_init_display(struct fbtft_par *par);
int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev,
struct platform_device *pdev,
const struct of_device_id *dt_ids);
void fbtft_remove_common(struct device *dev, struct fb_info *info);
/* fbtft-io.c */
int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len);
int fbtft_write_spi_emulate_9(struct fbtft_par *par, void *buf, size_t len);
int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len);
int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len);
int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len);
int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len);
/* fbtft-bus.c */
int fbtft_write_vmem8_bus8(struct fbtft_par *par, size_t offset, size_t len);
int fbtft_write_vmem16_bus16(struct fbtft_par *par, size_t offset, size_t len);
int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len);
int fbtft_write_vmem16_bus9(struct fbtft_par *par, size_t offset, size_t len);
void fbtft_write_reg8_bus8(struct fbtft_par *par, int len, ...);
void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...);
void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...);
void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...);
#define FBTFT_REGISTER_DRIVER_START(_display) \
\
static const struct of_device_id dt_ids[]; \
\
static int fbtft_driver_probe_spi(struct spi_device *spi) \
{ \
return fbtft_probe_common(_display, spi, NULL, dt_ids); \
} \
\
static void fbtft_driver_remove_spi(struct spi_device *spi) \
{ \
struct fb_info *info = spi_get_drvdata(spi); \
\
fbtft_remove_common(&spi->dev, info); \
} \
\
static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
{ \
return fbtft_probe_common(_display, NULL, pdev, dt_ids); \
} \
\
static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
{ \
struct fb_info *info = platform_get_drvdata(pdev); \
\
fbtft_remove_common(&pdev->dev, info); \
return 0; \
} \
\
static const struct of_device_id dt_ids[] = {
#define FBTFT_COMPATIBLE(_compatible) \
{ .compatible = _compatible },
#define FBTFT_VARIANT_COMPATIBLE(_compatible, _variant) \
{ .compatible = _compatible, .data = _variant },
#define FBTFT_REGISTER_DRIVER_END(_name, _display) \
\
{}, \
}; \
\
MODULE_DEVICE_TABLE(of, dt_ids); \
\
\
static struct spi_driver fbtft_driver_spi_driver = { \
.driver = { \
.name = _name, \
.of_match_table = dt_ids, \
}, \
.probe = fbtft_driver_probe_spi, \
.remove = fbtft_driver_remove_spi, \
}; \
\
static struct platform_driver fbtft_driver_platform_driver = { \
.driver = { \
.name = _name, \
.owner = THIS_MODULE, \
.of_match_table = dt_ids, \
}, \
.probe = fbtft_driver_probe_pdev, \
.remove = fbtft_driver_remove_pdev, \
}; \
\
static int __init fbtft_driver_module_init(void) \
{ \
int ret; \
\
ret = spi_register_driver(&fbtft_driver_spi_driver); \
if (ret < 0) \
return ret; \
ret = platform_driver_register(&fbtft_driver_platform_driver); \
if (ret < 0) \
spi_unregister_driver(&fbtft_driver_spi_driver); \
return ret; \
} \
\
static void __exit fbtft_driver_module_exit(void) \
{ \
spi_unregister_driver(&fbtft_driver_spi_driver); \
platform_driver_unregister(&fbtft_driver_platform_driver); \
} \
\
module_init(fbtft_driver_module_init); \
module_exit(fbtft_driver_module_exit);
#define FBTFT_REGISTER_SPI_DRIVER(_name, _comp_vend, _comp_dev, _display) \
\
static const struct of_device_id dt_ids[] = { \
{ .compatible = _comp_vend "," _comp_dev }, \
{}, \
}; \
\
static int fbtft_driver_probe_spi(struct spi_device *spi) \
{ \
return fbtft_probe_common(_display, spi, NULL, dt_ids); \
} \
\
static void fbtft_driver_remove_spi(struct spi_device *spi) \
{ \
struct fb_info *info = spi_get_drvdata(spi); \
\
fbtft_remove_common(&spi->dev, info); \
} \
\
MODULE_DEVICE_TABLE(of, dt_ids); \
\
static const struct spi_device_id spi_ids[] = { \
{ .name = _comp_dev }, \
{}, \
}; \
\
MODULE_DEVICE_TABLE(spi, spi_ids); \
\
static struct spi_driver fbtft_driver_spi_driver = { \
.driver = { \
.name = _name, \
.of_match_table = dt_ids, \
}, \
.id_table = spi_ids, \
.probe = fbtft_driver_probe_spi, \
.remove = fbtft_driver_remove_spi, \
}; \
\
module_spi_driver(fbtft_driver_spi_driver);
#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
FBTFT_REGISTER_DRIVER_START(_display) \
FBTFT_COMPATIBLE(_compatible) \
FBTFT_REGISTER_DRIVER_END(_name, _display)
/* Debug macros */
/* shorthand debug levels */
#define DEBUG_LEVEL_1 DEBUG_REQUEST_GPIOS
#define DEBUG_LEVEL_2 (DEBUG_LEVEL_1 | DEBUG_DRIVER_INIT_FUNCTIONS \
| DEBUG_TIME_FIRST_UPDATE)
#define DEBUG_LEVEL_3 (DEBUG_LEVEL_2 | DEBUG_RESET | DEBUG_INIT_DISPLAY \
| DEBUG_BLANK | DEBUG_REQUEST_GPIOS \
| DEBUG_FREE_GPIOS \
| DEBUG_VERIFY_GPIOS \
| DEBUG_BACKLIGHT | DEBUG_SYSFS)
#define DEBUG_LEVEL_4 (DEBUG_LEVEL_2 | DEBUG_FB_READ | DEBUG_FB_WRITE \
| DEBUG_FB_FILLRECT \
| DEBUG_FB_COPYAREA \
| DEBUG_FB_IMAGEBLIT | DEBUG_FB_BLANK)
#define DEBUG_LEVEL_5 (DEBUG_LEVEL_3 | DEBUG_UPDATE_DISPLAY)
#define DEBUG_LEVEL_6 (DEBUG_LEVEL_4 | DEBUG_LEVEL_5)
#define DEBUG_LEVEL_7 0xFFFFFFFF
#define DEBUG_DRIVER_INIT_FUNCTIONS BIT(3)
#define DEBUG_TIME_FIRST_UPDATE BIT(4)
#define DEBUG_TIME_EACH_UPDATE BIT(5)
#define DEBUG_DEFERRED_IO BIT(6)
#define DEBUG_FBTFT_INIT_FUNCTIONS BIT(7)
/* fbops */
#define DEBUG_FB_READ BIT(8)
#define DEBUG_FB_WRITE BIT(9)
#define DEBUG_FB_FILLRECT BIT(10)
#define DEBUG_FB_COPYAREA BIT(11)
#define DEBUG_FB_IMAGEBLIT BIT(12)
#define DEBUG_FB_SETCOLREG BIT(13)
#define DEBUG_FB_BLANK BIT(14)
#define DEBUG_SYSFS BIT(16)
/* fbtftops */
#define DEBUG_BACKLIGHT BIT(17)
#define DEBUG_READ BIT(18)
#define DEBUG_WRITE BIT(19)
#define DEBUG_WRITE_VMEM BIT(20)
#define DEBUG_WRITE_REGISTER BIT(21)
#define DEBUG_SET_ADDR_WIN BIT(22)
#define DEBUG_RESET BIT(23)
#define DEBUG_MKDIRTY BIT(24)
#define DEBUG_UPDATE_DISPLAY BIT(25)
#define DEBUG_INIT_DISPLAY BIT(26)
#define DEBUG_BLANK BIT(27)
#define DEBUG_REQUEST_GPIOS BIT(28)
#define DEBUG_FREE_GPIOS BIT(29)
#define DEBUG_REQUEST_GPIOS_MATCH BIT(30)
#define DEBUG_VERIFY_GPIOS BIT(31)
#define fbtft_init_dbg(dev, format, arg...) \
do { \
if (unlikely((dev)->platform_data && \
(((struct fbtft_platform_data *)(dev)->platform_data)->display.debug & DEBUG_DRIVER_INIT_FUNCTIONS))) \
dev_info(dev, format, ##arg); \
} while (0)
#define fbtft_par_dbg(level, par, format, arg...) \
do { \
if (unlikely((par)->debug & (level))) \
dev_info((par)->info->device, format, ##arg); \
} while (0)
#define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) \
do { \
if (unlikely((par)->debug & (level))) \
fbtft_dbg_hex(dev, sizeof(type), buf,\
(num) * sizeof(type), format, ##arg); \
} while (0)
#endif /* __LINUX_FBTFT_H */

14
st7789_module/reload.sh Normal file
View file

@ -0,0 +1,14 @@
#!/bin/bash
# Unload
sudo dtoverlay -r drm-minipitft114
sudo modprobe -r fb_st7789v
sudo modprobe -r fbtft
# Compile
sudo make
# Load again
sudo modprobe fbtft
sudo insmod ./fb_st7789v.ko
sudo dtoverlay drm-minipitft114

View file

@ -1,407 +0,0 @@
/*
* DRM driver for ST7789V panels with flexible config
*
* Copyright 2019 Limor Fried
* Copyright 2016 Noralf Trønnes
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
#include <video/mipi_display.h>
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_BGR 0x08
#define ST77XX_MADCTL_RGB 0x00
static u32 col_offset = 0;
static u32 row_offset = 0;
static u8 col_hack_fix_offset = 0;
static short x_offset = 0;
static short y_offset = 0;
static void st7789vada_enable(struct drm_simple_display_pipe *pipe,
struct drm_crtc_state *crtc_state,
struct drm_plane_state *plane_state)
{
struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
u8 addr_mode;
int ret;
DRM_DEBUG_KMS("\n");
ret = mipi_dbi_poweron_conditional_reset(mipi);
if (ret < 0)
return;
if (ret == 1)
goto out_enable;
mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET);
msleep(150);
mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
msleep(10);
mipi_dbi_command(mipi, MIPI_DCS_SET_PIXEL_FORMAT, 0x55); // 16 bit color
msleep(10);
mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, 0);
mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS, 0, 0, 0, 240);
mipi_dbi_command(mipi, MIPI_DCS_SET_PAGE_ADDRESS, 0, 0, 320>>8, 320&0xFF);
mipi_dbi_command(mipi, MIPI_DCS_ENTER_INVERT_MODE); // odd hack, displays are inverted
mipi_dbi_command(mipi, MIPI_DCS_ENTER_NORMAL_MODE);
msleep(10);
mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
msleep(10);
out_enable:
/* The PiTFT (ili9340) has a hardware reset circuit that
* resets only on power-on and not on each reboot through
* a gpio like the rpi-display does.
* As a result, we need to always apply the rotation value
* regardless of the display "on/off" state.
*/
switch (mipi->rotation) {
default:
addr_mode = 0;
x_offset = col_offset;
y_offset = row_offset;
break;
case 90:
addr_mode = ST77XX_MADCTL_MV | ST77XX_MADCTL_MX;
x_offset = row_offset;
y_offset = col_offset;
break;
case 180:
addr_mode = ST77XX_MADCTL_MX | ST77XX_MADCTL_MY;
x_offset = col_offset+col_hack_fix_offset;
// hack tweak to account for extra pixel width to make even
y_offset = row_offset;
break;
case 270:
addr_mode = ST77XX_MADCTL_MV | ST77XX_MADCTL_MY;
x_offset = row_offset;
y_offset = col_offset;
break;
}
mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
backlight_enable(mipi->backlight);
}
static const struct drm_simple_display_pipe_funcs st7789vada_pipe_funcs = {
.enable = st7789vada_enable,
.disable = mipi_dbi_pipe_disable,
.update = tinydrm_display_pipe_update,
.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
};
static struct drm_display_mode st7789vada_mode = {
TINYDRM_MODE(240, 320, 25, 15), // width, height, mm_w, mm_h
};
DEFINE_DRM_GEM_CMA_FOPS(st7789vada_fops);
static struct drm_driver st7789vada_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.fops = &st7789vada_fops,
TINYDRM_GEM_DRIVER_OPS,
.debugfs_init = mipi_dbi_debugfs_init,
.name = "st7789vada",
.desc = "ST7789V Adafruit",
.date = "20190914",
.major = 1,
.minor = 0,
};
static const struct of_device_id st7789vada_of_match[] = {
{ .compatible = "multi-inno,mi0283qt" },
{},
};
MODULE_DEVICE_TABLE(of, st7789vada_of_match);
static const struct spi_device_id st7789vada_id[] = {
{ "st7789vada", 0 },
{ },
};
MODULE_DEVICE_TABLE(spi, st7789vada_id);
static const struct drm_framebuffer_funcs st7789vada_fb_funcs = {
.destroy = drm_gem_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
.dirty = tinydrm_fb_dirty,
};
static const uint32_t st7789vada_formats[] = {
DRM_FORMAT_RGB565,
DRM_FORMAT_XRGB8888,
};
static int st7789vada_fb_dirty(struct drm_framebuffer *fb,
struct drm_file *file_priv,
unsigned int flags, unsigned int color,
struct drm_clip_rect *clips,
unsigned int num_clips)
{
struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
struct tinydrm_device *tdev = fb->dev->dev_private;
struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
bool swap = mipi->swap_bytes;
struct drm_clip_rect clip;
int ret = 0;
bool full;
void *tr;
u16 x1, x2, y1, y2;
if (!mipi->enabled)
return 0;
full = tinydrm_merge_clips(&clip, clips, num_clips, flags,
fb->width, fb->height);
DRM_DEBUG("Flushing [FB:%d] x1=%u, x2=%u, y1=%u, y2=%u\n", fb->base.id,
clip.x1, clip.x2, clip.y1, clip.y2);
if (!mipi->dc || !full || swap ||
fb->format->format == DRM_FORMAT_XRGB8888) {
tr = mipi->tx_buf;
ret = mipi_dbi_buf_copy(mipi->tx_buf, fb, &clip, swap);
if (ret)
return ret;
} else {
tr = cma_obj->vaddr;
}
x1 = clip.x1 + x_offset;
x2 = clip.x2 - 1 + x_offset;
y1 = clip.y1 + y_offset;
y2 = clip.y2 - 1 + y_offset;
//printk(KERN_INFO "setaddrwin %d %d %d %d\n", x1, y1, x2, y2);
mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS,
(x1 >> 8) & 0xFF, x1 & 0xFF,
(x2 >> 8) & 0xFF, x2 & 0xFF);
mipi_dbi_command(mipi, MIPI_DCS_SET_PAGE_ADDRESS,
(y1 >> 8) & 0xFF, y1 & 0xFF,
(y2 >> 8) & 0xFF, y2 & 0xFF);
ret = mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START, tr,
(clip.x2 - clip.x1) * (clip.y2 - clip.y1) * 2);
return ret;
}
/**
* st7789vada - MIPI DBI initialization
* @dev: Parent device
* @mipi: &mipi_dbi structure to initialize
* @pipe_funcs: Display pipe functions
* @driver: DRM driver
* @mode: Display mode
* @rotation: Initial rotation in degrees Counter Clock Wise
*
* This function initializes a &mipi_dbi structure and it's underlying
* @tinydrm_device. It also sets up the display pipeline.
*
* Supported formats: Native RGB565 and emulated XRGB8888.
*
* Objects created by this function will be automatically freed on driver
* detach (devres).
*
* Returns:
* Zero on success, negative error code on failure.
*/
int st7789vada_init(struct device *dev, struct mipi_dbi *mipi,
const struct drm_simple_display_pipe_funcs *pipe_funcs,
struct drm_driver *driver,
const struct drm_display_mode *mode, unsigned int rotation)
{
size_t bufsize = mode->vdisplay * mode->hdisplay * sizeof(u16);
struct tinydrm_device *tdev = &mipi->tinydrm;
int ret;
if (!mipi->command)
return -EINVAL;
mutex_init(&mipi->cmdlock);
mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL);
if (!mipi->tx_buf)
return -ENOMEM;
ret = devm_tinydrm_init(dev, tdev, &st7789vada_fb_funcs, driver);
if (ret)
return ret;
tdev->fb_dirty = st7789vada_fb_dirty;
/* TODO: Maybe add DRM_MODE_CONNECTOR_SPI */
ret = tinydrm_display_pipe_init(tdev, pipe_funcs,
DRM_MODE_CONNECTOR_VIRTUAL,
st7789vada_formats,
ARRAY_SIZE(st7789vada_formats), mode,
rotation);
if (ret)
return ret;
tdev->drm->mode_config.preferred_depth = 16;
mipi->rotation = rotation;
drm_mode_config_reset(tdev->drm);
DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n",
tdev->drm->mode_config.preferred_depth, rotation);
return 0;
}
static int st7789vada_probe(struct spi_device *spi)
{
struct device *dev = &spi->dev;
struct mipi_dbi *mipi;
struct gpio_desc *dc;
u32 rotation = 0;
u32 width = 240;
u32 height = 320;
int ret;
mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL);
if (!mipi)
return -ENOMEM;
mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(mipi->reset)) {
DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
return PTR_ERR(mipi->reset);
}
dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
if (IS_ERR(dc)) {
DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
return PTR_ERR(dc);
}
mipi->regulator = devm_regulator_get(dev, "power");
if (IS_ERR(mipi->regulator))
return PTR_ERR(mipi->regulator);
mipi->backlight = devm_of_find_backlight(dev);
if (IS_ERR(mipi->backlight))
return PTR_ERR(mipi->backlight);
device_property_read_u32(dev, "rotation", &rotation);
//printk(KERN_INFO "Rotation %d\n", rotation);
device_property_read_u32(dev, "width", &width);
if (width % 2) {
width +=1; // odd width will cause a kernel panic
col_hack_fix_offset = 1;
} else {
col_hack_fix_offset = 0;
}
//printk(KERN_INFO "Width %d\n", width);
if ((width == 0) || (width > 240)) {
width = 240; // default to full framebuff;
}
device_property_read_u32(dev, "height", &height);
//printk(KERN_INFO "Height %d\n", height);
if ((height == 0) || (height > 320)) {
height = 320; // default to full framebuff;
}
st7789vada_mode.hdisplay = st7789vada_mode.hsync_start =
st7789vada_mode.hsync_end = st7789vada_mode.htotal = width;
st7789vada_mode.vdisplay = st7789vada_mode.vsync_start =
st7789vada_mode.vsync_end = st7789vada_mode.vtotal = height;
device_property_read_u32(dev, "col_offset", &col_offset);
//printk(KERN_INFO "Column offset %d\n", col_offset);
device_property_read_u32(dev, "row_offset", &row_offset);
//printk(KERN_INFO "Row offset %d\n", row_offset);
ret = mipi_dbi_spi_init(spi, mipi, dc);
if (ret)
return ret;
/* Cannot read from this controller via SPI */
mipi->read_commands = NULL;
ret = st7789vada_init(&spi->dev, mipi, &st7789vada_pipe_funcs,
&st7789vada_driver, &st7789vada_mode, rotation);
if (ret)
return ret;
spi_set_drvdata(spi, mipi);
return devm_tinydrm_register(&mipi->tinydrm);
}
static void st7789vada_shutdown(struct spi_device *spi)
{
struct mipi_dbi *mipi = spi_get_drvdata(spi);
tinydrm_shutdown(&mipi->tinydrm);
}
static int __maybe_unused st7789vada_pm_suspend(struct device *dev)
{
struct mipi_dbi *mipi = dev_get_drvdata(dev);
return drm_mode_config_helper_suspend(mipi->tinydrm.drm);
}
static int __maybe_unused st7789vada_pm_resume(struct device *dev)
{
struct mipi_dbi *mipi = dev_get_drvdata(dev);
drm_mode_config_helper_resume(mipi->tinydrm.drm);
return 0;
}
static const struct dev_pm_ops st7789vada_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(st7789vada_pm_suspend, st7789vada_pm_resume)
};
static struct spi_driver st7789vada_spi_driver = {
.driver = {
.name = "st7789vada",
.owner = THIS_MODULE,
.of_match_table = st7789vada_of_match,
.pm = &st7789vada_pm_ops,
},
.id_table = st7789vada_id,
.probe = st7789vada_probe,
.shutdown = st7789vada_shutdown,
};
module_spi_driver(st7789vada_spi_driver);
MODULE_DESCRIPTION("Sitronix ST7789V Flexible DRM driver");
MODULE_AUTHOR("Limor Fried");
MODULE_LICENSE("GPL");

View file

@ -0,0 +1,3 @@
# udev rule for Focaltouch Capactive Touchscreen
SUBSYSTEM=="input", ATTRS{name}=="EP0110M09", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
SUBSYSTEM=="input", ATTRS{name}=="generic ft5x06*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"

2
templates/95-stmpe.rules Normal file
View file

@ -0,0 +1,2 @@
udev rule for STMPE Resistive Touchscreen Controller
SUBSYSTEM=="input", ATTRS{name}=="*stmpe*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"

View file

@ -0,0 +1 @@
SUBSYSTEM=="input", ATTRS{name}=="touchmouse", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"

View file

@ -0,0 +1,14 @@
# udev rules for SPI TFT DRM devices to create reliable symlinks
# Supports ili9341, st7789, and other SPI TFT displays
# Rule for ili9341 DRM device (and other SPI TFT displays)
SUBSYSTEM=="drm", KERNEL=="card*", KERNELS=="spi0.0", DRIVERS=="ili9341", SYMLINK+="dri/spitft"
# Generic rule for any SPI TFT display on spi0.0
SUBSYSTEM=="drm", KERNEL=="card*", KERNELS=="spi0.0", SUBSYSTEMS=="spi", SYMLINK+="dri/spitft"
# Rule for st7789 displays (add when needed)
SUBSYSTEM=="drm", KERNEL=="card*", KERNELS=="spi0.0", DRIVERS=="st7789", SYMLINK+="dri/spitft"
# Alternative rule using device path pattern
SUBSYSTEM=="drm", KERNEL=="card*", DEVPATH=="*/spi0/spi0.0/drm/card*", SYMLINK+="dri/spitft"

View file

@ -0,0 +1,5 @@
# udev rule for TSC2007 touchscreen to create /dev/input/touchscreen symlink and apply transformation
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="TSC2007 Touchscreen", SYMLINK+="input/touchscreen", ENV{LIBINPUT_CALIBRATION_MATRIX}="{calibration_matrix}"
# Backup rule using touchscreen capability and TSC2007 name pattern
SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_TOUCHSCREEN}=="1", ATTRS{name}=="*TSC2007*", SYMLINK+="input/touchscreen", ENV{LIBINPUT_CALIBRATION_MATRIX}="{calibration_matrix}"

View file

@ -0,0 +1,25 @@
#!/bin/bash
# Wait for TFT framebuffer to be ready
echo "Waiting for SPI TFT framebuffer..."
# Wait up to 30 seconds for /dev/fb0 or /dev/fb1 to appear
for i in {1..300}; do
for fbdev in 0 1; do
if [ -e /dev/fb$fbdev ]; then
echo "Found /dev/fb$fbdev, checking if it's {display_type}..."
# Check if it's actually the ili9341 device
if dmesg | grep -q "{display_type}.*fb$fbdev"; then
echo "{display_type} framebuffer ready, mapping console..."
con2fbmap 1 $fbdev
echo "Console mapped to framebuffer $fbdev"
exit 0
fi
fi
done
sleep 0.1
done
echo "Timeout waiting for SPI TFT framebuffer"
exit 1

View file

@ -0,0 +1,14 @@
[Unit]
Description=Map console to framebuffer for SPI TFT
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/con2fbmap-helper.sh
RemainAfterExit=yes
StandardOutput=journal
StandardError=journal
TimeoutStartSec=60
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,8 @@
# --- 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
dtparam=i2c_arm=on
{overlay}
# --- end adafruit-pitft-helper {date} ---

11
templates/fbcp.service Normal file
View file

@ -0,0 +1,11 @@
[Unit]
Description=Framebuffer copy utility for PiTFT
After=network.target
[Service]
Type=simple
ExecStartPre=/bin/sleep 10
ExecStart=/usr/local/bin/fbcp
[Install]
WantedBy=multi-user.target

430
voice_bonnet.sh Executable file
View file

@ -0,0 +1,430 @@
#!/bin/bash
: <<'DISCLAIMER'
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
This script is licensed under the terms of the MIT license.
Unless otherwise noted, code reproduced herein
was written for this script.
- The Pimoroni Crew - (modified by Adafruit!)
DISCLAIMER
# script control variables
productname="voice bonnet/BrainCraft HAT" # the name of the product to install
scriptname="voice_bonnet" # the name of this script
spacereq=1 # minimum size required on root partition in MB
debugmode="no" # whether the script should use debug routines
debuguser="none" # optional test git user to use in debug mode
debugpoint="none" # optional git repo branch or tag to checkout
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
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
osdeny=( "Darwin" "Kali" ) # list os-releases specifically disallowed
FORCE=$1
DEVICE_TREE=true
ASK_TO_REBOOT=false
CURRENT_SETTING=false
UPDATE_DB=false
BOOTCMD=/boot/firmware/cmdline.txt
CONFIG=/boot/firmware/config.txt
APTSRC=/etc/apt/sources.list
INITABCONF=/etc/inittab
BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
LOADMOD=/etc/modules
DTBODIR=/boot/overlays
# Fall back to old location
if ! test -f $CONFIG; then
CONFIG=/boot/config.txt
fi
# function define
confirm() {
if [ "$FORCE" == '-y' ]; then
true
else
read -r -p "$1 [y/N] " response < /dev/tty
if [[ $response =~ ^(yes|y|Y)$ ]]; then
true
else
false
fi
fi
}
prompt() {
read -r -p "$1 [y/N] " response < /dev/tty
if [[ $response =~ ^(yes|y|Y)$ ]]; then
true
else
false
fi
}
success() {
echo -e "$(tput setaf 2)$1$(tput sgr0)"
}
inform() {
echo -e "$(tput setaf 6)$1$(tput sgr0)"
}
warning() {
echo -e "$(tput setaf 1)$1$(tput sgr0)"
}
newline() {
echo ""
}
progress() {
count=0
until [ $count -eq $1 ]; do
echo -n "..." && sleep 1
((count++))
done
echo
}
sudocheck() {
if [ $(id -u) -ne 0 ]; then
echo -e "Install must be run as root. Try 'sudo ./$scriptname'\n"
exit 1
fi
}
sysclean() {
sudo apt-get clean && sudo apt-get autoclean
sudo apt-get -y autoremove &> /dev/null
}
sysupdate() {
if ! $UPDATE_DB; then
echo "Updating apt indexes..." && progress 3 &
sudo apt-get update 1> /dev/null || { warning "Apt failed to update indexes!" && exit 1; }
echo "Reading package lists..."
progress 3 && UPDATE_DB=true
fi
}
sysupgrade() {
sudo apt-get upgrade
sudo apt-get clean && sudo apt-get autoclean
sudo apt-get -y autoremove &> /dev/null
}
sysreboot() {
warning "Some changes made to your system require"
warning "your computer to reboot to take effect."
newline
if prompt "Would you like to reboot now?"; then
sync && sudo reboot
fi
}
# Given a filename, a regex pattern to match and a replacement string,
# 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
}
# If /boot/firmware/config.txt exists, make sure /boot/config.txt is a symlink to it
fix_config_symlink() {
if [ -f /boot/firmware/config.txt ]; then
if [ ! -L /boot/config.txt ]; then
warning "/boot/config.txt was overwritten as a file by another script."
if confirm "/boot/config.txt will be moved to /boot/firmware/config.txt and the symlink restored. Do you wish to continue?"; then
sudo mv /boot/config.txt /boot/firmware/config.txt
sudo ln -s /boot/firmware/config.txt /boot/config.txt
fi
fi
fi
}
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
IS_ARMv6=true
fi
fi
}
os_check() {
IS_RASPBIAN=false
IS_MACOSX=false
IS_SUPPORTED=false
IS_EXPERIMENTAL=false
if [ -f /etc/os-release ]; then
if cat /etc/os-release | grep "Raspbian" > /dev/null; then
IS_RASPBIAN=true && IS_SUPPORTED=true
fi
if command -v apt-get > /dev/null; then
for os in ${osreleases[@]}; do
if cat /etc/os-release | grep $os > /dev/null; then
IS_SUPPORTED=true && IS_EXPERIMENTAL=false
fi
done
for os in ${oswarning[@]}; do
if cat /etc/os-release | grep $os > /dev/null; then
IS_SUPPORTED=false && IS_EXPERIMENTAL=true
fi
done
for os in ${osdeny[@]}; do
if cat /etc/os-release | grep $os > /dev/null; then
IS_SUPPORTED=false && IS_EXPERIMENTAL=false
fi
done
fi
fi
if [ -d ~/.kano-settings ] || [ -d ~/.kanoprofile ]; then
IS_RASPBIAN=false
for os in ${oswarning[@]}; do
if [ $os == "Kano" ]; then
IS_SUPPORTED=false && IS_EXPERIMENTAL=true
fi
done
for os in ${osdeny[@]}; do
if [ $os == "Kano" ]; then
IS_SUPPORTED=false && IS_EXPERIMENTAL=false
fi
done
fi
if [ -f ~/.pt-dashboard-config ] || [ -d ~/.pt-dashboard ] || [ -d ~/.pt-os-dashboard ]; then
IS_RASPBIAN=false
for os in ${oswarning[@]}; do
if [ $os == "PiTop" ]; then
IS_SUPPORTED=false && IS_EXPERIMENTAL=true
fi
done
for os in ${osdeny[@]}; do
if [ $os == "PiTop" ]; then
IS_SUPPORTED=false && IS_EXPERIMENTAL=false
fi
done
fi
if [ -d ~/.config/ubuntu-mate ]; then
for os in ${osdeny[@]}; do
if [ $os == "Mate" ]; then
IS_SUPPORTED=false && IS_EXPERIMENTAL=false
fi
done
fi
if uname -s | grep "Darwin" > /dev/null; then
IS_MACOSX=true
for os in ${osdeny[@]}; do
if [ $os == "Darwin" ]; then
IS_SUPPORTED=false && IS_EXPERIMENTAL=false
fi
done
fi
}
raspbian_check() {
IS_SUPPORTED=false
IS_EXPERIMENTAL=false
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
elif cat /etc/os-release | grep "stretch" > /dev/null; then
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
IS_SUPPORTED=true && IS_EXPERIMENTAL=false
else
IS_SUPPORTED=false && IS_EXPERIMENTAL=false
fi
fi
}
: <<'MAINSTART'
Perform all global variables declarations as well as function definition
above this section for clarity, thanks!
MAINSTART
# checks and init
arch_check
os_check
if [ $debugmode != "no" ]; then
echo "USER_HOME is $USER_HOME" && newline
echo "IS_RASPBIAN is $IS_RASPBIAN"
echo "IS_MACOSX is $IS_MACOSX"
echo "IS_SUPPORTED is $IS_SUPPORTED"
echo "IS_EXPERIMENTAL is $IS_EXPERIMENTAL"
newline
fi
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_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
warning "Sorry, your CPU is not supported by this installer"
newline && exit 1
elif $IS_ARMv6 && [ $armv6 == "no" ]; then
warning "Sorry, your CPU is not supported by this installer"
newline && exit 1
fi
if [ $raspbianonly == "yes" ] && ! $IS_RASPBIAN;then
warning "This script is intended for Raspbian on a Raspberry Pi!"
newline && exit 1
fi
if $IS_RASPBIAN; then
raspbian_check
if ! $IS_SUPPORTED && ! $IS_EXPERIMENTAL; then
newline && warning "--- Warning ---" && newline
echo "The $productname installer"
echo "does not work on this version of Raspbian."
echo "Check https://github.com/$gitusername/$gitreponame"
echo "for additional information and support"
newline && exit 1
fi
fi
if ! $IS_SUPPORTED && ! $IS_EXPERIMENTAL; then
warning "Your operating system is not supported, sorry!"
newline && exit 1
fi
if $IS_EXPERIMENTAL; then
warning "Support for your operating system is experimental. Please visit"
warning "forums.adafruit.com if you experience issues with this product."
newline
fi
if [ $forcesudo == "yes" ]; then
sudocheck
fi
newline
echo "This script will install everything needed to use"
echo "$productname"
newline
warning "--- Warning ---"
newline
echo "Always be careful when running scripts and commands"
echo "copied from the internet. Ensure they are from a"
echo "trusted source."
newline
echo "If you want to see what this script does before"
echo "running it, you should run:"
echo " \curl -sS github.com/adafruit/Raspberry-Pi-Installer-Scripts/$scriptname"
newline
if confirm "Do you wish to continue?"; then
newline
echo "Checking hardware requirements..."
fix_config_symlink
if [ -e $CONFIG ] && grep -q "^device_tree=$" $CONFIG; then
DEVICE_TREE=false
fi
if $DEVICE_TREE; then
newline
echo "Adding Device Tree Entry to $CONFIG"
if [ -e $CONFIG ] && grep -q "^dtoverlay=seeed-2mic-voicecard$" $CONFIG; then
echo "dtoverlay already active"
else
echo "dtoverlay=seeed-2mic-voicecard" | sudo tee -a $CONFIG
ASK_TO_REBOOT=true
fi
if [ -e $CONFIG ] && grep -q "^dtoverlay=i2s-mmap$" $CONFIG; then
echo "i2s mmap dtoverlay already active"
else
echo "dtoverlay=i2s-mmap" | sudo tee -a $CONFIG
ASK_TO_REBOOT=true
fi
if [ -e $CONFIG ] && grep -q "^dtparam=i2s=on$" $CONFIG; then
echo "i2s interface already enabled"
else
reconfig $CONFIG "^#dtparam=i2s=on$" "dtparam=i2s=on"
ASK_TO_REBOOT=true
fi
else
newline
echo "No Device Tree Detected, not supported"
newline
exit 1
fi
newline
success "All done!"
newline
echo "Enjoy your new $productname!"
newline
if [ $promptreboot == "yes" ] || $ASK_TO_REBOOT; then
sysreboot
fi
else
newline
echo "Aborting..."
newline
fi
exit 0

12
wm8960-soundcard.service Normal file
View file

@ -0,0 +1,12 @@
[Unit]
Description=WM8960 Soundcard service
After=alsa-restore.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/wm8960-soundcard
User=root
[Install]
WantedBy=sysinit.target