Files
SCSI2SD/software/bootloaderhost/main.cc
Michael McMaster 5e0f1e3360 Added support for v4.2 boards
Renamed "pbook" firmware to "v4". Original "green" boards now under "v3".
Add external LED support for v4 firmware.
Added --reset to scsi2sd-config
bootloaderhost can now reset the board.
2014-07-12 23:55:57 +10:00

197 lines
4.0 KiB
C++

// Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
//
// This file is part of SCSI2SD.
//
// SCSI2SD is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// SCSI2SD is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
#include "SCSI2SD_HID.hh"
#include "SCSI2SD_Bootloader.hh"
#include "Firmware.hh"
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <stdio.h>
#include <unistd.h>
using namespace SCSI2SD;
extern "C"
void ProgressUpdate(unsigned char arrayId, unsigned short rowNum)
{
//std::cerr <<
//"Programmed flash array " << static_cast<int>(arrayId) <<
// ", row " << rowNum << std::endl;
std::cout << "." << std::flush;
}
static void usage()
{
std::cout << "Usage: bootloaderhost [-f] "
"/path/to/firmware.cyacd\n" <<
"\t-f\tForce, even if the firmware doesn't match the target board.\n\n" <<
std::endl;
}
int main(int argc, char* argv[])
{
std::cout <<
"PSoC 3/5LP USB HID Bootloader Host\n" <<
"Copyright (C) 2013 Michael McMaster <michael@codesrc.com>\n" <<
std::endl;
int force = 0;
opterr = 0;
int c;
while ((c = getopt(argc, argv, "v:p:f")) != -1)
{
switch (c)
{
case 'f':
force = 1;
break;
case '?':
usage();
exit(1);
}
}
std::string filename;
if (optind < argc)
{
filename = argv[optind];
}
else
{
usage();
exit(1);
}
// Enumerate and print the HID devices on the system
std::shared_ptr<Bootloader> bootloader(Bootloader::Open());
std::shared_ptr<HID> hid(HID::Open());
if (hid)
{
try
{
hid->enterBootloader();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
hid.reset();
}
}
if (!hid)
{
std::cout <<
"Waiting for device connection" << std::endl <<
"Connect USB cable to the bus-powered device now, or otherwise "
"reset the device." << std::endl;
}
while (!bootloader)
{
bootloader.reset(Bootloader::Open());
if (!bootloader && !hid)
{
hid.reset(HID::Open());
if (hid)
{
try
{
hid->enterBootloader();
}
catch (std::exception& e)
{
std::cerr << e.what();
}
}
}
if (!bootloader)
{
usleep(100000); // 100ms
}
}
std::stringstream foundMsg;
foundMsg <<
"Device Found\n" <<
" type:\t\t\t" << std::setw(4) << std::hex <<
Bootloader::VENDOR_ID << " " <<
Bootloader::PRODUCT_ID <<
"\n" <<
" path:\t\t\t" << bootloader->getDevicePath() << "\n";
std::cout << foundMsg.str() << std::endl;
Bootloader::HWInfo hwInfo(bootloader->getHWInfo());
std::cout <<
" Board:\t\t" << hwInfo.desc << "\n" <<
" Revision:\t\t" << hwInfo.version << std::endl;
if (hid)
{
std::cout <<
" Existing firmware:\t" <<
hid->getFirmwareVersionStr() << std::endl;
}
if (!bootloader->isCorrectFirmware(filename) && !force)
{
std::cerr <<
"ERROR: Unexpected firmware file. Expected: \""
<< hwInfo.firmwareName << "\"\n\n" <<
"Using firmware design for a different board will destroy your " <<
"hardware.\n" <<
"If you still wish to proceed, try again with the \"-f\" flag.\n" <<
std::endl;
exit(1);
}
Firmware firmware(filename);
std::stringstream firmMsg;
firmMsg <<
" Firmware Silicon ID:\t" << std::hex << firmware.siliconId() <<
"\n" <<
std::cout << firmMsg.str() << std::endl;
std::cout << "Starting firmware upload: " << filename << std::endl;
try
{
bootloader->load(filename, &ProgressUpdate);
std::cout << "Firmware upload complete." << std::endl;
}
catch (std::exception& e)
{
std::cerr << "ERROR: Firmware update failed.\n" << e.what() << std::endl;
exit(1);
}
return 0;
}