Wednesday, November 3, 2010

I2C level shifing

I couldn't get the off the shelf level translator (I2C-TRN) to work. I followed the instructions and removed the 3V3 jumper, and wired it up according to the instructions - but the IC on the board was getting REALLY hot (fried my finger tip) and there was > 3V on the "low side" SCL/SDA lines - which should have only been 1.8V max! I was concerned that I fried the BeagleBoard I2C I/O's (but fortunately they were OK).

I emailed support@gravitech.us asking for assistance with the I2C-TRN, but never got a response.

So, I instead of using the I2C-TRN, I opted to build an I2C level translator using 2 MOSFETs. I followed the Philips App Note AN7055, using (2) ZVN4424A/C thru-hole MOSFETs ordered from Digikey for about $1 each. The App Note was very clear and the design is simple and makes perfect sense.

This worked perfectly - the levels on both sides for logic 1 and 0 looked good, and I could immediately probe the bus and see the digital pot:

$ sudo i2cdetect -y -r 2
[sudo] password for mikevoyt:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- 28 -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Reading the pot 0 value worked:

$ i2cget -y 2 0x28
0x00

Writing a new value for pot 0 worked as well:
$ i2cset -y 2 0x28 0xa9 0x80
$ i2cget -y 2 0x28
0x80

And, indeed the resistance between L0 and W0 went from a few hundred ohms to 5K ohm.

Friday, October 22, 2010

momentary contact switch via an opto relay

We need to interface to another piece of equipment, which expects a momentary contact switch input.

I chose a Panasonic AQY212EH PhotoMos for this purpose. It's an optically isolated relay in a 4-pin DIP package.

I simply connected a BeagleBoard GPIO output to pin 1 through a 130 ohm resistor; and grounded pin 2. Then pins 3 and 4 can simulate a pushbutton. i.e., when the BeagleBoard output is driven high we have a closed circuit on pins 3-4 (about 1 ohm resistance); and when the BeagleBoard output is driven low, we've got an open circuit.

Simple, cheap, and it optically isolates the BeagleBoard from the external equipment.

I2C digital potentiometer

We need to control a valve from the BeagleBoard, which requires a 1-5V DC signal to actuate the valve from fully open to fully closed linearly.

I chose a digital potentiometer for this - the Maxim DS1803. The nice thing about this part is:
1) It's a DIP
2) It can be controlled via I2C
3) It can handle 5V across the resistor, perfect for our application.

Unfortunately this part will require a level translator, because a logic high is 0.7*Vcc = 3.5V. (We need Vcc to be 5V, since we'll be putting 5V across the resistor).

I couldn't find any DIP IC's for 1.8V <-> 5V level translation, and don't particularly want to hand solder surface mount parts, so I ordered a pre-fabbed level converter, the I2C-TRN, which uses a PCA9306 level shifter:

http://store.gravitech.us/dubii2cvotr.html

I found some on eBay for $13.50 in stock ready to ship.

I 've also prepared by soldered up a socket on a breadboard for the DS1803, and rebuilt the Ubuntu kernel so that the BeagleBoard should be ready to talk I2C on the expansion header pins 23 and 24.

enabling I2C on expansion header

I'd like to communicate with an I2C digital potentiometer (Maxim DS1803), using the I2C bus on the expansion header (pins 23 and 24). However, the only i2c busses that show up are 1 and 3, while the expansion header bus should be 2:

$ i2cdetect -l
i2c-1 unknown OMAP I2C adapter N/A
i2c-3 unknown OMAP I2C adapter N/A


I made the following change to the kernel to enable i2c-2:

1) in .config, set CONFIG_OMAP_MUX=y

2) in arch/arm/mach-omap2/board-omap3beagle.c, make these changes:

a) in omap3_beagle_i2c_init(), add:
omap_register_i2c_bus(2, 400, NULL, 0);

