Imrich Konkol / Mbed 2 deprecated lcd_tft_ssd2119

Dependencies:   EthernetNetIf mbed

Display.c

Committer:
ikon
Date:
2011-02-27
Revision:
2:456410210d03

File content as of revision 2:456410210d03:

// Display oriented routines in mBed Retro Picture Frame
#include "mbed.h"
#include "Display.h"
#include "Fonts.h"

SPI spi(p5, p6, p7);    // mosi, miso, sclk
DigitalOut DCS(p8);     // Display chip select
DigitalOut DRS(p15);    // Display reset
DigitalOut DCD(p16);    // Display command/data
DigitalOut DRD(p17);   // Display read
DigitalOut DWR(p18);   // Display write

//static uint16_t xx,yy;
//static uint16_t BACKGROUND, FOREGROUND;

// Global 256 colour palette arraysc
uint16_t palette256[256];

static uint16_t yy=0;
static uint16_t xx=0;

uint16_t BACKGROUND = WHITE;
uint16_t FOREGROUND = BLACK;


#define    HRES      320     // X axis # of pixels
#define    VRES      240     // Y axis # of pixels

// Essential display commands
/*************************************************/
void write_command(uint16_t command) {
    uint8_t raw;

    DRD = 1;
    DCS = 0;
    DCD = 0;

    raw = command;
    //raw &= 0x00FF;      // Keep bit9 low - means command
    //printf("Raw data: %d\n",raw);
    spi.write(raw);

    DWR = 1;
    DCS = 1;
}

/*************************************************/

//typedef unsigned char u8;
//typedef unsigned int u16;
void write_data(uint16_t value) {
    uint8_t raw;

    DRD = 1;
    DCD = 1;
    DCS = 0;

    raw = (value)>>8;
    // raw &= 0x00FF;      // Keep bit9 high - means data
    // raw |= 0x0100;
    // printf("Raw data: %d\n",raw);
    spi.write(raw);

    DCS = 1;
    //wait_ms(1);
    DCS = 0;

    raw = value;
    // raw &= 0x00FF;      // Keep bit9 high - means data
    // raw |= 0x0100;
    // printf("Raw data: %d\n",raw);
    spi.write(raw);

    DCS = 1;
}









// Set X & Y axis of next pixel write
void LcdSetPenXY(uint16_t x, uint16_t y) {
    write_command(0x004F);    // RAM address set for Y axis
    write_data(y);            // Page 58 of SSD2119 datasheet
    write_command(0x004E);    // RAM address set for X axis
    write_data(x);            // Page 58 of SSD2119 datasheet
    write_command(0x0022);    // Return back to pixel write mode
}


/*-----------------------------------------------------------------------------
  Name         :  LcdGotoXY
  Description  :  Sets cursor location to xy location corresponding to basic
                  font size.
  Argument(s)  :  x, y -> Coordinate for new cursor position. Range: 0,0..VRES/6,HRES/8
  Return value :  None.
-----------------------------------------------------------------------------*/
void LcdGotoXY ( uint8_t x, uint8_t y ) {
    // uint16_t xx, yy;
    xx = y * 8;
    yy = x * 6;
    //LcdCacheIdx = (x - 1) * HRES + (y - 1) * VRES;
    LcdSetPenXY(xx,yy);
}

/*-----------------------------------------------------------------------------
  Name         :  LcdGotoXY8
  Description  :  Sets cursor location to xy location corresponding to basic
                  font size 8x8 pixels (same as above but adjusted for S font).
  Argument(s)  :  x, y -> Coordinate for new cursor position. Range: 0,0..HRES/8,VRES/8
  Return value :  None.
-----------------------------------------------------------------------------*/
void LcdGotoXY8 ( uint8_t x, uint8_t y ) {
    // uint16_t xx, yy;
    xx = (HRES - 1) - ((x+1) * 8);
    yy = y * 8;
    //LcdCacheIdx = (x - 1) * HRES + (y - 1) * VRES;
    LcdSetPenXY(xx,yy);
}

typedef enum {
    FONT_1X = 1,
    FONT_2X = 2

} LcdFontSize;

typedef enum {
    PIXEL_OFF =  0,
    PIXEL_ON  =  1,
    PIXEL_XOR =  2

} LcdPixelMode;


// Added for horizontal print
void LcdChr8x8 ( uint8_t ch) {
    
    uint8_t i,j,c;
    
    if ( (ch < 0x20) || (ch > 0x7F) ) {
        //  Convert to a printable character.
        ch = 0x80;
    }
    
    for(i=0;i<8;i++) {
        c = Font8x8[8*(ch-32)+i];
    
        for ( j = 0; j < 8; j++ ) {
            if ( (c & 0x01) == 0x01 ) {
                write_data(FOREGROUND);
            } else {
                write_data(BACKGROUND);
            }
            c >>= 1;
        }
        yy++;
        write_command(0x004F);    // RAM address set for Y axis
        write_data(yy);       // Page 58 of SSD2119 datasheet
        write_command(0x0022);
     }
     yy-=8;
     xx-=8;
     LcdSetPenXY(xx,yy);
}

