Stand-alone HMD demo system built on mbed FRDM-K64F.

Dependencies:   SDFileSystem mbed FATFileSystem

main.cpp

Committer:
maruishi
Date:
2014-07-29
Revision:
0:9bbe50de69d8

File content as of revision 0:9bbe50de69d8:

#include "mbed.h"
#include "SDFileSystem.h"

DigitalOut myled(LED_GREEN);
Serial pc(PTC17, PTC16);
DigitalOut lcd_rs1(PTB19);
DigitalOut lcd_cs1(PTB18);
DigitalOut lcd_cs2(PTC1);
DigitalOut lcd_rst(PTC8);

DigitalIn push_sw(SW2);

SPI spi(PTD2,PTD3,PTD1);
SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");

/*
    LCDモジュールへのコマンドの送信(1バイト)
*/
void  lcd_command_write(unsigned char c)
{
    lcd_rs1 = 0;
    spi.write(c);
}

/*
    LCDモジュールへのデータの送信(1バイト)
*/
void  lcd_data_write(unsigned char c)
{
    lcd_rs1 = 1;
    spi.write(c);
}

/*
    LCDモジュールへのデータの送信(lenバイト)
*/
void lcd_writeData(unsigned char* buff,int len)
{
    int i;
    lcd_rs1 = 1;
    for(i=0; i<len; i++) {
        spi.write(*(buff+i));
    }
}

/*
    LCDモジュールの初期化処理
*/
void lcd_controllerInitial()
{
    int i;

    /*
    LCD初期化用データ
    cmd : true  = コマンド
          false = データ
    data : 送出する内容
    */
    const struct lcd_init_data {
        bool cmd;
        unsigned char data;
    } lcd_init_data_table[] = {
        { true,     0xB1 },     // FRMCTR1
        { false,    0x01 },
        { false,    0x2C },
        { false,    0x2D },

        { true,     0xB2 },     // FRMCTR2
        { false,    0x01 },
        { false,    0x2C },
        { false,    0x2D },

        { true,     0xB3 },     // FRMCTR3
        { false,    0x01 },
        { false,    0x2C },
        { false,    0x2D },
        { false,    0x01 },
        { false,    0x2C },
        { false,    0x2D },

        { true,     0xB4 },     // INVCTR
        { false,    0x07 },

        { true,     0xC0 },     // PWCTR1
        { false,    0xA2 },
        { false,    0x02 },
        { false,    0x84 },

        { true,     0xC1 },     // PWCTR2
        { false,    0xC5 },

        { true,     0xC2 },     // PWCTR3
        { false,    0x0A },
        { false,    0x00 },

        { true,     0xC3 },     // PWCTR4
        { false,    0x8A },
        { false,    0x2A },

        { true,     0xC4 },     // PWCTR5
        { false,    0x8A },
        { false,    0xEE },

        { true,     0xC5 },     // VMCTR1
        { false,    0x0E },

        { true,     0x36 },
        { false,    0xA8 },

        { true,     0xe0 },     // GAMCTRP1
        { false,    0x02 },
        { false,    0x1c },
        { false,    0x07 },
        { false,    0x12 },
        { false,    0x37 },
        { false,    0x32 },
        { false,    0x29 },
        { false,    0x2d },
        { false,    0x29 },
        { false,    0x25 },
        { false,    0x2b },
        { false,    0x39 },
        { false,    0x00 },
        { false,    0x01 },
        { false,    0x03 },
        { false,    0x10 },

        { true,     0xe1 },
        { false,    0x03 },
        { false,    0x1d },
        { false,    0x07 },
        { false,    0x06 },
        { false,    0x2e },
        { false,    0x2c },
        { false,    0x29 },
        { false,    0x2d },
        { false,    0x2e },
        { false,    0x2e },
        { false,    0x37 },
        { false,    0x3f },
        { false,    0x00 },
        { false,    0x00 },
        { false,    0x02 },
        { false,    0x10 },

        { true,     0x2a },     // CASET
        { false,    0x00 },
        { false,    0x01 },
        { false,    0x00 },
        { false,    0xA0 },

        { true,     0x2b },     // RASET
        { false,    0x00 },
        { false,    0x02 },
        { false,    0x00 },
        { false,    0x81 },

        { true,     0x3A },
        { false,    0x05 },     // 16bit/pixel
        { true,     0x29 },
    };

    lcd_rs1 = 0;
    lcd_cs1 = 0;
    lcd_cs2 = 0;

    spi.write(0x11);
    wait(0.120);

    for(i=0; i<sizeof(lcd_init_data_table)/sizeof(lcd_init_data_table[0]); i++) {
        if (lcd_init_data_table[i].cmd == true) {
            lcd_rs1 = 0;
            spi.write(lcd_init_data_table[i].data);
        } else {
            lcd_rs1 = 1;
            spi.write(lcd_init_data_table[i].data);
        }
    }
    wait(0.120);
    lcd_cs1 = 1;
    lcd_cs2 = 1;
}

void LCD_updateDisplay(int displayNo,unsigned char* buff)
{
    if (displayNo == 0) {
        lcd_cs1 = 0;
    } else {
        lcd_cs2 = 0;
    }
    lcd_command_write(0x2C);
    lcd_data_write(0);
    lcd_writeData((unsigned char*)buff,128*160*2);
    lcd_cs1 = 1;
    lcd_cs2 = 1;
}

/*
    LCD位置調整用の十字線表示を行う
*/
void adjustScreen()
{
    unsigned char fb[128*160*2];
    int i;

    memset(fb,0,sizeof(fb));
    for(i=0; i<128; i++) {
        fb[(80 + i*160)*2    ] = 0xff;
        fb[(80 + i*160)*2 + 1] = 0xff;
    }
    for(i=0; i<160; i++) {
        fb[(160*64 + i)*2    ] = 0xff;
        fb[(160*64 + i)*2 + 1] = 0xff;
    }
    LCD_updateDisplay(0,fb);
    LCD_updateDisplay(1,fb);
    while(1);
}

int main()
{
    unsigned char fb[2][128*160*2];
    FILE *fp;
    int size;

    pc.baud(115200);
    
    /* LCD制御用のSPI初期設定 */
    spi.format(8,0);
    spi.frequency(15000000);

    /* LCDモジュールのリセット */
    lcd_rst = 0;
    wait(0.1);
    lcd_rst = 1;
    wait(0.1);

    lcd_cs1 = 1;
    lcd_cs2 = 1;

    /* LCDモジュールの初期化処理の呼び出し */
    lcd_controllerInitial();

    if(push_sw == 1) {
        /* 起動時にSW2が押されていない場合は、SDカードからのビデオ再生を実行 */

        /* ビデオファイルのオープン */
        fp = fopen("/sd/video.rgb", "r");

        while (true) {
            size = fread(fb, sizeof(char), 128*160*2*2, fp);
            if(size == 128*160*2*2) {
                myled = !myled;
                LCD_updateDisplay(0,fb[0]);
                LCD_updateDisplay(1,fb[1]);
            } else {
                /* 指定したサイズがリード出来ない場合には、ファイル終端と判断 */
                fseek(fp,0L,SEEK_SET);
            }

            /* もしSW2が押されていたら、ファイルをクローズし、LCDを黒画像にする */
            if(push_sw == 0){
                fclose(fp);
                memset(fb[0],0,sizeof(fb[0]));
                LCD_updateDisplay(0,fb[0]);
                LCD_updateDisplay(1,fb[0]);
                while(1);
            }
        }
    } else {
        /* 起動時にSW2が押されている場合は、LCD調整画面を表示 */
        adjustScreen();
    }

}