diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7c0770f --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.user +USB_HID_Usage_Tables.pdf + diff --git a/Driver/prgKbd_debug/main.cpp b/Driver/prgKbd_debug/main.cpp index f9f1a57..0c28c87 100644 --- a/Driver/prgKbd_debug/main.cpp +++ b/Driver/prgKbd_debug/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -95,7 +96,7 @@ int main() //int argc, char *argv[] cout << iMan << "@" << iProd << "# " << ends; getline(cin, temp); command = QString::fromStdString(temp).split(" "); - if (command.at(0) == "exit") exit = true; + if (command.at(0) == "exit" || command.at(0) == "quit") exit = true; else if (command.at(0) == "reset") { cout << "Triggering a watchdog-reset..." << endl; sendMessage(CMD_RESET,0,0); @@ -164,6 +165,59 @@ int main() //int argc, char *argv[] } } } + else if (command.at(0) == "dump") { + int memSize = 512*16; + char buf[16]; + if (command.count() != 2) help(&command); + else { + ofstream file(command.at(1).toStdString().c_str()); + if (!file.is_open()) { + cerr << "ERROR: Couldn't open file!" << endl; + } + else { + cout << "Dumping memory..." << endl; + for (int addr=0; addr < memSize; ++addr) { + cout << "\r" << addr+1 << "\r\t / " << memSize << " Bytes (" << (int)((float)(addr+1)/memSize*100) << "%) " << ends; + int retVal = sendMessage(3, addr, 0, buf); + file << buf[0]; + } + cout << endl << "done." << endl; + } + } + } + else if (command.at(0) == "backup") { + sendMessage(4, 0, 0); + unsigned int memSize = 512*16; + char buf[16]; + if (command.count() != 2) help(&command); + else { + ifstream file(command.at(1).toStdString().c_str()); + if (!file.is_open()) { + cerr << "ERROR: Couldn't open file!" << endl; + } + else { + cout << "Writing memory..." << endl; + for (unsigned int addr=0; addr < memSize; ++addr) { + cout << "\r" << addr+1 << "\r\t / " << memSize << " Bytes (" << (int)((float)(addr+1)/memSize*100) << "%) " << ends; + unsigned int value, errs; + errs=0; + if ((value = file.get()) == -1) value=255; // If file end too early, fill up with 255s + + while (errs < 3) { + int retVal = sendMessage(2, addr, value, buf); + if (buf[0] != value) { + errs++; + cerr << endl << "ERROR writing to address " << addr <<". Read back " << (int)buf[0] << " instead of " << (int)value << ". Try " << errs << endl; + } + else { + errs = 255; + } + } + } + cout << endl << "done." << endl; + } + } + } else if (command.at(0) == "" || command.at(0) == " "); else if (command.at(0) == "help") { help(&command); @@ -199,6 +253,7 @@ bool sendMessage(int command, int var1, int var2) { // SHELL-RELATED functions void help (QStringList *cmd) { char pos=1; + if (cmd->count() == 1) pos = 0; if (cmd->at(pos) == "ping") { cout << "Syntax: ping [AnyChar]\nPing will simply return the character you entered." << endl; @@ -206,8 +261,45 @@ void help (QStringList *cmd) { else if (cmd->at(pos) == "raw") { cout << "Syntax: raw [command] ([Param1]) ([Param2])\nThis will send the raw data to the device. All parameters will be converted to numbers. (65->A)\nExample: raw\t42\t13\t37\n\t\t^cmd\t^param1\t^param2" << endl; } + else if (cmd->at(pos) == "dump") { + cout << "Syntax: dump [filename]\nDumps the full eeprom memory as bytecode into filename." << endl; + } + else if (cmd->at(pos) == "backup") { + cout << "Syntax: backup [filename]\nCopies the content of filename into the eeprom memory. Filename has to be a binary file." << endl; + } + else if (cmd->at(pos) == "help") { + cout << "List of commands: raw, rawnum, ping, help, dump, backup" << endl; + } else { cout << cmd->at(pos).toStdString().data() << ": Help not found!" << endl; } return; } + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/firmware/keyboard.c b/firmware/keyboard.c index 725faea..f53fa57 100644 --- a/firmware/keyboard.c +++ b/firmware/keyboard.c @@ -174,13 +174,14 @@ static uchar reportBuffer[24]; } else if(rq->bRequest == CMD_SWVERSION) { reportBuffer[0] = '0'; - reportBuffer[1] = '2'; + reportBuffer[1] = '3'; reportBuffer[2] = 'B'; return 3; } else if(rq->bRequest == CMD_EEWRITE) { EEWriteByte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8), rq->wIndex.bytes[0]); - reportBuffer[0] = EEReadByte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8)); // WE MIGHT HAVE 2 REMOVE THIS BECAUSE OF PERFORMANCE ISSUES + //reportBuffer[0] = EEReadByte(rq->wValue.bytes[0] + (rq->wValue.bytes[1] << 8)); // WE MIGHT HAVE 2 REMOVE THIS BECAUSE OF PERFORMANCE ISSUES -- Reading back too quickly causes an error (-1) + reportBuffer[0] = rq->wIndex.bytes[0]; return 1; } else if(rq->bRequest == CMD_EEREAD) { @@ -233,27 +234,10 @@ static uchar reportBuffer[24]; static void buildReport(void){ - if(newReport == 0){ - if (oldKey == Key_MODE) { - //Not yet implemented - } - else if (oldKey) { // One of the 16 keys was pressed - //reportBuffer[2] = 125 + oldKey; // 1+getKey() - // Set memAddr to the first byte of the pressed key - //memAddr = MEM_KEY_LENGTH*(oldKey-1); - //cMode = KEYMODE_PRESS; //default to keymode_press - //oldKey = 0; - continueExecution(); - } - else { - // Continue code execution. - continueExecution(); - } - } + if(newReport == 0) continueExecution(); } -//WICHTIG: BEIM CANCEL-COMMAND (255) einen release auslösen... oder auch nicht... lassen wirs den user konfigurieren... oder auch nicht.. hmm.... reportBuf komplett auf 0 setzen wäre das dann void continueExecution() { uint8_t newData = 0; while (!newData) { @@ -326,29 +310,20 @@ void continueExecution() { if ((keyType[oldKey-1] == KEYTYPE_TEXT) || keyAction == KEYACTION_DOWN) reportBuffer[0] &= ~(1 << (instr - 232)); // MOD-Keys (dis) else reportBuffer[0] |= (1 << (instr - 232)); // MOD-Keys (en) } - // MODS-KEYS are enabled/disabled using different commands. This will make it easier when being in text-mode. - /* OLD PART FOR MOD-KEYS: Replaced by new command set - New one is independent from mode - if (cMode == KEYMODE_DOWN) { // set bit - reportBuffer[0] |= (1 << (instr - 224)); - } - else if (cMode == KEYMODE_UP) { // clear bit - reportBuffer[0] &= ~(1 << (instr - 224)); - } - else { - // Err (press) - } - */ if (!flag_keyPress) memAddr++; // increase memory address // Currently there's NO protection.The system could jump onto the next key + // Can be simply fixed by using a modulo-operation on the current address and the MEM_KEY_LENGTH } } void detectKeyType() { - uint8_t keyId, x; + uint8_t keyId; + uint16_t x; for (keyId=0;keyId < 16; ++keyId) { + LED_PORT ^= (1 << LED_RED); for (x=0; x < MEM_KEY_LENGTH; ++x) { + wdt_reset(); uint8_t instr = EEReadByte(keyId*MEM_KEY_LENGTH+x); if (instr == INSTR_KEYDOWN || instr == INSTR_KEYUP) { // If KEYPRESS is used at any time, it is a text-command keyType[keyId] = KEYTYPE_KEY; @@ -363,6 +338,11 @@ void detectKeyType() { } void keyboard(void) { + LED_PORT |= (1 << LED_RED); + _delay_ms(250); // Make sure the cable is securely plugged in. + LED_PORT &= ~(1 << LED_RED); + _delay_ms(250); + wdt_enable(WDTO_2S); EEOpen(); // We open our eeprom uchar i; @@ -381,7 +361,8 @@ void keyboard(void) { usbDeviceConnect(); sei(); // Interrupt enable - LED_PORT ^= (1 << LED_GREEN); + LED_PORT &= ~(1 << LED_RED); + LED_PORT |= (1 << LED_GREEN); for(;;){ /* main event loop */ wdt_reset();