#include "stdafx.h" #include "stdio.h"; #include "DFUDevice.h" #include "DFUError.h" #include "DFUException.h" #include "ProgressForm.h" #include "TwineDFUExtras.h" using namespace System::Runtime::InteropServices; using namespace System::IO; namespace Tango { namespace FirmwareUpdateLib { DFUDevice::DFUDevice() { TwineExtras = gcnew TwineDFUExtras(); } DFUDevice::DFUDevice(tLMDFUDeviceInfo *deviceInfo, tLMDFUHandle deviceHandle) { devInfo = deviceInfo; devHandle = deviceHandle; TwineExtras = gcnew TwineDFUExtras(); } DFUDevice::~DFUDevice() { try { if (!_isDisposed) { _LMDFUDeviceClose(devHandle, FALSE); //Reset device? FALSE. _isDisposed = true; } } catch (Exception^ e) { //Do Nothing... } } void DFUDevice::SwitchToDFUMode() { tLMDFUErr eRetcode = _LMDFUModeSwitch(devHandle); _isDisposed = true; if (eRetcode != DFU_OK) { throw gcnew DFUException(eRetcode); } Mode = DFUMode::DFU; } void DFUDevice::ClearFlash() { tLMDFUErr eRetcode = _LMDFUErase(devHandle, 0, 0, true, NULL); if (eRetcode != DFU_OK) { throw gcnew DFUException(eRetcode); } } void DFUDevice::Reset() { tLMDFUErr eRetcode = _LMDFUDeviceClose(devHandle, TRUE); //Reset device? TRUE. _isDisposed = true; if (eRetcode != DFU_OK) { throw gcnew DFUException(eRetcode); } } void DFUDevice::Upload(array^ bytes, ProgressCallbackDelegate^ callback) { tLMDFUParams *psDFU; tLMDFUParams sDFU; tLMDFUErr eRetcode; // If it supports the Tiva DFU protocol, read back // some important parameters. if (SupportsTivaExtensions) { // Read flash size parameters from the device. eRetcode = _LMDFUParamsGet(devHandle, &sDFU); if (eRetcode != DFU_OK) { throw gcnew DFUException(eRetcode); } psDFU = &sDFU; } else { // The device doesn't support the Tiva // protocol so set the DFU parameter structure // pointer to NULL. psDFU = (tLMDFUParams *)0; } //Create an unmanaged array of from the bytes. pin_ptr p = &bytes[0]; unsigned char* pby = p; unsigned char* pcFileBuf = reinterpret_cast(pby); //Create notification form. IntPtr formHandle = IntPtr::Zero; if (callback != nullptr) { ProgressForm^ f = gcnew ProgressForm(callback, true); formHandle = f->Handle; // forces the form Control to be created. } //Upload the image and verify! eRetcode = _LMDFUDownloadBin(devHandle, pcFileBuf, (unsigned long)bytes->Length, AppStartAddress, TRUE, formHandle != IntPtr::Zero ? (HWND)formHandle.ToPointer() : NULL); if (eRetcode != DFU_OK) { throw gcnew DFUException(eRetcode); } } void DFUDevice::UploadTwineExtras(TwineDFUExtras^ extras, ProgressCallbackDelegate^ callback) { tLMDFUErr eRetcode; MemoryStream^ ms = gcnew MemoryStream(); BinaryWriter^ writer = gcnew BinaryWriter(ms, System::Text::Encoding::ASCII); //Write extension code. writer->Write(EXTENSION_CODE); //Write date time. writer->Write(extras->UploadDateTime->Ticks); //Write version. writer->Write(extras->Version->Major); writer->Write(extras->Version->Minor); writer->Write(extras->Version->Build); writer->Write(extras->Version->Revision); //Write Comments. String^ fixedString = extras->Comments->PadRight(EXTENSION_COMMENTS_LENGTH, ' '); writer->Write(fixedString->ToCharArray()); //Write Image size. writer->Write(extras->ImageLength); array^ extraBytes = ms->ToArray(); delete writer; delete ms; pin_ptr pt = &extraBytes[0]; unsigned char* pby2 = pt; unsigned char* extraBuf = reinterpret_cast(pby2); //Create notification form. IntPtr formHandle = IntPtr::Zero; if (callback != nullptr) { ProgressForm^ f = gcnew ProgressForm(callback, false); formHandle = f->Handle; // forces the form Control to be created. } //Upload the extra info! eRetcode = _LMDFUDownloadBin(devHandle, extraBuf, EXTENSION_LENGTH, FlashTopAddress - FlashBlockSize, FALSE, formHandle != IntPtr::Zero ? (HWND)formHandle.ToPointer() : NULL); if (eRetcode != DFU_OK) { throw gcnew DFUException(eRetcode); } } void DFUDevice::Download(ProgressCallbackDelegate^ callback) { tLMDFUParams *psDFU; tLMDFUParams sDFU; tLMDFUErr eRetcode; size_t iLen; unsigned long g_ulLength = 0; // If it supports the Tiva DFU protocol, read back // some important parameters. if (SupportsTivaExtensions) { // Read flash size parameters from the device. eRetcode = _LMDFUParamsGet(devHandle, &sDFU); if (eRetcode != DFU_OK) { throw gcnew DFUException(eRetcode); } psDFU = &sDFU; } else { // The device doesn't support the Tiva // protocol so set the DFU parameter structure // pointer to NULL. psDFU = (tLMDFUParams *)0; } //Allocate image buffer. lastDownloadBytes = (unsigned char *)malloc(ImageLength); //Create notification form. IntPtr formHandle = IntPtr::Zero; if (callback != nullptr) { ProgressForm^ f = gcnew ProgressForm(callback, false); formHandle = f->Handle; // forces the form Control to be created. } //Download image from device. eRetcode = _LMDFUUpload(devHandle, lastDownloadBytes, AppStartAddress, ImageLength, TRUE, formHandle != IntPtr::Zero ? (HWND)formHandle.ToPointer() : NULL); if (eRetcode != DFU_OK) { throw gcnew DFUException(eRetcode); } } array^ DFUDevice::GetDownloadBytes() { //Create a managed array from the chars array. IntPtr ptr(lastDownloadBytes); array^ bytes = gcnew array(ImageLength); Marshal::Copy(ptr, bytes, 0, ImageLength); return bytes; } void DFUDevice::FetchTwineExtras() { tLMDFUErr eRetcode; unsigned char *buffer; //Allocate image buffer. buffer = (unsigned char *)malloc(EXTENSION_LENGTH); //Download extras from device. eRetcode = _LMDFUUpload(devHandle, buffer, FlashTopAddress - FlashBlockSize, EXTENSION_LENGTH, TRUE, NULL); if (eRetcode == DFU_OK) { //Create a managed array from the chars array. IntPtr ptr(buffer); array^ bytes = gcnew array(EXTENSION_LENGTH); Marshal::Copy(ptr, bytes, 0, EXTENSION_LENGTH); MemoryStream^ ms = gcnew MemoryStream(bytes); BinaryReader^ reader = gcnew BinaryReader(ms, System::Text::Encoding::ASCII); bool hasExtras = reader->ReadInt32() == EXTENSION_CODE; if (hasExtras) { //Put has extras. TwineExtras->HasExtras = true; //Create DateTime from ticks. TwineExtras->UploadDateTime = gcnew DateTime(reader->ReadInt64()); //Create version. TwineExtras->Version = gcnew Version(reader->ReadInt32(), reader->ReadInt32(), reader->ReadInt32(), reader->ReadInt32()); //Read Comments. TwineExtras->Comments = gcnew String(reader->ReadChars(EXTENSION_COMMENTS_LENGTH)); TwineExtras->Comments = TwineExtras->Comments->Trim(); //Read Image Length. TwineExtras->ImageLength = reader->ReadInt32(); //Set Accurate Image Size ImageLength = TwineExtras->ImageLength; } delete reader; delete ms; } } } }