D D / Mbed 2 deprecated DISCO_L475VG_IOT01-Telegram-BOT

Dependencies:   BSP_B-L475E-IOT01 mbed es_wifi jsmn

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ArduCAM2640.h Source File

ArduCAM2640.h

00001 /*
00002   ArduCAM.h - Arduino library support for CMOS Image Sensor
00003   Copyright (C)2011-2015 ArduCAM.com. All right reserved
00004   
00005   Basic functionality of this library are based on the demo-code provided by
00006   ArduCAM.com. You can find the latest version of the library at
00007   http://www.ArduCAM.com
00008 
00009   Now supported controllers:
00010         -   OV7670
00011         -   MT9D111
00012         -   OV7675
00013         -   OV2640
00014         -   OV3640
00015         -   OV5642
00016         -   OV7660
00017         -   OV7725
00018         - MT9M112       
00019         - MT9V111
00020         - OV5640        
00021         - MT9M001           
00022                 
00023     We will add support for many other sensors in next release.
00024     
00025   Supported MCU platform
00026         -   Theoretically support all Arduino families
00027         -   Arduino UNO R3          (Tested)
00028         -   Arduino MEGA2560 R3     (Tested)
00029         -   Arduino Leonardo R3     (Tested)
00030         -   Arduino Nano            (Tested)
00031         -   Arduino DUE             (Tested)
00032         - Arduino Yun               (Tested)        
00033         -   Raspberry Pi            (Tested)
00034         
00035 
00036   If you make any modifications or improvements to the code, I would appreciate
00037   that you share the code with me so that I might include it in the next release.
00038   I can be contacted through http://www.ArduCAM.com
00039 
00040   This library is free software; you can redistribute it and/or
00041   modify it under the terms of the GNU Lesser General Public
00042   License as published by the Free Software Foundation; either
00043   version 2.1 of the License, or (at your option) any later version.
00044 
00045   This library is distributed in the hope that it will be useful,
00046   but WITHOUT ANY WARRANTY; without even the implied warranty of
00047   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00048   Lesser General Public License for more details.
00049 
00050   You should have received a copy of the GNU Lesser General Public
00051   License along with this library; if not, write to the Free Software
00052   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00053 */
00054 
00055 /*------------------------------------
00056     Revision History:
00057     2012/09/20  V1.0.0  by Lee  first release 
00058     2012/10/23  V1.0.1  by Lee  Resolved some timing issue for the Read/Write Register  
00059     2012/11/29  V1.1.0  by Lee  Add support for MT9D111 sensor
00060     2012/12/13  V1.2.0  by Lee  Add support for OV7675 sensor
00061     2012/12/28  V1.3.0  by Lee  Add support for OV2640,OV3640,OV5642 sensors
00062     2013/02/26  V2.0.0  by Lee  New Rev.B shield hardware, add support for FIFO control 
00063                                                             and support Mega1280/2560 boards 
00064     2013/05/28  V2.1.0  by Lee  Add support all drawing functions derived from UTFT library             
00065     2013/08/24  V3.0.0  by Lee  Support ArudCAM shield Rev.C hardware, features SPI interface and low power mode.
00066                                 Support almost all series of Arduino boards including DUE.  
00067     2014/03/09  V3.1.0  by Lee  Add the more impressive example sketches. 
00068                                 Optimise the OV5642 settings, improve image quality.
00069                                 Add live preview before JPEG capture.
00070                                 Add play back photos one by one after BMP capture.
00071     2014/05/01  V3.1.1  by Lee  Minor changes to add support Arduino IDE for linux distributions.   
00072     2014/09/30  V3.2.0  by Lee  Improvement on OV5642 camera dirver.            
00073     2014/10/06  V3.3.0  by Lee  Add OV7660,OV7725 camera support.           
00074     2015/02/27  V3.4.0  by Lee  Add the support for Arduino Yun board, update the latest UTFT library for ArduCAM.          
00075     2015/06/09  V3.4.1  by Lee  Minor changes and add some comments     
00076     2015/06/19  V3.4.2  by Lee  Add support for MT9M112 camera.         
00077     2015/06/20  V3.4.3  by Lee  Add support for MT9V111 camera.         
00078     2015/06/22  V3.4.4  by Lee  Add support for OV5640 camera.                                      
00079     2015/06/22  V3.4.5  by Lee  Add support for MT9M001 camera.                                                             
00080 --------------------------------------*/
00081 
00082 /*
00083 Parts of this software is related to https://os.mbed.com/users/dflet/ work.
00084 */
00085 
00086 
00087 #pragma once
00088 
00089 #include <mbed.h>
00090 #include "arducam_regs.h"
00091 
00092 /****************************************************/
00093 /* Sensor related definition                                                */
00094 /****************************************************/
00095 /****************************************************/
00096 /* ArduChip related definition                                          */
00097 /****************************************************/
00098 #define RWBIT                   0x80  //READ AND WRITE BIT IS BIT[7]
00099 
00100 #define ARDUCHIP_TEST1          0x00  //TEST register
00101 #define ARDUCHIP_TEST2          0x01  //TEST register
00102 
00103 #define ARDUCHIP_FRAMES         0x01  //Bit[2:0]Number of frames to be captured
00104 
00105 #define ARDUCHIP_MODE           0x02  //Mode register
00106 #define MCU2LCD_MODE            0x00
00107 #define CAM2LCD_MODE            0x01
00108 #define LCD2MCU_MODE            0x02
00109 
00110 #define ARDUCHIP_TIM            0x03  //Timming control
00111 #define HREF_LEVEL_MASK         0x01  //0 = High active ,       1 = Low active
00112 #define VSYNC_LEVEL_MASK        0x02  //0 = High active ,       1 = Low active
00113 #define LCD_BKEN_MASK           0x04  //0 = Enable,             1 = Disable
00114 #define DELAY_MASK              0x08  //0 = no delay,           1 = delay one clock
00115 #define MODE_MASK               0x10  //0 = LCD mode,           1 = FIFO mode
00116 #define FIFO_PWRDN_MASK         0x20  //0 = Normal operation,   1 = FIFO power down
00117 #define LOW_POWER_MODE          0x40  //0 = Normal mode,        1 = Low power mode
00118 
00119 #define ARDUCHIP_FIFO           0x04  //FIFO and I2C control
00120 #define FIFO_CLEAR_MASK         0x01
00121 #define FIFO_START_MASK         0x02
00122 #define FIFO_RDPTR_RST_MASK     0x10
00123 #define FIFO_WRPTR_RST_MASK     0x20
00124 
00125 #define ARDUCHIP_GPIO           0x06  //GPIO Write Register
00126 #define GPIO_RESET_MASK         0x01  //0 = default state,      1 =  Sensor reset IO value
00127 #define GPIO_PWDN_MASK          0x02  //0 = Sensor power down IO value, 1 = Sensor power enable IO value
00128 
00129 #define BURST_FIFO_READ         0x3C  //Burst FIFO read operation
00130 #define SINGLE_FIFO_READ        0x3D  //Single FIFO read operation
00131 
00132 #define ARDUCHIP_REV            0x40  //ArduCHIP revision
00133 #define VER_LOW_MASK            0x3F
00134 #define VER_HIGH_MASK           0xC0
00135 
00136 #define ARDUCHIP_TRIG           0x41  //Trigger source
00137 #define VSYNC_MASK              0x01
00138 #define SHUTTER_MASK            0x02
00139 #define CAP_DONE_MASK           0x08
00140 
00141 #define FIFO_SIZE1              0x42  //Camera write FIFO size[7:0] for burst to read
00142 #define FIFO_SIZE2              0x43  //Camera write FIFO size[15:8]
00143 #define FIFO_SIZE3              0x44  //Camera write FIFO size[18:16]
00144 
00145 #define OV2640_CHIPID_HIGH  0x0A
00146 #define OV2640_CHIPID_LOW   0x0B
00147 #define OV2640_CHIPID_HIGH_VALUE 0x26
00148 #define OV2640_CHIPID_LOW_VALUE 0x42
00149 
00150 /****************************************************/
00151 
00152 
00153 #define OV_RESOLUTION_VGA 1
00154 #define OV_RESOLUTION_QVGA 2
00155 #define OV_RESOLUTION_CIF 3
00156 #define OV_RESOLUTION_QQVGA 4
00157 
00158 #define OV2640_I2C_ADDR_W 0x0060
00159 #define OV2640_I2C_ADDR_R 0x0061
00160 
00161 class ArduCAM2640
00162 {
00163 public:
00164 
00165     // ctor dtor
00166     ArduCAM2640(){};
00167     ~ArduCAM2640(){};
00168 
00169     // setup
00170     bool Setup(int resolution,int jpeg_quality,DigitalOut *cam_cs, SPI *cam_spi, I2C *cam_i2c)
00171     {
00172         uint8_t vid = 0;
00173         uint8_t pid = 0;
00174         const struct sensor_reg8 *pivot;
00175 
00176         _cam_cs  = cam_cs;
00177         _cam_spi = cam_spi;
00178         _cam_i2c = cam_i2c;
00179 
00180         _cam_spi->format(8,0);
00181         _cam_spi->frequency(8000000);
00182         _cam_i2c->frequency(100000);
00183         *_cam_cs = 1;
00184 
00185         /* check spi i2c */
00186         wrSensorReg8_8(0xFF,0x01);
00187         rdSensorReg8_8(OV2640_CHIPID_HIGH,&vid);
00188         rdSensorReg8_8(OV2640_CHIPID_LOW,&pid);
00189         if ((vid != OV2640_CHIPID_HIGH_VALUE) || (pid != OV2640_CHIPID_LOW_VALUE))
00190         {
00191             printf("Can't find OV2640 module! vid = 0x%x pid = 0x%x\r\n", vid, pid);
00192             return false;
00193         }
00194 
00195         /* setup resolution and jpeg quality */
00196         wrSensorReg8_8(0xFF,0x01);
00197         wrSensorReg8_8(0x12,0x80);
00198         wait_ms(200);
00199 
00200         pivot = &OV2640_JPEG_INIT[0];
00201         while(1)
00202         {
00203             if(pivot->reg == 0xff && pivot->val == 0xff) break;
00204             // quality register
00205             if(pivot->reg == 0x44)
00206             {
00207                 wrSensorReg8_8(pivot->reg,(uint8_t)100-jpeg_quality);
00208             }
00209             else
00210                 wrSensorReg8_8(pivot->reg,pivot->val);
00211             pivot++;
00212         }
00213 
00214         pivot = &OV2640_YUV422[0];
00215         while(1)
00216         {
00217             if(pivot->reg == 0xff && pivot->val == 0xff) break;
00218             wrSensorReg8_8(pivot->reg,pivot->val);
00219             pivot++;
00220         }
00221 
00222         pivot = &OV2640_JPEG[0];
00223         while(1)
00224         {
00225             if(pivot->reg == 0xff && pivot->val == 0xff) break;
00226             wrSensorReg8_8(pivot->reg,pivot->val);
00227             pivot++;
00228         }
00229 
00230         wrSensorReg8_8(0xFF,0x01);
00231         wrSensorReg8_8(0x15,0x00);
00232 
00233         switch(resolution)
00234         {
00235         case OV_RESOLUTION_VGA:
00236             pivot = &OV2640_640x480_JPEG[0];
00237             break;
00238         case OV_RESOLUTION_QVGA:
00239             pivot = &OV2640_320x240_JPEG[0];
00240             break;
00241         case OV_RESOLUTION_QQVGA:
00242             pivot = &OV2640_160x120_JPEG[0];
00243             break;
00244         case OV_RESOLUTION_CIF:
00245             pivot = &OV2640_352x288_JPEG[0];
00246             break;
00247         default:
00248             printf("Wrong resolution\r\n");
00249             return false;
00250         };
00251 
00252         while(1)
00253         {
00254             if(pivot->reg == 0xff && pivot->val == 0xff) break;
00255             wrSensorReg8_8(pivot->reg,pivot->val);
00256             pivot++;
00257         }
00258 
00259         wait_ms(2000);
00260 
00261         return true;
00262     };
00263 
00264     uint32_t CaptureImage(uint8_t *image_buffer, uint32_t image_buffer_size,uint32_t *jpeg_start_index)
00265     {
00266         uint32_t fifolen = 0;
00267         uint32_t jpeg_start,jpeg_end;
00268 
00269             flush_fifo();
00270             start_capture();
00271             while (!(get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)))
00272             {
00273                 wait_ms(30);
00274             }
00275 
00276             fifolen = read_fifo_length() + 2;
00277             if(fifolen>image_buffer_size) 
00278             {
00279                 printf("Arducam::CaptureImage fifo_len %d exceeds image_buffer_size %d\r\n",fifolen,image_buffer_size);
00280                 return 0;
00281             }
00282             printf("fifo len %d\r\n",fifolen);
00283 
00284             image_buffer[0]=BURST_FIFO_READ;
00285             *_cam_cs = 0; 
00286             _cam_spi->write((char*)image_buffer,fifolen,(char*)image_buffer,fifolen);
00287             *_cam_cs = 1;
00288 
00289             jpeg_start = image_buffer_size;
00290             jpeg_end = 0;
00291             for(int i=0;i<fifolen-1;i++)
00292             {
00293                 if(image_buffer[i] == 0xFF)
00294                 {
00295                     if(image_buffer[i+1] == 0xD8 && jpeg_start == image_buffer_size)
00296                     {
00297                         jpeg_start = i;
00298                     }
00299                     else if(image_buffer[i+1] == 0xD9 && jpeg_end == 0)
00300                     {
00301                         jpeg_end = i+1;
00302                         break;
00303                     }
00304                 }
00305             }
00306 
00307             if( jpeg_start != image_buffer_size && jpeg_end != 0 )
00308             {
00309                 *jpeg_start_index = jpeg_start;
00310                 return (jpeg_end - jpeg_start + 1);
00311             }   
00312 
00313             return 0;
00314     };
00315 
00316 private:
00317     DigitalOut          *_cam_cs;
00318     SPI                 *_cam_spi;  
00319     I2C                 *_cam_i2c;
00320 
00321     //Low level SPI write operation
00322     int bus_write(int address, int value) 
00323     {
00324         // take the SS pin low to select the chip:
00325         *_cam_cs = 0;
00326         //  send in the address and value via SPI:
00327         _cam_spi->write(address);
00328         _cam_spi->write(value);
00329         // take the SS pin high to de-select the chip:
00330         *_cam_cs = 1;
00331         
00332         return 0;
00333     };
00334 
00335     //Low level SPI read operation
00336     uint8_t bus_read(int address) 
00337     {
00338         uint8_t value = 0;
00339         // take the SS pin low to select the chip:
00340         *_cam_cs = 0;
00341         //  send in the address and value via SPI:
00342         //  printf("addr = 0x%x\r\n",address);
00343         _cam_spi->write(address);
00344         value = _cam_spi->write(0x00);
00345         // take the SS pin high to de-select the chip:
00346         *_cam_cs = 1;
00347         return value;
00348     };
00349 
00350     //Write ArduChip internal registers
00351     void write_reg(uint8_t addr, uint8_t data)
00352     {
00353         bus_write(addr | 0x80, data);
00354     };
00355 
00356     //Read ArduChip internal registers
00357     uint8_t read_reg(uint8_t addr)
00358     {
00359         uint8_t data;
00360         data = bus_read(addr);
00361         return data;
00362     };
00363 
00364     //Reset the FIFO pointer to ZERO        
00365     void flush_fifo(void)
00366     {
00367         write_reg(ARDUCHIP_FIFO, FIFO_CLEAR_MASK);
00368     };
00369 
00370     //Send capture command
00371     void start_capture(void)
00372     {
00373         write_reg(ARDUCHIP_FIFO, FIFO_START_MASK);
00374     };
00375 
00376     //Clear FIFO Complete flag
00377     void clear_fifo_flag(void)
00378     {
00379         write_reg(ARDUCHIP_FIFO, FIFO_CLEAR_MASK);
00380     };
00381 
00382 
00383     //Read Write FIFO length
00384     //Support ArduCAM Mini only
00385     uint32_t read_fifo_length(void)
00386     {
00387         uint32_t len1,len2,len3=0;
00388         uint32_t length=0;
00389         len1 = read_reg(FIFO_SIZE1);    
00390         len2 = read_reg(FIFO_SIZE2);    
00391         len3 = read_reg(FIFO_SIZE3) & 0x07;
00392         length = ((len3 << 16) | (len2 << 8) | len1);// & 0x07ffff;
00393         return length;
00394     };
00395 
00396     //I2C Write 8bit address, 8bit data
00397     uint8_t wrSensorReg8_8(int regID, int regDat)
00398     {
00399         uint8_t buff[2];
00400         buff[0] = regID;
00401         buff[1] = regDat;
00402         _cam_i2c->write(OV2640_I2C_ADDR_W,(char*)buff,2);
00403         return(1);
00404     };
00405 
00406     //I2C Read 8bit address, 8bit data
00407     uint8_t rdSensorReg8_8(uint8_t regID, uint8_t* regDat)
00408     {
00409         _cam_i2c->write(OV2640_I2C_ADDR_W,(char*)&regID,1);
00410         _cam_i2c->read(OV2640_I2C_ADDR_R,(char*)regDat,1);
00411         return(1);
00412     };
00413 
00414     //Get corresponding bit status
00415     uint8_t get_bit(uint8_t addr, uint8_t bit)
00416     {
00417         uint8_t temp;
00418         temp = read_reg(addr);
00419         temp = temp & bit;
00420         return temp;
00421     };
00422 
00423 };
00424