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

📄 tft_lcd.c

📁 tft显示驱动程序
💻 C
字号:
/**************************************
TFT_LCD--FG050605DNCWAG01
(320 x R,G,B x 234) dot
16 bits per dot             --RGB 565
Pixel clock Frequency(Tclk) --6.25MHZ
Vertical period(Tvp)        --259 Thp
Vertical sync. pulse width  --3 Thp
Horizontal period(Thp)      --408 Tclk
Horizontal sync. pulse width--5 Tclk
**************************************/

#include <cdefBf531.h>
#include <ccblkfn.h>
#include <sys/exception.h>
#include "MyProcess.h"
#include "Scope.h"
#include "screen.h"
#include "menu.h"
#include "KeyCode.h"
#include "SecondRev.h"
#include "Cbasic.h"
#include "tft_lcd.h"
#include "cursor.h"

#define DESCRIPTOR_SIZE 3
#define NUM_BUFFERS 2

/*****************DMA***************/
#define XCNT 640//Inner loop count for 2D DMA
#define XMOD 2 //because X_MODIFY is specified in bytes
#define YCNT 525//outer loop count for 2D DMA
#define YMOD 2

#define DMA0_FLOW   (0x6000)
#define DMA0_NDSIZE (0x0300)

//显示缓冲区设定
#define FRAME_SIZE 			640*525*2
#define PADOFSTART			2*640*2
#define FRAME_BUF1			(FrameBufferAddr[0]+PADOFSTART)
#define FRAME_BUF2			(FrameBufferAddr[1]+PADOFSTART)
#define Frame1BufferAddr	FrameBufferAddr[0]
#define Frame2BufferAddr	FrameBufferAddr[1]
#pragma section("FrameBuffer", RUNTIME_INIT)
char FrameBufferAddr[2][FRAME_SIZE]={
    {
        [PADOFSTART]
        #include "PictureE.h"
    }
};

//内核定时器
#define HZ 1000
#define MAXTMNUM 10
static struct {
    unsigned long jiffies;
    void (*TimerHandler)(void); 
    unsigned short status;
} CoreTimer[MAXTMNUM];

//屏幕刷新
static struct {
    unsigned long jiffies;
    bool bSwitch;
	bool bOver;
	short bFlushFlag;
} FlushTFT={0, true, false, 3};

static void DelayAcqHandler(void);
static void FieldPeriodHandler(void);
static void ParameterHandler(void);
static void AutoCursorHandler(void);

inline static void StartFlush(void);
inline static void StopFlush(void);
inline static void WtFlushOver(void);

EX_INTERRUPT_HANDLER(Uart_ISR);
EX_INTERRUPT_HANDLER(ScanTrig);
EX_INTERRUPT_HANDLER(PPI_TxIsr);
EX_INTERRUPT_HANDLER(Core_ISR);
/////////////////////////中断函数////////////////////////////
EX_INTERRUPT_HANDLER(Core_ISR)
{
unsigned short i;

    ++CoreTimer[CORETM].jiffies;
    
    for (i=0; i<MAXTMNUM; i++)
    {
        if (CoreTimer[i].status==ST_ENABLE && CoreTimer[CORETM].jiffies > CoreTimer[i].jiffies)
    	    (*CoreTimer[i].TimerHandler)();
   	}
    		
    i=*pTCNTL;
    *pTCNTL=i | 0x04;
    ssync();
}

EX_INTERRUPT_HANDLER(PPI_TxIsr)
{	
	FlushTFT.bOver=false;
	FlushTFT.jiffies=GetTimer(CORETM);
	if (GetTimer(FIELDTM)==0)
		SetTimerStatus(FIELDTM, ST_ENABLE);
	else
		SetTimerStatus(FIELDTM, ST_OVER);
	*pDMA0_IRQ_STATUS |= DMA_DONE;	
	ssync();
}

EX_INTERRUPT_HANDLER(ScanTrig)
{
    //iTrigFlag=1;
    if (ISSCANLEV)
    	if (iProcFlag==PROC_READY)
    	{
    		iProcFlag=PROC_TRIGED;
    		
    	}
   SCANNTRI=0;	 
}  

