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 _______________________________________________ pvrusb2 mailing list [email protected] http://www.isely.net/cgi-bin/mailman/listinfo/pvrusb2
