Wednesday August 29, 2007 The joys of cardbus 1394 and the 4-pin connector
A couple months ago, I discovered that 1394 Cardbus adapters just work with Solaris. Well, at least, the cards that I have work with the notebook computers that I have.
Thinking about it, this makes sense. Cardbus is basically a PCI slot in a PCMCIA form factor. And, like most 1394 host adapters, most 1394 Cardbus adapters are based on 1394 OHCI compliant silicon and Solaris has a 1394 OHCI driver, hci1394.
The odd and really unexpected thing is that, in my experience, these 1394 Cardbus adapters have turned out to be more reliable than the built-in 1394 hardware (and/or the 6-to-4 pin adapters that I use).
The problem is the 4-pin 1394 connector. All of the x86/x64 notebook computers in my lab have 4-pin 1394 connectors. It takes up less real estate than the 6-pin connector and it removes the hassle of dealing with implementation of the 1394 power provider/supplier rules, so I can see why company's use it.
However, the 4-pin connector has two big problems. One is that it provides no power for bus-powered devices like IIDC cameras and some hard drives, so one has to connect the device to the computer through something like a powered hub (or the adapter that I use which gets 1394 power from any available USB connector). The other problem is that the 4-pin connector has features that contribute to it being an unreliable connector, such as fingers inside the connector can fatigue and break off and a shape and size that makes it hard to insert the cable into the connector (which can lead to damaged connectors).
This is not to say that there aren't problems using the 6-pin connector. I have a six-port 1394 hub develop four dead ports over time, a three-port 1394 Cardbus adapter develop a dead port in the last month and every MacBook (Titanium) and iMac that has entered my lab left my lab with dead 1394 ports (some had dead ports coming in and others developed them here).
However, aside from the one dead port on my three-port 1394 Cardbus adapter, they have been remarkably dependable. If you are having problems using Solaris with your notebook, I suggest trying a 1394 Cardbus adapter.
( Aug 29 2007, 10:15:35 PM PDT ) Permalink
In a previous blog, I wrote about the demise of the Apple iSight camera and how that was the last consumer grade IIDC camera on the market. However, I was mistaken.
I forgot about the Unibrain Fire-i.
I am not sure why I forgot about it. I worked an IIDC medical camera a few years and we had a Unibrain camera that we used to check what IIDC registers a real device implements, so I knew about them.
Unfortunately, you can't just walk into a store and buy one. Fortunately, there are a lot of online sources.
( Jul 20 2007, 09:27:07 AM PDT ) Permalink
I guess I discovered this back in November, but it didn't sink in until yesterday when a friend asked me if I had one to sell. Apple has silently discontinued the Apple iSight external firewire camera. They continue to brand the USB-based cameras that are integrated into the MacBook laptops and iMac as iSight, but if you want a camera for your Mac Mini or Mac Pro, you can't buy one from Apple anymore. USB alternatives that just plug-and-play with MacOS are available or will be soon, I guess. The story in the Apple Discussions area is that the iSight was discontinued because it contained too much hazardous material (hmmm, don't recall seeing a Proposition 65 notice on the box).
As far as I know, the iSight was the last consumer grade IIDC camera available on the market. The professional grade cameras like the Point Grey Research Dragonfly are still available, so IIDC isn't dead. This is just bad for people who wanted a high-quality, inexpensive IIDC camera. There are obviously unhappy people posting their displeasure in the Apple iSight Discussions area.
This is great for the folks who own iSights, but weren't using them because the cameras are now selling for more than when they were new on eBay. It is not great news for the folks who wanted one and didn't realize that Apple was discontinuing the model. I am sure if you continue to wait, prices will come back down to something sane in short order.
Ironically, I was finally getting around to implementing support for the iSight in the Solaris IIDC camera driver (dcam1394). Good thing for iSight fans that I didn't start implementing it sooner.
( Feb 07 2007, 04:06:46 AM PST ) Permalink
DCAM1394_CMD_PARAM_GET vs. DCAM1394_CMD_REG_READ
The Solaris dcam1394 driver allows access to an IIDC camera's control command registers (which I will abbreviate as IIDC registers) through two different methods.
One method is through the DCAM1394_CMD_PARAM_GET and DCAM1394_CMD_PARAM_SET ioctls (which I will abbreviate as PARAM_GET/SET). Under this method, the ioctls provide an abstraction for the IIDC camera's parameters (as well as some driver parameters). The parameters supported by this abstraction are documented in the dcam1394 man page.
The other method is through the DCAM1394_CMD_REG_READ and DCAM1394_CMD_REG_WRITE ioctls (which I will abbreviate as REG_READ/WRITE). Under this method, each IIDC register is individually accessed by the application. This requires detailed knowledge of the IIDC register set.
How do you use these ioctls?
For PARAM_GET/SET, refer to the blog that I wrote last year on the topic.
For REG_READ/WRITE, the application passes the IIDC register's offset (and, if writing, the value to write) to the driver through the ioctl. This is what code that does this might look like:
/* dcamctl_fd is the file descriptor from opening /dev/dcamctl */
dcam1394_reg_io_t cam_reg;
cam_reg.offs = 0x100; /* inquiry register for video format */
if (ioctl(dcamctl_fd, DCAM1394_CMD_REG_READ, &cam_reg) == -1) {
perror("reading the video format inquiry register failed");
}
printf("video formats supported:\n");
if (cam_reg.val & 0x01)
printf("vga uncompressed format\n");
if (cam_reg.val & 0x02)
printf("svga uncompressed 1 format\n");
if (cam_reg.val & 0x04)
printf("svga uncompressed 2 format\n");
if (cam_reg.val & 0x40)
printf("still image format\n");
if (cam_reg.val & 0x80)
printf("scalable image size format\n");
Why would you want to choose one over the other?
The obvious reason to choose the PARAM_GET/SET ioctls is that their use is documented in one place. The ioctls and the complete set of parameters that one can access through them are described in the dcam1394(7d) man page. Another reason is that, if the application needs to access a large number of parameters, PARAM_GET/SET are much more efficient interfaces.
The reasons not to choose PARAM_GET/SET are also the reasons to choose REG_READ/WRITE instead. For starters, the parameters that are available through PARAM_GET/SET were determined based on the first version of the IIDC spec (1.04). Additional parameters have been added to newer versions of the IIDC spec. Those parameters are not available through PARAM_GET/SET and are available through REG_READ/WRITE. Also, the PARAM_GET/SET interfaces have a lot of overhead when used to access a single parameter. On the other hand, the REG_READ/WRITE interfaces are very simple to use to access a single parameter.
The disadvantage of REG_READ/WRITE is that they require familiarity with the IIDC register set. The IIDC specifications are available from the 1394 Trade Association. Alternately, a simple Google search can be used to find a copy of the specification. Yet another alternative is the device specification from the manufacturer of the camera that you have (such as the manual for the Sony XCD-910 line of cameras).
While the big advantage of REG_READ/WRITE is that they can be used to handle devices that were implemented to newer versions of the IIDC spec (or to handle vendor-specific features), this is not sufficient for controlling all IIDC cameras.
The dcam1394 driver does not read the configuration ROM to determine the base address for the IIDC registers. Instead, it uses the base address that is used by most of the IIDC cameras on the market. Unfortunately, an example of a camera that uses a different base address is the most common, consumer-grade IIDC camera on the market, the Apple iSight (though Apple seems to be phasing it out, hence no link here). Also, the Solaris device discovery mechanism (/etc/driver_aliases) has only been set-up to attach the dcam1394 driver with a camera that claim to be a IIDC 1.04 device. To have Solaris attach the dcam1394 driver to cameras that claim to implement a newer version of the IIDC spec, the driver_aliases file needs to be updated so that there is an entry with spec_id and sw_version_id values that correspond to the version that the camera claims to support. Fortunately, the IIDC specs are backwards compatible.
Note that an application cannot completely depend on one of these sets of interfaces to control an IIDC camera. For example, the DCAM1394_CMD_FRAME_RCV_START and DCAM1394_CMD_FRAME_RCV_STOP ioctls (used to start and stop isochronous data transfers) require synchronization between the internal state of the dcam1394 driver with accessing the IIDC registers, so these accesses are done automatically. Also, some of the parameters that are accessed through PARAM_GET/SET are driver parameters, not IIDC parameters, so have to be accessed through PARAM_GET/SET.
I think that's it.
( Jan 12 2007, 02:12:21 AM PST ) Permalink
Back in January, I had big plans to do regular, technical blogs about IEEE 1394 in Solaris. This started off with plans for a series of blogs describing the Solaris API for accessing 1394-based web- and industrial-cameras (IIDC devices) through the dcam1394 driver. Unfortunately, as I was writing part 2 in that series, I discovered an apparent bug in the dcam1394 driver that affected the sample code that I intended to use to illustrate the APIs.
I had to determine the root cause and then fix that bug. However, while in the middle of doing that, some higher priority work came up and then some other stuff even more important stuff came up and then some stuff even more important than that came up.
Now, those other things are now mostly cleared out of the way and, while I still haven't fixed that dcam bug, now I can get back to blogging about 1394. Not only that, but I have had to get a better understanding of some areas of the Solaris 1394 support that I didn't understand as well as I should have in January, so the technical content of my blogs should be better.
So, in a couple of days, look for a write-up on how to use DCAM1394_CMD_REG_READ and DCAM1394_CMD_REG_WRITE to get more from your industrial camera than you can with DCAM1394_CMD_PARAM_GET and DCAM1394_CMD_PARAM_SET.
( Sep 05 2006, 12:45:00 AM PDT ) Permalink
Part 2 of the Writing 1394 Digital Camera Apps is coming
Just wanted to note that part 2 of my blog on Writing Solaris apps for 1394-based Digital Cameras is coming, though a little later than intended. It will explain how to set up the isochronous end of things and how to read video frames from the camera. There will also be a part 3 where I explain the interface for directly accessing the camera's registers.
In the process of writing the blog, I discovered that some sample code that I had been handing out for the last nine months is wrong and I need to correct it. Then I have to check my blog against it. Then I can post the blog.
But it is coming!
( Jan 17 2006, 10:18:00 AM PST ) Permalink
Writing Solaris apps for 1394-based digital cameras
Since Solaris Express 8/05, support for 1394-based digital cameras (also referred to as IIDC cameras) has been available in Solaris for SPARC and x86/x64. This support includes a public software interface to allow applications that use these cameras to be developed.
Actually, this support has been available on SPARC for some time. However, it was intended as part of a Sun video package that used a particular piece of hardware that is no longer available. Also, the software interface to that driver was not a public interface.
These cameras generally fall into one of two categories. At the low end are inexpensive web-cam devices, such as the (now defunct) Orange Micro iBot and the Apple iSight. At the high end are industrial cameras, such as devices from PixelLINK and Sony. These cameras implement the 1394-based Digital Camera Specification (later called the IIDC specification) from the 1394 Trade Association.
The driver in Solaris that deals with this class of devices is dcam1394 (referred to as dcam in this discussion). It currently supports the 1.04 version of the IIDC specification. Work is underway to enhance it to support the latest version of the specification. Unfortunately, the Apple iSight camera will not work with Solaris until this work has been completed.
When a dcam device is connected to the 1394 bus on a system running Solaris, there are two device files created for each instance of the device. /dev/dcamctlinstance is used to control the camera (the control device) and /dev/dcaminstance is used to read video frames from the camera (the streaming device).
Control of the camera is done through IOCTLs sent to the control device file. The ioctls and the data strutures that are passed to them are listed in the header file sys/dcam/dcam1394_io.h and you should include this file in your application.
There are three different types of control operations - simple camera operations, accessing camera registers directly and setting and querying camera parameters.
Most of the simple camera operations are involved with reading video frames from the camera, so I will defer that topic to the discussion of the streaming device. Also, directly accessing camera registers is not the preferred method of camera control, so I will defer discussion as well.
Setting and querying camera parameters is done in a manner that is a little awkward for accessing one parameter at a time, but very handy for accessing several at once. You allocate a parameter list, enable the parameters that you care about, assign new values to parameters (if setting values), pass the parameter list to the driver through an IOCTL and access the values read from the camera (if getting values).
What does this look like in C code? This is how you would read a parameter.
/* dcamctl_fd is the file descriptor from opening /dev/dcamctl */
int current_video_mode; /* video mode from camera */
dcam1394_param_list_t param_list;
PARAM_LIST_INIT(param_list);
PARAM_LIST_ADD(DCAM1394_PARAM_VID_MODE, DCAM1394_SUBPARAM_NONE);
if (ioctl(dcamctl_fd, DCAM1394_CMD_PARAM_GET, param_list) == -1)
fprintf(stderr, "cannot get video mode\n")
current_video_mode = PARAM_VAL(param_list, DCAM1394_PARAM_VIDEO_MODE,
DCAM1394_SUBPARAM_NONE);
This is how you would set a parameter:
/* dcamctl_fd is the file descriptor from opening /dev/dcamctl */
int new_video_mode = 1; /* new video mode for the camera */
dcam1394_param_list_t param_list;
PARAM_LIST_INIT(param_list);
PARAM_LIST_ADD(DCAM1394_PARAM_VID_MODE, DCAM1394_SUBPARAM_NONE);
PARAM_VAL(param_list, DCAM1394_PARAM_VIDEO_MODE, DCAM1394_SUBPARAM_NONE) =
new_video_mode;
if (ioctl(dcamctl_fd, DCAM1394_CMD_PARAM_SET, param_list) == -1)
fprintf(stderr, "cannot set video mode\n")
This is how you would set multiple parameters at once:
/* dcamctl_fd is the file descriptor from opening /dev/dcamctl */
int new_video_mode = 1; /* new video mode for the camera */
int new_frame_rate = 2; /* new frame rate for the camera */
int new_exposure = 128; /* new exposure value for the camera */
dcam1394_param_list_t param_list;
PARAM_LIST_INIT(param_list);
PARAM_LIST_ADD(DCAM1394_PARAM_VID_MODE, DCAM1394_SUBPARAM_NONE);
PARAM_LIST_ADD(DCAM1394_PARAM_FRAME_RATE, DCAM1394_SUBPARAM_NONE);
PARAM_LIST_ADD(DCAM1394_PARAM_EXPOSURE, DCAM1394_SUBPARAM_VALUE);
PARAM_VAL(param_list, DCAM1394_PARAM_VIDEO_MODE, DCAM1394_SUBPARAM_NONE) =
new_video_mode;
PARAM_VAL(param_list, DCAM1394_PARAM_FRAME_RATE, DCAM1394_SUBPARAM_NONE) =
new_frame_rate;
PARAM_VAL(param_list, DCAM1394_PARAM_EXPOSURE, DCAM1394_SUBPARAM_VALUE) =
new_exposure;
if (ioctl(dcamctl_fd, DCAM1394_CMD_PARAM_SET, param_list) == -1)
fprintf(stderr, "cannot set video mode\n")
For a list of parameters that you can access, refer to the dcam1394_io.h header file or the dcam1394(7D) man page as well as the IIDC specification or the documentation for your camera.
In a few days, I will describe how to read video frames from the camera.
( Jan 11 2006, 09:35:00 PM PST ) Permalink Comments [3]
Firewire in Solaris: The Good, The Bad and The Ugly
I figured that I would start 2006 by finally writing about Firewire/1394 support in Solaris. Some of you might not even know the current state of Firewire in Solaris, so here it is. The good, the bad and the ugly.
The Good
As of Solaris 10, the following 1394 device classes (along with the corresponding driver) are supported: mass storage devices (scsa1394) and camcorders and other AV/C devices (av1394). Also, Firewire host adapters that follow the 1394 OHCI (hci1394) are supported. All of this is supported on SPARC, x86 and x64 platforms.
Support for 1394-based digital cameras/IIDC devices (through the dcam1394 driver) has been available for SPARC since Solaris 9. Support on the x86 and x64 platforms is now available in Solaris Express (as 8/05) and will be available in an update release of Solaris 10 soon. Also, the software interfaces for the dcam1394 driver are now supported public interfaces.
All of the source code for the Solaris Firewire support is available through OpenSolaris, include the 1394 Software Framework (s1394) and the SBP-2 support (sbp2) modules.
The Bad
While most of the Solaris Firewire support worked fine, there are bugs. If you try and use certain Firewire hard drives or DVD burners or if you try to unload the host adapter driver on some hardware, your system may panic. Fortunately, these problems have been resolved and the fixes are available in Solaris Express.
Also, the dcam1394 driver only supports the camera features described in version 1.04 of the 1394 Trade Association's 1394-based Digital Camera Specification. This means that it does not support one of the most commonly available 1394 Digital Cameras out there, the Apple iSight.
Also, there are some Firewire features and devices that are not fully supported, such as 1394b and pro audio (IEC 61883-6). Also, while the software interfaces for customer written Firewire drivers and applications are available through OpenSolaris, aside from the dcam1394 driver, none of these interfaces are supported public interfaces.
The Ugly
Some of the Solaris Firewire support is really broken. The worst example of this is the av1394 driver. It has a number of odd bugs, but, most embarrassingly, it cannot do isochronous transfers on x86. I did the x86 port, so it is my fault.
Fortunately, most of the issues described above are either being actively worked on or have kind of fix available once I get to them.
If you have interest in the Firewire support in Solaris, let me know. I am always looking for feedback.
( Jan 02 2006, 11:30:00 AM PST ) Permalink Comments [2]
75% better disk performance from a Firewire disk over an internal disk?
This says absolutely nothing about Sun's implementation of Firewire support. And it probably says more about Apple's implementation of the Mac Mini that it does about Firewire disks. However ...
Slashdot passed on the tale of a Mac Mini owner who benchmarked a drive in a Firewire enclosure with 75% better performance over the Mac's internal drive. I find that amazing.
( May 17 2005, 03:13:42 PM PDT ) Permalink Comments [2]