EX_INTERRUPT_HANDLER(Uart_ISR)
{
	kscan2=*pUART_RBR;
	step2=1;
	
	//键盘加速处理
	if (kscan2>0x40 && kscan2<0xff)
	{
		kscan2&=0x3f;
		step2=10;
	}
	
	if (ISMENU(CALI_MENU) && (kscan2==KC_UP || kscan2==KC_DOWN || kscan2==KC_LEFT || kscan2==KC_RIGHT))
	{
		kscan2=kscan2 | 0x0100;
		if (step2!=1) step2=10;
	}
	
	//KEYCODE FILTER
    /*
    if (ISXY) 
    {
        if (kscan2==KC_MATH || kscan2==KC_SAVE || kscan2==KC_TRIGGER || kscan2==KC_HORIZON || kscan2==KC_MEASURE || kscan2==KC_CURSOR)  kscan2=0;
    }
    */
}


/////////////////////////初始化DMA0////////////////////////////
void Init_DMA(void)
{
    *pDMA0_X_COUNT = XCNT;
	*pDMA0_X_MODIFY = XMOD;
	
	*pDMA0_Y_COUNT = YCNT;		
	*pDMA0_Y_MODIFY = YMOD;
	
	*pDMA0_START_ADDR=(void *)(Frame1BufferAddr);
	
	*pDMA0_CONFIG=0x1094;
	ssync();

}

/////////////////////////初始化定时器TIMER1 TIMER2/////////////
void Init_Timers(void)
{
int config_word;

	//Timer1 and Timer2 config
	//TOGGLE_HI=0--The effective state of PULSE_HI is the programmed state
	//use PPI_CLK to clock counter|Enable pad in PWM_OUT mode|Count to end of period|
	//Negative action pulse|PWMOUT mode

	config_word=EMU_RUN|CLK_SEL|TIN_SEL|PERIOD_CNT|PWM_OUT;
	//config_word=CLK_SEL|TIN_SEL|PERIOD_CNT|PWM_OUT;
	
	//HSYNC
	*pTIMER1_CONFIG=config_word;
	*pTIMER1_PERIOD=800;
	*pTIMER1_WIDTH=96;

	//VSYNC
	*pTIMER2_CONFIG=config_word;
	*pTIMER2_PERIOD=525*800;
	*pTIMER2_WIDTH=2*800;

}
/////////////////////////初始化PPI/////////////////////////
void Init_PPI(void)
{
    
	//PPI config
	//PPI_FS1 and PPI_FS2 are treated as falling edge asserted
	//PPI samples data on falling edge and drives data on rising edge of PPI_CLK
	//16 bit|transmit mode(output)|2 frame syncs//
	*pPPI_CONTROL=0xf91e;
	
	//delay after asserting VS before starting to read out data//
	*pPPI_DELAY=96+40-1;
	
	//the data transfered in one line//
	*pPPI_COUNT=639; 
	
	StartFlush();
}
/////////////////////////初始化UART/////////////////////////
void InitUart(void)
{
	ssync();
	*pUART_LCR=0x83;
	//band rate=sclk/(16*Divider)
	*pUART_DLL=0xc4;
	*pUART_DLH=0x06;
	*pUART_LCR=0x03;
	*pUART_IER=0x01;
	*pUART_GCTL=0x01;
}
/////////////////////////初始化Interrupt/////////////////////////
void InitInterrupt(void)
{
	//Enable the SIC interrupt
	SCANNTRI=0;
	ssync();	
	if ((*pIMASK & 0x01000)==0)
		*pILAT=0x01000;
	*pSIC_IMASK=0x00084100;//PF1
	
	//pSIC_IMASK=0x00000100;//DMA
	//Install the handler in IMASK
	register_handler(ik_ivg12, ScanTrig);
	register_handler(ik_ivg8, PPI_TxIsr);
	register_handler(ik_ivg10, Uart_ISR);
	register_handler(ik_timer, Core_ISR);
}
/////////////////////////初始化PF/////////////////////////
void InitFlag(void)
{
	*pFIO_DIR=0xffff;

}
/////////////////////////初始化CoreTimer/////////////////////////
void InitCoreT(void)
{
unsigned short i;
    
    for (i=0; i<MAXTMNUM; i++)
    {
        CoreTimer[i].jiffies=0;
        CoreTimer[i].TimerHandler=NULL;
        CoreTimer[i].status=ST_DISABLE;
    }
        
    SetTimerStatus(CORETM, ST_ENABLE);
    
    AddTimer(DELAYACQTM, 50, DelayAcqHandler, ST_ENABLE);
    AddTimer(FIELDTM, 0, FieldPeriodHandler, ST_DISABLE);
	AddTimer(PARATM, 1000, ParameterHandler, ST_ENABLE);
	AddTimer(AUTOCURTM, 1000, AutoCursorHandler, ST_ENABLE);
    //time=2.5ns*(scale+1)*count
    *pTSCALE=0x00ff;
    *pTPERIOD=1563;
    *pTCOUNT=1563;
    *pTCNTL=0x01;
    Delay();
    ssync();
    *pTCNTL=0x0f;
    
}
//设置定时
void AddTimer(unsigned short i, unsigned long ms, void (*pHandler)(void), unsigned short enable)
{
	CoreTimer[i].jiffies=CoreTimer[CORETM].jiffies+ms*HZ/1000;
	CoreTimer[i].TimerHandler=pHandler;
	CoreTimer[i].status=enable;
}
//设置定时状态  
void SetTimerStatus(unsigned short i, unsigned short st)
{
    CoreTimer[i].status=st;
} 

