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