📄 tftconfig.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 + -