mirror of
https://bitbucket.org/C_Classic/prgkbd.git
synced 2024-11-22 18:25:09 +01:00
306 lines
11 KiB
C++
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).toAscii(),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).toAscii(),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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|