www.pudn.com > bu1566.rar > BUxx_aDSC.c


/* ************************************************************************ */ 
/*                                                                          */ 
/* ROHM BU15xx demo firmware on MD2306                                      */ 
/*     Client   : ROHM Co., Ltd.                                       */ 
/*     End User :                                                           */ 
/*                                                                          */ 
/*     Processor: ARM-7TDMI(THUMB Mode)                                     */ 
/*     Dev.Env. : ARM-SDTv2.51                                              */ 
/*                                                                          */ 
/*     API:BU15xx control Routines                                          */ 
/*                                                                          */ 
/*     file     : BUxx_aDSC.c                                               */ 
/*     Auther   : J.SATO(NTC)                                              */ 
/*     Date     : 2004/Jul./1 	                                            */ 
/*                                                                          */ 
/*     Copyright (c) 2002-04 Naritagiken Co., Ltd. All rights reserved.     */ 
/* ************************************************************************ */ 
 
/* ************************************************** */ 
/*		     INCLUDE FILES		      */ 
/* ************************************************** */ 
#include "BUxx_aDSC.h" 
#include "BUxx_demoset.h" 
#include "LPC2294.h" 
 
/* ************************************************** */ 
/*		        TYPEDEF		    	      */ 
/* ************************************************** */ 
#define  BU1554_MIN(x,y)   ((x)>(y) ? (y) : (x)) 
 
 /* ************************************************** */ 
/*		     LOCAL DEFINES		      */ 
/* ************************************************** */ 
 
/* ************************************************** */ 
/*		    GLOBAL VARIABLE		      */ 
/* ************************************************** */ 
 
volatile int gl_bank_chk; 
volatile int gl_je_end_chk; 
volatile int gl_jd_end_chk; 
volatile int gl_cam_end_chk; 
volatile int gl_check_int; 
volatile int gl_dsc_status; 
 
#ifdef HOSTJD_TEST         
unsigned char gl_intcheck_sequence[30]; 
unsigned char gl_intcheck_index=0; 
unsigned char gl_intdisp_sequence[30]; 
unsigned char gl_intdisp_index=0; 
unsigned char gl_intmask_begin=0; 
unsigned char gl_intmask_end=0; 
unsigned char gl_jpgintmask_begin=0; 
unsigned char gl_jpgintmask_end=0; 
#endif 
 
// 
// Structs and Types for JPEG header 
// 
 
typedef struct 
{                               // Huffman table 
    UINT8 cod[16]; 
    UINT8 val[1]; 
} 
HTABLE; 
 
typedef struct 
{                               // Q table 
    UINT8 table[8][8]; 
} 
QTABLE; 
 
typedef struct 
{                               // header information 
    UINT16 X; 
    UINT16 Y; 
    UINT16 interval; 
    UINT8 type;                 // 0:444, 1:422, 2:411, 3:420, 4:gray 
    HTABLE *h_y_dc; 
    HTABLE *h_y_ac; 
    HTABLE *h_c_dc; 
    HTABLE *h_c_ac; 
    QTABLE *q_y; 
    QTABLE *q_c; 
    UINT8 *code; 
    UINT32 code_size; 
} 
JPEG_INFO; 
 
UINT32 ctable[] = { 0, 8035, 7568, 6811, 5793, 4551, 3135, 1598 }; 
UINT8 zigzag[] = { 0, 1, 8, 16, 9, 2, 3, 10, 
    17, 24, 32, 25, 18, 11, 4, 5, 
    12, 19, 26, 33, 40, 48, 41, 34, 
    27, 20, 13, 6, 7, 14, 21, 28, 
    35, 42, 49, 56, 57, 50, 43, 36, 
    29, 22, 15, 23, 30, 37, 44, 51, 
    58, 59, 52, 45, 38, 31, 39, 46, 
    53, 60, 61, 54, 47, 55, 62, 63 
}; 
 
 
typedef struct 
{ 
    UINT8 regread[2]; 
} 
JPEG_data; 
 
typedef struct 
{ 
    UINT8 Lf[2]; 
    UINT8 P; 
    UINT8 Y[2]; 
    UINT8 X[2]; 
    UINT8 Nf; 
    UINT8 CHVT[3][3];           //CHVT[?][0]:C,CHVT[?][1]:HV,CHVT[?][2]:T        
} 
SOF_data; 
 
typedef struct 
{ 
    UINT8 Lh[2]; 
    UINT8 TcTh; 
    UINT8 Ln[16]; 
} 
DHT_data; 
 
typedef struct 
{ 
    UINT8 Lq[2]; 
    UINT8 PqTq; 
    UINT8 Qn[64]; 
} 
DQT_data; 
 
typedef struct 
{ 
    UINT8 Lr[2]; 
    UINT8 Ri[2]; 
} 
DRI_data; 
 
 
typedef struct 
{ 
    UINT8 Ls[2]; 
    UINT8 Ns; 
    UINT8 CTT[4][2];            //CTT[?][0]:Cs,CTT[?][1]:TdTa    
} 
SOS_data; 
 
/* ************************************************** */ 
/*		         CONST			      */ 
/* ************************************************** */ 
 
/* ************************************************** */ 
/*		    GLOBAL FUNCTIONS		      */ 
/* ************************************************** */ 
 
/* ************************************************** */ 
/*		     LOCAL FUNCTIONS		      */ 
/* ************************************************** */ 
static int jpeg_encode(UINT16 * start_add, UINT32 * const jpeg_size, 
                       const int entype, const UINT16 je_q, 
                       const UINT16 hflip); 
static int jpeg_decode(UINT8 * start_add, UINT32 * const jpeg_size, 
                       const CAMSET * const cam); 
static int jpeg_HostDec(UINT8 * start_add, UINT32 * const jpeg_size, UINT16* p_u16Rgb_addr, 
                       const CAMSET * const cam); 
 
static int analyze_header(UINT8 * const jpeg, UINT32 * const jpeg_size, 
                          JPEG_INFO * const jpeg_info); 
static void set_jpeg_setting(const UINT16 X, const UINT16 Y, 
                             const UINT16 interval, const UINT8 type); 
static void set_huf_table(const HTABLE * const y_dc, 
                          const HTABLE * const y_ac, 
                          const HTABLE * const c_dc, 
                          const HTABLE * const c_ac); 
static void set_q_table(const QTABLE * const q_y, 
                        const QTABLE * const q_c); 
static void set_each_q_table(const QTABLE * const qtbl); 
static void set_code(UINT8 * code, const UINT32 start, const UINT32 end); 
static void read_code(UINT16 ** start_add, int store_num); 
static void CheckJpegInt(void); 
static int JpegIntDisp(UINT16* u16Rgb_addr, UINT32* p_u32CurRgbSize, UINT32 u32TotalRgbSize); 
 