// Print 8*8 charset string
void LcdStr8x8 (  char *dataPtr ) {
    while ( *dataPtr ) {
        LcdChr8x8( *dataPtr++ );
    }
}

/*-----------------------------------------------------------------------------
  Name         :  LcdChr
  Description  :  Displays a character at current cursor location
                  and increment cursor location.
  Argument(s)  :  size -> Font size. See enum.
                  ch   -> Character to write.
  Return value :  None.
-----------------------------------------------------------------------------*/
void LcdChr (  uint8_t ch ) {
    uint8_t i, j, c;

    if ( (ch < 0x20) || (ch > 0x7F) ) {
        //  Convert to a printable character.
        ch = 0x80;
    }

    //write_command(0x0022);

    for ( i = 0; i < 6; i++ ) {
        if (i < 5) {
            c = FontLookup[ch - 32][i];
        } else {
            c = 0x00;                   // Space after each character
        }

        for ( j = 0; j < 8; j++ ) {
            if ( (c & 0x01) == 0x01 ) {
                //printf("X");
                write_data(FOREGROUND);
            } else {
                //printf(".");
                write_data(BACKGROUND);
            }
            //printf("\n");
            c >>= 1;
        }
        yy++;
        write_command(0x004F);    // RAM address set for Y axis
        write_data(yy);       // Page 58 of SSD2119 datasheet
        write_command(0x0022);
    }
}


/*-----------------------------------------------------------------------------
  Name         :  LcdStr
  Description  :  Displays a character at current cursor location and increment
                  cursor location according to font size.
  Argument(s)  :  size    -> Font size. See enum.
                  dataPtr -> Pointer to null terminated ASCII string to display.
  Return value :  None.
-----------------------------------------------------------------------------*/
void LcdStr (  char *dataPtr ) {
    while ( *dataPtr ) {
        LcdChr( *dataPtr++ );
    }
}


/*************************************************/
void initialization() {

    // Setup the spi for 8 bit data, high steady state clock,
    // second edge capture, with a 10 MHz clock rate
    spi.format(8,3);         // CPOL=1, CPHA=1
    spi.frequency(10000000); // SPI fastest possible
    /*
        SET_RD;
        SET_WR;
        SET_CS;
        SET_CD;
        PORTA=0x00;
        PORTE=0x00;

        CLR_RESET;
        delay(200);
        SET_RESET;
        delay(500);
    */
    DRD = 1;
    DWR = 1;
    DCS = 1;
    DCD = 1;

    DRS = 0;
    wait_ms(200);
    DRS = 1;
    wait_ms(500);

    write_command(0x0028);    // VCOM OTP
    write_data(0x0006);       // Page 55-56 of SSD2119 datasheet

    write_command(0x0000);    // start Oscillator
    write_data(0x0001);       // Page 36 of SSD2119 datasheet

    write_command(0x0010);    // Sleep mode
    write_data(0x0000);       // Page 49 of SSD2119 datasheet

    write_command(0x0001);    // Driver Output Control
    write_data(0x32EF);       // Page 36-39 of SSD2119 datasheet

    write_command(0x0002);    // LCD Driving Waveform Control
    write_data(0x0600);       // Page 40-42 of SSD2119 datasheet

    write_command(0x0003);    // Power Control 1
    write_data(0x6A38);       // Page 43-44 of SSD2119 datasheet

    write_command(0x0011);    // Entry Mode
    write_data(0x6870);       // Page 50-52 of SSD2119 datasheet

    write_command(0x000F);    // Gate Scan Position
    write_data(0x0000);       // Page 49 of SSD2119 datasheet

    write_command(0x000B);    // Frame Cycle Control
    write_data(0x5308);       // Page 45 of SSD2119 datasheet

    write_command(0x000C);    // Power Control 2
    write_data(0x0003);       // Page 47 of SSD2119 datasheet

    write_command(0x000D);    // Power Control 3
    write_data(0x000A);       // Page 48 of SSD2119 datasheet

    write_command(0x000E);    // Power Control 4
    write_data(0x2E00);       // Page 48 of SSD2119 datasheet

    write_command(0x001E);    // Power Control 5
    write_data(0x00BE);       // Page 53 of SSD2119 datasheet

    write_command(0x0025);    // Frame Frequency Control
    write_data(0x8000);       // Page 53 of SSD2119 datasheet

    write_command(0x0026);    // Analog setting
    write_data(0x7800);       // Page 54 of SSD2119 datasheet

    write_command(0x004E);    // Ram Address Set
    write_data(0x0000);       // Page 58 of SSD2119 datasheet

    write_command(0x004F);    // Ram Address Set
    write_data(0x0000);       // Page 58 of SSD2119 datasheet

    write_command(0x0012);    // Sleep mode
    write_data(0x08D9);       // Page 49 of SSD2119 datasheet

    // Gamma Control (R30h to R3Bh) -- Page 56 of SSD2119 datasheet
    write_command(0x0030);
    write_data(0x0000);

    write_command(0x0031);
    write_data(0x0104);

    write_command(0x0032);
    write_data(0x0100);

    write_command(0x0033);
    write_data(0x0305);

    write_command(0x0034);
    write_data(0x0505);

    write_command(0x0035);
    write_data(0x0305);

    write_command(0x0036);
    write_data(0x0707);

    write_command(0x0037);
    write_data(0x0300);

    write_command(0x003A);
    write_data(0x1200);

    write_command(0x003B);
    write_data(0x0800);

    write_command(0x0007);    // Display Control
    write_data(0x0033);       // Page 45 of SSD2119 datasheet

    wait_ms(150);

    write_command(0x0022);    // RAM data write/read
}

