Example #1
0
        void SendFirmwareUpdateImage(byte[] fwUpdateImageFileBuffer, uint payloadOffset, uint payloadLength, uint crcWord)
        {
            int  fwUpdateImageFileSize = fwUpdateImageFileBuffer.Length;
            uint packetSize            = 64;
            //byte[] fwUpdateImageFileBuffer = new byte[fwUpdateImageFileSize];
            uint bufferIndex;
            uint i;
            int  sentNormalPacketCount;//= 5000;
            uint packetSequenceNum;

            byte[] inBuf  = new byte[packetSize];
            byte[] outBuf = new byte[packetSize];
            int    nakSeqNum;

            //prepare trace to output file
            if (false)
            {
                Trace.Listeners.Add(new TextWriterTraceListener("FirmwareUpdateLog.txt"));
                Trace.AutoFlush = true;
            }

            try
            {
                // send start packet
                CreateStartPacket(outBuf, payloadLength, crcWord, packetSize);
                Device.SetHidFeatureReport(outBuf);
            }
            catch
            {
                throw;
            }

            Debug.WriteLine("OK! start packet!!!");
            UpdateFirmwareUpdateProtocolRevisionInDevice();

            LastStateReport          = new EgsDeviceFirmwareUpdateStateReport();
            LastStateReport.Message  = "Start sending boot image to device" + Environment.NewLine;
            LastStateReport.Message += "Current device firmware update protocol revision: " + FirmwareUpdateProtocolRevisionInDevice + Environment.NewLine;
            LastStateReport.Message += "Writing image file firmware update protocol revision: " + ImageFile.ProtocolRevision + Environment.NewLine;
            LastStateReport.Message += "Current device firmware revision: " + FirmwareVersionInDevice + Environment.NewLine;
            LastStateReport.Message += "Writing image file firmware revision: " + ImageFile.FirmwareVersion + Environment.NewLine;
            ProgressReport.ReportProgress(PercentProgress, LastStateReport);

            //-- check firmware version to update--
            if (ImageFile.ProtocolRevision <= FirmwareUpdateProtocolRevisionInDevice)
            {
                Debug.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Warning!! Image file protocol version= {0} is equal or older than device firmware protocol version= {1}", ImageFile.ProtocolRevision, FirmwareUpdateProtocolRevisionInDevice));
                if (IsToShowWarningMessages)
                {
                    // TODO: use Resources
                    MessageBoxResult mbr = MessageBox.Show("Image file version is equal or older than device firmware version." + Environment.NewLine + "Are you sure to continue?", "[WARNING] Trying to Upload Older Image to Device", MessageBoxButton.YesNo);
                    if (mbr == MessageBoxResult.No)
                    {
                        throw new OperationCanceledException();
                    }
                }
            }

            //-- send normal packet --
            bufferIndex           = 0;
            sentNormalPacketCount = 0;
            packetSequenceNum     = 1;
            uint loopCounter     = 0;
            uint errorCount      = 0;
            uint totalByteToSend = (uint)fwUpdateImageFileSize - payloadOffset;

            while ((payloadOffset + bufferIndex) < (fwUpdateImageFileSize - 1))
            {
                // NOTE: This is the long loop!
                if (ProgressReport.CancellationPending)
                {
                    throw new OperationCanceledException();
                }

                //--copy 64-4 bytes--
                for (i = 0; i < (packetSize - 4); i++)
                {
                    uint copyIndex = payloadOffset + bufferIndex + i;
                    if (copyIndex < fwUpdateImageFileSize)
                    {
                        inBuf[i] = fwUpdateImageFileBuffer[copyIndex];
                    }
                    else
                    {
                        //fill the rest with 0
                        inBuf[i] = 0;
                    }
                }

                // Deleted (2016/7/28)
                if (false)
                {
                    // NOTE: Added (2016/04/12)
                    Thread.Sleep(20);
                }

                sentNormalPacketCount = (int)packetSequenceNum;
                CreateFeaturePacket(packetSequenceNum, inBuf, outBuf, packetSize);

                {
                    // If it fails once, it continues to fail after Sleep(100) or waiting with debugger breaking.  Handle is Valid, so DevicePath may be correct.  SetFeature itself returns fail.
                    // Mr.T said, "Before the USB library in the device firmware has a stall problem, so retry was meaningful.  But now the bug is fixed so it may have no relation.".
                    var    trialCountMax = 1; // 10;
                    bool   hr            = false;
                    string errorMessage  = "";
                    for (int trialCount = 0; trialCount < trialCountMax; trialCount++)
                    {
                        try
                        {
                            Device.SetHidFeatureReport(outBuf);
                            hr = true;
                        }
                        catch (Exception ex)
                        {
                            if (false)
                            {
                                Debugger.Break();
                            }
                            errorMessage = ex.Message;
                            Debug.WriteLine(errorMessage);
                            Thread.Sleep(100);
                        }
                        if (hr)
                        {
                            break;
                        }
                    }
                    if (hr == false)
                    {
                        throw new InvalidOperationException(errorMessage);
                    }
                }


                PercentProgressInOneFile = RatioOfSendingImageFileInUpdatingByOneFile * (int)(bufferIndex + 1) / (int)totalByteToSend;
                Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Sent OK[{4:N2}%]: seqNum= 0x{0:X} bufferIndex= {1} sentPktCnt= 0x{2:X} totalRetransmitCnt={3}", packetSequenceNum, bufferIndex, sentNormalPacketCount, errorCount, PercentProgress));


                //-- get nak seq every 100 packets --
                loopCounter++;
                if ((loopCounter % 100) == 0)
                {
                    nakSeqNum = GetResponseFromDevice();

                    if (nakSeqNum > 0)
                    {
                        // resend NAK packet
                        errorCount++;
                        var report = new EgsDeviceFirmwareUpdateStateReport();
                        report.MessageForDebug = string.Format(CultureInfo.InvariantCulture, "Resend packet with seqNum= 0x{0:X}", nakSeqNum);
                        ProgressReport.ReportProgress(PercentProgress, report);
                        packetSequenceNum = (uint)nakSeqNum;
                    }
                    else
                    {
                        // not nak message, just skip
                        packetSequenceNum++;
                    }
                }
                else
                {
                    packetSequenceNum++;
                }

                // update bufferIndex
                if ((packetSequenceNum - 1) >= 0)
                {
                    bufferIndex = (packetSequenceNum - 1) * (packetSize - 4);
                }
                else
                {
                    bufferIndex = 0;
                }
            }


            // send end packet, commandID= 1(transfer complete)
            CreateEndPacket(outBuf, sentNormalPacketCount, 64, 1);
            try { Device.SetHidFeatureReport(outBuf); }
            catch (Exception ex) { throw new InvalidOperationException("Failed to send end packet.  Error Message: " + ex.Message); }


            // wait device to complete received buffer error checking
            if (WaitUpdateFinishResponse(1, 10000) == false)
            {
                throw new InvalidOperationException("No response from device.");
            }
            Debug.WriteLine("Finish transferring all image data to device successfully.");
            LastStateReport = new EgsDeviceFirmwareUpdateStateReport();


            // TODO: use Resources
            LastStateReport.Message = "Complete transferring boot image to device." + Environment.NewLine + "Now start writing to device flash memory." + Environment.NewLine;
            ProgressReport.ReportProgress(PercentProgress, LastStateReport);
            Debug.WriteLine("TURN OFF device power after click OK prior to flash writing completion, will damage device!");



            Debug.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Sending start write to flash command to device."));
            // send end packet, commandID= 2(start write to flash)
            CreateEndPacket(outBuf, sentNormalPacketCount, 64, 2);


            try { Device.SetHidFeatureReport(outBuf); }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                throw new InvalidOperationException("Sorry, but failed to send end packet.");
            }


            // wait device to complete write to flash
            if (WaitUpdateFinishResponse(2, 60000) == false)
            {
                throw new InvalidOperationException("No response from device.");
            }
        }