//----------------------------------------------------------------------------- 
//                             bu15xx initialize 
//----------------------------------------------------------------------------- 
int aDSC_bu15xx_OPEN(void) 
{ 
    int i; 
    UINT16 temp; 
    int ret_code = 0; 
    int err_code = 0; 
 
    gl_check_int = 0; 
    gl_dsc_status = 0; 
 
 
//---- HW Mode register initialize---- 
    hwmode_write(sSUSPEND); 
    hostcnt_write(sDIRECT_ACS | sDIRECT_ENABLE | HOST_TYPE); 
 
    mode_change(sREADY); 
    wait(1); 
 
    data_write(0xD0, 0x0004);   // SCLK ON 
    data_write(0xF8, 0x0000);   // RESET clear 
    data_write(0xF8, 0x0010);   // Initialize Register Enable 
    data_write(0xF8, 0x0011);   // Initialize Sequence Start 
 
    while (reg_read(REG) & 0x0002); 
    data_write(0xD0, 0x0000);   // SCLK OFF 
    data_write(0xF8, 0x0000);   // Initialize Register Disable 
    data_write(0xF8, 0x1000);   // Compensation Enable 
 
    data_write(0xD0, 0x0004);   // SCLK ON 
    data_write(0xD9, 0x0000);   // BANK 0 select 
    data_write(0xFA, 0x0300);   // BANK 0 Enable 
    data_write(0xD9, 0x0100);   // BANK 1 select 
    data_write(0xFA, 0x0300);   // BANK 1 Enable 
    data_write(0xD9, 0x0200);   // BANK 2 select 
    data_write(0xFA, 0x0300);   // BANK 2 Enable 
    data_write(0xD9, 0x0300);   // BANK 3 select 
    data_write(0xFA, 0x0300);   // BANK 3 Enable 
    data_write(0xD9, 0x0400);   // BANK 4 select 
    data_write(0xFA, 0x0300);   // BANK 4 Enable 
    data_write(0xD9, 0x0500);   // BANK 5 select 
    data_write(0xFA, 0x0300);   // BANK 5 Enable 
    data_write(0xD9, 0x0600);   // BANK 6 select 
    data_write(0xFA, 0x0300);   // BANK 6 Enable 
    data_write(0xD9, 0x0700);   // BANK 7 select 
    data_write(0xFA, 0x0300);   // BANK 7 Enable 
    data_write(0xD9, 0x0800);   // BANK 8 select 
    data_write(0xFA, 0x0300);   // BANK 8 Enable 
    data_write(0xD9, 0x0900);   // BANK 9 select 
    data_write(0xFA, 0x0300);   // BANK 9 Enable 
    data_write(0xD9, 0x0a00);   // BANK10 select 
    data_write(0xFA, 0x0300);   // BANK10 Enable 
    data_write(0xD9, 0x0b00);   // BANK11 select 
    data_write(0xFA, 0x0300);   // BANK11 Enable 
 
//---- Clock Mode register initialize---- 
    ret_code = clk_div1_set(SCLK_DIV);  // SCLK = XIN / SCLK_DIV 
    if (ret_code) 
        err_code = ret_code | 0x01000; 
 
    ret_code = clk_div2_set(LCDFR_DIV, LCDFR_DELAY);    // LCDFR = (SCLK / 4096) / LCDFR_DIV 
    if (ret_code) 
        err_code = ret_code | 0x01100; 
 
    ret_code = clk_div3_set(CAMCKO_DIV);        // CAMCKO = XIN / CAMCKO_DIV 
    if (ret_code) 
        err_code = ret_code | 0x01200; 
 
    clk_cnt_set(VD_EN | VDEDG_SEL | LCD_BASE_TIMING | sLCDFR_ENABLE | sSCK_ENABLE | sCMCK_ENABLE);      //LCDFR,SCLK,CAMCKO Enable 
 
//---- Interrupt register initialize---- 
    data_write(INDEX, 0x0000);  //Interrupt status clear 
    data_write(INTMSK, 0xffff); //all mask cleared 
    data_write(INTCNT, INT_POL | INT_SEL);      //Interrupt control 
 
//---- LED PWM Control initialize ---- 
    data_write(PWMCNT1, LEDCNT_POL | LEDCNT_EN); 
 
//---- GIO register initialize---- 
    data_write(GIOCNT, 0x7f7b); //all input 
    data_write(EXGIOCNT, 0xffff);       //all input 
     
 //---- GIO2 high:cam i/f ON ---- 
 
 
   //    data_write(GIOOUT, 0x0004);                              
   data_write(GIOOUT, 0x0000); 
    wait(5); 
  
     bit_write(0x0120, 0x0003,0x0000);   // GPIO2 cortarl 
 
//---- Memory register initialize---- 
    mem_point_set(0, 0);        //cam image storage position set 
    data_write(MEMCNT, 0x0000); 
 
    mem_acs_read_st(MEMACS_YUV); 
    for (i = 0; i < 5; i++) 
    { 
        temp = reg_read(REG); 
    } 
 
//---- CAM register initialize ---- 
    cam_if_set(sCAMRST_OFF | VSPOL | HSPOL | CKPOL | RGBorYUV | RGBORD | YUVORD);       //cam I/F setup 
    ret_code = cam_tim_set(CXS, CYS);   //A cam I/F frame start pixel position is set up 
    if (ret_code) 
        err_code = ret_code | 0x01300; 
 
    data_write(CAMFLT, sDISABLE);       //fliter function:DISABLE 
    ret_code = cam_size_set(CAM_HSIZE, CAM_VSIZE);      //Camera image size is set up 
    if (ret_code) 
        err_code = ret_code | 0x01400; 
 
    data_write(CAMYD, 0x0000);  //A brightness element is expanded 
    cam_lowpathfilter_set(); 
 
    mode_change(sREADY); 
    wait(1); 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                      BU15xx CLOSE dispose (SUSPEND mode) 
//----------------------------------------------------------------------------- 
void aDSC_bu15xx_CLOSE(void) 
{ 
    aDSC_Quit_Preview(); 
 
    if (bit_read(LCDCNT, bLCD_SEL) == sMAIN_ACS) 
    { 
        column_page_set(0, M_LCD_WSIZE - 1, 0, M_LCD_HSIZE - 1); 
    } 
    else 
    { 
        column_page_set(0, S_LCD_WSIZE - 1, 0, S_LCD_HSIZE - 1); 
    } 
 
    mode_change(sSUSPEND); 
 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                             Start Preview dispose 
//----------------------------------------------------------------------------- 
int aDSC_Start_Preview(const UINT16 st_x, const UINT16 st_y, 
                       const UINT16 xsize, const UINT16 ysize, 
                       const CAMSET * const cam) 
{ 
    int err_code = 0; 
    int ret_code = 0; 
 
    aDSC_Quit_Preview(); 
 
    ret_code = lcd_trans_set(st_x, st_y, xsize, ysize); 
    if (ret_code) 
        err_code = ret_code | 0x1500; 
 
    ret_code = cam_capture_set(cam); 
    if (ret_code) 
        err_code = ret_code | 0x1600; 
 
    mode_change(sNVIEWER);      //VIEWER MODE 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                            Quit Preview dispose 
//----------------------------------------------------------------------------- 
UINT16 aDSC_Quit_Preview(void) 
{ 
    UINT16 reg_data; 
 
    reg_data = hwmode_read(); 
    if (reg_data == sNVIEWER) 
    { 
        wait_int0(bLCDED_MSK); 
        /* William delete 20050524 
        if (bit_read(LCDCNT, bLCD_SEL) == sMAIN_ACS) 
        { 
            column_page_set(0, M_LCD_WSIZE - 1, 0, M_LCD_HSIZE - 1); 
        } 
        else 
        { 
            column_page_set(0, S_LCD_WSIZE - 1, 0, S_LCD_HSIZE - 1); 
        } 
        */ 
    } 
    else if (reg_data != sREADY) 
    { 
        mode_change(sREADY); 
    } 
 
    return (reg_data); 
} 
 
/* 
int aDSC_ExOverlay_Preview(const UINT16 *p_Ovldata,const tExOvl* p_ExOvl ) 
{  
    UINT16 cnt,u16Temp; 
    UINT8 u8OvlNum; 
 
    data_write(OVL_CNT,0x0012); 
 
    data_write(OVL_TRANS,0xffff); 
    data_write(OVL_TRMSK,0x0000); 
 
    data_write(OVLSIZE,0x2020);	//32*32 
    data_write(OVL_FRMST1,0x0000); 
    data_write(OVL_ST1,0x0000); 
    data_write(OVL_ED1,0x1f1f); 
 
    data_write(MEM_ADR_OVL_ST,0x0000); 
    data_write(MEM_ADR_OVL_ED,0x1f1f); 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, HIGH); //rectangle increment、auto increment on 
 
    memcnt_data = reg_read(INDEX); 
    reg_write(INDEX, MEMACS_OVL); 
 
    for(i=0;i<32*32;i++) 
    { 
        reg_write(REG, char_dat[i]); 
    } 
    bit_write(MEMCNT, bINCMTH | bADRINC, LOW); //rectangle increment、auto increment off 
 
//    data_write(OVL_CNT,0x0000); 
 
        reg_write(INDEX, OVL_CNT); 
        if ((reg_read(REG) & 0x0002) == 0) 
        { 
            wait_time = 0; 
            x_step = 1; 
            y_step = 1; 
            data_write(OVL_CNT, 0x0012); 
            data_write(OVL_FRMST1, (((M_LCD_WSIZE - 32) / 2) << 8) | ((M_LCD_HSIZE - 32) / 2)); //95,60 
        } 
 
    reg_write(INDEX, OVL_CNT); 
    if ((reg_read(REG) & 0x0002) != 0) //Overlay is on 
    { 
        if (wait_time >= 1000) 
        { 
            wait_time = 0; 
            reg_write(INDEX, OVL_FRMST1); 
            memcnt_data = reg_read(REG); 
 
            if (x_step == 1) 
            { 
                if (((memcnt_data & 0xff00) >> 8) + 0x0020 >= M_LCD_WSIZE) 
                    x_step = -1; 
            } 
            else 
            { 
                if ((memcnt_data & 0xff00) <= 0x0000) 
                    x_step = 1; 
            } 
 
            if (y_step == 1) 
            { 
                if ((memcnt_data & 0x00ff) + 0x0021 > M_LCD_HSIZE) 
                    y_step = -1; 
            } 
            else 
            { 
                if ((memcnt_data & 0x00ff) <= 0x0000) 
                    y_step = 1; 
            } 
 
 
            reg_write(REG, memcnt_data + (x_step << 8) + y_step); 
        } 
        else 
        { 
            wait_time++; 
        } 
    } 
 
 
 
 
     
    data_write(0xb0,p_exovl->ovlnum);// type, transparent,overlay1&2 
    data_write(0xb1,((p_exovl->xsize<<8)|p_exovl->ysize));//size= 
    u8OvlNum=p_exovl->ovlnum&0x0003; 
 
    if(u8OvlNum==0x0002) 
    { 
        u16Temp=(p_exovl->fmstx<<8)|p_exovl->fmsty; 
        data_write(0xb2,u16Temp);//X start &Y start in the frame 
        u16Temp=(p_exovl->ovlstx<<8)|p_exovl->ovlsty; 
        data_write(0xb7,u16Temp);// X start &Y start in the overlay memory 
        u16Temp=(p_exovl->ovledx<<8)|p_exovl->ovledy; 
        data_write(0xb8,u16Temp);// X end &Y end in the overlay memory 
    } 
 
    else if(u8OvlNum==0x0001) 
    { 
        data_write(0xb3,((p_exovl->fmstx<<8)|p_exovl->fmsty));// X start &Y start in the frame  
        data_write(0xb9,((p_exovl->ovlstx<<8)|p_exovl->ovlsty));// X start &Y start in the overlay memory 
        data_write(0xba,((p_exovl->ovledx<<8)|p_exovl->ovledy)); // X end &Y end in the overlay memory	 
    } 
 
    data_write(0xbb,p_exovl->ovl_trans);//transparent coclor 
    data_write(0xbc,p_exovl->ovl_trmsk);//transparent color mask 
    data_write(0xbd,p_exovl->front_color);//front color 
    data_write(0xbe,p_exovl->back_color);//background color 
 
    data_write(0xb5,((p_exovl->mem_adr_ovr_stx)<<8|p_exovl->mem_adr_ovr_sty));// MEM_ADR_OVL_ST  
    data_write(0xb6,((p_exovl->mem_adr_ovr_edx)<<8|p_exovl->mem_adr_ovr_edy));// (edx,edy)=(,) 
 
    reg_write(INDEX, 0xb4); 
    for (cnt = 0; cnt <(p_exovl->xsize)*(p_exovl->ysize) ; cnt++) 
    { 
        reg_write( REG, *ovl_data);					//RGB Data are written 
        ovl_data++; 
    } 
 
} 
*/     
//----------------------------------------------------------------------------- 
//                            interrupt dispose 
//----------------------------------------------------------------------------- 
void __irq aDSC_int_disp(void) 
{ 
#if !defined	BUXX_POLLING 
    UINT16 idx_push; 
    UINT16 reg_data; 
 
    switch (gl_dsc_status) 
    { 
    case sJPEGDECODE: 
    case sLEDMODE: 
        //no dispose 
        break; 
    case sRINGBUFFER: 
    case sHOSTJPEGDEC://KRIS ADD 2006-3-6 16:20 
        idx_push = reg_read(INDEX); 
 
        reg_data = data_read(JPG_INTST); 
        if (BUSACCESS_BIT == 8 && hostcnt_bitread(bHOST_END) != 0) 
        { 
            reg_data = 
                ((reg_data & 0xff00) >> 8) | ((reg_data & 0x00ff) << 8); 
        } 
 
        if (reg_data & bJE_RING_INT) 
        {                       // JE_RING_INT 
            bit_write(JPG_INTST, bJE_RING_INT, LOW);    // JE_RING_INT clear 
            gl_bank_chk++; 
        } 
        else if (reg_data & bJE_ED_INT) 
        { 
            bit_write(JPG_INTST, bJE_ED_INT, LOW);      // JE_ED_INT clear 
            gl_je_end_chk++; 
        } 
        if (reg_data & bJD_ED_INT)//Kris add 
        { 
            bit_write(JPG_INTST, bJD_ED_INT, LOW);      // JD_ED_INT clear 
            gl_jd_end_chk++; 
        } 
        reg_write(INDEX, idx_push); 
        break; 
    default: 
        idx_push = reg_read(INDEX); 
        mode_change(sREADY); 
 
        reg_write(INDEX, idx_push); 
        break; 
 
    } 
    gl_check_int = 1; 
  
 #if 1    
//  INT=p0.16 
 EXTINT = 0x01;  //ヌ蟲EINT0 ヨミカマアヨセ 
  VICVectAddr = 0x00;   //ヘィヨェヨミカマス? 
 
#else  
//  INT=p0.20 
   
  VICVectAddr = 0;			// マチソヨミカマス睫 
 EXTINT = 1<<3;			// ヌ蟲p0.20 EINT3ヨミカマアヨセ」ャ1<<3 オネシロモレ 0x08 
#endif 
 
#endif 
 
} 
 
//----------------------------------------------------------------------------- 
//                             filter function setup 
//----------------------------------------------------------------------------- 
int aDSC_filter_set(const char *format, ...) 
{ 
    int i; 
    va_list ap; 
    int filter = 0xff; 
    char *cmp[] = 
        { "disable", "thd", "gray", "sepia", "emboss", "edge1", "edge2", 
        "nega", "camyd" }; 
    int fil_sel[] = 
        { sDISABLE, sTHD, sGRAY, sSEPIA, sEMBOSS, sEDGE1, sEDGE2, sNEGA, 
        sCAMYD }; 
    int temp1, temp2; 
    UINT16 reg_data; 
    int err_code = 0; 
 
    reg_data = aDSC_Quit_Preview(); 
 
    va_start(ap, format); 
 
    for (i = 0; i < 10; i++) 
    { 
        if (strcmp(format, cmp[i]) == 0) 
        { 
            filter = fil_sel[i]; 
            break; 
        } 
    } 
 
    switch (filter) 
    { 
    case sDISABLE: 
        data_write(CAMFLT, sDISABLE);   // IDX_ADR : 0x11 no processing 
        break; 
    case sTHD: 
        data_write(CAMFLT, sTHD);       // IDX_ADR : 0x11 gradate in two grade 
        temp1 = va_arg(ap, int); 
        if (temp1 > maxFLTTHD) 
            err_code = 0x2001; 
        data_write(FLTTHD, temp1);      // IDX_ADR : 0x12 
        break; 
    case sGRAY: 
        data_write(CAMFLT, sGRAY);      // IDX_ADR : 0x11 gray scale 
        break; 
    case sSEPIA: 
        data_write(CAMFLT, sSEPIA);     // IDX_ADR : 0x11 sepia 
        temp1 = va_arg(ap, int); 
        if (temp1 > maxSEPIAR) 
            err_code = 0x2002; 
        temp2 = va_arg(ap, int); 
        if (temp2 > maxSEPIAB) 
            err_code = 0x2003; 
        data_write(FLTSEP, (temp1 << 8) | temp2);       // IDX_ADR : 0x13 SEPIAR = 32d, SEPIAB = -16d 
        temp1 = va_arg(ap, int); 
        if (temp1 > maxSEPRNG) 
            err_code = 0x2004; 
        data_write(SEPRNG, temp1);      // IDX_ADR : 0x14 
        break; 
    case sEMBOSS: 
        data_write(CAMFLT, sEMBOSS);    // IDX_ADR : 0x11 emboss 
        temp1 = data_read(FLTCOEF) & 0xff00; 
        temp2 = va_arg(ap, int); 
        if (temp2 > maxFLTEBS) 
            err_code = 0x2005; 
        data_write(FLTCOEF, temp1 | temp2);     // IDX_ADR : 0x15 
        break; 
    case sEDGE1: 
        data_write(CAMFLT, sEDGE1);     // IDX_ADR : 0x11 edge sampling1 
        temp1 = va_arg(ap, int); 
        if (temp1 > maxFLTTHD) 
            err_code = 0x2006; 
        data_write(FLTTHD, temp1);      // IDX_ADR : 0x12 Threshold = 0x01 
        temp1 = data_read(FLTCOEF) & 0x00ff; 
        temp2 = (va_arg(ap, int)); 
        if (temp2 > maxFLTEDG1) 
            err_code = 0x2007; 
        data_write(FLTCOEF, temp1 | (temp2 << 8));      // IDX_ADR : 0x15 
        break; 
    case sEDGE2: 
        data_write(CAMFLT, sEDGE2);     // IDX_ADR : 0x11 edge sampling2 
        temp1 = va_arg(ap, int); 
        if (temp1 > maxFLTEDG2) 
            err_code = 0x2008; 
        temp2 = va_arg(ap, int); 
        if (temp2 > maxEDG2OFS) 
            err_code = 0x2009; 
        data_write(FLTEDG2, temp1 << 8 | temp2);        // IDX_ADR : 0x16 
        break; 
    case sNEGA: 
        data_write(CAMFLT, sNEGA);      // IDX_ADR : 0x11 negative 
        break; 
    case sCAMYD: 
        temp1 = va_arg(ap, int); 
        if (temp1 > maxCAMYD) 
            err_code = 0x200a; 
        data_write(CAMYD, temp1); 
        break; 
    default: 
        err_code = 0x2000; 
        data_write(CAMFLT, sDISABLE);   // IDX_ADR : 0x11 no processing 
        break; 
    } 
 
    va_end(ap); 
    if (reg_data == sNVIEWER) 
        mode_change(sNVIEWER); 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                               I2C Dispose 
//----------------------------------------------------------------------------- 
int aDSC_i2c_set(const UINT16 seri_devtype, const UINT16 seri_devadr, 
                 const UINT16 seri_2ndadr, const UINT16 seri_dat, 
                 const UINT16 peri_sdc, const UINT16 seri_rw) 
{ 
    int busy_flag = 1; 
    int err_code = 0; 
 
    if (seri_devadr > maxSERI_DEVADR) 
        err_code = 0x2100; 
    if (seri_2ndadr > maxSERI_2NDADR) 
        err_code = 0x2101; 
    if (seri_dat > maxSERI_DAT) 
        err_code = 0x2102; 
    if (peri_sdc > maxPERI_SDC) 
        err_code = 0x2103; 
 
    if (err_code) 
    { 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
        return err_code; 
    } 
 
    data_write(SERIDEVADR, 
               sSERI_HZ | sSERI_PULL_ON | seri_devtype | sSERI_ENABLE | 
               seri_devadr); 
    data_write(SERI2NDADR, seri_2ndadr); 
    data_write(SERICNT, (seri_dat << 8) | (peri_sdc << 4) | seri_rw); 
 
    bit_write(SERICNT, bSERI_ST, HIGH); //serial transfer start 
    while (busy_flag) 
    {                           // SERI_BSYのポーリング 
        busy_flag = bit_read(SERICNT, bSERI_BSY); 
    } 
 
    wait(1);                    //Tbuf 
 
#if 0 
    if (bit_read(SERICNT, bACK_STAT)) 
        err_code = 0x2104; 
    if (err_code) 
    { 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
        return err_code; 
    } 
#endif 
 
    return 0; 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                      frame memory write(rgb565 data) 
//----------------------------------------------------------------------------- 
int aDSC_fmemory_write_rgb565(const UINT16 * rgb_data, const UINT16 st_x, 
                              const UINT16 st_y) 
{ 
    int cnt, write_count; 
    UINT16 xsize, ysize; 
    int err_code = 0; 
 
    aDSC_Quit_Preview(); 
 
    xsize = *rgb_data; 
    rgb_data++; 
    ysize = *rgb_data; 
    rgb_data++; 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, LOW);  //rectangle increment、auto increment off 
    err_code = 
        mem_adrst_ed_set(st_x, st_y, st_x + xsize - 1, st_y + ysize - 1); 
    if (err_code) 
        err_code |= 0x3000; 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, HIGH); //rectangle increment、auto increment on 
 
    write_count = xsize * ysize; 
 
    mem_acs_write_st(MEMACS_RGB); 
    for (cnt = 0; cnt < write_count; cnt++) 
    { 
        reg_write(REG, *rgb_data);      //RGB Data are written 
        rgb_data++; 
    } 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, LOW);  //rectangle increment、auto increment on 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
 
} 
 
int aDSC_ExOvlMemory_write_rgb565(const UINT16 * rgb_data) 
{ 
    int cnt, write_count; 
    UINT16 xsize, ysize; 
    int err_code = 0; 
 
 //   aDSC_Quit_Preview(); 
 
    xsize = *rgb_data; 
    rgb_data++; 
    ysize = *rgb_data; 
    rgb_data++; 
 
    data_write(MEM_ADR_OVL_ST,0x0000); 
    data_write(MEM_ADR_OVL_ED,((xsize-1)<<8)|(ysize-1)); 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, HIGH); //rectangle increment、auto increment on 
 
    write_count = xsize * ysize; 
 
    mem_acs_write_st(MEMACS_OVL); 
 
    for (cnt = 0; cnt < write_count; cnt++) 
    { 
        reg_write(REG, *rgb_data);      //RGB Data are written 
        rgb_data++; 
    } 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, LOW); //rectangle increment、auto increment off 
 
    return err_code;  
} 
 
