Dan Allegre / oled_graphic

Dependencies:   mbed

main.cpp

Committer:
dallegre
Date:
2015-06-22
Revision:
2:b558c2d645b2
Parent:
1:414748809a35
Child:
3:ffbd1961115d

File content as of revision 2:b558c2d645b2:

#include "mbed.h"
#include "ssd1306.h"
#include "FontPack.h"
#include "icons.h"
#include "CourierNew5x7.h"
#include "CourierNew_14x15.h"   //whatever.
 
DigitalOut dc(D9);      //D/C
DigitalOut rs(D8);      //RES (keep high)
DigitalOut cs(D7);      //CS  (active low)

SPI spi(SPI_MOSI,SPI_MISO,SPI_SCK);             //spi1 is the i2s
SPI spi2(PB_15,PB_14,PB_13);                    //spi2 is the display
 
int main() {
    
    spi2.frequency(8e6);                         //8MHz spi22.  This is fast enough for 88KHz 16 bit sampling.
    spi2.format(8,0);                            //16 bit.  clock polarity 0, phase 0.
    wait(.1);
    
    rs.write(1);
    wait(.1);
    
    SSD1306Init();
    clearScreen();
    
    while(1) {
        wait(.1);
        clearScreen();
        imageDraw(aphex7, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex5, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex4, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex3, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex2, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex2, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex3, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex4, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex5, 2, 40);
        wait(.1);
        clearScreen();
        imageDraw(aphex6, 2, 40);
        //wait(.1);
        //clearScreen();
        //imageDraw(aphex7, 2, 40);

    }
    
    //circleDraw(20,40,10);
    //circleDraw(40,20,30);
    //stringDraw(2, 40, "D A N");
    //stringDraw(4, 40, "mad scientist");
}






//bunch of shit below..

char SSD1306_init[] = {
        SSD1306_DISPLAYOFF,
        SSD1306_SETLOWCOLUMN,
        SSD1306_SETHIGHCOLUMN,
        SSD1306_SETSTARTLINE,
        SSD1306_SETCONTRAST,
        0xcf,
        SSD1306_SEGREMAP,
        SSD1306_NORMALDISPLAY,
        SSD1306_SETMULTIPLEX,
        0x3f,
        SSD1306_SETDISPLAYOFFSET,
        0x00,
        SSD1306_SETDISPLAYCLOCKDIV,
        0x80,
        SSD1306_SETPRECHARGE,
        0xf1,
        SSD1306_SETCOMPINS,
        0x12,
        SSD1306_SETVCOMDETECT,
        0x40,
        SSD1306_CHARGEPUMP,
        0x14,
        SSD1306_DISPLAYON
};

void SSD1306Init(void){
    cs.write(1);
    dc.write(0);
    rs.write(0);
    rs.write(1);
    SSD1306SendCommand(SSD1306_init, sizeof SSD1306_init); 
}

void SSD1306SendCommand(char *data, int i){
    cs.write(1);
    dc.write(0);        //data/command low for command.
    cs.write(0);
    while(i){
        spi2.write(*data);
        data++;
        i--;
    }
    cs.write(1);
}

void SSD1306SendData(char *data, int i){
    cs.write(1);
    dc.write(1);        //data/command high for data.
    cs.write(0);
    while(i){
        spi2.write(*data);
        data++;
        i--;
    }
    cs.write(1);
}

void setAddress( char page, char column )
{

    char pageAddress[] = {SSD1306_PAGE_START_ADDRESS};
    char columnAddress[] = { SSD1306_COLUMNADDRESS, SSD1306_COLUMNADDRESS_MSB, SSD1306_COLUMNADDRESS_LSB };

    if (page > SSD1306_MAXROWS)
    {
        page = SSD1306_MAXROWS;
    }

    if (column > SSD1306_LCDWIDTH)
    {
        column = SSD1306_LCDWIDTH;
    }

    pageAddress[0] = SSD1306_PAGE_START_ADDRESS | (SSD1306_MAXROWS - page);

    columnAddress[0] = SSD1306_COLUMNADDRESS;
    columnAddress[1] = SSD1306_COLUMNADDRESS_MSB | column;
    columnAddress[2] = SSD1306_COLUMNADDRESS_LSB;

    //__no_operation();

    SSD1306SendCommand(pageAddress, 1);
    SSD1306SendCommand(columnAddress, 3);

}

void clearScreen(void)
{
    char ramData[] = {0x00};

    char i,j;

    for(i=0; i < 8 ;i++)
    {
        setAddress(i,0);

        for(j=0; j < SSD1306_LCDWIDTH; j++)
        {
            SSD1306SendData(ramData, 1);
        }
    }
}

void charDraw(char row, char column, int data)
{
    int h;

    if (row > SSD1306_MAXROWS)
    {
        row = SSD1306_MAXROWS;
    }

    if (column > SSD1306_LCDWIDTH)
    {
        column = SSD1306_LCDWIDTH;
    }

    if ( data < 32 || data > 129 )
    {
        data = '.';
    }

    h = (data - 32) * 6;

    setAddress(row, column);
    SSD1306SendData( (char *)FONT6x8 + h, 6 );

}

void stringDraw( char row, char column, char *word)
{
    char a = 0;

    if (row > SSD1306_MAXROWS)
    {
        row = SSD1306_MAXROWS;
    }

    if (column > SSD1306_LCDWIDTH)
    {
        column = SSD1306_LCDWIDTH;
    }

    while (word[a] != 0)
    {
        if (word[a] != 0x0A)
        {
            if (word[a] != 0x0D)
            {
                charDraw(row, column, word[a]);

                //__no_operation();

                column += 6;

                if (column >= (SSD1306_LCDWIDTH - 6 ))
                {
                    column = 0;
                    if ( row < SSD1306_MAXROWS )
                        row++;
                    else
                        row = 0;
                }

            }
            else
            {
                if ( row < SSD1306_MAXROWS )
                    row++;
                else
                    row = 0;
                column = 0;
            }
            a++;
        }
    }
}

