裸机S3C6410显示控制器(4)- 裸机程序实现显示图片

       (1)背光控制

    刚开始误认为drivers/video/mini6410_backlight.c是背光的驱动程序,但实际它不是。TINY6410的LCD屏的驱动不同于其它LCD的驱动写法,它使用所谓的“一线触屏”驱动,驱动文件是drivers/input/touchscreen/mini6410_1wire_host.c。


驱动初始化:

static int __init dev_init(void)
{
	int ret;
	ret = misc_register(&ts_misc) | misc_register(&bl_misc) ;

	//set PWM as output, set output is 1.
	set_pin_up();
	set_pin_value(1);
	set_pin_as_output();

	if (ret == 0) {
		setup_irq(IRQ_TIMER3, &timer_for_1wire_irq);
		ret = init_timer_for_1wire();
		init_timer(&one_wire_timer);
		one_wire_timer_proc(0);        //设置背光为127 (默认)
		create_proc_read_entry("driver/one-wire-info", 0, NULL, read_proc, NULL);
	}
	
	if (ret == 0) {
		printk (TOUCH_DEVICE_NAME"\tinitialized\n");
		printk (BACKLIGHT_DEVICE_NAME"\tinitialized\n");
	}
	return ret;
}


static void __exit dev_exit(void)
{
	exitting = 1;
	remove_proc_entry("driver/one-wire-info", NULL);
	del_timer_sync(&one_wire_timer);
	free_irq(IRQ_TIMER3, &timer_for_1wire_irq);
	misc_deregister(&ts_misc);
	misc_deregister(&bl_misc);
}

一线触屏状态机:

enum {
	IDLE,
	START,
	REQUEST,
	WAITING,
	RESPONSE,
	STOPING,
} one_wire_status = IDLE;

static volatile unsigned int io_bit_count;
static volatile unsigned int io_data;
static volatile unsigned char one_wire_request;
static irqreturn_t timer_for_1wire_interrupt(int irq, void *dev_id)
{
	io_bit_count--;
	switch(one_wire_status) {     
	case START:                                     
		if (io_bit_count == 0) {
			io_bit_count = 16;
			one_wire_status = REQUEST;
		}
		break;

	case REQUEST:                               
		// Send a bit         
		set_pin_value(io_data & (1U << 31));
		io_data <<= 1;
		if (io_bit_count == 0) {
			io_bit_count = 2;
			one_wire_status = WAITING;
		}
		break;
		
	case WAITING:                             
		if (io_bit_count == 0) {
			io_bit_count = 32;
			one_wire_status = RESPONSE;
		}
		if (io_bit_count == 1) {
			set_pin_as_input();
			set_pin_value(1);
		}
		break;
		
	case RESPONSE:                        
		// Get a bit                    
		io_data = (io_data << 1) | get_pin_value();
		if (io_bit_count == 0) {
			io_bit_count = 2;
			one_wire_status = STOPING;
			set_pin_value(1);
			set_pin_as_output();
			one_wire_session_complete(one_wire_request, io_data);
		}
		break;

	case STOPING:                     // 2
		if (io_bit_count == 0) {
			one_wire_status = IDLE;
			stop_timer_for_1wire();
		}
		break;
		
	default:
		stop_timer_for_1wire();
	}
	return IRQ_HANDLED;
}

(2)LCD的初始化

