I tracked down a bug in the keyboard scanning of the DIY4 today. I thought there needed to be a delay in the scan routine between writing the scan lines and reading the return lines, but it turns out that another delay is needed also.The Energy Micro EFM32G “Gecko” family of microcontrollers have very flexible GPIO port configuration. Each pin can have an independently selected mode, of which there are many choices. Output drive is configurable, and inputs can have noise filtering. Outputs can be open source or open drain, with or without pulldowns or pullups. Inputs can also have pulldowns or pullups.
For the keyboard, I program the scan lines as open-drain outputs with pullups, and the return lines as inputs with pullups. What I found was that my keyboard scan code was reliable at 1 MHz, but had subtle problems at 7 MHz and not-so-subtle problems at 14 MHz and higher.
What I figured out with Richard Ottosen’s help is that because I’m using open-drain outputs for the scan lines, when I stop driving one scan line low, and start driving the next, the first line takes longer than I anticipated to get pulled high. It needs to rise from very close to 0V to 0.7 Vdd, 2.17V, before I drive the next scan line low.
The data sheet gives a typical pullup value of 40 Kohms, but doesn’t specify a minimum or maximum. To be conservative, we’ll assume a maximum of 100 Kohms. If we also assume that the total capacitance on the line is 10 pF, that gives a time constant of 1 us. To reach 3/4 of Vdd will require about 1.4 time constants, so I need to delay 1.4 us between releasing one scan line and driving the next. At 14 MHz that is about 20 instructions, so for now I’ve put in 20 NOP instructions. That fixed both the obvious keyboard scan problems, and a not-so-obvious problem where the ON key would terminate a running program, but the R/S key would not.
A better solution might be upon releasing a scan line, to briefly change the pin mode from open drain with pullup to totem pole actively driven high, then back again. That would pull up the line fast enough that it would be essentially processor speed independent.
In the course of testing this we also made some other observations:
- The bit-banging SPI for the FRAM works at 28 MHz with no additional delays required.
- The FRAM port configuration doesn’t raise the deep sleep mode current.
- Some of the other recent keyboard scanning changes, namely not raising the processor speed unless at least one key is pressed, reduces the deep sleep mode current from 20 uA to 10 uA.