/*************************************************/
void Display_Home() {
    xx = 0;
    yy = 0;
    write_command(0x004E);    // RAM address set
    write_data(0x0000);       // Page 58 of SSD2119 datasheet
    write_command(0x004F);    // RAM address set
    write_data(0x0000);       // Page 58 of SSD2119 datasheet

    write_command(0x0044);    // Vertical RAM address position
    write_data(0xEF00);       // Page 57 of SSD2119 datasheet
    write_command(0x0045);    // Horizontal RAM address position
    write_data(0x0000);       // Page 57 of SSD2119 datasheet
    write_command(0x0046);    // Horizontal RAM address position
    write_data(0x013F);       // Page 57 of SSD2119 datasheet

    write_command(0x0022);    // RAM data write/read
}


void display_rgb(unsigned int data) {
    unsigned int i,j;
    Display_Home();
    for (i=0;i<HRES;i++) {
        for (j=0;j<VRES;j++) {
            write_data(data);
        }
    }
}

void LCD_test() {
    //uint16_t i;
    unsigned int i,j;
    //bool b;
    Display_Home();

    printf("Disp home done.\n");
    for (i=0; i<HRES;i++) {
        //b = 0;
        for (j=0;j<VRES;j++) {

            /*
            if (j < (VRES/2)) {
                b = 0;
            } else {
                b = 1;
            }
            */
            //if (j == 120) b=1;
            //b=1;
            if (i>279)write_data(BLACK);
            else if (i>259) write_data(BLUE);    //{ if (b) { write_data(BLUE); } else { write_data(HBLUE); } }
            else if (i>239) write_data(HBLUE);
            else if (i>219) write_data(RED);     //{ if (b) { write_data(RED); } else { write_data(HRED); } }
            else if (i>199) write_data(HRED);
            else if (i>179) write_data(MAGENTA); //{ if (b) { write_data(MAGENTA); } else { write_data(HMAGENTA); } }
            else if (i>159) write_data(HMAGENTA);
            else if (i>139) write_data(GREEN);   //{ if (b) { write_data(GREEN); } else { write_data(HGREEN); } }
            else if (i>119) write_data(HGREEN);
            else if (i>99)  write_data(CYAN);    //{ if (b) { write_data(CYAN); } else { write_data(HCYAN); } }
            else if (i>79)  write_data(HCYAN);
            else if (i>59)  write_data(YELLOW);  //{ if (b) { write_data(YELLOW); } else { write_data(HYELLOW); } }
            else if (i>39)  write_data(HYELLOW);
            else if (i>19)  write_data(WHITE);
            else write_data(HWHITE);             //{ if (b) { write_data(WHITE); } else { write_data(HWHITE); } }
        }
        //printf("Col = %d\n",i);
    }
}

void cls() {
    // write_command(0x22);
    display_rgb(WHITE);
}

