From d7372bbd5abb645393f152509800a3fee1df1cda Mon Sep 17 00:00:00 2001 From: Paul Hollinsky Date: Mon, 1 Oct 2018 15:26:13 -0400 Subject: [PATCH] Incomplete device settings sending --- api/icsneoc/icsneoc.cpp | 30 +++++ api/icsneoc/include/icsneoc.h | 18 +++ device/idevicesettings.cpp | 117 ++++++++++++++++++ device/include/idevicesettings.h | 63 ++++++---- .../neovifire2/include/neovifire2settings.h | 33 +++-- 5 files changed, 225 insertions(+), 36 deletions(-) diff --git a/api/icsneoc/icsneoc.cpp b/api/icsneoc/icsneoc.cpp index aa1ab2b..7cf4ee5 100644 --- a/api/icsneoc/icsneoc.cpp +++ b/api/icsneoc/icsneoc.cpp @@ -210,4 +210,34 @@ bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLeng *maxLength = device->device->getType().toString().copy(str, *maxLength); str[*maxLength] = '\0'; return true; +} + +bool icsneo_settingsSend(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(!device->device->settings) // Settings are not available for this device + return false; + + return device->device->settings->send(); +} + +bool icsneo_settingsCommit(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(!device->device->settings) // Settings are not available for this device + return false; + + return device->device->settings->commit(); +} + +bool icsneo_setBaudrate(const neodevice_t* device, uint16_t netid, uint32_t newBaudrate) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(!device->device->settings) // Settings are not available for this device + return false; + + return device->device->settings->setBaudrateFor(netid, newBaudrate); } \ No newline at end of file diff --git a/api/icsneoc/include/icsneoc.h b/api/icsneoc/include/icsneoc.h index cf8f031..b93b387 100644 --- a/api/icsneoc/include/icsneoc.h +++ b/api/icsneoc/include/icsneoc.h @@ -44,6 +44,12 @@ extern bool DLLExport icsneo_setPollingMessageLimit(const neodevice_t* device, s extern bool DLLExport icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength); +extern bool DLLExport icsneo_settingsSend(const neodevice_t* device); + +extern bool DLLExport icsneo_settingsCommit(const neodevice_t* device); + +extern bool DLLExport icsneo_setBaudrate(const neodevice_t* device, uint16_t netid, uint32_t newBaudrate); + #ifdef __cplusplus } // extern "C" #endif @@ -98,6 +104,15 @@ fn_icsneo_setPollingMessageLimit icsneo_setPollingMessageLimit; typedef size_t(*fn_icsneo_getProductName)(const neodevice_t* device, char* str, size_t* maxLength); fn_icsneo_getProductName icsneo_getProductName; +typedef size_t(*fn_icsneo_settingsSend)(const neodevice_t* device); +fn_icsneo_settingsSend icsneo_settingsSend; + +typedef size_t(*fn_icsneo_settingsCommit)(const neodevice_t* device); +fn_icsneo_settingsCommit icsneo_settingsCommit; + +typedef size_t(*fn_icsneo_setBaudrate)(const neodevice_t* device, uint16_t netid, uint32_t newBaudrate); +fn_icsneo_setBaudrate icsneo_setBaudrate; + #define ICSNEO_IMPORT(func) func = (fn_##func)icsneo_dynamicLibraryGetFunction(icsneo_libraryHandle, #func) #define ICSNEO_IMPORTASSERT(func) if((ICSNEO_IMPORT(func)) == NULL) return 3 void* icsneo_libraryHandle = NULL; @@ -128,6 +143,9 @@ int icsneo_init() { ICSNEO_IMPORTASSERT(icsneo_getPollingMessageLimit); ICSNEO_IMPORTASSERT(icsneo_setPollingMessageLimit); ICSNEO_IMPORTASSERT(icsneo_getProductName); + ICSNEO_IMPORTASSERT(icsneo_settingsSend); + ICSNEO_IMPORTASSERT(icsneo_settingsCommit); + ICSNEO_IMPORTASSERT(icsneo_setBaudrate); icsneo_initialized = true; return 0; diff --git a/device/idevicesettings.cpp b/device/idevicesettings.cpp index 0cff1c9..d57f87a 100644 --- a/device/idevicesettings.cpp +++ b/device/idevicesettings.cpp @@ -1,4 +1,6 @@ #include "device/include/idevicesettings.h" +#include "communication/message/filter/include/main51messagefilter.h" +#include using namespace icsneo; @@ -72,5 +74,120 @@ void IDeviceSettings::refresh() { settings = std::move(rxSettings); settingsLoaded = true; + + if(settings.size() != structSize) { + std::cout << "Settings size was " << settings.size() << " bytes but it should be " << structSize << " bytes for this device" << std::endl; + settingsLoaded = false; + } + } +} + +bool IDeviceSettings::send() { + constexpr uint16_t GS_VERSION = 5; + std::vector bytestream; + bytestream.resize(6 + structSize); + bytestream[0] = GS_VERSION; + bytestream[1] = GS_VERSION >> 8; + bytestream[2] = structSize; + bytestream[3] = structSize >> 8; + uint16_t gs_checksum = CalculateGSChecksum(settings); + bytestream[4] = gs_checksum; + bytestream[5] = gs_checksum >> 8; + memcpy(bytestream.data() + 6, getRawStructurePointer(), structSize); + com->sendCommand(Command::SetSettings, bytestream); + std::shared_ptr msg = com->waitForMessageSync(Main51MessageFilter(Command::SetSettings), std::chrono::milliseconds(500)); + if(!msg || msg->data[1] != 1) { // The second byte of the response carries the result, 1 being success + refresh(); // Refresh our buffer with what the device has + return false; + } + + return true; +} + +bool IDeviceSettings::commit() { + if(!send()) + return false; + + com->sendCommand(Command::SaveSettings); + std::shared_ptr msg = com->waitForMessageSync(Main51MessageFilter(Command::SaveSettings), std::chrono::milliseconds(500)); + if(!msg || msg->data[1] != 1) { // The second byte of the response carries the result, 1 being success + refresh(); // Refresh our buffer with what the device has + return false; + } + + return true; +} + +bool IDeviceSettings::setBaudrateFor(Network net, uint32_t baudrate) { + switch(net.getType()) { + case Network::Type::CAN: { + CAN_SETTINGS* settings = getCANSettingsFor(net); + if(settings == nullptr) + return false; + + uint8_t newBaud = getEnumValueForBaudrate(baudrate); + if(newBaud == 0xFF) + return false; + settings->Baudrate = newBaud; + settings->auto_baud = false; + settings->SetBaudrate = AUTO; // Use the baudrate values instead of the TQ values + return true; + } + default: + return false; + } +} + +template bool IDeviceSettings::setStructure(const T& newStructure) { + if(sizeof(T) != structSize) + return false; // The wrong structure was passed in for the current device + + if(settings.size() != structSize) + settings.resize(structSize); + + memcpy(settings.data(), &newStructure, structSize); + return true; +} + +uint8_t IDeviceSettings::getEnumValueForBaudrate(uint32_t baudrate) { + switch(baudrate) { + case 20000: + return BPS20; + case 33000: + return BPS33; + case 50000: + return BPS50; + case 62000: + return BPS62; + case 83000: + return BPS83; + case 100000: + return BPS100; + case 125000: + return BPS125; + case 250000: + return BPS250; + case 500000: + return BPS500; + case 800000: + return BPS800; + case 1000000: + return BPS1000; + case 666000: + return BPS666; + case 2000000: + return BPS2000; + case 4000000: + return BPS4000; + case 5000000: + return CAN_BPS5000; + case 6667000: + return CAN_BPS6667; + case 8000000: + return CAN_BPS8000; + case 10000000: + return CAN_BPS10000; + default: + return 0xFF; } } \ No newline at end of file diff --git a/device/include/idevicesettings.h b/device/include/idevicesettings.h index d725bb4..787eeea 100644 --- a/device/include/idevicesettings.h +++ b/device/include/idevicesettings.h @@ -3,30 +3,6 @@ #include -#ifdef __cplusplus -#include "communication/include/communication.h" -#include - -namespace icsneo { - -class IDeviceSettings { -public: - static uint16_t CalculateGSChecksum(const std::vector& settings); - - IDeviceSettings(std::shared_ptr com) : com(com) {} - virtual ~IDeviceSettings() {} - virtual void refresh(); - //virtual void commit() = 0; - virtual void* getStructure() { return settings.data(); } - //virtual bool setBaudrate(int baud) = 0; -protected: - bool settingsLoaded = false; - std::vector settings; - std::shared_ptr com; -}; - -#endif - #pragma pack(push, 2) /* SetBaudrate in CAN_SETTINGS */ @@ -295,7 +271,42 @@ typedef struct _UART_SETTINGS #pragma pack(pop) #ifdef __cplusplus -} // End of the namespace -#endif +#include "communication/include/communication.h" +#include + +namespace icsneo { + +class IDeviceSettings { +public: + static uint16_t CalculateGSChecksum(const std::vector& settings); + + IDeviceSettings(std::shared_ptr com, size_t size) : com(com), structSize(size) {} + virtual ~IDeviceSettings() {} + + void refresh(); // Get from device + bool send(); // Send to device, device keeps settings in volatile RAM until power cycle + bool commit(); // Send to device, device keeps settings in EEPROM until next commit + + virtual bool setBaudrateFor(Network net, uint32_t baudrate); + + virtual CAN_SETTINGS* getCANSettingsFor(Network net) { return nullptr; } + virtual CANFD_SETTINGS* getCANFDSettingsFor(Network net) { return nullptr; } + + void* getRawStructurePointer() { return settings.data(); } + template T* getStructurePointer() { return static_cast((void*)settings.data()); } + template T getStructureCopy() { return *getStructurePointer(); } + template bool setStructure(const T& newStructure); + + uint8_t getEnumValueForBaudrate(uint32_t baudrate); +protected: + std::shared_ptr com; + size_t structSize; + bool settingsLoaded = false; + std::vector settings; +}; + +} + +#endif // __cplusplus #endif \ No newline at end of file diff --git a/device/neovifire2/include/neovifire2settings.h b/device/neovifire2/include/neovifire2settings.h index 21f5db2..7249457 100644 --- a/device/neovifire2/include/neovifire2settings.h +++ b/device/neovifire2/include/neovifire2settings.h @@ -113,18 +113,31 @@ typedef struct { class NeoVIFIRE2Settings : public IDeviceSettings { public: - NeoVIFIRE2Settings(std::shared_ptr com) : IDeviceSettings(com) {} - void refresh() { - IDeviceSettings::refresh(); - if(settingsLoaded) { - if(settings.size() != sizeof(neovifire2_settings_t)) { - std::cout << "Settings size was " << settings.size() << " but for a FIRE2 it should be " << sizeof(neovifire2_settings_t) << std::endl; - settingsLoaded = false; - } + NeoVIFIRE2Settings(std::shared_ptr com) : IDeviceSettings(com, sizeof(neovifire2_settings_t)) {} + CAN_SETTINGS* getCANSettingsFor(Network net) override { + auto cfg = getStructurePointer(); + switch(net.getNetID()) { + case Network::NetID::HSCAN: + return &(cfg->can1); + case Network::NetID::MSCAN: + return &(cfg->can2); + case Network::NetID::HSCAN2: + return &(cfg->can3); + case Network::NetID::HSCAN3: + return &(cfg->can4); + case Network::NetID::HSCAN4: + return &(cfg->can5); + case Network::NetID::HSCAN5: + return &(cfg->can6); + case Network::NetID::HSCAN6: + return &(cfg->can7); + case Network::NetID::HSCAN7: + return &(cfg->can8); + default: + return nullptr; } } -private: - neovifire2_settings_t* settingsStruct = (neovifire2_settings_t*)settings.data(); + CANFD_SETTINGS* getCANFDSettingsFor(Network net) override { return nullptr; } }; }