📄 sdi.c
字号:
z2 = ((35468 * tmp10)>>16) + z5; /* c2-c6 */
z4 = ((21407 * tmp12)>>14) + z5; /* c2+c6 */
z3 = (tmp11 *46341)>>16; /* c4 */
z11 = tmp7 + z3; /* phase 5 */
z13 = tmp7 - z3;
dataptr[40] = z13 + z2; /* phase 6 */
dataptr[24] = z13 - z2;
dataptr[8] = z11 + z4;
dataptr[56] = z11 - z4;
dataptr++; /* advance pointer to next column */
}
// Quantize/descale the coefficients, and store into output array
for (i = 0; i < 64; i++) {
/* Apply the quantization and scaling factor */
temp = datafloat[i] * fdtbl[i];
/* Round to nearest integer.
Since C does not specify the direction of rounding for negative
quotients, we have to force the dividend positive for portability.
The maximum coefficient size is +-16K (for 12-bit data), so this
code should work for either 16-bit or 32-bit ints.
*/
outdata[i] = (S16) ((S16)(temp + 16384.5) - 16384);
}
}
void process_DU(S8 *ComponentDU,float *fdtbl,S16 *DC,
bitstring *HTDC,bitstring *HTAC)
{
bitstring EOB=HTAC[0x00];
bitstring M16zeroes=HTAC[0xF0];
U8 i;
U8 startpos;
U8 end0pos;
U8 nrzeroes;
U8 nrmarker;
S16 Diff;
fdct_and_quantization(ComponentDU,fdtbl,DU_DCT);
//zigzag reorder
for (i=0;i<=63;i++)
{ DU[zigzag[i]]=DU_DCT[i];}
Diff=DU[0]-*DC;
*DC=DU[0];
//Encode DC
if (Diff==0) writebits(HTDC[0]); //Diff might be 0
else {writebits(HTDC[category[Diff]]);
writebits(bitcode[Diff]);
}
//Encode ACs
for (end0pos=63;(end0pos>0)&&(DU[end0pos]==0);end0pos--) ;
//end0pos = first element in reverse order !=0
if (end0pos==0) {writebits(EOB);return;}
i=1;
while (i<=end0pos)
{
startpos=i;
for (; (DU[i]==0)&&(i<=end0pos);i++) ;
nrzeroes=i-startpos;
if (nrzeroes>=16) {
for (nrmarker=1;nrmarker<=nrzeroes/16;nrmarker++)
{ writebits(M16zeroes);}
nrzeroes=nrzeroes%16;
}
writebits(HTAC[nrzeroes*16+category[DU[i]]]);writebits(bitcode[DU[i]]);
i++;
}
if (end0pos!=63) writebits(EOB);
}
void load_data_units_from_RGB_buffery(U16 xpos,U16 ypos)
{
U8 x,y;
U8 pos=0;
U32 location;
location=ypos*Ximage+xpos;
for (y=0;y<8;y++)
{
YDU[pos]=tupiany[location]-128;
YDU[pos+1]=tupiany[location+1]-128;
YDU[pos+2]=tupiany[location+2]-128;
YDU[pos+3]=tupiany[location+3]-128;
YDU[pos+4]=tupiany[location+4]-128;
YDU[pos+5]=tupiany[location+5]-128;
YDU[pos+6]=tupiany[location+6]-128;
YDU[pos+7]=tupiany[location+7]-128;
pos+=8;
location+=Ximage;
}
}
void load_data_units_from_RGB_bufferu(U16 xpos,U16 ypos)
{
U8 x,y;
U8 pos=0;
U32 location;
location=ypos*(Ximage/2)+xpos;
for (y=0;y<8;y++)
{
CbDU[pos]=tupianu[location]-128;
CbDU[pos+1]=tupianu[location+1]-128;
CbDU[pos+2]=tupianu[location+2]-128;
CbDU[pos+3]=tupianu[location+3]-128;
CbDU[pos+4]=tupianu[location+4]-128;
CbDU[pos+5]=tupianu[location+5]-128;
CbDU[pos+6]=tupianu[location+6]-128;
CbDU[pos+7]=tupianu[location+7]-128;
CrDU[pos]=tupianv[location]-128;
CrDU[pos+1]=tupianv[location+1]-128;
CrDU[pos+2]=tupianv[location+2]-128;
CrDU[pos+3]=tupianv[location+3]-128;
CrDU[pos+4]=tupianv[location+4]-128;
CrDU[pos+5]=tupianv[location+5]-128;
CrDU[pos+6]=tupianv[location+6]-128;
CrDU[pos+7]=tupianv[location+7]-128;
pos+=8;
location+=(Ximage/2);
}
}
void main_encoder()
{
S16 DCY=0,DCCb=0,DCCr=0; //DC coefficients used for differential encoding
U16 xpos,ypos;
Yimage=480;
Ximage=640; //9999999
for (ypos=0;ypos<Yimage;ypos+=8)
{
for (xpos=0;xpos<Ximage;xpos+=16)
{load_data_units_from_RGB_buffery(xpos,ypos);
process_DU(YDU,fdtbl_Y,&DCY,YDC_HT,YAC_HT);
load_data_units_from_RGB_buffery((xpos+8),ypos);
process_DU(YDU,fdtbl_Y,&DCY,YDC_HT,YAC_HT);
load_data_units_from_RGB_bufferu(xpos/2,ypos);
process_DU(CbDU,fdtbl_Cb,&DCCb,CbDC_HT,CbAC_HT);
process_DU(CrDU,fdtbl_Cb,&DCCr,CbDC_HT,CbAC_HT);
}
}
}
void init_all()
{
//set_DQTinfo();
//set_DHTinfo();
init_Huffman_tables();
Uart_Printf( "timercount=%d\n", timercount );
set_numbers_category_and_bitcode();
Uart_Printf( "timercount=%d\n", timercount );
// precalculate_YCbCr_tables();
prepare_quant_tables();
Uart_Printf( "timercount=%d\n", timercount );
}
void mainJPG()
{
U16 Ximage_original=640,Yimage_original=480; //the original image dimensions,
bitstring fillbits; //filling bitstring for the bit alignment of the EOI marker
//tupian1=(U8 *)0x32000000;
tupiany=(U8 *)0x32000000;
tupianu=(U8 *)0x3204b000;
tupianv=(U8 *)0x32070800;
number=0;
init_all();
SOF0info.width=Ximage_original;
SOF0info.height=Yimage_original;
writeword(0xFFD8); //SOI
write_APP0info();
write_DQTinfo();
write_SOF0info();
write_DHTinfo();
write_SOSinfo();
bytenew=0;bytepos=7;
Uart_Printf( "timercount=%d\n", timercount );
main_encoder();
Uart_Printf( "timercount=%d\n", timercount );
//Do the bit alignment of the EOI marker
if (bytepos>=0) {
fillbits.length=bytepos+1;
fillbits.value=(1<<(bytepos+1))-1;
writebits(fillbits);
}
writeword(0xFFD9); //EOI
free(category_alloc);
free(bitcode_alloc);
}
void __irq irq_timer3(void)
{
timercount++;
rSRCPND=BIT_TIMER3;
rINTPND=BIT_TIMER3;
}
void Test_SDI(void)
{
U32 save_rGPEUP, save_rGPECON;
int k;
U8 FATType; //
U8 SecPerClus; //每簇扇区数
U8 NumFATS; //FAT表数目
U32 SecPerDisk; //逻辑驱动器包含扇区数
U32 BytsPerSec; //每扇区字节数
U32 RootDirTable; //根目录开始扇区号
U32 RootSecCnt; //根目录占用扇区数
U32 FATStartSec; //FAT表开始扇区号
U32 FATSecCnt; //每个FAT占用扇区数
U32 DataStartSec; //数据区开始扇区号
U32 ClusPerData; //数据区包含簇数
U32 PathClusIndex; //
U32 RsvdForLow;
U32 startSector;
U32 FATSector;
U32 NumBeFATS;
U32 FATStartSec1;
U32 Resesect;
U8 *tupian2;
U32 i1;
unsigned int addr;
unsigned int *addr2;
/*
将 RGB(32位)转换成RGB(24位)
*/
/*
tupian1=(U8 *)0x31000000;
tupian2=(U8 *)0x32000000;
for (i1=0;i1<307200;i1++)
{tupian2[i1*3]=tupian1[i1*4];
tupian2[i1*3+1]=tupian1[i1*4+1];
tupian2[i1*3+2]=tupian1[i1*4+2];
}
*/
RCA=0;
MMC=0;
block=2;
// block=3072; //3072Blocks=1.5MByte, ((2Block=1024Byte)*1024Block=1MByte)
// block=13;
pISR_TIMER3=(unsigned)irq_timer3;
save_rGPEUP=rGPEUP;
save_rGPECON=rGPECON;
rGPEUP = 0xf83f; // SDCMD, SDDAT[3:0] => PU En.
rGPECON = 0xaaaaaaaa; //SDCMD, SDDAT[3:0]
// rGPECON = 0xaaa800aa; //SDCMD, SDDAT[3:0] => Input
RTC_Time_Set() ;
Uart_Printf("\nSDI Card Write and Read Test\n");
if(!SD_card_init())
return;
// TR_Buf_new();
// Wt_Block();
timercount=0;
rRTCCON = 1 ; //RTC read and write enable
year = 0x2000+rBCDYEAR ; //年
month = rBCDMON ; //月
day = rBCDDATE ; //日
// week = rBCDDAY ; //星期
hour = rBCDHOUR ; //小时
minute = rBCDMIN ; //分
second = rBCDSEC ; //秒
rRTCCON &= ~1 ; //RTC read and write disable
Uart_Printf( "RTC time : %04x-%02x-%02x %02x:%02x:%02x\n", year, month, day, hour, minute, second );
Uart_Printf( "rMPLLCON=%x\n", rMPLLCON );
Uart_Printf( "rUPLLCON=%x\n", rUPLLCON );
Uart_Printf( "rCLKCON=%x\n", rCLKCON );
Uart_Printf( "rCLKSLOW=%x\n", rCLKSLOW );
Uart_Printf( "rCLKDIVN=%x\n", rCLKDIVN );
Uart_Printf( "rCAMDIVN=%x\n", rCAMDIVN );
//rTCFG1=3;
rTCFG0=0xf9<<8;//prescaler value= 0xf9+1 =249+1
//rTCFG1=
//rTCNTO1=5000;
rTCNTB3=1000;//
rTCMPB3=2500;
rTCON=0x02<<16;
rTCON=0x09<<16;
k=0;
rINTMSK&=~(BIT_TIMER3);
mainJPG();
rTCON&=0x0fffff0ff;
rINTMSK|=BIT_TIMER3;
Uart_Printf( "timercount=%d\n", timercount );
rRTCCON = 1 ; //RTC read and write enable
year = 0x2000+rBCDYEAR ; //年
month = rBCDMON ; //月
day = rBCDDATE ; //日
// week = rBCDDAY ; //星期
hour = rBCDHOUR ; //小时
minute = rBCDMIN ; //分
second = rBCDSEC ; //秒
rRTCCON &= ~1 ; //RTC read and write disable
Uart_Printf( "RTC time : %04x-%02x-%02x %02x:%02x:%02x\n", year, month, day, hour, minute, second );
/************************************************************
读出0扇区数据,算出FAT 起始地址、FAT1起始地址、根目录起始地址
************************************************************/
//rTCON
addr=0x0000;
addr2=firstdata.l1data;
block=1;
Rd_Block(addr,addr2);
BytsPerSec=firstdata.b1data[12]*256+firstdata.b1data[11]; //确定000B 000C 指明该盘扇区包括字节数,一般为512 即0200
SecPerClus=firstdata.b1data[13]; //确定000D 指明该盘每簇包括的扇区 每簇2扇区
Resesect=firstdata.b1data[15]*256+firstdata.b1data[14]; //确定000E 000F 保留扇区数(在FAT1前的扇区数,包括引导扇区) 0020 即FAT1在32扇区()
NumFATS=firstdata.b1data[16]; //确定0010 该分区上的FAT副本数 02
//确定0011 0012 FAT32此项为0,FAT16 根目录项数
//确定0013 0014 FAT32此项为0,FAT16
NumBeFATS=firstdata.l1data[7];
//firstdata.b1data[31]+firstdata.b1data[30]*256+firstdata.b1data[29]*65536+firstdata.b1data[28]*16777216;
//firstdata.b1data[31]; //确定001C 001D 001E 001F 该分前扇区数 000000000
SecPerDisk=firstdata.l1data[8];
//firstdata.b1data[35]+firstdata.b1data[34]*256+firstdata.b1data[33]*65536+firstdata.b1data[32]*16777216; //确定0020 0021 0022 0023 该分区中扇区数 0003DF00 253696
FATSecCnt=firstdata.l1data[9];
//firstdata.b1data[39]+firstdata.b1data[38]*256;
//firstdata.l1data[9]; //确定0024 0025 0026 0027 FAT占据的扇区数(根据FAT占据的扇区数,FAT个数,隐藏扇区数决定根目录区位置) 000003D8 984
//确定0028 0029 扩展标志位
//确定002C 002D 002E 002F 根目录所在簇号 为2
//确定0030 0031 文件系统信息扇区号 0001
FATStartSec=NumBeFATS+Resesect; //FAT 起始地址
FATStartSec1=FATStartSec+FATSecCnt; //FAT1起始地址
RootDirTable=FATStartSec+NumFATS*FATSecCnt; //根目录起始地址
//读出FAT
addr=FATStartSec*BytsPerSec;
addr2=FATDATA.l1data;
block=2;
Rd_Block(addr,addr2);
//读出目录
addr=RootDirTable*BytsPerSec;
addr2=RWFDATA.l1data;
block=1;
Rd_Block(addr,addr2);
leng1=number;
/*
//读出数据
addr=0xF2000;
addr2=DDATA;
block=4;
Rd_Block(addr,addr2);
*/
addr2=(unsigned int *)0xF1800;
writefile(addr2,leng1);
View_Rx_buf();
if(MMC)
//TR_Buf_new();
if(MMC)
{
rSDICON |=(1<<5); // YH 0519, MMC Type SDCLK
Wt_Stream();
Rd_Stream();
View_Rx_buf();
}
Card_sel_desel(0); // Card deselect
if(!CMD9())
Uart_Printf("Get CSD fail!!!\n");
rSDIDCON=0;//tark???
rSDICSTA=0xffff;
rGPEUP=save_rGPEUP;
rGPECON=save_rGPECON;
}
void TR_Buf_new(void)
{
//-- Tx & Rx Buffer initialize
int i, j;
int start = 0x03020100;
Tx_buffer=(unsigned int *)0x31000000;
j=0;
for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]
*(Tx_buffer+i)=i+j+1;
// *(Tx_buffer+i)=0x5555aaaa;
Flush_Rx_buf();
/*
for(i=0;i<20;i++){
for(j=0;j<128;j++){
Tx_buffer[j+i*128]=start;
if(j % 64 == 63) start = 0x0302010;
else start = start + 0x04040404;
}
start = 0x03020100;
}
*/
}
void Flush_Rx_buf(void)
{
//-- Flushing Rx buffer
int i;
Rx_buffer=(unsigned int *)0x31800000;
for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]
*(Rx_buffer+i)=0;
Uart_Printf("End Rx buffer flush\n");
}
void View_Rx_buf()
{
//-- Display Rx buffer
int i,error=0;
Tx_buffer=(unsigned int *)0x31000000;
Rx_buffer=(unsigned int *)0x31800000;
Uart_Printf("Check Rx data\n");
for(i=0;i<128*block;i++)
{
if(Rx_buffer[i] != Tx_buffer[i])
{
Uart_Printf("\nTx/Rx error\n");
Uart_Printf("%d:Tx-0x%08x, Rx-0x%08x\n",i,Tx_buffer[i], Rx_buffer[i]);
error=1;
break;
}
//Uart_Printf(".");
}
if(!error)
{
Uart_Printf("\nThe Tx_buffer is same to Rx_buffer!\n");
Uart_Printf("SD CARD Write and Read test is OK!\n");
Uart_Printf("%d:Tx-0x%08x, Rx-0x%08x\n",i,Tx_buffer[i], Rx_buffer[i]);
}
}
void View_Tx_buf(void)
{
//-- Display Tx buffer
int i;
//for(i=0;i<2048;i++)
//Uart_Printf("TB[%02x]=%x,",Tx_buffer[i]);
}
int SD_card_init(void)
{
//-- SD controller & card initialize
int i;
char key;
/* Important notice for MMC test condition */
/* Cmd & Data lines must be enabled by pull up resister */
//YH 0816, Org rSDIPRE=PCLK/(2*INICLK)-1; // 400KHz
rSDIPRE=PCLK/(INICLK)-1; // 400KHz
Uart_Printf("Init. Frequency is %dHz\n",(PCLK/(rSDIPRE+1)));
// rSDICON=(1<<4)|(1<<1)|1; // Type B, FIFO reset, clk enable
rSDICON=1; // Type A, clk enable
// rSDICON=(1<<4)|1; // Type B, clk enable
Uart_Printf("rSDICON=0x%08x\n",rSDICON);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -