This is the sample program that can see the decode result of barcode data on Watson IoT.

Dependencies:   AsciiFont DisplayApp GR-PEACH_video LCD_shield_config LWIPBP3595Interface_STA_for_mbed-os USBDevice

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ZXingResource.h Source File

ZXingResource.h

Go to the documentation of this file.
00001 /**
00002  * @file    ZXingResource.h
00003  * @brief   mbed CoAP Endpoint Accelerometer sensor resource supporting CoAP GET
00004  * @author  Doug Anson
00005  * @version 1.0
00006  * @see
00007  *
00008  * Copyright (c) 2014
00009  *
00010  * Licensed under the Apache License, Version 2.0 (the "License");
00011  * you may not use this file except in compliance with the License.
00012  * You may obtain a copy of the License at
00013  *
00014  *     http://www.apache.org/licenses/LICENSE-2.0
00015  *
00016  * Unless required by applicable law or agreed to in writing, software
00017  * distributed under the License is distributed on an "AS IS" BASIS,
00018  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00019  * See the License for the specific language governing permissions and
00020  * limitations under the License.
00021  */
00022 
00023 #ifndef __ZXING_RESOURCE_H__
00024 #define __ZXING_RESOURCE_H__
00025 
00026 // Base class
00027 #include "mbed-connector-interface/DynamicResource.h"
00028 
00029 #include "DisplayBace.h"
00030 #include "ImageReaderSource.h"
00031 #include "DisplayApp.h"
00032 #include "AsciiFont.h"
00033 
00034 // forward declarations
00035 static void *_instance = NULL;
00036 extern "C" void _zxing_processing(const void *args);
00037 extern "C" void _zxing_loop(void);
00038 
00039 #define VIDEO_CVBS             (0)                 /* Analog  Video Signal */
00040 #define VIDEO_CMOS_CAMERA      (1)                 /* Digital Video Signal */
00041 #define VIDEO_RGB888           (1)
00042 
00043 /**** User Selection *********/
00044 /** Camera setting **/
00045 #define VIDEO_INPUT_METHOD     (VIDEO_CMOS_CAMERA) /* Select  VIDEO_CVBS or VIDEO_CMOS_CAMERA                       */
00046 #define VIDEO_INPUT_FORMAT     (VIDEO_RGB888)      /* Select  VIDEO_RGB888                                          */
00047 #define USE_VIDEO_CH           (0)                 /* Select  0 or 1            If selecting VIDEO_CMOS_CAMERA, should be 0.)               */
00048 #define VIDEO_PAL              (0)                 /* Select  0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */
00049 /** LCD setting **/
00050 #define LCD_ONOFF              (1)                 /* Select  0(without LCD) or 1(with LCD) */
00051 #if LCD_ONOFF
00052 #define LCD_TYPE               (0)                 /* Select  0(4.3inch) or 1(7.1inch) */
00053 #endif
00054 /*****************************/
00055 
00056 #if LCD_ONOFF
00057 /** LCD shield config **/
00058 #if (LCD_TYPE == 0)
00059   #include "LCD_shield_config_4_3inch.h"
00060 #else
00061   #include "LCD_shield_config_7_1inch.h"
00062 #endif
00063 #endif
00064 
00065 /** Video and Grapics (GRAPHICS_LAYER_0) parameter **/
00066 /* video input */
00067 #if USE_VIDEO_CH == (0)
00068   #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_0)
00069   #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S0_VFIELD)
00070 #else
00071   #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_1)
00072   #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S1_VFIELD)
00073 #endif
00074 
00075 /* NTSC or PAL */
00076 #if VIDEO_PAL == 0
00077   #define COL_SYS              (DisplayBase::COL_SYS_NTSC_358)
00078 #else
00079   #define COL_SYS              (DisplayBase::COL_SYS_PAL_443)
00080 #endif
00081 
00082 /* Video input */
00083 #define VIDEO_FORMAT           (DisplayBase::VIDEO_FORMAT_RGB888)
00084 #define GRAPHICS_FORMAT        (DisplayBase::GRAPHICS_FORMAT_RGB888)
00085 #define WR_RD_WRSWA            (DisplayBase::WR_RD_WRSWA_32BIT)
00086 
00087 /* The size of the video input */
00088 #if ((LCD_ONOFF) && (LCD_TYPE == 0))
00089   #define VIDEO_PIXEL_HW                LCD_PIXEL_WIDTH
00090   #define VIDEO_PIXEL_VW                LCD_PIXEL_HEIGHT
00091 #else
00092   #define VIDEO_PIXEL_HW                (640)  /* VGA */
00093   #define VIDEO_PIXEL_VW                (480)  /* VGA */
00094 #endif
00095 
00096 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
00097     in accordance with the frame buffer burst transfer mode. */
00098 /* FRAME BUFFER Parameter GRAPHICS_LAYER_0 */
00099 #define FRAME_BUFFER_NUM              (2u)
00100 #define FRAME_BUFFER_BYTE_PER_PIXEL   (4u)
00101 #define FRAME_BUFFER_STRIDE           (((VIDEO_PIXEL_HW * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
00102 
00103 #if LCD_ONOFF
00104 #define VIDEO_PIXEL_HW_STR              (VIDEO_PIXEL_HW - 64)
00105 #define VIDEO_PIXEL_VW_STR              (VIDEO_PIXEL_VW - 64)
00106 #define FRAME_BUFFER_BYTE_PER_PIXEL_STR (2u)
00107 #define FRAME_BUFFER_STRIDE_STR         (((VIDEO_PIXEL_HW_STR * FRAME_BUFFER_BYTE_PER_PIXEL_STR) + 31u) & ~31u)
00108 #endif
00109 
00110 static DisplayBase Display;
00111 static DisplayApp  display_app;
00112 static Timer decode_timer;
00113 #if LCD_ONOFF
00114 static DigitalOut  lcd_pwon(P7_15);
00115 static DigitalOut  lcd_blon(P8_1);
00116 static PwmOut      lcd_cntrst(P8_15);
00117 #endif
00118 
00119 /* 32 bytes aligned */
00120 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW]__attribute((aligned(32)));
00121 static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW]__attribute((aligned(32)));
00122 #if LCD_ONOFF
00123 static uint8_t user_frame_buffer_string[FRAME_BUFFER_STRIDE_STR * VIDEO_PIXEL_VW_STR]__attribute((aligned(32)));
00124 static AsciiFont ascii_font(user_frame_buffer_string, VIDEO_PIXEL_HW_STR, VIDEO_PIXEL_VW_STR, FRAME_BUFFER_STRIDE_STR, FRAME_BUFFER_BYTE_PER_PIXEL_STR);
00125 static bool      string_draw;
00126 #endif
00127 static uint8_t * decode_buffer = user_frame_buffer0;
00128 static uint8_t * FrameBufferTbl[FRAME_BUFFER_NUM] = {user_frame_buffer0, user_frame_buffer1};
00129 static volatile int32_t vfield_count = 0;
00130 static int write_buff_num = 0;
00131 static bool graphics_init_end = false;
00132 static int decode_wait_time = 0;
00133 
00134 vector<Ref<Result> > results;
00135 char ** decode_str;
00136 
00137 /****** cache control ******/
00138 static void dcache_clean(void * p_buf, uint32_t size) {
00139     uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0;
00140     uint32_t end_addr   = (uint32_t)p_buf + size;
00141     uint32_t addr;
00142 
00143     /* Data cache clean */
00144     for (addr = start_addr; addr < end_addr; addr += 0x20) {
00145         __v7_clean_dcache_mva((void *)addr);
00146     }
00147 }
00148 
00149 static void dcache_invalid(void * p_buf, uint32_t size){
00150     uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0;
00151     uint32_t end_addr   = (uint32_t)p_buf + size;
00152     uint32_t addr;
00153 
00154     /* Data cache invalid */
00155     for (addr = start_addr; addr < end_addr; addr += 0x20) {
00156         __v7_inv_dcache_mva((void *)addr);
00157     }
00158 }
00159 
00160 #if LCD_ONOFF
00161 /****** LCD ******/
00162 static void Init_LCD_Display(void) {
00163     DisplayBase::graphics_error_t error;
00164     DisplayBase::lcd_config_t lcd_config;
00165     PinName lvds_pin[8] = {
00166         /* data pin */
00167         P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
00168     };
00169 
00170     lcd_pwon = 0;
00171     lcd_blon = 0;
00172     Thread::wait(100);
00173     lcd_pwon = 1;
00174     lcd_blon = 1;
00175 
00176     Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
00177 
00178     /* Graphics initialization process */
00179     lcd_config = LcdCfgTbl_LCD_shield;
00180     error = Display.Graphics_init(&lcd_config);
00181     if (error != DisplayBase::GRAPHICS_OK) {
00182         printf("Line %d, error %d\n", __LINE__, error);
00183         mbed_die();
00184     }
00185     graphics_init_end = true;
00186 }
00187 
00188 static void Start_LCD_Display(uint8_t * p_buf) {
00189     DisplayBase::rect_t rect;
00190 
00191     rect.vs = 0;
00192     rect.vw = VIDEO_PIXEL_VW;
00193     rect.hs = 0;
00194     rect.hw = VIDEO_PIXEL_HW;
00195     Display.Graphics_Read_Setting(
00196         DisplayBase::GRAPHICS_LAYER_0,
00197         (void *)p_buf,
00198         FRAME_BUFFER_STRIDE,
00199         GRAPHICS_FORMAT,
00200         WR_RD_WRSWA,
00201         &rect
00202     );
00203     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
00204 }
00205 #endif
00206 
00207 /****** Video ******/
00208 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
00209     /* Interrupt callback function for Vfield interruption */
00210     if (vfield_count > 0) {
00211         vfield_count--;
00212     }
00213 }
00214 
00215 static void Wait_Vfield(const int32_t wait_count) {
00216     /* Wait for the specified number of times Vsync occurs */
00217     vfield_count = wait_count;
00218     while (vfield_count > 0) {
00219         Thread::wait(1);
00220     }
00221 }
00222 
00223 static void Init_Video(void) {
00224     DisplayBase::graphics_error_t error;
00225 
00226     /* Graphics initialization process */
00227     if (graphics_init_end == false) {
00228         /* When not initializing LCD, this processing is needed. */
00229         error = Display.Graphics_init(NULL);
00230         if (error != DisplayBase::GRAPHICS_OK) {
00231             printf("Line %d, error %d\n", __LINE__, error);
00232             mbed_die();
00233         }
00234         graphics_init_end = true;
00235     }
00236 
00237 #if VIDEO_INPUT_METHOD == VIDEO_CVBS
00238     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
00239     if( error != DisplayBase::GRAPHICS_OK ) {
00240         printf("Line %d, error %d\n", __LINE__, error);
00241         mbed_die();
00242     }
00243 #elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
00244     DisplayBase::video_ext_in_config_t ext_in_config;
00245     PinName cmos_camera_pin[11] = {
00246         /* data pin */
00247         P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
00248         /* control pin */
00249         P10_0,      /* DV0_CLK   */
00250         P1_0,       /* DV0_Vsync */
00251         P1_1        /* DV0_Hsync */
00252     };
00253 
00254     /* MT9V111 camera input config */
00255     ext_in_config.inp_format     = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */
00256     ext_in_config.inp_pxd_edge   = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing data          */
00257     ext_in_config.inp_vs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Vsync signals */
00258     ext_in_config.inp_hs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Hsync signals */
00259     ext_in_config.inp_endian_on  = DisplayBase::OFF;                      /* External input bit endian change on/off       */
00260     ext_in_config.inp_swap_on    = DisplayBase::OFF;                      /* External input B/R signal swap on/off         */
00261     ext_in_config.inp_vs_inv     = DisplayBase::SIG_POL_NOT_INVERTED;     /* External input DV_VSYNC inversion control     */
00262     ext_in_config.inp_hs_inv     = DisplayBase::SIG_POL_INVERTED;         /* External input DV_HSYNC inversion control     */
00263     ext_in_config.inp_f525_625   = DisplayBase::EXTIN_LINE_525;           /* Number of lines for BT.656 external input */
00264     ext_in_config.inp_h_pos      = DisplayBase::EXTIN_H_POS_CRYCBY;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
00265     ext_in_config.cap_vs_pos     = 6;                                     /* Capture start position from Vsync */
00266     ext_in_config.cap_hs_pos     = 150;                                   /* Capture start position form Hsync */
00267 #if ((LCD_ONOFF) && (LCD_TYPE == 0))
00268     /* The same screen ratio as the screen ratio of the LCD. */
00269     ext_in_config.cap_width      = 640;                                   /* Capture width */
00270     ext_in_config.cap_height     = 363;                                   /* Capture height Max 468[line]
00271                                                                              Due to CMOS(MT9V111) output signal timing and VDC5 specification */
00272 #else
00273     ext_in_config.cap_width      = 640;                                   /* Capture width */
00274     ext_in_config.cap_height     = 468;                                   /* Capture height Max 468[line]
00275                                                                              Due to CMOS(MT9V111) output signal timing and VDC5 specification */
00276 #endif
00277     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config);
00278     if( error != DisplayBase::GRAPHICS_OK ) {
00279         printf("Line %d, error %d\n", __LINE__, error);
00280         mbed_die();
00281     }
00282 
00283     /* Camera input port setting */
00284     error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
00285     if( error != DisplayBase::GRAPHICS_OK ) {
00286         printf("Line %d, error %d\n", __LINE__, error);
00287         mbed_die();
00288     }
00289 #endif
00290 
00291     /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
00292     error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield);
00293     if (error != DisplayBase::GRAPHICS_OK) {
00294         printf("Line %d, error %d\n", __LINE__, error);
00295         mbed_die();
00296     }
00297 }
00298 
00299 static void Start_Video(uint8_t * p_buf) {
00300     DisplayBase::graphics_error_t error;
00301 
00302     /* Video capture setting (progressive form fixed) */
00303     error = Display.Video_Write_Setting(
00304                 VIDEO_INPUT_CH,
00305                 COL_SYS,
00306                 p_buf,
00307                 FRAME_BUFFER_STRIDE,
00308                 VIDEO_FORMAT,
00309                 WR_RD_WRSWA,
00310                 VIDEO_PIXEL_VW,
00311                 VIDEO_PIXEL_HW
00312             );
00313     if (error != DisplayBase::GRAPHICS_OK) {
00314         printf("Line %d, error %d\n", __LINE__, error);
00315         mbed_die();
00316     }
00317 
00318     /* Video write process start */
00319     error = Display.Video_Start(VIDEO_INPUT_CH);
00320     if (error != DisplayBase::GRAPHICS_OK) {
00321         printf("Line %d, error %d\n", __LINE__, error);
00322         mbed_die();
00323     }
00324 
00325     /* Video write process stop */
00326     error = Display.Video_Stop(VIDEO_INPUT_CH);
00327     if (error != DisplayBase::GRAPHICS_OK) {
00328         printf("Line %d, error %d\n", __LINE__, error);
00329         mbed_die();
00330     }
00331 
00332     /* Video write process start */
00333     error = Display.Video_Start(VIDEO_INPUT_CH);
00334     if (error != DisplayBase::GRAPHICS_OK) {
00335         printf("Line %d, error %d\n", __LINE__, error);
00336         mbed_die();
00337     }
00338 }
00339 
00340 /** 
00341  * ZXingResource class
00342  */
00343 class ZXingResource : public DynamicResource
00344 {
00345 private:
00346     Thread * m_zxing_processor;
00347     
00348 public:
00349     /**
00350     Default constructor
00351     @param logger input logger instance for this resource
00352     @param obj_name input the Accelerometer Object name
00353     @param res_name input the Accelerometer Resource name
00354     @param observable input the resource is Observable (default: FALSE)
00355     */
00356 
00357     ZXingResource(const Logger *logger,const char *obj_name,const char *res_name,const bool observable = false) : DynamicResource(logger,obj_name,res_name,"ZXing",M2MBase::GET_ALLOWED,observable) {
00358         // init
00359         _instance = (void *)this;
00360 
00361 #if LCD_ONOFF
00362         // Initialze LCD
00363         Init_LCD_Display();
00364 #endif
00365         // Initialize Video
00366         Init_Video();
00367 
00368         // Initialize frame buffer
00369         for (int i = 0; i < FRAME_BUFFER_NUM; i++) {
00370             memset(FrameBufferTbl[i], 0, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW));
00371             dcache_clean(FrameBufferTbl[i], (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW));
00372         }
00373         
00374         // Start Video
00375         Start_Video(FrameBufferTbl[write_buff_num]);
00376         /* Wait for first video drawing */
00377         Wait_Vfield(2);
00378 
00379 #if LCD_ONOFF
00380         DisplayBase::rect_t rect;
00381 
00382         /* The layer by which the touch panel location is drawn */
00383         ascii_font.Erase(0x00000000);  /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */
00384         dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
00385         rect.vs = 32;
00386         rect.vw = VIDEO_PIXEL_VW_STR;
00387         rect.hs = 32;
00388         rect.hw = VIDEO_PIXEL_HW_STR;
00389         Display.Graphics_Read_Setting(
00390             DisplayBase::GRAPHICS_LAYER_1,
00391             (void *)user_frame_buffer_string,
00392             FRAME_BUFFER_STRIDE_STR,
00393             DisplayBase::GRAPHICS_FORMAT_ARGB4444,
00394             DisplayBase::WR_RD_WRSWA_32_16BIT,
00395             &rect
00396         );
00397         Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1);
00398         string_draw = false;
00399         /* Start of LCD */
00400         Start_LCD_Display(FrameBufferTbl[write_buff_num]);
00401         /* Backlight on */
00402         Thread::wait(200);
00403         lcd_cntrst.write(1.0);
00404 #endif
00405         decode_timer.reset();
00406         decode_timer.start();
00407 
00408         // no Thread yet
00409         this->m_zxing_processor = NULL;
00410     }
00411 
00412     /**
00413     Get the value of the barcode data
00414     @returns string containing the acclerometer sensor value
00415     */
00416     virtual string get() {
00417 #if 1
00418         if (this->m_zxing_processor == NULL) {
00419             // create the processing thread
00420             this->m_zxing_processor = new Thread(_zxing_processing);
00421         }  
00422                         
00423         if (*decode_str == NULL) {
00424             return string("0\0");
00425         } else {
00426             return string(*decode_str);
00427         }
00428         
00429 #endif
00430     }
00431 };
00432 
00433 void _zxing_processing(const void *args) {
00434     while (true) {
00435         _zxing_loop();
00436         Thread::wait(5);
00437     }
00438 }
00439 
00440 void _zxing_loop(void) {
00441     DisplayBase::graphics_error_t error;
00442     int decode_result = -1;
00443      
00444 #if 1
00445         decode_buffer = FrameBufferTbl[write_buff_num];
00446         write_buff_num++;
00447 
00448         if (write_buff_num >= FRAME_BUFFER_NUM) {
00449             write_buff_num = 0;
00450         }            
00451         /* Change video buffer */
00452         error = Display.Video_Write_Change(VIDEO_INPUT_CH, FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE);
00453         if (error != DisplayBase::GRAPHICS_OK) {
00454             printf("Line %d, error %d\n", __LINE__, error);
00455             mbed_die();
00456         }
00457         Wait_Vfield(2);
00458 #if LCD_ONOFF
00459         /* Change LCD buffer */
00460         Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, (void *)FrameBufferTbl[write_buff_num]);
00461 #endif
00462         dcache_invalid(decode_buffer, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW));
00463         /* Decode barcode image */
00464         if (decode_timer.read_ms() >= decode_wait_time) {
00465             decode_timer.reset();
00466             decode_result = ex_decode(decode_buffer, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW), VIDEO_PIXEL_HW, VIDEO_PIXEL_VW, &results);
00467             if (decode_result == 0) {
00468                 decode_str = (char **)&(results[0]->getText()->getText());
00469                 
00470                 if (_instance != NULL) {
00471                     // observe...
00472                     ((ZXingResource *)_instance)->observe();
00473                 }
00474 
00475 #if LCD_ONOFF
00476                 /* Drow string */
00477                 ascii_font.Erase(0x00000090);  /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */
00478                 int rest_size = strlen(*decode_str);
00479                 int draw_idx = 0;
00480                 int draw_size;
00481                 int draw_line = 0;
00482                 
00483                 while (rest_size > 0) {
00484                     draw_size = ascii_font.DrawStr(*decode_str + draw_idx, 6, 5 + (18 * draw_line), 0x0000ffff, 2);
00485                     if (draw_size <= 0) {
00486                         break;
00487                     }
00488                     rest_size -= draw_size;
00489                     draw_idx += draw_size;
00490                     draw_line++;
00491                 }
00492                 
00493                 dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
00494                 string_draw = true;
00495 #endif
00496                 decode_wait_time = 500;
00497             } else {
00498 #if LCD_ONOFF
00499                 if (string_draw != false) {
00500                     /* Clear string */
00501                     ascii_font.Erase(0x00000000);  /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */
00502                     dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
00503                     string_draw = false;
00504                 }
00505 #endif
00506                 decode_wait_time = 10;
00507             }
00508         }
00509         display_app.SendRgb888(decode_buffer, VIDEO_PIXEL_HW, VIDEO_PIXEL_VW);
00510 #endif
00511 }
00512 #endif // __ZXING_RESOURCE_H__