void LCDTest()
{
	int i, j;
	
	trace("Enter LCDTest().\r\n");

	(*(volatile unsigned int *)0x7410800c)=0;	//Must be '0' for Normal-path instead of By-pass

	 
	 ///set GPE0
	//*(volatile unsigned int*)0x7F008080 = 0x00011111;   
	//*(volatile unsigned int*)0x7F008084 = 0x00000001;
	//*(volatile unsigned int*)0x7F008088 = 0x00000000;

	GPIO_SetLCDType(eRGBIF); //set LCD mode to RGB mode
	
	//Set LCD GPIO Port
	GPIO_SetFunctionAll(eGPIO_I, 0xaaaaaaaa, 2); //GPI[15..0]-> RGB VD[15..0]
	GPIO_SetFunctionAll(eGPIO_J, 0xaaaaaaaa, 2); //GPJ[7..0]-> RGB VD[23..16], GPJ[11..8]-> VCLK, VDEN, VSYNC, HSYNC
	
	GPIO_SetFunctionEach(eGPIO_E, eGPIO_0, 1); //GPF[15] -> Output
	GPIO_SetDataEach(eGPIO_E, eGPIO_0 , 1); //GPF[15] -> High

	trace("LCD GPIO init ok.\r\n");
	
	//other pin gpio not set yet.
	//LCD reset has not done
	//LCD cmd init has not done
	
	//begin base display test.
	eBgWin = WIN0;
	eFgWin = WIN1;
	
	/*  RGB 5-6-5 format for SMDK EVAL BOARD */
	eBgBpp = RGB16;
	eFgBpp = RGB16;

	*(volatile unsigned long *)0x7E00F030 |= 1 << 3;  //set lcd clk enable in hclk_gate register

	
	
	LCD_InitDISPC(eBgBpp, uLcdFbAddr, eBgWin, false);
	LCD_SetWinOnOff(1, eBgWin);


	trace("Invoke LCD_Start().\r\n");
	LCD_Start();

	trace("Invoke set_bklight.\r\n");
	

	set_bklight();

}


void LCD_InitBase(void)
{
	u32 uLcdCon;
	u32 uILcdIntCon;
	u32 uClkVal, uClkDir;
	CLK_SRC_m eVClkSrc;
	u32 uVidconReg;
	u32 i;
	LCD_WINDOW eWin;

	oLcdc.m_bIsAutoBuf = false;
	oLcdc.m_uScanMode = 0; // progressive mode
	oLcdc.m_bIsLocalCalled[0] = false;
	oLcdc.m_bIsLocalCalled[1] = false;
	oLcdc.m_bIsLocalCalled[2] = false;
	
	
	/*set lcd clock source: 
	CLKSEL_F_HCLK           (0<<2)
	CLKSEL_F_SYSCON         (1<<2)
	CLKSEL_F_EXTCLK         (3<<2)
	*/
	oLcdc.m_uVideoClockSource = CLKSEL_F_HCLK;
	eVClkSrc = SRC_HCLK;
	
	oLcdc.m_uLcdHSz = 800;
	oLcdc.m_uLcdVSz = 480;
	oLcdc.m_uVidOutFormat = VIDOUT_RGBIF;
	oLcdc.m_uDitherMode = RDITHPOS_5BIT|GDITHPOS_6BIT|BDITHPOS_5BIT;
	oLcdc.m_uDitherMode &= ~DITHERING_ENABLE;
	
	LcdcOutp32(rVIDCON1, IHSYNC_INVERT | IVSYNC_INVERT); 	//Check 
		
	LcdcOutp32(rVIDTCON0, VBPDE(S3CFB_VBP) | VBPD(S3CFB_VBP) | VFPD(S3CFB_VFP) | VSPW(S3CFB_VSW));
	LcdcOutp32(rVIDTCON1, VFPDE(S3CFB_VFP) | HBPD(S3CFB_HBP) | HFPD(S3CFB_HFP) | HSPW(S3CFB_HSW));
	LcdcOutp32(rVIDTCON2, LINEVAL(oLcdc.m_uLcdVSz-1) | HOZVAL(oLcdc.m_uLcdHSz-1));
	LcdcOutp32(rDITHMODE, oLcdc.m_uDitherMode); // Fixed Dithering Matrix
		
	LCD_Stop();
	
	//Check up LCD to turn off
	
	while (1)
	{
		uLcdCon=Inp32(LCD_BASE+rVIDCON0);
		if( (uLcdCon&0x03) == 0 ) // checking whether disable the video output and the Display control signal or not.
		break;
	}
	
	LCD_SetClkSrc(eVClkSrc);
	
	/**
 * WARNING: CLKVAL is defined upon 133 MHz HCLK, please update it
 * when HCLK freq changed.
 *   VCLK = 133 MHz / (CLKVAL + 1)
 *   = ~33.25 MHz 
 */
	uClkVal = 3;
	uClkDir = 1;
	uVidconReg =
		PROGRESSIVE | oLcdc.m_uVidOutFormat | SUB_16_MODE | MAIN_16_MODE | PNRMODE_RGB_P | CLKVALUP_ALWAYS |
		CLKVAL_F(uClkVal) | /*VCLKEN_DISABLE |*/ CLKDIR_F(uClkDir) | oLcdc.m_uVideoClockSource|
		ENVID_DISABLE | ENVID_F_DISABLE;
	LcdcOutp32(rVIDCON0, uVidconReg);

	uILcdIntCon =Inp32(LCD_BASE+rVIDINTCON0);
	LcdcOutp32(rVIDINTCON0, 0);
	//LcdcOutp32(rVIDINTCON0, uILcdIntCon | FRAMESEL0_BACK | FRAMESEL1_NONE | INTFRMEN_DISABLE |
	//			FIFOSEL_WIN0 | FIFOLEVEL_25 | INTFIFOEN_DISABLE | INTEN_DISABLE);
	
	LCD_SetAllWinOnOff(0); // Turn all windows off
	LCD_SetAllWinColorMapOnOff(0); // Turn all windows color map off
	LCD_SetAllWinColorKeyOnOff(0); // Turn all windows Color Key off

	for (i=1; i<5; i++)
	{
		eWin =
			(i == 1) ? WIN1 :
			(i == 2) ? WIN2 :
			(i == 3) ? WIN3 : WIN4;

		LCD_SetAlpha(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, eWin);
	}
	
}

