|
|
当サイトは、玄箱PRO (KURO-BOX/Pro)を中心とした組み込み、Linuxと電子工作を扱っています。
会社案内
情報セキュリティおよび個人情報の取り扱いについて コメントとトラックバックは、spamを予防するために、編集担当が公開の作業をするまで非公開になっています。コメントはそれぞれ投稿した人のものです。 |
API_VERSION は、LCDd と ドライバのバージョンを確認するための変数です。必ず、このように書 きます。stay_in_forground はターミナルに表示するような場合には、バック・グラウンドで実行で きません。そのような場合に '1' にします。通常は '0' です。 supports_multiple は、複数のデ バイスを並べた表示をドライバでサポートする場合に'1'にします。簡単にはサポートせず'0'にする のがよいでしょう。symbol_prefix はドライバの名前を決めます。この名前が LCDd 本体からドライ バの関数を呼び出すのに使われます。ドライバの名前(ここでは akiglcd ) +'_' です。MODULE_EXPORT char * api_version = API_VERSION; MODULE_EXPORT int stay_in_foreground = 0; MODULE_EXPORT int supports_multiple = 0; MODULE_EXPORT char *symbol_prefix = "akiglcd_";
MODULE_EXPORT int akiglcd_init(Driver *drvthis);
ドライバの初期化時に呼ばれる関数です。通信の初期化や、設定ファイルの読み 込み、画面のクリア、必要なメモリの確保などを行います。
MODULE_EXPORT void akiglcd_close(Driver *drvthis)ドライバの終了時に呼ばれる関数です。ファイル・ディスクリプタを閉じたり、メモリの開放を行 います。
MODULE_EXPORT int akiglcd_width(Driver *drvthis);液晶画面の横の文字数を返します。
MODULE_EXPORT int akiglcd_height(Driver *drvthis);液晶画面の縦の文字数を返します。
MODULE_EXPORT void akiglcd_clear(Driver *drvthis);液晶画面の表示を全部消します。
MODULE_EXPORT void akiglcd_string(Driver *drvthis, int x, int y, char *str);液晶画面の (x, y) の位置に文字列 str を表示します。x, y は左上が (1, 1) です。
MODULE_EXPORT void akiglcd_chr(Driver *drvthis, int x, int y, char c);液晶画面の (x, y) の位置に文字 c を表示します。x, y は左上が (1, 1) です。 いずれも、drvthis という引数があります。ここの中に、動作に必要な内部情報(設定ファイルの 情報や、ファイル・ディスクリプタなど)を記憶します。
MODULE_EXPORT void akiglcd_flush(Driver *drvthis);が呼び出されたときに、画面をクリアせずに一気に転送します。画面をクリアしないので、表示に変 化がない部分は文字が消えないためちらつきが減ります。変化がある部分は、新しい文字か空白を書 くことで表示が更新されます。
MODULE_EXPORT int akiglcd_icon(Driver *drvthis, int x, int y, int icon);ハートマークや、矢印などを表示するためのアイコンを (x, y) に表示する関数です。(x, y) は 左上が (1,1) です。akiglcd.c を使う場合には、次のファイル font4.txt をフォントとしてあらか じめ書き込んでおき、特別な文字を表示する形にしています。
MODULE_EXPORT void akiglcd_backlight(Driver *drvthis, int state);バックライトのオン/オフ制御です。
MODULE_EXPORT void XXX_num (Driver *drvthis, int x, int num);時計表示などで、大きな数字を表示するための関数です。akiglcd ドライバでは用意していません 。
MODULE_EXPORT void XXX_vbar(Driver *drvthis, int x, int y, int len, int promille, int options);縦方向のバーを表示するための関数です。(x, y) の位置から上に向けて、len * promile/1000 文 字分のバーを表示します。akiglcd ドライバでは用意していません。
MODULE_EXPORT void XXX_hbar(Driver *drvthis, int x, int y, int len, int promille, int options);横方向のバーを表示するための関数です。(x, y) の位置から右に、len * promile/1000 文字分の バーを表示します。akiglcd ドライバでは用意していません。
MODULE_EXPORT void
akiglcd_clear(Driver *drvthis)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
memset(p->framebuf, ' ', p->width * p->height);
}
akiglcd_clear() では、空白文字で 20×4 文字埋めている。
MODULE_EXPORT void
akiglcd_chr(Driver *drvthis, int x, int y, char c)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
y--;
x--;
p->framebuf[(y * p->width) + x ] = c;
}
akiglcd_chr は、framebuf[] に1文字コピーしている。
MODULE_EXPORT void
akiglcd_string(Driver *drvthis, int x, int y, char *str)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
int i, len = strlen(str);
unsigned char *q;
x--;
y--;
if (y>=(p->height))
return;
if ((len + x)>(p->width))
len = len - (len+x-p->width);
if (len < 0)
return;
q = p->framebuf + (y*p->width) + x;
for (i = len; i>0; i --, q ++ , str ++) {
*q = *str;
}
}
akiglcd_string は、framebuf[] に文字列をコピーしている。コピー前には表示 幅を超えないようにチェックをしている。
MODULE_EXPORT void
akiglcd_flush(Driver *drvthis)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
const char poscmd[] = "x1bN0000r";
akiglcd_write(p->fd, poscmd, sizeof(poscmd)-1);
akiglcd_checkret(p->fd, '@');
akiglcd_write(p->fd, p->framebuf, p->width*p->height);
}
akiglcd_flush() 関数では、左上に座標を移動後、20×4文字一気に書き込んでい る。
ここで akiglcd_write() 関数というのを使っています。秋月グラフィック液晶キットは、表示す る文字のフォントを I2C バスで PIC とつながった ROM から読み出して表示しています。どうやら ROM からの読み出しに時間がかかるらしく、2文字以上連続して送ると文字が表示されないことがあ ったので、その対策として akiglcd_write() 関数を用意しています。 ここで、タイミングを usleep() で決めていますが、引数が '1' になっています。1[us]で十分で はないのですが、手持ちのUSB serial + 玄箱PROではうまく動作しているので、そのままにしていま す。短すぎる場合は、10*1000 (10ms) 単位で増やしてみてください。
int
akiglcd_write(int fd, const void *buf, int count)
{
int i;
for (i=count; i>0; i --) {
if (i > 1) {
write(fd, buf, 2);
buf +=2;
i --;
} else {
write(fd, buf, 1);
buf ++;
}
usleep(1);
}
return i;
}
MODULE_EXPORT int kurors_init(Driver *drvthis);ドライバの初期化時に呼ばれる関数です。通信の初期化や、設定ファイルの読み込みなどを行いま す。
MODULE_EXPORT void kurors_close(Driver *drvthis);ドライバの終了時に呼ばれる関数です。ファイル・ディスクリプタを閉じたり、メモリの開放を行 います。
MODULE_EXPORT const char *kurors_get_key(Driver *drvthis);押されたキーの名前を返す関数です。上矢印キーに相当するのは "UP", 下矢印は "Down" です。 また、新しく "Play" や "Center" といったキーの名前を使ってもかまいません。
MODULE_EXPORT const char *
kurors_get_key(Driver *drvthis)
{
PrivateData *p = (PrivateData *) drvthis->private_data;
char s, rbuf[1], tBuf[BUFSIZ];
int rSize;
char *ret = NULL;
switch (p->status) {
case WAIT_Y:
if (read(p->fd, rbuf, 1) == 1) {
if (rbuf[0] != 'Y') {
debug(RPT_INFO, "kurors: rec error, could not get 'Y'");
exit(-1);
}
p->status = WAIT_REC;
}
break;
case WAIT_REC:
rSize = read(p->fd, tBuf, BUFSIZ);
if (rSize < 0) {
debug(RPT_INFO, "kurors: read error");
exit(-1);
}
p->sumSize += rSize;
memcpy(&(p->rBuf[p->rIdx]), tBuf, rSize);
p->rIdx += rSize;
if (p->sumSize == 242) {
if((p->rBuf[0] != 'S') || (p->rBuf[241] != 'E') ) {
debug(RPT_INFO, "kurors: error");
exit(-1);
}
ret = analyze_rec(p->rBuf);
// Wait next key press
s = 'r';
write(p->fd, &s, 1);
p->status = WAIT_Y;
p->sumSize = 0;
p->rIdx = 0;
}
break;
default:
break;
}
return ret;
}
kurors_get_key() で待ちつづけると表示に影響が出るので、この関数でシリアル・バッファのデー
タをいつまでも待たないようにしています。具体的には kurors_init() で、
t.c_cc[VTIME]=0;
t.c_cc[VMIN]=0;
として、バッファが空の場合は read() が、すぐに返ってくるようにしています。
kurors_analyze() では、構造体 rsa の中のリモコン・コード(家電協フォーマットに近いもの)と
の比較をし、一致すれば key の中身を返しています。
struct rsaction_ {
char *code; // remote controller code
char *key; // key pad
};
struct rsaction_ rsa[] = {
/* SANSUI RS-F2 */
/* number buttons */
{"01011101101000101000001001111101", "Enter"}, /* 1 */
{"01011101101000100100001010111101", "Escape"}, /* 2 */
{"01011101101000101100001000111101", "Up"}, /* 3 */
{"01011101101000100010001011011101", "Down"}, /* 4 */
<続く>
このブログ記事を参照しているブログ一覧: lcdproc のドライバの書き方 (前編)
このブログ記事に対するトラックバックURL: http://www.eleki-jack.com/mt/mt-tb.cgi/1221
おすすめ書籍 |
![]() |
コメントする