[pvrusb2] question about managing HVR-1900 from an embedded host

Mike Isely isely at isely.net
Sat Jul 21 13:52:47 CDT 2012


Lots of comments interspersed below...

On Thu, 19 Jul 2012, Mark Atherton wrote:

>    Hi All,
>    I am working on a small, low power embedded digital TV project (see
>    [1]http://www.idesignz.org/DigiLiteZL/DigiLiteZL.htm, and associated
>    FPGA modulator
>    [2]http://www.idesignz.org/DigiLiteZL_FPGA/DigiLiteZL-FPGA.htm). One of
>    the next steps of the project is to hook a real-time MPEG2 video
>    encoder up to the system, running at a suitably low rate (maybe 1 or
>    2Mb/s total stream rate). The power budget for the system does not
>    allow for a PC, hence the desire to use a small embedded system.

Keep in mind that the mpeg encoder in the HVR-1900 needs a few watts, 
which is why such devices are not powered from the USB cable.


>    An HVR-1900 MPEG encoder is at hand, but only composite video and audio
>    inputs are required. This product appears to contain a Conexant CX23416
>    MPEG2 audio/video encoder, a CX25840 PAL/NTSC video decoder, and a
>    Cypress FX2, or FX2LP USB interface. The unit has misc stuff associated
>    with RF tuner etc, hopefully these can be ignored.

You should be able to safely ignore the RF side.


>    Moving on to signal flow: an external PAL video source will be plugged
>    into the HVR-1900, the HVR-1900 will be plugged into a custom
>    dsPIC33EP512MU810 board (which has a USB 1.1 host). The dsPIC has the
>    job of initially loading required firmware into the HVR-1900 then
>    selecting the required encode mode and translating the incoming real
>    time MPEG Program Stream into Transport Stream. This data will then be
>    transferred via a new parallel interface to the FPGA DVB-S modulator
>    (USB is currently used).

OK.  Sounds doable.


>    So far the PVR-1900 has been attached to Ubuntu Studio 10.x via a USB
>    1.1 hub, and it has been confirmed that the whole chain can generate a
>    1Mb/s PS using V4L. This was all rather easier than expected and worked
>    pretty much off the bat, so well done.that team.

I assume you mean HVR-1900, not PVR-1900.

Yes, early on in the pvrusb2 debugging I tried running it using USB 1.1 
and it worked pretty well using default encoding parameters.  However 
there are parameters possible that can raise the quality of the encode 
and it's possible to exceed what USB 1.1 can transport.  But with the 
defaults it's all good.


>    Having spent some time playing with a Cypress FX2 (CY7C68013) USB
>    interface dev kit, it appears that the FX2 can accept firmware over the
>    USB port, and run from it's internal 8k (FX2) or 16k (FX2LP) RAM using
>    vendor command 0xA0. A second stage boot loader (vend_ax) is required
>    if external RAM is required. Some amount of cleverness involves the
>    device re-enumerating itself from default VID / PID (0x04B4 / 0x8613)
>    once code has been loaded, so that alternate drivers can take over the
>    boot and control process. It also appears that DID is used to
>    differentiate the FX2 (DID 0x000x) from the FX2LP (DID 0xA00x).

The FX2 normally goes looking for an I2C EEPROM to be connected to it at 
a specific I2C address.  Having found such a part, the FX2 will expect a 
configuration block to be stored there which is used to set up the USB 
parameters, e.g. endpoint configuration, device ID, manufacturer ID, 
etc.  In addition to the configuration block, there can be a program 
stored there as well, which the FX2 will immediately copy to its 
internal RAM and execute.

For Hauppauge devices with this type of hardware, the EEPROM is 
programmed so that the device immediately reports the correct Hauppauge 
ID information and a small "boot" program will run.  However the device 
expects to be loaded with the "real" FX2 program, which the pvrusb2 
driver will do.  Since the USB ID doesn't change after the FX2 has been 
reloaded, the pvrusb2 driver has to do some crufty things to determine 
if the device's needs to have its FX2 program loaded.  I don't remember 
the specifics off-hand, but I believe in one case the driver attempts to 
look for a particular FX2 command to implemented.  In another case it 
may examine the endpoint configuration to tell apart the "boot" program 
from the "normal" program.

Code is loaded by forcing the FX2 into reset and then using the USB 
control endpoint to download a replacement program, using the vendor 
command you had mentioned.  The CPU is then released from reset, 
whereupon it "renumerates" into its run-time configuration.  This 
process is controlled via silicon not the FX2's processor, IIRC.


>    So the next challenge is to completely understand all steps required to
>    boot up a PVR-1900. From then, an understanding is required how to
>    configure and use the booted device.
>    At a guess, boot sequence is something like:
>    1) PVR-1900 is plugged into the host (dsPIC)
>    2) host registers and enumerates the FX2 device within the PVR-1900
>    using VID 0x04B4, PID 0x8613

