📄 display.c
字号:
/*
SSD1783 Display Driver for Motorola LTE
----------------------------
(c) motoprogger 2008
*/
#include "../libs/motolibs.h"
#include "dmac.h"
#include "rtr.h"
word rtr_h=0;
hword rtr_l=0;
void set_duration(hword ticks)
{
rtr_l=ticks+rtr_get_lsb();
rtr_h=rtr_get_msb();
if (rtr_l&0x8000)
{
rtr_l&=0x7FFF;
rtr_h++;
}
}
bool display_check_busy(void)
{
hword curr_rtr_l;
word curr_rtr_h;
hword diff_rtr_l;
word diff_rtr_h;
curr_rtr_l=rtr_get_lsb();
curr_rtr_h=rtr_get_msb();
diff_rtr_h=rtr_h-curr_rtr_h;
diff_rtr_l=rtr_l-curr_rtr_l;
if (diff_rtr_l&0x8000)
{
diff_rtr_l&=0x7FFF;
diff_rtr_h--;
}
if (diff_rtr_h==0 && diff_rtr_l<32) return false;
return true;
}
void display_wait(void)
{
return; //debug
while(display_check_busy());
}
void display_process_pixels(hword count)
{
//ticks=count*73; //73 ticks per 65536 pixels
//ticks=ticks>>16+1;
//set_duration(ticks);
__asm {
MOV R0, count
LSL R0, R0, #1
next:
SUB R0, R0, #1
BNE next
}
}
void display_sleep(bool ifsleep)
{
display_wait();
dmac_send_cmd_no(0x94|(ifsleep!=0));
}
void display_internal_oscillator(bool ifon)
{
display_wait();
dmac_send_cmd_no(0xD0|(ifon!=0));
}
void display_set_pcr(byte boost, bool refgen, bool intreg)
{
byte data;
data=(intreg!=0)|(refgen!=0)<<1|((boost-4)&3)<<2;
display_wait();
dmac_send_cmd_one(0x20,data);
}
void display_set_biasing_ratio(byte code)
{
byte data;
data=code&7;
display_wait();
dmac_send_cmd_one(0xFB,data);
}
void display_select_pwm_frc(byte frcbits)
{
byte data;
data=1^((frcbits>>1)^frcbits)&1|0x0E|(frcbits&2)<<5;
display_wait();
dmac_send_cmd_three(0xF7, 0x28, data, 0x05);
}
void display_set_termcomp(byte code)
{
byte data;
data=code&3;
display_wait();
dmac_send_cmd_one(0x82,data);
}
void display_set_com_scan(byte code)
{
byte data;
data=code&7;
display_wait();
dmac_send_cmd_one(0xBB, data);
}
void display_set_dataout_scan(byte p1, byte p2, byte p3)
{
display_wait();
dmac_send_cmd_three(0xBC,p1&7, p2&7, p3&0x1F);
}
void display_set_workarea(byte x1,byte y1,byte x2,byte y2)
{
display_wait();
dmac_send_cmd_two(0x75, y1, y2); //Set page address
dmac_send_cmd_two(0x15, x1, x2); //Set column address; maybe mixed?
}
void display_set_freq_nline(byte freqcode, byte nline)
{
display_wait();
dmac_send_cmd_two(0xF2, freqcode&0x6, nline&0x7f);
}
void display_set_contrast_regratio(byte contrast, byte ratiocode)
{
display_wait();
dmac_send_cmd_two(0x81,contrast&0x3f, ratiocode&7);
}
void display_set_inverse(bool isinverse)
{
byte cmd;
display_wait();
if (isinverse) cmd=0xA7;
else cmd=0xA6;
dmac_send_cmd_no(cmd);
}
void display_lcd_on(bool ison)
{
byte cmd;
display_wait();
if (ison) cmd=0xAF;
else cmd=0xAE;
dmac_send_cmd_no(cmd);
}
void display_set_fill_mode(bool fill)
{
display_wait();
dmac_send_cmd_one(0x92, fill);
}
void display_put_coords(byte x1, byte y1, byte x2, byte y2, byte * buff)
{
byte t;
if (x1>x2)
{
t=x1;
x1=x2;
x2=t;
}
if (y1>y2)
{
t=y1;
y1=y2;
y2=t;
}
buff[0]=x1;
buff[1]=y1;
buff[2]=x2;
buff[3]=y2;
}
void display_put_color(hword color, byte * buff)
{
buff[0]=(byte)(color>>8);
buff[1]=(byte)(color&0xFF);
}
void display_draw_line(byte x1, byte y1, byte x2, byte y2, hword color)
{
byte buff[6];
byte count;
byte dx;
byte dy;
display_put_coords(x1,y1,x2,y2,buff);
dx=buff[2]-buff[0]+1;
dy=buff[3]-buff[1]+1;
if (dx>dy) count=dx;
else count=dy;
display_put_color(color,buff+4);
*((word *) (buff+4))=color;
display_wait();
dmac_send_cmd_long(0x83,buff,6);
display_process_pixels(count);
}
void display_rectangle(byte x1, byte y1, byte x2, byte y2, hword brdcolor, hword fillcolor)
{
byte buff[8];
hword count;
byte dx;
byte dy;
display_put_coords(x1,y1,x2,y2,buff);
dx=buff[2]-buff[0]+1;
dy=buff[3]-buff[1]+1;
count=dx*dy;
display_put_color(brdcolor, buff+4);
display_put_color(fillcolor, buff+6);
display_wait();
dmac_send_cmd_long(0x84,buff,8);
display_process_pixels(count); //Doesn't work yet
dmac_wait();
}
void display_circle(byte x, byte y, byte r, hword brdcolor, hword fillcolor)
{
byte buff[5];
hword count;
buff[0]=x;
buff[1]=y;
buff[2]=r;
display_put_color(brdcolor, buff+3);
display_put_color(fillcolor, buff+5);
count=0xC910*r*r>>16;
display_wait();
dmac_send_cmd_long(0x86,buff,5);
display_process_pixels(count);
}
void display_copy(byte x1, byte y1, byte x2, byte y2, byte x3, byte y3)
{
byte buff[8];
hword count;
byte dx;
byte dy;
display_put_coords(x1,y1,x2,y2,buff);
dx=buff[2]-buff[0]+1;
dy=buff[3]-buff[1]+1;
count=dx*dy*2;
buff[4]=x3;
buff[5]=y3;
display_wait();
dmac_send_cmd_long(0x8A,buff,6);
dmac_wait();
display_process_pixels(count);
}
void display_put_image(byte x1, byte y1, byte x2, byte y2, byte * image)
{
byte buff[4];
hword count;
byte dx;
byte dy;
display_put_coords(x1,y1,x2,y2,buff);
dx=buff[2]-buff[0]+1;
dy=buff[3]-buff[1]+1;
//display_wait();
display_set_workarea(buff[0], buff[1], buff[2], buff[3]);
count=dx*dy*2;
dmac_send_cmd_long(0x5C,image,count);
display_process_pixels(count>>2);
dmac_wait();
}
void display_config_dmac(void)
{
dmac_config(0x4, 0x20, 0x1); //serial transfer, CS active low, transfer on falling egde, clock 52/0x80*0x20, data: RS=1
}
void display_init(void)
{
display_config_dmac();
display_sleep(false);
display_internal_oscillator(true);
display_set_pcr(6,true,true);
display_set_biasing_ratio(0x2); //bias 1/9
display_select_pwm_frc(0x2); //boost 6x, reference voltage generator on, internal regulator and voltage follower on
display_set_termcomp(0x0); //-0.1 %/degree
display_set_com_scan(0x1); //COM0->COM79 COM159<-COM80
display_set_dataout_scan(0,0,4);
display_set_dataout_scan(2,1,4);
display_set_workarea(0x1, 0x1, 0x80, 0x80);
display_set_freq_nline(0x5, 0x46); //63Hz, 70 lines
display_set_contrast_regratio(0x18,0x6); //contrast 0x18, regulator gain 12.24
display_set_inverse(true);
display_lcd_on(true);
display_set_fill_mode(true);
display_set_workarea(0x1, 0x1, 0x80, 0x80);
display_rectangle(0x0,0x0,0x81,0x81,0,0);
}
void display_shutdown(void)
{
display_wait();
display_lcd_on(false);
display_set_pcr(0,false,false);
display_internal_oscillator(false);
display_sleep(true);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -