⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdi.c

📁 一个自己编的将bmp压缩成jpeg格式图片并由串口与MD卡存取的程序。
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -