aitendo C128X64SPI-12P-M with FRDM KL25Z
aitendo の FSTN液晶モジュール(128x64/SPI)[C128X64SPI-12P-M] を KL25Z につないでみました。今のところ、ドット、ライン操作までしか用意できていません。コントローラ仕様によるとデバイスからデータを取得することができるのですが、シリアル(SPI)ではできないことになっているため、フレームバッファは自前で持っています。テスト用にドラゴン曲線を表示させてみました。
ところで aitendo の商品説明ページ中の FPCケーブル取り付け例の写真は誤っていました(修正された模様)。また、キャリーボードでの LCD とバックライトの GND と電源は直結されているようです。ついでにサンプルのコードでのフレームバッファの使い方にも誤りがありますからドット単位で操作する場合には注意が必要です。
2014.03.12
q61.org さんの Chibimo 表示器として使えるようにしてみました。ドラゴン曲線を描いた後、ホストからの Chibimo データを処理します。KL05 とトラ技 ARM ライタ基板でも動作を確認していますが、Chibimo として使うには USB シリアルの使える KL* が良いでしょう。
c128x64spi.cpp
- Committer:
- masato
- Date:
- 2014-03-03
- Revision:
- 2:f6b27ec62471
- Parent:
- 1:84b2d36d57f0
File content as of revision 2:f6b27ec62471:
#include "mbed.h" #include "c128x64spi.h" #define PAGE_SEL 0xB0 #define COL_SEL 0x10 const char init_cmd[] = { 0xE2, // S/W RESET 0xA3, // LCD bias // 0xAF, // Display ON 0xA0, // segment direction 0xC8, // Common direction 0x22, // Regulation register select 0x81, // EV select 0x2F, // Select EV value 0x2F, // Power control // 0x40, // initialy display line 40 0xB0, // set page address 0x10, // set column addr MSB 0x00, // set column addr LSB // 0xAF, // display ON 0xA4, // A5 .normal display, all pixels OFF 0xA6, // A7 .normal display (inverse pixel) 0xAF, // display ON }; c128x64spi::c128x64spi(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rs, PinName reset) : _spi(mosi, miso, sclk), _cs(cs), _rs(rs), _reset(reset) { int i, j; for (i = 0; i < 8; i++) for (j = 0; j < 128; j++) gfx_buf[i][j] = 0; // _spi.format(8, 3); // 8 bit spi mode 3 _spi.frequency(16000000); // 8MHz SPI clock .. _cs = 0; _reset = 0; // reset wait_ms(500); _reset = 1; for (i = 0; i < sizeof(init_cmd); i++) { wr_cmd(init_cmd[i]); } } void c128x64spi::hline(int x0, int x1, int y, int color) { for (int x = x0; x < x1; x++) pixel(x, y, color); } void c128x64spi::vline(int x, int y0, int y1, int color) { for (int y = y0; y < y1; y++) { pixel(x, y, color); } } void c128x64spi::line(int x0, int y0, int x1, int y1, int color) { #if 1 int dx = 0, dy = 0; int dx_sym = 0, dy_sym = 0; int dx_x2 = 0, dy_x2 = 0; int di = 0; dx = x1-x0; dy = y1-y0; if (dx == 0) { /* vertical line */ if (y1 > y0) vline(x0,y0,y1,color); else vline(x0,y1,y0,color); return; } if (dx > 0) { dx_sym = 1; } else { dx_sym = -1; } if (dy == 0) { /* horizontal line */ if (x1 > x0) hline(x0,x1,y0,color); else hline(x1,x0,y0,color); return; } if (dy > 0) { dy_sym = 1; } else { dy_sym = -1; } dx = dx_sym*dx; dy = dy_sym*dy; dx_x2 = dx*2; dy_x2 = dy*2; if (dx >= dy) { di = dy_x2 - dx; while (x0 != x1) { pixel(x0, y0, color); x0 += dx_sym; if (di<0) { di += dy_x2; } else { di += dy_x2 - dx_x2; y0 += dy_sym; } } pixel(x0, y0, color); } else { di = dx_x2 - dy; while (y0 != y1) { pixel(x0, y0, color); y0 += dy_sym; if (di < 0) { di += dx_x2; } else { di += dx_x2 - dy_x2; x0 += dx_sym; } } pixel(x0, y0, color); } #else int dx, dy; int sx, sy; int chg; int e; int i; int tmp; if (x0 > x1) { sx = -1; dx = x0 - x1; } else { sx = 1; dx = x1 - x0; } if (y0 > y1) { sy = -1; dy = y0 - y1; } else { sy = 1; dy = y1 - y0; } if (dy > dx) { tmp = dx; dx = dy; dy = tmp; chg = 1; } else { chg = 0; } e = (dy << 1) - dx; for (i = 0; i <= dx; i++) { pixel(x0, y0, color); if (e >= 0) { if (chg) x0 += sx; else y0 += sy; e -= (dx << 1); } if (chg) y0 += sy; else x0 += sx; e += (dy << 1); } #endif } void c128x64spi::clr(int sw) { int x, y; if (sw) sw = 0xff; for (y = 0; y < 8; y++) { // int page = y / 8; // wr_cmd(PAGE_SEL | y); for (x = 0; x < 128; x++) { wr_cmd(PAGE_SEL | y); int col = ((x & 0xF0) >> 4) | 0x10; wr_cmd(COL_SEL | col); wr_cmd(x & 0xf); gfx_buf[y][x] = sw; wr_dat(sw); } } } void c128x64spi::pixel(int x, int y, int sw) { if ((x < 0) || (x >= 128)) return; if ((y < 0) || (y >= 64)) return; int page, col; int row_in_page; page = y / 8; /* Selecting Page */ wr_cmd(PAGE_SEL | page); /* Selecting Column */ col = ((x & 0xF0) >> 4) | 0x10; wr_cmd(COL_SEL|col); wr_cmd(x & 0xf); /* Pixel location */ row_in_page = y % 8; if (sw) gfx_buf[page][x] |= (1 << row_in_page); else gfx_buf[page][x] &= ~(1 << row_in_page); wr_dat(gfx_buf[page][x]); loc_x++; } void c128x64spi::locate_x(int x) { /* Selecting Column */ int col = ((x & 0xF0) >> 4) | 0x10; wr_cmd(COL_SEL|col); wr_cmd(x & 0xf); loc_x = x; } void c128x64spi::locate_y(int y) { /* Selecting Page */ // y = y / 8; wr_cmd(PAGE_SEL | y); loc_y = y; } void c128x64spi::wr_cmd(int cmd) { _rs = 0; // rs low, cs low for transmitting command _cs = 0; _spi.write(cmd); // wait_ms(5); _cs = 1; } void c128x64spi::wr_dat(int dat) { _rs = 1; // rs high, cs low for transmitting data _cs = 0; _spi.write(dat); // wait_ms(5); _cs = 1; }