Many changes: added commandhandler module, macro functions, toggle function and

speed settings. Removed key repetition (no idea why it was there).
This commit is contained in:
Ronald Schaten 2009-02-14 21:11:43 +00:00
parent 68abf87a9c
commit ced5a39988
9 changed files with 263 additions and 19 deletions

View File

@ -16,7 +16,7 @@ HWOBJECTS = modelibmmodelm.o
COMPILE = avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega32 -DF_CPU=12000000L $(DEFINES)
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o $(HWOBJECTS)
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o commandhandler.o $(HWOBJECTS)
# symbolic targets:

187
firmware/commandhandler.c Normal file
View File

@ -0,0 +1,187 @@
/**
* \file commandhandler.c
* \brief TODO
* \author Ronald Schaten <ronald@schatenseite.de>
* \version $Id$
*
* License: TODO
*/
#include "commandhandler.h"
#include "keycodes.h"
#include "tools.h"
#include "modelinterface.h"
// TODO comment
typedef enum {
standard,
commandmode,
macrocommand,
macrodefinition,
macrodelete,
complexcommand
} Commandstate;
static Commandstate commandstate = standard;
#define MACROCOUNT 10
#define MACROLENGTH 20
// macrodefinitions[][0] is the macro-key
Key macrodefinitions[MACROCOUNT][MACROLENGTH + 1];
uint8_t macrocountindex = 0;
uint8_t macrodefinitionindex = 0;
uint8_t getMacroindex(Key macrokey) {
for (uint8_t i = 0; i < MACROCOUNT; i++) {
if ((macrodefinitions[i][0].mode == macrokey.mode) && (macrodefinitions[i][0].key == macrokey.key)) {
return i;
}
}
return MACROCOUNT;
}
void deleteMacroindex(Key macrokey) {
for (uint8_t i = 0; i < MACROCOUNT; i++) {
if ((macrodefinitions[i][0].mode == macrokey.mode) && (macrodefinitions[i][0].key == macrokey.key)) {
macrodefinitions[i][0].mode = MOD_NONE;
macrodefinitions[i][0].key = KEY_Reserved;
break;
}
}
}
void sendMacro(uint8_t index) {
for (uint8_t i = 0; i < MACROLENGTH; i++) {
if(macrodefinitions[index][i+1].key != KEY_Reserved) {
sendKey(macrodefinitions[index][i+1]);
} else {
break;
}
}
}
uint8_t checkmacrodefinition(uint8_t* reportbuffer) {
if ((reportbuffer[2] != KEY_Reserved) && (reportbuffer[3] == KEY_Reserved)) {
Key macrokey;
macrokey.mode = reportbuffer[0];
macrokey.key = reportbuffer[2];
return getMacroindex(macrokey);
}
return MACROCOUNT;
}
uint8_t setMacroindex(Key macrokey) {
for (uint8_t i = 0; i < MACROCOUNT; i++) {
if ((macrodefinitions[i][0].mode == macrokey.mode) && (macrodefinitions[i][0].key == macrokey.key)) {
macrodefinitions[i][0].mode = MOD_NONE;
macrodefinitions[i][0].key = KEY_Reserved;
break;
}
}
for (uint8_t i = 0; i < MACROCOUNT; i++) {
if ((macrodefinitions[i][0].mode == MOD_NONE) && (macrodefinitions[i][0].key == KEY_Reserved)) {
macrodefinitions[i][0].mode = macrokey.mode;
macrodefinitions[i][0].key = macrokey.key;
return i;
}
}
return MACROCOUNT;
}
uint8_t iskey(uint8_t* reportbuffer, uint8_t modifier, uint8_t key) {
if ((reportbuffer[0] == modifier) && (reportbuffer[2] == key) && (reportbuffer[3] == KEY_Reserved)) {
return 1;
} else {
return 0;
}
}
uint8_t ishotkey(uint8_t* reportbuffer) {
return iskey(reportbuffer, (MOD_SHIFT_LEFT | MOD_SHIFT_RIGHT), KEY_D);
}
void keypressed(uint8_t* reportbuffer, uint8_t size, uint16_t tickcounter) {
switch (commandstate) {
case commandmode:
if (iskey(reportbuffer, (MOD_SHIFT_LEFT | MOD_SHIFT_RIGHT), KEY_Reserved) ||
iskey(reportbuffer, MOD_SHIFT_LEFT, KEY_Reserved) ||
iskey(reportbuffer, MOD_SHIFT_RIGHT, KEY_Reserved) ||
iskey(reportbuffer, MOD_NONE, KEY_Reserved)) {
// ignore pressed shift-keys, probably still pressed from hot
// key usage
} else if (iskey(reportbuffer, MOD_NONE, KEY_T)) {
// toggle function
toggle();
commandstate = standard;
} else if (iskey(reportbuffer, MOD_NONE, KEY_M)) {
// record macro
commandstate = macrocommand;
} else if (iskey(reportbuffer, MOD_SHIFT_LEFT, KEY_M) || iskey(reportbuffer, MOD_SHIFT_RIGHT, KEY_M)) {
// delete macro
commandstate = macrodelete;
} else {
// command not recognized, return to standard mode
commandstate = standard;
}
break;
case macrocommand:
if (reportbuffer[2] == KEY_Reserved) {
// just modifier pressed => ignore
} else {
Key macrokey;
macrokey.mode = reportbuffer[0];
macrokey.key = reportbuffer[2];
macrocountindex = setMacroindex(macrokey);
if (macrocountindex == MACROCOUNT) {
// no space left
commandstate = standard;
} else {
commandstate = macrodefinition;
macrodefinitionindex = 0;
}
}
break;
case macrodefinition:
if (ishotkey(reportbuffer)) {
// macro definition complete
macrodefinitions[macrocountindex][macrodefinitionindex + 1].mode = MOD_NONE;
macrodefinitions[macrocountindex][macrodefinitionindex + 1].key = KEY_Reserved;
commandstate = standard;
} else if (reportbuffer[2] == KEY_Reserved) {
// just modifier pressed => ignore
} else {
macrodefinitions[macrocountindex][macrodefinitionindex + 1].mode = reportbuffer[0];
macrodefinitions[macrocountindex][macrodefinitionindex + 1].key = reportbuffer[2];
macrodefinitionindex++;
if (macrodefinitionindex == MACROLENGTH) {
// no space left in this macro
commandstate = standard;
}
}
break;
case macrodelete:
if (reportbuffer[2] == KEY_Reserved) {
// just modifier pressed => ignore
} else {
Key macrokey;
macrokey.mode = reportbuffer[0];
macrokey.key = reportbuffer[2];
deleteMacroindex(macrokey);
commandstate = standard;
}
break;
case complexcommand:
break;
default:
if (ishotkey(reportbuffer)) {
commandstate = commandmode;
} else if ((macrocountindex = checkmacrodefinition(reportbuffer)) != MACROCOUNT) {
sendMacro(macrocountindex);
} else {
usbSendReportBuffer(reportbuffer, size);
}
}
}

12
firmware/commandhandler.h Normal file
View File

@ -0,0 +1,12 @@
/**
* \file commandhandler.h
* \brief TODO
* \author Ronald Schaten <ronald@schatenseite.de>
* \version $Id$
*
* License: TODO
*/
#include <stdint.h>
void keypressed(uint8_t* reportbuffer, uint8_t size, uint16_t tickcounter);

View File

@ -235,6 +235,7 @@
#include "keycodes.h"
#include "tools.h"
#include "modelinterface.h"
#include "commandhandler.h"
/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
@ -341,6 +342,17 @@ uint8_t usbFunctionWrite(uchar *data, uchar len) {
return 0x01;
}
/**
* Send a report buffer to the computer.
* \param reportbuffer report buffer
*/
void usbSendReportBuffer(uint8_t* reportbuffer, uint8_t size) {
while (!usbInterruptIsReady()) {
usbPoll();
}
usbSetInterrupt(reportbuffer, size); // send
}
/**
* Send a single report to the computer. This function is not used during
* normal typing, it is only used to send non-pressed keys to simulate input.
@ -353,23 +365,11 @@ void usbSendReport(uint8_t mode, uint8_t key) {
repBuffer[0] = mode;
repBuffer[2] = key;
wdt_reset();
while (!usbInterruptIsReady()) {
usbPoll();
}
usbSetInterrupt(repBuffer, sizeof(repBuffer)); // send
usbSendReportBuffer(repBuffer, sizeof(repBuffer));
}
/* ------------------------------------------------------------------------- */
/**
* This structure can be used as a container for a single 'key'. It consists of
* the key-code and the modifier-code.
*/
typedef struct {
uint8_t mode;
uint8_t key;
} Key;
/**
* Convert an ASCII-character to the corresponding key-code and modifier-code
* combination.
@ -574,6 +574,7 @@ int main(void) {
uint8_t updateNeeded = 0;
uint8_t idleCounter = 0;
uint8_t updates = 0;
uint16_t tickcounter = 0;
wdt_enable(WDTO_2S);
hardwareInit();
usbInit();
@ -595,8 +596,12 @@ int main(void) {
// check timer if we need periodic reports
if (TIFR & (1 << TOV0)) {
TIFR = (1 << TOV0); // reset flag
if (tickcounter < UINT16_MAX) {
tickcounter++;
}
calculateSpeed(updates);
updates = 0;
/*
if (idleRate != 0) { // do we need periodic reports?
if(idleCounter > 4){ // yes, but not yet
idleCounter -= 5; // 22ms in units of 4ms
@ -605,11 +610,13 @@ int main(void) {
idleCounter = idleRate;
}
}
*/
}
// if an update is needed, send the report
if (updateNeeded && usbInterruptIsReady()) {
if (updateNeeded) {
updateNeeded = 0;
usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
keypressed(reportBuffer, sizeof(reportBuffer), tickcounter);
tickcounter = 0;
memcpy(oldReportBuffer, reportBuffer, sizeof(oldReportBuffer));
}
}

View File

@ -106,6 +106,10 @@ void printMatrix(void) {
sendString("---");
}
void toggle(void) {
// not used in this model/version
}
void setSpeed(uint8_t speed) {
// not used in this model/version
}

View File

@ -21,6 +21,11 @@ void hardwareInit(void);
*/
void printMatrix(void);
/**
* Toggle-function is called as a command, doesn't have to be implemented.
*/
void toggle(void);
/**
* This tells the current writing speed to the keyboard, for whatever it will
* do with the value.

View File

@ -41,6 +41,7 @@
uint8_t curmatrix[16]; ///< contains current state of the keyboard
uint8_t oldmatrix[16]; ///< contains old state of the keyboard
uint8_t ghostmatrix[16]; ///< contains pressed keys that belong to a ghost-key situation
uint8_t backlight = 0;
void hardwareInit(void) {
// column-port is input
@ -116,10 +117,22 @@ void printMatrix(void) {
sendString("---");
}
void toggle(void) {
// switch backlight on or off
if (backlight == 0) {
backlight = 1;
} else {
backlight = 0;
OCR1A = 0xffff;
OCR1B = 0xffff;
}
}
void setSpeed(uint8_t speed) {
uint16_t value = (speed + 1) * (speed + 1) - 1;
OCR1A = 0xffff - value;
OCR1B = value;
if (backlight == 1) {
OCR1A = 0xffff - ((256 - speed) * (256 - speed) - 1);
OCR1B = 0xffff - ((speed + 1) * (speed + 1) - 1);
}
}
void setLeds(uint8_t LEDstate) {

View File

@ -93,6 +93,10 @@ void printMatrix(void) {
sendString("\n");
}
void toggle(void) {
// not used in this model/version
}
void setSpeed(uint8_t speed) {
// not used in this model/version
}

View File

@ -13,4 +13,16 @@
#define LED_COMPOSE 0x08 ///< compose LED on a boot-protocol keyboard
#define LED_KANA 0x10 ///< kana LED on a boot-protocol keyboard
/**
* This structure can be used as a container for a single 'key'. It consists of
* the key-code and the modifier-code.
*/
typedef struct {
uint8_t mode;
uint8_t key;
} Key;
void sendString(char* string);
void sendKey(Key keytosend);
void usbSendReportBuffer(uint8_t* reportbuffer, uint8_t size);