keene fm transmitter
Mon, 14 Mar 2011 07:30 categories: codetl;dr: it works! software to be downloaded here
Half a year ago I purchased a usb fm transmitter from Keene Retail Ltd and funnily enough the audio part was immediately working with linux as it just showed up as an usb audio device linux was having drivers for.
[433346.713773] usbcore: registered new interface driver snd-usb-audio
[433346.731642] generic-usb 0003:046D:0A0E.0001: hiddev0,hidraw0: USB HID
v1.10i Device [HOLTEK B-LINK USB Audio ] on usb-0000:00:1d.0-1.2/input2
[433346.731662] usbcore: registered new interface driver usbhid
[433346.731664] usbhid: USB HID core driver
But of course there was a proprietary usb control protocol to set frequency, TX, preemphasis, volume and so on. So I started using the horrible windows only control software and captured the usb messages it sent to the stick using usbsnoop. Doing that was a horrible experience since the program was constantly making my computer freeze or disable the usb entirely so that i had to switch off the whole machine and reboot - no idea what was causing this and also no incentive to find out why. In the end I managed to capture enough data to basically understand the protocol that was used. But as with every good proprietary protocol you reverse engineer there are still things that are ambiguous or dont make sense or are redundant or where you see how the protocol developed from a less capable state. I had that all and I still dont fully understand the design goals but in the end (and what counts) I was able to assemble a samll C program that could control the FM transmitter as the windows client could.
Something out of the ordinary was, when I tried to contact the guys from Keene and ask them whether they would want to help me with writing a client that would work for their hardware on linux. It took some months but in the end I got this awesome message:
Dear Johannes,
I'm sorry this has taken a while but please find attached the source code for this unit.
If you are successful in producing linux drivers and software I would be happy to add your program as a download from our site, or link to your site should you prefer.
Good luck!
Kind regards,
Alan Quinby Director Keene Electronics Ltd
And attached I found a rar archive with a number of *.asm, *.LST, *.inc, and *.OBJ files and some files named HT82A821R with endings like *.bin, *.CV, *.DBG, *.dsw, *.MAK, *.MAP, *.OPT, *.OTP, *.PRJ and *.TSK. The first bunch of files was just assembler text and some C in between but I couldnt figure out how they belonged all together nor what toolchain those are belonging to. I also wonder why one would do any project in pure assembler instead of just using C? If anybody has a clue about what those files could mean dont hesitate to tell but since reverse engineering already gave me results I didnt feel brave enough to further dig into those piles of assembler. Nevertheless it was still great of them to just send the code around - something you only see seldomly! So kudos to Keene here.
Now the results of my reverse engineering can be found here and you can just compile and run keenectl.c with your stick inserted. You also have to run at as root and you musnt forget to rmmod the usbhid module beforehand but the program will tell you that as well once an error occurs. To set all values to default just run:
./keenectl - - - - - - -
The arguments correspond to TX (0-23), preemphasis (50us or 75us), channels
(mono or stereo), frequency (floats from 76.0-108.0), PA (30 to 120), enable or
disable and mute or unmute. If one of the arguments is -
the default value is
set. A command explicitly specifying the defaults would hence look like:
./keenectl 0 50us stereo 90.0f 120 enable unmute
To send all parameters, two 8 byte usb control messages are dispatched.
When you are done, you can play the music for example using mplayer:
mplayer -ao alsa:device=hw=1.0 YourMusic.wav
Have fun!