Stand-alone HMD demo system built on mbed FRDM-K64F.
Dependencies: SDFileSystem mbed FATFileSystem
Diff: main.cpp
- Revision:
- 0:9bbe50de69d8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jul 29 11:41:59 2014 +0000 @@ -0,0 +1,275 @@ +#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(); + } + +}