void LCD_InitWinRegs(LCD_WINDOW eWin)
{
	u32 uWinConXReg;
	u32 uAlphaValReg;
	u32 uFrmBufStAddrReg;
	u32 uFrmBufEndAddrReg;
	u32 uOffsetPageWidthReg;
	u32 uOsdLeftPosReg;
	u32 uOsdRightPosReg;
	u32 uWinConXRegVal;
	u32 uLcdEndX, uLcdEndY;
	



	uWinConXReg =
		(eWin == WIN0) ? rWINCON0 :
		(eWin == WIN1) ? rWINCON1 :
		(eWin == WIN2) ? rWINCON2 :
		(eWin == WIN3) ? rWINCON3 : rWINCON4;

	uAlphaValReg =
		(eWin == WIN1) ? rVIDOSD1C :
		(eWin == WIN2) ? rVIDOSD2C :
		(eWin == WIN3) ? rVIDOSD3C :
		(eWin == WIN4) ? rVIDOSD4C : rVIDOSD1C;

	uFrmBufStAddrReg =
		(eWin == WIN0) ? rVIDW00ADD0B0 :
		(eWin == WIN1) ? rVIDW01ADD0B0:
		(eWin == WIN2) ? rVIDW02ADD0 :
		(eWin == WIN3) ? rVIDW03ADD0 : rVIDW04ADD0;

	uFrmBufEndAddrReg =
		(eWin == WIN0) ? rVIDW00ADD1B0 :
		(eWin == WIN1) ? rVIDW01ADD1B0 :
		(eWin == WIN2) ? rVIDW02ADD1 :
		(eWin == WIN3) ? rVIDW03ADD1 : rVIDW04ADD1;

	uOffsetPageWidthReg =
		(eWin == WIN0) ? rVIDW00ADD2 :
		(eWin == WIN1) ? rVIDW01ADD2 :
		(eWin == WIN2) ? rVIDW02ADD2 :
		(eWin == WIN3) ? rVIDW03ADD2 : rVIDW04ADD2;

	uOsdLeftPosReg =
		(eWin == WIN0) ? rVIDOSD0A :
		(eWin == WIN1) ? rVIDOSD1A :
		(eWin == WIN2) ? rVIDOSD2A :
		(eWin == WIN3) ? rVIDOSD3A : rVIDOSD4A;

	uOsdRightPosReg =
		(eWin == WIN0) ? rVIDOSD0B :
		(eWin == WIN1) ? rVIDOSD1B :
		(eWin == WIN2) ? rVIDOSD2B :
		(eWin == WIN3) ? rVIDOSD3B : rVIDOSD4B;

	uWinConXRegVal = 0;
	
	if (eWin == WIN0)
	{
		if (!oLcdc.m_bIsLocalCalled[0]) // Input path is DMA
		{
			uWinConXRegVal =
				W0DMA | W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
				oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode|
				oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | oLcdc.m_uBppMode |
				ENWIN_F_DISABLE;
			
		}
		else // Input path is Local
		{
			//Assert(oLcdc.m_eLocalIn[0] == IN_POST);

			if(oLcdc.m_uLocalInColorSpace[0] == LOCALIN_YCbCr)
			{
				uWinConXRegVal =
				W0LOCAL_POST | W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
				oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_YUV |
				oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | oLcdc.m_uBppMode |
				ENWIN_F_DISABLE;
			}
			else
			{
				uWinConXRegVal =
				W0LOCAL_POST | W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
				oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_RGB |
				oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | oLcdc.m_uBppMode |
				ENWIN_F_DISABLE;
			}
			
		}

		LcdcOutp32(rVIDW00ADD0B1, oLcdc.m_uDoubleBufStAddr[0]);
		LcdcOutp32(rVIDW00ADD1B1, oLcdc.m_uDoubleBufEndAddr[0]);
		LcdcOutp32(rVIDOSD0C, OSDSIZE(oLcdc.m_uViewHSz[0]*oLcdc.m_uViewVSz[0]));
	}
	else
	{
		if (eWin == WIN1)
		{
			if (!oLcdc.m_bIsLocalCalled[1]) // Input path is DMA
			{
				uWinConXRegVal =
					W0DMA | W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
					oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode|
					oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
					BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
			}
			else // Input path is Local
			{
				//Assert(oLcdc.m_eLocalIn[1] == IN_POST || oLcdc.m_eLocalIn[1] == IN_CIM);

				if(oLcdc.m_uLocalInColorSpace[1] == LOCALIN_YCbCr)
				{
					uWinConXRegVal =
					((oLcdc.m_eLocalIn[1] == IN_CIM) ? W1ENLOCAL_CIM : W1ENLOCAL_POST) |
					W1LOCAL| W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
					oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_YUV |
					oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
					BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
				}
				else
				{
					uWinConXRegVal =
					((oLcdc.m_eLocalIn[1] == IN_CIM) ? W1ENLOCAL_CIM : W1ENLOCAL_POST) |
					W1LOCAL| W0BUF0 | W0BUFAUTO_DISABLE | BITSWP_DISABLE |
					oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_RGB |
					oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
					BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
				}	
			}
			
			// set double buf. addr. and offset size
			LcdcOutp32(rVIDW01ADD0B1, oLcdc.m_uDoubleBufStAddr[1]);
			LcdcOutp32(rVIDW01ADD1B1, oLcdc.m_uDoubleBufEndAddr[1]);

			LcdcOutp32(rVIDOSD1D, OSDSIZE(oLcdc.m_uViewHSz[1]*oLcdc.m_uViewVSz[1]));			
		}
		else // eWin == WIN2 OR WIN3 OR WIN4
		{
			if (eWin == WIN2)
			{
				if (!oLcdc.m_bIsLocalCalled[2]) // Input path is DMA
				{
					uWinConXRegVal =
						W0DMA | BITSWP_DISABLE |
						oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode|
						oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
						BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
				}
				else // Input path is Local
				{
					//Assert(oLcdc.m_eLocalIn[2] == IN_POST || oLcdc.m_eLocalIn[2] == IN_CIM);

					if(oLcdc.m_uLocalInColorSpace[2] == LOCALIN_YCbCr)
					{
					
						uWinConXRegVal =
						((oLcdc.m_eLocalIn[2] == IN_CIM) ? W1ENLOCAL_CIM : W1ENLOCAL_POST) | 
						W1LOCAL | BITSWP_DISABLE |oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_YUV |
						oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
						BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
					}
					else 
					{
						
						uWinConXRegVal =
						((oLcdc.m_eLocalIn[2] == IN_CIM) ? W1ENLOCAL_CIM : W1ENLOCAL_POST) | 
						W1LOCAL | BITSWP_DISABLE |oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode| IN_LOCAL_RGB |
						oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen | BLD_PIX_PLANE | oLcdc.m_uBppMode |
						BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
					}
					
				}

				LcdcOutp32(rVIDOSD2D, OSDSIZE(oLcdc.m_uViewHSz[2]*oLcdc.m_uViewVSz[2]));				
			}
			else // eWin == WIN3 || eWin == WIN4
			{
				uWinConXRegVal = 
					BITSWP_DISABLE | oLcdc.m_uBytSwpMode | oLcdc.m_uHawSwpMode |
					oLcdc.m_uMinBurstLen | oLcdc.m_uMaxBurstLen |
					BLD_PIX_PLANE | oLcdc.m_uBppMode | BLEND_ALPHA0_PLANE | ENWIN_F_DISABLE;
			}
		}

		LcdcOutp32(uAlphaValReg,
			ALPHA0_R(0xF) | ALPHA0_G(0xF) | ALPHA0_B(0xF) |
			ALPHA1_R(0xF) | ALPHA1_G(0xF)| ALPHA1_B(0xF));
	}

	LcdcOutp32(uWinConXReg, uWinConXRegVal);		
	LcdcOutp32(uFrmBufStAddrReg, oLcdc.m_uFbStAddr[eWin]);
	LcdcOutp32(uFrmBufEndAddrReg, oLcdc.m_uFbEndAddr[eWin]);
	LcdcOutp32(uOffsetPageWidthReg, (oLcdc.m_uOffsetSz[eWin]<<13) | oLcdc.m_uPageWidth[eWin]);

	uLcdEndX = oLcdc.m_uLcdStX + oLcdc.m_uViewHSz[eWin] - 1;
	uLcdEndY = oLcdc.m_uLcdStY + oLcdc.m_uViewVSz[eWin] - 1;

	if (oLcdc.m_uScanMode == 1) // Interlace mode
	{
		//Assert(!(oLcdc.m_uLcdStX%2));	// Left top -> Y coordinate must be even number in interlace mode
		//Assert(uLcdEndY%2); 			// Rigth bottom -> Y coordinate must be odd number in interlace mode

		// In interlace mode, Left Top Y(oLcdc.m_uLcdStY) and Right Bottom Y(uLcdEndY) must be divided by 2.
		// And, Right Bottom Y must be rounded down
		LcdcOutp32(uOsdLeftPosReg, OSD_LTX_F(oLcdc.m_uLcdStX) | (OSD_LTY_F(oLcdc.m_uLcdStY)>>1));
		LcdcOutp32(uOsdRightPosReg, OSD_RBX_F(uLcdEndX) | (OSD_RBY_F(uLcdEndY)>>1));
	}
	else // Progressive mode
	{
		LcdcOutp32(uOsdLeftPosReg, OSD_LTX_F(oLcdc.m_uLcdStX) | OSD_LTY_F(oLcdc.m_uLcdStY));
		LcdcOutp32(uOsdRightPosReg, OSD_RBX_F(uLcdEndX) | OSD_RBY_F(uLcdEndY));
	}
}

