Electronic Load 1.0 Programmable Constant Current Sink

Functions | Variables
keyboard.c File Reference

Routines for handling the Keyboard Matrix and the Encoder. More...

Include dependency graph for keyboard.c:

## Functions
KEY_CHAR_t | GetKey (void)
| Gets the next key from the keyboard buffer. More...
PutCharReturn_t | PutKey (KEY_CHAR_t c)
| Puts a key into the keyboard buffer. More...

## Variables
KEY_CHAR_t | buffer [KEYBUFSIZE]
| Keyboard buffer. More...
uint8_t | bufReadPtr
| Read Pointer Index of the keyboard buffer. The buffer is defined to be empty if Read PTR == Write PTR. More...
uint8_t | bufWritePtr
| Write Pointer Index of the keyboard buffer. The buffer is defined to be empty if Read PTR == Write PTR. More...
volatile uint8_t | keyboardLocked
| Lock status of the keyboard. More...
uint8_t | keynum
| Scancode of a key (0..11 or 255) More...
volatile uint8_t | keyPressed
| Contains the key pressed. Set it to KEY_NONE after usage. More...
uint8_t | keyTimer [KEY_RETLINES *KEY_SCANLINES]
| Starts counting at 0 as soon as a Key is pressed. Topped at KEY_REPEAT_DELAY. More...
uint8_t | lastRot
| Last value of the rotary encoder (0..3) More...
uint8_t | lastRotButton
| Last value of the rotary encoder pushbutton (0 or 1) More...
const char decodeMatrix [] | PROGMEM ={KEY_CANCEL,'7','4','1','0','8','5','2',KEY_ENTER,'9','6','3'}
| Decodes key value from scancode. The Scancode is the Index of this Table. More...
uint8_t | repeatRateCnt
| Counts as long as a Key is pressed from 0 to KEY_REPEAT_RATE and issues the key again on overflow. More...
uint8_t | rot
| Current value of the rotary encoder (0..3) More...
uint8_t | rotButton
| Current value of the rotary encoder pushbutton (0 or 1) More...
uint8_t | scancnt
| Counter for current scan line. More...

## Detailed Description

Routines for handling the Keyboard Matrix and the Encoder.

Author
  Robert Loos rober.nosp@m.t.lo.nosp@m.os@lo.nosp@m.oswe.nosp@m.b.de

Copyright
  Copyright (C) 2014 Robert Loos http://www.loosweb.de

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

This file contains routines for handling a key-matrix of up to 64 keys. In this project, we use only three scanlines and four returnlines. The macros KEYPORT, KEYPIN and KEYDDR have to be defined to reflect your actual hardware. KEY_SCANLINES is the number of scan lines (1..4) If a key is pressed, its value is stored in the keyboard buffer. The main program then reads the keys from the buffer. It reads KEY_NONE if no more keyboard events are available. It also handles the rotary encoder. Rotations and the pushbutton are reflected as keyboard events.
Note that we use the two upper bits of the character code as flags, so the decodeMatrix must not contain values above 0x3F! We have a numerical keyboard for now so digits are returned as their ASCII-value (which is below 0x40) and special values also return values below 0x40.

A Keystroke results in at least two events stored in the keyboard buffer. The order of the events is as follows:

- <Keycode> | KEY_PRESSED as soon as the Key is pressed
- <Keycode> | KEY_PRESSED_LONG if the Key is still pressed after some time
- <Keycode> | KEY_REPEAT is repeatedly issued if the Key is still pressed even longer
- <Keycode> | KEY_RELEASED as soon as the Key is released

Note
  If the keyboard buffer is full the event will be discarded. This might also happen with the KEY_RELEASED event and keys might to appear stucked then! So care has to be taken by the main program to process the events fast enough and/or the keyboard buffer to be long enough.

By the use of these four flags the main program can react very flexible to user input, even differently in different situations.
While processing e.g. a number input field, the KEY_REPEAT event can be used to quickly enter data whereas in other situations, KEY_REPEAT events can be ignored and instead KEY_RELEASED- and KEY_PRESSED_LONG-events can be used e.g. to recall or store presets.
Simply discard events you do not need.

