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
ZXingResource.h
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__
Generated on Tue Jul 12 2022 18:38:06 by 1.7.2