ks0713 SPI library. This library includes a small 5x5 ascii font and line function.

ks0713_spi.cpp

Committer:
muraguchi
Date:
2012-02-26
Revision:
1:408627d73aa8
Parent:
0:7b044b89e49c

File content as of revision 1:408627d73aa8:

#include "mbed.h"
#include "font5x5.h"
#include "ks0713_spi.h"

KS0713_SPI::KS0713_SPI(PinName mosi, PinName sclk, PinName cs1b, PinName rs, PinName rstb)
        : _spi(mosi,NC,sclk), _cs1b(cs1b), _rs(rs), _rstb(rstb) {
    init();
}


void KS0713_SPI::init() {
    _cs1b=0;
    _rs  =0;
    _rstb=0;

    _spi.format(8,0);
    _spi.frequency(5000000);


    wait(0.015); // wait for power up (reset low term must be greater than 900[ns])

    _rstb=1; // de-assert resetb


    writeCommand(0xA2); // LCD BIAS selection (1/65duty, 1/9bias)
    writeCommand(0xA1); // ADC selection (SEG128->SEG0)
    writeCommand(0xC0); // SHL selection (COM0->COM64)
    wait_ms(1);

    /*Power control
      Displaytech screen uses built-in power circuits
      Switch on in order as specified in data sheet
      wait 1ms between each command
      1st - Voltage converter ON = 0x2C
      2nd - Voltage regulator ON = 0x2E
      3rd - Voltage follower  ON = 0x2F */
    writeCommand(0x2C);  //0x2C = Voltage converter ON
    wait_ms(1);
    writeCommand(0x2E);  //0x2E = Voltage regulator ON
    wait_ms(1);
    writeCommand(0x2F);  //0x2F = Voltage follower ON


    // Regulator Resistor Selection
    /*Regulator resistor select
     Sets the internal resistance ratio used in the internal voltage regulator
     Refer to datasheet p.42
     This works as a corse contrast control
     0x20 = 1.9
     0x21 = 2.19
     0x22 = 2.55
     0x23 = 3.02
     0x24 = 3.61
     0x25 = 4.35
     0x26 = 5.29
     0x27 = 6.48 */
    writeCommand(0x23);

    /*Set reference voltage register
     Used as a fine contrast control
     0x81 = Enter voltage register set mode
     0x00 to 0x3F = 0 to 63 */
    writeCommand(0x81);  //0x81 = Enter voltage register set mode
    writeCommand(0x20);  //0x20 = Set ref voltage to 20

    /*Initial display line
     Specify DDRAM line for COM1
     0x40 + display line */
    writeCommand(0x40);  //Set initial line to 0

    /*Set page address
     Sets the initial page address to write to
     0xB0 + page address 0 to 8 */
    writeCommand(0xB0); //Initial page set to 0

    /*Set column address
     Sets the initial column to write to
     for LSB (b3-b0) 0x00 + first nibble
     for MSB (b7-b4) 0x10 + second nibble
     0x00 to 0x83 = column 0 to 131 */
    writeCommand(0x00);  //Sets LSB to 0
    writeCommand(0x10);  //Sets MSB to 0  - column is now set to 0

    /*Reverse display
     Selects either a normal display or a reverse display
     0xA6 = normal
     0xA7 = reverse */
    writeCommand(0xA6);  //Sets display to normal

    /*Set static indicator
     Sets up a static indicator on the display
     See datasheet p.42
     This is a 2 instruction cycle
     0xAC = static indicator ON
     0xAD = static indicator OFF
     Next instruction to set indicator type:
     0x00 = OFF
     0x01 = ON - 1 second blinking
     0x02 = ON - 0.5 second blinking
     0x03 = ON - always ON */
    writeCommand(0xAD);  //Static indicator OFF
    writeCommand(0x00);  //OFF - 0.5 second blinking

    /*Display ON/OFF
     Switched the display to on or off
     0xAE = Display OFF
     0xAF = Display ON */
    writeCommand(0xAF);

    clear();
    update();

    _x=0;
    _y=0;
}

void KS0713_SPI::writeCommand(unsigned char data) {
    _cs1b=0;
    _rs  =0;
    wait_us(1); // setup 55[ns]
    _spi.write(data);
    wait_us(1); // hold 180[ns]
    _cs1b=1;
}