int aDSC_fmemory_write_rgb565_2(const UINT16 * rgb_data, const UINT16 st_x, 
                              const UINT16 st_y, const UINT16 xsize, const UINT16 ysize ) 
{ 
    int cnt, write_count; 
    int err_code = 0; 
 
    aDSC_Quit_Preview(); 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, LOW);  //rectangle increment、auto increment off 
    err_code = 
        mem_adrst_ed_set(st_x, st_y, st_x + xsize - 1, st_y + ysize - 1); 
    if (err_code) 
        err_code |= 0x3000; 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, HIGH); //rectangle increment、auto increment on 
 
    write_count = xsize * ysize; 
 
    mem_acs_write_st(MEMACS_RGB); 
    for (cnt = 0; cnt < write_count; cnt++) 
    { 
        reg_write(REG, *rgb_data);      //RGB Data are written 
        rgb_data++; 
    } 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, LOW);  //rectangle increment、auto increment on 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
 
} 
 
 
 
int aDSC_ExOvlmemory_write(const UINT16 * rgb_data) 
{ 
    UINT16 u16Ovl_H, u16Ovl_V; 
 
    u16Ovl_H = *rgb_data; 
    u16Ovl_V = *(rgb_data+1); 
 
    data_write(OVL_CNT,0x0013); 
    data_write(OVL_TRANS,0xffff); 
    data_write(OVL_TRMSK,0x0000); 
 
    data_write(OVLSIZE, (u16Ovl_H<<8)|u16Ovl_V);	//32*32 
//    data_write(OVL_FRMST1,0x5b04); 
//    data_write(OVL_FRMST2,0x0878); 
    data_write(OVL_ST1,0x0000); 
    data_write(OVL_ED1,((u16Ovl_H-1)<<8)|(u16Ovl_V/2-1)); 
    data_write(OVL_ST2,u16Ovl_V/2); 
    data_write(OVL_ED2,((u16Ovl_H-1)<<8)|(u16Ovl_V-1)); 
 
    aDSC_ExOvlMemory_write_rgb565(rgb_data); //william for overlay 
 
    data_write(OVL_CNT,0x0000); 
 
    return 0; 
} 
 