void LCD_SetWinOnOff(u32 uOnOff, LCD_WINDOW eWin)
{
	u32 uWinTemp;
	u32 uWinConReg;

	uWinConReg =
		(eWin == WIN0) ? rWINCON0 :
		(eWin == WIN1) ? rWINCON1 :
		(eWin == WIN2) ? rWINCON2 :
		(eWin == WIN3) ? rWINCON3 : rWINCON4;

	uWinTemp=Inp32(LCD_BASE+uWinConReg);

	if (uOnOff) // Turn OSD on
		uWinTemp |= ENWIN_F_ENABLE;
	else // Turn OSD off
		uWinTemp &= ~ENWIN_F_ENABLE;

	LcdcOutp32(uWinConReg, uWinTemp);
}


void LCD_InitWin(CSPACE eBpp, 
				  u32 uFrameH,        //800
				  u32 uFrameV,       //480
				  u32 uX_Frame,    //0
				  u32 uY_Frame,   //0
				  u32 uViewH,       //800
				  u32 uViewV,       //480
				  u32 uX_Lcd,       //0
				  u32 uY_Lcd,      //0
				  u32 uFbAddr,     //
				  LCD_WINDOW eWin,
				  u8 bIsDoubleBuf)
{
	u32 uOffset;
	//u32 uLineVal;
	u32 uBurstSize;

	//if ( (eWin != WIN0 && eWin != WIN1) && bIsDoubleBuf == true )
	//	Assert(0); // In WIN2, WIN3 or WIN4, Double buffering can't be supported

	// Viewport size must be less than LCD size
	//Assert(uViewH <= oLcdc.m_uLcdHSz);
	//Assert(uViewV <= oLcdc.m_uLcdVSz);

	// Check (X,Y) coordinate is valid in LCD and Frame?
	//Assert( ((uX_Frame + uViewH) <= uFrameH) && ((uY_Frame + uViewV) <= uFrameV) );
	//Assert( (uX_Lcd + uViewH <= oLcdc.m_uLcdHSz) && (uY_Lcd + uViewV <= oLcdc.m_uLcdVSz) );

	// Double buffering is supported by only window 0 and window 1
	//if ( ((eWin != WIN0) && (eWin != WIN1)) && (bIsDoubleBuf == true) )
	//	Assert(0);

	oLcdc.m_uFrmHSz[eWin] = uFrameH;   //800
	oLcdc.m_uFrmVSz[eWin] = uFrameV;   //480

	oLcdc.m_uViewHSz[eWin] = uViewH;   //800
	oLcdc.m_uViewVSz[eWin] = uViewV;   //480

	oLcdc.m_uLcdStX = uX_Lcd;     //0
	oLcdc.m_uLcdStY = uY_Lcd;     //0

	uOffset = oLcdc.m_uFrmHSz[eWin] - oLcdc.m_uViewHSz[eWin];   //=0

	oLcdc.m_uBytSwpMode = BYTSWP_DISABLE;		// BYTE swap disable
	oLcdc.m_uHawSwpMode = HAWSWP_DISABLE;		// Half-Word swap disable

	oLcdc.m_uMaxBurstLen = MAX_BURSTLEN_16WORD;		// DMA'burst max 16word burst
	oLcdc.m_uMinBurstLen = MIN_BURSTLEN_16WORD;		// DMA'burst min 16 word burst


	//m_uBytes濂藉儚鏄鍗犲灏戜釜瀛楄妭锛屽鏋滃皬浜庝竴涓瓧鑺傦紝閭d箞m_uBytes=1锛屽苟涓攎_uBits琛ㄧず鍗犲灏戜綅銆?
	


	//else if (eBpp == RGB16)
	//{
		oLcdc.m_uBytes = 2;
		oLcdc.m_uBits = 1;
		//Assert( !(uOffset%2) ); // Must keep to word-alignment

		oLcdc.m_uBppMode = BPPMODE_F_16BPP_565;  //5<<2
		oLcdc.m_uHawSwpMode = HAWSWP_ENABLE;    // 1<<16
	//}
	

	// Get offsetsize, pagewidth and lineVal
	if (oLcdc.m_uFrmHSz[eWin] >= oLcdc.m_uViewHSz[eWin])
	{
		oLcdc.m_uOffsetSz[eWin] = uOffset*oLcdc.m_uBytes/oLcdc.m_uBits;      //0
		oLcdc.m_uPageWidth[eWin] = oLcdc.m_uViewHSz[eWin]*oLcdc.m_uBytes/oLcdc.m_uBits;  //=1600

		// Offset size must be more than the burst size
		uBurstSize =
			(oLcdc.m_uMaxBurstLen == MAX_BURSTLEN_16WORD) ? 16*4 :   //16
			(oLcdc.m_uMaxBurstLen == MAX_BURSTLEN_8WORD) ? 8*4 : 4*4;

		// Offset size must be more than the burst size
		//Assert( oLcdc.m_uOffsetSz[eWin] == 0 || !(oLcdc.m_uOffsetSz[eWin]%4) );
		//Assert(oLcdc.m_uPageWidth[eWin] > uBurstSize); // Page width must be more than burst size and be word-aligned

		//uLineVal = oLcdc.m_uViewVSz[eWin] - 1;
	} 
	else
	{
		//Assert(0);
	}

	oLcdc.m_uImgStAddr[eWin] = uFbAddr;

	oLcdc.m_uFbStAddr[eWin] = uFbAddr + (oLcdc.m_uFrmHSz[eWin]*uY_Frame + uX_Frame)*oLcdc.m_uBytes/oLcdc.m_uBits;  //= uFbAddr
	oLcdc.m_uFbEndAddr[eWin] = oLcdc.m_uFbStAddr[eWin] + (oLcdc.m_uOffsetSz[eWin]+oLcdc.m_uPageWidth[eWin])*(uFrameV);  //uFbAddr + 1600*480

	if ( (bIsDoubleBuf == true) && ((eWin == WIN0) || (eWin == WIN1)) )
	{
		oLcdc.m_uDoubleBufImgStAddr[eWin] = oLcdc.m_uImgStAddr[eWin] + oLcdc.m_uFrmHSz[eWin]*oLcdc.m_uFrmVSz[eWin]*oLcdc.m_uBytes/oLcdc.m_uBits;
		oLcdc.m_uDoubleBufStAddr[eWin] = oLcdc.m_uFbStAddr[eWin] + oLcdc.m_uFrmHSz[eWin]*oLcdc.m_uFrmVSz[eWin]*oLcdc.m_uBytes/oLcdc.m_uBits;
		oLcdc.m_uDoubleBufEndAddr[eWin] = oLcdc.m_uDoubleBufStAddr[eWin] + (oLcdc.m_uOffsetSz[eWin]+oLcdc.m_uPageWidth[eWin])*(uFrameV);
	}
	else if ( (bIsDoubleBuf == false) && ((eWin == WIN0) || (eWin == WIN1)) )
	{
		oLcdc.m_uDoubleBufStAddr[eWin] = oLcdc.m_uFbStAddr[eWin];
		oLcdc.m_uDoubleBufEndAddr[eWin] = oLcdc.m_uFbEndAddr[eWin];
	}

	LCD_InitWinRegs(eWin);

	// For back-ward compatibility LCDC V2.0
	if(eWin == WIN0)
		LCD_SetWinOnOff(1, WIN0); // first arguement == 1 -> turn on window
}

(3)显示图像

我儿子的照片,晚上用手机拍的图片,不是很清晰:



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值