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

📄 tftconfig.c

📁 BlackFin与摄像头的接口程序
💻 C
字号:
/** *********************************************************************
 * @file TFTconfig.c
 * @author Roland Oberhammer
 * @date 2006-06-16
 * @version 1.0
 *
 * initialize the TFT display
 *
 * NOTE: 	Currently the TFT-display functions are hardcoded 
 *			for 240 * 320 pixel.
 *			No other resolution is currently supported because 
 *			the timing is hardcoded.
 *
 *			If the framebuffer driver is in landscape format and the display 
 *			is in portrait format use the TFT_ROTATE_FRAME macro to rotate the frame.
 *			If you use this macro be sure that a section named
 *			"tft_descriptor_chain" is described in your linker file. For performance
 *			issues this section has to be in the internal l1 data memory.
 *
 *			If you use timer5 on a CM-BF537 be sure to have enabled the
 *			pin on the core module (soldering the right mount option)
 *
 *
 * @see TFTconfig.h
  ********************************************************************* **/
#include <environment.h>
#include <cycle_count_bf.h>
#include "../pwrmngt/clockquery.h"
#include "TFTConfig.h"
#include "../PPIconfig.h"
#include "../gpTimerConfig.h"

// needed for mdma
#if defined (__ADSPBF561__)
#include <cdefbf561.h>
#elif defined (__ADSPBF533__)
#include <cdefbf533.h>
#elif defined (__ADSPBF537__)
#include <cdefbf537.h>
#else
#error "processor not yet supported"
#endif


// If the framebuffer driver is in landscape format and the display 
// is in portrait format use the TFT_ROTATE_FRAME macro to rotate the frame.
// If you use this macro be sure that a section named
// "tft_descriptor_chain" is described in your linker file. For performance
// issues this section has to be in the internal l1 data memory.
#ifndef TFT_ROTATE_FRAME
#define TFT_ROTATE_FRAME
#endif

#ifndef TFT_DTMG_OVER_AND_GATE
#define TFT_DTMG_OVER_AND_GATE	// needed if the display is connected over an AND gate to create the dtmg timing
#endif

// some global stuff for managment purposes
section ("tft_descriptor_chain") static T_TFT_SPEC g_TFTspec;
// frame complete flag
section ("tft_descriptor_chain") unsigned char g_TFT_FrameComplete = 0;

unsigned short nBitReverse_Blue []  = { 0x0000, 0x8000, 0x4000, 0xc000, 0x2000, 0xa000, 0x6000, 0xe000, 0x1000, 0x9000, 0x5000, 0xd000, 0x3000,
								 	   0xb000, 0x7000, 0xf000, 0x0800, 0x8800, 0x4800, 0xc800, 0x2800, 0xa800, 0x6800, 0xe800, 0x1800, 0x9800,
									   0x5800, 0xd800, 0x3800, 0xb800, 0x7800, 0xf800 };
unsigned short nBitReverse_Green [] = { 0x0000, 0x0400, 0x0200, 0x0600, 0x0100, 0x0500, 0x0300, 0x0700, 0x0080, 0x0480, 0x0280, 0x0680, 0x0180,
									   0x0580, 0x0380, 0x0780, 0x0040, 0x0440, 0x0240, 0x0640, 0x0140, 0x0540, 0x0340, 0x0740, 0x00c0, 0x04c0,
									   0x02c0, 0x06c0, 0x01c0, 0x05c0, 0x03c0, 0x07c0, 0x0020, 0x0420, 0x0220, 0x0620, 0x0120, 0x0520, 0x0320, 
									   0x0720, 0x00a0, 0x04a0, 0x02a0, 0x06a0, 0x01a0, 0x05a0, 0x03a0, 0x07a0, 0x0060, 0x0460, 0x0260, 0x0660,
									   0x0160, 0x0560, 0x0360, 0x0760, 0x00e0, 0x04e0, 0x02e0, 0x06e0, 0x01e0, 0x05e0, 0x03e0, 0x07e0 };