b) in board_mux[], add:
static struct omap_board_mux board_mux[] __initdata = {
OMAP3_MUX(I2C2_SCL, OMAP_MUX_MODE0),
OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE0),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};

Now rebuild the kernel, copy it to the SD card, and reboot; and now we can see the bus:

$ i2cdetect -l
i2c-1 unknown OMAP I2C adapter N/A
i2c-3 unknown OMAP I2C adapter N/A
i2c-2 unknown OMAP I2C adapter N/A

$ sudo i2cdetect -F 2
Functionalities implemented by /dev/i2c-2:
I2C yes
SMBus Quick Command no
SMBus Send Byte yes
SMBus Receive Byte yes
SMBus Write Byte yes
SMBus Read Byte yes
SMBus Write Word yes
SMBus Read Word yes
SMBus Process Call yes
SMBus Block Write yes
SMBus Block Read no
SMBus Block Process Call no
SMBus PEC yes
I2C Block Write yes
I2C Block Read yes

And nowwe should be able to scan the bus - with the DS1803 on the bus we see:

sudo i2cdetect -y -r 2
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- 28 -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Wednesday, October 20, 2010

new camera

I chose a USB 400X digital microscope instead of a standard webcam for the new camera:

http://www.dealextreme.com/details.dx/sku.41844~r.27613104

I saw some sites refer to this as the "Oasis UMO19 MCU003". This is a US2.0 device and also supports multiple Isochronous streaming video endpoints, AND is a UVC device:
http://randomprojects.org/wiki/Oasis_UMO19_MCU003_USB_microscope

Here's someone's evaluation of this camera:
http://www.stealthcopter.com/blog/2010/09/photos-with-my-new-usb-microscope-20x-400x-1-3mp-digital-microscope/

In order to sample from both simultaneously, I had to enable the quirks module option - I made this happen automatically at boot time by adding a file called /etc/modprobe.d/uvcvideo.conf with the following line:
options uvcvideo quirks=0x80

Also, I couldn't stream from both cameras simultaneously at 640x480 30 frames/sec - I had to drop the frame size down to 352x288 in order to avoid the "Unable to start capture: No space left on device"

One other note - by default, this camera would automatically throttle the framerate depending on the lighting. For example, in dark lighting I'd only get about 6 frames/sec.

I toggled the "Exposure, Auto Priority" switch in GUVCVideo, and it turned off this "feature". And, it looks to be persistent - even after unplugging/rebooting, the camera still now does about 30 frames/sec regardless of lighting.

For reference, here's some more info about this camera:
$ udevadm info -q all -n /dev/video0
P: /devices/platform/ehci-omap.0/usb1/1-2/1-2.5/1-2.5:1.0/video4linux/video0
N: video0
S: char/81:0
S: v4l/by-id/usb-Vimicro_Co._ltd_Vimicro_USB2.0_UVC_PC_Camera-video-index0
S: v4l/by-path/platform-ehci-omap.0-usb-0:2.5:1.0-video-index0
E: UDEV_LOG=3
E: DEVPATH=/devices/platform/ehci-omap.0/usb1/1-2/1-2.5/1-2.5:1.0/video4linux/video0
E: MAJOR=81
E: MINOR=0
E: DEVNAME=/dev/video0
E: SUBSYSTEM=video4linux
E: ID_V4L_VERSION=2
E: ID_V4L_PRODUCT=Vimicro USB2.0 UVC PC Camera
E: ID_V4L_CAPABILITIES=:capture:
E: ID_VENDOR=Vimicro_Co._ltd
E: ID_VENDOR_ENC=Vimicro\x20Co.\x2cltd
E: ID_VENDOR_ID=0ac8
E: ID_MODEL=Vimicro_USB2.0_UVC_PC_Camera
E: ID_MODEL_ENC=Vimicro\x20USB2.0\x20UVC\x20PC\x20Camera
E: ID_MODEL_ID=3610
E: ID_REVISION=0100
E: ID_SERIAL=Vimicro_Co._ltd_Vimicro_USB2.0_UVC_PC_Camera
E: ID_TYPE=video
E: ID_BUS=usb
E: ID_USB_INTERFACES=:0e0100:0e0200:
E: ID_USB_INTERFACE_NUM=00
E: ID_USB_DRIVER=uvcvideo
E: ID_PATH=platform-ehci-omap.0-usb-0:2.5:1.0
E: ACL_MANAGE=1
E: DEVLINKS=/dev/char/81:0 /dev/v4l/by-id/usb-Vimicro_Co._ltd_Vimicro_USB2.0_UVC_PC_Camera-video-index0 /dev/v4l/by-path/platform-ehci-omap.0-usb-0:2.5:1.0-video-index0


