マイコン工作実験日記

Microcontroller を用いての工作、実験記録

キーはTAGで拾う -- 続編

2013-10-03 21:05:37 | LCD
前回の記事でとりあげた、TAGを使ったキー入力の主要コードを掲載しておくことにします。

#define DIGIT_LENGTH    15
char digits[DIGIT_LENGTH+1];

int ft800_getKey(Ft_Gpu_Hal_Context_t *phost;)
{
  int tag;

  ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,
        &ev_ft800, INT_TAG, CTL_TIMEOUT_NONE, 0);
  tag = Ft_Gpu_Hal_Rd8(phost, REG_TOUCH_TAG);
  return tag;
}

void do_Button(Ft_Gpu_Hal_Context_t *phost)
{
  int option, inspos, ckey, keyval;
 
  Ft_Gpu_CoCmd_FgColor(phost, 0xe0e000); /* Button color is yellow */
  SAMAPP_CoPro_Widget_Calibrate();

  digits[0] = 0;
  ckey = 0;
  inspos = 0;
  do {
    Ft_Gpu_CoCmd_Dlstart(phost);
    Ft_App_WrCoCmd_Buffer(phost,CLEAR_COLOR_RGB(0,0,0)); /* Black background */
    Ft_App_WrCoCmd_Buffer(phost,CLEAR(1,1,1));

    Ft_Gpu_CoCmd_FgColor(phost, 0x003880); /* Button color is light blue */
    Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(255,255,255)); /* Label color is white */

    /* Draw Dial Keypad */
    Ft_Gpu_CoCmd_Keys(phost, 10,  80, 300, 35, 28, ckey, "123");
    Ft_Gpu_CoCmd_Keys(phost, 10, 120, 300, 35, 28, ckey, "456");
    Ft_Gpu_CoCmd_Keys(phost, 10, 160, 300, 35, 28, ckey, "789");
    Ft_Gpu_CoCmd_Keys(phost, 10, 200, 300, 35, 28, ckey, "#0*");
    /* Draw delete key */
    Ft_Gpu_CoCmd_FgColor(phost, 0xc01000); /* Button color is red */
    Ft_App_WrCoCmd_Buffer(phost,TAG('D'));
    option = (ckey == 'D') ? OPT_FLAT : 0;
    Ft_Gpu_CoCmd_Button(phost, 320,  80, 100, 50, 29, option, "Delete");
    /* Draw call key */
    Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(192,0,0)); /* Label color is red */
    Ft_Gpu_CoCmd_FgColor(phost, 0x00c000);
    Ft_Gpu_CoCmd_GradColor(phost,0xc0c0c0);
    Ft_App_WrCoCmd_Buffer(phost,TAG('C'));
    option = (ckey == 'C') ? OPT_FLAT : 0;
    Ft_Gpu_CoCmd_Button(phost, 320, 185, 100, 50, 29, option, "Call");

    digits[inspos] = '_';
    digits[inspos+1] = 0;
    Ft_App_WrCoCmd_Buffer(phost,COLOR_RGB(255,255,255)); /* Text color is white */
    Ft_Gpu_CoCmd_Text(phost, 10, 20, 30, 0, digits);

    Ft_App_WrCoCmd_Buffer(phost,DISPLAY());
    Ft_Gpu_CoCmd_Swap(phost);

    /* Download the commands into fifo */
    Ft_App_Flush_Co_Buffer(phost);
    Ft_Gpu_Hal_WaitCmdfifo_empty(phost);

    keyval = ft800_getKey(phost);
    if (keyval == 0) {      /* Key has released */
      if ((ckey >= '0' && ckey <= '9') || (ckey == '*') || (ckey == '#')) {
        if (inspos < DIGIT_LENGTH) { 
          digits[inspos++] = ckey;
        }
      } else if (ckey == 'D') {
        if (inspos > 0) {
          digits[inspos] = 0';
          inspos--;
        }
      }
    }
    ckey = keyval;
  } while (ckey != 'C');
  /* Call key has pressed. */
}

キーの状態変化はft800_getKey()で拾います。この関数では、割り込み処理ハンドラで生成されるイベントを待って、REG_TOUCH_REGを読み取るだけです。これだけで、キーがタッチされた時には、そのキーに対応するTAGの値を、タッチが終わった時には値としてゼロが返ってきます。

呼び出し側ではタッチが終わったこと時に対応するキーの値を表示しています。キーの状態変化があるたびに全てのキーを描画しなおしていますが、描画速度にはまったく問題ありません。FT800の描画エンジンは、ディスプレイリスト(DL)と呼ばれる一連の描画コマンドを解釈/実行することでひとつの画面を表示する仕組みになっています。そしてエンジンに実行させるDLの内容を更新することで、表示内容を更新することができます。上記のコードではFt_Gpu_CoCmd_Dlstart()で、DLの先頭にポインタをセットし、つづく一連のAPIを使って、DLに書き込むコマンド列を生成していきます。 Ft_Gpu_CoCmd_Swap()でエンジンが参照するDLを入れ替えをおこなうので、通常コマンド列の最後にはこのコマンドが入ります。

SAM3Sには充分なメモリがあるので、FT800のDLに書き込むコマンド列はいったんマイコンのSRAM内に書き溜めておいて、最後に Ft_App_Flush_Co_Buffer()を読んで実際にFT800のDLにまとめてダウンロードしています。

DLについては、また次の記事で説明しようかと思います。