// Show Spectrum screen on the display
unsigned char scr2lcd(char *scrfile) {
    unsigned char a,ink,pap,pal;
    uint16_t in=0,pa=7;
    int c;
    bool std=1;
    unsigned int x,y,i,j,k,l,m;
    unsigned char screen[6976];
    uint16_t palette64[64];
    char fullpath[30];

    strcpy(fullpath,"/local/");
    strcat(fullpath,scrfile);

    printf("Opening File %s...\r\n",fullpath); // Drive should be marked as removed
    FILE *fp = fopen(fullpath, "r");
    if (!fp) {
        printf("File %s could not be opened!\r\n",scrfile);
        return(1);
    }

    //cls();        // Keep border, do not cls
    Display_Home();
    x=START_X;
    y=START_Y;
    LcdSetPenXY(x,y);

    write_command(0x22);

    i=0;
    while (  ( ( c = fgetc(fp) ) != EOF ) && (i<6976) ) {
        screen[i] = c;
        i++;
    }
    
    // Non-stanard screen
    if (i != 6912) { 
        
        printf("ULAplus or other format.\n");
        // ULAplus screen
        std=0;
        
        for(i=0;i<64;i++) {
            palette64[i] = palette256[screen[6912+i]];
        }
    } else 
        std = 1;
    
    fclose(fp);
    printf("Screen read done.\n");

    for (j=0;j<3;j++) {              // Screen "third"
        for (i=0;i<8;i++) {          // Line in third
            for (k=0;k<8;k++) {      // Microline
                for (l=32;l>0;l--) { // Byte
                    c = screen[j * 2048 + k * 256 + i * 32 + (l-1)];        // Pixel byte 
                    a = screen[6144 + j * 256 + i * 32 + (l-1)];            // Attr byte
                    if (std) {                                              // Handle attributes as ULA
                        ink = a & 0x07;
                        pap = ( a >> 3 ) & 0x07;
                        if ( (a & 0x40) == 0x40 ) {  // Bright1 - not for black (0)
                            if ( ink != 0 ) ink += 7;
                            if ( pap != 0 ) pap += 7;
                        }
                    } else {                                                // Otherwise treat as ULA+
                        pal = a >> 6;                                       // Palette suffix
                        ink = a & 0x07;
                        pap = ( a >> 3 ) & 0x07;
                        in = palette64[pal*16+ink];
                        pa = palette64[pal*16+8+pap]; 
                    } 
                    
                    for (m=0;m<8;m++) {                                     // Pixel

                        if ( (c & 0x01) == 0x01 ) {
                            if (std) 
                                write_data(colors[ink]);
                            else
                                write_data(in);
                        } else {
                            if (std) 
                                write_data(colors[pap]);
                            else
                                write_data(pa);
                        }
                        c >>= 1;
                    }
                }
                y++;
                x=START_X;
                LcdSetPenXY(x,y);

            }
        }
    }


    return(0);
}

// List files on internal filesystem
void Dir() {
    unsigned int i=0, y=2;
    char str[40];

    DIR *d = opendir("/local");               // Opens the root directory of the local file system
    struct dirent *p;
    while ((p = readdir(d)) != NULL) {        // Print the names of the files in the local file system
        //sprintf(str, "%s\n", p->d_name);        // to stdout.
        LcdStr(p->d_name);
        // LcdStr(p->filesize);
        y++;
        LcdGotoXY(0,y);
        if ( strstr(p->d_name,".SCR") != NULL) {
            i++;
        }
    }
    closedir(d);
    sprintf(str, "%d SCR files found!",i);
    LcdStr(str);
}

// Slideshow - show all SCR files from mbed FS
void SldShw() {
    DIR *d = opendir("/local");               // Opens the root directory of the local file system
    struct dirent *p;
    while ((p = readdir(d)) != NULL) {        // Print the names of the files in the local file system
        if ( strstr(p->d_name,".SCR") != NULL) {
            scr2lcd(p->d_name);                   // Display SCR files from listing
            wait(3.0);
        }
    }
    closedir(d);
}

// Show 256 color palette on the display
void ShowPalette256() {
    uint16_t r,g,b,x,y,c;
    uint16_t dr,dg,db,d;                 // Display data

    cls();
//    LcdSetPenXY(0,0);

    for (r=0;r<8;r++) {
        dr = r*36;
        dr <<= 8;
        dr &= 0xF800;
        for (g=0;g<8;g++) {
            dg = g*36;
            dg <<= 3;
            dg &= 0x07E0;

            for (b=0;b<4;b++) {
                // Color calculation
                db = b*85;
                db >>= 3;
                db &= 0x001F;

                d = dr | dg | db;

                // printf("%d\n",d);    // Debug palette print
                c = 32*g + 4*r + b;
                palette256[c] = d;
                
                for (y=0;y<8;y++) {
                    LcdSetPenXY(248-(8*(r*4+b)), (8*g)+y);
                    write_command(0x22);

                    for (x=0;x<8;x++) {
                        write_data(d);
                    } // endfor x

                } // endfor y
                
            } // endfor b
        } // endfor g
    } // endfor b

} // end function ShowPalette

// Terminal emulator