Tuesday, October 19, 2010

dual camera support

My application requires using 2 cameras simultaneously. However, when attempting to call uvcGrab after opening both devices, one of the devices would fail with:

"Unable to start capture: No space left on device"

I found this thread which was helpful - it turns out to be a USB bandwith issue:

http://www.mail-archive.com/linux-uvc-devel@lists.berlios.de/msg03820.html

Unfortunately, the camera I chose has only 1 single Isochronous Video Streaming interface with wMaxPacketSize of 3x1000 bytes as shown below. So even attempting to force the driver to load with the UVC_QUIRK_FIX_BANDWIDTH flag (sudo insmod drivers/media/video/uvc/uvcvideo.ko trace=0x7ff quirks=0x80) wouldn't allow both cameras to run simultaneously, even with 160x120 frames at 15FPS!

I need to find a new camera.


lsusb -v
Bus 001 Device 008: ID 18ec:3299 Arkmicro Technologies Inc.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x18ec Arkmicro Technologies Inc.
idProduct 0x3299
bcdDevice 1.00
iManufacturer 1
iProduct 2
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 498
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 320mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 14 Video
bFunctionSubClass 3 Video Interface Collection
bFunctionProtocol 0
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 1 Video Control
bInterfaceProtocol 0
iInterface 0
VideoControl Interface Descriptor:
bLength 13
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdUVC 1.00
wTotalLength 51
dwClockFrequency 24.000000MHz
bInCollection 1
baInterfaceNr( 0) 1
VideoControl Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Camera Sensor
bAssocTerminal 0
iTerminal 0
wObjectiveFocalLengthMin 0
wObjectiveFocalLengthMax 0
wOcularFocalLength 0
bControlSize 3
bmControls 0x0000200a
Auto-Exposure Mode
Exposure Time (Absolute)
Roll (Absolute)
VideoControl Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 5 (PROCESSING_UNIT)
Warning: Descriptor too short
bUnitID 2
bSourceID 1
wMaxMultiplier 0
bControlSize 2
bmControls 0x0000073f
Brightness
Contrast
Hue
Saturation
Sharpness
Gamma
Backlight Compensation
Gain
Power Line Frequency
iProcessing 0
bmVideoStandards 0x 9
None
SECAM - 625/50
VideoControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 3
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 2
iTerminal 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
VideoStreaming Interface Descriptor:
bLength 14
bDescriptorType 36
bDescriptorSubtype 1 (INPUT_HEADER)
bNumFormats 1
wTotalLength 275
bEndPointAddress 131
bmInfo 0
bTerminalLink 3
bStillCaptureMethod 2
bTriggerSupport 1
bTriggerUsage 0
bControlSize 1
bmaControls( 0) 27
VideoStreaming Interface Descriptor:
bLength 27
bDescriptorType 36
bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
bFormatIndex 1
bNumFrameDescriptors 5
guidFormat {59555932-0000-1000-8000-00aa00389b71}
bBitsPerPixel 16
bDefaultFrameIndex 1
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 1 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 0
VideoStreaming Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 1
bmCapabilities 0x00
Still image unsupported
wWidth 640
wHeight 480
dwMinBitRate 614400
dwMaxBitRate 18432000
dwMaxVideoFrameBufferSize 614400
dwDefaultFrameInterval 333333
bFrameIntervalType 4
dwFrameInterval( 0) 333333
dwFrameInterval( 1) 666666
dwFrameInterval( 2) 1000000
dwFrameInterval( 3) 2000000
VideoStreaming Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 2
bmCapabilities 0x00
Still image unsupported
wWidth 352
wHeight 288
dwMinBitRate 202752
dwMaxBitRate 6082560
dwMaxVideoFrameBufferSize 202752
dwDefaultFrameInterval 333333
bFrameIntervalType 4
dwFrameInterval( 0) 333333
dwFrameInterval( 1) 666666
dwFrameInterval( 2) 1000000
dwFrameInterval( 3) 2000000
VideoStreaming Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 3
bmCapabilities 0x00
Still image unsupported
wWidth 320
wHeight 240
dwMinBitRate 153600
dwMaxBitRate 4608000
dwMaxVideoFrameBufferSize 153600
dwDefaultFrameInterval 333333
bFrameIntervalType 4
dwFrameInterval( 0) 333333
dwFrameInterval( 1) 666666
dwFrameInterval( 2) 1000000
dwFrameInterval( 3) 2000000
VideoStreaming Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 4
bmCapabilities 0x00
Still image unsupported
wWidth 176
wHeight 144
dwMinBitRate 50688
dwMaxBitRate 1520640
dwMaxVideoFrameBufferSize 50688
dwDefaultFrameInterval 333333
bFrameIntervalType 4
dwFrameInterval( 0) 333333
dwFrameInterval( 1) 666666
dwFrameInterval( 2) 1000000
dwFrameInterval( 3) 2000000
VideoStreaming Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 5
bmCapabilities 0x00
Still image unsupported
wWidth 160
wHeight 120
dwMinBitRate 38400
dwMaxBitRate 1152000
dwMaxVideoFrameBufferSize 38400
dwDefaultFrameInterval 333333
bFrameIntervalType 4
dwFrameInterval( 0) 333333
dwFrameInterval( 1) 666666
dwFrameInterval( 2) 1000000
dwFrameInterval( 3) 2000000
VideoStreaming Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 3 (STILL_IMAGE_FRAME)
bEndpointAddress 0
bNumImageSizePatterns 3
wWidth( 0) 640
wHeight( 0) 480
wWidth( 1) 800
wHeight( 1) 600
wWidth( 2) 1280
wHeight( 2) 1024
bNumCompressionPatterns 3
VideoStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 13 (COLORFORMAT)
bColorPrimaries 0 (Unspecified)
bTransferCharacteristics 0 (Unspecified)
bMatrixCoefficients 0 (Unspecified)
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x13e8 3x 1000 bytes
bInterval 1
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 2
bInterfaceCount 2
bFunctionClass 1 Audio
bFunctionSubClass 1 Control Device
bFunctionProtocol 0
iFunction 4
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 4
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 40
bInCollection 1
baInterfaceNr( 0) 3
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Microphone
bAssocTerminal 0
bNrChannels 2
wChannelConfig 0x0003
Left Front (L)
Right Front (R)
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 10
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 2
bSourceID 1
bControlSize 1
bmaControls( 0) 0x00
bmaControls( 1) 0x03
Mute
Volume
bmaControls( 2) 0x03
Mute
Volume
iFeature 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 3
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 2
iTerminal 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 4
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 4
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 3
bDelay 1 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 1
bSubframeSize 2
bBitResolution 16
bSamFreqType 1 Discrete
tSamFreq[ 0] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0080 1x 128 bytes
bInterval 4
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 0 Undefined
wLockDelay 0 Undefined