Example #2
0
        EgsDeviceFirmwareUpdateResult DoWorkInternal()
        {
            try
            {
                if (FirmwareImageFilePathList == null)
                {
                    throw new ArgumentNullException("binaryFilepathList");
                }
                if (FirmwareImageFilePathList.Count == 0)
                {
                    throw new ArgumentException("binaryFilepathList.Count == 0");
                }

                // TODO: MUSTDO: test!
                Device.WaitTimeInMillisecondsBeforeSetFeatureReport = 2;
                Device.WaitTimeInMillisecondsBeforeGetFeatureReport = 10;

                CurrentIndexInFirmwareImageFilePathList = 0;
                LastStateReport = new EgsDeviceFirmwareUpdateStateReport()
                {
                    Message = "File List:" + Environment.NewLine
                };
                foreach (var firmwareImageFilePath in FirmwareImageFilePathList)
                {
                    LastStateReport.Message += "  " + firmwareImageFilePath + Environment.NewLine;
                }
                ProgressReport.ReportProgress(PercentProgress, LastStateReport);

                // NOTE: Rebooting device is unnecessary before staring DFU.  It is OK if the device is connected.
                LetUserConnectDevice();

                _CurrentIndexInFirmwareImageFilePathList = -1;
                foreach (var firmwareImageFilePath in FirmwareImageFilePathList)
                {
                    CurrentIndexInFirmwareImageFilePathList++;
                    // NOTE: If it is not set to 0, ProgressReport become increase unexpectedly.
                    PercentProgressInOneFile = 0;
                    LastStateReport          = new EgsDeviceFirmwareUpdateStateReport()
                    {
                        Message = "Sending image file path: " + firmwareImageFilePath + Environment.NewLine
                    };
                    ProgressReport.ReportProgress(PercentProgress, LastStateReport);

                    if (File.Exists(firmwareImageFilePath) == false)
                    {
                        throw new FileNotFoundException(Resources.EgsDeviceFirmwareUpdateModel_DfuImageFileIsInvalid, firmwareImageFilePath);
                    }
                    ImageFile = new EgsDeviceFirmwareUpdateImageFileModel(firmwareImageFilePath);
                    if (ImageFile == null || ImageFile.LoadedImageAsByteArray == null)
                    {
                        throw new FileFormatException(Resources.EgsDeviceFirmwareUpdateModel_DfuImageFileIsInvalid);
                    }

                    bool hasOneFileCompleted = false;
                    while (hasOneFileCompleted == false)
                    {
                        try
                        {
                            PercentProgressInOneFile = 0;
                            var startDateTime = DateTime.Now;
                            LastStateReport = new EgsDeviceFirmwareUpdateStateReport()
                            {
                                Message = "Start Time: " + startDateTime.ToString() + Environment.NewLine
                            };
                            ProgressReport.ReportProgress(PercentProgress, LastStateReport);

                            SendFirmwareUpdateImage(ImageFile.LoadedImageAsByteArray, ImageFile.PayloadOffset, ImageFile.PayloadLength, ImageFile.CrcWord);

                            var endDateTime = DateTime.Now;
                            LastStateReport = new EgsDeviceFirmwareUpdateStateReport()
                            {
                                Message = "End Time: " + DateTime.Now.ToString() + "  Elapsed: " + (endDateTime - startDateTime).ToString() + Environment.NewLine
                            };
                            ProgressReport.ReportProgress(PercentProgress, LastStateReport);

                            hasOneFileCompleted = true;
                        }
                        catch (OperationCanceledException)
                        {
                            throw;
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.Message);
                            var msg = Resources.EgsDeviceFirmwareUpdateModel_DfuFailed + Environment.NewLine;
                            msg            += Resources.EgsDeviceFirmwareUpdateModel_AppWillRetrySendingImageAgain + Environment.NewLine;
                            LastStateReport = new EgsDeviceFirmwareUpdateStateReport()
                            {
                                Message = msg, UserNotificationMessage = msg
                            };
                            LastStateReport.MessageForDebug = ex.Message;
                            ProgressReport.ReportProgress(PercentProgress, LastStateReport);
                        }
                        // NOTE: Whether it success or fails, reboot is necessary.
                        LetUserRestartDeviceByReconnectingUsbConnector();
                    }
                }

                // succeeded
                LastStateReport         = new EgsDeviceFirmwareUpdateStateReport();
                LastStateReport.Message = Resources.EgsDeviceFirmwareUpdateModel_DfuCompleted + Environment.NewLine;
                LastStateReport.UserNotificationMessage = Resources.EgsDeviceFirmwareUpdateModel_DfuCompleted + Environment.NewLine;
                LastStateReport.MessageForDebug         = Resources.EgsDeviceFirmwareUpdateModel_DfuCompleted;
                ProgressReport.ReportProgress(100, LastStateReport);
                MessageText = LastStateReport.Message;
                return(new EgsDeviceFirmwareUpdateResult(false, false, true, Resources.EgsDeviceFirmwareUpdateModel_DfuCompleted));
            }
            catch (OperationCanceledException ex)
            {
                Debug.WriteLine(ex.Message);
                LastStateReport         = new EgsDeviceFirmwareUpdateStateReport();
                LastStateReport.Message = Resources.EgsDeviceFirmwareUpdateModel_DfuCanceled + Environment.NewLine + Resources.EgsDeviceFirmwareUpdateModel_RestartDfuFromBeginning + Environment.NewLine;
                LastStateReport.UserNotificationMessage = LastStateReport.Message;
                LastStateReport.MessageForDebug         = ex.Message;
                ProgressReport.ReportProgress(PercentProgress, LastStateReport);
                MessageText = LastStateReport.Message;
                return(new EgsDeviceFirmwareUpdateResult(false, true, false, Resources.EgsDeviceFirmwareUpdateModel_DfuCanceled));
            }
        }