//----------------------------------------------------------------------------- 
//                      frame memory write(rgb565 data) 
//----------------------------------------------------------------------------- 
int aDSC_transparent_write_rgb565(const UINT16 * rgb_data, 
                                  const UINT16 st_x, const UINT16 st_y, 
                                  const UINT16 color, const UINT16 c_mask) 
{ 
    int cnt, write_count; 
    UINT16 xsize, ysize; 
    int err_code = 0; 
 
    aDSC_Quit_Preview(); 
 
    xsize = *rgb_data; 
    rgb_data++; 
    ysize = *rgb_data; 
    rgb_data++; 
 
    data_write(MEMTRANS, color); 
    data_write(MEMTRMSK, c_mask); 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, LOW);  //rectangle increment、auto increment off 
    err_code = 
        mem_adrst_ed_set(st_x, st_y, st_x + xsize - 1, st_y + ysize - 1); 
    if (err_code) 
        err_code |= 0x3100; 
 
    bit_write(MEMCNT, bTRON | bINCMTH | bADRINC, HIGH); //rectangle increment、auto increment on 
 
    write_count = xsize * ysize; 
 
    mem_acs_write_st(MEMACS_RGB); 
    for (cnt = 0; cnt < write_count; cnt++) 
    { 
        reg_write(REG, *rgb_data);      //RGB Data are written 
        rgb_data++; 
    } 
 
    data_write(MEMTRANS, 0x0000); 
    data_write(MEMTRMSK, 0xffff); 
    bit_write(MEMCNT, bTRON | bINCMTH | bADRINC, LOW);  //rectangle increment、auto increment on 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                      frame memory write(color select) 
//----------------------------------------------------------------------------- 
int aDSC_fmemory_clear(const UINT16 st_x, const UINT16 st_y, 
                       const UINT16 xsize, const UINT16 ysize, 
                       const UINT16 color) 
{ 
    int cnt, write_count; 
    int err_code = 0; 
 
    aDSC_Quit_Preview(); 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, LOW);  //rectangle increment、auto increment off 
    err_code = 
        mem_adrst_ed_set(st_x, st_y, st_x + xsize - 1, st_y + ysize - 1); 
    if (err_code) 
        err_code |= 0x3200; 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, HIGH); //rectangle increment、auto increment on 
 
    write_count = xsize * ysize; 
 
    mem_acs_write_st(MEMACS_RGB); 
    for (cnt = 0; cnt < write_count; cnt++) 
    { 
        reg_write(REG, color);  //RGB Data are written 
    } 
 
    bit_write(MEMCNT, bINCMTH | bADRINC, LOW);  //rectangle increment、auto increment on 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                            mask memory write 