Yup.

>    3) host downloads FX2 firmware (or second stage loader vend_ax) using
>    vendor command 0xA0
>    4) host releases FX2 8051 from reset, new code re-enumerates using
>    alternate VID / PID combination

Yes.  In the pvrusb2 driver, see the function pvr2_upload_firmware1() 
located in pvrusb2-hdw.c.  This performs the entire reset-upload-release 
sequence.  

>    -- at this point, the FX2 8051 is running a boot loader that will allow
>    code loading of CX25840 and CX23416 --

Yes but it's not a bootloader.  In the case of the pvrusb2 driver, at 
this point the FX2 is running is its final "operational" firmware.  It 
just so happens that this is then used to boot up the rest of the 
device.  But the FX2 firmware is not changed again.

>    5) host loads CX25840 firmware (possibly using two wire interface)

The CX25840 is loaded via its I2C port (the two wire interface), as 
driven by the FX2, which in turn acts as a proxy for the host where the 
pvrusb2 driver is running.

One very (very!) important function that the FX2 firmware performs is 
that it enables a sort of "proxy" access from the host system to its I2C 
controller.  This allows the pvrusb2 driver to execute all manner of I2C 
transactions; in fact the majority of the device's operations are 
performed via I2C.  The pvrusb2 driver makes all this work by 
implementing what appears to the rest of the kernel to be a "standard" 
Linux I2C adapter driver.  The pvrusb2 driver actually forwards all 
requests received via that adapter over to the FX2 via a 
command/response protocol on EP1.  This enables a key ability - every 
V4L-resident chip driver, designed to operate certain specific parts via 
I2C, automatically is able to access and operate corresponding chips 
inside your HVR-1900.  The pvrusb2 driver is effectively implementing a 
bridge between that chip driver and the actual hardware, by relaying 
transfer requests over USB to the FX2's firmware which then responds by 
performing the requested transfers using its own I2C controller.  The 
net result is that the I2C bus sitting inside your HVR-1900 - to which 
nearly everything is connected - is transparently accessible to any I2C 
client driver in the Linux kernel, and thus much of the rest of V4L.


>    6) host loads CX23416 firmware (not a clue)

The CX23416 is not I2C-connected.  Some other kind of control path 
exists between the CX23416 and the FX2.  It is probably a means whereby 
the FX2 can directly peek/poke the CX23416's RAM (there is a static RAM 
next to that part), coupled with an ability to do things like control 
the reset signal to the CX23416.

The pvrusb2 driver loads the '416's firmware basically by resetting the 
chip, doing other various poorly-documented things to the part, and then 
sending the firmware through another USB endpoint set up for the 
purpose.  Take a look at the function pvr2_upload_firmware2() in 
pvrusb2-hdw.c.  You'll also see various calls to pvr2_write_register() 
which implements a sort of access method to an address space within the 
'416.

>    7) host commands CX25840 to select video standard and input source

Yes, via the cx25840.ko kernel module, which in turn operates the chip 
via I2C transfers (see above).


>    8) host commands CX23416 to select MPEG encode profile, bit rate etc.

