#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
#include "ctb-0.16/ctb.h"
extern "C" {
#include "syspil.h"
#include "processpil.h"
}
#include "sketchbuild.h"
using namespace std;
vector<string> ports;
string SearchNewPort()
{
DWORD tick = GetTickCount();
vector<string> newports;
bool found = true;
do {
newports.clear();
ctb::GetAvailablePorts( newports );
for( int i = 0; i < (int)newports.size(); i++) {
// look for port in previous ports list
found = false;
for (int j = 0; j < ports.size(); j++) {
if (newports[i].compare(ports[j]) == 0) {
found = true;
break;
}
}
if (!found) {
return newports[i];
}
}
newports.clear();
msleep(1000);
} while (GetTickCount() - tick < 10000 && found);
return "";
}
string ResetLeonardo(const char* port)
{
string uploadPort;
ctb::SerialPort serialPort;
char devname[64];
sprintf(devname, "\\\\.\\%s", port);
cout << "Forcing reset using 1200bps open/close on " << port << "... ";
if (serialPort.Open(devname, 1200) != 0) {
cout << "error opening port " << port << endl;
return "";
}
//serialPort.ClrLineState(ctb::LinestateDtr);
serialPort.Close();
uploadPort = SearchNewPort();
return uploadPort;
}
int UploadToArduino(SHELL_PARAM* proc, const char* hexfile, const char* eepfile, int boardIndex, const char* serial, int baudrate, const char* avrpath)
{
#ifdef WIN32
const char* workDir = getenv("TEMP");
#else
const char* workDir = "/var/tmp";
#endif
char cmd[512];
char *p;
int ret = 0;
BOARD_CONFIG* board = boards + boardIndex;
if (!workDir || !*workDir) {
#ifdef win32
workDir = ".";
#else
workDir = "/var/tmp";
#endif
}
do {
string uploadPort;
if (!IsFileExist(hexfile)) {
cout << hexfile << " does not exist" << endl;
break;
}
// enumerate serial ports
cout << "Target Board: " << board->name << " (Baudrate: " << board->baudrate << ")" << endl;
if( ctb::GetAvailablePorts( ports )) {
cout << "Available serial ports:";
for( int i = 0; i < (int)ports.size(); i++) {
cout << " [" << (i + 1) << "]-" << ports[i];
}
cout << endl;
}
if (!serial) {
if (ports.size() == 0) {
cout << "No serial port is found." << endl;
break;
} else if (ports.size() == 1) {
serial = ports[0].c_str();
} else {
int portnum = 0;
cout << "Choose the port for uploading (1-" << ports.size() << ") or CTRL+C to exit: ";
scanf("%d", &portnum);
if (portnum == 0 || portnum > ports.size()) break;
serial = ports[portnum - 1].c_str();
}
}
cout << "Uploading to " << board->name << " via " << serial << " ..." << endl;
if (!strcmp(board->mcu, "atmega32u4") && stricmp(serial, "usbasp") && !baudrate) {
uploadPort = ResetLeonardo(serial);
if (!uploadPort.empty()) {
cout << uploadPort << " found!" << endl;
} else {
cout << "no new port found" << endl;
break;
}
}
p = cmd;
#ifdef WIN32
p += sprintf(p, "\"%savrdude.exe\" -C %savrdude.conf", avrpath, avrpath);
if (!stricmp(serial, "usbasp")) {
p += sprintf(p, " -cusbasp -Pusb");
} else if (baudrate) {
// ArduinoISP
p += sprintf(p, " -cstk500v1 -P\\\\.\\%s -b%d", serial, baudrate);
} else if (!strcmp(board->mcu, "atmega32u4")) {
p += sprintf(p, " -cavr109 -P\\\\.\\%s -b%d -D", uploadPort.c_str(), board->baudrate);
} else if (!strcmp(board->mcu, "atmega2560")) {
p += sprintf(p, " -cwiring -P\\\\.\\%s -b%d -D", serial, board->baudrate);
} else {
p += sprintf(p, " -carduino -P\\\\.\\%s -b%d -D", serial, board->baudrate);
}
#else
p += sprintf(p, "%savrdude -C /etc/avrdude.conf", avrpath);
if (!strcmp(serial, "usbasp")) {
p += sprintf(p, " -cusbasp -Pusb");
} else if (!strcmp(board->mcu, "atmega32u4")) {
p += sprintf(p, " -cavr109 -P%s -b%d", uploadPort, board->baudrate);
} else if (!strcmp(board->mcu, "atmega2560")) {
p += sprintf(p, " -cwiring -P%s -b%d", serial, board->baudrate);
} else {
p += sprintf(p, " -carduino -P%s -b%d", serial, board->baudrate);
}
#endif
p += sprintf(p, " -V -p%s -Uflash:w:\"%s\":i", board->mcu, hexfile);
if (eepfile) {
p += sprintf(p, " -Ueeprom:w:\"%s\":i", eepfile);
}
if (ShellExec(proc, cmd) != 0) {
break;
}
//ResetLeonardo(serial.c_str());
return 0;
} while(0);
return -1;
}