unsigned short nBitReverse_Red []   = { 0x0000, 0x0010, 0x0008, 0x0018, 0x0004, 0x0014, 0x000c, 0x001c, 0x0002, 0x0012, 0x000a, 0x001a, 0x0006,
									   0x0016, 0x000e, 0x001e, 0x0001, 0x0011, 0x0009, 0x0019, 0x0005, 0x0015, 0x000d, 0x001d, 0x0003, 0x0013,
									   0x000b, 0x001b, 0x0007, 0x0017, 0x000f, 0x001f };
									   
									   
									   
#ifdef TFT_ROTATE_FRAME
// descriptor list for the dma chain including descriptors for blanking lines
section ("tft_descriptor_chain") unsigned long anTFTdmaDescriptorTable[2 * (TFT_YSIZE + TFT_Y_BLANKING_LINES)];
// frame line counter
#endif
#ifndef TFT_DTMG_OVER_AND_GATE
section ("tft_descriptor_chain") signed short g_TFTlineCounter = 0;
#endif

#pragma section ("L1_code")
void TFTsetPixel (unsigned short x, unsigned short y, unsigned char pa_cRed, unsigned char pa_cGreen, unsigned char pa_cBlue) {
#ifdef TFT_ROTATE_FRAME
	if (g_TFTspec.bBitReverse) {
		*(unsigned short *)(((y * g_TFTspec.nYsize + /*y * TFT_Y_BLANKING_LINES*/ + x) * 2) + (unsigned long)g_TFTspec.pnFrameBuffer) = nBitReverse_Blue[pa_cBlue] | nBitReverse_Green[pa_cGreen] | nBitReverse_Red[pa_cRed];
	} else {
		*(unsigned short *)(((y * g_TFTspec.nYsize + /*y * TFT_Y_BLANKING_LINES*/ + x) * 2) + (unsigned long)g_TFTspec.pnFrameBuffer) = (pa_cBlue << 11) | (pa_cGreen << 5) | pa_cRed;
	}
#else
	if (g_TFTspec.bBitReverse) {
		*(unsigned short *)(((y * g_TFTspec.nXsize + x) * 2) + (unsigned long)g_TFTspec.pnFrameBuffer + TFT_Y_BLANKING_LINES * g_TFTspec.nXsize * g_TFTspec.cBytesPerPixel) = nBitReverse_Blue[pa_cBlue] | nBitReverse_Green[pa_cGreen] | nBitReverse_Red[pa_cRed];
	} else {
		*(unsigned short *)(((y * g_TFTspec.nXsize + x) * 2) + (unsigned long)g_TFTspec.pnFrameBuffer + TFT_Y_BLANKING_LINES * g_TFTspec.nXsize * g_TFTspec.cBytesPerPixel) = (pa_cBlue << 11) | (pa_cGreen << 5) | pa_cRed;
	}
#endif
}

#pragma section ("L1_code")
void TFTgetPixel(unsigned short x, unsigned short y, unsigned char *pa_pcRed, unsigned char *pa_pcGreen, unsigned char *pa_pcBlue) {
#ifdef TFT_ROTATE_FRAME		
	unsigned short nPixel = *(unsigned short *)(((y * g_TFTspec.nYsize + y * TFT_Y_BLANKING_LINES + x) * 2) + (unsigned long)g_TFTspec.pnFrameBuffer);
#else	
	unsigned short nPixel = *(unsigned short *)(((y * g_TFTspec.nXsize + x) * 2) + (unsigned long)g_TFTspec.pnFrameBuffer + TFT_Y_BLANKING_LINES * g_TFTspec.nXsize * g_TFTspec.cBytesPerPixel);
#endif
	*pa_pcRed = nPixel & 0x1f;
	*pa_pcGreen = (nPixel >> 5)  & 0x3f;
	*pa_pcBlue = (nPixel >> 11) & 0x1f;
}

#pragma section ("L1_code")
void TFTblendPixel(unsigned short x, unsigned short y, unsigned char pa_cRed, unsigned char pa_cGreen, unsigned char pa_cBlue, unsigned char pa_cAlpha) {
	unsigned char cRed;
	unsigned char cGreen;
	unsigned char cBlue;
	// fetch the current pixel color
	TFTgetPixel(x, y, &cRed, &cGreen, &cBlue);
	// calc the blend colors
	cRed = (pa_cRed * pa_cAlpha + cRed * (255 - pa_cAlpha)) >> 8;
	cGreen = (pa_cGreen * pa_cAlpha + cGreen * (255 - pa_cAlpha)) >> 8;
	cBlue = (pa_cBlue * pa_cAlpha + cBlue * (255 - pa_cAlpha)) >> 8;
	// set the new pixel color
	TFTsetPixel(x, y, cRed, cGreen, cBlue);
}

