• メインページ
  • データ構造
  • ファイル
  • ファイル一覧
  • グローバル

OpenSSM/libps2.c

説明を見る。
00001 /**************************************************************************************************
00002     Title           : PS/2 Keyboard Driver
00003     Programmer      : Yosuke FURUSAWA
00004     Copyright       : Copyright (C) 2010 Yosuke FURUSAWA.
00005     License         : 4-clause BSD License
00006     Since           : 2010/05/29
00007 
00008     Filename        : libps2.c
00009     Last up date    : 2010/05/30
00010     Kanji-Code      : Shift-JIS
00011     TAB Space       : 4
00012 
00013     Note            : In this version, do not support multi byte scan code and mouse protocol.
00014 **************************************************************************************************/
00015 
00016 
00017 /*
00018 ** スキャンコードセット 2 と仮定する
00019 */ 
00020 
00021 
00022 /*================================================================================================
00023 ヘッダファイルをインクルード
00024 =================================================================================================*/
00025 #include <p24FJ64GA002.h>
00026 
00027 #include "types.h"
00028 
00029 #include "librtc.h"
00030 #include "libps2.h"
00031 
00032 
00033 /*=================================================================================================
00034 マクロ定義
00035 ================================================================================================*/
00036 #define GPIO_PS2_CLK            PORTBbits.RB8
00037 #define GPIO_PS2_DAT            PORTBbits.RB9
00038 
00039 #define PS2_KEY_BUFFER_SIZE     5               /* 高速にタイプするなら、大きめに... */
00040 #define PS2_CODE_BUFFER_SIZE    16              /* PS2_main()のポーリング間隔とタイプ速度に依存 */
00041 
00042 
00043 /*=================================================================================================
00044 グローバル変数
00045 =================================================================================================*/
00046 PS2_T ps2;
00047 
00048 /* キーバッファ(アプリケーション参照用) */
00049 static unsigned char key_buf[ PS2_KEY_BUFFER_SIZE ];
00050 static unsigned char key_stptr;
00051 static unsigned char key_enptr;
00052 
00053 /* スキャンコードバッファ(プロトコル処理用) */
00054 static unsigned char code_buf[ PS2_CODE_BUFFER_SIZE ];
00055 static unsigned char code_stptr;
00056 static unsigned char code_enptr;
00057 
00058 /* スキャンコード -> キー変換テーブル cf : Fujitsu FMV-KB322, 109 keyboard */
00059 /* 規則性が全くない. なんで? (==; */
00060 static const unsigned char key[] = {
00061     KEY_NOP,            /* 0x00 */
00062     KEY_F9,             /* 0x01 */
00063     KEY_NOP,            /* 0x02 */
00064     KEY_F5,             /* 0x03 */
00065     KEY_F3,             /* 0x04 */
00066     KEY_F1,             /* 0x05 */
00067     KEY_F2,             /* 0x06 */
00068     KEY_F12,            /* 0x07 */
00069     KEY_NOP,            /* 0x08 */
00070     KEY_F10,            /* 0x09 */
00071     KEY_F8,             /* 0x0a */
00072     KEY_F6,             /* 0x0b */
00073     KEY_F4,             /* 0x0c */
00074     KEY_TAB,            /* 0x0d */
00075     KEY_HANKAKU,        /* 0x0e */
00076     KEY_NOP,            /* 0x0f */
00077     KEY_NOP,            /* 0x10 */
00078     KEY_ALT,            /* 0x11 */
00079     KEY_RSHIFT,         /* 0x12 :  KEY_LSHIFTに該当するが、コードを単純化するために RSHIFT */
00080     KEY_HIRAGANA,       /* 0x13 */
00081     KEY_CTRL,           /* 0x14 */
00082     'q',                /* 0x15 */
00083     '1',                /* 0x16 */
00084     KEY_NOP,            /* 0x17 */
00085     KEY_NOP,            /* 0x18 */
00086     KEY_NOP,            /* 0x19 */
00087     'z',                /* 0x1a */
00088     's',                /* 0x1b */
00089     'a',                /* 0x1c */
00090     'w',                /* 0x1d */
00091     '2',                /* 0x1e */
00092     KEY_LWIN,           /* 0x1f */
00093     KEY_NOP,            /* 0x20 */
00094     'c',                /* 0x21 */
00095     'x',                /* 0x22 */
00096     'd',                /* 0x23 */
00097     'e',                /* 0x24 */
00098     '4',                /* 0x25 */
00099     '3',                /* 0x26 */
00100     KEY_RWIN,           /* 0x27 */
00101     KEY_NOP,            /* 0x28 */
00102     ' ',                /* 0x29 */
00103     'v',                /* 0x2a */
00104     'f',                /* 0x2b */
00105     't',                /* 0x2c */
00106     'r',                /* 0x2d */
00107     '5',                /* 0x2e */
00108     KEY_APP,            /* 0x2f */
00109     KEY_NOP,            /* 0x30 */
00110     'n',                /* 0x31 */
00111     'b',                /* 0x32 */
00112     'h',                /* 0x33 */
00113     'g',                /* 0x34 */
00114     'y',                /* 0x35 */
00115     '6',                /* 0x36 */
00116     KEY_NOP,            /* 0x37 */
00117     KEY_NOP,            /* 0x38 */
00118     KEY_NOP,            /* 0x39 */
00119     'm',                /* 0x3a */
00120     'j',                /* 0x3b */
00121     'u',                /* 0x3c */
00122     '7',                /* 0x3d */
00123     '8',                /* 0x3e */
00124     KEY_NOP,            /* 0x3f */
00125     KEY_NOP,            /* 0x40 */
00126     ',',                /* 0x41 */
00127     'k',                /* 0x42 */
00128     'i',                /* 0x43 */
00129     'o',                /* 0x44 */
00130     '0',                /* 0x45 */
00131     '9',                /* 0x46 */
00132     KEY_NOP,            /* 0x47 */
00133     KEY_NOP,            /* 0x48 */
00134     '.',                /* 0x49 */
00135     '/',                /* 0x4a */
00136     'l',                /* 0x4b */
00137     ';',                /* 0x4c */
00138     'p',                /* 0x4d */
00139     '-',                /* 0x4e */
00140     KEY_NOP,            /* 0x4f */
00141     KEY_NOP,            /* 0x50 */
00142     '¥¥',             /* 0x51 */
00143     ':',                /* 0x52 */
00144     KEY_NOP,            /* 0x53 */
00145     '@',                /* 0x54 */
00146     '^',                /* 0x55 */
00147     KEY_NOP,            /* 0x56 */
00148     KEY_NOP,            /* 0x57 */
00149     KEY_CAPS,           /* 0x58 */
00150     KEY_RSHIFT,         /* 0x59 */
00151     KEY_ENTER,          /* 0x5a */
00152     '[',                /* 0x5b */
00153     KEY_NOP,            /* 0x5c */
00154     ']',                /* 0x5d */
00155     KEY_NOP,            /* 0x5e */
00156     KEY_NOP,            /* 0x5f */
00157     KEY_NOP,            /* 0x60 */
00158     KEY_NOP,            /* 0x61 */
00159     KEY_NOP,            /* 0x62 */
00160     KEY_NOP,            /* 0x63 */
00161     KEY_HENKAN,         /* 0x64 */
00162     KEY_NOP,            /* 0x65 */
00163     KEY_BACKSPACE,      /* 0x66 */
00164     KEY_MUHENKAN,       /* 0x67 */
00165     KEY_NOP,            /* 0x68 */
00166     KEY_END,            /* 0x69 */
00167     '¥¥',             /* 0x6a */
00168     KEY_LEFT,           /* 0x6b */
00169     KEY_HOME,           /* 0x6c */
00170     KEY_NOP,            /* 0x6d */
00171     KEY_NOP,            /* 0x6e */
00172     KEY_NOP,            /* 0x6f */
00173     KEY_INS,            /* 0x70 */
00174     KEY_DEL,            /* 0x71 */
00175     KEY_DOWN,           /* 0x72 */
00176     KEY_NOP,            /* 0x73 */
00177     KEY_RIGHT,          /* 0x74 */
00178     KEY_UP,             /* 0x75 */
00179     KEY_ESC,            /* 0x76 */
00180     KEY_NUM,            /* 0x77 */
00181     KEY_F11,            /* 0x78 */
00182     KEY_NOP,            /* 0x79 */
00183     KEY_PAGEDOWN,       /* 0x7a */
00184     KEY_NOP,            /* 0x7b */
00185     KEY_PRINT,          /* 0x7c */
00186     KEY_PAGEUP,         /* 0x7d */
00187     KEY_SCROLL,         /* 0x7e */
00188     KEY_NOP,            /* 0x7f */
00189     KEY_NOP,            /* 0x80 */
00190     KEY_NOP,            /* 0x81 */
00191     KEY_NOP,            /* 0x82 */
00192     KEY_F7,             /* 0x83 */
00193 };
00194 
00195 
00196 /*=================================================================================================
00197 プロトタイプ宣言
00198 =================================================================================================*/
00199  static BOOL PS2_key_put(unsigned char buf);
00200  static void PS2_code_buf_clear(void);
00201  static BOOL PS2_code_put(unsigned char buf);
00202  static unsigned char PS2_code_get(void);
00203  static unsigned char PS2_code_get_buf(void);
00204  static BOOL PS2_code_get_key(void);
00205 
00206 
00207 /**************************************************************************************************
00208 I/Oピン状態変化割り込み : 割り込みが足りない... INT0に配線すれば良かった...
00209 **************************************************************************************************/
00210 
00211 /* アセンブラ命令で MSB <--> LSBを変えられたはずだけど、調べるのが面倒なのでパス */
00212  static unsigned char reverse (unsigned char buf)
00213 {
00214     return(
00215             ((buf & 0b00000001) << 7)
00216         +   ((buf & 0b00000010) << 5)
00217         +   ((buf & 0b00000100) << 3)
00218         +   ((buf & 0b00001000) << 1)
00219         +   ((buf & 0b00010000) >> 1)
00220         +   ((buf & 0b00100000) >> 3)
00221         +   ((buf & 0b01000000) >> 5)
00222         +   ((buf & 0b10000000) >> 7)
00223     );
00224 
00225 }
00226 
00227 void __attribute__((interrupt, auto_psv)) _CNInterrupt(void)
00228 {
00229     static unsigned int  last  = 0x0000;
00230     static unsigned int  buf   = 0x0000;
00231     static unsigned char count = 0x00;
00232 
00233     IFS1bits.CNIF = 0;
00234 
00235     /* クロックが送られてきたら、処理を行う */
00236     if(GPIO_PS2_CLK == 0){
00237 
00238         /* 久しぶりのクロックならば、バッファをクリアする */
00239         if(RTC_get_ticks(last, rtc.tick) > 5){
00240             buf = 0x0000;
00241             count = 0x00;
00242         }
00243         last = rtc.tick;
00244 
00245         /* データ受信処理 */
00246         buf = (buf << 1) + GPIO_PS2_DAT;
00247         count++;
00248 
00249         /* 正しいパケットならば、スキャンコードバッファへ送る */
00250         if(count > 10){
00251             PS2_code_put(reverse(buf >> 2));        /* パリティビットは無視 */
00252             buf = 0x0000;
00253             count = 0x00;
00254         }
00255 
00256     } else {
00257         /* 立ち上がりエッジでは、何もしない */
00258     }
00259 
00260 
00261     return;
00262 }
00263 
00264 
00265 /**************************************************************************************************
00266 初期化
00267 **************************************************************************************************/
00268 void PS2_init(void)
00269 {
00270     PS2_key_buf_clear();
00271     PS2_code_buf_clear();
00272 
00273     ps2.wait = 3000;
00274 
00275     CNEN2bits.CN22IE = 1;
00276     IPC4bits.CNIP = 5;
00277     IEC1bits.CNIE = 1;
00278     IFS1bits.CNIF = 0;
00279 
00280     return;
00281 }
00282 
00283 
00284 /**************************************************************************************************
00285 プロトコル処理
00286 **************************************************************************************************/
00287 BOOL PS2_main(void)
00288 {
00289     /* スキャンコード -> キー変換処理 */
00290     PS2_code_get_key();
00291     return(TRUE);
00292 }
00293 
00294 /**************************************************************************************************
00295 キーバッファクリア
00296 **************************************************************************************************/
00297 void PS2_key_buf_clear(void)
00298 {
00299     key_stptr = 0x00;
00300     key_enptr = 0x00;
00301 
00302     PS2_code_buf_clear();
00303 
00304     return;
00305 }
00306 
00307 
00308 /*-------------------------------------------------------------------------------------------------
00309 スキャンコードバッファクリア
00310 -------------------------------------------------------------------------------------------------*/
00311  static void PS2_code_buf_clear(void)
00312 {
00313     code_stptr = 0x00;
00314     code_enptr = 0x00;
00315     return;
00316 }
00317 
00318 
00319 /*-------------------------------------------------------------------------------------------------
00320 キーバッファへ入れる
00321 -------------------------------------------------------------------------------------------------*/
00322  static BOOL PS2_key_put(unsigned char buf)
00323 {
00324     unsigned char nxptr;
00325 
00326     nxptr = key_enptr + 1;
00327     if(nxptr >= PS2_KEY_BUFFER_SIZE) nxptr = 0;
00328 
00329     /* Buffer is Full */
00330     if(key_stptr == nxptr){
00331         return(FALSE);
00332     }
00333 
00334     key_buf[ key_enptr ] = buf;
00335     key_enptr = nxptr;
00336 
00337     return(TRUE);
00338 }
00339 
00340 
00341 /*-------------------------------------------------------------------------------------------------
00342 スキャンコードバッファへ入れる
00343 -------------------------------------------------------------------------------------------------*/
00344  static BOOL PS2_code_put(unsigned char buf)
00345 {
00346     unsigned char nxptr;
00347 
00348     nxptr = code_enptr + 1;
00349     if(nxptr >= PS2_CODE_BUFFER_SIZE) nxptr = 0;
00350 
00351     /* Buffer is Full */
00352     if(code_stptr == nxptr){
00353         return(FALSE);
00354     }
00355 
00356     code_buf[ code_enptr ] = buf;
00357     code_enptr = nxptr;
00358 
00359     return(TRUE);
00360 }
00361 
00362 
00363 /**************************************************************************************************
00364 キーバッファから取得する
00365 **************************************************************************************************/
00366 unsigned char PS2_key_get(void)
00367 {
00368     unsigned char buf, nxptr;
00369 
00370     /* Buffer is Empty */
00371     if(key_stptr == key_enptr){
00372         return(0x00);
00373     }
00374 
00375     buf = key_buf[ key_stptr ];
00376 
00377     nxptr = key_stptr + 1;
00378     if(nxptr >= PS2_KEY_BUFFER_SIZE) nxptr = 0;
00379     key_stptr = nxptr;
00380 
00381     return(buf);
00382 }
00383 
00384 /* 確認するだけ... */
00385 unsigned char PS2_key_check(void)
00386 {
00387     /* Buffer is Empty */
00388     if(key_stptr == key_enptr){
00389         return(0x00);
00390     }
00391 
00392     return(key_buf[ key_stptr ]);
00393 }
00394 
00395 
00396 /*-------------------------------------------------------------------------------------------------
00397 スキャンコードバッファから取得する
00398 -------------------------------------------------------------------------------------------------*/
00399  static unsigned char PS2_code_get(void)
00400 {
00401     unsigned char buf, nxptr;
00402 
00403     /* Buffer is Empty */
00404     if(code_stptr == code_enptr){
00405         return(0x00);
00406     }
00407 
00408     buf = code_buf[ code_stptr ];
00409 
00410     nxptr = code_stptr + 1;
00411     if(nxptr >= PS2_CODE_BUFFER_SIZE) nxptr = 0;
00412     code_stptr = nxptr;
00413 
00414     return(buf);
00415 }
00416 
00417 
00418 /*-------------------------------------------------------------------------------------------------
00419 使用済バッファサイズを得る
00420 -------------------------------------------------------------------------------------------------*/
00421  unsigned char PS2_code_get_buf(void)
00422 {
00423     if(code_stptr >= code_enptr)    return(code_stptr - code_enptr);
00424     else                            return(code_stptr + code_enptr);
00425 }
00426 
00427 
00428 /*-------------------------------------------------------------------------------------------------
00429 スキャンコード -> キーコードへ変換する
00430 ---------------------------------------------------------------------------------------------------
00431 データの順番 : [CODE][RELEASE][CODE][CODE][RELEASE], etc...
00432 まじめにリリース処理を入れるのは面倒なので、インターバルでみる (^^;
00433 -------------------------------------------------------------------------------------------------*/
00434  static BOOL PS2_code_get_key(void)
00435 {
00436     unsigned char buf;
00437     static unsigned char last = 0x00;
00438     static unsigned int tick = 0x0000;
00439 
00440     while((buf = PS2_code_get()) != 0x00){
00441         if(RTC_get_ticks(tick, rtc.tick) > ps2.wait){
00442             last = 0x00;
00443         }
00444 
00445         /* 特定のコマンドを無視する. F0, E0, E1 など */
00446         if(buf != last && buf < sizeof(key)){
00447             if(key[buf] != KEY_NOP){
00448                 if(!PS2_key_put(key[buf])){
00449                     PS2_key_buf_clear();
00450                     PS2_key_put(key[buf]);
00451                 }
00452                 last = buf;
00453                 tick = rtc.tick;
00454             }
00455         }
00456     }
00457 
00458     return(TRUE);
00459 }

OpenSSMに対してThu Sep 9 2010 00:03:04に生成されました。  doxygen 1.7.1