void KS0713_SPI::writeData(unsigned char data) {
    _cs1b=0;
    _rs  =1;
    wait_us(1); // setup 55[ns]
    _spi.write(data);
    wait_us(1); // hold 180[ns]
    _cs1b=1;
}

void KS0713_SPI::clear() {
    for (int page=0; page<MBED_KS0713_SPI_HEIGHT/8; page++) {
        for (int column=0; column<MBED_KS0713_SPI_WIDTH; column++) {
            vram[column][page]=0x00;
        }
    }
}
void KS0713_SPI::fill() {
    for (int page=0; page<MBED_KS0713_SPI_HEIGHT/8; page++) {
        for (int column=0; column<MBED_KS0713_SPI_WIDTH; column++) {
            vram[column][page]=0xFF;
        }
    }
}
void KS0713_SPI::update() {
    for (int page=0; page<MBED_KS0713_SPI_HEIGHT/8; page++) {
        writeCommand(0xB0+page);
        writeCommand(0x10);
        writeCommand(0x00);
        for (int column=0; column<100; column++) {
            writeData(vram[column][page]);
        }
    }
}

void KS0713_SPI::locate(int x,int y) {
    _x=x;
    _y=y;
}

void KS0713_SPI::line(int x1, int y1, int x2, int y2) {
    int dist_x;
    int dist_y;
    int calc_point;

    if (x2>x1) {
        dist_x = x2-x1;
    } else {
        dist_x = x1-x2;
    }
    if (y2>y1) {
        dist_y = y2-y1;
    } else {
        dist_y = y1-y2;
    }



    if (dist_x>dist_y) {
        // x direction
        if (x1>x2)
            // step -1
        {
            for (int x=x1; x>=x2; x--) {
                if (x<0)
                    break;
                calc_point = y1+ ( (y2-y1) * (x-x1) / (x2-x1) );
                if (calc_point>=0 && calc_point<MBED_KS0713_SPI_HEIGHT)
                    vram[x][(calc_point>>3)] |= ( 0x1 <<(calc_point&0x7));
            }
        } else
            // step ++
        {
            // point 1 -> point 2
            for (int x=x1; x<=x2; x++) {
                if (x>=MBED_KS0713_SPI_WIDTH)
                    break;
                calc_point = y1+( (y2-y1) * (x-x1) / (x2-x1) );
                if (calc_point>=0 && calc_point<MBED_KS0713_SPI_HEIGHT)
                    vram[x][(calc_point>>3)] |= ( 0x1 <<(calc_point&0x7));
            }

        }
    } else {
        // y direction
        if (y1>y2)
            // step -1
        {
            for (int y=y1; y>=y2; y--) {
                if (y<0)
                    break;
                calc_point = x1+( (x2-x1) * (y-y1) / (y2-y1) );
                if (calc_point>=0 && calc_point<MBED_KS0713_SPI_WIDTH)
                    vram[calc_point][y>>3] |= ( 0x1 <<(y&0x7));
            }
        } else
            // step ++
        {
            // point 1 -> point 2
            for (int y=y1; y<=y2; y++) {
                if (y>=MBED_KS0713_SPI_HEIGHT)
                    break;
                calc_point = x1+( (x2-x1) * (y-y1) / (y2-y1) );
                if (calc_point>=0 && calc_point<MBED_KS0713_SPI_WIDTH)
                    vram[calc_point][y>>3] |= ( 0x1 <<(y&0x7));
            }
        }
    }
}


int KS0713_SPI::_putc(int value) {
    unsigned char fontdata;
    for (int cx=0; cx<5; cx++) {
        if ( _x+cx>=MBED_KS0713_SPI_WIDTH ) {
            break;
        }

        fontdata = font5x5[value-' '][cx];
        for (int cy=0; cy<5; cy++) {
            if (_y+cy>=MBED_KS0713_SPI_HEIGHT) {
                break ;
            }

            if (fontdata & 0x1) {
                vram[_x+cx][(_y+cy)>>3] |= ( 0x1 <<((_y+cy)&0x7));
            } else {
                vram[_x+cx][(_y+cy)>>3] &= ~( 0x1 <<((_y+cy)&0x7));

            }
            fontdata=fontdata>>1;
        }
    }

    _x+=6;
    return value;
}

int KS0713_SPI::_getc() {
    return -1;
}