Added support for dumping/restoring EEPROM-Contents

Functions are dump and backup
bugfixes
This commit is contained in:
Markus Koch 2013-08-19 17:35:25 +02:00
parent c77fe87379
commit 174f780cad
3 changed files with 112 additions and 36 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.user
USB_HID_Usage_Tables.pdf

View File

@ -1,6 +1,7 @@
#include <QtCore/QCoreApplication>
#include <iostream>
#include <QStringList>
#include <fstream>
#include <usbpp.h>
@ -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;
}

View File

@ -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();