void pixelDraw(char x, char y)
{
    char page, temp;
    char coordinate[] = {0x00};

    if (x > SSD1306_LCDWIDTH - 1)
    {
        x = SSD1306_LCDWIDTH - 1;
    }

    if (y > SSD1306_LCDHEIGHT - 1)
    {
        y = SSD1306_LCDHEIGHT - 1;
    }

    page = y / 8;
    temp = 0x80 >> (y % 8);
    coordinate[0] = temp;

    setAddress(page,x);
    SSD1306SendData(coordinate, 1);

}


void horizontalLine(char xStart, char xStop, char y)
{
    char temp = 0;
    char page, a;
    char ramData[] = { 0x00 };

    if (xStart > SSD1306_LCDWIDTH - 1)
    {
        xStart = SSD1306_LCDWIDTH - 1;
    }

    if (xStop > SSD1306_LCDWIDTH - 1)
    {
        xStop = SSD1306_LCDWIDTH - 1;
    }

    if (y > SSD1306_LCDHEIGHT - 1)
    {
        y = SSD1306_LCDHEIGHT - 1;
    }

    if (xStart > xStop)
    {
        temp = xStart;
        xStart = xStop;
        xStop = temp;
    }

    page = y / 8;
    temp = 0x80 >> (y %8);

    a = xStart;
    ramData[0] = temp;

    setAddress(page, xStart);

    while (a <= xStop)
    {
        SSD1306SendData(ramData, 1);
        a++;
    }
}

void verticalLine(char x, char yStart, char yStop)
{
    char temp1 = 0, temp2 = 0;
    char page1, page2, pageStart;
    char a;
    char ramData1[] = {0x00};
    char ramData2[] = {0x00};

    if (x > SSD1306_LCDWIDTH - 1)
    {
        x = SSD1306_LCDWIDTH - 1;
    }

    if (yStart > SSD1306_LCDHEIGHT - 1)
    {
        yStart = SSD1306_LCDHEIGHT - 1;
    }

    if (yStop > SSD1306_LCDHEIGHT - 1)
    {
        yStop = SSD1306_LCDHEIGHT - 1;
    }

        if (yStart > yStop)
        {
            temp1 = yStart;
            yStart = yStop;
            yStop = temp1;
        }

    page1 = yStart / 8;
    page2 = yStop / 8;
    pageStart = yStart % 8;

    if (page1 != page2)
    {
        if ( pageStart > 0)
        {
            temp1 = 0xFF00 >> pageStart;
            temp1 = temp1 ^ 0xFF;
        }
        else
        {
            temp1 = 0xFF;
        }
    }
    else
    {
        temp1 = 0;

        a = yStart - (page1 * 8);
        a = 0xFF00 >> a;
        temp2 = temp2 ^ a;
    }

    ramData1[0] = temp1;

    setAddress(page1,x);
    SSD1306SendData(ramData1, 1);

    a = page1 + 1;
    ramData1[0] = 0xFF;

    while (a < page2)
    {
        setAddress(a, x);
        SSD1306SendData(ramData1, 1);
        a++;
    }

    temp2 = 8 - (yStop % 8);
    temp2--;
    temp2 = 0xFF << temp2;

    ramData2[0] = temp2;

    setAddress(page2, x);
    SSD1306SendData(ramData2, 1);
}

void imageDraw(const char IMAGE[], char row, char column)
{
    char a, height, width;

    width = IMAGE[0];
    height = IMAGE[1];

    for ( a = 0; a < height; a++)
    {
        setAddress(row + a, column);
        SSD1306SendData((char *)IMAGE + 2 + a * width, width);
    }
}

void circleDraw(register int x, register int y, int r)
{
    register int xx = -r;
    register int yy = 0;
    register int e = 2 - (2 * r);
    do {
        pixelDraw(x - xx, y + yy);
        pixelDraw(x - yy, y - xx);
        pixelDraw(x + xx, y - yy);
        pixelDraw(x + yy, y + xx);
        if(e >  xx) e += ((++xx << 1) + 1);
        if(e <= yy) e += ((++yy << 1) + 1);
    } while (xx < 0);
}

void Fill_RAM( char data )
{
   unsigned char i,j;

   char ramData[] = { 0x00};

   ramData[0] = data;

   for(i=0; i < 8 ;i++)
   {
      setAddress(i,0);

      for(j=0; j < SSD1306_LCDWIDTH; j++)
      {
         SSD1306SendData(ramData, 1);
      }
   }
}

void Fill_RAM_PAGE(unsigned char page, char data)
{
   unsigned char j;

   char ramData[] = { 0x00 };

   ramData[0] = data;

   setAddress(page,0);

   for(j=0; j < SSD1306_LCDWIDTH ;j++)
   {
      SSD1306SendData(ramData, 1);
   }
}

void Set_Contrast_Control(unsigned char d)
{
    char ramData[] = {SSD1306_SETCONTRAST, 0x00};
    ramData[1] = d;

    SSD1306SendCommand(ramData, 2);
}

void Set_Inverse_Display(unsigned char d)
{
    // 0 = normal, 1 = inverted

    char ramData[] = {SSD1306_NORMALDISPLAY};
    ramData[0] = ramData[0] + d;

    SSD1306SendCommand(ramData, 1);
}

void Set_Display_On_Off(unsigned char d)    
{
    // 0 = off, 1 = on

    char ramData[] = {SSD1306_DISPLAYOFF};
    ramData[0] = ramData[0] + d;

    SSD1306SendCommand(ramData, 1);
}