#ifndef TFT_DTMG_OVER_AND_GATE
// interrupt handler for the ppi dma
#pragma section ("L1_code") 
void TFTppiHandler(void *pa_pClientArg) {
//#ifdef TFT_ROTATE_FRAME
	g_TFTlineCounter ++;
	if (g_TFTlineCounter == TFT_Y_BLANKING_LINES + 1) {
		// start normal period
		timer_set_period (g_TFTspec.tDtmgTimerHndl, TFT_XSIZE + TFT_X_BLANKING);
		timer_set_width (g_TFTspec.tDtmgTimerHndl, TFT_X_BLANKING);		
	}
	else if (g_TFTlineCounter == TFT_YSIZE + TFT_Y_BLANKING_LINES) {
		// start vsync period
		timer_set_period (g_TFTspec.tDtmgTimerHndl, TFT_Y_BLANKING_LINES * (TFT_XSIZE + TFT_X_BLANKING) + TFT_X_BLANKING + TFT_XSIZE/*1911+33+240*/);
		timer_set_width (g_TFTspec.tDtmgTimerHndl, TFT_Y_BLANKING_LINES * (TFT_XSIZE + TFT_X_BLANKING) + TFT_X_BLANKING/*1911+33*/);		
		g_TFTlineCounter = 0;
	}	
}

#endif


// sleep function
void TFTmsSleep (unsigned long pa_nMs, unsigned long pa_nCoreClk) {
	unsigned long long int cur,nd;
	
	_GET_CYCLE_COUNT(cur);
	nd = cur + pa_nCoreClk / 1000 * pa_nMs;
	while (cur < nd) {
		_GET_CYCLE_COUNT(cur);
	}
}

void TFTsetupFrameBufferUpdateProcess (unsigned long *pa_nWorkingBuffer0, unsigned long *pa_nWorkingBuffer1, void *pa_Generic) {
	g_TFTspec.pnWorkingBuffer0 = pa_nWorkingBuffer0;
	g_TFTspec.pnWorkingBuffer1 = pa_nWorkingBuffer1;
	g_TFTspec.cCurrentWorkingBuffer = 0;	
}

void TFTsetWorkingBuffer (unsigned char pa_cWorkingBuffer) {
	g_TFTspec.cCurrentWorkingBuffer = pa_cWorkingBuffer;
}

void TFTupdateFrameBuffer (void) {
}

// sets the brithness
void TFTsetBrightness (unsigned short pa_cBrightness) {
	if (pa_cBrightness > TFT_MAX_BRIGTHNESS) {
		pa_cBrightness = TFT_MAX_BRIGTHNESS;
	}
	
}

