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.

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?

UserRevisionLine numberNew 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