Exemple #1
0
        }//ds30L_Downloading()

        //---------------------------------------------------------------------
        // Constructor
        //---------------------------------------------------------------------
        public void DoMagic(string[] pstrArgs, ref bool pbResult)
        {
            pbResult = false;


            //-----------------------------------------------------------------
            // If no argumentsa are specified, display help
            //-----------------------------------------------------------------
            if (pstrArgs.Length == 0)
            {
                PrintHelp();
                return;
            }


            //-----------------------------------------------------------------
            // Validate arguments
            //-----------------------------------------------------------------
            bool                bResult             = false;
            clsParseSettings    objParseSettings    = new clsParseSettings();
            clsDownloadSettings objDownloadSettings = new clsDownloadSettings();

            ValidateParseArgs(pstrArgs, objParseSettings, objDownloadSettings, ref bResult);
            if (bResult == false)
            {
                return;
            }


            //-----------------------------------------------------------------
            // Nothing to do?
            //-----------------------------------------------------------------
            if (objDownloadSettings.writeProgram == false && objDownloadSettings.writeEEPROM == false && objDownloadSettings.writeConfigs == false)
            {
                Console.WriteLine("Nothing to do.");
                return;
            }


            //-----------------------------------------------------------------
            // Parse
            //-----------------------------------------------------------------
            objParseSettings.device = objDevice;
            DoParse(objParseSettings, objDownloadSettings);


            //-----------------------------------------------------------------
            // Create port
            //-----------------------------------------------------------------
            objPort = new clsSerialPort();
            objPort.Setup(strPort, iBaudrate);


            //-----------------------------------------------------------------
            // Increase process priority if polltime is low
            //-----------------------------------------------------------------
            if (objDownloadSettings.polltime < 100)
            {
                try {
                    System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.AboveNormal;
                } catch {
                    clsDebugTextbox.OutputInfo("Setting proccess priority failed.");
                }
            }


            //-----------------------------------------------------------------
            // Print settings
            //-----------------------------------------------------------------
            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("{0,-10} {1, -8}", "File:", strFile);
            Console.WriteLine("{0,-10} {1, -8}", "Port:", strPort);
            Console.WriteLine("{0,-10} {1, -8}", "Baudrate:", iBaudrate.ToString());
            Console.WriteLine("{0,-10} {1, -8}", "Device:", objDevice.name);


            //-----------------------------------------------------------------
            //
            //-----------------------------------------------------------------
            Console.WriteLine("");
            Console.WriteLine("");
            if (bNonInteractive == false)
            {
                Console.WriteLine("Press any key to begin download");
                Console.WriteLine("");
                Console.ReadKey();
            }


            //-----------------------------------------------------------------
            // Download
            //-----------------------------------------------------------------
            bool bDownloadResult = false;
            int  iStartTime      = Environment.TickCount;

            clsds30Loader.Download(objDevice, objPort, objHex, objDownloadSettings, 0, ref bDownloadResult);
            int iEndTime = Environment.TickCount;


            //-----------------------------------------------------------------
            // Restore process priority
            //-----------------------------------------------------------------
            if (objDownloadSettings.polltime < 100)
            {
                try {
                    System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.Normal;
                } catch {
                    clsDebugTextbox.OutputInfo("Setting proccess priority failed.");
                }
            }

            //-----------------------------------------------------------------
            // Download finished
            //-----------------------------------------------------------------
            objPort.Close();
            if (clsds30Loader.debugMode)
            {
                clsDebugTextbox.OutputInfo("Elapsed time: " + String.Format("{0:0.#}", Convert.ToSingle(iEndTime - iStartTime) / 1000.0) + " seconds", 1);
            }
            pbResult = bDownloadResult;
        }// DoMagic()
        }//ds30L_Downloading()	

        
        //---------------------------------------------------------------------
        // Constructor
        //---------------------------------------------------------------------
        public void DoMagic( string[] pstrArgs, ref bool pbResult ) 
        {
            pbResult = false;            

            
            //-----------------------------------------------------------------
            // If no argumentsa are specified, display help
            //-----------------------------------------------------------------
            if ( pstrArgs.Length == 0 ) {
                PrintHelp();
                return;
            }


            //-----------------------------------------------------------------
            // Validate arguments
            //-----------------------------------------------------------------
            bool bResult = false;
            clsParseSettings objParseSettings = new clsParseSettings();
            clsDownloadSettings objDownloadSettings = new clsDownloadSettings();
            ValidateParseArgs( pstrArgs, objParseSettings, objDownloadSettings, ref bResult );
            if ( bResult == false ) {
                return;
            }


            //-----------------------------------------------------------------
            // Nothing to do?
            //-----------------------------------------------------------------
			if ( objDownloadSettings.writeProgram == false && objDownloadSettings.writeEEPROM == false && objDownloadSettings.writeConfigs == false  ) {
				Console.WriteLine( "Nothing to do." );
				return;
			}


            //-----------------------------------------------------------------
            // Parse
            //-----------------------------------------------------------------
            objParseSettings.device = objDevice;
            DoParse( objParseSettings, objDownloadSettings );

            
            //-----------------------------------------------------------------
            // Create port
            //-----------------------------------------------------------------
            objPort = new clsSerialPort();
            objPort.Setup( strPort, iBaudrate );


            //-----------------------------------------------------------------
            // Increase process priority if polltime is low
            //-----------------------------------------------------------------
            if ( objDownloadSettings.polltime < 100 ) {
                try {
                    System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.AboveNormal;
                } catch {
                    clsDebugTextbox.OutputInfo( "Setting proccess priority failed." );
                }
            }


            //-----------------------------------------------------------------
            // Print settings
            //-----------------------------------------------------------------
            Console.WriteLine( "" );
            Console.WriteLine( "" );
            Console.WriteLine( "{0,-10} {1, -8}", "File:", strFile );
            Console.WriteLine( "{0,-10} {1, -8}", "Port:", strPort );
            Console.WriteLine( "{0,-10} {1, -8}", "Baudrate:", iBaudrate.ToString() );
            Console.WriteLine( "{0,-10} {1, -8}", "Device:", objDevice.name );


            //-----------------------------------------------------------------
            // 
            //-----------------------------------------------------------------            
            Console.WriteLine( "" );
            Console.WriteLine( "" );
            if ( bNonInteractive == false ) {
                Console.WriteLine( "Press any key to begin download" );
                Console.WriteLine( "" );
                Console.ReadKey();
            }
            

            //-----------------------------------------------------------------
            // Download
            //-----------------------------------------------------------------
            bool bDownloadResult = false;
            int iStartTime = Environment.TickCount;
            clsds30Loader.Download( objDevice, objPort, objHex, objDownloadSettings, 0, ref bDownloadResult );
            int iEndTime = Environment.TickCount;


            //-----------------------------------------------------------------
            // Restore process priority
            //-----------------------------------------------------------------
            if ( objDownloadSettings.polltime < 100 ) {
                try {
                    System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.Normal;
                } catch {
                    clsDebugTextbox.OutputInfo( "Setting proccess priority failed." );
                }
            }

            //-----------------------------------------------------------------
            // Download finished
            //-----------------------------------------------------------------            
            objPort.Close();
            if ( clsds30Loader.debugMode ) {
                clsDebugTextbox.OutputInfo( "Elapsed time: " + String.Format( "{0:0.#}", Convert.ToSingle(iEndTime - iStartTime) / 1000.0 ) + " seconds", 1 );			
            } 
            pbResult = bDownloadResult;
        }// DoMagic()
        //---------------------------------------------------------------------
        // ResetDevice()
        //---------------------------------------------------------------------
        private static void ResetDevice( clsSerialPort pobjPort, clsDownloadSettings pobjSettings, int iTabLevel, ref bool pbResult )
        {
            pbResult = false;

            //--------------------------------------------------------------------------
            // Reset - command
            //--------------------------------------------------------------------------
            if ( pobjSettings.resetCommand == true ) {
                // Inform user
                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, "Sending reset command", iTabLevel) );

                // Parse resetcommand
                bool bSplitResult = false;
                byte[] bBytes = pobjPort.SplitHexStringToBytes( pobjSettings.resetCommandSequence, ref bSplitResult );
                if ( bSplitResult == false ) {
                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Couldn't parse reset command sequence", iTabLevel) );
                    return;
                }
                /*string[] strBytes = pobjSettings.resetCommandSequence.Split( ';' );
                byte[] bBytes = new byte[ strBytes.Length ];
                int iIndex = 0;
                foreach ( string strByte in strBytes ) {
                    bBytes[iIndex] = byte.Parse( strByte, System.Globalization.NumberStyles.HexNumber );
                    ++iIndex;
                }*/

                // Open port
                int iOldBaudrate = pobjPort.baudrate;
                pobjPort.baudrate = pobjSettings.resetBaudrate;
                bool bOpenPortResult = false;
                PortOpen( pobjPort, pobjSettings, ref bOpenPortResult );

                // Send reset command and close port
                pobjPort.SendBytes( ref bBytes, bBytes.Length );
                while ( pobjPort.outBufferCount > 0 );
                pobjPort.Close();

                // Restore baudrate
                pobjPort.baudrate = iOldBaudrate;

                SleepResponsive( pobjSettings.resetTime );

            //--------------------------------------------------------------------------
            // Reset - dtr
            //--------------------------------------------------------------------------
            } else if ( pobjSettings.resetDtr == true ) {
                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, "Resetting by dtr", iTabLevel) );
                pobjPort.dtrEnable = true;
                SleepResponsive( pobjSettings.resetTime );
                pobjPort.dtrEnable = false;

            //--------------------------------------------------------------------------
            // Reset - rts
            //--------------------------------------------------------------------------
            } else if ( pobjSettings.resetRts == true ) {
                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, "Resetting by rts", iTabLevel) );
                pobjPort.rtsEnable = true;
                SleepResponsive( pobjSettings.resetTime );
                pobjPort.rtsEnable = false;
            }

            pbResult = true;
        }
 //---------------------------------------------------------------------
 // PortClose()
 //---------------------------------------------------------------------
 private static void PortClose( clsSerialPort pobjPort )
 {
     pobjPort.Close();
 }
        //---------------------------------------------------------------------
        // FindLoader()
        //---------------------------------------------------------------------
        public static void FindLoader( clsDevice pobjDevice, clsSerialPort pobjPort , clsDownloadSettings pobjSettings, int iTabLevel, ref bool pbResult )
        {
            int iDeviceIdFound = -1;
            bool bGetResponseResult = false;
            bool bPortWasOpened = false;

            pbResult = false;

            //-----------------------------------------------------------------
            // Test-mode
            //-----------------------------------------------------------------
            if ( bTestMode == true ) {
                iFWVerMaj = iTestVerMaj;
                iFWVerMin = iTestVerMin;
                iFWVerRev = iTestVerRev;
                iDeviceIdFound = iTestDeviceID;
                //return true;

            //-----------------------------------------------------------------
            // Real-mode
            //-----------------------------------------------------------------
            } else {

                int iVerMaj = 0, iVerMinRev = 0;
                int iTimeIdReceived = 0;

                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, "Searching for bl ", iTabLevel) );

                //--------------------------------------------------------------------------
                // Open port if not open
                //--------------------------------------------------------------------------
                if ( pobjPort.isOpen == false ) {
                    pobjPort.Open();
                    if ( pobjPort.isOpen == false ) {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Failed to open port", iTabLevel) );
                        return;
                    }
                    bPortWasOpened = true;
                }

                // Empty buffers prior to hello command incase there's some crap
                pobjPort.EmptyBuffers( true, false );

                //--------------------------------------------------------------------------
                // Send hello to bootloader
                //--------------------------------------------------------------------------
                bool bDeviceIDReceived = false;
                {
                    int iLastSend = Environment.TickCount - pobjSettings.polltime;
                    int iLastPoll = Environment.TickCount - pobjSettings.polltime;
                    int iStartTime = Environment.TickCount;

                    bool bByteReceived = false;

                    bool bTimedOut = false;

                    do {
                        // Check first byte, discard if null
                        if ( Environment.TickCount - iLastPoll >= pobjSettings.polltime/10) {
                            iLastPoll = Environment.TickCount;

                            if ( bByteReceived == false && pobjPort.inBufferCount > 0 ) {
                                bByteReceived = true;
                                iDeviceIdFound = GetResponse( pobjPort, ref bGetResponseResult );
                                if ( bGetResponseResult == false ) {
                                    if ( bPortWasOpened == true ) pobjPort.Close();
                                    return;
                                }
                                if ( iDeviceIdFound == 0 ) {
                                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, "(discarded null byte)", -1) );
                                } else {
                                    bDeviceIDReceived = true;
                                    iTimeIdReceived = Environment.TickCount;
                                    break;
                                }

                            }
                        }

                        // Send hello
                       if ( Environment.TickCount - iLastSend >= pobjSettings.polltime ) {
                            iLastSend = Environment.TickCount;
                            pobjPort.SendByte( cHello );
                            OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, ". ", -1) );
                        }

                        // Check for timeout
                        bTimedOut = ( Environment.TickCount - iStartTime >= pobjSettings.timeout );

                        // Handle message queue
                        Application.DoEvents();
                    } while (
                        bAbort == false &&
                        bTimedOut == false &&
                        (bByteReceived == false || pobjPort.inBufferCount == 0)
                    );

                    if ( bAbort == true  ) {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "aborted", -1) );
                        bAbort = false;
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    } else if ( bTimedOut == true ) {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "timed out", -1) );
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }
                }

                //--------------------------------------------------------------------------
                // Read device id
                //--------------------------------------------------------------------------
                if ( bDeviceIDReceived == false ) {
                    iDeviceIdFound = GetResponse( pobjPort, ref bGetResponseResult );
                    if ( bGetResponseResult == false ) {
                        iTimeIdReceived = Environment.TickCount;
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }
                }

                //--------------------------------------------------------------------------
                // Delay to receive firmware version if any
                //--------------------------------------------------------------------------
                int iTime = 1 + 30000 / pobjPort.baudrate;
                while ( Environment.TickCount - iTimeIdReceived < iTime && pobjPort.inBufferCount < 3 ) {
                }

                //--------------------------------------------------------------------------
                // Firmware doesn´t send version, assume 0.9.4
                //--------------------------------------------------------------------------
                if ( pobjPort.inBufferCount == 1 ) {
                        iFWVerMaj = 0;
                        iFWVerMin = 9;
                        iFWVerRev = 4;

                //--------------------------------------------------------------------------
                // Firmware that sends major and minor
                //--------------------------------------------------------------------------
                } else if ( pobjPort.inBufferCount == 2 ) {
                    iVerMaj = GetResponse( pobjPort, ref bGetResponseResult );
                    if ( bGetResponseResult == false ) {
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }
                    iFWVerMaj = ( (iVerMaj & 0x70) >> 4 );
                    iFWVerMin = ( iVerMaj & 0xF );
                    iFWVerRev = 0;

                //--------------------------------------------------------------------------
                // Firmware that sends major, minor and revision
                //--------------------------------------------------------------------------
                } else if ( pobjPort.inBufferCount == 3 ) {
                    iVerMaj = GetResponse( pobjPort, ref bGetResponseResult );
                    if ( bGetResponseResult == false ) {
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }
                    iVerMinRev = GetResponse( pobjPort, ref bGetResponseResult );
                    if ( bGetResponseResult == false ) {
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }

                    iFWVerMaj = ( iVerMaj & 0x7F );
                    iFWVerMin = ( (iVerMinRev & 0xF0) >> 4 );
                    iFWVerRev = ( iVerMinRev & 0xF );
                }

                //--------------------------------------------------------------------------
                // PIC18 indicated by msb in fw ver major
                //--------------------------------------------------------------------------
                if ( (iVerMaj & 0x80) > 0 ) {
                    iDeviceIdFound += 300;
                }
            }//Test-/real-mode

            //--------------------------------------------------------------------------
            // Find device from device id
            //--------------------------------------------------------------------------
            clsDevice objFoundDevice = clsDevices.DeviceGet( iDeviceIdFound );

            //--------------------------------------------------------------------------
            // Invalid ID returned
            //--------------------------------------------------------------------------
            if ( objFoundDevice == null ) {
                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Found unknown device id(" + iDeviceIdFound.ToString() + ") fw ver. " + iFWVerMaj.ToString() + "." + iFWVerMin.ToString() + "." + iFWVerRev.ToString(), iTabLevel) );
                if ( bPortWasOpened == true ) pobjPort.Close();
                return;
            }

            //--------------------------------------------------------------------------
            // Bootloader found
            //--------------------------------------------------------------------------
            OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.success, "Found " + objFoundDevice.name + " fw ver. " + iFWVerMaj.ToString() + "." + iFWVerMin.ToString() + "." + iFWVerRev.ToString(), iTabLevel) );

            //--------------------------------------------------------------------------
            // Different device found from choosen
            //--------------------------------------------------------------------------
            if ( objFoundDevice.id != pobjDevice.id ) {
                OnDownloading(new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Wrong pic detected(" + objFoundDevice.id.ToString() + ")/selected(" + pobjDevice.id.ToString() + "), aborting", iTabLevel));
                if ( bPortWasOpened == true ) pobjPort.Close();
                return;
            }

            pbResult = true;

            // Close port if it was openeed
            if ( bPortWasOpened == true ) {
                pobjPort.Close();
            }
        }
        //---------------------------------------------------------------------
        // Download()
        //---------------------------------------------------------------------
        public static void Download( clsDevice pobjDevice, clsSerialPort pobjPort, clsHex pobjHex, clsDownloadSettings pobjSettings, int iTabLevel, ref bool pbResult )
        {
            //
            bool bWriteSuccess = false;
            bool bParseResult = false;

            pbResult = false;
            bAbort = false;
            OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.started, "Initiating download...", iTabLevel++) );

            // Test-mode
            if ( bTestMode == true ) {
                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.warning, "Test-mode is active", iTabLevel) );
            }

            //--------------------------------------------------------------------------
            // Reset device
            //--------------------------------------------------------------------------
            bool bResetResult = false;
            ResetDevice( pobjPort, pobjSettings, iTabLevel, ref bResetResult );
            if ( bResetResult == false ) {
                return;
            }

            //--------------------------------------------------------------------------
            // Open port
            //--------------------------------------------------------------------------
            bool bOpenPortResult = false;
            PortOpen( pobjPort, pobjSettings, ref bOpenPortResult );

            //--------------------------------------------------------------------------
            // Find loader
            //--------------------------------------------------------------------------
            bool bFindLoaderResult = false;
            FindLoader( pobjDevice, pobjPort, pobjSettings, iTabLevel, ref bFindLoaderResult );
            if ( bFindLoaderResult == false ) {
                PortClose( pobjPort );
                return;
            }

            //--------------------------------------------------------------------------
            // Init progressbar
            //--------------------------------------------------------------------------
            OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.progressStarted, "", 0) );

            //--------------------------------------------------------------------------
            // Determine size of the bootloader found
            //--------------------------------------------------------------------------
            bool bGetBLSizeResult = false;
            iBootloaderSizeR = GetBLSize( pobjDevice, ref bGetBLSizeResult );
            if ( bGetBLSizeResult == false ) {
                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Unknown firmware version", iTabLevel) );
                PortClose( pobjPort );
                return;
            }

            //--------------------------------------------------------------------------
            //
            //--------------------------------------------------------------------------
            bool WaitBLReadyResponseResult = false;
            WaitBLReadyResponse( pobjPort, iTabLevel, ref WaitBLReadyResponseResult );
            if ( WaitBLReadyResponseResult == false ) {
                PortClose( pobjPort );
                return;
            }

            //--------------------------------------------------------------------------
            // Setup parse settings
            //--------------------------------------------------------------------------
            clsParseSettings objParseSettings = new clsParseSettings( iBootloaderSizeR, pobjDevice, false, pobjSettings.noGoto );

            //--------------------------------------------------------------------------
            // PIC18F
            //--------------------------------------------------------------------------
            if ( pobjDevice.family.name == "PIC18F" ) {
                clsHex18F objHex18F = (clsHex18F)pobjHex;

                // Parse
                objHex18F.ParseHexFile( objParseSettings, iTabLevel, ref bParseResult );
                if ( bParseResult == false ) {
                    PortClose( pobjPort );
                    return;
                }

                // Write versions 0.9.0 - 1.0.0
                if (
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 2 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 1 )
                ) {
                    bWriteSuccess = WriteFlash18F_0_9_0( pobjPort, pobjDevice, objHex18F, pobjSettings.writeProgram, pobjSettings.writeEEPROM, pobjSettings.writeConfigs, iTabLevel );

                    // Write versions 1.5
                } else if (
                    ( iFWVerMaj == 1 && iFWVerMin == 5 )
                ) {
                    bWriteSuccess = WriteFlash18F_0_9_0( pobjPort, pobjDevice, objHex18F, pobjSettings.writeProgram, false, false, iTabLevel );

                // Unkown version
                } else {
                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Unknown firmware version", iTabLevel) );
                    PortClose( pobjPort );
                    return;
                }

            //--------------------------------------------------------------------------
            // PIC18FJ
            //--------------------------------------------------------------------------
            } else if ( pobjDevice.family.name == "PIC18FJ" ) {
                clsHex18FJ objHex18FJ = (clsHex18FJ)pobjHex;

                // Parse
                objHex18FJ.ParseHexFile( objParseSettings, iTabLevel, ref bParseResult );
                if ( bParseResult == false ) {
                    PortClose( pobjPort );
                    return;
                }

                // Write versions 0.9.0 - 0.9.1
                if (
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 1 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 0 )
                ) {
                    bWriteSuccess = WriteFlash18FJ_0_9_0( pobjPort, pobjDevice, objHex18FJ, pobjSettings.writeProgram, iTabLevel );

                // Unkown version
                } else {
                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Unknown firmware version", iTabLevel) );
                    PortClose( pobjPort );
                    return;
                }

            //--------------------------------------------------------------------------
            // PIC24F
            //--------------------------------------------------------------------------
            } else if ( pobjDevice.family.name == "PIC24F" ) {
                clsHex24F objHex24F = (clsHex24F)pobjHex;

                // Parse
                objHex24F.ParseHexFile( objParseSettings, iTabLevel, ref bParseResult );
                if ( bParseResult == false ) {
                    PortClose( pobjPort );
                    return;
                }

                // Write versions 0.9.0 - 0.9.0
                if (
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 1 )
                ) {
                    bWriteSuccess = WriteFlash24F_0_9_0( pobjPort, pobjDevice, objHex24F, pobjSettings.writeProgram, pobjSettings.writeEEPROM, pobjSettings.writeConfigs, iTabLevel );

                // Unkown version
                } else {
                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Unknown firmware version", iTabLevel) );
                    PortClose( pobjPort );
                    return;
                }

            //--------------------------------------------------------------------------
            // PIC24FJ
            //--------------------------------------------------------------------------
            } else if ( pobjDevice.family.name == "PIC24FJ" ) {
                clsHex24FJ objHex24FJ = (clsHex24FJ)pobjHex;

                // Parse
                objHex24FJ.ParseHexFile( objParseSettings, iTabLevel, ref bParseResult );
                if ( bParseResult == false ) {
                    PortClose( pobjPort );
                    return;
                }

                // Write versions 0.9.0 - 1.0.1
                if (
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 1 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 1 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 2 )
                ) {
                    bWriteSuccess = WriteFlash24FJ_1_0_0( pobjPort, pobjDevice, objHex24FJ, pobjSettings.writeProgram, pobjSettings.writeEEPROM, pobjSettings.writeConfigs, iTabLevel );

                // Unkown version
                } else {
                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Unknown firmware version", iTabLevel) );
                    PortClose( pobjPort );
                    return;
                }

            //--------------------------------------------------------------------------
            // PIC24H
            //--------------------------------------------------------------------------
            } else if ( pobjDevice.family.name == "PIC24H" ) {
                clsHex24H objHex24H = (clsHex24H)pobjHex;

                // Parse
                objHex24H.ParseHexFile( objParseSettings, iTabLevel, ref bParseResult );
                if ( bParseResult == false ) {
                    PortClose( pobjPort );
                    return;
                }

                // Write versions 0.9.0 - 0.9.1
                if (
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 1 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 0 )
                ) {
                    bWriteSuccess = WriteFlash24H_0_9_0( pobjPort, pobjDevice, objHex24H, pobjSettings.writeProgram, pobjSettings.writeConfigs, iTabLevel );

                // Unkown version
                } else {
                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Unknown firmware version", iTabLevel) );
                    PortClose( pobjPort );
                    return;
                }

            //--------------------------------------------------------------------------
            // dsPIC30F
            //--------------------------------------------------------------------------
            } else if ( pobjDevice.family.name == "dsPIC30F" ) {
                clsHex30F objHex30F = (clsHex30F)pobjHex;

                // Parse
                objHex30F.ParseHexFile( objParseSettings, iTabLevel, ref bParseResult );
                if ( bParseResult == false ) {
                    PortClose( pobjPort );
                    return;
                }

                // Write versions 0.9.4 - 1.0.1
                if (
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 4 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 1 )
                ) {
                    bWriteSuccess = WriteFlash30_1_0_1( pobjPort, pobjDevice, objHex30F, pobjSettings.writeProgram, pobjSettings.writeEEPROM, pobjSettings.writeConfigs, iTabLevel );

                // Versions 2.0.0 - 2.0.2
                } else if (
                    ( iFWVerMaj == 2 && iFWVerMin == 0 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 2 && iFWVerMin == 0 && iFWVerRev == 1 ) ||
                    ( iFWVerMaj == 2 && iFWVerMin == 0 && iFWVerRev == 2 )
                ) {
                    bWriteSuccess = WriteFlash30_2_0_0( pobjPort, pobjDevice, objHex30F, pobjSettings.writeProgram, pobjSettings.writeEEPROM, pobjSettings.writeConfigs, iTabLevel );

                // Unkown version
                } else {
                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Unknown firmware version", iTabLevel) );
                    PortClose( pobjPort );
                    return;
                }

            //--------------------------------------------------------------------------
            // dsPIC33F
            //--------------------------------------------------------------------------
            } else if ( pobjDevice.family.name == "dsPIC33FJ" ) {
                clsHex33FJ objHex33F = (clsHex33FJ)pobjHex;

                // Parse
                objHex33F.ParseHexFile( objParseSettings, iTabLevel, ref bParseResult );
                if ( bParseResult == false ) {
                    PortClose( pobjPort );
                    return;
                }

                // Write vrsions 0.9.0 - 1.0.0
                if (
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 1 ) ||
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 2 ) ||
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 3 ) ||
                    ( iFWVerMaj == 0 && iFWVerMin == 9 && iFWVerRev == 4 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 0 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 1 ) ||
                    ( iFWVerMaj == 1 && iFWVerMin == 0 && iFWVerRev == 2 )
                ) {
                    bWriteSuccess = WriteFlash33_1_0_0( pobjPort, pobjDevice, objHex33F, pobjSettings.writeProgram, pobjSettings.writeConfigs, iTabLevel );

                // Unkown version
                } else {
                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Unknown firmware version", iTabLevel) );
                    PortClose( pobjPort );
                    return;
                }
            }

            //--------------------------------------------------------------------------
            // Download completed
            //--------------------------------------------------------------------------
            pobjPort.Close();

            if ( bWriteSuccess == true ) {
                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.completed, "Download finished", iTabLevel) );
            }

            OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.progressEnded, "", 0) );
            pbResult = bWriteSuccess;
        }