Saturday, September 25, 2010

Rebuilding the kernel

Although everything works so far out-of-the-box, I wanted to go through the exercise of building my own kernel, in case I need to change some of the configs or add any patches. Actually a PWM patch requires a change from the default Ubuntu kernel.

I tried a few ways of rebuilding the kernel, including the "old-fashioned Debian way", and using the automated Ubuntu scripts; however, I ran into various problems using these methods. I wanted to install the kernel on the SD card (not NAND) so that I could test different kernels out, while keeping the known good one in NAND in case the one on SD couldn't boot. The automated scripts would re-image NAND, and the "old-fashioned" way had various build/config issues and it was hard

The easiest way I found to rebuild the kernel is as follows. This keeps the kernel exactly as configured out of the box, allowing you to add your own patches on top.

1) install kernel sources on root filesystem with:
sudo apt-get build-dep --no-install-recommends linux-image-$(uname -r)
apt-get source linux-image-$(uname -r)
apt-get install qt3-dev-tools

2) copy over the old config
cp /boot/config-2.6.33-500-omap .config

3) configure the kernel
make xconfig

4) Build kernel and modules
make bzImage - builds vmlinuz
make modules - builds all the modules
make modules_install - installs modules in /lib/modules/

My kernel was named 2.6.33, so there are modules in /lib/modules/2.6.33

