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

📄 display.c

📁 A few drivers for the Motorola C380 s celluar phone hardware with a simple test application. It s co
💻 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 + -