Skip to content

Instantly share code, notes, and snippets.

@zerkalica
Created January 4, 2016 23:34
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 zerkalica/f1c3a0a889cd974c495d to your computer and use it in GitHub Desktop.
Save zerkalica/f1c3a0a889cd974c495d to your computer and use it in GitHub Desktop.
Banana pro lirc GPIO transmitter (sender)
# Cubietruck automatic lirc device detection by Igor Pecovnik
str=$(cat /proc/bus/input/devices | grep "H: Handlers=sysrq rfkill kbd event" | awk '{print $(NF)}')
sed -i 's/DEVICE="\/dev\/input.*/DEVICE="\/dev\/input\/'$str'"/g' /etc/lirc/hardware.conf
# /etc/lirc/hardware.conf
#
#Chosen Remote Control
REMOTE="devinput"
REMOTE_MODULES=""
REMOTE_DRIVER="devinput"
REMOTE_DEVICE="/dev/input/event1"
REMOTE_SOCKET=""
REMOTE_LIRCD_CONF="/etc/lirc/lircd.conf"
REMOTE_LIRCD_ARGS=""
#Chosen IR Transmitter
TRANSMITTER="gpio"
TRANSMITTER_MODULES=""
TRANSMITTER_DRIVER="default"
TRANSMITTER_DEVICE="/dev/$(ls /sys/devices/platform/lirc_gpio.0/lirc/)"
TRANSMITTER_SOCKET=""
TRANSMITTER_LIRCD_CONF="/etc/lirc/lircd-send.conf"
TRANSMITTER_LIRCD_ARGS=""
TRANSMITTER_PIN=2
#Disable kernel support.
#Typically, lirc will disable in-kernel support for ir devices in order to
#handle them internally. Set to false to prevent lirc from disabling this
#in-kernel support.
#DISABLE_KERNEL_SUPPORT="true"
#Enable lircd
START_LIRCD="true"
#Don't start lircmd even if there seems to be a good config file
#START_LIRCMD="false"
#Try to load appropriate kernel modules
LOAD_MODULES="true"
# Default configuration files for your hardware if any
LIRCMD_CONF=""
#Forcing noninteractive reconfiguration
#If lirc is to be reconfigured by an external application
#that doesn't have a debconf frontend available, the noninteractive
#frontend can be invoked and set to parse REMOTE and TRANSMITTER
#It will then populate all other variables without any user input
#If you would like to configure lirc via standard methods, be sure
#to leave this set to "false"
FORCE_NONINTERACTIVE_RECONFIGURATION="false"
#START_LIRCMD="true"
#! /bin/sh
### BEGIN INIT INFO
# Provides: lirc
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts LIRC daemon.
# Description: LIRC is used to control different
# infrared receivers and transceivers.
### END INIT INFO
load_modules ()
{
MODULES_MISSING=false
log_daemon_msg "Loading LIRC modules"
for mod in $*; do
if [ $mod = "udev" ]; then
log_end_msg 0
log_success_msg "Restarted via udev, don't reload modules"
break
else
modprobe $mod 2> /dev/null || MODULES_MISSING=true
fi
done
log_end_msg $?
if $MODULES_MISSING; then
log_failure_msg "Unable to load LIRC kernel modules. Verify your"
log_failure_msg "selected kernel modules in /etc/lirc/hardware.conf"
START_LIRCMD=false
START_LIRCD=false
fi
}
build_remote_args ()
{
REMOTE_ARGS="$*"
#For remote only detection support, we need
#both REMOTE_DEVICE and TRANSMITTER_DEVICE undefined
if [ -z "$REMOTE_DEVICE" ] && [ -z "$TRANSMITTER_DEVICE" ] && [ -c $dev ]; then
REMOTE_DEVICE="$dev"
fi
#If we have a REMOTE_DEVICE or REMOTE_DRIVER defined (either because no devices
#were defined, OR if we explicitly did), then populate REMOTE_ARGS
if [ -n "$REMOTE_DEVICE" ] || [ -n "$REMOTE_DRIVER" ]; then
if [ -n "$REMOTE_DEVICE" ] && [ "$REMOTE_DEVICE" != "none" ]; then
REMOTE_ARGS="--device=$REMOTE_DEVICE $REMOTE_ARGS"
fi
if [ -n "$REMOTE_DRIVER" ] && [ "$REMOTE_DRIVER" != "none" ]; then
REMOTE_ARGS="--driver=$REMOTE_DRIVER $REMOTE_ARGS"
fi
#Now, if we ALSO have a transmitter defined, add some args
#To make the first lircd listen up
if [ -n "$TRANSMITTER_DEVICE" ] || [ -n "$TRANSMITTER_DRIVER" ]; then
REMOTE_ARGS="$REMOTE_ARGS --connect=localhost:8765"
fi
REMOTE_ARGS="--output=$REMOTE_SOCKET $REMOTE_ARGS"
fi
REMOTE_PID="--pidfile=/run/lirc/lircd.pid"
echo $REMOTE_ARGS
}
build_transmitter_args ()
{
TRANSMITTER_ARGS="$*"
#Transmitters must be explicitly be defined
if [ -n "$TRANSMITTER_DEVICE" ] || [ -n "$TRANSMITTER_DRIVER" ]; then
if [ -n "$TRANSMITTER_DEVICE" ] && [ "$TRANSMITTER_DEVICE" != "none" ]; then
TRANSMITTER_ARGS="--device=$TRANSMITTER_DEVICE $TRANSMITTER_ARGS"
fi
if [ -n "$TRANSMITTER_DRIVER" ] && [ "$TRANSMITTER_DRIVER" != "none" ]; then
TRANSMITTER_ARGS="--driver=$TRANSMITTER_DRIVER $TRANSMITTER_ARGS"
fi
#Now, if we ALSO have a remote defined, add some args
#To make the second lircd connect
if [ -n "$REMOTE_DEVICE" ] || [ -n "$REMOTE_DRIVER" ]; then
TRANSMITTER_ARGS="$TRANSMITTER_ARGS --listen --pidfile=/run/lirc/lircd1.pid"
TRANSMITTER_PID="--pidfile=/run/lirc/lircd1.pid"
else
TRANSMITTER_PID="--pidfile=/run/lirc/lircd.pid"
fi
TRANSMITTER_ARGS="--output=$TRANSMITTER_SOCKET $TRANSMITTER_ARGS"
if [ -n "$TRANSMITTER_LIRCD_CONF" ] ; then
TRANSMITTER_ARGS="$TRANSMITTER_ARGS $TRANSMITTER_LIRCD_CONF"
fi
fi
echo $TRANSMITTER_ARGS
}
in_kernel_support() {
if [ -d /sys/class/rc ] && [ "$DISABLE_KERNEL_SUPPORT" = "true" ]; then
for file in `find /sys/class/rc/*/ -name protocols`; do
if [ "$1" = "disable" ]; then
echo "lirc" > $file
else
echo "none" > $file
for protocol in `cat $file`; do
echo "+${protocol}" > $file
done
fi
done
fi
}
. /lib/lsb/init-functions
test -f /usr/sbin/lircd || exit 0
test -f /usr/sbin/lircmd || exit 0
START_LIRCMD=true
START_LIRCD=true
START_IREXEC=true
DISABLE_KERNEL_SUPPORT=true
if [ -f /etc/lirc/hardware.conf ];then
. /etc/lirc/hardware.conf
fi
if [ ! -f /etc/lirc/lircd.conf ] || grep -q "^#UNCONFIGURED" /etc/lirc/lircd.conf; then
if [ "$1" = "start" ]; then
log_success_msg "No valid /etc/lirc/lircd.conf has been found."
log_success_msg "Remote control support has been disabled."
log_success_msg "Reconfigure LIRC or manually replace /etc/lirc/lircd.conf to enable."
fi
START_LIRCD=false
START_LIRCMD=false
START_IREXEC=false
fi
if [ ! -f /etc/lirc/lircmd.conf ] || grep -q "^#UNCONFIGURED" /etc/lirc/lircmd.conf; then
START_LIRCMD=false
fi
if [ ! -f /etc/lirc/lircrc ] || grep -q "^#UNCONFIGURED" /etc/lirc/lircrc; then
START_IREXEC=false
fi
#We need default socket locations
OLD_SOCKET="/dev/lircd"
if [ -z "$REMOTE_SOCKET" ]; then
REMOTE_SOCKET="/run/lirc/lircd"
fi
if [ -z "$TRANSMITTER_SOCKET" ]; then
TRANSMITTER_SOCKET="/run/lirc/lircd"
#Now, if we ALSO have a remote defined,
#change the default transmitter socket
if [ -n "$REMOTE_DEVICE" ] || [ -n "$REMOTE_DRIVER" ]; then
TRANSMITTER_SOCKET="${TRANSMITTER_SOCKET}1"
fi
fi
case "$1" in
start)
if [ "$LOAD_MODULES" = "true" ] && [ "$START_LIRCD" = "true" ]; then
load_modules $2 $REMOTE_MODULES $TRANSMITTER_MODULES $MODULES
in_kernel_support "disable"
fi
if [ "$START_LIRCD" = "true" ]; then
mkdir -p "/run/lirc"
log_daemon_msg "Starting remote control daemon(s) : "
REMOTE_LIRCD_ARGS=`build_remote_args $REMOTE_LIRCD_ARGS`
TRANSMITTER_LIRCD_ARGS=`build_transmitter_args $TRANSMITTER_LIRCD_ARGS`
RES=1
#if we have a transmitter defined, start it first
if [ -n "$TRANSMITTER_LIRCD_ARGS" ]; then
log_progress_msg "LIRC (transmitter)"
if [ -n "$TRANSMITTER_PIN" ] ; then
echo $TRANSMITTER_PIN > /sys/class/lirc_gpio/tx_gpio_pin
fi
start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/lircd --pidfile=$TRANSMITTER_PID -- $TRANSMITTER_LIRCD_ARGS < /dev/null
RES=$?
fi
if [ -n "$REMOTE_LIRCD_ARGS" ]; then
log_progress_msg "LIRC (remote)"
start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/lircd --pidfile=$REMOTE_PID -- $REMOTE_LIRCD_ARGS < /dev/null
RES=$?
fi
log_end_msg $RES
#Set up symlinks, starting with the remote if present.
if [ -n "$REMOTE_LIRCD_ARGS" ]; then
if [ -S "$REMOTE_SOCKET" -a "$OLD_SOCKET" != "$REMOTE_SOCKET" ]; then
rm -f $OLD_SOCKET && ln -s $REMOTE_SOCKET $OLD_SOCKET
fi
if [ -n "$TRANSMITTER_LIRCD_ARGS" ]; then
if [ -S "$TRANSMITTER_SOCKET" ]; then
rm -f ${OLD_SOCKET}1 && ln -s $TRANSMITTER_SOCKET ${OLD_SOCKET}1
fi
fi
elif [ -n "$TRANSMITTER_LIRCD_ARGS" ]; then
if [ -S "$TRANSMITTER_SOCKET" -a "$OLD_SOCKET" != "$TRANSMITTER_SOCKET" ]; then
rm -f $OLD_SOCKET && ln -s $TRANSMITTER_SOCKET $OLD_SOCKET
fi
fi
fi
if [ "$START_LIRCMD" = "true" ]; then
mkdir -p "/run/lirc"
log_daemon_msg "Starting remote control mouse daemon : LIRCMD "
start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/lircmd < /dev/null
log_end_msg $?
fi
if [ "$START_IREXEC" = "true" ]; then
mkdir -p "/run/lirc"
log_daemon_msg "Starting execution daemon: irexec"
start-stop-daemon --start --quiet --oknodo --exec /usr/bin/irexec -- -d /etc/lirc/lircrc < /dev/null
log_end_msg $?
fi
;;
stop)
in_kernel_support "enable"
if [ "$START_IREXEC" = "true" ]; then
log_daemon_msg "Stopping execution daemon: irexec"
start-stop-daemon --stop --oknodo --quiet --exec /usr/bin/irexec
log_end_msg $?
fi
if [ "$START_LIRCMD" = "true" ]; then
log_daemon_msg "Stopping remote control mouse daemon: LIRCMD"
start-stop-daemon --stop --oknodo --quiet --exec /usr/sbin/lircmd
log_end_msg $?
fi
if [ "$START_LIRCD" = "true" ]; then
log_daemon_msg "Stopping remote control daemon(s): LIRC"
start-stop-daemon --stop --oknodo --quiet --exec /usr/sbin/lircd --pidfile /run/lirc/lircd.pid
start-stop-daemon --stop --oknodo --quiet --exec /usr/sbin/lircd --pidfile /run/lirc/lircd1.pid
log_end_msg $?
[ -h "$OLD_SOCKET" ] && rm -f $OLD_SOCKET
[ -h "${OLD_SOCKET}1" ] && rm -f ${OLD_SOCKET}1
fi
;;
reload|force-reload)
if [ "$START_IREXEC" = "true" ]; then
start-stop-daemon --stop --quiet --signal 1 --exec /usr/bin/irexec
fi
if [ "$START_LIRCD" = "true" ]; then
start-stop-daemon --stop --quiet --signal 1 --exec /usr/sbin/lircd
fi
if [ "$START_LIRCMD" = "true" ]; then
start-stop-daemon --stop --quiet --signal 1 --exec /usr/sbin/lircmd
fi
;;
restart)
$0 stop
#passes parameter $2 which is possibly our udev paramater
$0 start $2
;;
*)
echo "Usage: /etc/init.d/lircd {start|stop|reload|restart|force-reload}"
exit 1
esac
exit 0
#/etc/lirc/lircd-send.conf
begin remote
name roku
bits 8
flags SPACE_ENC|CONST_LENGTH
eps 30
aeps 100
header 9054 4472
one 561 1663
zero 561 567
ptrail 565
repeat 9055 2236
pre_data_bits 16
pre_data 0x77E1
post_data_bits 8
post_data 0xF1
gap 108151
toggle_bit_mask 0x0
begin codes
KEY_UP 0x50
KEY_DOWN 0x30
KEY_LEFT 0x90
KEY_RIGHT 0x60
KEY_PLAY 0xFA 0xA0
KEY_MENU 0xC0
KEY_OK 0x3A 0xA0
end codes
end remote
# generated by devinput.sh
# /etc/lirc/lircd.conf
begin remote
name devinput
bits 16
eps 30
aeps 100
pre_data_bits 16
pre_data 0x0001
post_data_bits 32
post_data 0x00000001
gap 132799
toggle_bit 0
begin codes
POWER 87
MUTE 92
HELP 5
PREFS 9
FAVS 21
R2C1 4
R2C2 8
R2C3 20
VOLUME+ 255
VOLUME- 93
INFO 16
MOUSE 17
ZOOM+ 12
ZOOM- 88
R5C1 84
R5C2 91
R5C3 23
MENU 22
HOME 71
BACK 79
LEFT 6
RIGHT 14
UP 67
DOWN 10
OK 2
STOP 19
PLAY 80
SEARCH 13
REV 7
FWD 3
PREV 15
NEXT 11
RED 85
GREEN 78
YELLOW 73
BLUE 72
1 26
2 1
3 69
4 89
5 77
6 64
7 82
8 83
9 65
0 90
AUDIO 68
SUBTITLE 70
end codes
end remote
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
# Parameters can be specified after the module name.
hci_uart
gpio_sunxi
rfcomm
hidp
sunxi-ir
bonding
spi_sun7i
8021q
a20_tp
#ap6210
lirc_gpio
@zerkalica
Copy link
Author