// sets up the timer and ppi for the tft-display
T_ERROR_CODE TFTsetup (	unsigned char pa_cPPI,
						unsigned long pa_nCoreClk,
						unsigned long pa_nSystemClk, 
						unsigned short pa_nXsize, 
						unsigned short pa_nYsize,
						unsigned char pa_BytePerPixel,
						unsigned char pa_cPWMtimer,
						unsigned char pa_cDTMGshiftTimer,
						bool pa_bCreateDCLK,
						unsigned char pa_cDCLKtimer,
						T_GPIO_MASK pa_cPCIflag,
						unsigned char *nFrameBuffer,
						bool pa_bBitReverse,
						void *pa_Reserved) {
							
	T_ERROR_CODE erResult = ERR_NONE;
	
	// filling the global spec structure
	g_TFTspec.pnFrameBuffer = nFrameBuffer;
	g_TFTspec.nXsize = pa_nXsize;
	g_TFTspec.nYsize = pa_nYsize;
	g_TFTspec.bBitReverse = pa_bBitReverse;
	g_TFTspec.cBytesPerPixel = pa_BytePerPixel;
	
	if (pa_bCreateDCLK) {
		// create the dclk clock output (usually 5.33Mhz)
		float fSCKLPeriod = 1.0 / (float)(pa_nSystemClk);
		float fTFTClockPeriod = 1.0 / (float)(TFT_CLOCK_FREQ);
		unsigned long nTimerPeriod = (unsigned long)(fTFTClockPeriod / fSCKLPeriod);
		unsigned long nTimerWidth = nTimerPeriod / 2;
		g_TFTspec.tDclkTimerHndl = timer_gp_setup (pa_cDCLKtimer, TFT_DCLK_TIMER_CONFIG, nTimerWidth, nTimerPeriod, true, pa_nSystemClk, 0);
	}

	// configure the timer for the pwm output ( max brigthness)
	float fSCKLPeriod = 1.0 / (float)(pa_nSystemClk);
	float fTFTClockPeriod = 1.0 / (float)(TFT_PWM_FREQ);
	unsigned long nTimerPeriod = (unsigned long)(fTFTClockPeriod / fSCKLPeriod);
	unsigned long nTimerWidth = nTimerPeriod;	// 100% duty cycle
	g_TFTspec.tPwmTimerHndl = timer_gp_setup (pa_cPWMtimer, TFT_PWM_TIMER_CONFIG, nTimerWidth, nTimerPeriod, true, pa_nSystemClk, 0);
			
	// configure gpio for pci pin	
	gpio_becomeOutput (pa_cPCIflag);

	// define the timer used for hsync and dtmg depending on the ppi witch the display is connected
	unsigned char cHSYNCtimer;
	unsigned char cDTMGtimer;
	if (pa_cPPI == 0) {
#if defined (__ADSPBF561__)
		cHSYNCtimer = 8;
		cDTMGtimer = 9;
#elif defined (__ADSPBF537__)
		cHSYNCtimer = 0;
		cDTMGtimer = 1;
#else
#error "processor not yet supported"
#endif
	} 
	else if (pa_cPPI == 1) {
		cHSYNCtimer = 10;
		cDTMGtimer = 11;
	} else {
		erResult = ERR_ILLEGAL_PPI;
		return erResult;
	}
	g_TFTspec.cPPI = pa_cPPI;

	
#ifdef __ADSPBF537__
	// enable the upper 8 databits of the ppi
	// because is not done by the ppi driver
	unsigned short nValue = *pPORTG_FER;
	*pPORTG_FER |= 0xff00;	// enabling PPI data signals (D8 - D15).
	*pPORTG_FER |= 0xff00;	
	nValue = *pPORT_MUX;
	*pPORT_MUX &= ~0x0e00;
	*pPORT_MUX &= ~0x0e00;
#endif	

	// setup dma and ppi
#ifdef TFT_ROTATE_FRAME

	// fill the descriptor table
	unsigned short i = 0;
	for (i=0; i<TFT_YSIZE + TFT_Y_BLANKING_LINES - 1; i++) {
		// next descriptor pointer		
		anTFTdmaDescriptorTable[2 * i] = (unsigned long)&anTFTdmaDescriptorTable[2 * i + 2];
		// next startaddres
		if (i<TFT_Y_BLANKING_LINES) {
			// blanking lines
			anTFTdmaDescriptorTable[2 * i + 1] = (unsigned long)g_TFTspec.pnFrameBuffer;			
		} else {
			// visible lines
			anTFTdmaDescriptorTable[2 * i + 1] = (unsigned long)g_TFTspec.pnFrameBuffer + 2 * (pa_nYsize + /*TFT_Y_BLANKING_LINES*/ - 1 - (i - TFT_Y_BLANKING_LINES));
		}
	}
	// last descriptor points to first
	anTFTdmaDescriptorTable[2 * (TFT_YSIZE + TFT_Y_BLANKING_LINES - 1)] = (unsigned long)&anTFTdmaDescriptorTable[0];
	anTFTdmaDescriptorTable[2 * (TFT_YSIZE + TFT_Y_BLANKING_LINES - 1) + 1] = (unsigned long)g_TFTspec.pnFrameBuffer;
	
	// setup ppi and dma
#ifndef TFT_DTMG_OVER_AND_GATE	
	erResult = ppi_setup_gp (	pa_cPPI,
								(unsigned long)g_TFTspec.pnFrameBuffer,
								0x381f,
								0,
								TFT_XSIZE - 1,
								27,
								0x7485,			// interrupt enable
								pa_nXsize,
								2 * (TFT_YSIZE/* + TFT_Y_BLANKING_LINES*/),
								0,
								0,
								(unsigned long)&anTFTdmaDescriptorTable[0],
								(T_PPI_CALLBACK)TFTppiHandler);
#else
	erResult = ppi_setup_gp (	pa_cPPI,
								(unsigned long)g_TFTspec.pnFrameBuffer,
								0x381f,
								0,
								TFT_XSIZE - 1,
								27,
								0x7405,			// interrupt disable
								pa_nXsize,
								2 * (TFT_YSIZE/* + TFT_Y_BLANKING_LINES*/),
								0,
								0,
								(unsigned long)&anTFTdmaDescriptorTable[0],
								0);
#endif

#else	// #if TFT_ROTATE_FRAME	

#ifndef TFT_DTMG_OVER_AND_GATE
	erResult = ppi_setup_gp (	pa_cPPI,
								(unsigned long)g_TFTspec.pnFrameBuffer,
								0x381f,
								0,
								TFT_XSIZE - 1,
								27,
								0x10d5,		// interrupts enable
								TFT_XSIZE,
								2,
								TFT_YSIZE + TFT_Y_BLANKING_LINES,
								2,
								0,
								(T_PPI_CALLBACK)TFTppiHandler);
#else
	erResult = ppi_setup_gp (	pa_cPPI,
								(unsigned long)(g_TFTspec.pnFrameBuffer),
								0x381f,
								0,
								TFT_XSIZE - 1,
								27,
								0x1055,		// interrupts disable
								TFT_XSIZE,
								2,
								TFT_YSIZE + TFT_Y_BLANKING_LINES,
								2,
								0,
								0);
#endif
								
#endif	//#if TFT_ROTATE_FRAME								

	if (erResult != ERR_NONE) {
		return erResult;
	}

	// setup hsync timing signal
	g_TFTspec.tHsyncTimerHndl = timer_gp_setup (cHSYNCtimer, TFT_HSYNC_TIMER_CONFIG, 5, 273, false, pa_nSystemClk, 0);
#ifdef TFT_DTMG_OVER_AND_GATE
	// setup dtmg timing signal
	g_TFTspec.tDtmgTimerHndl = timer_gp_setup (cDTMGtimer, TFT_DTMG_TIMER_CONFIG, 33, 273, false, pa_nSystemClk, 0);
	// setup help timer for vsync period in dtmg signal
	g_TFTspec.tDtmgVsyncTimerHndl = timer_gp_setup (pa_cDTMGshiftTimer, TFT_DTMG_TIMER_CONFIG, 1911, 89271, false, pa_nSystemClk, 0);
#else
	// setup dtmg timing signal
	g_TFTspec.tDtmgTimerHndl = timer_gp_setup (cDTMGtimer, TFT_DTMG_TIMER_CONFIG, 1911+33, 1911+33+240, false, pa_nSystemClk, 0);	
#endif
	
	// enable pci
	gpio_set (pa_cPCIflag);
	asm ("ssync;");

	// enable dtmg timer
	timer_enable (g_TFTspec.tDtmgTimerHndl);
#ifdef TFT_DTMG_OVER_AND_GATE
	// enable help timer for vsync period in dtmg signal
	timer_enable (g_TFTspec.tDtmgVsyncTimerHndl);
#endif	
	// enable hsync timer
	timer_enable (g_TFTspec.tHsyncTimerHndl);
	
	if (pa_bCreateDCLK) {	
		// enable 5.33 Mhz clock
		timer_enable (g_TFTspec.tDclkTimerHndl);
	}

	// wait at least one frame
	TFTmsSleep (50, pa_nCoreClk);
	
	// enable the pwm timer
	timer_enable (g_TFTspec.tPwmTimerHndl);

	return erResult;
}

unsigned long TFTgetFramebuffer (void) {
	return (unsigned long)(g_TFTspec.pnFrameBuffer);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -