A Simple library to capture pictures from the uCam by 4D Systems
Revision 0:68395cd065e4, committed 2012-05-29
- Comitter:
- ms523
- Date:
- Tue May 29 08:01:20 2012 +0000
- Commit message:
- Working with external FeRAM. Will require hacking to save the data to other formats of memory
Changed in this revision
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/uCam.cpp Tue May 29 08:01:20 2012 +0000 @@ -0,0 +1,391 @@ +#include "uCam.h" +#include "mbed.h" + +#define DEBUG + +// Set up some memory to hold the commands +const unsigned char SYNC[] = {0xAA, 0x0D, 0x00, 0x00, 0x00, 0x00}; +const unsigned char ACK[] = {0xAA, 0x0E, 0x0D, 0x00, 0x00, 0x00}; +const unsigned char BAUD_115200[] = {0xAA, 0x07, 0x01, 0x0F, 0x00, 0x00}; +const unsigned char BAUD_737280[] = {0xAA, 0x07, 0x00, 0x04, 0x00, 0x00}; +const unsigned char BAUD_921600[] = {0xAA, 0x07, 0x01, 0x01, 0x00, 0x00}; +const unsigned char BAUD_1228800[] = {0xAA, 0x07, 0x02, 0x00, 0x00, 0x00}; +const unsigned char GET_PICTURE[] = {0xAA, 0x04, 0x02, 0x00, 0x00, 0x00}; // take snapshot picture + +int picture_size; // To track the current picture size +DigitalOut led1(LED1),led2(LED2),led3(LED3),led4(LED4); + +uCam::uCam(PinName tx, PinName rx, int buffer) + : _uCam(tx,rx,buffer) { + + // Set the initial baud rate + _uCam.baud(115200); +} + +// Waits for an response from the uCam module and checks that a valid ACK was received +int uCam::Get_Response(unsigned char type, unsigned char command) { + // First wait for the uCam module to send the reply or timeout + // This waits for the module to become readable or timesout after 50 ms + char times = 0; // Variable to check for timeouts + do { + wait(0.001); // Wait 1 ms + times++; // Inc variable + if (_uCam.readable()) + break; + } while (times < 100 ); + // Check if it timed out + if (times > 99) { + printf("\n\r Response Timeout"); + return(0); + } + // Get the reply from the uCam module (will be 6 bytes + unsigned char reply[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + for (int i=0; i<6; i++) { + reply[i] = _uCam.getc(); + } + // Check reply was valid, A valid ACK should be 0xAA, 0x0E, Command ID, X, 0x00, 0x00 + if (reply[0] == 0xAA && reply[1] == type && reply[2] == command && reply[4] == 0x00 && reply[5] == 0x00) + // It was an ACK so return true + return(1); + else { + // Reply was invalid so print the reply and return false + return(0); + } +} + +int uCam::Sync() { + // This will give 60 attempts to sync with the uCam module + for (int i=0; i<=10; i ++) { + // Send out the sync command + for (int i=0; i<6; i++) { + _uCam.putc(SYNC[i]); + } + // Check if the response was an ACK + if (Get_Response(_ACK,SYNC[1])) { + // It was an ACK so now get the next response - it should be a sync + if (Get_Response(_SYNC,0x00)) { + // We need a small delay (1ms) from receiving the SYNC response and sending an ACK in return + wait(0.001); + for (int i=0; i<6; i++) { + _uCam.putc(ACK[i]); + } + // Everything is now complete so return true + return(1); + } + } + // Wait a while and try again + wait(0.01); + printf("\n\r Sync failed - trying again"); + } + // Something went wrong so return false + return(0); +} + +int uCam::SetBaud(int baud) { + // Send out the set baud command + for (int i=0; i<6; i++) { + // Select the correct data for the desired baud + if (baud == 115200) + _uCam.putc(BAUD_115200[i]); + else if (baud == 737280) + _uCam.putc(BAUD_737280[i]); + else if (baud == 921600) + _uCam.putc(BAUD_921600[i]); + else if (baud == 1228800) + _uCam.putc(BAUD_1228800[i]); + } + + // Check if the response was an ACK + if (Get_Response(_ACK,0x07)) { + // An ACk was received so we can now set the mbed to the new baud rate + _uCam.baud(baud); + // New baud rate confirmed - return true + return(1); + } else + // Something went wrong - return false + return(0); +} + +int uCam::Initial(unsigned char COLOUR, unsigned char RES) { + // Set up a buffer to hold the uCam response + unsigned char buf[6] = {0xAA, 0x01, 0x00, COLOUR, 0x00, 0x00}; + + //Amend the initial command for the type of image + if (buf[3]==0x07) { + buf[5] = RES; // The image is a JPEG so set byte 5 + } else { + buf[4] = RES; // The image is RAW so set byte 4 + } + + // Get the number of bytes to be transferred + // Start by finding out how many bytes per pixel + if (COLOUR == GREY_8BIT || COLOUR == COLOUR_8BIT) { + picture_size = 1; + } else if (COLOUR == COLOUR_16BIT) { + picture_size = 2; + } + // Then multiply this by the number of pixels + if (RES == RAW_80x60) + picture_size = picture_size*80*60; + else if (RES == RAW_160x120) + picture_size = picture_size*160*120; + else if (RES == RAW_320x240) + picture_size = picture_size*320*240; + else if (RES == RAW_640x480) + picture_size = picture_size*640*480; + else if (RES == RAW_128x128) + picture_size = picture_size*128*128; + else if (RES == RAW_128x96) + picture_size = picture_size*128*96; + + // Send out the initial command + for (int i=0; i<6; i++) { + _uCam.putc(buf[i]); + } + + // Check for ACK + if (Get_Response(_ACK,0x01)) { + // An ACk was received - return true + return(1); + } else { + // Something went wrong - return false + return(0); + } +} + +int uCam::Get_Picture(unsigned char *data) { + + // Send out the get picture command + for (int i=0; i<6; i++) { + _uCam.putc(GET_PICTURE[i]); + } + + if (!Get_Response(_ACK,0x04)) + // Something went wrong + return(0); + + // Get response from uCam + for (int i=0; i<picture_size; i++) { + if (_uCam.readable()) + data[i] = _uCam.getc(); + else { + i--; + } + } + + // We need a small delay (1ms) from receiving the SYNC response and sending an ACK in return + wait(0.001); + for (int i=0; i<6; i++) { + _uCam.putc(ACK[i]); + } + // Everything is now complete so return true + return(1); +} + +int uCam::Save_Picture_To_Memory(FeRAM &flash, int address) { + // Variables + unsigned char buf[6]; // Buffer to save data from uCam before its written to flash + int length; // The length of the incoing data (sent in data packet from uCam) + char binned = 0; // Escape variable to break out of function if some data isn't sent from uCam + Timer bin; // Timer to see if uCam has hung + + Timer t; + t.start(); + + // Send out the get picture command + for (int i=0; i<6; i++) { + _uCam.putc(GET_PICTURE[i]); + } + + if (!Get_Response(_ACK,0x04)) + // Something went wrong + return(0); +#ifdef DEBUG + printf("\n Getting picture"); +#endif + // Get the first 6 bytes + // Format 0xAA 0x0A (Data command), Data type, 3 bytes to show length + for (int i=0; i<6; i++) { + while (!_uCam.readable()) { + wait_us(1); + } + buf[i] = _uCam.getc(); // Get a byte of data + } + length = (buf[5] << 16) + (buf[4] << 8) + buf[3]; + + // Get response from uCam and save to flash + bin.start(); + for (int i=0; i<length; i++) { +#ifdef DEBUG + // See where we are... + if (i>length/4) + led1 = 1; + if (i>length/2) + led2 = 1; + if (i>length*3/4) + led3 = 1; +#endif + // reset the timer + bin.reset(); + + while (!_uCam.readable()) { +#ifdef DEBUG + led4 = 1; // Turn LED on to show we're waiting +#endif + // Check to see if we have been waiting for more than 10 ms + if (bin.read() > 0.01) { + printf("\n binned at %d",i); + binned = 1; + break; + } + } +#ifdef DEBUG + led4 = 0; // Turn LED off again +#endif + + // If this if statement runs than it means the uCam module has hung + if (binned) { + for (; i<length; i++) { + flash.write_byte(i + address, 0x00); // Fill the remaining bytes with 0x00 + } + break; // This breaks out of the loop and writes an ACk back to uCam + } + + // uCam has a byte of data ready to read - so go get it! + flash.write_byte(i + address, _uCam.getc()); + + } + // All data has been received so send an ACK back to the uCam module + _uCam.putc(0xAA); + _uCam.putc(0x0E); + _uCam.putc(0x0A); + _uCam.putc(0x00); + _uCam.putc(0x01); + _uCam.putc(0x00); + +#ifdef DEBUG + t.stop(); + //printf("\n Finished in %.3f Secs",t.read()); + + // Turn all the LEDs off + led1 = led2 = led3 = led4 = 0; +#endif + + // Everything is now complete so return true + return(1); +} + +int uCam::Save_Zoom_Picture_To_Memory(FeRAM &flash, int address){ + // Variables + unsigned char buf[6]; // Buffer to save data from uCam before its written to flash + unsigned char dummy; // Byte to read in unwanted info + int length; // The length of the incoing data (sent in data packet from uCam) + int pos = 0; + char binned = 0; // Escape variable to break out of function if some data isn't sent from uCam + Timer bin; // Timer to see if uCam has hung + + Timer t; + t.start(); + + // Send out the get picture command +#ifdef DEBUG + printf("\n\n\n\n\n\n\n\n\n\n"); +#endif + for (int i=0; i<6; i++) { + _uCam.putc(GET_PICTURE[i]); + #ifdef DEBUG + printf("[%X],",GET_PICTURE[i]); + #endif + } + + if (!Get_Response(_ACK,0x04)) + // Something went wrong + return(0); +#ifdef DEBUG + printf("\n Getting picture \n"); +#endif + // Get the first 6 bytes + // Format 0xAA 0x0A (Data command), Data type, 3 bytes to show length + for (int i=0; i<6; i++) { + while (!_uCam.readable()) { + wait_us(1); + } + buf[i] = _uCam.getc(); // Get a byte of data + printf("[%2X],",buf[i]); + } + length = (buf[5] << 16) + (buf[4] << 8) + buf[3]; +#ifdef DEBUG + printf("\n Length is: %d \n[%d] [%d] [%d]",length, buf[5], buf[4], buf[3]); +#endif + + // Get response from uCam and save to flash + bin.start(); + for (int i=0; i<length; i++) { +#ifdef DEBUG + // See where we are... + if (i>length/4) + led1 = 1; + if (i>length/2) + led2 = 1; + if (i>length*3/4) + led3 = 1; +#endif + // reset the timer + bin.reset(); + + while (!_uCam.readable()) { +#ifdef DEBUG + led4 = 1; // Turn LED on to show we're waiting +#endif + // Check to see if we have been waiting for more than 10 ms + if (bin.read() > 0.01) { + printf("\n binned at %d",i); + binned = 1; + break; + } + } +#ifdef DEBUG + led4 = 0; // Turn LED off again +#endif + + // If this if statement runs than it means the uCam module has hung + if (binned) { + for (; i<length; i++) { + flash.write_byte(i + address, 0x00); // Fill the remaining bytes with 0x00 + } + break; // This breaks out of the loop and writes an ACk back to uCam + } + + // uCam has a byte of data ready to read - so go get it! + // Need to check here if I actually want it! + if (i < 320 * 60 * 2 || i > 320 * 180 * 2) // Pixel is too high or low + dummy = _uCam.getc(); + else if (i % 640 < 160) // Pixel is too left + dummy = _uCam.getc(); + else if (i % 640 < 160 + 320){ // Pixel is in the centre - go get it! + flash.write_byte(pos + address, _uCam.getc()); + pos++; + } else // Pixel is too right + dummy = _uCam.getc(); + + + } + // All data has been received so send an ACK back to the uCam module + _uCam.putc(0xAA); + _uCam.putc(0x0E); + _uCam.putc(0x0A); + _uCam.putc(0x00); + _uCam.putc(0x01); + _uCam.putc(0x00); + +#ifdef DEBUG + t.stop(); + //printf("\n Finished in %.3f Secs",t.read()); + + // Turn all the LEDs off + led1 = led2 = led3 = led4 = 0; +#endif + + // Everything is now complete so return true + return(1); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uCam.h Tue May 29 08:01:20 2012 +0000 @@ -0,0 +1,61 @@ +#ifndef __UCAM_H__ +#define __UCAM_H__ + +#include "mbed.h" +#include "MODSERIAL.h" +#include "FeRAM.h" + +// Define colours +#define GREY_2BIT 0x01 +#define GREY_4BIT 0x02 +#define GREY_8BIT 0x03 +#define COLOUR_8BIT 0x04 +#define COLOUR_12BIT 0x05 +#define COLOUR_16BIT 0x06 +#define JPEG 0x07 +// Define RAW formats +#define RAW_80x60 0x01 +#define RAW_160x120 0x03 +#define RAW_320x240 0x05 +#define RAW_640x480 0x07 +#define RAW_128x128 0x09 +#define RAW_128x96 0x0B +// Define JPEG formats +#define JPEG_60x64 0x01 +#define JPEG_160x128 0x03 +#define JPEG_320x240 0x05 +#define JPEG_640x480 0x07 +// Define uCam responses +#define _ACK 0x0E +#define _SYNC 0x0D + +// mode codes for 23K256 +#define BYTE_MODE 0x00 +#define SEQUENTIAL_MODE 0x40 + +// command codes for 23K256 +#define READ 0x03 +#define WRITE 0x02 +#define READ_STATUS 0x05 // called RDSR in datasheet +#define WRITE_STATUS 0x01 // called WRSR in datasheet + +class uCam { +public: + // define which pins are used + uCam(PinName tx, PinName rx, int buffer); + + // Methods + int Sync(); + int SetBaud(int baud); + int Initial(unsigned char COLOUR, unsigned char RES); + int Get_Picture(unsigned char *data); + int Get_Response(unsigned char type, unsigned char command); + int Save_Picture_To_Memory(FeRAM &flash, int address); + int Save_Zoom_Picture_To_Memory(FeRAM &flash, int address); + +private: + MODSERIAL _uCam; // uCam TX and RX + +}; + +#endif \ No newline at end of file