5) create an initramfs (similar to initrd) - I named mine "newinitramfs"
mkinitramfs -o newinitramfs 2.6.33

6) make a uboot compatible version of kernel - I called mine "newimage":
mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n "new kernel" -d arch/arm/boot/zImage newimage

7) make a uboot compatible version of the initrd - I called mine "newinitrd":
mkimage -A arm -O linux -T ramdisk -C none -a 0x0 -e 0x0 -n initrd -d newinitramfs newinitrd

8) copy "newimage" and "newinitrd" to root SD card (mine was mounted in /media/4BD6-F1E1)


9) test loading it from uboot:
mmc init
fatload mmc 0 0x80000000 newkernel
fatload mmc 0 0x81600000 newinitrd
bootm 0x80000000 0x81600000
setenv bootargs console=ttyS2,115200 root=UUID= splash vram=12M omap fb.mode=dvi:1280x720MR-16@60 fixrtc

Note that the old uboot command to boot from the NAND was:
bootcmd=nand read 80000000 280000 400000;nand read 81600000 680000 1000000;bootm 80000000 81600000

10) If everything works, can now overwrite it with the following, to auto-boot from SD instead:

setenv bootcmd "mmc init; fatload mmc 0 0x80000000 newimage; fatload mmc 0 0x81600000 newinitrd; bootm 0x80000000 0x81600000"
saveenv


I now have an Ubuntu 10.04 kernel booting the BeagleBoard from the SD card, and can easily modify the kernel, rebuild, and copy it over to the SD card and reboot. The nice thing is that I can make a copy of the known good SD card, and use another one for development. Alternatively, if anything goes wrong, the bootcmd can be changed back to boot from NAND.

Friday, September 24, 2010

testing the GPIO pins

We'll have to interface to some external devices using the GPIO pins. The expansion header has a couple dozen pins, most of which can be configured as GPIO's. There's also 3 pins that can be configured as PWMs (which can be controlled by hardware timers), and an I2C.

I verified that pin 3 can function as an output (driving either +1.8V high, or 0V low) using the following on the console:

#first, export the pin so the file shows up in /sys/class/gpio
sudo sh -c "echo 139 > /sys/class/gpio/export"

#now make an output
sudo sh -c "echo out > /sys/class/gpio/gpio139/direction"

#now we can toggle the pin high
sudo sh -c "echo high > /sys/class/gpio/gpio139/direction"

#or low
sudo sh -c "echo low > /sys/class/gpio/gpio139/direction"


We can also verify that the pins functions correctly as an input:

#change direction to an input
sudo sh -c "echo in > /sys/class/gpio/gpio139/direction"

#short pin3 to pin1 (1.8V) to verify it's high
cat /sys/class/gpio/gpio139/value
1

