#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
extern "C" {
#include "syspil.h"
#include "processpil.h"
}
#include "sketchbuild.h"
using namespace std;
int UploadToArduino(SHELL_PARAM* proc, const char* hexfile, const char* eepfile, int boardIndex, const char* serial, int baudrate, const char* avrpath);
int main(int argc, char* argv[])
{
char* filepath;
const char* serial = 0;
char* appdir;
char *p;
int ret = 0;
int boardIndex = 0;
int ispBaudrate = 0;
BOARD_CONFIG* board = boards;
CArduinoBuilder builder;
cout << "Arduino Uploader Version " << BUILDER_VERSION << endl << "(C)2013 Written by Stanley Huang <stanleyhuangyc@gmail.com>" << endl << "Distributed under GPL license" << endl << endl;
if (argc < 2) {
int i;
cout << "Command line syntax:" << endl << argv[0] << " [sketch/hex file] [board type] [MCU frequency in MHz] [serial port/usbasp]" << endl << endl
<< "Board types:" << endl;
for (i = 0; boards[i].name; i++) {
cout << (i + 1) << " - " << boards[i].name << endl;
}
cout << endl;
return -1;
}
// get app dir
appdir = strdup(argv[0]);
p = strrchr(appdir, '/');
if (!p) p = strrchr(appdir, '\\');
if (p)
*(p + 1) = 0;
else
*appdir = 0;
#ifdef WIN32
// set toolchain path
char* pathenv = new char[4096];
GetEnvironmentVariable("PATH", pathenv, 4096 - strlen(appdir) - 16);
strcat(pathenv, ";");
strcat(pathenv, appdir);
strcat(pathenv, "bin");
SetEnvironmentVariable("PATH", pathenv);
delete pathenv;
#endif
filepath = argv[1];
builder.hexfile = new char[strlen(filepath) + 5];
sprintf(builder.hexfile, "%s.hex", filepath);
if (argc > 2) {
int boardCount;
for (boardCount = 0; boards[boardCount].name; boardCount++);
if (isdigit(argv[2][0])) {
boardIndex = atoi(argv[2]);
boardIndex--;
} else {
for (boardIndex = 0; boardIndex < boardCount; boardIndex++) {
if (strstr(boards[boardIndex].id, argv[2])) break;
}
}
if (boardIndex < 0 || boardIndex >= boardCount) {
cout << "No valid board selected." << endl;
return -2;
}
}
board = boards + boardIndex;
if (argc > 3)
builder.freq =atoi(argv[3]);
else
builder.freq = 16;
if (argc > 4)
serial = argv[4];
if (argc > 5)
ispBaudrate = atoi(argv[5]);
// initialize builder
if (boardIndex >= 0) {
builder.board = boards + boardIndex;
}
if (!strstr(filepath, ".hex") && !strstr(filepath, ".HEX")) {
char* buildDir = new char [strlen(filepath) + 1];
strcpy(buildDir, filepath);
p = strrchr(buildDir, '/');
if (!p) p = strrchr(buildDir, '\\');
if (p) *p = 0;
builder.buildDir = buildDir;
remove(builder.hexfile);
if (strstr(filepath, ".elf")) {
builder.proc.flags = SF_REDIRECT_STDOUT;
if (!builder.ConvertELFtoHEX(filepath)) {
builder.ConsoleOutput("Error generating HEX file");
ret = ERROR_SIZE;
}
} else {
builder.ConsoleOutput("Build Target: %s ", builder.board->name);
builder.ConsoleOutput("(MCU: %s)\r\n", builder.board->mcu);
remove(builder.hexfile);
builder.sketchPath = filepath;
ret = builder.BuildSketch();
builder.proc.iRetCode = ret;
if (!IsFileExist(builder.hexfile)) {
cout << endl << "Error occurred during compiliation" << endl;
if (ret == 0) ret = -1;
}
if (ret == SUCCESS && serial) {
builder.ConsoleOutput("\r\n");
}
}
if (ret == SUCCESS && serial) {
char* eepfile = 0;
builder.ConsoleOutput("Starting upload for %s ", builder.board->name);
builder.ConsoleOutput("via %s...\r\n", serial);
builder.proc.flags = SF_REDIRECT_STDERR;
if (builder.target.eepBytes > 0) {
eepfile = new char[strlen(builder.hexfile) + 5];
sprintf(eepfile, "%s.eep", builder.hexfile);
}
builder.proc.flags = SF_ALLOC | SF_REDIRECT_STDERR;
ret = UploadToArduino(&builder.proc, builder.hexfile, eepfile, boardIndex, serial, ispBaudrate, "bin/");
while (ShellRead(&builder.proc, 3000) > 0) cout << builder.proc.buffer;
ShellClean(&builder.proc);
if (eepfile) delete eepfile;
}
delete buildDir;
builder.buildDir = 0;
} else if (serial) {
ret = UploadToArduino(&builder.proc, filepath, 0, boardIndex, serial, ispBaudrate, "bin/");
}
free(builder.hexfile);
free(appdir);
#ifdef _DEBUG
printf("Press ENTER to exit...");
getchar();
#endif
return ret;
}