A Simple library to capture pictures from the uCam by 4D Systems
uCam.cpp@0:68395cd065e4, 2012-05-29 (annotated)
- Committer:
- ms523
- Date:
- Tue May 29 08:01:20 2012 +0000
- Revision:
- 0:68395cd065e4
Working with external FeRAM. Will require hacking to save the data to other formats of memory
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ms523 | 0:68395cd065e4 | 1 | #include "uCam.h" |
ms523 | 0:68395cd065e4 | 2 | #include "mbed.h" |
ms523 | 0:68395cd065e4 | 3 | |
ms523 | 0:68395cd065e4 | 4 | #define DEBUG |
ms523 | 0:68395cd065e4 | 5 | |
ms523 | 0:68395cd065e4 | 6 | // Set up some memory to hold the commands |
ms523 | 0:68395cd065e4 | 7 | const unsigned char SYNC[] = {0xAA, 0x0D, 0x00, 0x00, 0x00, 0x00}; |
ms523 | 0:68395cd065e4 | 8 | const unsigned char ACK[] = {0xAA, 0x0E, 0x0D, 0x00, 0x00, 0x00}; |
ms523 | 0:68395cd065e4 | 9 | const unsigned char BAUD_115200[] = {0xAA, 0x07, 0x01, 0x0F, 0x00, 0x00}; |
ms523 | 0:68395cd065e4 | 10 | const unsigned char BAUD_737280[] = {0xAA, 0x07, 0x00, 0x04, 0x00, 0x00}; |
ms523 | 0:68395cd065e4 | 11 | const unsigned char BAUD_921600[] = {0xAA, 0x07, 0x01, 0x01, 0x00, 0x00}; |
ms523 | 0:68395cd065e4 | 12 | const unsigned char BAUD_1228800[] = {0xAA, 0x07, 0x02, 0x00, 0x00, 0x00}; |
ms523 | 0:68395cd065e4 | 13 | const unsigned char GET_PICTURE[] = {0xAA, 0x04, 0x02, 0x00, 0x00, 0x00}; // take snapshot picture |
ms523 | 0:68395cd065e4 | 14 | |
ms523 | 0:68395cd065e4 | 15 | int picture_size; // To track the current picture size |
ms523 | 0:68395cd065e4 | 16 | DigitalOut led1(LED1),led2(LED2),led3(LED3),led4(LED4); |
ms523 | 0:68395cd065e4 | 17 | |
ms523 | 0:68395cd065e4 | 18 | uCam::uCam(PinName tx, PinName rx, int buffer) |
ms523 | 0:68395cd065e4 | 19 | : _uCam(tx,rx,buffer) { |
ms523 | 0:68395cd065e4 | 20 | |
ms523 | 0:68395cd065e4 | 21 | // Set the initial baud rate |
ms523 | 0:68395cd065e4 | 22 | _uCam.baud(115200); |
ms523 | 0:68395cd065e4 | 23 | } |
ms523 | 0:68395cd065e4 | 24 | |
ms523 | 0:68395cd065e4 | 25 | // Waits for an response from the uCam module and checks that a valid ACK was received |
ms523 | 0:68395cd065e4 | 26 | int uCam::Get_Response(unsigned char type, unsigned char command) { |
ms523 | 0:68395cd065e4 | 27 | // First wait for the uCam module to send the reply or timeout |
ms523 | 0:68395cd065e4 | 28 | // This waits for the module to become readable or timesout after 50 ms |
ms523 | 0:68395cd065e4 | 29 | char times = 0; // Variable to check for timeouts |
ms523 | 0:68395cd065e4 | 30 | do { |
ms523 | 0:68395cd065e4 | 31 | wait(0.001); // Wait 1 ms |
ms523 | 0:68395cd065e4 | 32 | times++; // Inc variable |
ms523 | 0:68395cd065e4 | 33 | if (_uCam.readable()) |
ms523 | 0:68395cd065e4 | 34 | break; |
ms523 | 0:68395cd065e4 | 35 | } while (times < 100 ); |
ms523 | 0:68395cd065e4 | 36 | // Check if it timed out |
ms523 | 0:68395cd065e4 | 37 | if (times > 99) { |
ms523 | 0:68395cd065e4 | 38 | printf("\n\r Response Timeout"); |
ms523 | 0:68395cd065e4 | 39 | return(0); |
ms523 | 0:68395cd065e4 | 40 | } |
ms523 | 0:68395cd065e4 | 41 | // Get the reply from the uCam module (will be 6 bytes |
ms523 | 0:68395cd065e4 | 42 | unsigned char reply[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
ms523 | 0:68395cd065e4 | 43 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 44 | reply[i] = _uCam.getc(); |
ms523 | 0:68395cd065e4 | 45 | } |
ms523 | 0:68395cd065e4 | 46 | // Check reply was valid, A valid ACK should be 0xAA, 0x0E, Command ID, X, 0x00, 0x00 |
ms523 | 0:68395cd065e4 | 47 | if (reply[0] == 0xAA && reply[1] == type && reply[2] == command && reply[4] == 0x00 && reply[5] == 0x00) |
ms523 | 0:68395cd065e4 | 48 | // It was an ACK so return true |
ms523 | 0:68395cd065e4 | 49 | return(1); |
ms523 | 0:68395cd065e4 | 50 | else { |
ms523 | 0:68395cd065e4 | 51 | // Reply was invalid so print the reply and return false |
ms523 | 0:68395cd065e4 | 52 | return(0); |
ms523 | 0:68395cd065e4 | 53 | } |
ms523 | 0:68395cd065e4 | 54 | } |
ms523 | 0:68395cd065e4 | 55 | |
ms523 | 0:68395cd065e4 | 56 | int uCam::Sync() { |
ms523 | 0:68395cd065e4 | 57 | // This will give 60 attempts to sync with the uCam module |
ms523 | 0:68395cd065e4 | 58 | for (int i=0; i<=10; i ++) { |
ms523 | 0:68395cd065e4 | 59 | // Send out the sync command |
ms523 | 0:68395cd065e4 | 60 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 61 | _uCam.putc(SYNC[i]); |
ms523 | 0:68395cd065e4 | 62 | } |
ms523 | 0:68395cd065e4 | 63 | // Check if the response was an ACK |
ms523 | 0:68395cd065e4 | 64 | if (Get_Response(_ACK,SYNC[1])) { |
ms523 | 0:68395cd065e4 | 65 | // It was an ACK so now get the next response - it should be a sync |
ms523 | 0:68395cd065e4 | 66 | if (Get_Response(_SYNC,0x00)) { |
ms523 | 0:68395cd065e4 | 67 | // We need a small delay (1ms) from receiving the SYNC response and sending an ACK in return |
ms523 | 0:68395cd065e4 | 68 | wait(0.001); |
ms523 | 0:68395cd065e4 | 69 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 70 | _uCam.putc(ACK[i]); |
ms523 | 0:68395cd065e4 | 71 | } |
ms523 | 0:68395cd065e4 | 72 | // Everything is now complete so return true |
ms523 | 0:68395cd065e4 | 73 | return(1); |
ms523 | 0:68395cd065e4 | 74 | } |
ms523 | 0:68395cd065e4 | 75 | } |
ms523 | 0:68395cd065e4 | 76 | // Wait a while and try again |
ms523 | 0:68395cd065e4 | 77 | wait(0.01); |
ms523 | 0:68395cd065e4 | 78 | printf("\n\r Sync failed - trying again"); |
ms523 | 0:68395cd065e4 | 79 | } |
ms523 | 0:68395cd065e4 | 80 | // Something went wrong so return false |
ms523 | 0:68395cd065e4 | 81 | return(0); |
ms523 | 0:68395cd065e4 | 82 | } |
ms523 | 0:68395cd065e4 | 83 | |
ms523 | 0:68395cd065e4 | 84 | int uCam::SetBaud(int baud) { |
ms523 | 0:68395cd065e4 | 85 | // Send out the set baud command |
ms523 | 0:68395cd065e4 | 86 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 87 | // Select the correct data for the desired baud |
ms523 | 0:68395cd065e4 | 88 | if (baud == 115200) |
ms523 | 0:68395cd065e4 | 89 | _uCam.putc(BAUD_115200[i]); |
ms523 | 0:68395cd065e4 | 90 | else if (baud == 737280) |
ms523 | 0:68395cd065e4 | 91 | _uCam.putc(BAUD_737280[i]); |
ms523 | 0:68395cd065e4 | 92 | else if (baud == 921600) |
ms523 | 0:68395cd065e4 | 93 | _uCam.putc(BAUD_921600[i]); |
ms523 | 0:68395cd065e4 | 94 | else if (baud == 1228800) |
ms523 | 0:68395cd065e4 | 95 | _uCam.putc(BAUD_1228800[i]); |
ms523 | 0:68395cd065e4 | 96 | } |
ms523 | 0:68395cd065e4 | 97 | |
ms523 | 0:68395cd065e4 | 98 | // Check if the response was an ACK |
ms523 | 0:68395cd065e4 | 99 | if (Get_Response(_ACK,0x07)) { |
ms523 | 0:68395cd065e4 | 100 | // An ACk was received so we can now set the mbed to the new baud rate |
ms523 | 0:68395cd065e4 | 101 | _uCam.baud(baud); |
ms523 | 0:68395cd065e4 | 102 | // New baud rate confirmed - return true |
ms523 | 0:68395cd065e4 | 103 | return(1); |
ms523 | 0:68395cd065e4 | 104 | } else |
ms523 | 0:68395cd065e4 | 105 | // Something went wrong - return false |
ms523 | 0:68395cd065e4 | 106 | return(0); |
ms523 | 0:68395cd065e4 | 107 | } |
ms523 | 0:68395cd065e4 | 108 | |
ms523 | 0:68395cd065e4 | 109 | int uCam::Initial(unsigned char COLOUR, unsigned char RES) { |
ms523 | 0:68395cd065e4 | 110 | // Set up a buffer to hold the uCam response |
ms523 | 0:68395cd065e4 | 111 | unsigned char buf[6] = {0xAA, 0x01, 0x00, COLOUR, 0x00, 0x00}; |
ms523 | 0:68395cd065e4 | 112 | |
ms523 | 0:68395cd065e4 | 113 | //Amend the initial command for the type of image |
ms523 | 0:68395cd065e4 | 114 | if (buf[3]==0x07) { |
ms523 | 0:68395cd065e4 | 115 | buf[5] = RES; // The image is a JPEG so set byte 5 |
ms523 | 0:68395cd065e4 | 116 | } else { |
ms523 | 0:68395cd065e4 | 117 | buf[4] = RES; // The image is RAW so set byte 4 |
ms523 | 0:68395cd065e4 | 118 | } |
ms523 | 0:68395cd065e4 | 119 | |
ms523 | 0:68395cd065e4 | 120 | // Get the number of bytes to be transferred |
ms523 | 0:68395cd065e4 | 121 | // Start by finding out how many bytes per pixel |
ms523 | 0:68395cd065e4 | 122 | if (COLOUR == GREY_8BIT || COLOUR == COLOUR_8BIT) { |
ms523 | 0:68395cd065e4 | 123 | picture_size = 1; |
ms523 | 0:68395cd065e4 | 124 | } else if (COLOUR == COLOUR_16BIT) { |
ms523 | 0:68395cd065e4 | 125 | picture_size = 2; |
ms523 | 0:68395cd065e4 | 126 | } |
ms523 | 0:68395cd065e4 | 127 | // Then multiply this by the number of pixels |
ms523 | 0:68395cd065e4 | 128 | if (RES == RAW_80x60) |
ms523 | 0:68395cd065e4 | 129 | picture_size = picture_size*80*60; |
ms523 | 0:68395cd065e4 | 130 | else if (RES == RAW_160x120) |
ms523 | 0:68395cd065e4 | 131 | picture_size = picture_size*160*120; |
ms523 | 0:68395cd065e4 | 132 | else if (RES == RAW_320x240) |
ms523 | 0:68395cd065e4 | 133 | picture_size = picture_size*320*240; |
ms523 | 0:68395cd065e4 | 134 | else if (RES == RAW_640x480) |
ms523 | 0:68395cd065e4 | 135 | picture_size = picture_size*640*480; |
ms523 | 0:68395cd065e4 | 136 | else if (RES == RAW_128x128) |
ms523 | 0:68395cd065e4 | 137 | picture_size = picture_size*128*128; |
ms523 | 0:68395cd065e4 | 138 | else if (RES == RAW_128x96) |
ms523 | 0:68395cd065e4 | 139 | picture_size = picture_size*128*96; |
ms523 | 0:68395cd065e4 | 140 | |
ms523 | 0:68395cd065e4 | 141 | // Send out the initial command |
ms523 | 0:68395cd065e4 | 142 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 143 | _uCam.putc(buf[i]); |
ms523 | 0:68395cd065e4 | 144 | } |
ms523 | 0:68395cd065e4 | 145 | |
ms523 | 0:68395cd065e4 | 146 | // Check for ACK |
ms523 | 0:68395cd065e4 | 147 | if (Get_Response(_ACK,0x01)) { |
ms523 | 0:68395cd065e4 | 148 | // An ACk was received - return true |
ms523 | 0:68395cd065e4 | 149 | return(1); |
ms523 | 0:68395cd065e4 | 150 | } else { |
ms523 | 0:68395cd065e4 | 151 | // Something went wrong - return false |
ms523 | 0:68395cd065e4 | 152 | return(0); |
ms523 | 0:68395cd065e4 | 153 | } |
ms523 | 0:68395cd065e4 | 154 | } |
ms523 | 0:68395cd065e4 | 155 | |
ms523 | 0:68395cd065e4 | 156 | int uCam::Get_Picture(unsigned char *data) { |
ms523 | 0:68395cd065e4 | 157 | |
ms523 | 0:68395cd065e4 | 158 | // Send out the get picture command |
ms523 | 0:68395cd065e4 | 159 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 160 | _uCam.putc(GET_PICTURE[i]); |
ms523 | 0:68395cd065e4 | 161 | } |
ms523 | 0:68395cd065e4 | 162 | |
ms523 | 0:68395cd065e4 | 163 | if (!Get_Response(_ACK,0x04)) |
ms523 | 0:68395cd065e4 | 164 | // Something went wrong |
ms523 | 0:68395cd065e4 | 165 | return(0); |
ms523 | 0:68395cd065e4 | 166 | |
ms523 | 0:68395cd065e4 | 167 | // Get response from uCam |
ms523 | 0:68395cd065e4 | 168 | for (int i=0; i<picture_size; i++) { |
ms523 | 0:68395cd065e4 | 169 | if (_uCam.readable()) |
ms523 | 0:68395cd065e4 | 170 | data[i] = _uCam.getc(); |
ms523 | 0:68395cd065e4 | 171 | else { |
ms523 | 0:68395cd065e4 | 172 | i--; |
ms523 | 0:68395cd065e4 | 173 | } |
ms523 | 0:68395cd065e4 | 174 | } |
ms523 | 0:68395cd065e4 | 175 | |
ms523 | 0:68395cd065e4 | 176 | // We need a small delay (1ms) from receiving the SYNC response and sending an ACK in return |
ms523 | 0:68395cd065e4 | 177 | wait(0.001); |
ms523 | 0:68395cd065e4 | 178 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 179 | _uCam.putc(ACK[i]); |
ms523 | 0:68395cd065e4 | 180 | } |
ms523 | 0:68395cd065e4 | 181 | // Everything is now complete so return true |
ms523 | 0:68395cd065e4 | 182 | return(1); |
ms523 | 0:68395cd065e4 | 183 | } |
ms523 | 0:68395cd065e4 | 184 | |
ms523 | 0:68395cd065e4 | 185 | int uCam::Save_Picture_To_Memory(FeRAM &flash, int address) { |
ms523 | 0:68395cd065e4 | 186 | // Variables |
ms523 | 0:68395cd065e4 | 187 | unsigned char buf[6]; // Buffer to save data from uCam before its written to flash |
ms523 | 0:68395cd065e4 | 188 | int length; // The length of the incoing data (sent in data packet from uCam) |
ms523 | 0:68395cd065e4 | 189 | char binned = 0; // Escape variable to break out of function if some data isn't sent from uCam |
ms523 | 0:68395cd065e4 | 190 | Timer bin; // Timer to see if uCam has hung |
ms523 | 0:68395cd065e4 | 191 | |
ms523 | 0:68395cd065e4 | 192 | Timer t; |
ms523 | 0:68395cd065e4 | 193 | t.start(); |
ms523 | 0:68395cd065e4 | 194 | |
ms523 | 0:68395cd065e4 | 195 | // Send out the get picture command |
ms523 | 0:68395cd065e4 | 196 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 197 | _uCam.putc(GET_PICTURE[i]); |
ms523 | 0:68395cd065e4 | 198 | } |
ms523 | 0:68395cd065e4 | 199 | |
ms523 | 0:68395cd065e4 | 200 | if (!Get_Response(_ACK,0x04)) |
ms523 | 0:68395cd065e4 | 201 | // Something went wrong |
ms523 | 0:68395cd065e4 | 202 | return(0); |
ms523 | 0:68395cd065e4 | 203 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 204 | printf("\n Getting picture"); |
ms523 | 0:68395cd065e4 | 205 | #endif |
ms523 | 0:68395cd065e4 | 206 | // Get the first 6 bytes |
ms523 | 0:68395cd065e4 | 207 | // Format 0xAA 0x0A (Data command), Data type, 3 bytes to show length |
ms523 | 0:68395cd065e4 | 208 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 209 | while (!_uCam.readable()) { |
ms523 | 0:68395cd065e4 | 210 | wait_us(1); |
ms523 | 0:68395cd065e4 | 211 | } |
ms523 | 0:68395cd065e4 | 212 | buf[i] = _uCam.getc(); // Get a byte of data |
ms523 | 0:68395cd065e4 | 213 | } |
ms523 | 0:68395cd065e4 | 214 | length = (buf[5] << 16) + (buf[4] << 8) + buf[3]; |
ms523 | 0:68395cd065e4 | 215 | |
ms523 | 0:68395cd065e4 | 216 | // Get response from uCam and save to flash |
ms523 | 0:68395cd065e4 | 217 | bin.start(); |
ms523 | 0:68395cd065e4 | 218 | for (int i=0; i<length; i++) { |
ms523 | 0:68395cd065e4 | 219 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 220 | // See where we are... |
ms523 | 0:68395cd065e4 | 221 | if (i>length/4) |
ms523 | 0:68395cd065e4 | 222 | led1 = 1; |
ms523 | 0:68395cd065e4 | 223 | if (i>length/2) |
ms523 | 0:68395cd065e4 | 224 | led2 = 1; |
ms523 | 0:68395cd065e4 | 225 | if (i>length*3/4) |
ms523 | 0:68395cd065e4 | 226 | led3 = 1; |
ms523 | 0:68395cd065e4 | 227 | #endif |
ms523 | 0:68395cd065e4 | 228 | // reset the timer |
ms523 | 0:68395cd065e4 | 229 | bin.reset(); |
ms523 | 0:68395cd065e4 | 230 | |
ms523 | 0:68395cd065e4 | 231 | while (!_uCam.readable()) { |
ms523 | 0:68395cd065e4 | 232 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 233 | led4 = 1; // Turn LED on to show we're waiting |
ms523 | 0:68395cd065e4 | 234 | #endif |
ms523 | 0:68395cd065e4 | 235 | // Check to see if we have been waiting for more than 10 ms |
ms523 | 0:68395cd065e4 | 236 | if (bin.read() > 0.01) { |
ms523 | 0:68395cd065e4 | 237 | printf("\n binned at %d",i); |
ms523 | 0:68395cd065e4 | 238 | binned = 1; |
ms523 | 0:68395cd065e4 | 239 | break; |
ms523 | 0:68395cd065e4 | 240 | } |
ms523 | 0:68395cd065e4 | 241 | } |
ms523 | 0:68395cd065e4 | 242 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 243 | led4 = 0; // Turn LED off again |
ms523 | 0:68395cd065e4 | 244 | #endif |
ms523 | 0:68395cd065e4 | 245 | |
ms523 | 0:68395cd065e4 | 246 | // If this if statement runs than it means the uCam module has hung |
ms523 | 0:68395cd065e4 | 247 | if (binned) { |
ms523 | 0:68395cd065e4 | 248 | for (; i<length; i++) { |
ms523 | 0:68395cd065e4 | 249 | flash.write_byte(i + address, 0x00); // Fill the remaining bytes with 0x00 |
ms523 | 0:68395cd065e4 | 250 | } |
ms523 | 0:68395cd065e4 | 251 | break; // This breaks out of the loop and writes an ACk back to uCam |
ms523 | 0:68395cd065e4 | 252 | } |
ms523 | 0:68395cd065e4 | 253 | |
ms523 | 0:68395cd065e4 | 254 | // uCam has a byte of data ready to read - so go get it! |
ms523 | 0:68395cd065e4 | 255 | flash.write_byte(i + address, _uCam.getc()); |
ms523 | 0:68395cd065e4 | 256 | |
ms523 | 0:68395cd065e4 | 257 | } |
ms523 | 0:68395cd065e4 | 258 | // All data has been received so send an ACK back to the uCam module |
ms523 | 0:68395cd065e4 | 259 | _uCam.putc(0xAA); |
ms523 | 0:68395cd065e4 | 260 | _uCam.putc(0x0E); |
ms523 | 0:68395cd065e4 | 261 | _uCam.putc(0x0A); |
ms523 | 0:68395cd065e4 | 262 | _uCam.putc(0x00); |
ms523 | 0:68395cd065e4 | 263 | _uCam.putc(0x01); |
ms523 | 0:68395cd065e4 | 264 | _uCam.putc(0x00); |
ms523 | 0:68395cd065e4 | 265 | |
ms523 | 0:68395cd065e4 | 266 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 267 | t.stop(); |
ms523 | 0:68395cd065e4 | 268 | //printf("\n Finished in %.3f Secs",t.read()); |
ms523 | 0:68395cd065e4 | 269 | |
ms523 | 0:68395cd065e4 | 270 | // Turn all the LEDs off |
ms523 | 0:68395cd065e4 | 271 | led1 = led2 = led3 = led4 = 0; |
ms523 | 0:68395cd065e4 | 272 | #endif |
ms523 | 0:68395cd065e4 | 273 | |
ms523 | 0:68395cd065e4 | 274 | // Everything is now complete so return true |
ms523 | 0:68395cd065e4 | 275 | return(1); |
ms523 | 0:68395cd065e4 | 276 | } |
ms523 | 0:68395cd065e4 | 277 | |
ms523 | 0:68395cd065e4 | 278 | int uCam::Save_Zoom_Picture_To_Memory(FeRAM &flash, int address){ |
ms523 | 0:68395cd065e4 | 279 | // Variables |
ms523 | 0:68395cd065e4 | 280 | unsigned char buf[6]; // Buffer to save data from uCam before its written to flash |
ms523 | 0:68395cd065e4 | 281 | unsigned char dummy; // Byte to read in unwanted info |
ms523 | 0:68395cd065e4 | 282 | int length; // The length of the incoing data (sent in data packet from uCam) |
ms523 | 0:68395cd065e4 | 283 | int pos = 0; |
ms523 | 0:68395cd065e4 | 284 | char binned = 0; // Escape variable to break out of function if some data isn't sent from uCam |
ms523 | 0:68395cd065e4 | 285 | Timer bin; // Timer to see if uCam has hung |
ms523 | 0:68395cd065e4 | 286 | |
ms523 | 0:68395cd065e4 | 287 | Timer t; |
ms523 | 0:68395cd065e4 | 288 | t.start(); |
ms523 | 0:68395cd065e4 | 289 | |
ms523 | 0:68395cd065e4 | 290 | // Send out the get picture command |
ms523 | 0:68395cd065e4 | 291 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 292 | printf("\n\n\n\n\n\n\n\n\n\n"); |
ms523 | 0:68395cd065e4 | 293 | #endif |
ms523 | 0:68395cd065e4 | 294 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 295 | _uCam.putc(GET_PICTURE[i]); |
ms523 | 0:68395cd065e4 | 296 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 297 | printf("[%X],",GET_PICTURE[i]); |
ms523 | 0:68395cd065e4 | 298 | #endif |
ms523 | 0:68395cd065e4 | 299 | } |
ms523 | 0:68395cd065e4 | 300 | |
ms523 | 0:68395cd065e4 | 301 | if (!Get_Response(_ACK,0x04)) |
ms523 | 0:68395cd065e4 | 302 | // Something went wrong |
ms523 | 0:68395cd065e4 | 303 | return(0); |
ms523 | 0:68395cd065e4 | 304 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 305 | printf("\n Getting picture \n"); |
ms523 | 0:68395cd065e4 | 306 | #endif |
ms523 | 0:68395cd065e4 | 307 | // Get the first 6 bytes |
ms523 | 0:68395cd065e4 | 308 | // Format 0xAA 0x0A (Data command), Data type, 3 bytes to show length |
ms523 | 0:68395cd065e4 | 309 | for (int i=0; i<6; i++) { |
ms523 | 0:68395cd065e4 | 310 | while (!_uCam.readable()) { |
ms523 | 0:68395cd065e4 | 311 | wait_us(1); |
ms523 | 0:68395cd065e4 | 312 | } |
ms523 | 0:68395cd065e4 | 313 | buf[i] = _uCam.getc(); // Get a byte of data |
ms523 | 0:68395cd065e4 | 314 | printf("[%2X],",buf[i]); |
ms523 | 0:68395cd065e4 | 315 | } |
ms523 | 0:68395cd065e4 | 316 | length = (buf[5] << 16) + (buf[4] << 8) + buf[3]; |
ms523 | 0:68395cd065e4 | 317 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 318 | printf("\n Length is: %d \n[%d] [%d] [%d]",length, buf[5], buf[4], buf[3]); |
ms523 | 0:68395cd065e4 | 319 | #endif |
ms523 | 0:68395cd065e4 | 320 | |
ms523 | 0:68395cd065e4 | 321 | // Get response from uCam and save to flash |
ms523 | 0:68395cd065e4 | 322 | bin.start(); |
ms523 | 0:68395cd065e4 | 323 | for (int i=0; i<length; i++) { |
ms523 | 0:68395cd065e4 | 324 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 325 | // See where we are... |
ms523 | 0:68395cd065e4 | 326 | if (i>length/4) |
ms523 | 0:68395cd065e4 | 327 | led1 = 1; |
ms523 | 0:68395cd065e4 | 328 | if (i>length/2) |
ms523 | 0:68395cd065e4 | 329 | led2 = 1; |
ms523 | 0:68395cd065e4 | 330 | if (i>length*3/4) |
ms523 | 0:68395cd065e4 | 331 | led3 = 1; |
ms523 | 0:68395cd065e4 | 332 | #endif |
ms523 | 0:68395cd065e4 | 333 | // reset the timer |
ms523 | 0:68395cd065e4 | 334 | bin.reset(); |
ms523 | 0:68395cd065e4 | 335 | |
ms523 | 0:68395cd065e4 | 336 | while (!_uCam.readable()) { |
ms523 | 0:68395cd065e4 | 337 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 338 | led4 = 1; // Turn LED on to show we're waiting |
ms523 | 0:68395cd065e4 | 339 | #endif |
ms523 | 0:68395cd065e4 | 340 | // Check to see if we have been waiting for more than 10 ms |
ms523 | 0:68395cd065e4 | 341 | if (bin.read() > 0.01) { |
ms523 | 0:68395cd065e4 | 342 | printf("\n binned at %d",i); |
ms523 | 0:68395cd065e4 | 343 | binned = 1; |
ms523 | 0:68395cd065e4 | 344 | break; |
ms523 | 0:68395cd065e4 | 345 | } |
ms523 | 0:68395cd065e4 | 346 | } |
ms523 | 0:68395cd065e4 | 347 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 348 | led4 = 0; // Turn LED off again |
ms523 | 0:68395cd065e4 | 349 | #endif |
ms523 | 0:68395cd065e4 | 350 | |
ms523 | 0:68395cd065e4 | 351 | // If this if statement runs than it means the uCam module has hung |
ms523 | 0:68395cd065e4 | 352 | if (binned) { |
ms523 | 0:68395cd065e4 | 353 | for (; i<length; i++) { |
ms523 | 0:68395cd065e4 | 354 | flash.write_byte(i + address, 0x00); // Fill the remaining bytes with 0x00 |
ms523 | 0:68395cd065e4 | 355 | } |
ms523 | 0:68395cd065e4 | 356 | break; // This breaks out of the loop and writes an ACk back to uCam |
ms523 | 0:68395cd065e4 | 357 | } |
ms523 | 0:68395cd065e4 | 358 | |
ms523 | 0:68395cd065e4 | 359 | // uCam has a byte of data ready to read - so go get it! |
ms523 | 0:68395cd065e4 | 360 | // Need to check here if I actually want it! |
ms523 | 0:68395cd065e4 | 361 | if (i < 320 * 60 * 2 || i > 320 * 180 * 2) // Pixel is too high or low |
ms523 | 0:68395cd065e4 | 362 | dummy = _uCam.getc(); |
ms523 | 0:68395cd065e4 | 363 | else if (i % 640 < 160) // Pixel is too left |
ms523 | 0:68395cd065e4 | 364 | dummy = _uCam.getc(); |
ms523 | 0:68395cd065e4 | 365 | else if (i % 640 < 160 + 320){ // Pixel is in the centre - go get it! |
ms523 | 0:68395cd065e4 | 366 | flash.write_byte(pos + address, _uCam.getc()); |
ms523 | 0:68395cd065e4 | 367 | pos++; |
ms523 | 0:68395cd065e4 | 368 | } else // Pixel is too right |
ms523 | 0:68395cd065e4 | 369 | dummy = _uCam.getc(); |
ms523 | 0:68395cd065e4 | 370 | |
ms523 | 0:68395cd065e4 | 371 | |
ms523 | 0:68395cd065e4 | 372 | } |
ms523 | 0:68395cd065e4 | 373 | // All data has been received so send an ACK back to the uCam module |
ms523 | 0:68395cd065e4 | 374 | _uCam.putc(0xAA); |
ms523 | 0:68395cd065e4 | 375 | _uCam.putc(0x0E); |
ms523 | 0:68395cd065e4 | 376 | _uCam.putc(0x0A); |
ms523 | 0:68395cd065e4 | 377 | _uCam.putc(0x00); |
ms523 | 0:68395cd065e4 | 378 | _uCam.putc(0x01); |
ms523 | 0:68395cd065e4 | 379 | _uCam.putc(0x00); |
ms523 | 0:68395cd065e4 | 380 | |
ms523 | 0:68395cd065e4 | 381 | #ifdef DEBUG |
ms523 | 0:68395cd065e4 | 382 | t.stop(); |
ms523 | 0:68395cd065e4 | 383 | //printf("\n Finished in %.3f Secs",t.read()); |
ms523 | 0:68395cd065e4 | 384 | |
ms523 | 0:68395cd065e4 | 385 | // Turn all the LEDs off |
ms523 | 0:68395cd065e4 | 386 | led1 = led2 = led3 = led4 = 0; |
ms523 | 0:68395cd065e4 | 387 | #endif |
ms523 | 0:68395cd065e4 | 388 | |
ms523 | 0:68395cd065e4 | 389 | // Everything is now complete so return true |
ms523 | 0:68395cd065e4 | 390 | return(1); |
ms523 | 0:68395cd065e4 | 391 | } |