#short pin3 to pin 27 (gnd) to verify it's low
cat /sys/class/gpio/gpio139/value
0

Finally, note that the 2 user LED's (USR0 and USR1) are already configured by the default Ubuntu kernel, and can be turned on and off like so:

sudo sh -c "echo 1 > /sys/devices/platform/leds-gpio/leds/beagleboard\:\:usr0/brightness"
sudo sh -c "echo 0 > /sys/devices/platform/leds-gpio/leds/beagleboard\:\:usr0/brightness"

In summary ,this verifies that the kernel gpio module is working and we can properly manipulate the GPIO's. Note this can also be done programatically within a C program using fopen, fread, fwrite, etc.

Wednesday, September 22, 2010

up and running

My BeagleBoard and accessories arrived from LiquidWare within a couple of days. I powered it with a wall-wort phone charger from an Android phone via the mini USB connector, and plugged in a USB hub with USB<->Ethernet and the USB stick, and the DVI cable to a monitor. After trying to install the netbook image, I was seeing CRAMFS errors on the monitor. It turns out the first image I downloaded and dd'd onto the SD card was a bad image - the MD5 sum didn't match.

I re-downloaded the image and verified the MD5 sum. However, now the BeagleBoard boot parameters were set up to boot from NAND, and not the SD card. So, I needed access to the serial port to change this.

I bought a Micro Connectors, Inc. "IDC10" connector from Fry's - a 10-pin female header to a 9-pin DB9F (PLU #257237, F02-203, barcode 1586000620); and a null-modem cable (DB9F <-> DB9F). Unfortunately this didn't work - I saw either nothing or garbage characters out of the BeagleBoard.

It turned out the "IDC10" connector I got was not wired up to the DB9 as expected. Pin 1 of the header went to pin 1 of the DB9; but Pin 2 of the header went to Pin 6 of the DB9! I cut the ribbon cable in half and re-routed the 3 wires (TX, RX, and GND), and was finally able to access the serial port.

This command (found on the Ubuntu wiki) got me booting from the SD card again:
OMAP3 beagleboard.org # mmc init
OMAP3 beagleboard.org # fatload mmc 0 0x82000000 boot.scr
...
OMAP3 beagleboard.org # source 0x82000000

This time, the Ubuntu netbook image booted from the SD card, and installed onto the USB stick out of the box - I now have a BeagleBoard running Samba, sshd, Ubuntu netbook desktop on the DVI monitor, and set up for remote building under NetBeans on my MacBook.

Here's the extra packages I installed:

sudo apt-get install openssh-server
sudo apt-get install samba
sudo apt-get install build-essential
sudo apt-get install libsdl1.2-dev
sudo apt-get install manpages manpages-dev manpages-posix manpages-posix-dev freebsd-manpages

Finally I purged this package, as it was taking a lot of CPU (update-apt-xapi showed 90+% CPU in 'top') and not needed for this type of embedded environment:
sudo aptitude purge apt-xapian-index

Tuesday, September 14, 2010

webcam issues

One problem I ran into today was a strange issue with the webcam. For my project, I need to capture video at 30 fps and perform some image analysis. I'm using the luvcview project as a starting point.

The problem is that I wanted to shut off auto-exposure, and that didn't seem to work with my particular webcam. I'm using WC1200RED webcam, which internally has an Arkmicro Technologies Inc. device (18ec:3299). According to the Linux uvc page this is model number QC3231, although I don't see this model number anywhere (although I since tossed the packaging).

After playing around with the camera for a bit, I stumbled upon a way to disable auto-exposure with the following change:

case A_EXPOSURE_OFF:
control.id =V4L2_CID_EXPOSURE_AUTO;
- control.value =8;
+ control.value =2;
if ((value = ioctl(videoIn->fd, VIDIOC_S_CTRL, &control)) < 0)
printf("Set Auto Exposure off error\n");