Yes, via a sort of register-hosted mailbox interface.  This is done in 
pvrusb2-encoder.c.  Operations of the CX23416 are done by sending it 
command words with arguments specific to each command.  These commands 
are written to reigsters related to the CX23416 (with the help of the 
FX2).

In earlier versions of the pvrusb2 driver, the specific commands to be 
sent were constructed by the pvrusb2 driver itself.  However this code 
was combined with similar code from the ivtv driver (and I think another 
driver out there) to form a new V4L module, known as cx2341x.ko.  So all 
the "intelligence" for talking to the '416 is actually in that module 
now.  The pvrusb2 driver still has to implement the handshake to the 
chip (which is unique to the hardware) but nowadays, basically the 
pvrusb2 driver tells cx2341x what it needs then cx2341x issues the 
correct commands which the pvrusb2 driver then feeds into the chip (via 
the FX2).

If you look at the standalone pvrusb2 driver, you can still see the 
older implementation - it's still there for cases where the driver is 
compiled against a very old kernel.  But if the kernel has cx2341x in 
it, the driver will disable its own cx2341x command-forming logic and 
defer instead to the cx2341x module.


>    9) host commands CX23416 to start encoding

Yes.  Same mechanism as (8).


>    10) host fetches buffers of MPEG video using BULK transfers over EP2 or
>    EP6 (?)

Actually, EP4 should be the spigot for streaming in video (search for 
call to "pvr2_stream_setup()" in pvrusb2-hdw.c, where the endpoint is 
passed down to lower level code.  While streaming, the driver 
continuously queues bulk transfer URBs to that endpoint.

Note that commands to the FX2 itself are always done using EP1.  It's a 
pretty simple protocol: You send a command byte followed by some number 
of bytes specific to the command, and then just read back the result.  
All FX2 commands are run this way.  There is a general-purpose function 
in the pvrusb2 driver that implements the host side of this protocol.  
The function name is "pvr2_send_request_ex()" and can be found in 
pvrusb2-hdw.c.  Example commands of this sort include requests for I2C 
data transfer, read/write of cx23416 registers, etc...


>    11) host translates PS to TS, sending output video to FPGA via parallel
>    interface

The pvrusb2 driver currently doesn't do any processing on the received 
stream.  But obviously what you do with the received packets is up to 
you...


>    12) repeat from 10

Yes.  In the case of the pvrusb2 driver, this is done with a pool of 
request URBs, which makes sense since the USB stack in Linux is 
naturally asynchronous.  The pvrusb2 driver always tries to keep some 
minimum number of URBs queued for reception.  Received data is kept in a 
ring buffer until the user application reads out the data - presumably 
to keep the stream running smoothly, the user application will always 
have a read() posted or at least a select() or poll() pending to the 
driver's open device node.  In your PIC environment of course this is 
probably going to be completely different...


>    Notes:
>    13) is BT565 is used as video path between CX25840 to CX23416, if not,
>    then what ?

I believe it is.  I have been told in the past that this is the data 
format used between those two chips, however I've never had (yet) to 
implement anything that relied on this knowledge.  From the viewpoint of 
the pvrusb2 driver, "magic" happens between those two parts :-)


>    14) looks like Linux uses v4l-pvrusb2-73xxx-01.fw (16,384 bytes) to
>    load into FX2

Yes.


>    15) looks like Linux uses v4l-cx25840.fw (16,382 bytes) to load into
>    CX25840

Yes.

>    16) looks like Linux uses v4l-cx2341x-enc.fw (376,836 bytes) to load
>    into CX23416

Yes.


>    Any corrections, pointers to relevant web pages, or other help to start
>    filling in the great voids of understanding will be most appreciated.
>    Many thanks,
>    Mark
>    PS Phew !
> 
> References
> 
>    1. http://www.idesignz.org/DigiLiteZL/DigiLiteZL.htm
>    2. http://www.idesignz.org/DigiLiteZL_FPGA/DigiLiteZL-FPGA.htm

Hope that helps.

  -Mike

-- 

Mike Isely
isely @ isely (dot) net
PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8


More information about the pvrusb2 mailing list