You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

714 lines
24 KiB

4 years ago
4 years ago
  1. #!/bin/bash
  2. # (C) Adafruit Industries, Creative Commons 3.0 - Attribution Share Alike
  3. #
  4. # Instructions!
  5. # cd ~
  6. # wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/adafruit-pitft.sh
  7. # chmod +x adafruit-pitft.sh
  8. # sudo ./adafruit-pitft.sh
  9. if [ $(id -u) -ne 0 ]; then
  10. echo "Installer must be run as root."
  11. echo "Try 'sudo bash $0'"
  12. exit 1
  13. fi
  14. UPDATE_DB=false
  15. UNINSTALL=false
  16. ############################ CALIBRATIONS ############################
  17. # For TSLib
  18. POINTERCAL_28r0="4232 11 -879396 1 5786 -752768 65536"
  19. POINTERCAL_28r90="33 -5782 21364572 4221 35 -1006432 65536"
  20. POINTERCAL_28r180="-4273 61 16441290 4 -5772 21627524 65536"
  21. POINTERCAL_28r270="-9 5786 -784608 -4302 19 16620508 65536"
  22. POINTERCAL_35r0="5724 -6 -1330074 26 8427 -1034528 65536"
  23. POINTERCAL_35r90="5 8425 -978304 -5747 61 22119468 65536"
  24. POINTERCAL_35r180="-5682 -1 22069150 13 -8452 32437698 65536"
  25. POINTERCAL_35r270="3 -8466 32440206 5703 -1 -1308696 65536"
  26. POINTERCAL_28c="320 65536 0 -65536 0 15728640 65536"
  27. # for PIXEL desktop
  28. TRANSFORM_28r0="0.988809 -0.023645 0.060523 -0.028817 1.003935 0.034176 0 0 1"
  29. TRANSFORM_28r90="0.014773 -1.132874 1.033662 1.118701 0.009656 -0.065273 0 0 1"
  30. TRANSFORM_28r180="-1.115235 -0.010589 1.057967 -0.005964 -1.107968 1.025780 0 0 1"
  31. TRANSFORM_28r270="-0.033192 1.126869 -0.014114 -1.115846 0.006580 1.050030 0 0 1"
  32. TRANSFORM_35r0="-1.098388 0.003455 1.052099 0.005512 -1.093095 1.026309 0 0 1"
  33. TRANSFORM_35r90="-0.000087 1.094214 -0.028826 -1.091711 -0.004364 1.057821 0 0 1"
  34. TRANSFORM_35r180="1.102807 0.000030 -0.066352 0.001374 1.085417 -0.027208 0 0 1"
  35. TRANSFORM_35r270="0.003893 -1.087542 1.025913 1.084281 0.008762 -0.060700 0 0 1"
  36. TRANSFORM_28c0="-1 0 1 0 -1 1 0 0 1"
  37. TRANSFORM_28c90="0 1 0 -1 0 1 0 0 1"
  38. TRANSFORM_28c180="1 0 0 0 1 0 0 0 1"
  39. TRANSFORM_28c270="0 -1 1 1 0 0 0 0 1"
  40. ROTATE_28c0="rotate=90,touch-invx=true,touch-invy=true"
  41. ROTATE_28c90="rotate=90,touch-swapxy=true,touch-invx=true"
  42. ROTATE_28c180="rotate=90"
  43. ROTATE_28c270="rotate=270,touch-swapxy=true,touch-invy=true"
  44. warning() {
  45. echo WARNING : $1
  46. }
  47. ############################ Script assisters ############################
  48. # Given a list of strings representing options, display each option
  49. # preceded by a number (1 to N), display a prompt, check input until
  50. # a valid number within the selection range is entered.
  51. selectN() {
  52. for ((i=1; i<=$#; i++)); do
  53. echo $i. ${!i}
  54. done
  55. echo
  56. REPLY=""
  57. while :
  58. do
  59. echo -n "SELECT 1-$#: "
  60. read
  61. if [[ $REPLY -ge 1 ]] && [[ $REPLY -le $# ]]; then
  62. return $REPLY
  63. fi
  64. done
  65. }
  66. function print_version() {
  67. echo "Adafruit PiTFT Helper v2.1.0"
  68. exit 1
  69. }
  70. function print_help() {
  71. echo "Usage: $0 "
  72. echo " -h Print this help"
  73. echo " -v Print version information"
  74. echo " -u [homedir] Specify path of primary user's home directory (defaults to /home/pi)"
  75. exit 1
  76. }
  77. group=ADAFRUIT
  78. function info() {
  79. system="$1"
  80. group="${system}"
  81. shift
  82. FG="1;32m"
  83. BG="40m"
  84. echo -e "[\033[${FG}\033[${BG}${system}\033[0m] $*"
  85. }
  86. function bail() {
  87. FG="1;31m"
  88. BG="40m"
  89. echo -en "[\033[${FG}\033[${BG}${group}\033[0m] "
  90. if [ -z "$1" ]; then
  91. echo "Exiting due to error"
  92. else
  93. echo "Exiting due to error: $*"
  94. fi
  95. exit 1
  96. }
  97. function ask() {
  98. # http://djm.me/ask
  99. while true; do
  100. if [ "${2:-}" = "Y" ]; then
  101. prompt="Y/n"
  102. default=Y
  103. elif [ "${2:-}" = "N" ]; then
  104. prompt="y/N"
  105. default=N
  106. else
  107. prompt="y/n"
  108. default=
  109. fi
  110. # Ask the question
  111. read -p "$1 [$prompt] " REPLY
  112. # Default?
  113. if [ -z "$REPLY" ]; then
  114. REPLY=$default
  115. fi
  116. # Check if the reply is valid
  117. case "$REPLY" in
  118. Y*|y*) return 0 ;;
  119. N*|n*) return 1 ;;
  120. esac
  121. done
  122. }
  123. function has_repo() {
  124. # Checks for the right raspbian repository
  125. # http://mirrordirector.raspbian.org/raspbian/ stretch main contrib non-free rpi firmware
  126. if [[ $(grep -h ^deb /etc/apt/sources.list /etc/apt/sources.list.d/* | grep "mirrordirector.raspbian.org") ]]; then
  127. return 0
  128. else
  129. return 1
  130. fi
  131. }
  132. progress() {
  133. count=0
  134. until [ $count -eq $1 ]; do
  135. echo -n "..." && sleep 1
  136. ((count++))
  137. done
  138. echo
  139. }
  140. sysupdate() {
  141. if ! $UPDATE_DB; then
  142. # echo "Checking for correct software repositories..."
  143. # has_repo || { warning "Missing Apt repo, please add deb http://mirrordirector.raspbian.org/raspbian/ stretch main contrib non-free rpi firmware to /etc/apt/sources.list.d/raspi.list" && exit 1; }
  144. echo "Updating apt indexes..." && progress 3 &
  145. sudo apt update 1> /dev/null || { warning "Apt failed to update indexes!" && exit 1; }
  146. sudo apt-get update 1> /dev/null || { warning "Apt failed to update indexes!" && exit 1; }
  147. echo "Reading package lists..."
  148. progress 3 && UPDATE_DB=true
  149. fi
  150. }
  151. # Given a filename, a regex pattern to match and a replacement string,
  152. # perform replacement if found, else append replacement to end of file.
  153. # (# $1 = filename, $2 = pattern to match, $3 = replacement)
  154. reconfig() {
  155. grep $2 $1 >/dev/null
  156. if [ $? -eq 0 ]; then
  157. # Pattern found; replace in file
  158. sed -i "s/$2/$3/g" $1 >/dev/null
  159. else
  160. # Not found; append (silently)
  161. echo $3 | sudo tee -a $1 >/dev/null
  162. fi
  163. }
  164. ############################ Sub-Scripts ############################
  165. function softwareinstall() {
  166. echo "Installing Pre-requisite Software...This may take a few minutes!"
  167. apt-get install -y libts0 1> /dev/null 2>&1 || apt-get install -y tslib 1> /dev/null 2>&1 || { warning "Apt failed to install TSLIB!" && exit 1; }
  168. apt-get install -y bc fbi git python-dev python-pip python-smbus python-spidev evtest libts-bin device-tree-compiler 1> /dev/null || { warning "Apt failed to install software!" && exit 1; }
  169. pip install evdev 1> /dev/null || { warning "Pip failed to install software!" && exit 1; }
  170. }
  171. # Remove any old flexfb/fbtft stuff
  172. function uninstall_bootconfigtxt() {
  173. if grep -q "adafruit-pitft-helper" "/boot/config.txt"; then
  174. echo "Already have an adafruit-pitft-helper section in /boot/config.txt."
  175. echo "Removing old section..."
  176. cp /boot/config.txt /boot/configtxt.bak
  177. sed -i -e "/^# --- added by adafruit-pitft-helper/,/^# --- end adafruit-pitft-helper/d" /boot/config.txt
  178. fi
  179. }
  180. # Remove any old flexfb/fbtft stuff
  181. function uninstall_etc_modules() {
  182. rm -f /etc/modprobe.d/fbtft.conf
  183. sed -i 's/spi-bcm2835//g' "/etc/modules"
  184. sed -i 's/flexfb//g' "/etc/modules"
  185. sed -i 's/fbtft_device//g' "/etc/modules"
  186. }
  187. # update /boot/config.txt with appropriate values
  188. function update_configtxt() {
  189. uninstall_bootconfigtxt
  190. uninstall_etc_modules
  191. if [ "${pitfttype}" == "22" ]; then
  192. overlay="dtoverlay=pitft22,rotate=${pitftrot},speed=64000000,fps=30"
  193. fi
  194. if [ "${pitfttype}" == "28r" ]; then
  195. overlay="dtoverlay=pitft28-resistive,rotate=${pitftrot},speed=64000000,fps=30"
  196. fi
  197. if [ "${pitfttype}" == "28c" ]; then
  198. rotateparams=$(eval echo "\$ROTATE_$pitfttype$touchrot")
  199. overlay=$(printf "dtoverlay=pitft28-capacitive,speed=64000000,fps=30\ndtoverlay=pitft28-capacitive,${rotateparams}")
  200. fi
  201. if [ "${pitfttype}" == "35r" ]; then
  202. overlay="dtoverlay=pitft35-resistive,rotate=${pitftrot},speed=20000000,fps=20"
  203. fi
  204. if [ "${pitfttype}" == "st7789_240x320" ]; then
  205. dtc -@ -I dts -O dtb -o /boot/overlays/drm-st7789v_240x320.dtbo overlays/st7789v_240x320-overlay.dts
  206. overlay="dtoverlay=drm-st7789v_240x320,rotate=${pitftrot}"
  207. fi
  208. if [ "${pitfttype}" == "st7789_240x240" ]; then
  209. dtc -@ -I dts -O dtb -o /boot/overlays/drm-minipitft13.dtbo overlays/minipitft13-overlay.dts
  210. overlay="dtoverlay=drm-minipitft13,rotate=${pitftrot}"
  211. fi
  212. if [ "${pitfttype}" == "st7789_240x135" ]; then
  213. dtc -@ -I dts -O dtb -o /boot/overlays/drm-minipitft114.dtbo overlays/minipitft114-overlay.dts
  214. overlay="dtoverlay=drm-minipitft114,rotation=${pitftrot}"
  215. fi
  216. # any/all st7789's need their own kernel driver
  217. if [ "${pitfttype}" == "st7789_240x240" ] || [ "${pitfttype}" == "st7789_240x320" ] || [ "${pitfttype}" == "st7789_240x135" ]; then
  218. echo "############# UPGRADING KERNEL ###############"
  219. sudo apt update || { warning "Apt failed to update itself!" && exit 1; }
  220. sudo apt-get upgrade || { warning "Apt failed to install software!" && exit 1; }
  221. apt-get install -y raspberrypi-kernel-headers 1> /dev/null || { warning "Apt failed to install software!" && exit 1; }
  222. [ -d /lib/modules/$(uname -r)/build ] || { warning "Kernel was updated, please reboot now and re-run script!" && exit 1; }
  223. pushd st7789_module
  224. make -C /lib/modules/$(uname -r)/build M=$(pwd) modules || { warning "Apt failed to compile ST7789V drivers!" && exit 1; }
  225. mv /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tiny/mi0283qt.ko /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tiny/mi0283qt.BACK
  226. mv /lib/modules/$(uname -r)/kernel/drivers/staging/fbtft/fb_st7789v.ko /lib/modules/$(uname -r)/kernel/drivers/staging/fbtft/fb_st7789v.BACK
  227. mv st7789v_ada.ko /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tiny/mi0283qt.ko
  228. mv fb_st7789v.ko /lib/modules/$(uname -r)/kernel/drivers/staging/fbtft/fb_st7789v.ko
  229. popd
  230. fi
  231. date=`date`
  232. cat >> /boot/config.txt <<EOF
  233. # --- added by adafruit-pitft-helper $date ---
  234. hdmi_force_hotplug=1 # required for cases when HDMI is not plugged in!
  235. dtparam=spi=on
  236. dtparam=i2c1=on
  237. dtparam=i2c_arm=on
  238. $overlay
  239. # --- end adafruit-pitft-helper $date ---
  240. EOF
  241. }
  242. function update_udev() {
  243. cat > /etc/udev/rules.d/95-touchmouse.rules <<EOF
  244. SUBSYSTEM=="input", ATTRS{name}=="touchmouse", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
  245. EOF
  246. cat > /etc/udev/rules.d/95-ftcaptouch.rules <<EOF
  247. SUBSYSTEM=="input", ATTRS{name}=="EP0110M09", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
  248. SUBSYSTEM=="input", ATTRS{name}=="generic ft5x06*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
  249. EOF
  250. cat > /etc/udev/rules.d/95-stmpe.rules <<EOF
  251. SUBSYSTEM=="input", ATTRS{name}=="*stmpe*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
  252. EOF
  253. }
  254. function update_pointercal() {
  255. if [ "${pitfttype}" == "28r" ] || [ "${pitfttype}" == "35r" ]; then
  256. echo $(eval echo "\$POINTERCAL_$pitfttype$pitftrot") > /etc/pointercal
  257. fi
  258. if [ "${pitfttype}" == "28c" ]; then
  259. echo $(eval echo "\$POINTERCAL_$pitfttype") > /etc/pointercal
  260. fi
  261. }
  262. function install_console() {
  263. echo "Set up main console turn on"
  264. if ! grep -q 'fbcon=map:10 fbcon=font:VGA8x8' /boot/cmdline.txt; then
  265. echo "Updating /boot/cmdline.txt"
  266. sed -i 's/rootwait/rootwait fbcon=map:10 fbcon=font:VGA8x8/g' "/boot/cmdline.txt"
  267. else
  268. echo "/boot/cmdline.txt already updated"
  269. fi
  270. echo "Turning off console blanking"
  271. # pre-stretch this is what you'd do:
  272. if [ -e /etc/kbd/config ]; then
  273. sed -i 's/BLANK_TIME=.*/BLANK_TIME=0/g' "/etc/kbd/config"
  274. fi
  275. # as of stretch....
  276. # removing any old version
  277. sed -i -e '/^# disable console blanking.*/d' /etc/rc.local
  278. sed -i -e '/^sudo sh -c "TERM=linux setterm -blank.*/d' /etc/rc.local
  279. sed -i -e "s|^exit 0|# disable console blanking on PiTFT\\nsudo sh -c \"TERM=linux setterm -blank 0 >/dev/tty0\"\\nexit 0|" /etc/rc.local
  280. reconfig /etc/default/console-setup "^.*FONTFACE.*$" "FONTFACE=\"Terminus\""
  281. reconfig /etc/default/console-setup "^.*FONTSIZE.*$" "FONTSIZE=\"6x12\""
  282. echo "Setting raspi-config to boot to console w/o login..."
  283. (cd "$target_homedir" && raspi-config nonint do_boot_behaviour B2)
  284. # remove fbcp
  285. sed -i -e "/^.*fbcp.*$/d" /etc/rc.local
  286. }
  287. function uninstall_console() {
  288. echo "Removing console fbcon map from /boot/cmdline.txt"
  289. sed -i 's/rootwait fbcon=map:10 fbcon=font:VGA8x8/rootwait/g' "/boot/cmdline.txt"
  290. echo "Screen blanking time reset to 10 minutes"
  291. if [ -e "/etc/kbd/config" ]; then
  292. sed -i 's/BLANK_TIME=0/BLANK_TIME=10/g' "/etc/kbd/config"
  293. fi
  294. sed -i -e '/^# disable console blanking.*/d' /etc/rc.local
  295. sed -i -e '/^sudo sh -c "TERM=linux.*/d' /etc/rc.local
  296. }
  297. function install_fbcp() {
  298. echo "Installing cmake..."
  299. 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; }
  300. echo "Downloading rpi-fbcp..."
  301. pushd /tmp
  302. #curl -sLO https://github.com/tasanakorn/rpi-fbcp/archive/master.zip
  303. curl -sLO https://github.com/adafruit/rpi-fbcp/archive/master.zip
  304. echo "Uncompressing rpi-fbcp..."
  305. rm -rf /tmp/rpi-fbcp-master
  306. unzip master.zip 1> /dev/null || { warning "Failed to uncompress fbcp!" && exit 1; }
  307. cd rpi-fbcp-master
  308. mkdir build
  309. cd build
  310. echo "Building rpi-fbcp..."
  311. echo -e "\nset (CMAKE_C_FLAGS \"-std=gnu99 ${CMAKE_C_FLAGS}\")" >> ../CMakeLists.txt
  312. cmake .. 1> /dev/null || { warning "Failed to cmake fbcp!" && exit 1; }
  313. make 1> /dev/null || { warning "Failed to make fbcp!" && exit 1; }
  314. echo "Installing rpi-fbcp..."
  315. install fbcp /usr/local/bin/fbcp
  316. popd
  317. rm -rf /tmp/rpi-fbcp-master
  318. # Start fbcp in the appropriate place, depending on init system:
  319. if [ "$SYSTEMD" == "0" ]; then
  320. # Add fbcp to /etc/rc.local:
  321. echo "We have sysvinit, so add fbcp to /etc/rc.local..."
  322. grep fbcp /etc/rc.local >/dev/null
  323. if [ $? -eq 0 ]; then
  324. # fbcp already in rc.local, but make sure correct:
  325. sed -i "s|^.*fbcp.*$|/usr/local/bin/fbcp \&|g" /etc/rc.local >/dev/null
  326. else
  327. # Insert fbcp into rc.local before final 'exit 0':
  328. sed -i "s|^exit 0|/usr/local/bin/fbcp \&\\nexit 0|g" /etc/rc.local >/dev/null
  329. fi
  330. else
  331. # Install fbcp systemd unit, first making sure it's not in rc.local:
  332. uninstall_fbcp_rclocal
  333. echo "We have systemd, so install fbcp systemd unit..."
  334. install_fbcp_unit || bail "Unable to install fbcp unit file"
  335. sudo systemctl enable fbcp.service
  336. fi
  337. # if there's X11 installed...
  338. if [ -e /etc/lightdm ]; then
  339. echo "Setting raspi-config to boot to desktop w/o login..."
  340. raspi-config nonint do_boot_behaviour B4
  341. fi
  342. # Disable overscan compensation (use full screen):
  343. raspi-config nonint do_overscan 1
  344. # Set up HDMI parameters:
  345. echo "Configuring boot/config.txt for forced HDMI"
  346. reconfig /boot/config.txt "^.*hdmi_force_hotplug.*$" "hdmi_force_hotplug=1"
  347. reconfig /boot/config.txt "^.*hdmi_group.*$" "hdmi_group=2"
  348. reconfig /boot/config.txt "^.*hdmi_mode.*$" "hdmi_mode=87"
  349. reconfig /boot/config.txt "^[^#]*dtoverlay=vc4-fkms-v3d.*$" "#dtoverlay=vc4-fkms-v3d"
  350. # if there's X11 installed...
  351. if [ -e /etc/lightdm ]; then
  352. if [ "${pitfttype}" == "35r" ]; then
  353. echo "Using x1.5 resolution"
  354. SCALE=1.5
  355. else
  356. echo "Using x2 resolution"
  357. SCALE=2.0
  358. fi
  359. else
  360. echo "Using native resolution"
  361. SCALE=1
  362. fi
  363. WIDTH=`python -c "print(int(${WIDTH_VALUES[PITFT_SELECT-1]} * ${SCALE}))"`
  364. HEIGHT=`python -c "print(int(${HEIGHT_VALUES[PITFT_SELECT-1]} * ${SCALE}))"`
  365. reconfig /boot/config.txt "^.*hdmi_cvt.*$" "hdmi_cvt=${WIDTH} ${HEIGHT} 60 1 0 0 0"
  366. if [ "${pitftrot}" == "90" ] || [ "${pitftrot}" == "270" ] || [ "${pitfttype}" == "st7789_240x320" ]; then
  367. # dont rotate HDMI on 90 or 270
  368. reconfig /boot/config.txt "^.*display_hdmi_rotate.*$" ""
  369. fi
  370. if [ "${pitftrot}" == "0" ]; then
  371. reconfig /boot/config.txt "^.*display_hdmi_rotate.*$" "display_hdmi_rotate=1"
  372. # this is a hack but because we rotate HDMI we have to 'unrotate' the TFT!
  373. pitftrot=90
  374. update_configtxt || bail "Unable to update /boot/config.txt"
  375. pitftrot=0
  376. fi
  377. if [ "${pitftrot}" == "180" ]; then
  378. reconfig /boot/config.txt "^.*display_hdmi_rotate.*$" "display_hdmi_rotate=3"
  379. # this is a hack but because we rotate HDMI we have to 'unrotate' the TFT!
  380. pitftrot=90
  381. update_configtxt || bail "Unable to update /boot/config.txt"
  382. pitftrot=180
  383. fi
  384. }
  385. function install_fbcp_unit() {
  386. cat > /etc/systemd/system/fbcp.service <<EOF
  387. [Unit]
  388. Description=Framebuffer copy utility for PiTFT
  389. After=network.target
  390. [Service]
  391. Type=simple
  392. ExecStartPre=/bin/sleep 10
  393. ExecStart=/usr/local/bin/fbcp
  394. [Install]
  395. WantedBy=multi-user.target
  396. EOF
  397. }
  398. function uninstall_fbcp() {
  399. uninstall_fbcp_rclocal
  400. sudo systemctl disable fbcp.service
  401. # Enable overscan compensation
  402. raspi-config nonint do_overscan 0
  403. # Set up HDMI parameters:
  404. echo "Configuring boot/config.txt for default HDMI"
  405. reconfig /boot/config.txt "^.*hdmi_force_hotplug.*$" "hdmi_force_hotplug=0"
  406. reconfig /boot/config.txt "^.*#.*dtoverlay=vc4-fkms-v3d.*$" "dtoverlay=vc4-fkms-v3d"
  407. sed -i -e '/^hdmi_group=2.*$/d' /boot/config.txt
  408. sed -i -e '/^hdmi_mode=87.*$/d' /boot/config.txt
  409. sed -i -e '/^hdmi_cvt=.*$/d' /boot/config.txt
  410. }
  411. function uninstall_fbcp_rclocal() {
  412. # Remove fbcp from /etc/rc.local:
  413. echo "Remove fbcp from /etc/rc.local, if it's there..."
  414. sed -i -e '/^.*fbcp.*$/d' /etc/rc.local
  415. }
  416. function update_xorg() {
  417. if [ "${pitfttype}" == "28r" ] || [ "${pitfttype}" == "35r" ]; then
  418. matrix=$(eval echo "\$TRANSFORM_$pitfttype$pitftrot")
  419. transform="Option \"TransformationMatrix\" \"${matrix}\""
  420. cat > /usr/share/X11/xorg.conf.d/20-calibration.conf <<EOF
  421. Section "InputClass"
  422. Identifier "STMPE Touchscreen Calibration"
  423. MatchProduct "stmpe"
  424. MatchDevicePath "/dev/input/event*"
  425. Driver "libinput"
  426. ${transform}
  427. EndSection
  428. EOF
  429. fi
  430. if [ "${pitfttype}" == "28c" ]; then
  431. matrix=$(eval echo "\$TRANSFORM_$pitfttype$pitftrot")
  432. transform="Option \"TransformationMatrix\" \"${matrix}\""
  433. cat > /usr/share/X11/xorg.conf.d/20-calibration.conf <<EOF
  434. Section "InputClass"
  435. Identifier "FocalTech Touchscreen Calibration"
  436. MatchProduct "EP0110M09"
  437. MatchDevicePath "/dev/input/event*"
  438. Driver "libinput"
  439. ${transform}
  440. EndSection
  441. EOF
  442. fi
  443. }
  444. ####################################################### MAIN
  445. target_homedir="/home/pi"
  446. clear
  447. echo "This script downloads and installs"
  448. echo "PiTFT Support using userspace touch"
  449. echo "controls and a DTO for display drawing."
  450. echo "one of several configuration files."
  451. echo "Run time of up to 5 minutes. Reboot required!"
  452. echo
  453. echo "Select configuration:"
  454. selectN "PiTFT 2.4\", 2.8\" or 3.2\" resistive (240x320)" \
  455. "PiTFT 2.2\" no touch (240x320)" \
  456. "PiTFT 2.8\" capacitive touch (240x320)" \
  457. "PiTFT 3.5\" resistive touch (320x480)" \
  458. "PiTFT Mini 1.3\" or 1.54\" display (240x240) - WARNING! WILL UPGRADE YOUR KERNEL TO LATEST" \
  459. "MiniPiTFT 1.14\" display (240x135) - WARNING! WILL UPGRADE YOUR KERNEL TO LATEST" \
  460. "ST7789V 2.0\" no touch (240x320) - WARNING! WILL UPGRADE YOUR KERNEL TO LATEST" \
  461. "Uninstall PiTFT" \
  462. "Quit without installing"
  463. PITFT_SELECT=$?
  464. if [ $PITFT_SELECT -gt 8 ]; then
  465. exit 1
  466. fi
  467. if [ $PITFT_SELECT -eq 8 ]; then
  468. UNINSTALL=true
  469. fi
  470. if ! $UNINSTALL; then
  471. echo "Select rotation:"
  472. selectN "90 degrees (landscape)" \
  473. "180 degrees (portrait)" \
  474. "270 degrees (landscape)" \
  475. "0 degrees (portrait)"
  476. PITFT_ROTATE=$?
  477. if [ $PITFT_ROTATE -gt 4 ]; then
  478. exit 1
  479. fi
  480. fi
  481. PITFT_ROTATIONS=("90" "180" "270" "0")
  482. PITFT_TYPES=("28r" "22" "28c" "35r" "st7789_240x240" "st7789_240x135" "st7789_240x320")
  483. WIDTH_VALUES=(320 320 320 480 240 240 320)
  484. HEIGHT_VALUES=(240 240 240 320 240 135 240)
  485. HZ_VALUES=(64000000 64000000 64000000 32000000 64000000 64000000)
  486. args=$(getopt -uo 'hvri:o:b:u:' -- $*)
  487. [ $? != 0 ] && print_help
  488. set -- $args
  489. for i
  490. do
  491. case "$i"
  492. in
  493. -h)
  494. print_help
  495. ;;
  496. -v)
  497. print_version
  498. ;;
  499. -u)
  500. target_homedir="$2"
  501. echo "Homedir = ${2}"
  502. shift
  503. shift
  504. ;;
  505. esac
  506. done
  507. # check init system (technique borrowed from raspi-config):
  508. info PITFT 'Checking init system...'
  509. if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
  510. echo "Found systemd"
  511. SYSTEMD=1
  512. elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
  513. echo "Found sysvinit"
  514. SYSTEMD=0
  515. else
  516. bail "Unrecognised init system"
  517. fi
  518. if grep -q boot /proc/mounts; then
  519. echo "/boot is mounted"
  520. else
  521. echo "/boot must be mounted. if you think it's not, quit here and try: sudo mount /dev/mmcblk0p1 /boot"
  522. if ask "Continue?"; then
  523. echo "Proceeding."
  524. else
  525. bail "Aborting."
  526. fi
  527. fi
  528. if [[ ! -e "$target_homedir" || ! -d "$target_homedir" ]]; then
  529. bail "$target_homedir must be an existing directory (use -u /home/foo to specify)"
  530. fi
  531. if ! $UNINSTALL;
  532. then
  533. pitfttype=${PITFT_TYPES[$PITFT_SELECT-1]}
  534. pitftrot=${PITFT_ROTATIONS[$PITFT_ROTATE-1]}
  535. touchrot=$pitftrot
  536. if [ "${pitfttype}" != "28r" ] && [ "${pitfttype}" != "28c" ] && [ "${pitfttype}" != "35r" ] && [ "${pitfttype}" != "22" ] && [ "${pitfttype}" != "st7789_240x240" ] && [ "${pitfttype}" != "st7789_240x320" ] && [ "${pitfttype}" != "st7789_240x135" ]; then
  537. echo "Type must be one of:"
  538. echo " '28r' (2.8\" resistive, PID 1601)"
  539. echo " '28c' (2.8\" capacitive, PID 1983)"
  540. echo " '35r' (3.5\" Resistive)"
  541. echo " '22' (2.2\" no touch)"
  542. echo " 'st7789_240x240' (1.54\" or 1.3\" no touch)"
  543. echo " 'st7789_320x240' (2.0\" no touch)"
  544. echo " 'st7789_240x135' (1.14\" no touch)"
  545. echo
  546. print_help
  547. fi
  548. info PITFT "System update"
  549. sysupdate || bail "Unable to apt-get update"
  550. info PITFT "Installing Python libraries & Software..."
  551. softwareinstall || bail "Unable to install software"
  552. info PITFT "Updating /boot/config.txt..."
  553. update_configtxt || bail "Unable to update /boot/config.txt"
  554. if [ "${pitfttype}" == "28r" ] || [ "${pitfttype}" == "35r" ] || [ "${pitfttype}" == "28c" ] ; then
  555. info PITFT "Updating SysFS rules for Touchscreen..."
  556. update_udev || bail "Unable to update /etc/udev/rules.d"
  557. info PITFT "Updating TSLib default calibration..."
  558. update_pointercal || bail "Unable to update /etc/pointercal"
  559. fi
  560. # ask for console access
  561. if ask "Would you like the console to appear on the PiTFT display?"; then
  562. info PITFT "Updating console to PiTFT..."
  563. uninstall_fbcp || bail "Unable to uninstall fbcp"
  564. install_console || bail "Unable to configure console"
  565. else
  566. info PITFT "Making sure console doesn't use PiTFT"
  567. uninstall_console || bail "Unable to configure console"
  568. if ask "Would you like the HDMI display to mirror to the PiTFT display?"; then
  569. info PITFT "Adding FBCP support..."
  570. install_fbcp || bail "Unable to configure fbcp"
  571. if [ -e /etc/lightdm ]; then
  572. info PITFT "Updating X11 default calibration..."
  573. update_xorg || bail "Unable to update calibration"
  574. fi
  575. else
  576. # remove fbcp
  577. uninstall_fbcp || bail "Unable to uninstall fbcp"
  578. fi
  579. fi
  580. else
  581. info PITFT "Uninstalling PiTFT"
  582. uninstall_bootconfigtxt
  583. uninstall_console
  584. uninstall_fbcp
  585. uninstall_fbcp_rclocal
  586. uninstall_etc_modules
  587. fi
  588. #info PITFT "Updating X11 setup tweaks..."
  589. #update_x11profile || bail "Unable to update X11 setup"
  590. #if [ "${pitfttype}" != "35r" ]; then
  591. # # ask for 'on/off' button
  592. # if ask "Would you like GPIO #23 to act as a on/off button?"; then
  593. # info PITFT "Adding GPIO #23 on/off to PiTFT..."
  594. # install_onoffbutton || bail "Unable to add on/off button"
  595. # fi
  596. #fi
  597. # update_bootprefs || bail "Unable to set boot preferences"
  598. info PITFT "Success!"
  599. echo
  600. echo "Settings take effect on next boot."
  601. echo
  602. echo -n "REBOOT NOW? [y/N] "
  603. read
  604. if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
  605. echo "Exiting without reboot."
  606. exit 0
  607. fi
  608. echo "Reboot started..."
  609. reboot
  610. exit 0