//获取定时时间
unsigned long GetTimer(unsigned short i)
{
    return CoreTimer[i].jiffies;
}
//设置定时时间
void SetTimer(unsigned short i, unsigned long ms)
{
    CoreTimer[i].jiffies=CoreTimer[CORETM].jiffies+ms*HZ/1000;
}
//时间到?
unsigned short TimeIsOver(unsigned short i)
{
    return CoreTimer[i].status==ST_OVER;
}

//延迟采集
static void DelayAcqHandler(void)
{
    ReSample();
    CoreTimer[DELAYACQTM].status=ST_OVER;
}

//屏幕场信号周期
static void FieldPeriodHandler(void)
{
    ++CoreTimer[FIELDTM].jiffies;
}
  
//参数刷新速率
static void ParameterHandler(void)
{
    CoreTimer[PARATM].status=ST_OVER;
} 

//自动光标刷新速率
static void AutoCursorHandler(void)
{
    CoreTimer[AUTOCURTM].status=ST_OVER;
} 

//暂停屏幕刷新
inline static void StopFlush(void)
{
	//Disable Timer 	
	*pTIMER_ENABLE = 0;
	ssync();
	
	//Disable PPI.
	*pPPI_CONTROL &= ~1;
	ssync();
	//Disable DMA0
	*pDMA0_CONFIG &= ~1;
	ssync();
}

//屏幕刷新使能
inline static void StartFlush(void)
{
	if (FlushTFT.bSwitch==true)	
	{
		*pDMA0_START_ADDR=(void *)(Frame1BufferAddr);
	}

	else 
	{
	    *pDMA0_START_ADDR=(void *)(Frame2BufferAddr);
	}
	ssync();

	//Enable DMA0
	*pDMA0_CONFIG |= 1;
	ssync();

	//Enable PPI
	*pPPI_CONTROL |= 1;
	ssync();

	//Enable Timer 	
	*pTIMER_ENABLE = TIMEN1 | TIMEN2;
	ssync();
	
	FlushTFT.bSwitch ^= true;
	FlushTFT.bFlushFlag--;
}

//等待当前屏幕刷新完成
#pragma optimize_off
inline static void WtFlushOver(void)
{
	FlushTFT.bOver=true;	
	while (FlushTFT.bOver==true);
}

void Flush(void)
{
    if (FlushTFT.bFlushFlag)
	{
	    unsigned int temp;
	    
		
		//切换显示屏幕区
		WtFlushOver();
		temp=cli();
		StopFlush();
		StartFlush();
		sti(temp);
	}
}

long GetFrameAddr(void)
{
    return  (long)(FlushTFT.bSwitch ? FRAME_BUF1 : FRAME_BUF2);
}

void SetCoherent(short x)
{
    if (FlushTFT.bFlushFlag<x)
    	FlushTFT.bFlushFlag=x;
}

short GetCoherent(void)
{
    return FlushTFT.bFlushFlag;
}

⌨️ 快捷键说明

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