Updated 4X4 keypad code that works on STM32F407 and Mbed-OS-5. InterruptIn on STM32F4 MCUs seem to float without PullDown/Up, without forced PullDown the original code doesn't work on STM32F407 and most likely other STM32 MCUs as well.
Keypad.cpp@11:75328ab1acf4, 2020-01-27 (annotated)
- Committer:
- zhiyong
- Date:
- Mon Jan 27 05:15:16 2020 +0000
- Revision:
- 11:75328ab1acf4
- Parent:
- 10:da060f8c03e8
Added PullDown to InterruptIn initialization so the code can work on STM32F4. Also removed debounce delay in ISR to work on mbed-os-5.; ; Tested working on customized boarded based on Arch_Max/STM32F407VET6.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yoonghm | 10:da060f8c03e8 | 1 | #include "Keypad.h" |
yoonghm | 10:da060f8c03e8 | 2 | |
yoonghm | 10:da060f8c03e8 | 3 | extern Serial PC; |
yoonghm | 10:da060f8c03e8 | 4 | |
yoonghm | 10:da060f8c03e8 | 5 | void Keypad::_cbRow0Rise() |
yoonghm | 10:da060f8c03e8 | 6 | { |
yoonghm | 10:da060f8c03e8 | 7 | _checkIndex(0, _rows[0]); |
yoonghm | 10:da060f8c03e8 | 8 | } |
yoonghm | 10:da060f8c03e8 | 9 | |
yoonghm | 10:da060f8c03e8 | 10 | void Keypad::_cbRow1Rise() |
yoonghm | 10:da060f8c03e8 | 11 | { |
yoonghm | 10:da060f8c03e8 | 12 | _checkIndex(1, _rows[1]); |
yoonghm | 10:da060f8c03e8 | 13 | } |
yoonghm | 10:da060f8c03e8 | 14 | |
yoonghm | 10:da060f8c03e8 | 15 | void Keypad::_cbRow2Rise() |
yoonghm | 10:da060f8c03e8 | 16 | { |
yoonghm | 10:da060f8c03e8 | 17 | _checkIndex(2, _rows[2]); |
yoonghm | 10:da060f8c03e8 | 18 | } |
yoonghm | 10:da060f8c03e8 | 19 | |
yoonghm | 10:da060f8c03e8 | 20 | void Keypad::_cbRow3Rise() |
yoonghm | 10:da060f8c03e8 | 21 | { |
yoonghm | 10:da060f8c03e8 | 22 | _checkIndex(3, _rows[3]); |
yoonghm | 10:da060f8c03e8 | 23 | } |
yoonghm | 10:da060f8c03e8 | 24 | |
yoonghm | 10:da060f8c03e8 | 25 | void |
yoonghm | 10:da060f8c03e8 | 26 | Keypad::_setupRiseTrigger |
yoonghm | 10:da060f8c03e8 | 27 | ( |
yoonghm | 10:da060f8c03e8 | 28 | ) |
yoonghm | 10:da060f8c03e8 | 29 | { |
yoonghm | 10:da060f8c03e8 | 30 | if (_rows[0]) { |
zhiyong | 11:75328ab1acf4 | 31 | _rows[0]->rise(callback(this, &Keypad::_cbRow0Rise)); |
yoonghm | 10:da060f8c03e8 | 32 | } |
yoonghm | 10:da060f8c03e8 | 33 | |
yoonghm | 10:da060f8c03e8 | 34 | if (_rows[1]) { |
zhiyong | 11:75328ab1acf4 | 35 | _rows[1]->rise(callback(this, &Keypad::_cbRow1Rise)); |
yoonghm | 10:da060f8c03e8 | 36 | } |
yoonghm | 10:da060f8c03e8 | 37 | |
yoonghm | 10:da060f8c03e8 | 38 | if (_rows[2]) { |
zhiyong | 11:75328ab1acf4 | 39 | _rows[2]->rise(callback(this, &Keypad::_cbRow2Rise)); |
yoonghm | 10:da060f8c03e8 | 40 | } |
yoonghm | 10:da060f8c03e8 | 41 | |
yoonghm | 10:da060f8c03e8 | 42 | if (_rows[3]) { |
zhiyong | 11:75328ab1acf4 | 43 | _rows[3]->rise(callback(this, &Keypad::_cbRow3Rise)); |
yoonghm | 10:da060f8c03e8 | 44 | } |
yoonghm | 10:da060f8c03e8 | 45 | } |
yoonghm | 10:da060f8c03e8 | 46 | |
yoonghm | 10:da060f8c03e8 | 47 | |
yoonghm | 10:da060f8c03e8 | 48 | Keypad::Keypad |
yoonghm | 10:da060f8c03e8 | 49 | (PinName r0 |
yoonghm | 10:da060f8c03e8 | 50 | ,PinName r1 |
yoonghm | 10:da060f8c03e8 | 51 | ,PinName r2 |
yoonghm | 10:da060f8c03e8 | 52 | ,PinName r3 |
yoonghm | 10:da060f8c03e8 | 53 | ,PinName c0 |
yoonghm | 10:da060f8c03e8 | 54 | ,PinName c1 |
yoonghm | 10:da060f8c03e8 | 55 | ,PinName c2 |
yoonghm | 10:da060f8c03e8 | 56 | ,PinName c3 |
yoonghm | 10:da060f8c03e8 | 57 | ,int debounce_ms |
yoonghm | 10:da060f8c03e8 | 58 | ) |
yoonghm | 10:da060f8c03e8 | 59 | { |
yoonghm | 10:da060f8c03e8 | 60 | PinName rPins[4] = {r0, r1, r2, r3}; |
yoonghm | 10:da060f8c03e8 | 61 | PinName cPins[4] = {c0, c1, c2, c3}; |
yoonghm | 10:da060f8c03e8 | 62 | |
yoonghm | 10:da060f8c03e8 | 63 | for (int i = 0; i < 4; i++) { |
yoonghm | 10:da060f8c03e8 | 64 | _rows[i] = NULL; |
yoonghm | 10:da060f8c03e8 | 65 | _cols[i] = NULL; |
yoonghm | 10:da060f8c03e8 | 66 | } |
yoonghm | 10:da060f8c03e8 | 67 | |
yoonghm | 10:da060f8c03e8 | 68 | _nRow = 0; |
yoonghm | 10:da060f8c03e8 | 69 | for (int i = 0; i < 4; i++) { |
yoonghm | 10:da060f8c03e8 | 70 | if (rPins[i] != NC) { |
zhiyong | 11:75328ab1acf4 | 71 | // PullDown required, otherwise won't work on STM32F407, most likely not on other STM32 MCUs as well |
zhiyong | 11:75328ab1acf4 | 72 | // Without PullDown, InterruptIn seems to float |
zhiyong | 11:75328ab1acf4 | 73 | _rows[i] = new InterruptIn(rPins[i], PullDown); |
yoonghm | 10:da060f8c03e8 | 74 | _nRow++; |
yoonghm | 10:da060f8c03e8 | 75 | } else |
yoonghm | 10:da060f8c03e8 | 76 | break; |
yoonghm | 10:da060f8c03e8 | 77 | } |
yoonghm | 10:da060f8c03e8 | 78 | _setupRiseTrigger(); |
yoonghm | 10:da060f8c03e8 | 79 | |
yoonghm | 10:da060f8c03e8 | 80 | _nCol = 0; |
yoonghm | 10:da060f8c03e8 | 81 | for (int i = 0; i < 4; i++) { |
yoonghm | 10:da060f8c03e8 | 82 | if (cPins[i] != NC) { |
yoonghm | 10:da060f8c03e8 | 83 | _cols[i] = new DigitalOut(cPins[i]); |
yoonghm | 10:da060f8c03e8 | 84 | _nCol++; |
yoonghm | 10:da060f8c03e8 | 85 | } else |
yoonghm | 10:da060f8c03e8 | 86 | break; |
yoonghm | 10:da060f8c03e8 | 87 | } |
yoonghm | 10:da060f8c03e8 | 88 | |
yoonghm | 10:da060f8c03e8 | 89 | _debounce = debounce_ms; |
yoonghm | 10:da060f8c03e8 | 90 | } |
yoonghm | 10:da060f8c03e8 | 91 | |
yoonghm | 10:da060f8c03e8 | 92 | Keypad::~Keypad |
yoonghm | 10:da060f8c03e8 | 93 | () |
yoonghm | 10:da060f8c03e8 | 94 | { |
yoonghm | 10:da060f8c03e8 | 95 | for (int i = 0; i < 4; i++) { |
yoonghm | 10:da060f8c03e8 | 96 | if (_rows[i] != 0) |
yoonghm | 10:da060f8c03e8 | 97 | delete _rows[i]; |
yoonghm | 10:da060f8c03e8 | 98 | } |
yoonghm | 10:da060f8c03e8 | 99 | |
yoonghm | 10:da060f8c03e8 | 100 | for (int i = 0; i < 4; i++) { |
yoonghm | 10:da060f8c03e8 | 101 | if (_cols[i] != 0) |
yoonghm | 10:da060f8c03e8 | 102 | delete _cols[i]; |
yoonghm | 10:da060f8c03e8 | 103 | } |
yoonghm | 10:da060f8c03e8 | 104 | } |
yoonghm | 10:da060f8c03e8 | 105 | |
yoonghm | 10:da060f8c03e8 | 106 | void |
yoonghm | 10:da060f8c03e8 | 107 | Keypad::start |
yoonghm | 10:da060f8c03e8 | 108 | ( |
yoonghm | 10:da060f8c03e8 | 109 | ) |
yoonghm | 10:da060f8c03e8 | 110 | { |
yoonghm | 10:da060f8c03e8 | 111 | for (int i = 0; i < _nCol; i++) |
yoonghm | 10:da060f8c03e8 | 112 | _cols[i]->write(1); |
yoonghm | 10:da060f8c03e8 | 113 | } |
yoonghm | 10:da060f8c03e8 | 114 | |
yoonghm | 10:da060f8c03e8 | 115 | void |
yoonghm | 10:da060f8c03e8 | 116 | Keypad::stop |
yoonghm | 10:da060f8c03e8 | 117 | ( |
yoonghm | 10:da060f8c03e8 | 118 | ) |
yoonghm | 10:da060f8c03e8 | 119 | { |
yoonghm | 10:da060f8c03e8 | 120 | for (int i = 0; i < _nCol; i++) |
yoonghm | 10:da060f8c03e8 | 121 | _cols[i++]->write(0); |
yoonghm | 10:da060f8c03e8 | 122 | } |
yoonghm | 10:da060f8c03e8 | 123 | |
yoonghm | 10:da060f8c03e8 | 124 | void |
yoonghm | 10:da060f8c03e8 | 125 | Keypad::attach |
yoonghm | 10:da060f8c03e8 | 126 | (uint32_t (*fptr)(uint32_t index) |
yoonghm | 10:da060f8c03e8 | 127 | ) |
yoonghm | 10:da060f8c03e8 | 128 | { |
yoonghm | 10:da060f8c03e8 | 129 | _callback.attach(fptr); |
yoonghm | 10:da060f8c03e8 | 130 | } |
yoonghm | 10:da060f8c03e8 | 131 | |
yoonghm | 10:da060f8c03e8 | 132 | void |
yoonghm | 10:da060f8c03e8 | 133 | Keypad::_checkIndex |
yoonghm | 10:da060f8c03e8 | 134 | (int row |
yoonghm | 10:da060f8c03e8 | 135 | ,InterruptIn *therow |
yoonghm | 10:da060f8c03e8 | 136 | ) |
yoonghm | 10:da060f8c03e8 | 137 | { |
zhiyong | 11:75328ab1acf4 | 138 | // Blocking waiting not allowed by mbed-os-5 |
zhiyong | 11:75328ab1acf4 | 139 | // Keypad seems to work fine without debounce |
yoonghm | 10:da060f8c03e8 | 140 | #ifdef THREAD_H |
zhiyong | 11:75328ab1acf4 | 141 | //Thread::wait(_debounce); |
yoonghm | 10:da060f8c03e8 | 142 | #else |
zhiyong | 11:75328ab1acf4 | 143 | //wait_ms(_debounce); |
yoonghm | 10:da060f8c03e8 | 144 | #endif |
yoonghm | 10:da060f8c03e8 | 145 | |
yoonghm | 10:da060f8c03e8 | 146 | if (therow->read() == 0) |
yoonghm | 10:da060f8c03e8 | 147 | return; |
yoonghm | 10:da060f8c03e8 | 148 | |
yoonghm | 10:da060f8c03e8 | 149 | int c; |
yoonghm | 10:da060f8c03e8 | 150 | for (c = 0; c < _nCol; c++) { |
yoonghm | 10:da060f8c03e8 | 151 | _cols[c]->write(0); // de-energize the column |
yoonghm | 10:da060f8c03e8 | 152 | if (therow->read() == 0) { |
yoonghm | 10:da060f8c03e8 | 153 | break; |
yoonghm | 10:da060f8c03e8 | 154 | } |
yoonghm | 10:da060f8c03e8 | 155 | } |
yoonghm | 10:da060f8c03e8 | 156 | |
yoonghm | 10:da060f8c03e8 | 157 | int index = row * _nCol + c; |
yoonghm | 10:da060f8c03e8 | 158 | _callback.call(index); |
yoonghm | 10:da060f8c03e8 | 159 | start(); // Re-energize all columns |
yoonghm | 10:da060f8c03e8 | 160 | } |
yoonghm | 10:da060f8c03e8 | 161 |