I can't find this documented anywhere, but it does seem to work; it's probably worth posting a question on the UVC list at some point.

Monday, September 13, 2010

Set up Development Environment

I'd like to set up a comfortable environment for editing, building, and debugging the apps running on the BeagleBoard, from my MacBook running OS X. I found this excellent post on the subject, describing remote debugging using NetBeans, a great IDE (I prefer it to Eclipse):
http://mechomaniac.com/BeagleboardDevelopmentWithNetbeans

The idea is to run the IDE on your host machine, and mount the BeagleBoard root filesystem via Samba, so you can build, run, and debug the code on the device. This is great, especially if your host machine is OS X, because you don't have to worry about cross compilation, Linux header files, etc.

It skipped a couple of steps, which are described here:


Set up Samba on BeagleBoard
  • Install samba on BeagleBoard with: sudo apt-get install samba
  • create a samba password for any user account with: sudo smbpasswd <username>
  • edit samba config (etc/samba/smb.conf) to map the root filesystem to a samba share:

[Root]
comment = Root
path = /
guest ok = no
browseable = yes
public = yes
writable = yes

Finally, restart samba: "sudo /etc/init.d/smbd restart"


Now you can connect to the samba share via the Finder, or with the NetBeans IDE. To connect via the Finder, launch the Finder; then select "Go -> Connect to Server ..."and enter "smb://<BeagleBoard IP address>" for the Server address.

Preparing the SD Card

While I'm waiting to get the parts, I'm going to prepare an SD card for installing Ubuntu Linux on the BeagleBoard. I'm following the BeagleNetbookInstall instructions found here: https://wiki.ubuntu.com/ARM/Beagle

Step 1

wget http://cdimage.ubuntu.com/ports/releases/lucid/release/ubuntu-10.04-netbook-armel+omap.img

Note the image is 525M

Step 2
I'm doing this from OS X:
  • Insert 2G sdcard
  • diskutil unmount disk1s1
  • dd if=~/ubuntu-10.04-netbook-armel+omap.img of=/dev/disk1
It's that easy! Now we have an sdcard ready to use for booting.

Ordering the Gear

Here's the initial parts list for this project:
  • (1) BeagleBoard C4 from LiquidWare - $149
  • (1) USB Ethernet Adapter from LiquidWare - $33.78
  • (1) Belkin USB 2.0 Plus Hub (7 Port) F5U307-BRN from Amazon - $22.99
  • (1) Kingston DataTraveler I - 8 GB USB 2.0 Flash Drive DTI/8GB from Amazon - $22.79
  • (1) Plugable USB to RS-232 DB9 Serial Adapter (Prolific PL2303HX Chipset) from Amazon - $14.95
  • (1) Cables Unlimited PCM-2296-06 HDMI to DVI D Cable, 6 feet from Amazon - $6.79
  • (1) WC1200RED UVC compliant webcam from Office Depot - $19.99

Welcome

This blog was created to document my adventures with BeagleBoard for my own reference; as well as anyone else who is considering a project using the BeagleBoard, and would like to hear about my experience.

My first project is a factory automation application. I prototyped part of the project with a PC running Linux, and plan to replicate my work on the BeagleBoard. Specifically, I need to:
  1. Interface to a webcam to capture video frames at 30 frames/sec, and perform some analysis on the image;
  2. Interface to an external piece of equipment using the serial port;
  3. Control at least (2) stepper motors;
  4. Possibly interface to 1 or 2 external sensors (TBD).

The BeagleBoard was chosen for this project for: its small size, "hackability" (GPIO's, PWM's, I2C, etc are brought out to headers), relatively low cost, and most importantly, its support for Linux (it looks like Ubuntu should run out of the box).

I'll try to document aspects of this project that might help myself replicate what I've done here for application to other projects; or someone else get started with their own project.

So let's get started!

PS: The title of this post comes from a song by the Boards of Canada.