prgKbd-keyboard/Driver/prgKbd_debug/main.cpp

306 lines
11 KiB
C++

#include <QtCore/QCoreApplication>
#include <iostream>
#include <QStringList>
#include <fstream>
#include <usbpp.h>
// DEVICE-RELATED DEFINES
#define USBDEV_SHARED_VENDOR 0x16C0 /* VOTI */
#define USBDEV_SHARED_PRODUCT 0x03e8 /* Obdev's free shared PID */
/* Use obdev's generic shared VID/PID pair and follow the rules outlined
* in firmware/usbdrv/USBID-License.txt.
*/
// COMMANDS:
#define CMD_PING 0
#define CMD_SWVERSION 1
#define CMD_EEWRITE 2
#define CMD_EEREAD 3
#define CMD_EEOPEN 4 // Can be used if errors occour while writing to the device.
#define CMD_RESET 5 // WDT RESET
// OTHER DEFS:
#define IDENTIFY_NAME 0
#define IDENTIFY_VERSION 1
struct usb_dev_handle *dev;
// functions
int sendMessage(int command, int var1, int var2, char *buffer);
bool sendMessage(int command, int var1, int var2);
//shell
void help (QStringList *cmd);
using namespace std;
int main() //int argc, char *argv[]
{
// USB-Variables
struct usb_bus *bus;
struct usb_device *devs;
char iMan[256]; // Manufacturer name
char iProd[256]; // Product name
// Some other vars
bool break_loop = false;
// Init
usb_init(); // Init USB
usb_set_debug(3); // Debug on
usb_find_busses();
usb_find_devices();
// Scan for device
for (bus = usb_busses; bus; bus = bus->next) { // Cycle through all busses
for (devs = bus->devices; devs; devs = devs->next) { // Cycle through all devices on that bus.
cout << "Checking device: \n\tBUS:" << bus->dirname << "\\" << devs->filename << "\n\tIDV:" << devs->descriptor.idVendor << "\n\tIDP:" << devs->descriptor.idProduct << endl;
if (devs->descriptor.idVendor == USBDEV_SHARED_VENDOR && devs->descriptor.idProduct == USBDEV_SHARED_PRODUCT) {
cout << "FOUND DEVICE! " << endl;
break_loop = true; // Tell the second loop to exit as well.
break; // Exit loop
}
}
if (break_loop) break; // Break if dev was found
}
// Check whether a device was found
if (!break_loop) { // If we didn't leave the loop on purpose the device wasn't found
cout << "!!! ERROR: Device couldn't be found !!!" << endl;
return 1;
}
// If the device was found we try to open it.
dev = usb_open(devs); // Since we left the loop when the right device was active we may still use it now.
if (dev) { // We were able to open it :)
// query basic info
usb_get_string_simple(dev,devs->descriptor.iManufacturer,iMan, sizeof(iMan));
usb_get_string_simple(dev,devs->descriptor.iProduct,iProd, sizeof(iProd));
}
else {
cout << "!!! ERROR: Device could not be opened !!!" << endl;
return 1;
}
// Create the shell
QStringList command;
string temp;
bool exit = false;
while (!exit) {
cout << iMan << "@" << iProd << "# " << ends;
getline(cin, temp);
command = QString::fromStdString(temp).split(" ");
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);
}
else if (command.at(0) == "raw") {
if (command.count() < 2) help(&command);
int p1 = 0, p2 = 0;
if (command.count() >= 4) {
p1 = command.at(2).toInt();
p2 = command.at(3).toInt();
}
else if (command.count() >= 3) {
p1 = command.at(2).toInt();
}
char buf[16];
int retVal = sendMessage(command.at(1).toInt(), p1, p2, buf);
if (retVal > 0) {
buf[retVal] = 0;
cout << "Answer (" << QString::number(retVal).toStdString().data() << "B): " << buf << endl;
}
else if (retVal == 0) {
cout << "This command has no response." << endl;
}
else {
cout << "ERROR: " << retVal << endl;
}
}
else if (command.at(0) == "rawnum") {
if (command.count() < 2) help(&command);
int p1 = 0, p2 = 0;
if (command.count() >= 4) {
p1 = command.at(2).toInt();
p2 = command.at(3).toInt();
}
else if (command.count() >= 3) {
p1 = command.at(2).toInt();
}
char buf[16];
int retVal = sendMessage(command.at(1).toInt(), p1, p2, buf);
if (retVal > 0) {
buf[retVal] = 0;
cout << "Answer (" << QString::number(retVal).toStdString().data() << "B): ";
for (int y = 0; y < retVal; y++) {
cout << " 0x" << QString::number(buf[y], 16).toStdString().data() << "(" << QString::number((unsigned char) buf[y],10).toStdString().data() << ")";
}
cout << endl;
}
else if (retVal == 0) {
cout << "This command has no response." << endl;
}
else {
cout << "ERROR: " << retVal << endl;
}
}
else if (command.at(0) == "ping") {
if (command.count() != 2) help(&command);
else {
char buf[1];
int retVal = sendMessage(CMD_PING, command.at(1).at(0).unicode(),0, buf);
if (retVal > 0) {
buf[retVal] = 0;
cout << "PING returned (" << QString::number(retVal).toStdString().data() << "B): " << buf << endl;
}
else {
cout << "ERROR: Received no data!" << endl;
}
}
}
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 (false && buf[0] != value) { // Disabled due to an error in the fw?
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);
}
else {
cout << command.at(0).toStdString().data() << ": Command not found!" << endl;
}
// Ping dev to mke sure it's still alive
char buf[1];
int8_t retVal = sendMessage(CMD_PING, command.at(0).at(0).unicode(),0, buf); // instead of creating a random number we use the first letter of our alst command
if (retVal <= 0) {
cout << "ERROR: LOST CONNECTION!" << endl;
exit = 1;
}
}
cout << "Closing device..." << endl;
usb_close(dev);
return 0;
}
int sendMessage(int command, int var1, int var2, char *buffer) {
return (usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, command, var1, var2, (char *)buffer, sizeof(buffer), 5000));
}
bool sendMessage(int command, int var1, int var2) {
if (usb_control_msg(dev, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, command, var1, var2, NULL, 0, 5000) < 0) return false;
return true;
}
// 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;
}
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;
}