2020年12月19日土曜日

STM32で廉価4chオシロを作ろう (8) LCD MSP3520 ILI9488 制御の勘所

本日はヒラサカさんの56歳の生誕祭なので日本国民の祝日です.

さて本日も、STM32で4chオシロを作りましょう.

LCDを動かすのがわからんくてしばらく困っていたのですがやっと少し表示が出ました.

LCDはMSP3520という中華製品で、サイズは3.5inchだったかな.LCD driver ICはILI9488です.画素数は480x320.3bit/pixel modeで動かしていますから8colorsです.ILI9488にはSPIで接続しています.

今回はILI9488の制御について解説します.

【SPIの結線】
SCK,CS,MISO,MOSI、のお決まりの4本線はSPIの作法に則って配線すればOKです.
CSはLow Activeです.CSは常にLowでも問題なく動いてます.(レジスタ制御が一区切りする毎にCS=Highにするなどは不要ということです)

ところがこの他にもう1本の制御線があるんです.DT/REGとか呼びます.何の役割かというと、レジスタアクセスとGRAMアクセスを識別するためです.レジスタアクセスの時はLowにする、GRAMアクセスの時はHighにする.
なので、STM32のSPIをDMAで処理する時には少々めんどくさくなります.SPI-DMAを2度に分けなければならないからです.
GPIO操作でDT/REG=Low
SPI-DMAでレジスタコマンドを送信
GPIO操作でDT/REG=High
SPI-DMAでGRAMデータを送信

SPI clockの最高周波数は、ILI9488の制約で20MHzまでです.
STM32F205の事情では、バス周波数が60MHzでそれをプリスケーラで4分周して15MHzでSPIを動かしますので20→15MHzに損しちゃってます.
CPOLとCPHAの設定にも注意してね.

【SPI以外の結線】
SPI以外の信号があります.
左側の5本はタッチパネル信号線なので無視します.
LEDは、backlightのON/OFFです.Highで点灯.
RESETは、hard resetです.Lowでreset.
VCCは3.3Vでも5VでもOKらしい.いまは5Vで動かしています.

【ILI9488のPS系レジスタ】
制御softwareのハナシに移ります.

datasheetのレジスタを見ると、Power Saveやreset系レジスタで怪しいのはこんなにたくさんあります.これらの依存関係がよくわかりません.
Soft Reset、Sleep IN、Sleep OUT、Normal Display Mode ON、All Pixel OFF、All Pixel ON、Display OFF、Display ON、Idle Mode OFF、Idle Mode ON
GitHubのcodeをチラ見しても、いろいろやり過ぎていてよくわからん.
レジスタのデフォ値を不揮発メモリに記憶することもできるみたいよ.
わたしが買ったLCDにはどんなデフォ値がストアされているのかは不明です.

なので動かしてみるしかないです.

【ILI9488を動かすミニマム操作】
この画面を出すのに必要な最低限の操作を記します.左上が原点で、右下が最大点です.
GRAM data formatは3bit pixelで、1byteに2pixelsが入ります.
なので、480x320の全面を埋め尽くすなら、480x320/2=76800bytes送信すればいいです.計算では40mSecぐらいかかる見込みです.

ILI9488を初期設定して画面をblackにして、シアンとマゼンタの矩形を描きます.
void LCD_setup(void){
LCD_RESET();         hardware reset
HAL_Delay(200);       200mSec待ち
LCD_BACKLIGHT_ON();       hardware back light LED ON
LCD_CS();                  hardware CS=Low
LCD_send_command(ILI9488_SLPOUT);     Sleep Out  (11H)
LCD_send_command(ILI9488_MADCTL);      Memory Access Ctl. (36H)
LCD_send_byte(0xE0);           座標系設定
LCD_send_command(ILI9488_PIXFMT);     Interface Pixel fmt. (3AH)
LCD_send_byte(0x01);                  3bit/pixel mode

LCD_rectangle(0,0,479,319,0);             全画面ブラック
LCD_rectangle(0,0,239,159,6);             シアンの矩形
LCD_rectangle(239,159,479,319,5);      マゼンタの矩形
}

レジスタコマンド送信routine
void LCD_send_command( uint8_t x ){
LCD_CMD();      DT/REG=Low
HAL_SPI_Transmit(&hspi1, &x, 1, 1000);
}

データ送信routine
void LCD_send_byte(uint8_t x){
LCD_DATA();       DT/REG=High
HAL_SPI_Transmit(&hspi1, &x, 1, 1000);
}

矩形範囲を塗りつぶすroutine
void LCD_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t col){
uint8_t c;
c = col & 0x7;
LCD_send_command(ILI9488_DISPOFF);        一応画面OFF
LCD_send_command(ILI9488_CASET);        描画X座標範囲指定
LCD_send_byte( x1>>8 );
LCD_send_byte( x1 );
LCD_send_byte( x2>>8 );
LCD_send_byte( x2 );
LCD_send_command(ILI9488_PASET);        描画Y座標範囲指定
LCD_send_byte( y1>>8 );
LCD_send_byte( y1 );
LCD_send_byte( y2>>8 );
LCD_send_byte( y2 );
LCD_send_command(ILI9488_RAMWR);       GRAM書き予告
for(int i=0;i<(x2-x1)*(y2-y1)/2;i++) 
LCD_send_byte((c<<3) + c);    GRAMデータ送信
LCD_send_command(ILI9488_DISPON);        画面ON
}

今後はいろんな描画routineをつくらなくちゃ.

かしこ

4 件のコメント:

  1. LCD_RESET()などは、どのドキュメントを参照しましたか?

    返信削除
    返信
    1. 記憶が薄れていますが、これとか使えそうな資料みたく思います.
      https://www.hpinfotech.ro/ILI9488.pdf

      削除
  2. ありがとうございます。ライブラリ自体は以下にございました。
    http://www.lcdwiki.com/3.5inch_SPI_Module_ILI9488_SKU:MSP3520

    返信削除
    返信
    1. 忘れちまっててすいませんでしたー
      がんばってくださーい

      削除