Each event can be disabled by commenting out the definition of KEYBOARD_WITH_xxx in keyboard.h to save some program space and usage of the keyboard buffer if necessary.

Note
  If and only if all Events except KEY_PRESSED (which is 0) are disabled, the decode matrix may contain values >0x3F. If you really need ASCII-characters you may want to define KEY_CHAR_t to uint16_t (and adjust the values of keyboard flags, of course). This would double the size of the keyboard buffer and might increase the size of routines using KEY_CHAR_t.

## Function Documentation

## ◆ PutKey()

PutCharReturn_t PutKey | ( | KEY_CHAR_t | c | ) |

Puts a key into the keyboard buffer.

Parameters

  c | The character

Returns
  PUTKEY_DONE on success, PUTKEY_ERROR_BUFFER_FULL if the character has been discarded due to buffer full, PUTKEY_ERROR_KEYBOARD_LOCKED if keyboard is locked.

If the buffer is full or the keyboard is locked, the character is discarded. Check the return value of PutKey() if desirable.
You can call this routine from anywhere in your program to simulate keyboard events but be aware of the keyboard buffer length. It is good policy to honor the return value to make sure the key has actually been placed in the queue.

Here is the call graph for this function:

## ◆ GetKey()

KEY_CHAR_t GetKey | ( | void |  | ) |

Gets the next key from the keyboard buffer.

Returns
  The key

If the keyboard buffer is empty the function returns KEY_NONE. Be sure to define KEY_NONE to a value not included in your decode matrix!

Note
  You can test the keyboard buffer with keyStat() wich will return true if keystrokes are pending without actually calling GetKey().

## Variable Documentation

## ◆ scancnt

uint8_t scancnt

Counter for current scan line.

## ◆ keynum

uint8_t keynum

Scancode of a key (0..11 or 255)

## ◆ PROGMEM

const char rotMatrix [] PROGMEM ={KEY_CANCEL,'7','4','1','0','8','5','2',KEY_ENTER,'9','6','3'}

Decodes key value from scancode. The Scancode is the Index of this Table.

Matrix for decoding the rotary encoder.

The index is (lastRot<<2 | rot). A 0 means no (valid) transition.

## ◆ buffer

KEY_CHAR_t buffer[KEYBUFSIZE]

Keyboard buffer.

## ◆ bufReadPtr

uint8_t bufReadPtr

Read Pointer Index of the keyboard buffer. The buffer is defined to be empty if Read PTR == Write PTR.

## ◆ bufWritePtr

uint8_t bufWritePtr

Write Pointer Index of the keyboard buffer. The buffer is defined to be empty if Read PTR == Write PTR.

## ◆ keyTimer

uint8_t keyTimer[KEY_RETLINES *KEY_SCANLINES]

Starts counting at 0 as soon as a Key is pressed. Topped at KEY_REPEAT_DELAY.

## ◆ lastRot

uint8_t lastRot

Last value of the rotary encoder (0..3)

## ◆ rot

uint8_t rot

Current value of the rotary encoder (0..3)

## ◆ lastRotButton

uint8_t lastRotButton

Last value of the rotary encoder pushbutton (0 or 1)

## ◆ rotButton

uint8_t rotButton

Current value of the rotary encoder pushbutton (0 or 1)

## ◆ repeatRateCnt

uint8_t repeatRateCnt

Counts as long as a Key is pressed from 0 to KEY_REPEAT_RATE and issues the key again on overflow.

## ◆ keyPressed

volatile uint8_t keyPressed

Contains the key pressed. Set it to KEY_NONE after usage.

Normally, the getKey-function should be used. This variable has been introduced to wait for keys although the keyboard is locked. When locked, keys will not be written into the keyboard buffer but keyPressed is set to the value of the key.

## ◆ keyboardLocked

volatile uint8_t keyboardLocked

Lock status of the keyboard.

If !=0, keys and encoder actions are no longer placed into the keyboard buffer. Alternatively, the keyPressed- variable is set to allow a "wait-for-any-key".
This is used when running test programs to avoid user interference. The keyboard can be locked by USB-commands to prevent user actions to interfere with program activity.