More or less as an exercise, I'm attempting to turn an old 1981 industrial keyboard into a USB keyboard with my shiny new CY8CKIT-059. It's mostly going really well --- designing circuits with Psoc Creator is great, I've done the necessary (trivial) hardware modifications, and decoding the keyboard matrix works fine in a bench test.
The problem is that when I ramp the speed up from a few hertz to the 500Hz to 1kHz I need for real life, I start receiving lots of spurious signals coming in in certain keys.
The way the keyboard originally worked is an 8048 microcontroller drove the columns of the keyboard matrix via a 74145 encoder, which takes a 4-bit value and energises one of ten column drivers. The keyswitches then connect these to one of eight row senses, which are wired to the microcontroller's GPIO pins. I've kept the same design, simply replacing the original 8048 with the CY8CKIT-059 --- the pinout's even mostly compatible.
Project wise, I have a 500Hz clock driving a 4-bit counter; this is connected to the 74145 inputs. So, on every rising edge, the counter increments and causes the 74145 to energise another column. I have an interrupt attached to the same clock via a NOT gate, so every falling edge the interrupt fires --- this is make sure that all the GPIO has had time to settle. The software then looks at which column is being driven, reads the matrix, and figures out which keys have been pressed or released.
When the sense clock is running at above about 200Hz, I see the same row being asserted for several adjacent columns. So, I'll see that column 3 is energised and row 4 is asserted... then at the next interrupt column 4 is energised and row 4 is asserted... then at the next interrupt column 5 is energised and row 4 is still asserted. Columns 6 and above and 2 and below are fine (for this example).
This only happens with a fast clock, so it's not a wiring issue on my board. It's completely repeatable, and only applies to some keys (always the same ones, always the same spurious columns). The board has no relevant capacitors that I can find on the board (there's one left, between 0V and 5V). My output pins are set to 'strong drive' (and are connected to the column drivers via the 74145 anyway); the keyswitches are literal physical switches which connect a column and a row. The column drivers are active low, so when the user pressed a key the relevant row pin is pulled low; they're set to 'resistive pullup'.
I don't have access to a scope; I'm going to try to scrounge one up. But until then --- are there any obvious things I need to do / or not do? I'm out of ideas.
74145 datasheet here: DM74145.pdf - Google Drive (and it claims a 30ns switching time, which is way faster than the 1ms period between my sense clock ticks).
I would suggest to set the output mode of the probe pins from transparent to single sync. Maybe there are some glitches from the counter output.
I didn't know that setting was there until I went to look for it --- ta. But it hasn't helped.
I've mapped the misbehaving keys and they're clustered on a single matrix row. I think it's behaving as if there's a capacitor on that particular row sensing line, so that once it sees the energised column, it stays energised for the next few columns. But there's no such capacitor on the board --- the only one left is across the 0V/5V power supply line!
This particular row sensing line is connected to P0.4, which is one of the opamp pins in the psoc5. Is there any internal capacitance there?
I have actually managed to work around this by adjusting my design --- when a key is pressed, we stop scanning the matrix and instead focus on the single row with pressed keys until the key is released. This actually seems to work, much to my surprise. I also note that while I was investigating the old defunct microcontroller, it behaved in the same way. Maybe this is just a feature of the board. It does have some long tracks on it...
When you want to reduce ringing due to long lines you may try setting the pin's slew rate from fast to slow.