Skip to content

Instantly share code, notes, and snippets.

@Holzhaus
Created March 23, 2015 15:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Holzhaus/9d328e2f4ad31357f025 to your computer and use it in GitHub Desktop.
Save Holzhaus/9d328e2f4ad31357f025 to your computer and use it in GitHub Desktop.
ODROID-C1 display tool
#!/bin/bash
#
# Copyright (c) 2015, Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
function mode2info() {
local result=""
case "$1" in
vga) result="640x480" ;;
480p) result="720x480" ;;
576p) result="720x576" ;;
800x480p60hz) result="800x480" ;;
800x600p60hz) result="800x600" ;;
1024x600p60hz) result="1024x600" ;;
1024x768p60hz) result="1024x768" ;;
1360x768p60hz) result="1360x768" ;;
1366x768p60hz) result="1366x768" ;;
1440x900p60hz) result="1440x900" ;;
1600x900p60hz) result="1600x900" ;;
1680x1050p60hz) result="1680x1050" ;;
720p) result="1280x720" ;;
800p) result="1280x800" ;;
sxga) result="1280x1024" ;;
1080i50hz) result="1080i@50Hz" ;;
1080p24hz) result="1080p@24Hz" ;;
1080p50hz) result="1080p@50Hz" ;;
1080p) result="1080p@60Hz" ;;
1920x1200) result="1920x1200" ;;
esac
if [ -z "$result" ]; then
return 1
else
echo "$result"
return 0
fi
}
function mode2axis() {
local result=""
case "$1" in
vga) result="0 0 639 749" ;;
480p) result="0 0 719 479" ;;
576p) result="0 0 719 575" ;;
800x480p60hz) result="0 0 799 479" ;;
800x600p60hz) result="0 0 799 599" ;;
1024x600p60hz) result="0 0 1023 599" ;;
1024x768p60hz) result="0 0 1023 767" ;;
1360x768p60hz) result="0 0 1359 767" ;;
1366x768p60hz) result="0 0 1365 767" ;;
1440x900p60hz) result="0 0 1439 899" ;;
1600x900p60hz) result="0 0 1599 899" ;;
1680x1050p60hz) result="0 0 1679 1049" ;;
720p) result="0 0 1279 719" ;;
800p) result="0 0 1279 799" ;;
sxga) result="0 0 1279 1023" ;;
1080*) result="0 0 1919 1079" ;;
1920x1200) result="0 0 1919 1199" ;;
esac
if [ -z "$result" ]; then
return 1
else
echo "$result"
return 0
fi
}
function mode2geometry() {
local result=""
case "$1" in
vga*) result="640 480 640 960";;
480*) result="720 480 720 960";;
576*) result="720 576 720 1152";;
800x480p60hz) result="800 480 800 960";;
800x600p60hz) result="800 600 800 1200";;
1024x600p60hz) result="1024 600 1024 1200";;
1024x768p60hz) result="1024 768 1024 1536";;
1360x768p60hz) result="1360 768 1360 1536";;
1366x768p60hz) result="1366 768 1366 1536";;
1440x900p60hz) result="1440 900 1440 1800";;
1600x900p60hz) result="1600 900 1600 1800";;
1680x1050p60hz) result="1680 1050 1680 2100";;
720p) result="1280 720 1280 1440";;
800p) result="1280 800 1280 1600";;
sxga) result="1280 1024 1280 2048";;
1080*) result="1920 1080 1920 2160";;
1920x1200) result="1920 1200 1920 2400";;
esac
if [ -z "$result" ]; then
return 1
else
echo "$result"
return 0
fi
}
SCRIPTNAME="c1_displaytool"
SCRIPTVERSION="0.1"
USAGE="Usage: $(basename "$0") [-h] [-v] [-m mode] [-b bpp]"
# Parse command line options.
while getopts hvm:b: OPT; do
case "$OPT" in
h)
echo $USAGE
exit 0
;;
v)
echo "${SCRIPTNAME} v${SCRIPTVERSION}"
echo "(c) 2015, Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de>"
echo
echo "This program is free software: you can redistribute it and/or modify"
echo "it under the terms of the BSD 3-Clause License."
exit 0
;;
m)
mode=$OPTARG
;;
b)
bpp=$OPTARG
;;
\?)
# getopts issues an error message
echo $USAGE >&2
exit 1
;;
esac
done
# Get current mode
cur_mode=$(cat "/sys/class/display/mode")
if [ "$?" -ne "0" ]; then
echo "ERROR: unable to get current mode" >&2
exit 1
fi
# Get current bpp
cur_bpp=$(cat "/sys/class/graphics/fb0/bits_per_pixel")
if [ "$?" -ne "0" ]; then
echo "ERROR: unable to get current bpp" >&2
exit 2
fi
# Check if any changes have been requested
if ( [ -z "$mode" ] || [ "$cur_mode" == "$mode" ] ) && ( [ -z "$bpp" ] || [ "$cur_bpp" == "$bpp" ] ); then
# No change requested, printing current values
cur_info=$(mode2info "$cur_mode")
echo "Current setting: $cur_mode ($cur_info) at $cur_bpp bpp"
exit 0
fi
# Check if mode setting is valid
info=$(mode2info "$mode")
if [ -n "$mode" ] && [ -z "$info" ]; then
echo "ERROR: invalid mode '$mode'" >&2
exit 3
fi
# Check if bpp setting is valid
if [ -n "$bpp" ] && ( [ "$bpp" != "16" ] && [ "$bpp" != "24" ] && [ "$bpp" != "32" ] ); then
echo "ERROR: invalid bpp '$bpp' (must be 16, 24 or 32)" >&2
exit 4
fi
# If mode/bpp is not set, keep current setting
if [ -n "$mode" ] && [ "$cur_mode" != "$mode" ]; then
echo "Changing mode from '$cur_mode' to '$mode' ($info)"
else
mode="$cur_mode"
fi
if [ -n "$bpp" ] && [ "$cur_bpp" != "$bpp" ]; then
echo "Changing bpp from '$cur_bpp' to '$bpp'"
else
bpp="$cur_bpp"
fi
# Get the needed axis/geometry values
axis=$(mode2axis "$mode")
geometry=$(mode2geometry "$mode")
if [ -z "$axis" ] || [ -z "$geometry" ]; then
# This shouldn't happen
echo "ERROR: Failed to get respective axis/geometry values" >&2
exit 5
fi
# Settings look ok, let's check if we actually have the necessary write permissions
files=('/dev/fb0' '/sys/class/display/mode' '/sys/class/graphics/fb0/free_scale_axis' '/sys/class/graphics/fb0/window_axis')
for file in "${files[@]}"
do
if ! [ -w "$file" ]; then
echo "ERROR: You don't have permission to write to '$file'!" >&2
exit 6
fi
done
# OK, we can do it!
echo "Executing 'fbset -fb /dev/fb0 -g $geometry $bpp'..."
fbset -fb /dev/fb0 -g $geometry $bpp
if [ "$?" -ne "0" ]; then
echo "ERROR: fbdev command returned with non-zero exit status $?, aborting..." >&2
exit 7
fi
echo "Setting display mode to $mode..."
echo "$mode" > /sys/class/display/mode
echo "Setting free_scale_axis to '$axis'..."
echo "$axis" > /sys/class/graphics/fb0/free_scale_axis
echo "Setting window_axis to '$axis'..."
echo "$axis" > /sys/class/graphics/fb0/window_axis
echo "Done."
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment