Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of RA8875 by
Revision 75:ca78388cfd77, committed 2014-11-28
- Comitter:
- WiredHome
- Date:
- Fri Nov 28 22:37:53 2014 +0000
- Parent:
- 74:686faa218914
- Child:
- 76:c981284eb513
- Commit message:
- Finalized the KeyPad support using the RA8875 built-in keyscan support.
Changed in this revision
--- a/RA8875.cpp Sun Nov 09 20:38:49 2014 +0000
+++ b/RA8875.cpp Fri Nov 28 22:37:53 2014 +0000
@@ -69,6 +69,15 @@
// uSec should it wait between each polling activity.
#define POLLWAITuSec 10
+// Private RawKeyMap for the Keyboard interface
+static const uint8_t KeyMap[22] =
+ {
+ 0,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 255
+ };
+
RA8875::RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, const char *name)
: GraphicsDisplay(name)
@@ -82,6 +91,7 @@
Reset();
Power(true);
Backlight_u8(255);
+ pKeyMap = KeyMap;
#ifdef PERF_METRICS
performance.start();
ClearPerformance();
@@ -265,49 +275,112 @@
// #### end of touch panel code additions
-RetCode_t RA8875::KeypadInit(bool scanEnable, bool longDetect, uint8_t sampleTime, uint8_t scanFrequency,
- uint8_t longTimeAdjustment, bool interruptEnable, bool wakeupEnable)
+RetCode_t RA8875::KeypadInit(bool scanEnable, bool longDetect, uint8_t sampleTime, uint8_t scanFrequency,
+ uint8_t longTimeAdjustment, bool interruptEnable, bool wakeupEnable)
{
uint8_t value = 0;
-
+
if (sampleTime > 3 || scanFrequency > 7 || longTimeAdjustment > 3)
return bad_parameter;
value |= (scanEnable) ? 0x80 : 0x00;
value |= (longDetect) ? 0x40 : 0x00;
value |= (sampleTime & 0x03) << 4;
value |= (scanFrequency & 0x07);
- WriteCommand(0xC0, value); // Enable Key Scan (and ignore possibility of an error)
-
+ WriteCommand(0xC0, value); // KSCR1 - Enable Key Scan (and ignore possibility of an error)
+
value = 0;
value |= (wakeupEnable) ? 0x80 : 0x00;
value |= (longTimeAdjustment & 0x03) << 2;
- WriteCommand(0xC1, value); // (and ignore possibility of an error)
-
- value = ReadCommand(0xF0); // (and ignore possibility of an error)
+ WriteCommand(0xC1, value); // KSCR2 - (and ignore possibility of an error)
+
+ value = ReadCommand(0xF0); // (and ignore possibility of an error)
value &= ~0x10;
value |= (interruptEnable) ? 0x10 : 0x00;
- return WriteCommand(0xF0, value);
+ return WriteCommand(0xF0, value); // INT
}
-bool RA8875::_kbhit(void)
+RetCode_t RA8875::SetKeyMap(const uint8_t * CodeList)
+{
+ pKeyMap = CodeList;
+ return noerror;
+}
+
+bool RA8875::readable(void)
{
return (ReadCommand(0xF1) & 0x10); // check KS status - true if kbhit
}
-uint8_t RA8875::_getch(void)
+uint8_t RA8875::getc(void)
{
- while (!_kbhit()) {
+ //#define GETC_DEV
+ #ifdef GETC_DEV
+ uint8_t keyCode1, keyCode2;
+ #endif
+ uint8_t keyCode3;
+ static uint8_t count = 0;
+ uint8_t col, row;
+ uint8_t key;
+
+ while (!readable()) {
wait_us(POLLWAITuSec);
- COUNTIDLETIME(POLLWAITuSec);
+ // COUNTIDLETIME(POLLWAITuSec); // As it is voluntary to call the getc and pend. Don't tally it.
}
-
// read the key press number
uint8_t keyNumReg = ReadCommand(0xC1) & 0x03;
- // read the key code
- uint8_t keyCode = ReadCommand(0xC2 + keyNumReg);
- // Clear KS status
- WriteCommand(0xF1, 0x10);
- return keyCode;
+ count++;
+ switch (keyNumReg) {
+ case 0x01: // one key
+ keyCode3 = ReadCommand(0xC2);
+ #ifdef GETC_DEV
+ keyCode2 = 0;
+ keyCode1 = 0;
+ #endif
+ break;
+ case 0x02: // two keys
+ keyCode3 = ReadCommand(0xC3);
+ #ifdef GETC_DEV
+ keyCode2 = ReadCommand(0xC2);
+ keyCode1 = 0;
+ #endif
+ break;
+ case 0x03: // three keys
+ keyCode3 = ReadCommand(0xC4);
+ #ifdef GETC_DEV
+ keyCode2 = ReadCommand(0xC3);
+ keyCode1 = ReadCommand(0xC2);
+ #endif
+ break;
+ default: // no keys (key released)
+ keyCode3 = 0xFF;
+ #ifdef GETC_DEV
+ keyCode2 = 0;
+ keyCode1 = 0;
+ #endif
+ break;
+ }
+ if (keyCode3 == 0xFF)
+ key = pKeyMap[0]; // Key value 0
+ else {
+ row = (keyCode3 >> 4) & 0x03;
+ col = (keyCode3 & 7);
+ key = row * 5 + col + 1; // Keys value 1 - 20
+ if (key > 21) {
+ key = 21;
+ }
+ key = pKeyMap[key];
+ key |= (keyCode3 & 0x80); // combine the key held flag
+ }
+ #if GETC_DEV // for Development only
+ SetTextCursor(0, 20);
+ printf(" Reg: %02x\r\n", keyNumReg);
+ printf(" key1: %02x\r\n", keyCode1);
+ printf(" key2: %02x\r\n", keyCode2);
+ printf(" key3: %02x\r\n", keyCode3);
+ printf(" count: %02X\r\n", count);
+ printf(" key: %02X\r\n", key);
+ #endif
+ WriteCommand(0xF1, 0x10); // Clear KS status
+ return key;
}
#ifdef PERF_METRICS
@@ -315,7 +388,7 @@
{
for (int i=0; i<METRICCOUNT; i++)
metrics[i] = 0;
- idlecounter = 0;
+ idletime_usec = 0;
}
void RA8875::RegisterPerformance(method_e method)
@@ -328,7 +401,7 @@
void RA8875::CountIdleTime(uint32_t t)
{
- idlecounter += t;
+ idletime_usec += t;
}
void RA8875::ReportPerformance(Serial & pc)
@@ -337,7 +410,7 @@
for (int i=0; i<METRICCOUNT; i++) {
pc.printf("%10d uS %s\r\n", metrics[i], metricsName[i]);
}
- pc.printf("%10d uS Idle time polling display for ready.\r\n", idlecounter);
+ pc.printf("%10d uS Idle time polling display for ready.\r\n", idletime_usec);
}
#endif
@@ -533,8 +606,8 @@
RetCode_t RA8875::SetTextCursor(loc_t x, loc_t y)
{
- cursor_x = x;
- cursor_y = y; // for non-internal fonts
+ cursor_x = x; // set these values for non-internal fonts
+ cursor_y = y;
WriteCommandW(0x2A, x);
WriteCommandW(0x2C, y);
return noerror;
@@ -1625,9 +1698,9 @@
// /__/ /_____________/ /_____________/ /__/
//
// Everything from here down is test code.
+//
bool SuppressSlowStuff = false;
-
void TextWrapTest(RA8875 & display, Serial & pc)
{
if (!SuppressSlowStuff)
@@ -1646,11 +1719,97 @@
wait_ms(3000);
}
+
+void ShowKey(RA8875 & display, int key)
+{
+ loc_t col, row;
+ dim_t r1 = 25;
+ color_t color = (key & 0x80) ? Red : Green;
+
+ key &= 0x7F; // remove the long-press flag
+ row = (key - 1) / 5;
+ col = (key - 1) % 5;
+ if (col > 5) col = 5;
+ if (row > 4) row = 4;
+ display.circle(450 - + (2 * r1) * col, 200 - (2 * r1) * row, r1-2, color, FILL);
+}
+
+void HideKey(RA8875 & display, int key)
+{
+ loc_t col, row;
+ dim_t r1 = 25;
+
+ row = (key - 1) / 5;
+ col = (key - 1) % 5;
+ if (col > 5) col = 5;
+ if (row > 4) row = 4;
+ display.background(Black);
+ display.circle(450 - (2 * r1) * col, 200 - (2 * r1) * row, r1-2, Black, FILL);
+ display.circle(450 - (2 * r1) * col, 200 - (2 * r1) * row, r1-2, Blue);
+}
+
+void KeyPadTest(RA8875 & display, Serial & pc)
+{
+ const uint8_t myMap[22] = {
+ 0,
+ 'a', 'b', 'c', 'd', 'e',
+ 'f', 'g', 'h', 'i', 'j',
+ 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't',
+ 'x'
+ };
+
+ display.background(Black);
+ display.foreground(Blue);
+ display.cls();
+ display.Backlight_u8(255);
+ display.puts(0,0, "KeyPad Test. Touch the keypad...");
+ pc.printf("\r\n"
+ "Raw KeyPad Test. Keypad returns the key-number.\r\n"
+ "Press [most] any PC keyboard key to advance to next test.\r\n");
+ RetCode_t ret = display.KeypadInit(true, true, 3, 7, 3);
+ if (ret != noerror)
+ pc.printf("returncode from KeypadInit is %d\r\n", ret);
+ int lastKey = 0;
+ while (!pc.readable()) {
+ if (display.readable()) {
+ int key = display.getc();
+ if (key) {
+ if (((key & 0x7F) != lastKey) && (lastKey != 0))
+ HideKey(display, lastKey);
+ ShowKey(display, key);
+ lastKey = key & 0x7F;
+ } else {
+ // erase the last one
+ if (lastKey)
+ HideKey(display, lastKey);
+ }
+ }
+ }
+ (void)pc.getc();
+ pc.printf("\r\n"
+ "Map KeyPad Test. Keypad returns the remapped key 'a' - 't'.\r\n"
+ "Press [most] any PC keyboard key to advance to exit test.\r\n");
+ display.SetKeyMap(myMap);
+ while (!pc.readable()) {
+ if (display.readable()) {
+ int key = display.getc();
+ bool longPress = key & 0x80;
+ display.SetTextCursor(0, 120);
+ display.printf("Long Press: %d\r\n", longPress);
+ display.printf(" Remapped: %c %02X\r\n", (key) ? key & 0x7F : ' ', key);
+ }
+ }
+ (void)pc.getc();
+ display.SetKeyMap();
+ pc.printf("\r\n");
+}
+
void TextCursorTest(RA8875 & display, Serial & pc)
{
- const char * iCursor = "The I-Beam cursor should be visible for this text.\r\n";
- const char * uCursor = "The Underscore cursor should be visible for this text.\r\n";
- const char * bCursor = "The Block cursor should be visible for this text.\r\n";
+ const char * iCursor = "The I-Beam cursor should be visible for this text.\r\n";
+ const char * uCursor = "The Underscore cursor should be visible for this text.\r\n";
+ const char * bCursor = "The Block cursor should be visible for this text.\r\n";
const char * bbCursor = "The Blinking Block cursor should be visible for this text.\r\n";
const char * p;
int delay = 100;
@@ -2198,6 +2357,7 @@
"T - Triangles P - Pixels \r\n"
"C - Circles E - Ellipses\r\n"
"A - Auto Test mode S - Speed Test\r\n"
+ "K - Keypad Test\r\n"
"p - print screen r - reset \r\n"
"l - layer test w - wrapping text \r\n"
#ifdef PERF_METRICS
@@ -2233,6 +2393,9 @@
case 'D':
DOSColorTest(lcd, pc);
break;
+ case 'K':
+ KeyPadTest(lcd, pc);
+ break;
case 'W':
WebColorTest(lcd, pc);
break;
@@ -2283,6 +2446,8 @@
wait_ms(20);
mbed_reset();
break;
+ case ' ':
+ break;
default:
printf("huh?\n");
break;
--- a/RA8875.h Sun Nov 09 20:38:49 2014 +0000
+++ b/RA8875.h Fri Nov 28 22:37:53 2014 +0000
@@ -8,11 +8,11 @@
// Define this to enable code that monitors the performance of various
// graphics commands.
-//#define PERF_METRICS
+#define PERF_METRICS
// What better place for some test code than in here and the companion
// .cpp file. See also the bottom of this file.
-//#define TESTENABLE
+#define TESTENABLE
/// DOS colors - slightly color enhanced
#define Black (color_t)(RGB(0,0,0))
@@ -85,8 +85,7 @@
///
/// @todo Add Scroll support for text.
/// @todo Improve sync between internal and external font support - cursor, window, scroll.
-/// @todo Add Hardware reset signal.
-/// @todo Add Keypad Support.
+/// @todo Add Hardware reset signal - but testing to date indicates it is not needed.
/// @todo Add high level objects - x-y graph, meter, others... but these will
/// probably be best served in another class, since they may not
/// be needed for many uses.
@@ -363,6 +362,7 @@
///
uint8_t TouchPanelReadRaw(loc_t *x, loc_t *y);
+#if 0
/// Append interrupt handler for specific RA8875 interrupt source
///
/// @param[in] bISRType Interrupt Source, should be:
@@ -387,8 +387,7 @@
/// @return none
///
void UnAppendISR(uint8_t bISRType);
-
-
+#endif
/// Initialize the keypad interface on the RA8875 controller.
///
/// Enables the keypad subsystem. It will scan the 4 x 5 matrix
@@ -414,11 +413,43 @@
uint8_t longTimeAdjustment = 0,
bool interruptEnable = false, bool wakeupEnable = false);
+ /// Create Key Code definitions for the key matrix.
+ ///
+ /// This API provides a table of 22 key-code assignments for the matrix of keys.
+ /// This can be used to translate the keys 1 - 20 into some other value, as
+ /// well as to communicate the "no key" (zero) and "error state" (21).
+ ///
+ /// In this way, a keypad could easily emulate a piece of a keyboard, transforming
+ /// 0 - 20 into the values 0, '0', '1', '2', '3', '4', '5', '6', '7', '8',
+ /// '9', '+', '-', '*' , '/', '=', '<bs>', '<cr>', and so on...
+ ///
+ /// @code
+ /// // Return Value by Row, Column Example reassignment
+ /// // Column 0 1 2 3 4
+ /// // +-------------------------+ +-------------------------+
+ /// // Row 0 | 1 2 3 4 5 | | '7' '8' '9' ' ' ' ' |
+ /// // 1 | 6 7 8 9 10 | | '4' '5' '6' '/' '-' |
+ /// // 2 | 11 12 13 14 15 | | '1' '2' '3' '*' '+' |
+ /// // 3 | 16 17 18 19 20 | | '0' '.' ',' ' ' '\n' |
+ /// // +-------------------------+ +-------------------------+
+ /// // Return value 0 = No Key pressed
+ /// // Return value 21 = Error
+ /// @endcode
+ ///
+ /// @param[in] CodeList is a pointer to an always available byte-array
+ /// where the first 22 bytes are used as the transformation
+ /// from raw code to your reassigned value.
+ /// If CodeList is NULL, the original raw value key map is
+ /// restored.
+ /// @returns noerror.
+ ///
+ RetCode_t SetKeyMap(const uint8_t * CodeList = NULL);
+
/// Determine if a key has been hit
///
/// @returns true if a key has been hit
///
- bool _kbhit();
+ bool readable();
/// Blocking read of the keypad.
///
@@ -426,26 +457,18 @@
/// to avoid hanging your processes.
///
/// A keypad connected to the RA8875 is connected in a matrix of 4 rows and 5 columns.
- /// The row where a key is pressed is returned in the lower 2 bits of the upper nibble,
- /// and the column where a key is pressed is returned in the lower 3 bits of the lower nibble.
+ /// When pressed, this method will return a code in the range of 1 through 20, reserving
+ /// the value 0 to indicate that no key is pressed.
///
/// Additionally, if configured to detect a "long press", bit 7 will be set to indicate
/// this. In this situation, first a "normal press" would be detected and signaled and
/// soon after that a "long press" of the same key would be detected and communicated.
///
- /// Return value encoding: LxRR xCCC
- /// L = Long Press was detected
- /// RR = Row number 0 to 3
+ /// @return 8-bit where bit 7 indicates a long press. The remaining bits indicate the
+ /// keypress using 0 = no key pressed, 1 - 20 = the key pressed.
///
- /// @return 8-bit value coded as L0RR 0CCC:
- /// - L = 1 = Long Press detected
- /// - x = 0 = not used
- /// - R = 0-3 = Row Number
- /// - C = 0-4 = Column Number
- ///
- uint8_t _getch();
-
-
+ uint8_t getc();
+
/// Write a command to the display with a word of data.
///
/// This is a high level command, and may invoke several primitives.
@@ -1505,6 +1528,8 @@
///
unsigned char spiread();
+ const uint8_t * pKeyMap;
+
SPI spi; ///< spi port
bool spiWriteSpeed; ///< indicates if the current mode is write or read
unsigned long spiwritefreq; ///< saved write freq
@@ -1531,7 +1556,7 @@
METRICCOUNT
} method_e;
unsigned long metrics[METRICCOUNT];
- unsigned long idlecounter;
+ unsigned long idletime_usec;
void RegisterPerformance(method_e method);
Timer performance;
#endif
--- a/TextDisplay.cpp Sun Nov 09 20:38:49 2014 +0000
+++ b/TextDisplay.cpp Fri Nov 28 22:37:53 2014 +0000
@@ -5,7 +5,7 @@
#include "TextDisplay.h"
-#define DEBUG "Text"
+//#define DEBUG "Text"
// ...
// INFO("Stuff to show %d", var); // new-line is automatically appended
//
