aitendo C128X64SPI-12P-M with FRDM KL25Z

Dependencies:   mbed

/media/uploads/masato/c128x64spi-12p_2.jpg

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* が良いでしょう。

/media/uploads/masato/12876787564_6915e1f553_z.jpg

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;
}