//----------------------------------------------------------------------------- 
//int aDSC_maskmemory_write(const UINT16 xsize, const UINT16 ysize) 
int aDSC_maskmemory_write(const UINT16 xstart, const UINT16 ystart, 
 const UINT16 xsize, const UINT16 ysize, const UINT16 alpha_color) 
{ 
    int err_code = 0; 
 
    aDSC_Quit_Preview(); 
 
//    err_code = mem_maskmemory_set(xsize, ysize);//kris test 2006-5-12 15:02 
     err_code = mem_maskmemory_set(xstart, ystart,xsize, ysize,  alpha_color); 
 
    if (err_code) 
    { 
        err_code |= 0x3300; 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    } 
    return (err_code); 
 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                         overlayframe on dispose 
//----------------------------------------------------------------------------- 
void aDSC_overlayframe_on(void) 
{ 
    UINT16 reg_data; 
 
    reg_data = aDSC_Quit_Preview(); 
    bit_write(MEMCNT, bMSKON, HIGH);    //MASK ON 
 
    if (reg_data == sNVIEWER) 
        mode_change(sNVIEWER); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                        overlayframe off dispose 
//----------------------------------------------------------------------------- 
void aDSC_overlayframe_off(void) 
{ 
    UINT16 reg_data; 
 
    reg_data = aDSC_Quit_Preview(); 
    bit_write(MEMCNT, bMSKON, LOW);     //MASK OFF 
 
    if (reg_data == sNVIEWER) 
        mode_change(sNVIEWER); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                             Data transfer start 
//----------------------------------------------------------------------------- 
int aDSC_data_trans_st(const UINT16 st_x, const UINT16 st_y, 
                       const UINT16 xsize, const UINT16 ysize) 
{ 
    int err_code = 0; 
 
    aDSC_Quit_Preview(); 
 
    err_code = lcd_trans_set(st_x, st_y, xsize, ysize); 
    if (err_code) 
        return (err_code | 0x4000); 
 
    mode_change(sLCDMANUAL); 
 
    gl_check_int = 0; 
    data_write(INTST, 0x0000);  //Interrupt status clear 
    data_write(INTMSK, 0x077e); //lcded_int enable 
 
    bit_write(MLCDCNT, bMSCANST, HIGH); //Data transfer start 
 
#if defined BUXX_POLLING 
    wait(10); 
    reg_write(INDEX, INTST); 
    while (reg_read(REG) == 0); 
    mode_change(sREADY); 
#else 
    while (gl_check_int == 0); 
#endif 
    data_write(INTMSK, 0xffff); //all mask cleared 
 
//      wait_int0(bLCDED_MSK); 
    mode_change(sREADY); 
 
    if (bit_read(LCDCNT, bLCD_SEL) == sMAIN_ACS) 
    { 
        column_page_set(0, M_LCD_WSIZE - 1, 0, M_LCD_HSIZE - 1); 
    } 
    else 
    { 
        column_page_set(0, S_LCD_WSIZE - 1, 0, S_LCD_HSIZE - 1); 
    } 
 
    return 0; 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                    MainLCD or SubLCD select, LCD initialize 
//----------------------------------------------------------------------------- 
int aDSC_lcdaccess_set(const int access) 
{ 
    int err_code = 0; 
    int ret_code = 0; 
 
    hostcnt_write(sDIRECT_ACS | sDIRECT_ENABLE | HOST_TYPE); 
 
    if (access == sMAIN_ACS) 
    { 
        data_write(MLCDTYPE, M_LCD_CTYPE);      //???color 
        ret_code = lcd_wav_set(M_LCDWL, M_LCDWH); 
        if (ret_code) 
            err_code = ret_code | 0x4100; 
        ret_code = lcd_size_set(M_LCD_WSIZE, M_LCD_HSIZE); 
        if (ret_code) 
            err_code = ret_code | 0x4200; 
        ret_code = lcd_point_set(0, 0, M_LCD_WSIZE - 1, M_LCD_HSIZE - 1); 
        if (ret_code) 
            err_code = ret_code | 0x4300; 
    } 
    else 
    { 
        data_write(MLCDTYPE, S_LCD_CTYPE);      //???color 
        ret_code = lcd_wav_set(S_LCDWL, S_LCDWH); 
        if (ret_code) 
            err_code = ret_code | 0x4100; 
        ret_code = lcd_size_set(S_LCD_WSIZE, S_LCD_HSIZE); 
        if (ret_code) 
            err_code = ret_code | 0x4200; 
        ret_code = lcd_point_set(0, 0, S_LCD_WSIZE - 1, S_LCD_HSIZE - 1); 
        if (ret_code) 
            err_code = ret_code | 0x4300; 
    } 
 
    ret_code = lcd_cmd_set(access); 
    if (ret_code) 
        err_code = ret_code | 0x4400; 
 
    //---- MAIN LCD設定 ---- 
    bit_write(LCDCNT, bPARA_SERI | bLCD_SEL, LOW); 
    bit_write(LCDCNT, sPARALLEL | access, HIGH); 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return err_code; 
 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                            Frame JPEG Encode dispose 
//----------------------------------------------------------------------------- 
int aDSC_FrameEncode(UINT16 * start_add, UINT32 * const jpeg_size, 
                     const UINT16 st_x, const UINT16 st_y, 
                     const UINT16 xsize, const UINT16 ysize, 
                     const UINT16 je_q) 
{ 
    int err_code = 0; 
    UINT16 reg_camflt; 
 
    aDSC_Quit_Preview(); 
 
    if (je_q > maxJE_Q) 
    { 
        err_code = 0x11000; 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
        return (err_code); 
    } 
 
    reg_camflt = data_write(CAMFLT, sDISABLE); 
 
    err_code = 
        lcd_point_set(st_x, st_y, st_x + xsize - 1, st_y + ysize - 1); 
    if (err_code) 
    { 
        err_code |= 0x11100; 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
        return (err_code); 
    } 
 
    err_code = 
        jpeg_encode(start_add, jpeg_size, sFRAMEJPEG, je_q, sJE_HFLIP_OFF); 
    if (err_code) 
    { 
        err_code |= 0x11200; 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
        return (err_code); 
    } 
 
    data_write(CAMFLT, reg_camflt); 
 
    return (err_code); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                           Camera JPEG Encode dispose 
//----------------------------------------------------------------------------- 
int aDSC_CameraEncode(UINT16 * start_add, UINT32 * const jpeg_size, 
                      const CAMSET * const cam, const UINT16 je_q, 
                      const UINT16 je_hflip) 
{ 
    int err_code = 0; 
 
    aDSC_Quit_Preview(); 
 
    if (je_q > maxJE_Q) 
    { 
        err_code = 0x11500; 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
        return (err_code); 
    } 
 
 
    err_code = cam_capture_set(cam); 
    if (err_code) 
    { 
        err_code |= 0x11600; 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
        return (err_code); 
    } 
 
    err_code = jpeg_encode(start_add, jpeg_size, sRINGBUFFER, je_q, je_hflip); 
     
    if (err_code) 
    { 
        err_code |= 0x11700; 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
        return (err_code); 
    } 
 
    return (err_code); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                             Jpeg Decode dispose 
//----------------------------------------------------------------------------- 
int aDSC_Decode(UINT16 * start_add, UINT32 * const jpeg_size, 
                const CAMSET * cam) 
{ 
    int err_code = 0; 
 
    aDSC_Quit_Preview(); 
 
    err_code = jpeg_decode((UINT8 *) start_add, jpeg_size, cam); 
 
    if (err_code) 
    { 
        err_code |= 0x12000; 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    } 
    return (err_code); 
} 
 
int aDSC_HostJpegDec(UINT16 * start_add, UINT32 * const jpeg_size, UINT16* p_u16Rgb_addr,  
                              const CAMSET * cam) 
{ 
    int err_code = 0; 
 
    aDSC_Quit_Preview(); 
 
    err_code = jpeg_HostDec((UINT8 *) start_add, jpeg_size, p_u16Rgb_addr, cam); 
 
    if (err_code) 
    { 
        err_code |= 0x13000; 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    } 
    return (err_code); 
 
} 
 
//----------------------------------------------------------------------------- 
//                              Red LED setup   
//----------------------------------------------------------------------------- 
int aDSC_redled_set(const UINT16 ledon, const UINT16 ledoff, 
                    const UINT16 slope, const UINT16 duty) 
{ 
    int err_code = 0; 
 
    if (ledon > maxRON) 
        err_code = 0x5000; 
    if (ledoff > maxROFF) 
        err_code = 0x5001; 
    if (slope > maxRSLOPE) 
        err_code = 0x5002; 
    if (duty > maxRDUTY) 
        err_code = 0x5003; 
 
    data_write(PWMRCNT, (ledon << 8) | (ledoff)); 
    bit_write(PWMSLOPE, bRSLOPE, LOW); 
    bit_write(PWMSLOPE, slope << 8, HIGH); 
    bit_write(PWMDUTY, bRDUTY, LOW); 
    bit_write(PWMDUTY, duty << 8, HIGH); 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                               Green LED setup 
//----------------------------------------------------------------------------- 
int aDSC_greenled_set(const UINT16 ledon, const UINT16 ledoff, 
                      const UINT16 slope, const UINT16 duty) 
{ 
    int err_code = 0; 
 
    if (ledon > maxGON) 
        err_code = 0x5010; 
    if (ledoff > maxGOFF) 
        err_code = 0x5011; 
    if (slope > maxGSLOPE) 
        err_code = 0x5012; 
    if (duty > maxGDUTY) 
        err_code = 0x5013; 
 
    data_write(PWMGCNT, (ledon << 8) | (ledoff)); 
    bit_write(PWMSLOPE, bGSLOPE, LOW); 
    bit_write(PWMSLOPE, slope << 4, HIGH); 
    bit_write(PWMDUTY, bGDUTY, LOW); 
    bit_write(PWMDUTY, duty << 4, HIGH); 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                                Blue LED setup 
//----------------------------------------------------------------------------- 
int aDSC_blueled_set(const UINT16 ledon, const UINT16 ledoff, 
                     const UINT16 slope, const UINT16 duty) 
{ 
    int err_code = 0; 
 
    if (ledon > maxGON) 
        err_code = 0x5020; 
    if (ledoff > maxGOFF) 
        err_code = 0x5021; 
    if (slope > maxGSLOPE) 
        err_code = 0x5022; 
    if (duty > maxGDUTY) 
        err_code = 0x5023; 
 
    data_write(PWMBCNT, (ledon << 8) | (ledoff)); 
    bit_write(PWMSLOPE, bBSLOPE, LOW); 
    bit_write(PWMSLOPE, slope, HIGH); 
    bit_write(PWMDUTY, bBDUTY, LOW); 
    bit_write(PWMDUTY, duty, HIGH); 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                           3 color LED on/off  
//----------------------------------------------------------------------------- 
int aDSC_3cled_on_off(const UINT16 rsw, const UINT16 gsw, const UINT16 bsw, 
                      const UINT16 pwmclk, const UINT16 mode) 
{ 
    UINT16 hwmode; 
    int err_code = 0; 
 
    if (pwmclk > maxPWMCLK) 
        err_code = 0x5030; 
 
    hwmode = hwmode_read(); 
    gl_dsc_status = sLEDMODE; 
    aDSC_Quit_Preview(); 
    gl_dsc_status = mode; 
 
    if (rsw == sRSW_OFF && gsw == sGSW_OFF && bsw == sBSW_OFF) 
    {                           //LED OFF 
        if (bit_read(PWMCNT1, bPWMWHT_EN)) 
        {                       //WHITE LED ON 
            bit_write(PWMCNT1, bPWM3C_EN, LOW); 
        } 
        else 
        {                       //ALL LED OFF 
            bit_write(PWMCNT1, bPWM_EN | bPWM3C_EN, LOW);       //PWM OFF 
        } 
    } 
    else 
    { 
        bit_write(PWMCNT1, bPWM_EN | bPWM3C_EN, HIGH); 
    } 
    data_write(PWMCNT2, mode | (pwmclk << 4) | rsw | gsw | bsw); 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                            White LED on/off   
//----------------------------------------------------------------------------- 
int aDSC_whiteled_on_off(const UINT16 pwmwht_en, const UINT16 pwmwht_peri, 
                         const UINT16 pwmwht_duty) 
{ 
    UINT16 mode; 
    int err_code = 0; 
 
    if (pwmwht_peri > maxPWMWHT_PERI) 
        err_code = 0x5040; 
    if (pwmwht_duty > maxPWMWHT_DUTY) 
        err_code = 0x5041; 
 
    mode = hwmode_read(); 
    gl_dsc_status = sLEDMODE; 
    aDSC_Quit_Preview(); 
    gl_dsc_status = mode; 
 
    if (pwmwht_en == sPWMWHT_DISABLE) 
    {                           //WHITE LED OFF 
        if (bit_read(PWMCNT1, bPWM3C_EN)) 
        {                       //3C LED ON 
            bit_write(PWMCNT1, bPWMWHT_EN, LOW); 
        } 
        else 
        {                       //ALL LED OFF 
            bit_write(PWMCNT1, bPWM_EN | bPWMWHT_EN, LOW);      //PWM OFF 
        } 
    } 
    else 
    { 
        bit_write(PWMCNT1, bPWM_EN | bPWMWHT_EN, HIGH); 
    } 
 
    data_write(PWMWCNT, (pwmwht_peri << 8) | pwmwht_duty); 
 
    if (err_code) 
        DEBUG_WRITE((0, 0, "%x", err_code)); 
    return (err_code); 
} 
 
void aDSC_GIO_Write(UINT8 u8GioIndex, UINT8 u8Bit) 
{ 
    bit_write(GIOCNT, 0x1< u32BufMaxSize) 
                { 
                    err_code = 0x02; 
                    goto ENC_END; 
                } 
 
                read_code(&start_add, count / 2); 
 
#if BUSACCESS_BIT == 8 && ENDIAN == sLITTLE_END 
                reg_data = hostcnt_bitread(0xffff); 
                reg_data = ((reg_data & 0xff00) >> 8) | ((reg_data & 0x00ff) << 8); 
                hostcnt_write(reg_data & (UINT16) (~(bHOST_END))); 
#endif 
 
                if (gl_bank_chk == 0 && gl_je_end_chk == 1) 
                { 
                    je_size += BANK_SIZE * bank_count; 
                    if (je_size > *jpeg_size) 
                    { 
                        err_code = 0x02; 
                        goto ENC_END; 
                    } 
                    *jpeg_size = je_size; 
                    break; 
                } 
                else 
                { 
                    gl_bank_chk--; 
                    bank_count++; 
                    if (gl_bank_chk >= BANK_NUM) 
                    { 
                        err_code = 0x03; 
                        goto ENC_END; 
                    } 
                } 
            } 
 #if defined BUXX_POLLING 
{ 
            UINT16 u16IntStatus=0; 
            while ((u16IntStatus = data_read(JPG_INTST)) == 0); 
            if (u16IntStatus & bJE_RING_INT) 
            {                       // JE_RING_INT 
                bit_write(JPG_INTST, bJE_RING_INT, LOW);      // JE_RING_INT clear 
                gl_bank_chk++; 
            } 
            if (u16IntStatus & bJE_ED_INT) 
            { 
                bit_write(JPG_INTST, bJE_ED_INT, LOW);                // JE_ED_INT clear 
                gl_je_end_chk++; 
            } 
} 
 #endif 
        } 
    } 
    else 
    { 
    	int dummy_mode = gl_dsc_status; 
	gl_dsc_status = sLEDMODE;   // Dummy set 
	 
	gl_check_int = 0; 
	data_write(JPG_INTST, 0x0000);      //Interrupt status clear 
	data_write(JPG_INTMSK, 0x0006);   //bJE_ED_MSK disable  
 
   	bit_write(JPG_CNT, bJE_ST, HIGH);   // JPEG encode start 
   	wait(1); 
 
#if defined BUXX_POLLING 
	reg_write(INDEX, JPG_INTST); 
	while (reg_read(REG) == 0); 
#else 
	while (gl_check_int == 0); 
#endif 
	data_write(JPG_INTMSK, 0xffff);     //mask all JPEG int  
 
	gl_dsc_status = dummy_mode; 
        while (data_read(JPG_ST1)); 
 
#if defined sCAMERAJPEG 
        if (entype == sCAMERAJPEG) 
        { 
            if (data_read(JPG_ST2)) 
            { 
                err_code = 0x01; 
                goto ENC_END; 
            } 
        } 
#endif 
 
        je_size = read_je_size() * 2; 
	 mode_change(sREADY); //William add for BU1563 fm-encode failed 20050508 
	  
        if (je_size > *jpeg_size) 
        { 
            err_code = 0x02; 
            goto ENC_END; 
        } 
	 
        mem_adr_abs_set(0x00000000); 
 
#if BUSACCESS_BIT == 8 && ENDIAN == sLITTLE_END 
        hostcnt_bitwrite(bHOST_END, HIGH); 
#endif 
 
        mem_acs_read_st(MEMACS_ABS); 
        for (i = 0; i < je_size / 2; i++) 
        { 
            *start_add = reg_read(REG); 
            start_add++; 
        } 
 
#if BUSACCESS_BIT == 8 && ENDIAN == sLITTLE_END 
        reg_data = hostcnt_bitread(0xffff); //fix for compile 20050509 
        reg_data = ((reg_data & 0xff00) >> 8) | ((reg_data & 0x00ff) << 8); 
        hostcnt_write(reg_data & (UINT16) (~(bHOST_END)));      //rectangle increment、auto increment on         
#endif 
 
        *jpeg_size = je_size; 
    } 
 
//William add for fail-safe begin 
	if(*(UINT16*)(start_add-1)==0x0000)  
	{ 
	    (*jpeg_size)-=2; 
	} 
 
	if(*(p_u16StartAddr+(*jpeg_size)/2-1) 
#if ENDIAN == sLITTLE_END 
		!=0xd9ff 
#else 
		!=0xffd9 
#endif 
	)	 
	    err_code = 0x04; 
//William add for fail-safe end 
 
  ENC_END: 
#if BUSACCESS_BIT == 16 && ENDIAN == sLITTLE_END 
    bit_write(MEMCNT, bSWAP_BYTE, LOW); 
#endif 
    bit_write(MEMCNT, bADRINC, LOW); 
    mode_change(sREADY); 
    return err_code; 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                              JPEG Decode dispose 
//----------------------------------------------------------------------------- 
static int jpeg_HostDec(UINT8 * start_add, UINT32 * const jpeg_size, UINT16* p_u16Rgb_addr, 
                       const CAMSET * const cam) 
{ 
 
    JPEG_INFO jpeg_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 
    static QTABLE q_c; 
    static QTABLE q_y; 
    UINT32 code_offset; 
    UINT16 reg_camif, reg_camtim, reg_cxsize, reg_cysize; 
    UINT16 u16ClkCntReg=0,u16MemCntReg=0; 
    UINT32 u32CurRgbSize=0; 
    int err_code = 0; 
 
    jpeg_info.q_y = &q_y; 
    jpeg_info.q_c = &q_c; 
 
    jpeg_info.code = start_add; 
 
    bit_write(MEMCNT, bADRINC, HIGH); 
 
    bit_write(JPG_CNT, bSWRST | bRING_A_RST, HIGH);     // Reset JPEG core 
    wait(1);                    // wait 1ms 
    bit_write(JPG_CNT, bSWRST | bRING_A_RST, LOW);      // Clear Reset 
 
    mode_change(sREADY);        //READY MODE 
    u16ClkCntReg=data_write(CLKCNT, sVD|bVD_EN|bSCKEN|0x0000); 
    u16MemCntReg=data_write(MEMCNT, bADRINC|0x0000); 
 
    err_code = analyze_header(start_add, jpeg_size, &jpeg_info); 
    if (err_code)  return err_code; 
 
    reg_camif = data_write(CAMIF, 0x0700);      //cam I/F normal、camvs/camhs LOW sink、YUV(4:2:2)、UYVYUYVY 
    reg_camtim = data_write(CAMTIM, 0x0000);    //A cam I/F frame start pixel position is set up 
 
    reg_cxsize = data_read(CXSIZE);     // Xsize 
    reg_cysize = data_read(CYSIZE);     // Ysize 
    cam_size_set(jpeg_info.X, jpeg_info.Y); 
     
    if (cam->cst_x + cam->xsize > jpeg_info.X ) 
        err_code = 0x0110; 
    if (cam->cst_y + cam->ysize > jpeg_info.Y ) 
        err_code = 0x0111; 
 
    *p_u16Rgb_addr++=jpeg_info.X; 
    *p_u16Rgb_addr++=jpeg_info.Y ; 
 
    err_code = cam_capture_set(cam); 
    if (err_code) 
    { 
        err_code |= 0x0100; 
        goto DEC_END; 
    } 
 
    set_jpeg_setting(jpeg_info.X, jpeg_info.Y, jpeg_info.interval, 
                     jpeg_info.type); 
 
    mode_change(sHOSTJPEGDEC); 
 
    set_huf_table(jpeg_info.h_y_dc, jpeg_info.h_y_ac, jpeg_info.h_c_dc, 
                  jpeg_info.h_c_ac); 
    set_q_table(jpeg_info.q_y, jpeg_info.q_c); 
 
    gl_cam_end_chk=0; 
    data_write(INTMSK, (UINT16)(~bCAMED_MSK));   //cam_ed_int enable 
    bit_write(INTMSK, bCAMED_INT, LOW);  // clear int 
 
    jpeg_info.code_size=5120; //test 20050519 
    for (code_offset = 0; code_offset < jpeg_info.code_size; 
         code_offset += 5120) 
    { 
        set_code(jpeg_info.code, code_offset, BU1554_MIN(code_offset + 5120, jpeg_info.code_size));    // (re)start decode 
        err_code=JpegIntDisp((UINT16*)p_u16Rgb_addr, &u32CurRgbSize, jpeg_info.X*jpeg_info.Y); 
        wait(10); 
        if (err_code) 
        { 
            err_code |= 0x0300; 
            goto DEC_END; 
        } 
        p_u16Rgb_addr+=u32CurRgbSize; 
        err_code = bit_read(JPG_ST2, bJD_ERROR); 
        if (err_code) 
        { 
            err_code |= 0x0200; 
            goto DEC_END; 
        } 
    } 
/* //test 20050519 
    if(gl_cam_end_chk == 0) 
    { 
        CheckJpegInt(); 
    } 
*/ 
    reg_write(INDEX, RING_RD_RGB); 
//    read_code(&p_u16Rgb_addr, (jpeg_info.X*jpeg_info.Y)%0x2000);  //test 20050519 
{ //test 20050519 
    UINT16 reg_data; 
    reg_data = reg_read(REG); 
    reg_data = reg_read(REG); 
    read_code(&p_u16Rgb_addr, 0x6000);  
} 
#ifdef HOSTJD_TEST         
    gl_intdisp_sequence[gl_intdisp_index]=3; 
    gl_intdisp_index++; 
#endif 
    gl_cam_end_chk=0; 
    data_write(INTMSK, 0xffff);   //cam_ed_int disable 
    bit_write(INTMSK, bCAMED_INT, LOW);  // clear int 
 
  DEC_END: 
    data_write(CAMIF, reg_camif);       //cam I/F normal、camvs/camhs LOW sink、YUV(4:2:2)、UYVYUYVY 
    data_write(CAMTIM, reg_camtim);     //A cam I/F frame start pixel position is set up 
    data_write(CXSIZE, reg_cxsize);     // Xsize 
    data_write(CYSIZE, reg_cysize);     // Ysize 
    data_write(CLKCNT, u16ClkCntReg); 
    data_write(MEMCNT,u16MemCntReg); 
    mode_change(sREADY); 
    bit_write(MEMCNT, bADRINC, LOW); 
 
    return err_code; 
 
} 
 
static int jpeg_decode(UINT8 * start_add, UINT32 * const jpeg_size, 
                       const CAMSET * const cam) 
{ 
 
    JPEG_INFO jpeg_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 
    static QTABLE q_c; 
    static QTABLE q_y; 
    UINT32 code_offset; 
    UINT16 reg_camif, reg_camtim, reg_cxsize, reg_cysize; 
    int err_code = 0; 
 
    jpeg_info.q_y = &q_y; 
    jpeg_info.q_c = &q_c; 
 
    jpeg_info.code = start_add; 
 
    bit_write(MEMCNT, bADRINC, HIGH); 
 
    bit_write(JPG_CNT, bSWRST | bRING_A_RST, HIGH);     // Reset JPEG core 
    wait(1);                    // wait 1ms 
    bit_write(JPG_CNT, bSWRST | bRING_A_RST, LOW);      // Clear Reset 
 
    mode_change(sREADY);        //READY MODE 
    mode_change(sJPEGDECODE); 
 
    err_code = analyze_header(start_add, jpeg_size, &jpeg_info); 
    if (err_code)  return err_code; 
 
    //////////////////////////////////////////////////////////// 
    // jpeg decode camera parameter setting 
    // 
    reg_camif = data_write(CAMIF, 0x0700);      //cam I/F normal、camvs/camhs LOW sink、YUV(4:2:2)、UYVYUYVY 
    reg_camtim = data_write(CAMTIM, 0x0000);    //A cam I/F frame start pixel position is set up 
 
    reg_cxsize = data_read(CXSIZE);     // Xsize 
    reg_cysize = data_read(CYSIZE);     // Ysize 
    cam_size_set(jpeg_info.X, jpeg_info.Y); 
 
    if (cam->cst_x + cam->xsize > jpeg_info.X / cam->srkx) 
        err_code = 0x0110; 
    if (cam->cst_y + cam->ysize > jpeg_info.Y / cam->srky) 
        err_code = 0x0111; 
 
    err_code = cam_capture_set(cam); 
    if (err_code) 
    { 
        err_code |= 0x0100; 
        goto DEC_END; 
    } 
 
    //////////////////////////////////////////////////////////// 
    // jpeg decode parameter setting 
    // 
 
    set_jpeg_setting(jpeg_info.X, jpeg_info.Y, jpeg_info.interval, 
                     jpeg_info.type); 
 
    //////////////////////////////////////////////////////////// 
    // Write Huffman table[L] 
    // 
 
    set_huf_table(jpeg_info.h_y_dc, jpeg_info.h_y_ac, jpeg_info.h_c_dc, 
                  jpeg_info.h_c_ac); 
 
 
    //////////////////////////////////////////////////////////// 
    // Write Q table 
 
    set_q_table(jpeg_info.q_y, jpeg_info.q_c); 
 
 
    ///////////////////////////////////////////////// 
    // Write jpeg code 
 
    // 
    // Main Loop 
    // 
 
 
    for (code_offset = 0; code_offset < jpeg_info.code_size; 
         code_offset += 5120) 
    { 
        set_code(jpeg_info.code, code_offset, BU1554_MIN(code_offset + 5120, jpeg_info.code_size));    // (re)start decode 
        bit_write(JPG_CNT, bJD_ST, HIGH); 
        wait_int0_jpeg(bJD_ED_MSK);     // wait JD_ED interrupt 
        err_code = bit_read(JPG_ST2, bJD_ERROR); 
        if (err_code) 
        { 
            err_code |= 0x0200; 
            goto DEC_END; 
        } 
    } 
 
 
    // if JD_STAT is 1, then restart decode 
    if (bit_read(JPG_ST1, bJD_STAT)) 
    { 
        bit_write(JPG_CNT, bJD_ST, HIGH);       // (re)start decode 
        wait_int0_jpeg(bJD_ED_MSK);     // wait JD_ED interrupt 
        err_code = bit_read(JPG_ST2, bJD_ERROR); 
        if (err_code) 
        { 
            err_code |= 0x0200; 
            goto DEC_END; 
        } 
    } 
 
 
 
  DEC_END: 
    data_write(CAMIF, reg_camif);       //cam I/F normal、camvs/camhs LOW sink、YUV(4:2:2)、UYVYUYVY 
    data_write(CAMTIM, reg_camtim);     //A cam I/F frame start pixel position is set up 
    data_write(CXSIZE, reg_cxsize);     // Xsize 
    data_write(CYSIZE, reg_cysize);     // Ysize 
    mode_change(sREADY); 
    bit_write(MEMCNT, bADRINC, LOW); 
 
    return err_code; 
 
} 
 
static void CheckJpegInt(void) 
{ 
#if defined BUXX_POLLING 
    UINT16 u16JpgIntStatus=0,u16IntStatus=0; 
    UINT16 idx_push = reg_read(INDEX); 
    while (u16JpgIntStatus == 0 && u16IntStatus==0) 
    { 
        u16JpgIntStatus=(data_read(JPG_INTST) & 0x0007); 
        u16IntStatus=(data_read(INTST) & 0x0004); 
    } 
    if (u16JpgIntStatus & bJE_RING_INT) 
    {                       // JE_RING_INT 
        bit_write(JPG_INTST, bJE_RING_INT, LOW);      //RING_INT clear 
        gl_bank_chk++; 
#ifdef HOSTJD_TEST         
        gl_intcheck_sequence[gl_intcheck_index]=1; 
        gl_intcheck_index++; 
#endif 
    } 
    if (u16JpgIntStatus & bJD_ED_INT) 
    { 
        bit_write(JPG_INTST, bJD_ED_INT, LOW);                // JE_ED_INT clear 
        gl_jd_end_chk++; 
#ifdef HOSTJD_TEST         
        gl_intcheck_sequence[gl_intcheck_index]=2; 
        gl_intcheck_index++; 
#endif 
    } 
    if(u16IntStatus & bCAMED_INT) 
    { 
        bit_write(INTST, bCAMED_INT, LOW);                // CAM_ED_INT clear 
        gl_cam_end_chk++; 
#ifdef HOSTJD_TEST         
        gl_intcheck_sequence[gl_intcheck_index]=3; 
        gl_intcheck_index++; 
#endif 
    } 
    reg_write(INDEX,idx_push); 
#else 
    while (gl_bank_chk == 0 && gl_jd_end_chk == 0 /*&& gl_cam_end_chk==0*/); 
#endif 
 
} 
 
static int JpegIntDisp(UINT16* u16Rgb_addr, UINT32* p_u32CurRgbSize, UINT32 u32TotalRgbSize) 
{    
    UINT32 count=0,i; 
    UINT16 bank_count=0; 
    UINT16 reg_data=0; 
//    static UINT16 u16BankMaxNumber=0; 
    gl_bank_chk = 0; 
    gl_jd_end_chk = 0; 
     
    data_write(JPG_INTMSK, (UINT16)(~(bJD_ED_MSK|bJE_RING_MSK)));   //jped_int enable 
    bit_write(JPG_INTMSK, bJE_RING_INT | bJD_ED_INT, LOW);  // clear int 
 
    bit_write(JPG_CNT, bJD_ST, HIGH); 
    for(i=0;i<10;i++); 
     
    while (1) 
    { 
        CheckJpegInt(); //check RING_INT and JD_ED_INT 
 
        if (gl_bank_chk != 0 || (gl_bank_chk == 0 && gl_jd_end_chk == 1))  
        { 
            if (gl_bank_chk != 0)  //RING_INT appear 
            { 
#ifdef HOSTJD_TEST         
                gl_intdisp_sequence[gl_intdisp_index]=1; 
                gl_intdisp_index++; 
#endif 
                count = BANK_SIZE; 
                if(*p_u32CurRgbSize==0) //first time RGB read should include twice dummy read  
                { 
                    bit_write(MEMCNT, bRGB_FRAME, HIGH); 
                    reg_write(INDEX, RING_RD_RGB); 
                    reg_data=reg_read(REG); 
                    reg_data=reg_read(REG); 
                } 
                else 
                { 
                    reg_write(INDEX, RING_RD_RGB); 
                } 
#if BUSACCESS_BIT == 8 && ENDIAN == sLITTLE_END 
                hostcnt_bitwrite(bHOST_END, HIGH); 
                reg_write(INDEX, RING_RD_RGB); 
#endif 
                read_code(&u16Rgb_addr, count / 2); 
 
#if BUSACCESS_BIT == 8 && ENDIAN == sLITTLE_END 
                reg_data = hostcnt_bitread(0xffff); 
                reg_data = ((reg_data & 0xff00) >> 8) | ((reg_data & 0x00ff) << 8); 
                hostcnt_write(reg_data & (UINT16) (~(bHOST_END)));      //rectangle increment、auto increment on         
#endif 
                gl_bank_chk--; 
                bank_count++; 
                if (gl_bank_chk >= BANK_NUM)   return 0x03; 
            } 
 
            if (gl_bank_chk == 0 && gl_jd_end_chk == 1)  //JD_ED_INT appear 
            { 
#ifdef HOSTJD_TEST         
                gl_intdisp_sequence[gl_intdisp_index]=2; 
                gl_intdisp_index++; 
#endif 
                gl_jd_end_chk--; 
                *p_u32CurRgbSize = BANK_SIZE * bank_count/2; //word unit 
//                u16BankMaxNumber+=bank_count; 
                break; 
            } 
        } 
    } 
 
    data_write(JPG_INTMSK, 0xffff);   //lcded_int disable 
    bit_write(JPG_INTMSK, bJE_RING_INT | bJD_ED_INT, LOW);  // clear int 
 
    return 0; 
} 
 
//----------------------------------------------------------------------------- 
//                           JPEG Header analyze         
//----------------------------------------------------------------------------- 
static int analyze_header(UINT8 * const jpeg, UINT32 * const jpeg_size, 
                          JPEG_INFO * const jpeg_info) 
{ 
    UINT32 pos; 
    UINT16 size; 
    UINT8 flag; 
    UINT32 htbl_pos[4] = { 0, 0, 0, 0 }; 
    UINT32 qtbl_pos[4] = { 0, 0, 0, 0 }; 
    UINT8 c[3] = { 0, 0, 0 }; 
    UINT8 hv[3] = { 0, 0, 0 }; 
    UINT8 tq[3] = { 0, 0, 0 }; 
    UINT8 cs[3] = { 0, 0, 0 }; 
    UINT8 tdta[3] = { 0, 0, 0 }; 
    UINT8 nf = 0, ns = 0; 
    int j, k, l, eoi_chk = 0; 
    struct 
    { 
        int sof; 
        int dht; 
        int sos; 
        int dqt; 
        int dri; 
    } 
    HEADER_chk = 
    { 
    0, 0, 0, 0, 0}; 
 
 
    for (pos = 0; pos < *jpeg_size; pos++) 
    { 
        switch (CHAR_SHORT(((JPEG_data *) (jpeg + pos))->regread)) 
        { 
        case 0xffc0:           //SOF                            
            if (HEADER_chk.sof >= 1) 
                return 0x0001; 
            HEADER_chk.sof++; 
            size = CHAR_SHORT(((SOF_data *) (jpeg + pos + 2))->Lf); 
 
            jpeg_info->X = CHAR_SHORT(((SOF_data *) (jpeg + pos + 2))->X); 
            jpeg_info->Y = CHAR_SHORT(((SOF_data *) (jpeg + pos + 2))->Y); 
            nf = ((SOF_data *) (jpeg + pos + 2))->Nf; 
            if (nf != 1 && nf != 3) 
                return 0x0002; 
 
            for (j = 0; j < nf; j++) 
            { 
                c[j] = ((SOF_data *) (jpeg + pos + 2))->CHVT[j][0]; 
                hv[j] = ((SOF_data *) (jpeg + pos + 2))->CHVT[j][1]; 
                tq[j] = ((SOF_data *) (jpeg + pos + 2))->CHVT[j][2]; 
            } 
            if (size != (8 + nf * 3)) 
                return 0x0003; 
            pos += size + 1; 
            break; 
        case 0xffc1: 
        case 0xffc2: 
        case 0xffc3: 
        case 0xffc5: 
        case 0xffc6: 
        case 0xffc7: 
        case 0xffc9: 
        case 0xffca: 
        case 0xffcb: 
        case 0xffcd: 
        case 0xffce: 
        case 0xffcf: 
            return 0x0004; 
            break; 
        case 0xffc4:           //DHT 
            if (HEADER_chk.dht >= 4) 
                return 0x0006; 
            HEADER_chk.dht++; 
            size = CHAR_SHORT(((DHT_data *) (jpeg + pos + 2))->Lh); 
 
            flag = ((DHT_data *) (jpeg + pos + 2))->TcTh; 
            flag = 
                (flag & 0xe0) | ((flag & 0x10) >> 3) | ((flag & 0x0e) << 1) 
                | (flag & 0x01); 
            if (flag > 3) 
                return 0x0007; 
            htbl_pos[flag] = pos + 5; 
            for (j = 0, l = 0; j < 16; j++) 
            { 
                l += ((DHT_data *) (jpeg + pos + 2))->Ln[j]; 
            } 
            if (size != (19 + l)) 
                return 0x0008; 
            pos += size + 1; 
            break; 
        case 0xffda:           //SOS 
            if (HEADER_chk.sos >= 1) 
                return 0x000b; 
            HEADER_chk.sos++; 
            size = CHAR_SHORT(((SOS_data *) (jpeg + pos + 2))->Ls); 
            ns = ((SOS_data *) (jpeg + pos + 2))->Ns; 
            if (ns != nf) 
                return 0x000c; 
            for (j = 0; j < nf; j++) 
            { 
                for (k = 0; k < nf; k++) 
                { 
                    if (((SOS_data *) (jpeg + pos + 2))->CTT[j][0] == c[k]) 
                    {           //Cs 
                        cs[j] = k; 
                    } 
                } 
                flag = ((SOS_data *) (jpeg + pos + 2))->CTT[j][1]; 
                flag = 
                    (flag & 0xe0) | ((flag & 0x10) >> 3) | ((flag & 0x0e) 
                                                            << 1) | (flag & 
                                                                     0x01); 
                if (flag > 3) 
                    return 0x000d; 
                tdta[j] = flag; 
            } 
 
            if (jpeg[pos + 5 + ns * 2] != 0 || jpeg[pos + 6 + ns * 2] != 63 
                || jpeg[pos + 7 + ns * 2] != 0) 
                return 0x000e; 
 
            jpeg_info->code = jpeg + pos + 2 + size; 
            pos += size + 1; 
            break; 
 
        case 0xffdb:           //DQT 
            if (HEADER_chk.dqt >= 2) 
                return 0x0010; 
            HEADER_chk.dqt++; 
            size = CHAR_SHORT(((DQT_data *) (jpeg + pos + 2))->Lq); 
 
            flag = ((DQT_data *) (jpeg + pos + 2))->PqTq;       // PqTq 
            if (flag > 3) 
                return 0x0020; 
            qtbl_pos[flag] = pos + 5; 
 
            if (size != (2 + 65)) 
                return 0x0030; 
            pos += size + 1; 
            break; 
        case 0xffdd:           //DRI 
            if (HEADER_chk.dri >= 1) 
                return 0x0060; 
            HEADER_chk.dri++; 
            size = CHAR_SHORT(((DRI_data *) (jpeg + pos + 2))->Lr); 
 
            jpeg_info->interval = 
                CHAR_SHORT(((DRI_data *) (jpeg + pos + 2))->Ri); 
            if (size != 4) 
                return 0x0070; 
            pos += size + 1; 
            break; 
        case 0xffd9:           //EOI 
            pos += 2; 
            jpeg_info->code_size = 
                (UINT32) ((jpeg + pos) - (jpeg_info->code)); 
            eoi_chk = 1; 
            break; 
        default: 
 
            break; 
        } 
        if (eoi_chk == 1) 
            break; 
    } 
 
//      if (pos != jpeg_size) return 0x00f0; 
    if (pos != *jpeg_size) 
        *jpeg_size = pos; 
    if (HEADER_chk.sof != 1) 
        return 0x0001; 
    if (HEADER_chk.dht != 4) 
        return 0x0006; 
    if (HEADER_chk.sos != 1) 
        return 0x000b; 
    if (HEADER_chk.dqt != 2) 
        return 0x0010; 
 
 
    // 
    // Check Header 
    // 
 
    if (nf == 3) 
    { 
        if (hv[cs[0]] == 0x11 && hv[cs[1]] == 0x11 && hv[cs[2]] == 0x11) 
        {                       // 444 
            jpeg_info->type = 0x0000; 
        } 
        else if (hv[cs[0]] == 0x21 && hv[cs[1]] == 0x11 
                 && hv[cs[2]] == 0x11) 
        {                       // 422 
            jpeg_info->type = 0x0001; 
        } 
        else if (hv[cs[0]] == 0x41 && hv[cs[1]] == 0x11 
                 && hv[cs[2]] == 0x11) 
        {                       // 411 
            jpeg_info->type = 0x0002; 
        } 
        else if (hv[cs[0]] == 0x22 && hv[cs[1]] == 0x11 
                 && hv[cs[2]] == 0x11) 
        {                       // 420 
            jpeg_info->type = 0x0003; 
        } 
        else 
        { 
            return 0x0005; 
        } 
    } 
    else if (nf == 1) 
    { 
        jpeg_info->type = 0x0004; 
    } 
    else 
    { 
        return 0x0005; 
    } 
 
    if (nf == 3 && (tdta[1] != tdta[2] || tdta[1] != tdta[2])) 
        return 0x0009; 
    jpeg_info->h_y_dc = (HTABLE *) & jpeg[htbl_pos[tdta[0] >> 1]]; 
    jpeg_info->h_y_ac = (HTABLE *) & jpeg[htbl_pos[2 + (tdta[0] & 1)]]; 
    if (nf == 3) 
    { 
        jpeg_info->h_c_dc = (HTABLE *) & jpeg[htbl_pos[tdta[1] >> 1]]; 
        jpeg_info->h_c_ac = (HTABLE *) & jpeg[htbl_pos[2 + (tdta[1] & 1)]]; 
    } 
 
    if (nf == 3 && tq[cs[1]] != tq[cs[2]]) 
        return 0x0040; 
    for (j = 0; j < 64; j++) 
    { 
        jpeg_info->q_y->table[zigzag[j] / 8][zigzag[j] % 8] = 
            jpeg[qtbl_pos[tq[cs[0]]] + j]; 
        if (nf == 3) 
        { 
            jpeg_info->q_c->table[zigzag[j] / 8][zigzag[j] % 8] = 
                jpeg[qtbl_pos[tq[cs[1]]] + j]; 
        } 
    } 
 
    return 0; 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                           JPEG register setup         
//----------------------------------------------------------------------------- 
static void set_jpeg_setting(const UINT16 X, const UINT16 Y, 
                             const UINT16 interval, const UINT8 type) 
{ 
    data_write(JD_PICTYPE, type); 
    data_write(JD_INTERVAL, interval); 
    data_write(JD_XSIZE, X); 
    data_write(JD_YSIZE, Y); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                         HUffman table setup   
//----------------------------------------------------------------------------- 
static void set_huf_table(const HTABLE * const y_dc, 
                          const HTABLE * const y_ac, 
                          const HTABLE * const c_dc, 
                          const HTABLE * const c_ac) 
{ 
 
    UINT8 val_size_y_dc = 0; 
    UINT8 val_size_y_ac = 0; 
    UINT8 val_size_c_dc = 0; 
    UINT8 val_size_c_ac = 0; 
    int i; 
 
    // 
    // Set Register jd_huf_* 
    // and count 
    // 
 
    reg_write(INDEX, JD_HUF_Y_DC1); 
    for (i = 0; i < 16; i++) 
    { 
        reg_write(REG, y_dc->cod[i]); 
        val_size_y_dc += y_dc->cod[i]; 
    } 
 
    reg_write(INDEX, JD_HUF_Y_AC1); 
    for (i = 0; i < 16; i++) 
    { 
        reg_write(REG, y_ac->cod[i]); 
        val_size_y_ac += y_ac->cod[i]; 
    } 
 
    reg_write(INDEX, JD_HUF_C_DC1); 
    for (i = 0; i < 16; i++) 
    { 
        reg_write(REG, c_dc->cod[i]); 
        val_size_c_dc += c_dc->cod[i]; 
    } 
 
    reg_write(INDEX, JD_HUF_C_AC1); 
    for (i = 0; i < 16; i++) 
    { 
        reg_write(REG, c_ac->cod[i]); 
        val_size_c_ac += c_ac->cod[i]; 
    } 
 
    // 
    // Set Memory to huffman table value 
    // 
 
    mem_adr_abs_set(sHUFTABLE_ADDRESS); 
    mem_acs_write_st(MEMACS_ABS); 
 
    for (i = 0; i < val_size_y_dc; i++) 
    { 
        reg_write(REG, y_dc->val[i]); 
    } 
    for (; i < 256; i++) 
    {                           // padding 
        reg_write(REG, 0); 
    } 
 
 
    for (i = 0; i < val_size_c_dc; i++) 
    { 
        reg_write(REG, c_dc->val[i]); 
    } 
    for (; i < 256; i++) 
    {                           // padding 
        reg_write(REG, 0); 
    } 
 
    for (i = 0; i < val_size_y_ac; i++) 
    { 
        reg_write(REG, y_ac->val[i]); 
    } 
    for (; i < 256; i++) 
    {                           // padding 
        reg_write(REG, 0); 
    } 
 
 
    for (i = 0; i < val_size_c_ac; i++) 
    { 
        reg_write(REG, c_ac->val[i]); 
    } 
    for (; i < 256; i++) 
    {                           // padding 
        reg_write(REG, 0); 
    } 
 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                              Q table setup    
//----------------------------------------------------------------------------- 
static void set_q_table(const QTABLE * const q_y, const QTABLE * const q_c) 
{ 
    mem_adr_abs_set(sQTABLE_ADDRESS); 
    mem_acs_write_st(MEMACS_ABS); 
 
    set_each_q_table(q_y); 
 
    set_each_q_table(q_c); 
} 
 
 
 
//----------------------------------------------------------------------------- 
//                              Q table setup 
//----------------------------------------------------------------------------- 
static void set_each_q_table(const QTABLE * const qtbl) 
{ 
    UINT32 data1; 
    UINT32 data2; 
    UINT32 data3; 
    UINT32 data4; 
    int shift1, shift2; 
    int x, i; 
 
    for (x = 0; x < 8; x++) 
    { 
        for (i = 0; i < 4; i++) 
        { 
            switch (i) 
            { 
            case 0: 
                data1 = ctable[4] * (qtbl->table[0][x]); 
                data2 = ctable[4] * (qtbl->table[4][x]); 
                data3 = ctable[4] * (qtbl->table[0][x]); 
                data4 = ctable[4] * (qtbl->table[4][x]); 
                break; 
            case 1: 
                data1 = ctable[1] * (qtbl->table[1][x]); 
                data2 = ctable[7] * (qtbl->table[7][x]); 
                data3 = ctable[7] * (qtbl->table[1][x]); 
                data4 = ctable[1] * (qtbl->table[7][x]); 
                break; 
            case 2: 
                data1 = ctable[2] * (qtbl->table[2][x]); 
                data2 = ctable[6] * (qtbl->table[6][x]); 
                data3 = ctable[6] * (qtbl->table[2][x]); 
                data4 = ctable[2] * (qtbl->table[6][x]); 
                break; 
            case 3: 
                data1 = ctable[3] * (qtbl->table[3][x]); 
                data2 = ctable[5] * (qtbl->table[5][x]); 
                data3 = ctable[5] * (qtbl->table[3][x]); 
                data4 = ctable[3] * (qtbl->table[5][x]); 
                break; 
            } 
 
            // ctable < 8192(2^13) and qtable < 256(2^8), so data < 2^21 
            // Now, shift the data to less than 2^12, and set the shift 
 
            shift1 = 0; 
            if (data1 >= 8192 || data3 >= 8192) 
            { 
                // data1 or data3 is larger than 12bit 
                shift1 = 1; 
                data1 >>= 2; 
                data3 >>= 2; 
            } 
            if (data1 >= 8192 || data3 >= 8192) 
            { 
                // Yet, data1 or data3 is larger than 12bit 
                shift1 = 2; 
                data1 >>= 3; 
                data3 >>= 3; 
            } 
            if (data1 >= 8192 || data3 >= 8192) 
            { 
                // Yet, data1 or data3 is larger than 12bit 
                shift1 = 3; 
                data1 >>= 3; 
                data3 >>= 3; 
            } 
            shift2 = 0; 
            if (data2 >= 8192 || data4 >= 8192) 
            { 
                // data2 or data4 is larger than 12bit 
                shift2 = 1; 
                data2 >>= 2; 
                data4 >>= 2; 
            } 
            if (data2 >= 8192 || data4 >= 8192) 
            { 
                // Yet, data2 or data4 is larger than 12bit 
                shift2 = 2; 
                data2 >>= 3; 
                data4 >>= 3; 
            } 
            if (data2 >= 8192 || data4 >= 8192) 
            { 
                // Yet, data2 or data4 is larger than 12bit 
                shift2 = 3; 
                data2 >>= 3; 
                data4 >>= 3; 
            } 
 
            reg_write(REG, data1 | (shift1 << 13)); 
            reg_write(REG, data2 | (shift2 << 13)); 
            reg_write(REG, data3); 
            reg_write(REG, data4); 
        } 
    } 
} 
 
//----------------------------------------------------------------------------- 
//                             JPEG code write 
//----------------------------------------------------------------------------- 
static void set_code(UINT8 * code, const UINT32 start, const UINT32 end) 
{ 
    UINT32 i; 
    UINT16 data; 
 
    mem_adr_abs_set(sJD_ADDRESS); 
    mem_acs_write_st(MEMACS_ABS); 
 
    for (i = start; i < end; i += 2) 
    { 
        data = CHAR_SHORT(((JPEG_data *) (code + i))->regread); 
        reg_write(REG, data); 
    } 
 
    if (end == start + i + 1) 
    { 
        data = CHAR_SHORT(((JPEG_data *) (code + i))->regread); 
        reg_write(REG, data & 0xff00); 
    } 
 
} 
 
//----------------------------------------------------------------------------- 
//                       
//----------------------------------------------------------------------------- 
static void read_code(UINT16 ** start_add, int store_num) 
{ 
    int i; 
    int count; 
    volatile UINT16 *address; 
    UINT16 *sram_add; 
    address = REG_ACCESS; 
    sram_add = *start_add; 
 
    if (store_num % 16) //last spare code less than one bank 
    { 
        count = store_num; 
        for (i = 0; i < count; i++) 
        { 
#if BUSACCESS_BIT == 16 
            *sram_add = *address; 
#elif BUSACCESS_BIT == 8 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
#endif 
            sram_add++; 
        } 
    } 
    else //a whole bank code 
    { 
        count = store_num / 16; 
        for (i = 0; i < count; i++) 
        { 
#if BUSACCESS_BIT == 16 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
            *sram_add = *address; 
            sram_add++; 
#elif BUSACCESS_BIT == 8 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
            *sram_add = (*address & 0x00ff) << 8; 
            *sram_add |= *address & 0x00ff; 
            sram_add++; 
#endif 
        } 
    } 
    *start_add = sram_add; 
}