Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
zxing_main.cpp
00001 00002 #include "mbed.h" 00003 #include "rtos.h" 00004 #include "DisplayBace.h" 00005 #include "ImageReaderSource.h" 00006 00007 #define VIDEO_CVBS (0) /* Analog Video Signal */ 00008 #define VIDEO_CMOS_CAMERA (1) /* Digital Video Signal */ 00009 00010 /**** User Selection *********/ 00011 /** Camera setting **/ 00012 #define VIDEO_INPUT_METHOD (VIDEO_CMOS_CAMERA) /* Select VIDEO_CVBS or VIDEO_CMOS_CAMERA */ 00013 #define USE_VIDEO_CH (0) /* Select 0 or 1 If selecting VIDEO_CMOS_CAMERA, should be 0.) */ 00014 #define VIDEO_PAL (0) /* Select 0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */ 00015 /** LCD setting **/ 00016 #define LCD_ONOFF (1) /* Select 0(without LCD) or 1(with LCD) */ 00017 #define LCD_TYPE (0) /* Select 0(4.3inch) or 1(7.1inch) */ 00018 /** JPEG out setting **/ 00019 #define JPEG_SEND (0) /* Select 0(JPEG images are not output to PC) or 1(JPEG images are output to PC on USB(CDC) for focusing the camera) */ 00020 /** Decode hints **/ 00021 #define DECODE_HINTS (DecodeHints::ONED_HINT | DecodeHints::QR_CODE_HINT | DecodeHints::DATA_MATRIX_HINT | DecodeHints::AZTEC_HINT) 00022 /*****************************/ 00023 00024 #if LCD_ONOFF 00025 /** LCD shield config **/ 00026 #if (LCD_TYPE == 0) 00027 #include "LCD_shield_config_4_3inch.h" 00028 #else 00029 #include "LCD_shield_config_7_1inch.h" 00030 #endif 00031 #include "AsciiFont.h" 00032 #endif 00033 00034 #if JPEG_SEND 00035 #include "JPEG_Converter.h" 00036 #include "DisplayApp.h" 00037 #endif 00038 00039 /** Video and Grapics (GRAPHICS_LAYER_0) parameter **/ 00040 /* video input */ 00041 #if USE_VIDEO_CH == (0) 00042 #define VIDEO_INPUT_CH (DisplayBase::VIDEO_INPUT_CHANNEL_0) 00043 #define VIDEO_INT_TYPE (DisplayBase::INT_TYPE_S0_VFIELD) 00044 #else 00045 #define VIDEO_INPUT_CH (DisplayBase::VIDEO_INPUT_CHANNEL_1) 00046 #define VIDEO_INT_TYPE (DisplayBase::INT_TYPE_S1_VFIELD) 00047 #endif 00048 00049 /* NTSC or PAL */ 00050 #if VIDEO_PAL == 0 00051 #define COL_SYS (DisplayBase::COL_SYS_NTSC_358) 00052 #else 00053 #define COL_SYS (DisplayBase::COL_SYS_PAL_443) 00054 #endif 00055 00056 /* Video input */ 00057 #define VIDEO_FORMAT (DisplayBase::VIDEO_FORMAT_YCBCR422) 00058 #define GRAPHICS_FORMAT (DisplayBase::GRAPHICS_FORMAT_YCBCR422) 00059 #define WR_RD_WRSWA (DisplayBase::WR_RD_WRSWA_16BIT) 00060 #define FRAME_BUFFER_BYTE_PER_PIXEL (2u) 00061 00062 #if VIDEO_INPUT_METHOD == VIDEO_CVBS 00063 #define WAIT_VFIELD_CNT (2) 00064 #else 00065 #define WAIT_VFIELD_CNT (1) 00066 #endif 00067 00068 /* The size of the video input */ 00069 #if ((LCD_ONOFF) && (LCD_TYPE == 0)) 00070 #define VIDEO_PIXEL_HW LCD_PIXEL_WIDTH 00071 #define VIDEO_PIXEL_VW LCD_PIXEL_HEIGHT 00072 #else 00073 #define VIDEO_PIXEL_HW (640) /* VGA */ 00074 #define VIDEO_PIXEL_VW (480) /* VGA */ 00075 #endif 00076 00077 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128 00078 in accordance with the frame buffer burst transfer mode. */ 00079 /* FRAME BUFFER Parameter GRAPHICS_LAYER_0 */ 00080 #define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u) 00081 00082 static DisplayBase Display; 00083 static Timer decode_timer; 00084 00085 /* 32 bytes aligned */ 00086 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW]__attribute((section("NC_BSS"),aligned(32))); 00087 00088 static volatile int32_t vfield_count = 0; 00089 static bool graphics_init_end = false; 00090 static int decode_wait_time = 0; 00091 static void (*p_callback_func)(char * addr, int size); 00092 00093 #if LCD_ONOFF 00094 /****** LCD ******/ 00095 static DigitalOut lcd_pwon(P7_15); 00096 static DigitalOut lcd_blon(P8_1); 00097 static PwmOut lcd_cntrst(P8_15); 00098 00099 static void Init_LCD_Display(void) { 00100 DisplayBase::graphics_error_t error; 00101 DisplayBase::lcd_config_t lcd_config; 00102 PinName lvds_pin[8] = { 00103 /* data pin */ 00104 P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0 00105 }; 00106 00107 lcd_pwon = 0; 00108 lcd_blon = 0; 00109 Thread::wait(100); 00110 lcd_pwon = 1; 00111 lcd_blon = 1; 00112 00113 Display.Graphics_Lvds_Port_Init(lvds_pin, 8); 00114 00115 /* Graphics initialization process */ 00116 lcd_config = LcdCfgTbl_LCD_shield; 00117 error = Display.Graphics_init(&lcd_config); 00118 if (error != DisplayBase::GRAPHICS_OK) { 00119 printf("Line %d, error %d\n", __LINE__, error); 00120 mbed_die(); 00121 } 00122 graphics_init_end = true; 00123 } 00124 00125 static void Start_LCD_Display(uint8_t * p_buf) { 00126 DisplayBase::rect_t rect; 00127 00128 rect.vs = 0; 00129 rect.vw = VIDEO_PIXEL_VW; 00130 rect.hs = 0; 00131 rect.hw = VIDEO_PIXEL_HW; 00132 Display.Graphics_Read_Setting( 00133 DisplayBase::GRAPHICS_LAYER_0, 00134 (void *)p_buf, 00135 FRAME_BUFFER_STRIDE, 00136 GRAPHICS_FORMAT, 00137 WR_RD_WRSWA, 00138 &rect 00139 ); 00140 Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); 00141 } 00142 00143 #define VIDEO_PIXEL_HW_STR (VIDEO_PIXEL_HW - 64) 00144 #define VIDEO_PIXEL_VW_STR (VIDEO_PIXEL_VW - 64) 00145 #define FRAME_BUFFER_BYTE_PER_PIXEL_STR (2u) 00146 #define FRAME_BUFFER_STRIDE_STR (((VIDEO_PIXEL_HW_STR * FRAME_BUFFER_BYTE_PER_PIXEL_STR) + 31u) & ~31u) 00147 00148 static uint8_t user_frame_buffer_string[FRAME_BUFFER_STRIDE_STR * VIDEO_PIXEL_VW_STR]__attribute((section("NC_BSS"),aligned(32))); 00149 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); 00150 static bool string_draw; 00151 00152 static void decode_string_init(void) { 00153 DisplayBase::rect_t rect; 00154 00155 /* The layer by which the touch panel location is drawn */ 00156 ascii_font.Erase(0x00000000); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ 00157 rect.vs = 32; 00158 rect.vw = VIDEO_PIXEL_VW_STR; 00159 rect.hs = 32; 00160 rect.hw = VIDEO_PIXEL_HW_STR; 00161 Display.Graphics_Read_Setting( 00162 DisplayBase::GRAPHICS_LAYER_1, 00163 (void *)user_frame_buffer_string, 00164 FRAME_BUFFER_STRIDE_STR, 00165 DisplayBase::GRAPHICS_FORMAT_ARGB4444, 00166 DisplayBase::WR_RD_WRSWA_32_16BIT, 00167 &rect 00168 ); 00169 Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1); 00170 string_draw = false; 00171 } 00172 00173 static void decode_string_disp(char ** decode_str) { 00174 if ((decode_str != NULL) && (*decode_str != NULL)) { 00175 /* Drow string */ 00176 ascii_font.Erase(0x00000090); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ 00177 int rest_size = strlen(*decode_str); 00178 int draw_idx = 0; 00179 int draw_size; 00180 int draw_line = 0; 00181 00182 while (rest_size > 0) { 00183 draw_size = ascii_font.DrawStr(*decode_str + draw_idx, 6, 5 + (18 * draw_line), 0x0000ffff, 2); 00184 if (draw_size <= 0) { 00185 break; 00186 } 00187 rest_size -= draw_size; 00188 draw_idx += draw_size; 00189 draw_line++; 00190 } 00191 string_draw = true; 00192 } else { 00193 if (string_draw != false) { 00194 /* Clear string */ 00195 ascii_font.Erase(0x00000000); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ 00196 string_draw = false; 00197 } 00198 } 00199 } 00200 #endif // LCD_ONOFF 00201 00202 #if JPEG_SEND 00203 /****** Jpeg Send ******/ 00204 #define JPEG_ENC_MAX_SIZE (1024 * 63) 00205 #define JPEG_SIGNAL_CAP_COMP (1L) 00206 00207 #define JPEGSEND_STB (0) 00208 #define JPEGSEND_ENC (1) 00209 00210 static Thread jpegsendTask(osPriorityAboveNormal, 2048); 00211 static DisplayApp display_app; 00212 static uint8_t JpegBuffer[JPEG_ENC_MAX_SIZE]__attribute((section("NC_BSS"),aligned(8))); //8 bytes aligned!; 00213 volatile static uint32_t jpegsend_status = JPEGSEND_STB; 00214 00215 static void jpegsendTask_main( void ) { 00216 JPEG_Converter Jcu; 00217 size_t jcu_encode_size; 00218 00219 while (1) { 00220 Thread::signal_wait(JPEG_SIGNAL_CAP_COMP, 80); 00221 jpegsend_status = JPEGSEND_ENC; 00222 00223 /* JPEG Enc Start */ 00224 JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; 00225 JPEG_Converter::encode_options_t encode_options; 00226 bitmap_buff_info.width = VIDEO_PIXEL_HW; 00227 bitmap_buff_info.height = VIDEO_PIXEL_VW; 00228 bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422; 00229 bitmap_buff_info.buffer_address = (void *)user_frame_buffer0; 00230 encode_options.encode_buff_size = sizeof(JpegBuffer); 00231 encode_options.p_EncodeCallBackFunc = NULL; 00232 encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_16_8BIT; 00233 jcu_encode_size = 0; 00234 if (Jcu.encode(&bitmap_buff_info, JpegBuffer, &jcu_encode_size, &encode_options) != JPEG_Converter::JPEG_CONV_OK) { 00235 jcu_encode_size = 0; 00236 } 00237 00238 /* JPEG Data Send */ 00239 if ((jcu_encode_size > 256) && (jcu_encode_size < JPEG_ENC_MAX_SIZE)) { 00240 display_app.SendJpeg(JpegBuffer, jcu_encode_size); 00241 } 00242 jpegsend_status = JPEGSEND_STB; 00243 } 00244 } 00245 00246 static void jpegsendTask_init( void ) { 00247 jpegsendTask.start(jpegsendTask_main); 00248 } 00249 00250 static void jpegsend_cap_comp( void ) { 00251 if (jpegsend_status == JPEGSEND_STB) { 00252 jpegsendTask.signal_set(JPEG_SIGNAL_CAP_COMP); 00253 } 00254 } 00255 #endif // JPEG_SEND 00256 00257 /****** Video ******/ 00258 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) { 00259 /* Interrupt callback function for Vfield interruption */ 00260 if (vfield_count > 0) { 00261 vfield_count--; 00262 } 00263 #if JPEG_SEND 00264 jpegsend_cap_comp(); 00265 #endif // JPEG_SEND 00266 } 00267 00268 static void Wait_Vfield(const int32_t wait_count) { 00269 /* Wait for the specified number of times Vsync occurs */ 00270 vfield_count = wait_count; 00271 while (vfield_count > 0) { 00272 Thread::wait(1); 00273 } 00274 } 00275 00276 static void Init_Video(void) { 00277 DisplayBase::graphics_error_t error; 00278 00279 /* Graphics initialization process */ 00280 if (graphics_init_end == false) { 00281 /* When not initializing LCD, this processing is needed. */ 00282 error = Display.Graphics_init(NULL); 00283 if (error != DisplayBase::GRAPHICS_OK) { 00284 printf("Line %d, error %d\n", __LINE__, error); 00285 mbed_die(); 00286 } 00287 graphics_init_end = true; 00288 } 00289 00290 #if VIDEO_INPUT_METHOD == VIDEO_CVBS 00291 error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL); 00292 if( error != DisplayBase::GRAPHICS_OK ) { 00293 printf("Line %d, error %d\n", __LINE__, error); 00294 mbed_die(); 00295 } 00296 #elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA 00297 DisplayBase::video_ext_in_config_t ext_in_config; 00298 PinName cmos_camera_pin[11] = { 00299 /* data pin */ 00300 P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0, 00301 /* control pin */ 00302 P10_0, /* DV0_CLK */ 00303 P1_0, /* DV0_Vsync */ 00304 P1_1 /* DV0_Hsync */ 00305 }; 00306 00307 /* MT9V111 camera input config */ 00308 ext_in_config.inp_format = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */ 00309 ext_in_config.inp_pxd_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing data */ 00310 ext_in_config.inp_vs_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing Vsync signals */ 00311 ext_in_config.inp_hs_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing Hsync signals */ 00312 ext_in_config.inp_endian_on = DisplayBase::OFF; /* External input bit endian change on/off */ 00313 ext_in_config.inp_swap_on = DisplayBase::OFF; /* External input B/R signal swap on/off */ 00314 ext_in_config.inp_vs_inv = DisplayBase::SIG_POL_NOT_INVERTED; /* External input DV_VSYNC inversion control */ 00315 ext_in_config.inp_hs_inv = DisplayBase::SIG_POL_INVERTED; /* External input DV_HSYNC inversion control */ 00316 ext_in_config.inp_f525_625 = DisplayBase::EXTIN_LINE_525; /* Number of lines for BT.656 external input */ 00317 ext_in_config.inp_h_pos = DisplayBase::EXTIN_H_POS_CRYCBY; /* Y/Cb/Y/Cr data string start timing to Hsync reference */ 00318 ext_in_config.cap_vs_pos = 6; /* Capture start position from Vsync */ 00319 ext_in_config.cap_hs_pos = 150; /* Capture start position form Hsync */ 00320 #if ((LCD_ONOFF) && (LCD_TYPE == 0)) 00321 /* The same screen ratio as the screen ratio of the LCD. */ 00322 ext_in_config.cap_width = 640; /* Capture width */ 00323 ext_in_config.cap_height = 363; /* Capture height Max 468[line] 00324 Due to CMOS(MT9V111) output signal timing and VDC5 specification */ 00325 #else 00326 ext_in_config.cap_width = 640; /* Capture width */ 00327 ext_in_config.cap_height = 468; /* Capture height Max 468[line] 00328 Due to CMOS(MT9V111) output signal timing and VDC5 specification */ 00329 #endif 00330 error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config); 00331 if( error != DisplayBase::GRAPHICS_OK ) { 00332 printf("Line %d, error %d\n", __LINE__, error); 00333 mbed_die(); 00334 } 00335 00336 /* Camera input port setting */ 00337 error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11); 00338 if( error != DisplayBase::GRAPHICS_OK ) { 00339 printf("Line %d, error %d\n", __LINE__, error); 00340 mbed_die(); 00341 } 00342 #endif 00343 00344 /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */ 00345 error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield); 00346 if (error != DisplayBase::GRAPHICS_OK) { 00347 printf("Line %d, error %d\n", __LINE__, error); 00348 mbed_die(); 00349 } 00350 } 00351 00352 static void Start_Video(uint8_t * p_buf) { 00353 DisplayBase::graphics_error_t error; 00354 00355 /* Video capture setting (progressive form fixed) */ 00356 error = Display.Video_Write_Setting( 00357 VIDEO_INPUT_CH, 00358 COL_SYS, 00359 p_buf, 00360 FRAME_BUFFER_STRIDE, 00361 VIDEO_FORMAT, 00362 WR_RD_WRSWA, 00363 VIDEO_PIXEL_VW, 00364 VIDEO_PIXEL_HW 00365 ); 00366 if (error != DisplayBase::GRAPHICS_OK) { 00367 printf("Line %d, error %d\n", __LINE__, error); 00368 mbed_die(); 00369 } 00370 00371 /* Video write process start */ 00372 error = Display.Video_Start(VIDEO_INPUT_CH); 00373 if (error != DisplayBase::GRAPHICS_OK) { 00374 printf("Line %d, error %d\n", __LINE__, error); 00375 mbed_die(); 00376 } 00377 00378 /* Video write process stop */ 00379 error = Display.Video_Stop(VIDEO_INPUT_CH); 00380 if (error != DisplayBase::GRAPHICS_OK) { 00381 printf("Line %d, error %d\n", __LINE__, error); 00382 mbed_die(); 00383 } 00384 00385 /* Video write process start */ 00386 error = Display.Video_Start(VIDEO_INPUT_CH); 00387 if (error != DisplayBase::GRAPHICS_OK) { 00388 printf("Line %d, error %d\n", __LINE__, error); 00389 mbed_die(); 00390 } 00391 } 00392 00393 /****** zxing_init ******/ 00394 void zxing_init(void (*pfunc)(char * addr, int size)) { 00395 00396 #if JPEG_SEND 00397 jpegsendTask_init(); 00398 #endif // JPEG_SEND 00399 #if LCD_ONOFF 00400 /* Initialization of LCD */ 00401 Init_LCD_Display(); /* When using LCD, please call before than Init_Video(). */ 00402 #endif // LCD_ONOFF 00403 /* Initialization of Video */ 00404 Init_Video(); 00405 00406 /* Initialization memory */ 00407 memset(user_frame_buffer0, 0, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW)); 00408 00409 /* Start of Video */ 00410 Start_Video(user_frame_buffer0); 00411 /* Wait for first video drawing */ 00412 Wait_Vfield(WAIT_VFIELD_CNT); 00413 #if LCD_ONOFF 00414 decode_string_init(); 00415 /* Start of LCD */ 00416 Start_LCD_Display(user_frame_buffer0); 00417 /* Backlight on */ 00418 Thread::wait(200); 00419 lcd_cntrst.write(1.0); 00420 #endif // LCD_ONOFF 00421 p_callback_func = pfunc; 00422 decode_timer.reset(); 00423 decode_timer.start(); 00424 } 00425 00426 /****** zxing_main ******/ 00427 int zxing_loop() { 00428 int decode_result = -1; 00429 vector<Ref<Result> > results; 00430 char ** decode_str = NULL; 00431 00432 Wait_Vfield(WAIT_VFIELD_CNT); 00433 /* Decode barcode image */ 00434 if (decode_timer.read_ms() >= decode_wait_time) { 00435 decode_timer.reset(); 00436 DecodeHints hints(DECODE_HINTS); 00437 hints.setTryHarder(false); 00438 decode_result = ex_decode(user_frame_buffer0, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW), VIDEO_PIXEL_HW, VIDEO_PIXEL_VW, &results, hints); 00439 if (decode_result == 0) { 00440 decode_str = (char **)&(results[0]->getText()->getText()); 00441 int size = strlen(*decode_str); 00442 if (p_callback_func != NULL) { 00443 p_callback_func(*decode_str, size); 00444 } 00445 decode_wait_time = 500; 00446 } else { 00447 decode_wait_time = 10; 00448 } 00449 #if LCD_ONOFF 00450 decode_string_disp(decode_str); 00451 #endif // LCD_ONOFF 00452 } 00453 00454 return decode_result; 00455 } 00456
Generated on Wed Jul 13 2022 20:52:13 by
