Device: Add CoreMini flashing support
parent
ec51393dfc
commit
4248c1a538
|
|
@ -510,7 +510,33 @@ bool Device::stopScript()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::uploadCoremini(std::unique_ptr<std::istream>&& stream, Disk::MemoryType memType) {
|
bool Device::uploadCoremini(std::unique_ptr<std::istream>&& stream, Disk::MemoryType memType) {
|
||||||
|
|
||||||
|
if(!stream || stream->bad()) {
|
||||||
|
report(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> bin(std::istreambuf_iterator<char>(*stream), {}); // Read the whole stream
|
||||||
|
|
||||||
|
if(bin.size() < 4) {
|
||||||
|
report(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t scriptVersion = *(uint16_t*)(&bin[2]); // Third and fourth byte are version number stored in little endian
|
||||||
|
|
||||||
|
auto scriptStatus = getScriptStatus();
|
||||||
|
|
||||||
|
if(!scriptStatus) {
|
||||||
|
return false; // Already added an API error
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scriptStatus->coreminiVersion != scriptVersion) {
|
||||||
|
// Version on device and script are not the same
|
||||||
|
report(APIEvent::Type::CoreminiUploadVersionMismatch, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto startAddress = getCoreminiStartAddress(memType);
|
auto startAddress = getCoreminiStartAddress(memType);
|
||||||
if(!startAddress) {
|
if(!startAddress) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -531,29 +557,12 @@ bool Device::uploadCoremini(std::unique_ptr<std::istream>&& stream, Disk::Memory
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!stream || stream->bad()) {
|
if(!clearScript(memType)) {
|
||||||
report(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> bin(std::istreambuf_iterator<char>(*stream), {}); // Read the whole stream
|
|
||||||
|
|
||||||
if(bin.size() < 4) {
|
if(!eraseScriptMemory(memType, static_cast<uint64_t>(bin.size()))) {
|
||||||
report(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t scriptVersion = *(uint16_t*)(&bin[2]); // Third and fourth byte are version number stored in little endian
|
|
||||||
|
|
||||||
auto scriptStatus = getScriptStatus();
|
|
||||||
|
|
||||||
if(!scriptStatus) {
|
|
||||||
return false; // Already added an API error
|
|
||||||
}
|
|
||||||
|
|
||||||
if(scriptStatus->coreminiVersion != scriptVersion) {
|
|
||||||
// Version on device and script are not the same
|
|
||||||
report(APIEvent::Type::CoreminiUploadVersionMismatch, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -563,7 +572,7 @@ bool Device::uploadCoremini(std::unique_ptr<std::istream>&& stream, Disk::Memory
|
||||||
return false; // Already added an API error
|
return false; // Already added an API error
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*numWritten == 0) {
|
if(*numWritten != static_cast<uint64_t>(bin.size())) {
|
||||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
||||||
return false; // Failed to write
|
return false; // Failed to write
|
||||||
}
|
}
|
||||||
|
|
@ -571,16 +580,60 @@ bool Device::uploadCoremini(std::unique_ptr<std::istream>&& stream, Disk::Memory
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::clearScript()
|
bool Device::eraseScriptMemory(Disk::MemoryType memType, uint64_t amount) {
|
||||||
|
static std::shared_ptr<MessageFilter> NeoEraseDone = std::make_shared<MessageFilter>(Network::NetID::NeoMemoryWriteDone);
|
||||||
|
|
||||||
|
auto startAddress = getCoreminiStartAddress(memType);
|
||||||
|
if(!startAddress) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(memType != Disk::MemoryType::Flash) {
|
||||||
|
// Only need to erase on flash
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> arguments(9, 0);
|
||||||
|
|
||||||
|
uint32_t numWords = static_cast<uint32_t>(amount / 2);
|
||||||
|
|
||||||
|
arguments[0] = static_cast<uint8_t>(memType);
|
||||||
|
*reinterpret_cast<uint32_t*>(&arguments[1]) = static_cast<uint32_t>(*startAddress / 512);
|
||||||
|
*reinterpret_cast<uint32_t*>(&arguments[5])= numWords;
|
||||||
|
|
||||||
|
auto msg = com->waitForMessageSync([this, &arguments] {
|
||||||
|
return com->sendCommand(Command::NeoEraseMemory, arguments);
|
||||||
|
}, NeoEraseDone, std::chrono::milliseconds(3000));
|
||||||
|
|
||||||
|
if(!msg) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device::clearScript(Disk::MemoryType memType)
|
||||||
{
|
{
|
||||||
if(!stopScript())
|
if(!stopScript())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
auto startAddress = getCoreminiStartAddress(memType);
|
||||||
|
if(!startAddress) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> clearData(512, 0xCD);
|
std::vector<uint8_t> clearData(512, 0xCD);
|
||||||
uint64_t ScriptLocation = 0; //We only support a coremini in an SDCard, which is at the very beginning of the card
|
auto written = writeLogicalDisk(*startAddress, clearData.data(), clearData.size(), std::chrono::milliseconds(2000), memType);
|
||||||
auto written = writeLogicalDisk(ScriptLocation, clearData.data(), clearData.size());
|
|
||||||
|
|
||||||
return written > 0;
|
if(!written) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(*written == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::transmit(std::shared_ptr<Frame> frame) {
|
bool Device::transmit(std::shared_ptr<Frame> frame) {
|
||||||
|
|
|
||||||
|
|
@ -18,18 +18,20 @@ std::optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communicatio
|
||||||
|
|
||||||
const uint64_t currentSector = pos / SectorSize;
|
const uint64_t currentSector = pos / SectorSize;
|
||||||
const uint8_t memLocation = (uint8_t)memType;
|
const uint8_t memLocation = (uint8_t)memType;
|
||||||
|
|
||||||
|
uint64_t numWords = amount / 2;
|
||||||
|
|
||||||
auto msg = com.waitForMessageSync([¤tSector, &memLocation, &com] {
|
auto msg = com.waitForMessageSync([¤tSector, &memLocation, &com, &numWords] {
|
||||||
return com.sendCommand(Command::NeoReadMemory, {
|
return com.sendCommand(Command::NeoReadMemory, {
|
||||||
memLocation,
|
memLocation,
|
||||||
uint8_t(currentSector & 0xFF),
|
uint8_t(currentSector & 0xFF),
|
||||||
uint8_t((currentSector >> 8) & 0xFF),
|
uint8_t((currentSector >> 8) & 0xFF),
|
||||||
uint8_t((currentSector >> 16) & 0xFF),
|
uint8_t((currentSector >> 16) & 0xFF),
|
||||||
uint8_t((currentSector >> 24) & 0xFF),
|
uint8_t((currentSector >> 24) & 0xFF),
|
||||||
uint8_t(SectorSize & 0xFF),
|
uint8_t(numWords & 0xFF),
|
||||||
uint8_t((SectorSize >> 8) & 0xFF),
|
uint8_t((numWords >> 8) & 0xFF),
|
||||||
uint8_t((SectorSize >> 16) & 0xFF),
|
uint8_t((numWords >> 16) & 0xFF),
|
||||||
uint8_t((SectorSize >> 24) & 0xFF)
|
uint8_t((numWords >> 24) & 0xFF)
|
||||||
});
|
});
|
||||||
}, NeoMemorySDRead, timeout);
|
}, NeoMemorySDRead, timeout);
|
||||||
|
|
||||||
|
|
@ -60,15 +62,17 @@ std::optional<uint64_t> NeoMemoryDiskDriver::writeLogicalDiskAligned(Communicati
|
||||||
const uint64_t currentSector = pos / SectorSize;
|
const uint64_t currentSector = pos / SectorSize;
|
||||||
const uint8_t memLocation = (uint8_t)memType;
|
const uint8_t memLocation = (uint8_t)memType;
|
||||||
|
|
||||||
auto msg = com.waitForMessageSync([¤tSector, &memLocation, &com, from, amount] {
|
uint64_t numWords = amount / 2;
|
||||||
|
|
||||||
|
auto msg = com.waitForMessageSync([¤tSector, &memLocation, &com, from, amount, &numWords] {
|
||||||
std::vector<uint8_t> command = {
|
std::vector<uint8_t> command = {
|
||||||
memLocation,
|
memLocation,
|
||||||
uint8_t(currentSector & 0xFF),
|
uint8_t(currentSector & 0xFF),
|
||||||
uint8_t((currentSector >> 8) & 0xFF),
|
uint8_t((currentSector >> 8) & 0xFF),
|
||||||
uint8_t((currentSector >> 16) & 0xFF),
|
uint8_t((currentSector >> 16) & 0xFF),
|
||||||
uint8_t((currentSector >> 24) & 0xFF),
|
uint8_t((currentSector >> 24) & 0xFF),
|
||||||
uint8_t(SectorSize & 0xFF),
|
uint8_t(numWords & 0xFF),
|
||||||
uint8_t((SectorSize >> 8) & 0xFF),
|
uint8_t((numWords >> 8) & 0xFF),
|
||||||
};
|
};
|
||||||
command.insert(command.end(), from, from + amount);
|
command.insert(command.end(), from, from + amount);
|
||||||
return com.sendCommand(Command::NeoWriteMemory, command);
|
return com.sendCommand(Command::NeoWriteMemory, command);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// Usage:
|
// Usage:
|
||||||
// ./libicsneocpp-coremini [DEVICE_SERIAL] [COREMINI_SCRIPT_PATH]
|
// ./libicsneocpp-coremini [DEVICE_SERIAL] [COREMINI_SCRIPT_PATH] [FLASH | SD]
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
@ -8,14 +8,14 @@
|
||||||
|
|
||||||
void displayUsage() {
|
void displayUsage() {
|
||||||
std::cout << "Usage:\n";
|
std::cout << "Usage:\n";
|
||||||
std::cout << "./libicsneocpp-coremini [DEVICE_SERIAL] [COREMINI_SCRIPT_PATH]\n";
|
std::cout << "./libicsneocpp-coremini [DEVICE_SERIAL] [COREMINI_SCRIPT_PATH] [FLASH | SD]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
std::vector<std::string> arguments(argv, argv + argc);
|
std::vector<std::string> arguments(argv, argv + argc);
|
||||||
|
|
||||||
if(arguments.size() != 3) {
|
if(arguments.size() != 4) {
|
||||||
displayUsage();
|
displayUsage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
@ -50,14 +50,25 @@ int main(int argc, char** argv) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!device->uploadCoremini(std::make_unique<std::ifstream>(arguments[2], std::ios::binary), icsneo::Disk::MemoryType::Flash))
|
std::string memTypeString = arguments[3];
|
||||||
{
|
|
||||||
|
icsneo::Disk::MemoryType type;
|
||||||
|
if(memTypeString == "FLASH") {
|
||||||
|
type = icsneo::Disk::MemoryType::Flash;
|
||||||
|
} else if(memTypeString == "SD") {
|
||||||
|
type = icsneo::Disk::MemoryType::SD;
|
||||||
|
} else {
|
||||||
|
std::cout << "Incorrect memory type option" << std::endl;
|
||||||
|
displayUsage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device->uploadCoremini(std::make_unique<std::ifstream>(arguments[2], std::ios::binary), type)) {
|
||||||
std::cout << "Failed to upload coremini" << std::endl;
|
std::cout << "Failed to upload coremini" << std::endl;
|
||||||
std::cout << icsneo::GetLastError() << std::endl;
|
std::cout << icsneo::GetLastError() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!device->startScript(icsneo::Disk::MemoryType::Flash))
|
if (!device->startScript(type)) {
|
||||||
{
|
|
||||||
std::cout << "Failed to start script" << std::endl;
|
std::cout << "Failed to start script" << std::endl;
|
||||||
std::cout << icsneo::GetLastError() << std::endl;
|
std::cout << icsneo::GetLastError() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ enum class Command : uint8_t {
|
||||||
GetVBattReq = 0xDF, // Previously known as RED_CMD_VBATT_REQUEST
|
GetVBattReq = 0xDF, // Previously known as RED_CMD_VBATT_REQUEST
|
||||||
ScriptStatus = 0xE0, // Previously known as RED_CMD_SCRIPT_STATUS
|
ScriptStatus = 0xE0, // Previously known as RED_CMD_SCRIPT_STATUS
|
||||||
MiscControl = 0xE7,
|
MiscControl = 0xE7,
|
||||||
|
NeoEraseMemory = 0xEA, // Previously known as RED_CMD_ERASE_MEMORY
|
||||||
Extended = 0xF0, // Previously known as RED_CMD_EXT_COMM
|
Extended = 0xF0, // Previously known as RED_CMD_EXT_COMM
|
||||||
ExtendedData = 0xF2, // Previously known as RED_CMD_EXTENDED_DATA
|
ExtendedData = 0xF2, // Previously known as RED_CMD_EXTENDED_DATA
|
||||||
FlexRayControl = 0xF3,
|
FlexRayControl = 0xF3,
|
||||||
|
|
|
||||||
|
|
@ -148,9 +148,11 @@ public:
|
||||||
int8_t prepareScriptLoad();
|
int8_t prepareScriptLoad();
|
||||||
bool startScript(Disk::MemoryType memType = Disk::MemoryType::SD);
|
bool startScript(Disk::MemoryType memType = Disk::MemoryType::SD);
|
||||||
bool stopScript();
|
bool stopScript();
|
||||||
bool clearScript();
|
bool clearScript(Disk::MemoryType memType = Disk::MemoryType::SD);
|
||||||
bool uploadCoremini(std::unique_ptr<std::istream>&& stream, Disk::MemoryType memType = Disk::MemoryType::SD);
|
bool uploadCoremini(std::unique_ptr<std::istream>&& stream, Disk::MemoryType memType = Disk::MemoryType::SD);
|
||||||
|
|
||||||
|
bool eraseScriptMemory(Disk::MemoryType memType, uint64_t amount);
|
||||||
|
|
||||||
virtual std::optional<MemoryAddress> getCoreminiStartAddressFlash() const {
|
virtual std::optional<MemoryAddress> getCoreminiStartAddressFlash() const {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/device/tree/neovifire2/neovifire2settings.h"
|
#include "icsneo/device/tree/neovifire2/neovifire2settings.h"
|
||||||
|
#include "icsneo/disk/neomemorydiskdriver.h"
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class NeoVIFIRE2 : public Device {
|
class NeoVIFIRE2 : public Device {
|
||||||
|
|
@ -89,7 +89,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NeoVIFIRE2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
NeoVIFIRE2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||||
initialize<NeoVIFIRE2Settings>(makeDriver);
|
initialize<NeoVIFIRE2Settings, Disk::NeoMemoryDiskDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSettings(IDeviceSettings& ssettings) override {
|
void setupSettings(IDeviceSettings& ssettings) override {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue