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

Revision:
0:7d720671e6dc
Child:
1:67f8b5cfde75
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-endpoint-resources/ZXingResource.h	Thu Nov 10 20:04:48 2016 +0900
@@ -0,0 +1,512 @@
+/**
+ * @file    ZXingResource.h
+ * @brief   mbed CoAP Endpoint Accelerometer sensor resource supporting CoAP GET
+ * @author  Doug Anson
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ZXING_RESOURCE_H__
+#define __ZXING_RESOURCE_H__
+
+// Base class
+#include "mbed-connector-interface/DynamicResource.h"
+
+#include "DisplayBace.h"
+#include "ImageReaderSource.h"
+#include "DisplayApp.h"
+#include "AsciiFont.h"
+
+// forward declarations
+static void *_instance = NULL;
+extern "C" void _zxing_processing(const void *args);
+extern "C" void _zxing_loop(void);
+
+#define VIDEO_CVBS             (0)                 /* Analog  Video Signal */
+#define VIDEO_CMOS_CAMERA      (1)                 /* Digital Video Signal */
+#define VIDEO_RGB888           (1)
+
+/**** User Selection *********/
+/** Camera setting **/
+#define VIDEO_INPUT_METHOD     (VIDEO_CMOS_CAMERA) /* Select  VIDEO_CVBS or VIDEO_CMOS_CAMERA                       */
+#define VIDEO_INPUT_FORMAT     (VIDEO_RGB888)      /* Select  VIDEO_RGB888                                          */
+#define USE_VIDEO_CH           (0)                 /* Select  0 or 1            If selecting VIDEO_CMOS_CAMERA, should be 0.)               */
+#define VIDEO_PAL              (0)                 /* Select  0(NTSC) or 1(PAL) If selecting VIDEO_CVBS, this parameter is not referenced.) */
+/** LCD setting **/
+#define LCD_ONOFF              (1)                 /* Select  0(without LCD) or 1(with LCD) */
+#if LCD_ONOFF
+#define LCD_TYPE               (0)                 /* Select  0(4.3inch) or 1(7.1inch) */
+#endif
+/*****************************/
+
+#if LCD_ONOFF
+/** LCD shield config **/
+#if (LCD_TYPE == 0)
+  #include "LCD_shield_config_4_3inch.h"
+#else
+  #include "LCD_shield_config_7_1inch.h"
+#endif
+#endif
+
+/** Video and Grapics (GRAPHICS_LAYER_0) parameter **/
+/* video input */
+#if USE_VIDEO_CH == (0)
+  #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_0)
+  #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S0_VFIELD)
+#else
+  #define VIDEO_INPUT_CH       (DisplayBase::VIDEO_INPUT_CHANNEL_1)
+  #define VIDEO_INT_TYPE       (DisplayBase::INT_TYPE_S1_VFIELD)
+#endif
+
+/* NTSC or PAL */
+#if VIDEO_PAL == 0
+  #define COL_SYS              (DisplayBase::COL_SYS_NTSC_358)
+#else
+  #define COL_SYS              (DisplayBase::COL_SYS_PAL_443)
+#endif
+
+/* Video input */
+#define VIDEO_FORMAT           (DisplayBase::VIDEO_FORMAT_RGB888)
+#define GRAPHICS_FORMAT        (DisplayBase::GRAPHICS_FORMAT_RGB888)
+#define WR_RD_WRSWA            (DisplayBase::WR_RD_WRSWA_32BIT)
+
+/* The size of the video input */
+#if ((LCD_ONOFF) && (LCD_TYPE == 0))
+  #define VIDEO_PIXEL_HW                LCD_PIXEL_WIDTH
+  #define VIDEO_PIXEL_VW                LCD_PIXEL_HEIGHT
+#else
+  #define VIDEO_PIXEL_HW                (640)  /* VGA */
+  #define VIDEO_PIXEL_VW                (480)  /* VGA */
+#endif
+
+/*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
+    in accordance with the frame buffer burst transfer mode. */
+/* FRAME BUFFER Parameter GRAPHICS_LAYER_0 */
+#define FRAME_BUFFER_NUM              (2u)
+#define FRAME_BUFFER_BYTE_PER_PIXEL   (4u)
+#define FRAME_BUFFER_STRIDE           (((VIDEO_PIXEL_HW * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
+
+#if LCD_ONOFF
+#define VIDEO_PIXEL_HW_STR              (VIDEO_PIXEL_HW - 64)
+#define VIDEO_PIXEL_VW_STR              (VIDEO_PIXEL_VW - 64)
+#define FRAME_BUFFER_BYTE_PER_PIXEL_STR (2u)
+#define FRAME_BUFFER_STRIDE_STR         (((VIDEO_PIXEL_HW_STR * FRAME_BUFFER_BYTE_PER_PIXEL_STR) + 31u) & ~31u)
+#endif
+
+static DisplayBase Display;
+static DisplayApp  display_app;
+static Timer decode_timer;
+#if LCD_ONOFF
+static DigitalOut  lcd_pwon(P7_15);
+static DigitalOut  lcd_blon(P8_1);
+static PwmOut      lcd_cntrst(P8_15);
+#endif
+
+/* 32 bytes aligned */
+static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW]__attribute((aligned(32)));
+static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW]__attribute((aligned(32)));
+#if LCD_ONOFF
+static uint8_t user_frame_buffer_string[FRAME_BUFFER_STRIDE_STR * VIDEO_PIXEL_VW_STR]__attribute((aligned(32)));
+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);
+static bool      string_draw;
+#endif
+static uint8_t * decode_buffer = user_frame_buffer0;
+static uint8_t * FrameBufferTbl[FRAME_BUFFER_NUM] = {user_frame_buffer0, user_frame_buffer1};
+static volatile int32_t vfield_count = 0;
+static int write_buff_num = 0;
+static bool graphics_init_end = false;
+static int decode_wait_time = 0;
+
+vector<Ref<Result> > results;
+char ** decode_str;
+
+/****** cache control ******/
+static void dcache_clean(void * p_buf, uint32_t size) {
+    uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0;
+    uint32_t end_addr   = (uint32_t)p_buf + size;
+    uint32_t addr;
+
+    /* Data cache clean */
+    for (addr = start_addr; addr < end_addr; addr += 0x20) {
+        __v7_clean_dcache_mva((void *)addr);
+    }
+}
+
+static void dcache_invalid(void * p_buf, uint32_t size){
+    uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0;
+    uint32_t end_addr   = (uint32_t)p_buf + size;
+    uint32_t addr;
+
+    /* Data cache invalid */
+    for (addr = start_addr; addr < end_addr; addr += 0x20) {
+        __v7_inv_dcache_mva((void *)addr);
+    }
+}
+
+#if LCD_ONOFF
+/****** LCD ******/
+static void Init_LCD_Display(void) {
+    DisplayBase::graphics_error_t error;
+    DisplayBase::lcd_config_t lcd_config;
+    PinName lvds_pin[8] = {
+        /* data pin */
+        P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
+    };
+
+    lcd_pwon = 0;
+    lcd_blon = 0;
+    Thread::wait(100);
+    lcd_pwon = 1;
+    lcd_blon = 1;
+
+    Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
+
+    /* Graphics initialization process */
+    lcd_config = LcdCfgTbl_LCD_shield;
+    error = Display.Graphics_init(&lcd_config);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+    graphics_init_end = true;
+}
+
+static void Start_LCD_Display(uint8_t * p_buf) {
+    DisplayBase::rect_t rect;
+
+    rect.vs = 0;
+    rect.vw = VIDEO_PIXEL_VW;
+    rect.hs = 0;
+    rect.hw = VIDEO_PIXEL_HW;
+    Display.Graphics_Read_Setting(
+        DisplayBase::GRAPHICS_LAYER_0,
+        (void *)p_buf,
+        FRAME_BUFFER_STRIDE,
+        GRAPHICS_FORMAT,
+        WR_RD_WRSWA,
+        &rect
+    );
+    Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
+}
+#endif
+
+/****** Video ******/
+static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
+    /* Interrupt callback function for Vfield interruption */
+    if (vfield_count > 0) {
+        vfield_count--;
+    }
+}
+
+static void Wait_Vfield(const int32_t wait_count) {
+    /* Wait for the specified number of times Vsync occurs */
+    vfield_count = wait_count;
+    while (vfield_count > 0) {
+        Thread::wait(1);
+    }
+}
+
+static void Init_Video(void) {
+    DisplayBase::graphics_error_t error;
+
+    /* Graphics initialization process */
+    if (graphics_init_end == false) {
+        /* When not initializing LCD, this processing is needed. */
+        error = Display.Graphics_init(NULL);
+        if (error != DisplayBase::GRAPHICS_OK) {
+            printf("Line %d, error %d\n", __LINE__, error);
+            mbed_die();
+        }
+        graphics_init_end = true;
+    }
+
+#if VIDEO_INPUT_METHOD == VIDEO_CVBS
+    error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC, NULL);
+    if( error != DisplayBase::GRAPHICS_OK ) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+#elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
+    DisplayBase::video_ext_in_config_t ext_in_config;
+    PinName cmos_camera_pin[11] = {
+        /* data pin */
+        P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
+        /* control pin */
+        P10_0,      /* DV0_CLK   */
+        P1_0,       /* DV0_Vsync */
+        P1_1        /* DV0_Hsync */
+    };
+
+    /* MT9V111 camera input config */
+    ext_in_config.inp_format     = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */
+    ext_in_config.inp_pxd_edge   = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing data          */
+    ext_in_config.inp_vs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Vsync signals */
+    ext_in_config.inp_hs_edge    = DisplayBase::EDGE_RISING;              /* Clock edge select for capturing Hsync signals */
+    ext_in_config.inp_endian_on  = DisplayBase::OFF;                      /* External input bit endian change on/off       */
+    ext_in_config.inp_swap_on    = DisplayBase::OFF;                      /* External input B/R signal swap on/off         */
+    ext_in_config.inp_vs_inv     = DisplayBase::SIG_POL_NOT_INVERTED;     /* External input DV_VSYNC inversion control     */
+    ext_in_config.inp_hs_inv     = DisplayBase::SIG_POL_INVERTED;         /* External input DV_HSYNC inversion control     */
+    ext_in_config.inp_f525_625   = DisplayBase::EXTIN_LINE_525;           /* Number of lines for BT.656 external input */
+    ext_in_config.inp_h_pos      = DisplayBase::EXTIN_H_POS_CRYCBY;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
+    ext_in_config.cap_vs_pos     = 6;                                     /* Capture start position from Vsync */
+    ext_in_config.cap_hs_pos     = 150;                                   /* Capture start position form Hsync */
+#if ((LCD_ONOFF) && (LCD_TYPE == 0))
+    /* The same screen ratio as the screen ratio of the LCD. */
+    ext_in_config.cap_width      = 640;                                   /* Capture width */
+    ext_in_config.cap_height     = 363;                                   /* Capture height Max 468[line]
+                                                                             Due to CMOS(MT9V111) output signal timing and VDC5 specification */
+#else
+    ext_in_config.cap_width      = 640;                                   /* Capture width */
+    ext_in_config.cap_height     = 468;                                   /* Capture height Max 468[line]
+                                                                             Due to CMOS(MT9V111) output signal timing and VDC5 specification */
+#endif
+    error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT, &ext_in_config);
+    if( error != DisplayBase::GRAPHICS_OK ) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Camera input port setting */
+    error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
+    if( error != DisplayBase::GRAPHICS_OK ) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+#endif
+
+    /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
+    error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, IntCallbackFunc_Vfield);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+}
+
+static void Start_Video(uint8_t * p_buf) {
+    DisplayBase::graphics_error_t error;
+
+    /* Video capture setting (progressive form fixed) */
+    error = Display.Video_Write_Setting(
+                VIDEO_INPUT_CH,
+                COL_SYS,
+                p_buf,
+                FRAME_BUFFER_STRIDE,
+                VIDEO_FORMAT,
+                WR_RD_WRSWA,
+                VIDEO_PIXEL_VW,
+                VIDEO_PIXEL_HW
+            );
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Video write process start */
+    error = Display.Video_Start(VIDEO_INPUT_CH);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Video write process stop */
+    error = Display.Video_Stop(VIDEO_INPUT_CH);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+
+    /* Video write process start */
+    error = Display.Video_Start(VIDEO_INPUT_CH);
+    if (error != DisplayBase::GRAPHICS_OK) {
+        printf("Line %d, error %d\n", __LINE__, error);
+        mbed_die();
+    }
+}
+
+/** 
+ * ZXingResource class
+ */
+class ZXingResource : public DynamicResource
+{
+private:
+    Thread * m_zxing_processor;
+    
+public:
+    /**
+    Default constructor
+    @param logger input logger instance for this resource
+    @param obj_name input the Accelerometer Object name
+    @param res_name input the Accelerometer Resource name
+    @param observable input the resource is Observable (default: FALSE)
+    */
+
+    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) {
+        // init
+        _instance = (void *)this;
+
+#if LCD_ONOFF
+        // Initialze LCD
+        Init_LCD_Display();
+#endif
+        // Initialize Video
+        Init_Video();
+
+        // Initialize frame buffer
+        for (int i = 0; i < FRAME_BUFFER_NUM; i++) {
+            memset(FrameBufferTbl[i], 0, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW));
+            dcache_clean(FrameBufferTbl[i], (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW));
+        }
+        
+        // Start Video
+        Start_Video(FrameBufferTbl[write_buff_num]);
+        /* Wait for first video drawing */
+        Wait_Vfield(2);
+
+#if LCD_ONOFF
+        DisplayBase::rect_t rect;
+
+        /* The layer by which the touch panel location is drawn */
+        ascii_font.Erase(0x00000000);  /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */
+        dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
+        rect.vs = 32;
+        rect.vw = VIDEO_PIXEL_VW_STR;
+        rect.hs = 32;
+        rect.hw = VIDEO_PIXEL_HW_STR;
+        Display.Graphics_Read_Setting(
+            DisplayBase::GRAPHICS_LAYER_1,
+            (void *)user_frame_buffer_string,
+            FRAME_BUFFER_STRIDE_STR,
+            DisplayBase::GRAPHICS_FORMAT_ARGB4444,
+            DisplayBase::WR_RD_WRSWA_32_16BIT,
+            &rect
+        );
+        Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1);
+        string_draw = false;
+        /* Start of LCD */
+        Start_LCD_Display(FrameBufferTbl[write_buff_num]);
+        /* Backlight on */
+        Thread::wait(200);
+        lcd_cntrst.write(1.0);
+#endif
+        decode_timer.reset();
+        decode_timer.start();
+
+        // no Thread yet
+        this->m_zxing_processor = NULL;
+    }
+
+    /**
+    Get the value of the barcode data
+    @returns string containing the acclerometer sensor value
+    */
+    virtual string get() {
+#if 1
+        if (this->m_zxing_processor == NULL) {
+            // create the processing thread
+            this->m_zxing_processor = new Thread(_zxing_processing);
+        }  
+                        
+        if (*decode_str == NULL) {
+            return string("{\"barcodeData\":0}\0");
+        } else {
+            return string(*decode_str);
+        }
+        
+#endif
+    }
+};
+
+void _zxing_processing(const void *args) {
+    while (true) {
+        _zxing_loop();
+        Thread::wait(5);
+    }
+}
+
+void _zxing_loop(void) {
+    DisplayBase::graphics_error_t error;
+    int decode_result = -1;
+     
+#if 1
+        decode_buffer = FrameBufferTbl[write_buff_num];
+        write_buff_num++;
+
+        if (write_buff_num >= FRAME_BUFFER_NUM) {
+            write_buff_num = 0;
+        }            
+        /* Change video buffer */
+        error = Display.Video_Write_Change(VIDEO_INPUT_CH, FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE);
+        if (error != DisplayBase::GRAPHICS_OK) {
+            printf("Line %d, error %d\n", __LINE__, error);
+            mbed_die();
+        }
+        Wait_Vfield(2);
+#if LCD_ONOFF
+        /* Change LCD buffer */
+        Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0, (void *)FrameBufferTbl[write_buff_num]);
+#endif
+        dcache_invalid(decode_buffer, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW));
+        /* Decode barcode image */
+        if (decode_timer.read_ms() >= decode_wait_time) {
+            decode_timer.reset();
+            decode_result = ex_decode(decode_buffer, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW), VIDEO_PIXEL_HW, VIDEO_PIXEL_VW, &results);
+            if (decode_result == 0) {
+                decode_str = (char **)&(results[0]->getText()->getText());
+                
+                if (_instance != NULL) {
+                    // observe...
+                    ((ZXingResource *)_instance)->observe();
+                }
+
+#if LCD_ONOFF
+                /* Drow string */
+                ascii_font.Erase(0x00000090);  /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */
+                int rest_size = strlen(*decode_str);
+                int draw_idx = 0;
+                int draw_size;
+                int draw_line = 0;
+                
+                while (rest_size > 0) {
+                    draw_size = ascii_font.DrawStr(*decode_str + draw_idx, 6, 5 + (18 * draw_line), 0x0000ffff, 2);
+                    if (draw_size <= 0) {
+                        break;
+                    }
+                    rest_size -= draw_size;
+                    draw_idx += draw_size;
+                    draw_line++;
+                }
+                
+                dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
+                string_draw = true;
+#endif
+                decode_wait_time = 500;
+            } else {
+#if LCD_ONOFF
+                if (string_draw != false) {
+                    /* Clear string */
+                    ascii_font.Erase(0x00000000);  /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */
+                    dcache_clean(user_frame_buffer_string, sizeof(user_frame_buffer_string));
+                    string_draw = false;
+                }
+#endif
+                decode_wait_time = 10;
+            }
+        }
+        display_app.SendRgb888(decode_buffer, VIDEO_PIXEL_HW, VIDEO_PIXEL_VW);
+#endif
+}
+#endif // __ZXING_RESOURCE_H__