Need patch sunxi kernel drivers:

https://github.com/matzrh/sunxi-lirc

PIN number is sys row for banana pro in this table:

http://wiki.lemaker.org/How_to_control_the_IO_on_the_SBC_boards#Appendix:_40_Pins_GPIO_Mapping_Table_for_Banana_Pro_and_LeMaker_Guitar

Example: hardware pin 3 PB21 (WTI2_SDA) is sys pin 2.

Test:

irsend -d /dev/lircd1 SEND_ONCE roku KEY_UP

And led flashes

@MichaelHills
Copy link

Hi @zerkalica how did you get lirc_gpio working? I'm using Bananian 15.08 (3.4.108) on my Banana Pro and am currently cloning https://github.com/Bananian/linux-bananapi in order to try to build https://github.com/matzrh/sunxi-lirc

I am a developer but not familiar with Linux development nor how to build kernel modules. I am following this guide http://forum.lemaker.org/thread-14072-1-1.html and my hope is I can build lirc_gpio and then load it into my current kernel.

I've built an IR emitter circuit that I want to control using a GPIO port. All I want to do is be able to transmit IR remote control codes, I don't care about receiving. I did get irw working though using this gist and I can receive IR signals from my TV remote, but it looks like I need lirc_gpio to be able to transmit.

