ILI9341を使ってみた


ILIのSPIな液晶を試してみたくなり、中国発送の安いモジュールを入手して試してみました。

こちらのページが非常に参考になりました。

RST = 21
RS = 17

W = 240
H = 320

CMD_SLEEP_OUT = 0x11
CMD_DISPLAY_ON = 0x29
CMD_COLUMN_ADDRESS_SET = 0x2a
CMD_PAGE_ADDRESS_SET = 0x2b
CMD_MEMORY_WRITE = 0x2c
CMD_MEMORY_ACCESS_CONTROL = 0x36
CMD_COLMOD = 0x3a

MAC_PORTRAIT = 0xe8
MAC_LANDSCAPE = 0x48
COLMOD_16BIT = 0x55
COLMOD_18BIT = 0x66

MAC_CONFIG = MAC_LANDSCAPE

def write_command(tft, c)
  tft.gpio_set(RS, 0)
  arr = tft.transfer([c], 0)
end

def write_data(tft, c)
  tft.gpio_set(RS, 1)
  arr = tft.transfer([c], 0)
end

def write_data16(tft, c)
  tft.gpio_set(RS, 1)
  arr = tft.transfer([c >> 8, c & 0xff], 0)
end

def set_update_rect(tft, sx, ex, sy, ey)
  write_command(tft, CMD_COLUMN_ADDRESS_SET)
  write_data16(tft, sx)
  write_data16(tft, ex)
  write_command(tft, CMD_PAGE_ADDRESS_SET)
  write_data16(tft, sy)
  write_data16(tft, ey)
  write_command(tft, CMD_MEMORY_WRITE)
end

def setup(tft)
  tft.setreset(RST)
  tft.setrs(RS)

  tft.gpio_setflags(RST, BsdTft::OUTPUT)
  tft.gpio_setflags(RS, BsdTft::OUTPUT)

  lcd_init(tft)
end

def lcd_init(tft)
  tft.gpio_set(RST, 0)
  tft.gpio_set(RST, 1)

  write_command(tft, CMD_MEMORY_ACCESS_CONTROL)
  write_data(tft, MAC_CONFIG)

  write_command(tft, CMD_COLMOD)
  write_data(tft, COLMOD_16BIT)

  write_command(tft, CMD_SLEEP_OUT)
  usleep(60*1000)
  write_command(tft, CMD_DISPLAY_ON)
end

def rgb565_conv(r, g, b)
  rr = (r >> 3) << 11
  gg = (g >> 2) << 5
  bb = (b >> 3)
  return rr | gg | bb
end

def OldlcdCopy(tft, c)
  for i in 1..320 do
    rgba = c.getpix(0, i - 1, 240)
    for n in 1..240 do
      color = rgb565_conv(rgba[0 + (n - 1) * 4], rgba[1 + (n - 1) * 4],
        rgba[2 + (n - 1) * 4])
      write_data16(tft, color)
    end
  end
end


tft = BsdTft.new(1, 0, BsdTft::S6D0151)

setup(tft)

c = Cairo.new(W, H)

c.set_source_rgb(1, 0, 0)
c.move_to(0, 0)
c.line_to(100, 100)
c.stroke();

set_update_rect(tft, 0, W, 0, H);

OldlcdCopy(tft, c)

こんな感じに表示されました。

とりあえずBsdTft::S6D0151で初期化してますが、mruby-bsdtftに実装を追加していきたいと思います。

この液晶は240x320で128x160な液晶の3.75倍のデータ量があります。その分画面全体の再描画が遅くなります。

原因はわからないのですが、今のところレジスタのリードはできてません。

パラレルなILI9325は初期化がいろいろ必要でしたが、こちらはかなり少なくなっています。発売時期の違いなのでしょうか?追記:上記の簡単な初期化でも表示できますが、ケースによっては不安定な事もあるようです。やはりいろいろ初期化は必要なようで、mruby-bsdtftでは変更してあります。