www.pudn.com > bu1566.rar > BUxx_aDSC.c, change:2006-12-21,size:81665b
/* ************************************************************************ */
/* */
/* 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;
}