Controlling and reading a usb radio continued

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I have an issue with my silicon labs usb fmradio and after apending
with Hans de Goede, he suggested that I should email you people.

I have bought a silicon labs usb fmradio and I have written a python GUI
to control it. I have downloaded pyv4l2radio-0.3 which would also offer me
RDS decoding. But except for opening and closing the radio device nothing
else works in this library.
I also downloaded pyFMRadio-0.22 and again the same problem.
Note however that the radio does work. I am running gnomeradio and I can
scan and tune to radio stations and everything works fine.
But when I am using the python FMRadio library included in pyv4l2radio-0.3
or pyFMRadio-0.22 the usb radio automatically tunes to 96.3MHz. Amazingly
enough, RDS decoding does work, and that's how I know that the radio is
tuned to 96.3, its in the RDS text transmitted by the radio station at
96.3MHz.
This is the output I get from dmesg:
[  131.804472] usb 2-1.2: new full-speed USB device number 3 using ehci_hcd
[  131.983778] USB radio driver for Si470x FM Radio Receivers, Version 1.0.10
[  131.984497] radio-si470x 2-1.2:1.2: DeviceID=0x1242 ChipID=0x0a0f
[  131.985051] radio-si470x 2-1.2:1.2: software version 0, hardware version 4
[  131.985060] radio-si470x 2-1.2:1.2: This driver is known to work
with software version 7,
[  131.985065] radio-si470x 2-1.2:1.2: but the device has software version 0.
[  131.985070] radio-si470x 2-1.2:1.2: If you have some trouble using
this driver,
[  131.985074] radio-si470x 2-1.2:1.2: please report to V4L ML at
linux-media@xxxxxxxxxxxxxxx
[  132.034526] usbcore: registered new interface driver radio-si470x
[  132.036412] usbcore: registered new interface driver snd-usb-audio


I think that there is a problem with the kernel definitions for ioctl
commands. can you take a look and tell me if you see anything weird?

_IOC_NRBITS   = 8
_IOC_TYPEBITS = 8
_IOC_SIZEBITS = 14
_IOC_DIRBITS  = 2

_IOC_NRSHIFT   = 0
_IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS
_IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS
_IOC_DIRSHIFT  = _IOC_SIZESHIFT + _IOC_SIZEBITS

_IOC_WRITE = 1
_IOC_READ  = 2

_IOC  = lambda d,t,nr,size: (d << _IOC_DIRSHIFT) | (ord(t) <<
_IOC_TYPESHIFT) | \
                            (nr << _IOC_NRSHIFT) | (size <<
_IOC_SIZESHIFT)
_IOW  = lambda t,nr,size: _IOC(_IOC_WRITE, t, nr, size)
_IOWR = lambda t,nr,size: _IOC(_IOC_READ | _IOC_WRITE, t, nr, size)

# V4L2 stuff for accessing the tuner driver
_VIDIOC_G_TUNER     = _IOWR('V', 29, 84)
_VIDIOC_G_FREQUENCY = _IOWR('V', 56, 44)
_VIDIOC_S_FREQUENCY = _IOW ('V', 57, 44)
_VIDIOC_G_CTRL      = _IOWR('V', 27, 8)
_VIDIOC_S_CTRL      = _IOWR('V', 28, 8)

# tuner capabilities
_V4L2_TUNER_CAP_LOW    = 0x0001
_V4L2_TUNER_CAP_NORM_  = 0x0002
_V4L2_TUNER_CAP_STEREO = 0x0010
_V4L2_TUNER_CAP_LANG2  = 0x0020
_V4L2_TUNER_CAP_SAP    = 0x0020

# user-class control IDs defined by V4L2
_V4L2_CTRL_CLASS_USER = 0x00980000
_V4L2_CID_BASE        = _V4L2_CTRL_CLASS_USER | 0x900
_V4L2_CID_FM_BAND     = _V4L2_CID_BASE + 0

# signal scanning parameters
_SIGNAL_LOCK_TIME = 0.1
_SIGNAL_TRIES = 1
_SIGNAL_SAMPLE_SLEEP = 0.005
_SIGNAL_THRESHOLD = 20
_SCAN_STEP_KHZ = 50

I also noticed that if I tune to a station with gnomeradio and shut
gnomeradio down, if I run a test python program (based on FMRadio) to open
the radio, the radio device starts automatically tuned to the frequency last
tuned by gnomeradio. If I try to set_frequency to anywhere the usb radio
tunes to 96.3 and the get_frequency, get_signal_strength functions return 0.

Also function __get_tuner executes an ioctl call:
data = ioctl(self.__fd, _VIDIOC_G_TUNER, struct.pack("84x"))
fields = struct.unpack("L32sLLLLLLll4L", data)
which crashes with a message about 'struct unpack expects 136 bytes'
Then I changed it to: data = ioctl(self.__fd, _VIDIOC_G_TUNER,
struct.pack("136x"))
and no more crashes. However, printing the frequency range and factor I
get
rangelow:1.14933324841e+16
rangehigh 62.5
factor: 0.016
The frequency ranges do not make any sense and perhaps the entire answer
of the ioctl is garbage.
Any ideas, that would point me to the correct direction as to how to fix
this, would be greatly appreciated.

I include some of the other ioctl calls for you and I am also
attaching the entire file for you to have a more complete picture (The
file is 400 lines long)
get_fm_band:
   inp = struct.pack("Ll", _V4L2_CID_FM_BAND, 0)
   data = ioctl(self.__fd, _VIDIOC_G_CTRL, inp)

get_frequency:
   inp = struct.pack("LLL8L", self.__tuner["index"],
self.__tuner["type"], 0, 0, 0, 0, 0, 0, 0, 0, 0)
   data = ioctl(self.__fd, _VIDIOC_G_FREQUENCY, inp)

set_fm_band:
   inp = struct.pack("Ll", _V4L2_CID_FM_BAND, band)
   ioctl(self.__fd, _VIDIOC_S_CTRL, inp)

get_fm_band:
   inp = struct.pack("Ll", _V4L2_CID_FM_BAND, 0)
   data = ioctl(self.__fd, _VIDIOC_G_CTRL, inp)

__set_frequency:
   inp = struct.pack("LLL8L",
                          self.__tuner["index"],
                          self.__tuner["type"],
                          #freq, 0, 0, 0, 0, 0, 0, 0, 0)
                          int(freq * self.__factor), 0, 0, 0, 0, 0, 0, 0, 0)
   ioctl(self.__fd, _VIDIOC_S_FREQUENCY, inp)

Attachment: FMRadio.py
Description: Binary data


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux