Snapstream firefly mini
Contents
Snapstream Firefly Mini Remote (IR, USB, mini)
Product Web page: http://www.snapstream.com/products/fireflymini/
There are two version of this remote. The original full size rf firefly remote, Snapstream Firefly and the new mini-firefly remote that is IR based. This guide is for the IR version.
Description
This remote is cheap IR-based USB remote control, the smaller cousin of the larger, RF-based Snapstream Firefly remote. I have found this device to be an acceptable remote; it is cheap, compact and performs as expected when setup correctly. The IR range and sensitivity is a little disappointing, I have found that correct placement of the IR receiver makes a big difference.
Issues and Problems
The Firefly Mini is a USB HID device so should work without dedicated drivers. Indeed plugging this remote should result in some of the buttons working immediately (0-9, up, down, left, right, and OK). The remainder - except for 3 of them (Last, Guide, and the special "Firefly" buttion) can be mapped as any key on the keyboard using the 'Xmodmap' command. You can see you current keymappings with by typing "xmodmap -pke" at the terminal.
The list of keycodes for each non-standard buttion (found with XEV command) are:
Close = 175
Mute = 160
Last = no keycode in XEV
Exit = 234
VOL+ = 176
VOL- = 174
Option = 134
Firefly = no keycode in XEV
Menu = 158
Record = 177
Guide = no keycode in XEV
Stop = 164
Prev|<< = 144
Play = 179
Next>>| = 153
REW<< = 152
Pause = 110
FFWD>> = 180
For example, from the terminal one can enter:
xmodmap -e "keycode 179 = p"
And the main keymap will be changed so when you press the "Play" button on the Firefly remote it will act as if it is pressing "p" on the keyboard. This is a temporary modification that is lost on re-boot. So, in order to keep these settings you need to include these xmodmap commands in an init script during your window manager startup. Alternatively, you can create a text file of the key settings to launch with xmodmap. For example one can create a keys.txt file like this:
# /var/lib/mythtv/keys.txt keycode 164 = Escape keycode 134 = m keycode 152 = Left keycode 180 = Right keycode 144 = less keycode 179 = p keycode 153 = greater keycode 177 = r keycode 160 = F9
And then executing "xmodmap /var/lib/mythtv/keys.txt". In Mythbuntu, you can add this line to "programs run at statup" gui in XFCE window manager. Using this method does not require the use of LIRC, the remote will act as if it is a keystroke on the keyboard.
To determine the key name of a key do:
xev
press the key you want to know the name of and you will see
KeyPress event, serial 31, synthetic NO, window 0x3000001, root 0x1a6, subw 0x0, time 794284, (-250,-129), root:(301,319), state 0x0, keycode 34 (keysym 0x5b, bracketleft), same_screen YES, XLookupString gives 1 bytes: (5b) "[" XmbLookupString gives 1 bytes: (5b) "[" XFilterEvent returns: False
bracketleft is the name of that key.
The rest of this guide is dedicated to configuring your system so that all buttons on the Firefly Mini are functional. This is achieved by:
- Ensuring kernel support for all buttons on the Firefly Mini
- Configuring lirc to read keypresses from the Linux /dev/input/event subsystem
- Configuring lirc to send appropriate events to MythTV
NOTE: lirc is used to handle 'special' buttons, the normal buttons (0-9, up, down, left, right, ok) are not handled by lirc.
Ensure Firefly Mini hardware is working
When plugged in to the system the Firefly Mini should be recognized as a composite USB device with two interfaces:
[root@localhost simon]# cat /proc/bus/usb/devices ... T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=1.5 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=1233 ProdID=e007 Rev= 1.00 S: Manufacturer=HOLTEK S: Product=USB Keyboard C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 Driver=usbhid E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=10ms I: If#= 1 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=usbhid E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=10ms ...
The first interface is a USB HID Keyboard (Prot=01), most of the 'standard keyboard' buttons found on a standard keyboard are attached to this interface, they are generally the ones that work out-of-the-box even without full kernel support.
The second interface is a USB HID mouse device (Prot=02) that maps to most of the other buttons (close, guide, menu etc.).
When the Firefly Mini is attached two entries should be created in /dev/input/ that correspond with the the keyboard and consumer device (e.g. event0 and event1). The exact numbers used depend on the number of other USB HID devices attached to your system.
Fixed device names for these devices are also generated by udev under /dev/input/by-id, with symbolic links to the underlying devices, for example:
# stat -c "%N" /dev/input/by-id/usb-HOLTEK_USB_Keyboard-* `/dev/input/by-id/usb-HOLTEK_USB_Keyboard-event-kbd' -> `../event1' `/dev/input/by-id/usb-HOLTEK_USB_Keyboard-event-mouse' -> `../event2' `/dev/input/by-id/usb-HOLTEK_USB_Keyboard-mouse' -> `../mouse1'
You should be able to read from each of the above event devices and see some data appear when keys are pressed. If you do not have full kernel support, some keys (such as the red 'Snapstream' button) do not produce any output on any of the event devices.
Kernel
Kernel 2.6.20 and up have support for all of the keys on the remote.
The following patch was created against FC6 2.6.18-1.2849, use it or a similar change to add full support for earlier kernels.
--- a/drivers/usb/input/hid-input.c 2006-09-19 20:42:06.000000000 -0700 +++ b/drivers/usb/input/hid-input.c 2006-12-31 14:26:00.000000000 -0800 @@ -403,9 +403,12 @@ static void hidinput_configure_usage(str case 0x000: goto ignore; case 0x034: map_key_clear(KEY_SLEEP); break; case 0x036: map_key_clear(BTN_MISC); break; + case 0x040: map_key_clear(KEY_MENU); break; case 0x045: map_key_clear(KEY_RADIO); break; case 0x08a: map_key_clear(KEY_WWW); break; + case 0x083: map_key_clear(KEY_LAST); break; case 0x08d: map_key_clear(KEY_PROGRAM); break; + case 0x09a: map_key_clear(KEY_PVR); break; case 0x095: map_key_clear(KEY_HELP); break; case 0x09c: map_key_clear(KEY_CHANNELUP); break; case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; @@ -426,10 +429,12 @@ static void hidinput_configure_usage(str case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; case 0x183: map_key_clear(KEY_CONFIG); break; case 0x18a: map_key_clear(KEY_MAIL); break; + case 0x18e: map_key_clear(KEY_CALENDAR); break; case 0x192: map_key_clear(KEY_CALC); break; case 0x194: map_key_clear(KEY_FILE); break; case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; case 0x201: map_key_clear(KEY_NEW); break; + case 0x203: map_key_clear(KEY_CLOSE); break; case 0x207: map_key_clear(KEY_SAVE); break; case 0x208: map_key_clear(KEY_PRINT); break; case 0x209: map_key_clear(KEY_PROPS); break;
Apply the patch, install the resulting kernel and reboot. When running the new kernel pressing each button on the Firefly Mini should result in some characters appearing on one of the /dev/input/eventX devices.
Create a udev rule for the remote control consumer device =
We will be using lirc to interpret the data from /dev/input and generate events however lirc must have a fixed device name to read data from. In order to create a fixed device name we need a custom udev rule.
Identify the /dev/input/eventX device that corresponds to the red 'Snapstream' button button on the remote control. Repeatedly pressing the red button while using cat to read from each eventX device should do the trick. Next we need to find unique modalias for this device:
udevinfo -a -p $(udevinfo -q path -n /dev/input/eventX) [root@localhost SOURCES]# udevinfo -a -p $(udevinfo -q path -n /dev/input/event1) Udevinfo starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/class/input/input1/event1': KERNEL=="event1" SUBSYSTEM=="input" SYSFS{dev}=="13:65" looking at parent device '/class/input/input1': ID=="input1" BUS=="input" DRIVER=="" SYSFS{uniq}=="" SYSFS{phys}=="usb-0000:00:10.2-1/input1" SYSFS{name}=="HOLTEK USB Keyboard" looking at parent device '/devices/pci0000:00/0000:00:10.2/usb3/3-1/3-1:1.1': ID=="3-1:1.1" BUS=="usb" DRIVER=="usbhid" SYSFS{modalias}=="usb:v1233pE007d0100dc00dsc00dp00ic03isc01ip02" <==== THIS ONE! SYSFS{bInterfaceProtocol}=="02" SYSFS{bInterfaceSubClass}=="01" SYSFS{bInterfaceClass}=="03" SYSFS{bNumEndpoints}=="01" SYSFS{bAlternateSetting}==" 0" SYSFS{bInterfaceNumber}=="01" looking at parent device '/devices/pci0000:00/0000:00:10.2/usb3/3-1': ID=="3-1" BUS=="usb" DRIVER=="usb" SYSFS{configuration}=="" SYSFS{product}=="USB Keyboard" SYSFS{manufacturer}=="HOLTEK" SYSFS{maxchild}=="0" SYSFS{version}==" 1.10" SYSFS{devnum}=="2" SYSFS{speed}=="1.5" ...
Locate the first modalias line and note the long value contained within it. Now create a new file /etc/udev/rules.d/10-local.rules with the following content:
KERNEL=="event*",SYSFS{modalias}=="<your modalias value here>",SYMLINK="input/firefly-mini"
With this rule in place unplugging and replugging the remote control should result in this:
[root@localhost SOURCES]# ls -l /dev/input/* crw------- 1 root root 13, 64 Jan 1 14:36 /dev/input/event0 crw------- 1 root root 13, 65 Jan 1 14:36 /dev/input/event1 crw------- 1 root root 13, 66 Jan 1 14:36 /dev/input/event2 lrwxrwxrwx 1 root root 6 Jan 1 14:36 /dev/input/firefly-mini -> event1 crw------- 1 root root 13, 63 Jan 1 14:36 /dev/input/mice crw------- 1 root root 13, 32 Jan 1 14:36 /dev/input/mouse0 [root@localhost SOURCES]#
Configure lirc
The Firefly Mini remote needs to be defined in the lircd.conf file, add the following to yours:
begin remote name firefly-mini bits 32 begin codes CLOSE 0x100ce MUTE 0x10071 VOLUMEDOWN 0x10072 VOLUMEUP 0x10073 CHANNELUP 0x10192 CHANNELDOWN 0x10193 LAST 0x10195 BACK 0x1009e PROPS 0x10082 PVR 0x1016e MENU 0x1008b RECORD 0x100a7 CALENDAR 0x1018d STOPCD 0x100a6 PREVIOUSSONG 0x100a5 PLAY 0x100cf NEXTSONG 0x100a3 REWIND 0x100a8 PAUSE 0x10077 FASTFORWARD 0x100d0 end codes end remote
We will use lirc to read events from /dev/input/firefly-mini. To do this we'll use the lirc 'dev/input' driver, which uses the lirc_i2c kernel module. If you have not yet configured and installed lirc, do so now.
When lircd the device and driver to use should be specified. I added the following line to /etc/rc.local:
/usr/local/sbin/lircd --driver=dev/input --device=/dev/input/firefly-mini --output=/dev/lircd --pidfile /var/run/lircd.pid
Or, perhaps configure LIRCD_OPTIONS in /etc/init.d/lircd, such that you can use the standard rc scripts to start/stop/restart lircd:
LIRCD_OPTIONS="--driver=dev/input --device=/dev/input/firefly-mini --output=/dev/lircd --pidfile /var/run/lircd.pid"
With lircd.conf updated and lircd running irw and pressing special keys (other than 0-9, up, down, left, right, ok) should generate output:
[root@localhost SOURCES]# irw 0000000000010073 00 VOLUMEUP firefly-mini 0000000000010072 00 VOLUMEDOWN firefly-mini 0000000000010192 00 CHANNELUP firefly-mini 0000000000010193 00 CHANNELDOWN firefly-mini 000000000001016e 00 PVR firefly-mini
Finally modify your /home/mythtv/.lircrc and /home/mythtv/.mythtv/lircrc files to perform appropriate actions when buttons are pressed. Here is my lircrc file as it stands today, it's a work in progress.
NOTE: Alt+Home and Alt+G should be configured using Setup->Keys to make the red button and the guide button work.
# MythTV begin prog = mythtv button = CLOSE config = Esc repeat = 1 end begin prog = mythtv button = MUTE config = | repeat = 1 end begin prog = mythtv button = VOLUMEUP config = ] end begin prog = mythtv button = VOLUMEDOWN config = [ end begin prog = mythtv button = CHANNELUP config = Up end begin prog = mythtv button = CHANNELDOWN config = Down end begin prog = mythtv button = LAST config = H repeat = 1 end begin prog = mythtv button = BACK config = Esc repeat = 1 end begin prog = mythtv button = PROPS config = I repeat = 1 end begin prog = mythtv button = PVR config = Alt+Home repeat = 1 end begin prog = mythtv button = MENU config = M repeat = 1 end begin prog = mythtv button = RECORD config = R repeat = 1 end begin prog = mythtv button = CALENDAR config = Alt+G repeat = 1 end begin prog = mythtv button = STOPCD config = Esc repeat = 1 end begin prog = mythtv button = PREVIOUSSONG config = Q repeat = 1 end begin prog = mythtv button = PLAY config = P repeat = 1 end begin prog = mythtv button = NEXTSONG config = Z repeat = 1 end begin prog = mythtv button = REWIND config = < repeat = 1 end begin prog = mythtv button = PAUSE config = P end begin prog = mythtv button = FASTFORWARD config = > end # mplayer begin prog = mplayer button = BACK config = quit end
Good luck!