Fork without short circuits

Dependents:   SaveKeypad

Fork of keypad by HM Yoong

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers keypad.cpp Source File

keypad.cpp

00001 #include "keypad.h"
00002 
00003 Keypad::Keypad(PinName row3, PinName row2, PinName row1, PinName row0,
00004                PinName col3, PinName col2, PinName col1, PinName col0,
00005                int debounce_ms):
00006     _row0(row0), _row1(row1), _row2(row2), _row3(row3),
00007     _cols(col0, col1, col2, col3)
00008 {
00009     _debounce = debounce_ms;
00010     _rows[0] = &_row0;
00011     _rows[1] = &_row1;
00012     _rows[2] = &_row2;
00013     _rows[3] = &_row3;
00014     for (int r = 0; r < row_count; r++)
00015         _rows[r]->mode(PullUp);
00016     _cols.mode(OpenDrain);
00017     _cols.output();
00018 }
00019 
00020 void Keypad::_setupFallTrigger(void)
00021 {
00022     for (int r = 0; r < row_count; r++)
00023         _rows[r]->fall(this, &Keypad::_callback);
00024 }
00025 
00026 void Keypad::Start(void)
00027 {
00028     /* make the columns zero so they can pull rows down */
00029     _cols = 0x00;
00030 }
00031 
00032 void Keypad::Stop(void)
00033 {
00034     /* make the columns one so they cannot pull any rows down anymore */
00035     _cols = ~0x00;
00036 }
00037 
00038 void Keypad::CallAfterInput(uint32_t (*fptr)(uint32_t index))
00039 {
00040     _input.attach(fptr);
00041     _setupFallTrigger();
00042 }
00043 
00044 int Keypad::DebouncedScan()
00045 {
00046     /* debounce */
00047     wait_ms(_debounce);
00048 
00049     return Scan();
00050 }
00051 
00052 int Keypad::Scan()
00053 {
00054     /* lookup row */
00055     int r = -1;
00056     for (r = 0; r < row_count; r++) {
00057         if (*_rows[r] == 0)
00058             break;
00059     }
00060 
00061     /* if we didn't find a valid row, return */
00062     if (!(0 <= r && r < row_count))
00063         return -1;
00064 
00065     /* scan columns to find out which one pulls down the row */
00066     int c = -1;
00067     for (c = 0; c < col_count; c++) {
00068         _cols = ~(1 << c);
00069         if (*_rows[r] == 0)
00070             break;
00071     }
00072 
00073     /* re-energize all columns */
00074     Start();
00075 
00076     /* if we didn't find a valid column, return */
00077     if (!(0 <= c && c < col_count))
00078         return -1;
00079 
00080     return r * col_count + c;
00081 }
00082 
00083 int Keypad::DebouncedScanMultiple()
00084 {
00085     /* debounce */
00086     wait_ms(_debounce);
00087 
00088     return ScanMultiple();
00089 }
00090 
00091 int Keypad::ScanMultiple()
00092 {
00093     int res = 0;
00094     for (int c = 0; c < col_count; c++) {
00095         _cols = ~(1 << c);
00096         for (int r = 0; r < row_count; r++) {
00097             if (*_rows[r] == 0) {
00098                 res |= 1 << (r * col_count + c);
00099             }
00100         }
00101     }
00102 
00103     return res;
00104 }
00105 
00106 void Keypad::_callback()
00107 {
00108     /* lookup */
00109     int position = DebouncedScan();
00110 
00111     /* call back a valid position */
00112     if (position >= 0)
00113         _input.call(position);
00114 }
00115