Zhiyong Li / keypad
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Keypad.cpp Source File

Keypad.cpp

00001 #include "Keypad.h"
00002 
00003 extern Serial PC;
00004 
00005 void Keypad::_cbRow0Rise()
00006 {
00007     _checkIndex(0, _rows[0]);
00008 }
00009 
00010 void Keypad::_cbRow1Rise()
00011 {
00012     _checkIndex(1, _rows[1]);
00013 }
00014 
00015 void Keypad::_cbRow2Rise()
00016 {
00017     _checkIndex(2, _rows[2]);
00018 }
00019 
00020 void Keypad::_cbRow3Rise()
00021 {
00022     _checkIndex(3, _rows[3]);
00023 }
00024 
00025 void
00026 Keypad::_setupRiseTrigger
00027 (
00028 )
00029 {
00030     if (_rows[0]) {
00031         _rows[0]->rise(callback(this, &Keypad::_cbRow0Rise));
00032     }
00033 
00034     if (_rows[1]) {
00035         _rows[1]->rise(callback(this, &Keypad::_cbRow1Rise));
00036     }
00037 
00038     if (_rows[2]) {
00039         _rows[2]->rise(callback(this, &Keypad::_cbRow2Rise));
00040     }
00041 
00042     if (_rows[3]) {
00043         _rows[3]->rise(callback(this, &Keypad::_cbRow3Rise));
00044     }
00045 }
00046 
00047 
00048 Keypad::Keypad
00049 (PinName      r0
00050 ,PinName      r1
00051 ,PinName      r2
00052 ,PinName      r3
00053 ,PinName      c0
00054 ,PinName      c1
00055 ,PinName      c2
00056 ,PinName      c3
00057 ,int          debounce_ms
00058 )
00059 {
00060     PinName rPins[4] = {r0, r1, r2, r3};
00061     PinName cPins[4] = {c0, c1, c2, c3};
00062 
00063     for (int i = 0; i < 4; i++) {
00064         _rows[i] = NULL;
00065         _cols[i] = NULL;
00066     }
00067     
00068     _nRow = 0;
00069     for (int i = 0; i < 4; i++) {
00070         if (rPins[i] != NC) {
00071             // PullDown required, otherwise won't work on STM32F407, most likely not on other STM32 MCUs as well
00072             // Without PullDown, InterruptIn seems to float
00073             _rows[i] = new InterruptIn(rPins[i], PullDown);
00074             _nRow++;
00075         } else
00076             break;
00077     }
00078     _setupRiseTrigger();
00079     
00080     _nCol = 0;
00081     for (int i = 0; i < 4; i++) {
00082         if (cPins[i] != NC) {
00083             _cols[i] = new DigitalOut(cPins[i]);
00084             _nCol++;
00085         } else
00086             break;
00087     }
00088 
00089     _debounce = debounce_ms; 
00090 }
00091 
00092 Keypad::~Keypad
00093 ()
00094 {
00095     for (int i = 0; i < 4; i++) {
00096         if (_rows[i] != 0)
00097             delete _rows[i];
00098     }
00099 
00100     for (int i = 0; i < 4; i++) {
00101         if (_cols[i] != 0)
00102             delete _cols[i];
00103     }
00104 }
00105 
00106 void
00107 Keypad::start
00108 (
00109 )
00110 {
00111     for (int i = 0; i < _nCol; i++)
00112         _cols[i]->write(1);
00113 }
00114 
00115 void
00116 Keypad::stop
00117 (
00118 )
00119 {
00120     for (int i = 0; i < _nCol; i++)
00121         _cols[i++]->write(0);
00122 }
00123 
00124 void
00125 Keypad::attach
00126 (uint32_t     (*fptr)(uint32_t index)
00127 )
00128 {
00129     _callback.attach(fptr);
00130 }
00131 
00132 void
00133 Keypad::_checkIndex
00134 (int          row
00135 ,InterruptIn *therow
00136 )
00137 {
00138     // Blocking waiting not allowed by mbed-os-5
00139     // Keypad seems to work fine without debounce
00140 #ifdef THREAD_H
00141     //Thread::wait(_debounce);
00142 #else
00143     //wait_ms(_debounce);
00144 #endif
00145 
00146     if (therow->read() == 0)
00147         return;
00148 
00149     int c;
00150     for (c = 0; c < _nCol; c++) {
00151         _cols[c]->write(0); // de-energize the column
00152         if (therow->read() == 0) {
00153             break;
00154         }
00155     }
00156     
00157     int index = row * _nCol + c;
00158     _callback.call(index);
00159     start(); // Re-energize all columns
00160 }
00161