<V.3版>
グラフィックス液晶 INT035 by Legato
 LED タッチ オンオフ

(→プロジェクトファイル(Harmony Ver.3版 MHC v3.8.0) ダウンロード


 液晶に表示されるボタン(スイッチ)ウィジェットをクリックするとLEDがオンオフするプログラムです。このプログラムを設計する場合を 例にしてグラフィック液晶を使う場合の
① MHCの設定
② グラフィック液晶INT035のドライバーの組み込み方法
③ Graphics Composerによる液晶画面表示の操作方法
④ 外部I/Oの制御方法
   などを説明します。


<仕様>   
   ・Harmony Ver.2のグラフィックスライブラリを使い液晶画面にボタンウィジェット(以下、ボタンと云う)を表示する。
 ・ボタンの表面には "LED ON/OFF"と表示する。文字は黒色とする。
 ・ボタン表面色は 水色(skyblue)とし、背景色は黄緑色(lightgreen)とする。
 ・グラフィック液晶は Displaytech社のINT035(3.5インチ、QVGA)とする。
 ・ボタンをクリックすると 4個のLEDが消灯している場合は点灯し、点灯している場合は消灯すること。
   尚、LEDはPIC起動後は消灯していること。
 ・LEDの点灯、消灯動作はボタンをリリース(指を離した時)のイベントにもとづき行われること。
 ・ボタンのチャタリング対策を織り込むこと。
 ・キャラクタ液晶も接続しタッチの位置を表示すること。 タッチ位置の座標原点(X= 0, Y = ,0)は左上とし、右下は(X = 320, Y = 240)とする。
   尚、タッチ後液晶から指を離した場合は離した時の座標値を保持してそのまま表示のこと。
 ・PIC起動時、キャラクタ液晶に以下を 2sec 表示すること
     1行目: Harmony Graphics
     2行目: LED Touch OnOff
   
<回路図> (→PDFファイル
 
<外観> PIC32MZ評価ボード(→購入方法)を使った実験品の外観です。
     汎用モジュール評価ボード(段積みボード)には本テーマと関係ない部品が多々実装されています。



 
<動作結果> (→ 動画:1080pのHD動画を見ることができます。)
 ①タッチの瞬間 ②右上を鉛筆でクリックした瞬間

   
<解説> 記載してある内容は要点だけです。 詳細はプロジェクトファイルを精読願います。
          (追記)参考資料 → URL
■ 新規プロジェクトの作成 (→ 新規プロジェクト作成手順
   PICは、PIC32MZ2048EFH100を選択します。 グラフィックに係る特段の設定はありません。
  忘れないで設定項目しておく項目としてencodingに Shift_JISを選択しておくことがあげられます。 これを忘れるとコメント欄が文字化けして
  しまいます。

 
■ キャラクタ液晶制御、及びINT035タッチ制御のライブラリの追加とインクルード
 ・キャラクタ液晶制御のライブラリは 1lcd_lib_XC32.h、と1lcd_lib_XC32.c に分かれています。
  ① 1lcd_lib_XC32.h と1lcd_lib_XC32.cを main.cがあるフォルダにコピーします。 
  ② プロジェクトファイルに追加します。
  ③ 1lcd_lib_XC32.hをapp.cにインクルードします。

 ・INT035タッチ制御のライブラリはINT035_Touch_lib_XC32.hとINT035_Touch_lib_XC32.c に分かれています。
  ① INT035_Touch_lib_XC32.hINT035_Touch_lib_XC32.c をmain.cがあるフォルダにコピーします。
  ② プロジェクトファイルに追加します。
  ③ INT035_Touch_lib_XC32.hをapp.cにインクルードします。
 
■ MHC作成1
項目 1. [Clock Diagram]タブで、クロックの構成を外付け24MHz水晶発振器用、システムクロック200MHzに設定します。
 POSCMOD: → EC
 FPLLICLK: → POSC
 FPLLIDIV: → DIV_3
2.[Prpject Graph]タブでの設定
■追加コンポーネント
 Core
 CORE TIMER
 TIME
 EBI
 GFX Core LE
 Input System Service
 LE External Controller
 LE Parallel(EBI)
 Legato
 Legato Graphics w/PDA TM4301B Display
■ コンポーネント間の接続
 TIME -  CORE TIMER
 EBI・EBI_CS0 - LE Parallel(EBI)・EBI_CS
 LE Parallel(EBI)・Parallel Display Interface
   - LE External Controller・Parallel Display Interface
 LE External Controlle
r・LE Display Driver
   -Legato・LE Display Driver
3. 追加コンポーネントの設定1
 黄緑部分がDefaultからの変更部分です。
MHC
備考   ★コンパイルするには、非常にsimpleなものでよいのでGraphics Composerで作成されたScreenが必要となります。 例:MHC作成2(Graphics Compser)の 7.  
項目 4. 追加コンポーネントの設定2
 黄緑部分がDefaultからの変更部分です。
5. [Pin Settings]タブでの設定
■ピンへのCustom Name 設定
 EBIモジュールの パラレル制御は6800のRead/Write方式が使われています。 INT035のパラレル制御はは8080のRead/Writeが使われています。 この為Harmony v.3では8080のRead/Writeのデバイス用に制御ポート WR,RD,RS,CS,RESETをGPIOに設定して、ポートに特定の名前をつけることによって 8080のRead/Writeが実行できるライブラリが用意されています。したがってここでは 各ポートに以下のように命名します。 タッチ制御用のBSP_MAXTOUCH_CHGも必須です。
Pin
Num
Pin ID  Custom Name  Function Direction Latch  備考 
2 RA5 GFX_DISP_INTF_PIN_RESET GPIO OUT Low ★ Direction: OUT 
8 RC3 GFX_DISP_INTF_PIN_WR GPIO OUT High ★ Latch: High
9 RC4 GFX_DISP_INTF_PIN_RD GPIO OUT High ★ Latch: High 
20 RB5 GFX_DISP_INTF_PIN_BACKLIGHT GPIO OUT High なくても可 
23 RB2 BSP_MAXTOUCH_CHG GPIO  IN    
95 RG14 GFX_DISP_INTF_PIN_CS GPIO OUT High  
97 RG13 GFX_DISP_INTF_PIN_RSDC GPIO OUT High  
  以上の設定を行うことにより plib_gpio.hの中で Harmony のライブラリ関数と各ポートが関連付けされます。
MHC
備考  
項目 7. [Pin Settings]タブでの設定
■ON/OFF制御用LEDポートの設定
 LED用ポートのRG15(1)、RD4(81)、RA15(67)、RA14(66)のFunctionをGPIO, DirectionをOutに設定します。 Custom Nameは制御とは関係ありません。
 
   
MHC  
備考      
 
 
■ MHC作成2(Graphics Compser)
項目 1. Graphics Composerを開きます。
メニューバー [MHC] →[Tool] → [Legato Graphics Composer] 
2. Legato Graphics Composerのダイアログが開きますのでcreate a new project using the new project wizard のボタンをクリックします。 3. 使用するグラフィック液晶(INT035)の解像度をWidth:320、 Hight:240をインプットします。
MHC  
備考      
項目 4. カラーモードとして、16ビットカラーのRGB565を選択します。 5. Defaultを選択 6. Finishを選択
MHC
備考      
項目 7. 右上のTool BoxのInput Widgetsの中からButton Widgetsをドラッグして、ボタンスイッチとして適当と思われる位置、大きさに配置する。微調整は、Object EditorのPositionのX,YやSizeのWidth,Heightに数値を打鍵して入力する。 8. 左下のScheme Windowのボタンをクリックして新しく色のSchemeを作成する。Scheme Editor タブをクリックして、Scheme Editorを表示後、追加したSchemeをBaseSkyBlue_TextBlackと命名する。Baseの欄をクリックして色設定用のColor Editor(RGB565)が現れるのでボタンウィジェットの前面の色として水色(SkyBlue)を選択する。文字色(Text)はデフォルトの黒色のままとする。 9. 同様にBackgroundPanel用のSchemeとしてBase色が黄緑色のBaseGreenを作成する。
MHC
備考      
項目 10. 右下のWindowをObject Editorに変更してボタンウィジェットの名前(Name)をLedBtnに変更します。 ボタンウィジェットの前面色を水色に変更すべく、Schemeの欄 (internal)をクリックします。Scheme Selectのダイアログが現れますので 作成したSkyBlue_TextBlackのSchemeを選択してOKのボタンをクリックします。 11.  ボタンウィジェットの前面が水色に変わります。 Schemeの欄にScheme名のBaseSkyBlue_TextBlackが表示されます。 12. ボタンウィジェットの前面に"LED ON/OFF"の文字を表示させます。 
 文字表示の第一ステップとして表示する文字のフォントを設定します。Graphica Composerのメニューバーから [Asset] → [Font]をクリックします。
MHC
備考      
項目 13. Font Mangerのダイアログが開くので、をクリックしてインポートするフォントファイルをファイルリストのダイアログから選択します。ここではNotoSans-Bold.ttfを選択します。 14.  使用するフォントサイズとして24を選択します。プロジェクトの中で使用するフォント名としてここではBold_24と命名します。 15. 次に表示される文字列を作成します。
Graphics Composerのメニューバーから Asset → Strings をクリックします。
MHC
備考      
項目 16. String Mangerのダイアログが開くのでをクリックして文字列入力欄を表示します。 17. Name欄に表示する文字列のオブジェクト名を英数字で命名します。スペースや記号は使用できません。プログラム中にも使用されるので何を意味するかわかりやすい命名にしておくとよいとおもいます。Valueの欄に実際にボタンウィジェット前面に表示する文字を記載します。 18. Font欄をクリックするとSelect Fontダイアログが開くので 14.で作成したBold_24を選択します。
MHC
備考      
項目 19. ボタンウィジェットLedBtnを選択してObject Editorを表示します。Object EditorのString欄をクリックするとSelect Stringダイアログが現れますので Led_On_Offを選択するとダイアログの前面にLED ON/OFFの文字が表示されます。 20. ボタンウィジェットを押した時にイベントが発生すべく EventsのPressed欄のチェックボックスにチェックを追加します。  
MHC  
備考      
 
 
■ app.cに、青字部分を追加します。 
 
①MHCで定義された変数がapp.cでも使用できるようにします。
  #include "definitions.h" //必須
 
②インクルードファイルを追加します。stdio.hがないと、sprintf( )がコンパイラのバージョンによってコンパイルで警告となることが
  あります。  
  
#include <stdio.h>
  #include "1lcd_lib_XC32.h"

  #include "INT035_Touch_lib_XC32.h"
 
③INT035タッチ制御のライブラリ、INT035_Touch_lib_XC32.hとINT035_Touch_lib_XC32.c で使用される変数です。
  int adcX,adcY; //タッチ座標x,y
  int cTouched; //タッチ発生で1
  int prevTouched; //一巡前の タッチ発生で '1'、 タッチ無なら '0'
  int prev_abcX, prev_abcY;
 
④遅延関数やキャラクタ液晶のライブラリで使用される変数です。
  int delay_Clock = 200000000; //システムクロック:200MHz
  char Buf[64];
 
⑤遅延関数です。
  void delay_us(volatile unsigned int usec) //1μsec遅延
  {
    volatile int count;
    count = (int)(delay_Clock/20000000)*usec;

    do //実測 at 200MH (Clock=200000000)
    { //delay_us(1000):1000.4μsec delay_us(100):100.6μsec delay_us(10):10.5μsec  delay_us(1):1.5μsec
      asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP");
      asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

      count--;
    }while(count != 0);
  }
  ……
  ……
 
⑥INT035のタッチパネルのタッチ座標を取得する関数です。 ys_TouchGetX() はタッチ位置のx座標を  ys_TouchGetY() はタッチ位置のy座標を戻り値として返します。 これらの関数は、INT035タッチ制御のライブラリ、INT035_Touch_lib_XC32.hとINT035_Touch_lib_XC32.c で定義されています。
 SYS_INP_InjectTouchDown()、SYS_INP_InjectTouchMove()、SYS_INP_InjectTouchUp()は、HarmonyのLegatoのライブラリ関数です。 これらの関数を使って、タッチプレス、タッチムーブ、タッチアップのイベントをシステムに注入しています。
 ys_DRV_TOUCH_INT035() は、tasks.cの中でHarmonyの無限ループの毎サイクルごとに呼ばれています。
尚、INT035のタッチ制御はSPI制御が使われていますが、PIC32MZの内臓SPIモジュールは使用していません。
  void ys_DRV_TOUCH_INT035(void) //MSP2807タッチ検出 //タッチ検出、タッチ種類、タッチ位置とシステムに注入
  {
    cTouched = INT035_TouchDetect(); //タッチ検出で '1' //Position detedted
    adcX = ys_TouchGetX(); //タッチ位置のx座標
    adcY = ys_TouchGetY(); //タッチ位置のy座標

    if((prevTouched == 0) && (cTouched == 1)) // Touch: Pressed
    {
      SYS_INP_InjectTouchDown(0,adcX,adcY); //Touch:Pressed をシステムに注入
    }

    if(prevTouched == 1) //一巡前のタッチが有った場合
    {
      if(cTouched == 1) // Touch: Moved
      {
        SYS_INP_InjectTouchMove(1,adcX,adcY); //Touch:Movedをシステムに注入
      }
      else //Touch: Released
      {
        SYS_INP_InjectTouchUp(0,prev_abcX,prev_abcY); //touch:Upをシステムに注入
      }
    }

    ////前回の値を保持
    prevTouched = cTouched;
    prev_abcX = adcX;
    prev_abcX = adcY;

    //タッチ位置座標のキャラクタ液晶への表示
    if(cTouched) //タッチ有無判定
    {
      if(adcX<320 && adcY<240) //座標表示範囲: (0,0)-(320,240)の矩形を指定
      {
        //キャラクタ液晶にタッチ位置座標を表示
        lcd_cmd(0x80); //1目の先頭へ
        sprintf(Buf,"Touch Position \r\n");//
        //sprintf(Buf,"cTouched=%d \r\n",cTouched);//
        lcd_str(Buf); //液晶表示

        lcd_cmd(0xC0); //2行目の先頭へ
        sprintf(Buf,"X=%d, Y=%d \r\n",adcX, adcY); //
        lcd_str(Buf); // 開始メッセージ1行目表示
      }
    }
    else
    {
      delay_ms(10);
    }
  }



⑦ys_TouchHardwareInit()でINT035のタッチ制御ライブラリ関数を初期化しています。
  ys_TouchHardwareInit(); //INT035のタッチ制御ライブラリ関数初期化

  lcd_init(); // LCD初期化
  lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF
  lcd_clear();

  lcd_cmd(0x80); //1目の先頭へ
  sprintf(Buf,"Touch Position \r\n");//
  lcd_str(Buf); //液晶表示

  lcd_cmd(0xC0); //2行目の先頭へ
  sprintf(Buf,"X= , Y= \r\n"); //
  lcd_str(Buf); // 開始メッセージ1行目表示

  delay_ms(1000);

 
 
以下、app.c 全文
 
■ initialization.cに、青字部分を追加します。 
  ① PICの立ち上がりを350msec遅延させます。INT035の内部制御回路が完全に立ち上がるまでの遅延時間です。 INT035が完全に立ち上がる前にPICが立ち上がり、 PICと接続しているピン(CS,RS,RD,WR,RESET 及びDATA00-DATA15)に何らかのパルス信号が入ってしまうとINT035は    永遠に立ち上がれなくなってしまいます。 PIC32MZ評価ボード(MZ100-A001)ではハードの回路で リセットICM51957Bにより650msecの遅延時間を作って、 合計1000msec(= ハード650msec + ソフト350msec )でプログラムをつくるようにしています。
 ( → INT035の立ち上がり時間に係るQ.A.)

    delay_ms(350); //INT035の内部回路が立ち上がるまで待つ

以下、initialization.c 全文

 
 
■ tasks.cに、青字部分を追加します。
  ①ys_DRV_TOUCH_INT035() をtasks.cの中で実行することにより、 Harmonyの無限ループのサイクル毎に INT035へのタッチ有無、座標、種類が検出され、Harmonyのタッチ関係のシステムに通知されます。
  ys_DRV_TOUCH_INT035(); //INT035タッチ座標検出、Harmonyへ通知
 
以下、tasks.c 全文
 
 
■ drv_gfx_external_controller.cに、青字部分の修正、追加を行います。
  ① MHCの設定が生成されるコードのこの部分に反映されないので、手書きでの修正が必要となります。
  #define DISPLAY_WIDTH 320
  #define DISPLAY_HEIGHT 240
  //#define DISPLAY_WIDTH 480
  //#define DISPLAY_HEIGHT 272
 
  ②drv_gfx_external_controller.cはLE External Controllerコンポーネントにより生成されるファイルです。 下記の部分はこのファイルで定義されているDRV_SSD1963_Configure(SSD1963_DRV *drvPtr)と云う関数の内容部分です。 INT035を初期化に関する関数です。 INT035はSDD1963を内臓していますが、32ビットのATMELが内臓されていてピクセルクロック周波数、水平同期、垂直同期、ピクセルフォーマットに係る設定が自動化されている為SSD1963だけの場合とは異なっています。 下記は実機での表示を見ながら修正した結果です。
  GFX_Disp_Intf intf = (GFX_Disp_Intf) drvPtr->port_priv; //#define GFX_Disp_Intf uint32_t
  uint8_t cmd;
  uint8_t parms[16];

  DRV_SSD1963_NCSAssert(intf); //GFX_DISP_INTF_PIN_CS = 0; → CSピン = 0

  //液晶INT035初期化
  //Set Data Interface //無いと色がおかしくなる
  cmd = 0xf0; //#define SSD1963_CMD_SET_DATA_INTERFACE 0xF0
  parms[0] = 0x3; // 16bitカラー/RGB565の場合:0x3 //24bitカラー:0x2
  GFX_Disp_Intf_WriteCommand(intf, cmd);
  GFX_Disp_Intf_WriteData(intf, parms, 1);


  //Turn on backlight //無いと液晶がONしない
  cmd = 0xbe;
  parms[0] = 0x6;
  parms[1] = 0xff;
  parms[2] = 0x1;
  parms[3] = 0x0;
  parms[4] = 0x0;
  GFX_Disp_Intf_WriteCommand(intf, cmd);
  GFX_Disp_Intf_WriteData(intf, parms, 5);


  //Turn on the display //無いと液晶がWhite Screenとなる
  cmd = 0x29;
  GFX_Disp_Intf_WriteCommand(intf, cmd);

  DRV_SSD1963_NCSDeassert(intf); //GFX_DISP_INTF_PIN_CS = 1; //CSピン = 1
 
 以下、drv_gfx_external_controller.c 全文
 
 
■ le_gen_screen_Screen0.cに、青字部分の修正、追加を行います。
  ① PIC32MZで使用されているレジスタ名やポート名などがソースコードで使用できるようにp32xxx.hをインクルードします。
  #include <p32xxxx.h> //ys added //レジスタ名など引き当ての為 //LATDbits.LATD0 = 1;

  ② プロジェクトで定義された変数や関数が使えるようにdefinitions.hをインクルードします。
  #include "definitions.h" //必須 ys added //これがないと SYS_TIME_CallbackRegisterMS()がコンパイエラー
 
  ③ 所要の変数を宣言します。
  int Led_Mode;
  int ChangeNG;
 
  ④ 4個のキバン上のLEDを 消灯している場合は点灯し、点灯している場合は消灯します。 
  void LedFunc(void)
  {
    if(Led_Mode == 0)
    {
      Led_Mode = 1;
      LATGbits.LATG15 = 1; //LED1点灯 //RG15(1)
      LATDbits.LATD4 = 1; //LED2 //RD4(81)
      LATAbits.LATA15 = 1; //LED3 //RA15(67)
      LATAbits.LATA14 = 1; //LED4 //RA(66)
    }
    else
    {
      Led_Mode = 0;
      LATGbits.LATG15 = 0; //LED1消灯
      LATDbits.LATD4 = 0; //LED2
      LATAbits.LATA15 = 0; //LED3
      LATAbits.LATA14 = 0; //LED4
    }
  }
 
  ⑤ システムタイマのコールバック関数です。 SYS_TIME_CallbackRegisterMS(TimerCallback_LedBtn, 0, 500, SYS_TIME_SINGLE ); 関数でセットされると、500msec後に呼び出されます。 ボタンウィジェットのチャタリング防止です。
  //ワンショットタイマ コールバック関数
  void TimerCallback_LedBtn ( uintptr_t context ) //ボタン誤動作防止、500msecワンショットタイマ
  {
    ChangeNG = 0; //500msec経過したので、LED On/Off制御許可
  }
 
  ⑥ ボタンウィジェットLedBtnを押した時に発生するイベント関数です。 500msec以内にボタンウィジェットを押したイベントが発生していなければ、LED制御を行い、そしてコールバック関数のセットを行います。
  void event_Screen0_LedBtn_OnPressed(leButtonWidget* btn)
  {
    if(ChangeNG == 0) //LED On/Off制御 許可の場合 //チャタリング防止
    {
      LedFunc(); //LED: ON/OFF
      ChangeNG = 1; //LED on/Off制御 不許可
      SYS_TIME_CallbackRegisterMS(TimerCallback_LedBtn, 0, 500, SYS_TIME_SINGLE ); //500msec遅延
    }
  }
 
 
 以下、le_gen_screen_Screen0.c 全文
 
 
■ sys_input_listener.cに、青字部分の修正、追加を行います。
  ① 以下の修正を行わないとコンパイルエラーが発生します。
    constがダブっています。 defaultKeyDownHandler(const const SYS_INP_KeyEvent* evt)関数引き数で constがダブっています。 Harmonyのライブラリsyntax errorと思われます。
  static void defaultKeyDownHandler(const SYS_INP_KeyEvent* evt) { } //ys added
  //static void defaultKeyDownHandler(const const SYS_INP_KeyEvent* evt) { }
 
 以下、sys_input_listener.c 全文