private void EraseDeploymentSectors(string devicePath, Firmware upgradeFirmware) { STDfuDevice device = new STDfuDevice(devicePath); // TODO: make sure we are in DFU mode; if we are in app mode (runtime) then we need to detach and re-enumerate. // get our total deployment sectors count List <uint> allSectorBaseAddresses = new List <uint>(); foreach (Firmware.FirmwareRegion region in upgradeFirmware.FirmwareRegions) { if (region.Name.ToUpper() == "DEPLOYMENT") { allSectorBaseAddresses.AddRange(region.SectorBaseAddresses); } } // erase each sector for (int iSector = 0; iSector < allSectorBaseAddresses.Count; iSector++) { if (!device.EraseSector(allSectorBaseAddresses[iSector])) { throw new Exception("Could not erase sector."); } _updateWorker.ReportProgress((int)((((double)iSector + 1) / (double)allSectorBaseAddresses.Count) * 100)); } //// step 4: restart board //device.SetAddressPointer(0x08000001); // NOTE: for thumb2 instructinos, we added 1 to the "base address". Otherwise our board will not restart properly. //// leave DFU mode. //device.LeaveDfuMode(); }
private Firmware GetLatestFirmwareForProduct(byte productID) { Firmware newestFirmware = null; foreach (Firmware firmware in _firmwares) { if (firmware.ProductID == productID) { if (newestFirmware == null || (newestFirmware.Version.CompareTo(firmware.Version) < 0)) { newestFirmware = firmware; } } } return(newestFirmware); }
private void EraseAndUploadDevice(string devicePath, Firmware upgradeFirmware, double startProgressPercent, double operationTotalProgressPercent) { double localProgressPercent = 0.0; STDfuDevice device = new STDfuDevice(devicePath); // TODO: make sure we are in DFU mode; if we are in app mode (runtime) then we need to detach and re-enumerate. // get our total sectors and block counts List <uint> allSectorBaseAddresses = new List <uint>(); uint totalBlockCount = 0; foreach (Firmware.FirmwareRegion region in upgradeFirmware.FirmwareRegions) { allSectorBaseAddresses.AddRange(region.SectorBaseAddresses); if (region.Filename != null) { System.IO.StreamReader streamReader = new System.IO.StreamReader(upgradeFirmware.FolderPath + "\\" + region.Filename); string hexFileString = streamReader.ReadToEnd(); streamReader.Dispose(); byte[] hexFileBytes = SrecHexEncoding.GetBytes(hexFileString, region.BaseAddress); totalBlockCount += (uint)Math.Ceiling((double)hexFileBytes.Length / (double)device.BlockTransferSize); } } // erase each sector for (int iSector = 0; iSector < allSectorBaseAddresses.Count; iSector++) { if (!device.EraseSector(allSectorBaseAddresses[iSector])) { throw new Exception("Could not erase sector."); } localProgressPercent = (((double)iSector + 1) / (double)allSectorBaseAddresses.Count) * 0.5; _updateWorker.ReportProgress(CalculateWorkerProgress(localProgressPercent, startProgressPercent, operationTotalProgressPercent)); } // do "read unprotect" //Debug.Print("Unprotecting all sectors, erasing..."); //Debug.Print("operation " + (stdfuDeviceReadUnprotect() ? "SUCCESS" : "FAILED")); //// do mass erase //Debug.Print("erasing all sectors..."); //Debug.Print("operation " + (device.EraseAllSectors() ? "SUCCESS" : "FAILED")); //localProgressPercent = 0.3; // now flash the board! ushort blockSize = device.BlockTransferSize; ushort completedBlocks = 0; foreach (Firmware.FirmwareRegion region in upgradeFirmware.FirmwareRegions) { if (region.Filename != null) { System.IO.StreamReader streamReader = new System.IO.StreamReader(upgradeFirmware.FolderPath + "\\" + region.Filename); string hexFileString = streamReader.ReadToEnd(); streamReader.Dispose(); byte[] hexFileBytes = SrecHexEncoding.GetBytes(hexFileString, region.BaseAddress); // set our download address pointer if (device.SetAddressPointer(region.BaseAddress) == false) { throw new Exception("Could not set base address for flash operation."); } // write blocks to the board and verify; we must have already erased our sectors before this point for (ushort index = 0; index <= (hexFileBytes.Length / blockSize); index++) { // write block to the board byte[] buffer = new byte[Math.Min(hexFileBytes.Length - (index * blockSize), blockSize)]; Array.Copy(hexFileBytes, index * blockSize, buffer, 0, buffer.Length); bool success = device.WriteMemoryBlock(index, buffer); if (!success) { throw new Exception("Write failed."); } // verify written block byte[] verifyBuffer = new byte[buffer.Length]; success = device.ReadMemoryBlock(index, verifyBuffer); if (!success || !buffer.SequenceEqual(verifyBuffer)) { throw new Exception("Verify failed."); } completedBlocks++; localProgressPercent = 0.5 + (((double)(completedBlocks + 1) / (double)totalBlockCount) * 0.5); _updateWorker.ReportProgress(CalculateWorkerProgress(localProgressPercent, startProgressPercent, operationTotalProgressPercent)); } } } // step 4: restart board device.SetAddressPointer(0x08000001); // NOTE: for thumb2 instructinos, we added 1 to the "base address". Otherwise our board will not restart properly. // leave DFU mode. device.LeaveDfuMode(); }
private void OnDeviceArrival(Guid classGuid, string devicePath) { if (classGuid == DEVICE_INTERFACE_GUID_STDFU) { bool alreadyFound = false; foreach (DeviceInfo deviceInfo in _devices) { if (deviceInfo.DevicePath.ToUpper() == devicePath.ToUpper()) { alreadyFound = true; break; } } if (!alreadyFound) { // get the board's device type and settings try { byte productID; byte[] macAddress; byte otpSlotsFree; OtpSettings otpSettings = new OtpSettings(devicePath); bool success = otpSettings.ReadSettings(out productID, out macAddress, out otpSlotsFree); if (!success) { _devices.Add(new DeviceInfo() { CanUpdate = false, OtpSlotsFree = 0, IsChecked = false, DevicePath = devicePath, MacAddress = macAddress, ProductID = productID, ProductName = "Unknown (please reconnect)", UpgradeFirmware = null, UpgradeVersion = "Unknown", }); return; } /* BEGIN: ADD THIS IN IF WE WANT TO AUTO-SET OUR OTP PRODUCT ID EN MASSE */ if (otpSlotsFree > 2) { otpSettings.ReadSettings(out productID, out macAddress, out otpSlotsFree); if (productID == 0) { // 9=Netduino3Wifi // 8=Netduino3Ethernet // 5=NetduinoPlus2 // 7=Netduino3 // 6=Netduino2 otpSettings.WriteSettings(9, _macAddresses.GetNextAddress()); //otpSettings.WriteSettings(6, macAddress); } success = otpSettings.ReadSettings(out productID, out macAddress, out otpSlotsFree); if (!success) { return; } } /* END: ADD THIS IN IF WE WANT TO AUTO-SET OUR OTP PRODUCT ID EN MASSE */ // by default, we hide one OTP slot. This is so that users cannot accidentally use up all slots--and have one final chance to change the cnofiguration. if (otpSlotsFree >= 1 && _hideOneOtpSlot) { otpSlotsFree--; } // now find the latest firmware for this product Firmware upgradeFirmware = null; if (productID != 0) { upgradeFirmware = GetLatestFirmwareForProduct(productID); } string productName = (upgradeFirmware != null ? upgradeFirmware.ProductName : "STM Device in DFU Mode"); _devices.Add(new DeviceInfo() { CanUpdate = (upgradeFirmware != null), OtpSlotsFree = otpSlotsFree, IsChecked = false, DevicePath = devicePath, MacAddress = macAddress, ProductID = productID, ProductName = productName, UpgradeFirmware = upgradeFirmware, UpgradeVersion = (upgradeFirmware != null ? upgradeFirmware.Version.ToString() + (upgradeFirmware.VersionBetaSuffix != null ? " " + upgradeFirmware.VersionBetaSuffix : "") : "Unknown") }); } catch { } } } }