Edit: As an alternative route I'm going to try to implement a lirc userspace driver (http://www.lirc.org/html/driver-api.html) as I do seem to have gpio access.

Edit again: Sorry I now realise this was about Armbian and not Bananian.

More edits: I got everything working with Legacy Jessie Armbian for Banana Pro (http://www.armbian.com/banana-pi-pro/). I was able to send over gpios using

modprobe lirc_gpio gpio_out_pin=2
# or do this to change it later / set it manually
# echo 2 >/sys/class/lirc_gpio/tx_gpio_pin
lircd --device=/dev/lirc0 --driver=default remotes.conf
irsend SEND_ONCE LG_AKB72915207 KEY_POWER

You can figure out which lirc device using from this gist's hardware.conf
ls /sys/devices/platform/lirc_gpio.0/lirc
or just do
lircd --device=/dev/$(ls /sys/devices/platform/lirc_gpio.0/lirc/) --driver=default remotes.conf

@Manuko99
Copy link

HI zerlaica

I have been trying to set upIR as as transmitter but I haven't any successful result about that. When I write this command "modprobe lirc_gpio gpio_out_pin=2" in the terminal , I got this error "modprobe:FATAL: Module lirc_gpio not found in directory /lib/modules/3.4.39-BPI-M3-kernel"
PLease can you help me how can I fix that error and could you help the steps to set up a IR as transmitter, thank you so much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment