Friday, November 8, 2013

XiCam Tech Issues

I decided to give up on my so called "XiCam" project.  The end goal was to control a digital camera via USB from a laptop or Android tablet.  When I first attached my camera to my notebook, it appeared that the drivers would only treat the camera as a mass-storage device.  When attached to a Windows computer, however, a window pops up asking for permission to install Samsung's Intelli-Studio program, which apparently includes the capability to update new firmware to the attached camera.  This told me two things: 1) There is more information which can be received from the camera than appears from Linux systems and 2) the capability exists to update firmware from a host PC.

However, even if I managed to get the firmware from the camera, there is still no guarantee that I'll be able to understand it once I've disassembled the code.  And even after spending the effort in figuring it out, then I may still not be able to hack it to control exposure time or trigger the camera via USB.  I decided I was better off, for my own sanity, to just buy a different camera when I'm ready to take pictures at that level.

It turns out, without any special settings or using my home made mounting bracket, I can still get decent pictures.  Here's a picture I took of Jupiter this morning:

Tuesday, November 5, 2013

USB Protocol

When you plug a USB device into a port on your computer (aka the "host"), the hardware signals the USB host controller that a new device has been attached.  The host controller then sends a command to the newly attached device via the default endpoint in an attempt to find out what the device is (vendor ID, product ID, product type, etc.).  Then it decides what drivers need to be used to work with that device.

I had originally thought, based on the simple configuration, that the only features available to control via USB was access to the data on the flash drive.  I now believe that this is simply how the driver treats the device.  If I were running Windows, I would be prompted to install the Intelli-Studio software, which is apparently built into the device.  If I ever wanted to update the firmware, I would have to do that through Intelli-Studio.  This means two things.  First, the capability to grab software from the camera exists.  Second, the capability to replace the camera firmware via USB also exists.

Just as before, I monitored the USB debugging data from port 2 by issuing the command:

$ sudo cat /sys/kernel/debug/usb/usbmon/2u > bus2data.txt
in one terminal window and,
$ tail -f bus2data.txt
in another. I plugged the camera into the USB port, but no messages were produced until I actually turned the camera on.

The first group of messages appear to be communication between the host controller and the USB port hub,

ffff880137cc2840 2476103001 S Ci:2:000:0 s 80 06 0100 0000 0040 64 <
ffff880137cc2840 2476103172 C Ci:2:000:0 0 18 = 12010002 00000040 e8040613 00000102 0301
The term "Ci:2:000:0" translates to "Input control packet to USB bus 2, device zero, endpoint zero". Eventually I start getting USB events like this,
ffff880137cc2840 2476234892 S Ci:2:007:0 s 80 06 0100 0000 0012 18 <
ffff880137cc2840 2476235047 C Ci:2:007:0 0 18 = 12010002 00000040 e8040613 00000102 0301
This submission/callback pair is the device telling the host controller what it is. The first byte is length (0x12=18 bytes), the next is bDescriptorType (0x01=1), USB minor and major version (0x00, 0x02 or "2.0"), The next word contains the device class (0x00), subclass (0x00), protocol (0x00) and maxPacketSize (0x40=64 bytes). The next word contains the vendor and product ID numbers (0x04e8 = Samsung, 0x1306 = ST100 digital camera). Then comes device version (minor, major, in this case 0.0), manufacturer (the '1' here means SAMSUNG, though I'm not sure yet how the USB host controller knows this) and the '2' designates that it is a digital camera. The 3 indicates the serial number. These must be pointers to information strings or something like that. Finally, the '0x01" at the end tells the number of device configurations that are available.

The next submission/callback pair describes the first (and only) configuration.

ffff880137cc2840 2476235204 S Ci:2:007:0 s 80 06 0200 0000 0009 9 <
ffff880137cc2840 2476235293 C Ci:2:007:0 0 9 = 09022000 010100c0 00
which corresponds to this:
 Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA

The next pair is the first (and only) interface,

ffff880137cc2840 2476235412 S Ci:2:007:0 s 80 06 0200 0000 0020 32 <
ffff880137cc2840 2476235547 C Ci:2:007:0 0 32 = 09022000 010100c0 00090400 00020805 50000705 02020002 00070582 02000200
which corresponds to this:
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      5 SFF-8070i
      bInterfaceProtocol     80 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
So what happened to endpoint one? And what does this mean?
ffff880137cc2840 2476235709 S Ci:2:007:0 s 80 06 0300 0000 00ff 255 <
ffff880137cc2840 2476235792 C Ci:2:007:0 0 4 = 04030904
ffff880137cc2840 2476235826 S Ci:2:007:0 s 80 06 0302 0409 00ff 255 <
ffff880137cc2840 2476235917 C Ci:2:007:0 0 48 = 30035300 61006d00 73007500 6e006700 20004400 69006700 69007400 61006c00
ffff880137cc2840 2476235936 S Ci:2:007:0 s 80 06 0301 0409 00ff 255 <
ffff880137cc2840 2476236042 C Ci:2:007:0 0 20 = 14035300 41004d00 53005500 4e004700 20002000
ffff880137cc2840 2476236055 S Ci:2:007:0 s 80 06 0303 0409 00ff 255 <
ffff880137cc2840 2476236167 C Ci:2:007:0 0 28 = 1c034500 30003000 30003000 30003000 30003000 30003000 32002000
ffff880137cc2a80 2476236645 S Co:2:007:0 s 00 09 0001 0000 0000 0
ffff880137cc2a80 2476236792 C Co:2:007:0 0 0
ffff8801122bfc00 2477238949 S Ci:2:007:0 s a1 fe 0000 0000 0001 1 <
ffff8801122bfc00 2477260196 C Ci:2:007:0 0 1 = 01
0x30=decimal 48, 0x03=index 3, 0x53='S', 0x61='a', 0x6d='m', 0x73='s', 0x75='u', 0x6e='n', 0x67='g', 0x20=' ', 0x44='D', 0x69='i', 0x67='g', 0x69='i', 0x74='t', 0x61='a', 0x6c='l'
0x14=decimal 20, 0x03=index 3, 0x53='S', 0x41='A', 0x4d='M', 0x53='S', 0x55='U', 0x4e='N', 0x47='G', 0x20=' ', 0x20=' '
0x1c=decimal 28, 0x03=index 3, 0x45='E', 0x30='0', 0x32='2', 0x20=' '
So these must be the info strings, although the string "camera" doesn't show up. The first byte must be the string size in bytes (wide char format), the second byte the number of info strings, in this case '3', then the actual strings ("Samsung Digital", "SAMSUNG ", and "E00000000002 ").

Sunday, November 3, 2013

XiCam Assembly

There are two parts to this project. One was developing a device driver to run my digital camera from my tablet. This is likely a fools errand, but you can't succeed unless you try, right? The other, far simpler, part is to build a structure that holds the camera lens fixed against the telescope eyepiece. The assembly in the pictures cost me about $9 from The Home Depot. It consists of a 2"x5" joiner plate (Simpson TP15). It's thin, but fairly rigid. I drilled holes for a 1/4" machine screw (I suppose this is fairly standard for mounting cameras to a tripod) and a 3/8" screw. I held the plate steady by hand, and nearly slit my wrist when the drill passed through and the plate spun loose. So be wise: use a clamp if you try this. I used a 1" long machine screw with nut and locking washer to hold the camera in place. I used a 3" hex bolt with nuts and standard washers (the lock washers tend to tilt the bolt unless you really tighten it). The bolt feeds into a 1" pipe clamp, which happens to fit the eyepiece perfectly. It does not, however, fit around the larger eyepiece, which I think might be more useful due to the wider field of view.

I was tinkering around with the built-in exposure and ISO settings. The ST100 allows up to ST3200 and uses an exposure scale of -2 to 2 (I don't really know what that means. Could it be a multiplier for integration time?). The first picture I took the other night. It was fairly overcast, and we get a lot of light pollution around here. I used exposure setting "zero" (for "auto") and ISO 3200. The second picture is Vega, taken last night using my medieval eyepiece attachment device. The high magnification makes vibrations even more annoying, so I will certainly need to get a larger clamp so I can use the lower magnification, larger FOV eyepiece.


Getting USB Debugging Info from the Linux Command Line.

Not ready to give up on this just yet. Having a closer look at the command line tools that are available.
seans@snowpack:~$ sudo lsusb -v

...

Bus 002 Device 005: ID 04e8:1306 Samsung Electronics Co., Ltd 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x04e8 Samsung Electronics Co., Ltd
  idProduct          0x1306 
  bcdDevice            0.00
  iManufacturer           1 SAMSUNG  
  iProduct                2 Samsung Digital Camera 
  iSerial                 3 E00000000002 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      5 SFF-8070i
      bInterfaceProtocol     80 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0001
  Self Powered
Ubuntu has a USB debugging feature, which on my installation was running automatically. You can monitor the communication on the various USB buses by,
seans@snowpack:~$ sudo cat /sys/kernel/debug/usb/usbmon/2u > bus2data.txt
Here's a sample of the output,
ffff88009bf78240 752186120 S Bo:2:005:2 -115 31 = 55534243 18070000 08000000 80010c4a 01000010 00000008 00000000 000000
ffff88009bf78240 752186154 C Bo:2:005:2 0 31 >
ffff880062803c00 752186180 S Bi:2:005:2 -115 8 <
ffff880062803c00 752186403 C Bi:2:005:2 -32 0
ffff88009bf78240 752186412 S Co:2:005:0 s 02 01 0000 0082 0000 0
ffff88009bf78240 752186527 C Co:2:005:0 0 0
ffff88009bf78240 752186548 S Bi:2:005:2 -115 13 <
ffff88009bf78240 752207425 C Bi:2:005:2 0 13 = 55534253 18070000 08000000 01
ffff88009bf78240 752207452 S Bo:2:005:2 -115 31 = 55534243 19070000 12000000 80010c03 00000012 00000000 00000000 000000
ffff88009bf78240 752207652 C Bo:2:005:2 0 31 >
ffff880062803c00 752207718 S Bi:2:005:2 -115 18 <
ffff880062803c00 752207778 C Bi:2:005:2 0 18 = 70000500 0000000a 00000000 20000000 0000
ffff88009bf78240 752207788 S Bi:2:005:2 -115 13 <
ffff88009bf78240 752207901 C Bi:2:005:2 0 13 = 55534253 19070000 00000000 00
ffff88009bf78240 752698083 S Bo:2:005:2 -115 31 = 55534243 1a070000 00000000 00000c00 00000000 00000000 00000000 000000
ffff88009bf78240 752698157 C Bo:2:005:2 0 31 >
ffff88009bf78240 752698391 S Bi:2:005:2 -115 13 <
ffff88009bf78240 752698527 C Bi:2:005:2 0 13 = 55534253 1a070000 00000000 00
ffff88009bf78240 754234230 S Bo:2:005:2 -115 31 = 55534243 1b070000 08000000 80010c4a 01000010 00000008 00000000 000000
ffff88009bf78240 754234295 C Bo:2:005:2 0 31 >
ffff8801380f9f00 754234315 S Bi:2:005:2 -115 8 <
ffff8801380f9f00 754234415 C Bi:2:005:2 -32 0
ffff88009bf78240 754234438 S Co:2:005:0 s 02 01 0000 0082 0000 0
ffff88009bf78240 754234528 C Co:2:005:0 0 0
ffff88009bf78240 754234540 S Bi:2:005:2 -115 13 <
ffff88009bf78240 754255617 C Bi:2:005:2 0 13 = 55534253 1b070000 08000000 01
ffff88009bf78240 754255664 S Bo:2:005:2 -115 31 = 55534243 1c070000 12000000 80010c03 00000012 00000000 00000000 000000
ffff88009bf78240 754255906 C Bo:2:005:2 0 31 >
ffff880132d0b3c0 754255925 S Bi:2:005:2 -115 18 <
ffff880132d0b3c0 754256032 C Bi:2:005:2 0 18 = 70000500 0000000a 00000000 20000000 0000
ffff88009bf78240 754256047 S Bi:2:005:2 -115 13 <
ffff88009bf78240 754256155 C Bi:2:005:2 0 13 = 55534253 1c070000 00000000 00
I still don't understand some of the intermediate messages, but I found a resource that explains a couple of them. I made this legend from the description on that webpage.
The upshot is that there seems to be a means to send a variety of commands over the same "configuration". However, I haven't been able to find any resource that describes the commands and arguments that would be recognized by the device. I thought about just sending 256 different command signals to see what comes back, but I think I'd risk sending a factory reset signal or something that might render the camera useless. I'd rather have a camera that doesn't do everything I want but works than have no camera at all.

Saturday, November 2, 2013

Okay, so maybe I'm a glutton for punishment or just dumb. But I decided I didn't like the Windows installation after all. Mainly because I didn't feel like dealing with the "bonus" software and the friendly reminders to register for software I haven't used in four years. Also, I think trying to run Ubuntu in a VM was a little too much to ask for the HP. Long story short, I reinstalled Ubuntu 12.04 and made a promise to myself that I wouldn't try to install (or uninstall) any packages related to the USB.
Side note: I could have installed an earlier version of Eclipse using apt-get, but I wanted to go with the Kepler edition, so I downloaded the tarball instead. After installing the Android SDK, I was surprised to find that adb wasn't working. I kept getting file not found errors, even though I could clearly see it was there. Problem was I didn't have 32-bit executable support installed yet. Ran apt-get intall ia32-libs, which installed a whole bunch of crap. But this did, in fact, solve the problem.
Back to business. At first glance it doesn't look like I'll be able to control the camera at the level I want, at least from the USB. Here's what I get from the command line:
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 003: ID 090c:137b Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) 
Bus 005 Device 002: ID 046d:c52f Logitech, Inc. Wireless Mouse M305
Bus 002 Device 004: ID 04e8:1306 Samsung Electronics Co., Ltd 
seans@snowpack:~$ sudo cat /sys/kernel/debug/usb/devices

...

T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  4 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=04e8 ProdID=1306 Rev= 0.00
S:  Manufacturer=SAMSUNG  
S:  Product=Samsung Digital Camera 
S:  SerialNumber=E00000000002 
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=05 Prot=50 Driver=usb-storage
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

...
(note: I removed all the extra crap related to the host controllers and USB mouse). A more experienced eye might see something else. But what I see is that I'll only be able to access files through USB.  I need to do a little research to see exactly what each term means, but I believe "T" designates a device, either root hub or hardware device, "D" designates the USB version, number of available configurations and a few other things I don't know.  I get the vendor number and product ID, but I don't understand "Rev" (revision?  if so, why zero?).  "S" must designate some generic string descriptor.  I don't believe the serial number that's given there.  "C" seems to designate the start of a specific configuration, not sure what the asterisk is for.  "#Ifs is the number of sub-configurations, in this case there's just the one.  "I" indicates the sub-configuration and "E" are endpoints.  This allows one input (I) and one output (O) bulk endpoint, designed for transferring large amounts of data.  Seems like this device is configured at "full speed" (480 MBps).<p>

 I did some searching on the interwebs and found that, at least for other digital cameras, any "hacking" of the firmware had to be done via memory chip. I can see how this might work for this camera, since it does seem to do some check of the SD chip when turning it on. As of now there's no firmware provided for this particular model, but I'll keep my eyes peeled.

Friday, November 1, 2013

Getting Basic Information from a USB Device

Top-level stuff (no code required)
From command line:
[strattonsr@bishop]$ lsusb

gives manufacturer ID : product ID and one-line description

[strattonsr@bishop]$ cat /sys/kernel/debug/usb/devices

gives more detailed info about device configurations

sample

T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 2
P: Vendor=04e8 ProdID=6860 Rev= 4.00
S: Manufacturer=SAMSUNG
S: Product=SAMSUNG_Android_SCH-I535
S: SerialNumber=d6190436
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 96mA
I:* If#=0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=(none)
E: Ad=81(I) Atr=02(Bulk) MsPS= 512 Ivl=0ms
E: Ad=01(O) Atr=02(Bulk) MxPS=512 Ivl=125us
E: Ad=82(I) Atr=03(Int.) MxPS= 28 Ivl=4ms
C: #Ifs Cfg#= 2 Atr=c0 MxPwr= 96mA
A: FirstIf#= 1 IfCount= 2 Cls=02(comm.) Sub=02 Prot=01
I: If#= 0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=125us
E: Ad=82(I) Atr=03(Int.) MxPS=  28 Ivl=4ms
I: If#= 1 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=
E: Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I: If#= 2 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=
E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms