Kenji Arai / Keypad

Dependents:   Keypad_input_OS2 Keypad_input

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Keypad.cpp Source File

Keypad.cpp

00001 /*
00002  * Mbed Library
00003  *  example:
00004  *      Akizuki AE-KIT45-KEYPAD4X3
00005  *      http://akizukidenshi.com/catalog/g/gK-12229/
00006  *
00007  * Copyright (c) 2017,'20,'21 Kenji Arai / JH1PJL
00008  *  http://www7b.biglobe.ne.jp/~kenjia/
00009  *  https://os.mbed.com/users/kenjiArai/
00010  *      Created:    September 27th, 2017
00011  *      Revised:    February  18th, 2021
00012  */
00013 
00014 #include "Keypad.h"
00015 
00016 //#define DEBUG_LED     // for debug
00017 
00018 #if defined(DEBUG_LED)
00019 extern DigitalOut my_led;
00020 #define LEDON   {my_led=1;}
00021 #define LEDOFF  {my_led=0;}
00022 #else
00023 #define LEDON   {;}
00024 #define LEDOFF  {;}
00025 #endif
00026 
00027 Keypad::Keypad(
00028     PinName kx, PinName ky, PinName kz,
00029     PinName ka, PinName kb, PinName kc, PinName kd
00030 )
00031 {
00032     k_in[0]  = new DigitalIn(ka, PullUp);
00033     k_in[1]  = new DigitalIn(kb, PullUp);
00034     k_in[2]  = new DigitalIn(kc, PullUp);
00035     k_in[3]  = new DigitalIn(kd, PullUp);
00036     k_out[0] = new DigitalInOut(kx, PIN_OUTPUT, OpenDrain, 1);
00037     k_out[1] = new DigitalInOut(ky, PIN_OUTPUT, OpenDrain, 1);
00038     k_out[2] = new DigitalInOut(kz, PIN_OUTPUT, OpenDrain, 1);
00039     key_mode    = 12;
00040     key_in_num  = 4;
00041     key_out_num = 3;
00042     initialize();
00043 }
00044 
00045 Keypad::Keypad(
00046     PinName kx, PinName ky, PinName kz, PinName kw,
00047     PinName ka, PinName kb, PinName kc, PinName kd
00048 )
00049 {
00050     k_in[0]  = new DigitalIn(ka, PullUp);
00051     k_in[1]  = new DigitalIn(kb, PullUp);
00052     k_in[2]  = new DigitalIn(kc, PullUp);
00053     k_in[3]  = new DigitalIn(kd, PullUp);
00054     k_out[0] = new DigitalInOut(kx, PIN_OUTPUT, OpenDrain, 1);
00055     k_out[1] = new DigitalInOut(ky, PIN_OUTPUT, OpenDrain, 1);
00056     k_out[2] = new DigitalInOut(kz, PIN_OUTPUT, OpenDrain, 1);
00057     k_out[3] = new DigitalInOut(kw, PIN_OUTPUT, OpenDrain, 1);
00058     key_mode    = 16;
00059     key_in_num  = 4;
00060     key_out_num = 4;
00061     initialize();
00062 }
00063 
00064 Keypad::Keypad(
00065     PinName kx, PinName ky, PinName kz, PinName kw,
00066     PinName ka, PinName kb, PinName kc, PinName kd, PinName ke
00067 )
00068 {
00069     k_in[0]  = new DigitalIn(ka, PullUp);
00070     k_in[1]  = new DigitalIn(kb, PullUp);
00071     k_in[2]  = new DigitalIn(kc, PullUp);
00072     k_in[3]  = new DigitalIn(kd, PullUp);
00073     k_in[4]  = new DigitalIn(ke, PullUp);
00074     k_out[0] = new DigitalInOut(kx, PIN_OUTPUT, OpenDrain, 1);
00075     k_out[1] = new DigitalInOut(ky, PIN_OUTPUT, OpenDrain, 1);
00076     k_out[2] = new DigitalInOut(kz, PIN_OUTPUT, OpenDrain, 1);
00077     k_out[3] = new DigitalInOut(kw, PIN_OUTPUT, OpenDrain, 1);
00078     key_mode    = 20;
00079     key_in_num  = 5;
00080     key_out_num = 4;
00081     initialize();
00082 }
00083 
00084 Keypad::Keypad(
00085     PinName kx, PinName ky, PinName kz, PinName kw, PinName kv,
00086     PinName ka, PinName kb, PinName kc, PinName kd, PinName ke
00087 )
00088 {
00089     k_in[0]  = new DigitalIn(ka, PullUp);
00090     k_in[1]  = new DigitalIn(kb, PullUp);
00091     k_in[2]  = new DigitalIn(kc, PullUp);
00092     k_in[3]  = new DigitalIn(kd, PullUp);
00093     k_in[4]  = new DigitalIn(ke, PullUp);
00094     k_out[0] = new DigitalInOut(kx, PIN_OUTPUT, OpenDrain, 1);
00095     k_out[1] = new DigitalInOut(ky, PIN_OUTPUT, OpenDrain, 1);
00096     k_out[2] = new DigitalInOut(kz, PIN_OUTPUT, OpenDrain, 1);
00097     k_out[3] = new DigitalInOut(kw, PIN_OUTPUT, OpenDrain, 1);
00098     k_out[4] = new DigitalInOut(kv, PIN_OUTPUT, OpenDrain, 1);
00099     key_mode    = 25;
00100     key_in_num  = 5;
00101     key_out_num = 5;
00102     initialize();
00103 }
00104 
00105 void Keypad::initialize(void)
00106 {
00107     uint8_t j,i;
00108     for (j = 0; j < key_out_num; j++) {
00109         for(i = 0; i < key_in_num; i++) {
00110             key_transent_cntr[j][i] = CHNG_CNT;
00111             key_state[j][i] = OFF_state;
00112         }
00113     }
00114     for(i = 0; i < BF_SIZE; i++) {
00115         buf[i] = 0;
00116     }
00117     read_addr = 0;
00118     write_addr = 0;
00119 #if (MBED_MAJOR_VERSION == 2)
00120     tk.attach_us(callback(this, &Keypad::key_scan), 2000); // 2mS
00121 #else
00122     tk.attach(callback(this, &Keypad::key_scan), 2ms); // 2mS
00123 #endif
00124 }
00125 
00126 void Keypad::key_scan(void)
00127 {
00128     LEDON;
00129     for (int32_t j = 0; j < key_out_num; j++) {
00130         for (int32_t k = 0; k < key_out_num; k++) {
00131             *k_out[k] = 1;
00132         }
00133         *k_out[j] = 0;
00134         wait_us(1);
00135         for (int32_t i = 0; i < key_in_num; i++) {
00136             switch (key_state[j][i]) {
00137                 case OFF_state:
00138                     if (*k_in[i] == 0) { // key on
00139                         key_state[j][i] = OFF_to_ON_transient;
00140                         key_transent_cntr[j][i] = CHNG_CNT;
00141                     }
00142                     break;
00143                 case OFF_to_ON_transient:
00144                     if (*k_in[i] == 0) { // key on
00145                         if (--key_transent_cntr[j][i] < -CHNG_CNT) {
00146                             // save data into buffer
00147                             bf_put(j * key_in_num + i + 1);
00148                             key_state[j][i] = ON_state;
00149                         }
00150                     } else {    // key off
00151                         if (++key_transent_cntr[j][i] > CHNG_CNT) {
00152                             key_state[j][i] = OFF_state;
00153                         }
00154                     }
00155                     break;
00156                 case ON_state:
00157                     if (*k_in[i] == 1) { // key off
00158                         key_state[j][i] = ON_to_OFF_transient;
00159                         key_transent_cntr[j][i] = -CHNG_CNT;
00160                     }
00161                     break;
00162                 case ON_to_OFF_transient:
00163                     if (*k_in[i] == 0) { // key on
00164                         if (--key_transent_cntr[j][i] < -CHNG_CNT) {
00165                             key_state[j][i] = ON_state;
00166                         }
00167                     } else {    // key off
00168                         if (++key_transent_cntr[j][i] > CHNG_CNT) {
00169                             key_state[j][i] = OFF_state;
00170                         }
00171                     }
00172                     break;
00173                 default:    // just in case
00174                     key_state[j][i] = OFF_state;
00175                     break;
00176             }
00177         }
00178     }
00179     for (int32_t k = 0; k < key_out_num; k++) {
00180         *k_out[k] = 1;
00181     }
00182     LEDOFF;
00183 }
00184 
00185 uint8_t Keypad::read(void)
00186 {
00187     return bf_get();
00188 }
00189 
00190 bool Keypad::read_state(uint8_t key_num)
00191 {
00192     
00193     uint8_t x = (key_num - 1) % key_out_num;
00194     uint8_t y = (key_num - 1)/ key_out_num;
00195     if (key_state[y][x] == ON_state) {
00196         return true;
00197     } else {
00198         return false;
00199     }
00200 }
00201 
00202 void Keypad::bf_put(char dt)
00203 {
00204     uint8_t next = write_addr + 1;
00205     if (next == BF_SIZE) {
00206         next = 0;
00207     }
00208     buf[write_addr] = dt;
00209     write_addr = next;
00210 }
00211 
00212 int8_t Keypad::bf_get (void)
00213 {
00214     if (read_addr == write_addr) {
00215         return 0;
00216     }
00217     uint8_t dt = buf[read_addr];
00218     ++read_addr;
00219     if (read_addr == BF_SIZE) {
00220         read_addr = 0;
00221     }
00222     return dt;
00223 }