This is an digital video camera program using NKK\'s oLED swtich and 4D Systems\' uCam serial camera. It takes image from the uCam and displays on the IS-C15 switch. Some image processing demos are included. This program uses FatFileSytem, SDFileSystem, and TextLCD library. See http://www.youtube.com/watch?v=fqHTaCRHyQs for how it works. CQ出版社の「mbed/ARM活用事例」第10章シリアル接続カメラと有機ELディスプレイ内蔵スイッチで作るmbedディジタル・カメラの作例です。動作の様子は http://www.youtube.com/watch?v=fqHTaCRHyQs で見れます。

Dependencies:   TextLCD mbed SDFileSystem

Files at this revision

API Documentation at this revision

Comitter:
non
Date:
Thu Oct 06 00:54:08 2011 +0000
Child:
1:e848ee65abc9
Commit message:

Changed in this revision

FATFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
TextLCD.cpp Show annotated file Show diff for this revision Revisions of this file
TextLCD.h Show annotated file Show diff for this revision Revisions of this file
isc15.cpp Show annotated file Show diff for this revision Revisions of this file
isc15.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
ucam.cpp Show annotated file Show diff for this revision Revisions of this file
ucam.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FATFileSystem.lib	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_unsupported/code/fatfilesystem/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simon/code/SDFileSystem/#b1ddfc9a9b25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.cpp	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,159 @@
+/* mbed TextLCD Library, for a 4-bit LCD based on HD44780
+ * Copyright (c) 2007-2010, sford
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "TextLCD.h"
+#include "mbed.h"
+
+TextLCD::TextLCD(PinName rs, PinName e, PinName d0, PinName d1,
+                 PinName d2, PinName d3, LCDType type) : _rs(rs),
+        _e(e), _d(d0, d1, d2, d3),
+        _type(type) {
+
+    _e  = 1;
+    _rs = 0;            // command mode
+
+    wait(0.015);        // Wait 15ms to ensure powered up
+
+    // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
+    for (int i=0; i<3; i++) {
+        writeByte(0x3);
+        wait(0.00164);  // this command takes 1.64ms, so wait for it
+    }
+    writeByte(0x2);     // 4-bit mode
+    wait(0.000040f);    // most instructions take 40us
+
+    writeCommand(0x28); // Function set 001 BW N F - -
+    writeCommand(0x0C);
+    writeCommand(0x6);  // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes
+    cls();
+}
+
+void TextLCD::character(int column, int row, int c) {
+    int a = address(column, row);
+    writeCommand(a);
+    writeData(c);
+}
+
+void TextLCD::cls() {
+    writeCommand(0x01); // cls, and set cursor to 0
+    wait(0.00164f);     // This command takes 1.64 ms
+    locate(0, 0);
+}
+
+void TextLCD::locate(int column, int row) {
+    _column = column;
+    _row = row;
+}
+
+int TextLCD::_putc(int value) {
+    if (value == '\n') {
+        _column = 0;
+        _row++;
+        if (_row >= rows()) {
+            _row = 0;
+        }
+    } else {
+        character(_column, _row, value);
+        _column++;
+        if (_column >= columns()) {
+            _column = 0;
+            _row++;
+            if (_row >= rows()) {
+                _row = 0;
+            }
+        }
+    }
+    return value;
+}
+
+int TextLCD::_getc() {
+    return -1;
+}
+
+void TextLCD::writeByte(int value) {
+    _d = value >> 4;
+    wait(0.000040f); // most instructions take 40us
+    _e = 0;
+    wait(0.000040f);
+    _e = 1;
+    _d = value >> 0;
+    wait(0.000040f);
+    _e = 0;
+    wait(0.000040f);  // most instructions take 40us
+    _e = 1;
+}
+
+void TextLCD::writeCommand(int command) {
+    _rs = 0;
+    writeByte(command);
+}
+
+void TextLCD::writeData(int data) {
+    _rs = 1;
+    writeByte(data);
+}
+
+int TextLCD::address(int column, int row) {
+    switch (_type) {
+        case LCD20x4:
+            switch (row) {
+                case 0:
+                    return 0x80 + column;
+                case 1:
+                    return 0xc0 + column;
+                case 2:
+                    return 0x94 + column;
+                case 3:
+                    return 0xd4 + column;
+            }
+        case LCD16x2B:
+            return 0x80 + (row * 40) + column;
+        case LCD16x2:
+        case LCD20x2:
+        default:
+            return 0x80 + (row * 0x40) + column;
+    }
+}
+
+int TextLCD::columns() {
+    switch (_type) {
+        case LCD20x4:
+        case LCD20x2:
+            return 20;
+        case LCD16x2:
+        case LCD16x2B:
+        default:
+            return 16;
+    }
+}
+
+int TextLCD::rows() {
+    switch (_type) {
+        case LCD20x4:
+            return 4;
+        case LCD16x2:
+        case LCD16x2B:
+        case LCD20x2:
+        default:
+            return 2;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.h	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,111 @@
+/* mbed TextLCD Library, for a 4-bit LCD based on HD44780
+ * Copyright (c) 2007-2010, sford
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MBED_TEXTLCD_H
+#define MBED_TEXTLCD_H
+
+#include "mbed.h"
+
+/** A TextLCD interface for driving 4-bit HD44780-based LCDs
+ *
+ * Currently supports 16x2, 20x2 and 20x4 panels
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "TextLCD.h"
+ * 
+ * TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d0-d3
+ * 
+ * int main() {
+ *     lcd.printf("Hello World!\n");
+ * }
+ * @endcode
+ */
+class TextLCD : public Stream {
+public:
+
+    /** LCD panel format */
+    enum LCDType {
+        LCD16x2     /**< 16x2 LCD panel (default) */
+        , LCD16x2B  /**< 16x2 LCD panel alternate addressing */
+        , LCD20x2   /**< 20x2 LCD panel */
+        , LCD20x4   /**< 20x4 LCD panel */
+    };
+
+    /** Create a TextLCD interface
+     *
+     * @param rs    Instruction/data control line
+     * @param e     Enable line (clock)
+     * @param d0-d3 Data lines
+     * @param type  Sets the panel size/addressing mode (default = LCD16x2)
+     */
+    TextLCD(PinName rs, PinName e, PinName d0, PinName d1, PinName d2, PinName d3, LCDType type = LCD16x2);
+
+#if DOXYGEN_ONLY
+    /** Write a character to the LCD
+     *
+     * @param c The character to write to the display
+     */
+    int putc(int c);
+
+    /** Write a formated string to the LCD
+     *
+     * @param format A printf-style format string, followed by the
+     *               variables to use in formating the string.
+     */
+    int printf(const char* format, ...);
+#endif
+
+    /** Locate to a screen column and row
+     *
+     * @param column  The horizontal position from the left, indexed from 0
+     * @param row     The vertical position from the top, indexed from 0
+     */
+    void locate(int column, int row);
+
+    /** Clear the screen and locate to 0,0 */
+    void cls();
+
+    int rows();
+    int columns();
+
+protected:
+
+    // Stream implementation functions
+    virtual int _putc(int value);
+    virtual int _getc();
+
+    int address(int column, int row);
+    void character(int column, int row, int c);
+    void writeByte(int value);
+    void writeCommand(int command);
+    void writeData(int data);
+
+    DigitalOut _rs, _e;
+    BusOut _d;
+    LCDType _type;
+
+    int _column;
+    int _row;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/isc15.cpp	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,227 @@
+/* mbed NKK IS-C15/C01 oLED switch library
+ * Copyright (c) 2011, Noriaki Mitsunaga
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "isc15.h"
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Some constants
+////////////////////////////////////////////////////////////////////////////////////////
+const int DAT = 1;
+const int CMD = 0;
+
+////////////////////////////////////////////////////////////////////////////////////////
+//    OLED's initial setup commands (IS15)
+////////////////////////////////////////////////////////////////////////////////////////
+const    unsigned char    SetupColumnAddress[]        =    {    0x03,    0x15,    0x10,    0x4f    };
+const    unsigned char    SetupRowaddress[]            =    {    0x03,    0x75,    0x00,    0x2f    };
+const    unsigned char    SetContrastColorA[]         =    {    0x02,    0x81,    0x19    };
+const    unsigned char    SetContrastColorB[]         =    {    0x02,    0x82,    0x14    };
+const    unsigned char    SetContrastColorC[]         =    {    0x02,    0x83,    0x24    };
+const    unsigned char    MasterCurrentControl[]        =    {    0x02,    0x87,    0x0f    };
+const    unsigned char    RemapColorDepth[]            =    {    0x02,    0xa0,    0x70    };
+const    unsigned char    SetDisplayStartLine[]        =    {    0x02,    0xa1,    0x00    };
+const    unsigned char    SetDisplayOffset[]            =    {    0x02,    0xa2,    0x10    };
+const    unsigned char    SetDisplayMode[]            =    {    0x01,    0xa4    };
+const    unsigned char    SetMultiplexRatio[]            =    {    0x02,    0xa8,    0x2f    };
+const    unsigned char    DimModeSetting[]            =    {    0x05,    0xab,    0x12,    0x0c,    0x14,    0x12    };
+const    unsigned char    SetDisplayDim[]                =    {    0x01,    0xac    };
+const    unsigned char    SetDisplayOff[]                =    {    0x01,    0xae    };
+const    unsigned char    SetDisplayNormal[]            =    {    0x01,    0xaf    };
+const    unsigned char    SetMasterConfiguration[]    =    {    0x02,    0xad,    0x8e    };
+const    unsigned char    PhasePeriodAdjustment[]        =    {    0x02,    0xb1,    0x44    };
+const    unsigned char    DisplayClockDivider[]        =    {    0x02,    0xb3,    0xa0    };
+const    unsigned char    EnableLinearGrayScale[]        =    {    0x01,    0xb9    };
+const    unsigned char    SetPrechargeLevel[]            =    {    0x02,    0xbb,    0x12    };
+const    unsigned char    SetVcomh[]                    =    {    0x03,    0xbe,    0x28    };
+
+const    unsigned char    ColorDepth64k[]                =    {    0x02,    0xa0,    0x70    };
+const    unsigned char    ColorDepth256[]                =    {    0x02,    0xa0,    0x30    };
+
+//    OLED's initial setup commands (for display only type (IS01) )
+const    unsigned char    SetupColumnAddress_d[]        =    {    0x03,    0x15,    0x16,    0x49    }; //display
+const    unsigned char    SetupRowaddress_d[]            =    {    0x03,    0x75,    0x00,    0x23    }; //display
+const    unsigned char    SetContrastColorA_d[]         =    {    0x02,    0x81,    0x0f    }; //display
+const    unsigned char    SetContrastColorB_d[]         =    {    0x02,    0x82,    0x0e    }; //display
+const    unsigned char    SetContrastColorC_d[]         =    {    0x02,    0x83,    0x1b    }; //display
+const    unsigned char    SetDisplayOffset_d[]            =    {    0x02,    0xa2,    0x1c    }; //display
+const    unsigned char    SetMultiplexRatio_d[]            =    {    0x02,    0xa8,    0x23    }; //display
+const    unsigned char    DimModeSetting_d[]            =    {    0x05,    0xab,    0x0b,    0x08,    0x0f,    0x12    }; //display
+const    unsigned char    DisplayClockDivider_d[]        =    {    0x02,    0xb3,    0x30    }; //display
+const    unsigned char    SetVcomh_d[]                    =    {    0x03,    0xbe,    0x21    }; //display
+
+//
+//        Change OLED's address setting
+//
+void    ISC15::AdrInit( int DevType )    {
+    if (spi == NULL)
+        return;
+
+    if (DevType == ISC15_DEVICE_ISC15) {
+        SendCommand( SetupColumnAddress );
+        SendCommand( SetupRowaddress );
+    } else {
+        SendCommand( SetupColumnAddress_d );
+        SendCommand( SetupRowaddress_d );
+    }
+}
+
+
+//
+//        Display data on OLED
+//
+void    ISC15::Disp( int Mode, const unsigned char *dat )    {
+    if (spi == NULL)
+        return;
+
+    AdrInit(DevType);
+    DspMode(Mode);
+    if (Mode == ISC15_DSPMODE_64K)
+        SendData(dat, ISC15_WIDTH*ISC15_HEIGHT*2);
+    else
+        SendData(dat, ISC15_WIDTH*ISC15_HEIGHT);
+}
+
+//
+//        Change OLED's color depth setting (64K or 256 colors)
+//
+void    ISC15::DspMode( int DspMode )    {
+    if (spi == NULL)
+        return;
+
+    if ( DspMode == ISC15_DSPMODE_64K )    {
+        SendCommand( ColorDepth64k );
+    } else    {
+        SendCommand( ColorDepth256 );
+    }
+}
+
+//
+//        Fill out display
+//
+void    ISC15::Fill(unsigned char c)    {
+    if (spi == NULL)
+        return;
+
+    AdrInit(DevType);
+    DspMode(0);
+
+    is_dc = DAT;
+    for (int i = ISC15_WIDTH*ISC15_HEIGHT; i>0; i --) {
+        is_cs = 0;
+        spi->write(c);
+        is_cs = 1;
+    }
+}
+
+//
+//        initial settings of OLED
+//
+void    ISC15::Init( int DeviceType, SPI *s )    {
+    volatile unsigned char    delay = 0x20;
+
+    DevType = DeviceType;
+    spi = s;
+
+    //    reset OLED
+    is_vcc = 0;
+    is_reset = 0;
+    wait_us(3);
+    is_reset = 1;
+    is_vcc = 1;
+
+    //    initial settings
+    AdrInit(DevType);
+
+    if (DevType == ISC15_DEVICE_ISC15) {
+        SendCommand( SetContrastColorA );
+        SendCommand( SetContrastColorB );
+        SendCommand( SetContrastColorC );
+        SendCommand( MasterCurrentControl );
+        SendCommand( SetDisplayStartLine );
+        SendCommand( SetDisplayOffset );
+        SendCommand( SetDisplayMode );
+        SendCommand( SetMultiplexRatio );
+        SendCommand( DimModeSetting );
+        SendCommand( SetMasterConfiguration );
+        SendCommand( PhasePeriodAdjustment );
+        SendCommand( DisplayClockDivider );
+        SendCommand( EnableLinearGrayScale );
+        SendCommand( SetPrechargeLevel );
+        SendCommand( SetVcomh );
+    } else {
+        SendCommand( SetContrastColorA_d );
+        SendCommand( SetContrastColorB_d );
+        SendCommand( SetContrastColorC_d );
+        SendCommand( MasterCurrentControl );
+        SendCommand( SetDisplayStartLine );
+        SendCommand( SetDisplayOffset_d );
+        SendCommand( SetDisplayMode );
+        SendCommand( SetMultiplexRatio_d );
+        SendCommand( DimModeSetting_d );
+        SendCommand( SetMasterConfiguration );
+        SendCommand( PhasePeriodAdjustment );
+        SendCommand( DisplayClockDivider_d );
+        SendCommand( EnableLinearGrayScale );
+        SendCommand( SetPrechargeLevel );
+        SendCommand( SetVcomh_d );
+    }
+
+    //    display mode settings
+    DspMode( ISC15_DSPMODE_64K);
+
+    SendCommand( SetDisplayNormal );
+}
+
+//
+//      Send a command / data to OLED via SPI
+//
+void    ISC15::Send( const unsigned char *p, int len )    {
+    if (spi == NULL)
+        return;
+
+    for (; len>0; len --, p ++) {
+        is_cs = 0;
+        spi->write(*p);
+        is_cs = 1;
+    }
+}
+
+//
+//        Send a command to OLED
+//
+void    ISC15::SendCommand( const unsigned char *com )    {
+    if (spi == NULL)
+        return;
+
+    is_dc = CMD;
+    Send(com+1, *com);
+}
+
+//
+//        Send data to OLED
+//
+void    ISC15::SendData( const unsigned char *dat, int len )    {
+    if (spi == NULL)
+        return;
+
+    is_dc = DAT;
+    Send(dat, len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/isc15.h	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,61 @@
+/* mbed NKK IS-C15/C01 oLED switch library
+ * Copyright (c) 2011, Noriaki Mitsunaga
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef __ISC15_H__
+#define __ISC15_H__
+
+#include "mbed.h"
+
+#define ISC15_DEVICE_ISC01 0
+#define ISC15_DEVICE_ISC15 1
+
+#define ISC15_DSPMODE_256 0
+#define ISC15_DSPMODE_64K 1
+
+#define ISC15_WIDTH 64
+#define ISC15_HEIGHT 48
+
+class ISC15 {
+public:
+    ISC15( PinName cs, PinName reset, PinName dc, PinName vcc )
+            : is_cs(cs), is_reset(reset), is_dc(dc), is_vcc(vcc) {
+        DevType = 1;
+        spi = NULL;
+    }
+    void    Cls() {
+        Fill(0);
+    };
+    void    Disp( int Mode, const unsigned char *dat );
+    void    Fill( unsigned char c );
+    void    Init( int DeviceType, SPI *s );
+
+private:
+    DigitalOut is_cs, is_reset, is_dc, is_vcc;
+    int DevType; // 0:ISC01, 1:ISC15
+    SPI *spi;
+
+    void    AdrInit( int DevType );
+    void    DspMode( int DspMode_ );
+    void    Send( const unsigned char *p, int len );
+    void    SendCommand( const unsigned char *com );
+    void    SendData( const unsigned char *dat, int len );
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,347 @@
+/* This software is an digital video camera program using NKK's oLED swtich
+ * and 4D Systems' uCam serial camera. It takes image from the uCam and 
+ * displays on the IS-C15 switch. Some image processing demos are included.
+ *
+ * This program uses FatFileSytem, SDFileSystem, and TextLCD library. 
+ *   
+ * Copyright (c) 2011, Noriaki Mitsunaga
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "mbed.h"
+// #define USE_LCD              // Need this if you want to use text LCD
+#ifdef USE_LCD
+#include "TextLCD.h"
+#endif
+// #include "SDFileSystem.h" // Need this if you want to save to SD-Card
+
+#include "isc15.h"
+#include "ucam.h"
+
+// SDFileSystem sd(p5, p6, p7, p8, "sd"); // Need this if you want to save to SD-Card
+LocalFileSystem local("local"); // Need this if you want to save to local flash
+SPI spi(p11, p12, p13); // mosi(SDO), miso(SDI), sclk(SCLK)
+
+ISC15 ISC15(p16, p15, p14, p18);   // NKK IS-C15 oLED swtich
+DigitalOut led1(LED1), led2(LED2); // On board LEDs
+DigitalIn sw1(p17);                // Shutter switch (IS-C15)
+uCam ucam(p9, p10);                // uCam-TTL (p9=TX, p10=RX)
+
+Ticker timer;
+bool sw1pressed = false;
+bool sw1pressing = false;
+
+#ifdef USE_LCD
+TextLCD lcd(p24, p26, p27, p28, p29, p30); // rs, e, d0-d3
+#define LCDPRINTF(...) lcd.printf(__VA_ARGS__)
+#else
+#define LCDPRINTF(...)
+#endif /* USE_LCD */
+
+/* Function prototypes */
+void checkSW();
+int  SaveJPEG(const char *fname);
+
+/* main fuction */
+int main() {
+    unsigned char cam[80*60*2];
+    unsigned char oled[64*48*2];
+    int n = 0;
+
+    sw1.mode(PullUp);
+    led1 = led2 = 1;
+    // Setup the spi for 8 bit data, high steady state clock,
+    // second edge capture, with a 4MHz clock rate
+    spi.format(8, 3);
+    spi.frequency(4000000);
+    // Initialize IS Color 15's oLED
+    ISC15.Init(ISC15_DEVICE_ISC15, &spi);
+    // Clear oLED display
+    ISC15.Cls();
+
+    // Initialize uCam-TTL
+    LCDPRINTF("Init Camera..\n");
+    if (!ucam.Init()) {
+        LCDPRINTF("Init failed.\n");
+        goto ERROR;
+    }
+    // Set AC frequency (60 for Kansai-area, 50 for Kanto-area)
+    if (!ucam.LightFreq(60))
+        goto ERROR;
+    // Attach tick timer to checkSW function
+    timer.attach_us(checkSW, 20000);
+
+    LCDPRINTF("Starting.\n");
+    led1 = led2 = 0;
+
+    for (;;) {
+        // Flush LED
+        led1 = 1;
+        wait(0.1);
+        led1 = 0;
+
+#if 1   /* D1: Set 1 to test RGB565 mode */
+        if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_RGB565, UCAM_RAW_RESOLUTION_80X60, cam))
+            goto ERROR;
+
+        for (int y=0; y<48; y++) {
+            unsigned char *rg = cam + (80-64)/2 + ((60-48)/2+y)*80*2;
+            unsigned char *gb = rg + 1;
+            unsigned char *p = oled + y*64*2;
+            for (int x=0; x<64; x++, rg+=2, gb+=2) {
+                *p ++ = (*gb <<3)    | (*rg & 0x7);
+                *p ++ = (*gb & 0xe0) | (*rg >> 3);
+            }
+        }
+        ISC15.Disp(ISC15_DSPMODE_64K, oled);
+#endif
+
+#if 0   /* D2: Set 1 to test 4bit gray mode */
+        if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_4BITG, UCAM_RAW_RESOLUTION_80X60, cam))
+            goto ERROR;
+
+        for (int y=0; y<48; y++) {
+            unsigned char *v = cam + ((80-64)/2 + ((60-48)/2+y)*80)/2;
+            unsigned char *p = oled + y*64*2;
+            for (int x=0; x<64; x++, v++) {
+                int V = (*v & 0xf0) >> 4;
+                *p ++ = (V << 4)    | (V >> 1);
+                *p ++ = ((V << 2) & 0xe0) | (V << 1);
+                x ++;
+
+                V = *v & 0xf;
+                *p ++ = (V << 4)    | (V >> 1);
+                *p ++ = ((V << 2) & 0xe0) | (V << 1);
+            }
+        }
+        ISC15.Disp(ISC15_DSPMODE_64K, oled);
+#endif
+
+#if 0   /* D3: Set 1 to test 8bit gray mode */
+        if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_8BITG, UCAM_RAW_RESOLUTION_80X60, cam))
+            goto ERROR;
+
+        for (int y=0; y<48; y++) {
+            unsigned char *v = cam + (80-64)/2 + ((60-48)/2+y)*80;
+            unsigned char *p = oled + y*64*2;
+            for (int x=0; x<64; x++, v++) {
+                *p ++ = (*v & 0xf8) | (*v >> 5);
+                *p ++ = ((*v << 3) & 0xe0) | (*v >> 3);
+            }
+        }
+        ISC15.Disp(ISC15_DSPMODE_64K, oled);
+#endif
+
+#if 0   /* D4: Set 1 to test RGB332 mode */
+        if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_RGB332, UCAM_RAW_RESOLUTION_80X60, cam))
+            goto ERROR;
+
+        for (int y=0; y<48; y++) {
+            unsigned char *v = cam + ((80-64)/2 + ((60-48)/2+y)*80);
+            unsigned char *p = oled + y*64*2;
+            for (int x=0; x<64; x++, v++) {
+                int B = (*v & 0xe0) >> 5; /* 3bits */
+                int G = (*v & 0x1c) >> 3; /* 3bits */
+                int R = (*v & 0x3);       /* 2bits */
+                *p ++ = (B << 6) | G;
+                *p ++ =  R << 2;
+            }
+        }
+        ISC15.Disp(ISC15_DSPMODE_64K, oled);
+#endif
+
+#if 0   /* D5: Set 1 to test cropping (digital zoom) */
+        if (!ucam.SnapshotRawCrop(UCAM_COLOR_TYPE_RGB565,
+                                  UCAM_RAW_RESOLUTION_160X120, 48, 36, 64, 48, cam))
+            goto ERROR;
+
+        unsigned char *rg = cam;
+        unsigned char *gb = rg + 1;
+        unsigned char *p = oled;
+        for (int i=64*48; i>0; i--, rg+=2, gb+=2) {
+            *p ++ = (*gb <<3)    | (*rg & 0x7);
+            *p ++ = (*gb & 0xe0) | (*rg >> 3);
+        }
+        ISC15.Disp(ISC15_DSPMODE_64K, oled);
+#endif
+
+#if 0   /* D6: Set 1 to test 8bit gray differential image */
+        unsigned char cam2[80*60];
+        static unsigned char *camp = cam, *cam2p = cam2;
+
+        if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_8BITG, UCAM_RAW_RESOLUTION_80X60, camp))
+            goto ERROR;
+
+        for (int y=0; y<48; y++) {
+            unsigned char *v = camp + (80-64)/2 + ((60-48)/2+y)*80;
+            unsigned char *b = cam2p + (80-64)/2 + ((60-48)/2+y)*80;
+            unsigned char *p = oled + y*64*2;
+
+            for (int x=0; x<64; x++, v++, b++) {
+                if (abs(*v-*b)>10) {
+                    *p ++ = (*v & 0xf8) | (*v >> 5);
+                    *p ++ = ((*v << 3) & 0xe0) | (*v >> 3);
+                } else {
+                    *p ++ = 0;
+                    *p ++ = 0;
+                }
+            }
+        }
+        if (camp == cam) {
+            camp = cam2;
+            cam2p = cam;
+        } else {
+            camp = cam;
+            cam2p = cam2;
+        }
+        ISC15.Disp(ISC15_DSPMODE_64K, oled);
+#endif
+
+#if 0   /* D7: Set 1 to show RGB565 image when images' differential is large */
+        unsigned char cam2[80*60*2];
+        static unsigned char *camp = cam, *cam2p = cam2;
+
+        if (!ucam.SnapshotRawCrop(UCAM_COLOR_TYPE_RGB565,
+                                  UCAM_RAW_RESOLUTION_80X60, 8, 6, 64, 48, camp))
+            goto ERROR;
+
+        unsigned char *rg = camp;
+        unsigned char *gb = rg + 1;
+        unsigned char *rg0 = cam2p;
+        unsigned char *gb0 = rg0 + 1;
+        unsigned int diff = 0;
+
+        for (int i=64*48; i>0; i--, rg+=2, gb+=2, rg0+=2, gb0+=2)
+            diff += abs(((*rg & 0x7)<<3 | (*gb >> 5))-((*rg0 & 0x7)<<3 | (*gb0>> 5)));
+        LCDPRINTF("d: %d.\n", diff);
+
+        if (diff > 3000) {
+            rg = camp;
+            gb = rg + 1;
+            unsigned char *p = oled;
+            for (int i=64*48; i>0; i--, rg+=2, gb+=2) {
+                *p ++ = (*gb <<3)    | (*rg & 0x7);
+                *p ++ = (*gb & 0xe0) | (*rg >> 3);
+            }
+            ISC15.Disp(ISC15_DSPMODE_64K, oled);
+        } else {
+            ISC15.Cls();
+        }
+        if (camp == cam) {
+            camp = cam2;
+            cam2p = cam;
+        } else {
+            camp = cam;
+            cam2p = cam2;
+        }
+#endif
+
+        if (sw1pressed) {
+            char fname[20];
+//            sprintf(fname, "/sd/%05d.jpg", n); // Save to SD-Card
+            sprintf(fname, "/local/%05d.jpg", n); // Save to local flash memory
+            LCDPRINTF("Saving image\n");
+            SaveJPEG(fname);
+            LCDPRINTF("DONE        \n");
+            n ++;
+            sw1pressed = false;
+            led2 = 0;
+        }
+    }
+
+ERROR:
+    LCDPRINTF("ERROR\n");
+    while (1) {
+        led1 = 1;
+        wait(0.1);
+        led1 = 0;
+        wait(0.1);
+    }
+}
+
+/* ------------------------------------------ */
+/*   Check current status of the switch       */
+/*   The fuction is called by 20ms timer      */
+/* ------------------------------------------ */
+void checkSW() {
+    if (sw1 == 0) {
+        /* Swtich is pressed */
+        sw1pressed = true;
+        sw1pressing = true;
+        led2 = 1;
+    } else {
+        /* Switch is open */
+        sw1pressing = false;
+        led2 = 0;
+    }
+}
+
+/* ------------------------------------------ */
+/* Save a JPEG image read from uCam to a file */
+/* ------------------------------------------ */
+int SaveJPEG(const char *fname) {
+    /* Open file */
+    FILE *fp = fopen(fname, "wb");
+    if (fp == NULL) {
+        LCDPRINTF("XXX %s\n", fname);
+        return 0;
+    }
+
+    /* Prepare to recieve JPEG image */    
+    int sz = ucam.SnapshotJPEGi(UCAM_JPEG_RESOLUTION_320X240, 512);
+    if (sz == 0)
+        return 0;
+
+    /* Recieve packets */
+    int pno = 0;
+    unsigned char cam[512];
+    while (sz > 0) {
+        int pksz = 512;
+        led2 = ~led2;
+
+        if (sz < (512 - 6))
+            pksz = sz + 6;
+        LCDPRINTF("%d %d\n", pno, pksz);
+        /* Recieve a packet */
+        if (!ucam.SnapshotJPEGd(pno, cam, pksz)) {
+            if (fp != NULL)
+                fclose(fp);
+            return 0;
+        }
+        /* Write the packet */
+        if (fp != NULL)
+            fwrite(cam + 4, 1, pksz - 6, fp);
+        sz -= (pksz - 6);
+        pno ++;
+        /* Check end of the image */
+        if (sz == 0) {
+            if (pksz == 512) {
+                // Send reset command as manual says
+                wait_ms(3);
+                ucam.Reset();
+                ucam.Init();
+            } else {
+                ucam.ACK_F0F0();
+            }
+        }
+    }
+    fclose(fp);
+
+    return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ucam.cpp	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,280 @@
+/* 4D Systems uCam serial RAW/JPEG camera library
+ * Copyright (c) 2011, Noriaki Mitsunaga
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "mbed.h"
+#include "ucam.h"
+
+// uCam-TTL commands:
+const unsigned char ACK[] = {0xaa, 0x0e, 0x0d, 0, 0, 0};
+const unsigned char ACK1[] = {0xaa, 0x0e, 0x0d, 0, 1, 0};
+const unsigned char ACK_F0F0_[] = {0xaa, 0x0e, 0, 0, 0xf0, 0xf0};
+const unsigned char GETPICTURE_SNAPSHOT[] = {0xaa, 0x04, 0x01, 0, 0, 0};
+// const unsigned char GETPICTURE_RAWPREVIEW[] = {0xaa, 0x04, 0x02, 0, 0, 0};
+const unsigned char RESET[] = {0xaa, 0x08, 0x01, 0x0, 0x0, 0xff};
+const unsigned char SNAPSHOT_JPEG[] = {0xaa, 0x05, 0x00, 1, 0, 0};
+const unsigned char SNAPSHOT_RAW[] = {0xaa, 0x05, 0x01, 1, 0, 0};
+const unsigned char SYNC[] = {0xaa, 0x0d, 0, 0, 0, 0};
+
+// Send special ACK
+void uCam::ACK_F0F0() {
+    write(ACK_F0F0_, sizeof(ACK_F0F0_));
+}
+
+// Check if buf is valid ACK.
+int uCam::checkACK(const unsigned char *buf) {
+    if (buf[0] == ACK[0] && buf[1] == ACK[1] && buf[2] == ACK[2]
+            && buf[4] == 0 && buf[5] == 0)
+        return 1;
+
+    return 0;
+}
+
+// Compare buf to SYNC
+int uCam::checkSYNC(const unsigned char *buf) {
+    if (memcmp(buf, SYNC, sizeof(SYNC)) == 0)
+        return 1;
+
+    return 0;
+}
+
+// Send a command to uCam via the serial
+int uCam::Command(const unsigned char *cmd) {
+    // Send the command
+    write(cmd, 6);
+
+    // Wait for response
+    unsigned char buf[6];
+    read(buf, 6);
+
+    // Check ACK
+    if (buf[0] == 0xaa && buf[1] == 0x0e
+            && buf[2] == cmd[1]
+            /* ignore fourth byte */
+            && buf[4] == 0 && buf[5] == 0)
+        return 1;
+
+    return 0;
+}
+
+// Initialize communcation to uCam
+int uCam::Init() {
+    int i;
+    unsigned char buf[12];
+
+    for (i=0; i<60; i ++) {
+        // Send SYNC and check the answer
+        write(SYNC, sizeof(SYNC));
+        if (readT(buf, sizeof(buf)) == 12 && checkACK(buf)) {
+            break;
+        }
+    }
+    if (i == 60)      // Too many retries
+        return 0;
+
+    // Check SYNC
+    if (!checkSYNC(buf+6)) {
+        return 0;
+    }
+    write(ACK, sizeof(ACK));
+    return 1;
+}
+
+// Set light frequencey (50Hz or 60Hz) to reduce flicker.
+int uCam::LightFreq(int f) {
+    unsigned char LIGHT[] = {0xaa, 0x13, 0, 0, 0, 0};
+
+    if (f == 50)
+        LIGHT[2] = 0x0;
+    else if (f == 60)
+        LIGHT[2] = 0x1;
+    else
+        return 0;
+
+    return Command(LIGHT);
+}
+
+// Recive data from serial. It blocks until it recieves len bytes.
+// buf: recieving buffer
+// len: length to recieve
+void uCam::read(unsigned char *p, int len) {
+    for (; len>0; len--, p++) {
+        *p = s->getc();
+    }
+}
+
+// Recive data from serial with timeout
+// buf: recieving buffer
+// len: length of the buffer
+int uCam::readT(unsigned char *buf, int len) {
+    int c = 0;
+    unsigned char *q = buf;
+
+    for (int j=0; j<2000; j ++) {
+        if (s->readable()) {
+            *q = s->getc();
+            if (c < len) {
+                q ++;
+                c ++;
+            }
+        }
+        wait_us(50);
+    }
+
+    return c;
+}
+
+// Reset uCam
+void uCam::Reset() {
+    Command(RESET);
+}
+
+// Recieve a JPEG image packet. You need to call SnapshotJPEGi() before.
+// no: packet number (starts from 0)
+// buf: recieving buffer
+// pksz: packet size to recieve
+int uCam::SnapshotJPEGd(int no, unsigned char *buf, int pksz) {
+    unsigned char ACK_[] = {0xaa, 0x0e, 0x00, 0, 0, 0};
+
+    ACK_[4] = no & 0xff;
+    ACK_[5] = (no >> 8) & 0xff;
+
+    write(ACK_, sizeof(ACK_));
+    read(buf, pksz);
+
+    return 1;
+}
+
+// Prepare to recieve a JPEG image.
+// Res: resolution of the image (did not work well for 640x480 with uCam-TTL(ov528 version))
+// pksz: packet size to recieve
+int uCam::SnapshotJPEGi(int Res, int pksz) {
+    unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x07, 0x01, 0x00};
+    unsigned char SET_PACKAGESIZE[] = {0xaa, 0x06, 0x08, 0x00, 0x00, 0x00};
+    unsigned char buf[6];
+
+    INITIAL[5] = Res;
+    SET_PACKAGESIZE[3] = pksz & 0xff;
+    SET_PACKAGESIZE[4] = (pksz >> 8) & 0xff;
+
+    if (!Command(INITIAL))
+        return 0;
+    if (!Command(SET_PACKAGESIZE))
+        return 0;
+    if (!Command(SNAPSHOT_JPEG))
+        return 0;
+    if (!Command(GETPICTURE_SNAPSHOT))
+        return 0;
+
+    read(buf, 6);
+    if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
+        return 0;
+
+    return buf[5]<<16 | buf[4]<<8 | buf[3]; // return file size
+}
+
+// Take a raw image. 
+//
+// Color: color mode (supporte form 8bit gray, RGB232, or RGB565 only)
+// Res: image resolution
+// buf: buffer to save the image
+int uCam::SnapshotRaw(int Color, int Res, unsigned char *buf) {
+    unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x00, 0x00, 0x07};
+
+    INITIAL[3] = Color;
+    INITIAL[4] = Res;
+
+    if (!Command(INITIAL))
+        return 0;
+    if (!Command(SNAPSHOT_RAW))
+        return 0;
+    if (!Command(GETPICTURE_SNAPSHOT))
+        return 0;
+
+    read(buf, 6);
+    if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
+        return 0;
+
+    // lcd.printf("%d\n", buf[3] + buf[4]<<8 + buf[5]<<16);
+    read(buf, buf[5]<<16 | buf[4]<<8 | buf[3] /* 80*60*2*/ );
+    write(ACK1, sizeof(ACK1));
+
+    return 1;
+}
+
+// Take a raw image. This function crops
+// the image while it is recieving data from uCam
+//
+// Color: color mode (supporte form 8bit gray, RGB232, or RGB565 only)
+// Res: image resolution
+// x0, y0: top left corner of the cropping area
+// w, h: width and height of cropping area
+// buf: buffer to save the image
+int uCam::SnapshotRawCrop(int Color, int Res,
+                          int x0, int y0, int w, int h,
+                          unsigned char *buf) {
+    unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x00, 0x00, 0x07};
+    int W = ucam_raw_resolution_w[(Res-1)/2];
+    int H = ucam_raw_resolution_h[(Res-1)/2];
+
+    if (Color == UCAM_COLOR_TYPE_RGB565) {
+        W *= 2;
+        x0 *= 2;
+        w *= 2;
+    }
+
+    INITIAL[3] = Color;
+    INITIAL[4] = Res;
+
+    if (!Command(INITIAL))
+        return 0;
+    if (!Command(SNAPSHOT_RAW))
+        return 0;
+    if (!Command(GETPICTURE_SNAPSHOT))
+        return 0;
+
+    read(buf, 6);
+    if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
+        return 0;
+
+    for (int i=y0*W; i>0; i--) /* Skip */
+        s->getc();
+
+    for (int i=h; i>0; i--) {
+        for (int j=x0; j>0; j--) /* Skip */
+            s->getc();
+        read(buf, w);
+        buf += w;
+        for (int j=W-w-x0; j>0; j--) /* Skip */
+            s->getc();
+    }
+    for (int i=(H-y0-h)*W; i>0; i--) /* Skip */
+        s->getc();
+    write(ACK1, sizeof(ACK1));
+
+    return 1;
+}
+
+// Write <len> characters from p to the serial
+void uCam::write(const unsigned char *p, int len) {
+    for (; len>0; len--, p++) {
+        s->putc(*p);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ucam.h	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,82 @@
+/* 4D Systems uCam serial RAW/JPEG camera library
+ * Copyright (c) 2011, Noriaki Mitsunaga
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef __UCAM_H__
+#define __UCAM_H__
+
+#include "mbed.h"
+
+#define UCAM_COLOR_TYPE_2BITG  0x1
+#define UCAM_COLOR_TYPE_4BITG  0x2
+#define UCAM_COLOR_TYPE_8BITG  0x3
+#define UCAM_COLOR_TYPE_RGB332 0x4
+#define UCAM_COLOR_TYPE_RGB444 0x5
+#define UCAM_COLOR_TYPE_RGB565 0x6
+#define UCAM_COLOR_TYPE_JPEG   0x7
+
+#define UCAM_RAW_RESOLUTION_80X60   0x1
+#define UCAM_RAW_RESOLUTION_160X120 0x3
+#define UCAM_RAW_RESOLUTION_320X240 0x5
+#define UCAM_RAW_RESOLUTION_640X480 0x7
+#define UCAM_RAW_RESOLUTION_128x128 0x9
+#define UCAM_RAW_RESOLUTION_128x96  0xB
+
+const int ucam_raw_resolution_w[] = {80, 160, 320, 640, 128, 128};
+const int ucam_raw_resolution_h[] = {60, 120, 240, 480, 128, 96};
+
+#define UCAM_JPEG_RESOLUTION_80X64   0x1
+#define UCAM_JPEG_RESOLUTION_160X128 0x3
+#define UCAM_JPEG_RESOLUTION_320X240 0x5
+#define UCAM_JPEG_RESOLUTION_640X480 0x7
+
+class uCam {
+public:
+    uCam(PinName tx, PinName rx) {
+        s = new Serial(tx, rx);
+        s->baud(57600);
+    }
+    ~uCam() {
+        delete s;
+    }
+
+    int Command(const unsigned char *cmd);
+    void ACK_F0F0();
+    int Init();
+    int LightFreq(int f);
+    void Reset();
+    int SnapshotRaw(int Color, int Res, unsigned char *buf);
+    int SnapshotRawCrop(int Color, int Res,
+                        int x0, int y0, int w, int h,
+                        unsigned char *buf);
+    int SnapshotJPEGi(int Res, int pksz);
+    int SnapshotJPEGd(int no, unsigned char *buf, int pksz);
+
+private:
+    Serial *s;
+
+    int  checkACK(const unsigned char *buf);
+    int  checkSYNC(const unsigned char *buf);
+    void read(unsigned char *p, int len);
+    int  readT(unsigned char *buf, int len);
+    void write(const unsigned char *p, int len);
+};
+
+#endif