예제 #1
0
        }// CompareTo()

        //---------------------------------------------------------------------
        // CopyFrom()
        //---------------------------------------------------------------------
        public void CopyFrom(clsParseSettings pobjSettings)
        {
            bootloaderSizeR  = pobjSettings.bootloaderSizeR;
            device           = pobjSettings.device;
            fileTimestamp    = pobjSettings.fileTimestamp;
            allowBlOverwrite = pobjSettings.allowBlOverwrite;
            noGoto           = pobjSettings.noGoto;
        }// CopyFrom()
예제 #2
0
        }//Property: noGoto


        //---------------------------------------------------------------------
        // CompareTo()
        // Returns: true if equal, false if not equal
        //---------------------------------------------------------------------
        public bool CompareTo(clsParseSettings pobjSettings)
        {
            return(
                bootloaderSizeR == pobjSettings.bootloaderSizeR &&
                device == pobjSettings.device &&
                fileTimestamp == pobjSettings.fileTimestamp &&
                allowBlOverwrite == pobjSettings.allowBlOverwrite &&
                noGoto == pobjSettings.noGoto
                );
        }// CompareTo()
 //---------------------------------------------------------------------
 // Constructor()
 //---------------------------------------------------------------------
 public clsHex( string pstrFilename )
 {
     objParsedSettings = new clsParseSettings();
     strFilename = pstrFilename;
 }
 //---------------------------------------------------------------------
 // Constructor()
 //---------------------------------------------------------------------
 public clsHex()
 {
     objParsedSettings = new clsParseSettings();
 }
 //---------------------------------------------------------------------
 // UpdateParsedSettings()
 //---------------------------------------------------------------------
 protected void UpdateParsedSettings( clsParseSettings pobjSettings )
 {
     bIsParsed = true;
     objParsedSettings.CopyFrom( pobjSettings );
 }
		}//Hex_Validate()	


		//---------------------------------------------------------------------
		// DoParse()
		// Description:
		//---------------------------------------------------------------------
		public void DoParse()
		{	
			int iBootLoaderSizeR = 0;
			clsDevice objDevice = clsDevices.DeviceGet( cboDevice.Text );	
            bool bParseResult = false;

            // Here we only assume a bootloader size to be able to parse the hex-file            
            if ( cboFamily.Text == "PIC18F" ) {
                objHex = new clsHex18F( txtFilename.Text );
                iBootLoaderSizeR = 5 * objDevice.pageSizeR;

             } else if ( cboFamily.Text == "PIC18FJ" ) {
                objHex = new clsHex18FJ( txtFilename.Text );
                iBootLoaderSizeR = 16;
           
            } else if ( cboFamily.Text == "PIC24F" ) {
                objHex = new clsHex24F( txtFilename.Text );
                iBootLoaderSizeR = 4;

            } else if ( cboFamily.Text == "PIC24FJ" ) {
                objHex = new clsHex24FJ( txtFilename.Text );
                iBootLoaderSizeR = 8;
            
            } else if ( cboFamily.Text == "PIC24H" ) {
                objHex = new clsHex24H( txtFilename.Text );
                iBootLoaderSizeR = 8;

            } else if ( cboFamily.Text == "dsPIC30F" ) {				
				objHex = new clsHex30F( txtFilename.Text );
				iBootLoaderSizeR = 4;				
			
            } else if ( cboFamily.Text == "dsPIC33FJ" ) {
				objHex = new clsHex33FJ( txtFilename.Text );				
				iBootLoaderSizeR = 8;
            
            } else {
				return;
			}
	        
            // Check file existence
            if ( File.Exists(txtFilename.Text) == false ) {
                return;
            }

            // Enum events
            objHex.HexFileValidate += new clsHex.HexFileValidateDelegate( Hex_Validate );
            objHex.HexFileParse += new clsHex.HexFileParseDelegate( Hex_Parse );

            // Parse settings
            clsParseSettings objParseSettings = new clsParseSettings(  iBootLoaderSizeR, objDevice, chkAllowBlOverwrite.Checked, chkNoGoto.Checked );

            // Parse
			if ( objDevice != null ) {
				txtInfo.Text = "";
				objHex.ParseHexFile( objParseSettings, 0, ref bParseResult );
				
				if ( objHex.hasValidProgram ) {
					chkWriteProgram.Enabled = true;
				} else {
					chkWriteProgram.Enabled = false;
					chkWriteProgram.Checked = false;
				}
				if ( objHex.hasValidEEPROM ) {
					chkWriteEEPROM.Enabled = true;
				} else {
					chkWriteEEPROM.Enabled = false;
					chkWriteEEPROM.Checked = false;
				}
				
				if ( objHex.hasValidConfigs ) {
					chkWriteConfigs.Enabled = true;
				} else {
					chkWriteConfigs.Enabled = false;
					chkWriteConfigs.Checked = false;
				}										
			}		
		}//DoParse();
        private void UploadNowBtn_Click(object sender, EventArgs e)
        {
            uploadInProgress = true;
            // Verify that a valid file path has been entered. If a path is present in the box it is already validated so
            // there is no need to do any further validation.
            if (HexFilePathTB.Text.Length == 0)
            {
                MessageBox.Show("You must select the path to the desired Hex file in order to perform upload.", "File Path Error");
                return;
            }

            // Perform the upload...
            bool uploadSuccess = false;
            try
            {
                this.Cursor = Cursors.WaitCursor;

                // Initialize ds30 Loader engine
                {
                    string strBasePath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
                    bool bds30LoaderInitializeResult = false;

                    clsds30Loader.Initialize(strBasePath, ref bds30LoaderInitializeResult);

                    if (bds30LoaderInitializeResult == false)
                    {
                        MessageBox.Show("Failed to initialize ds30 Loader.", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        this.Cursor = Cursors.Default;
                        return;
                    }
                }
                // Get device object
                clsDevice objDevice = clsDeviceDb.DeviceGet("PIC24HJ128GP204");

                if (objDevice == null)
                {
                    MessageBox.Show("Unknown device, write aborted.", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    this.Cursor = Cursors.Default;
                    return;
                }
                // Parse hex file
                //clsHex18F objHex = new clsHex18F( "serlcd.hex" );

                clsHex objHex = (fileIsAutoDownloaded) ? new clsHex(hexFileDestPath) : new clsHex(HexFilePathTB.Text);
                {
                    bool bParseResult = false;
                    clsParseSettings objParseSettings = new clsParseSettings();

                    objHex.HexFileValidate += new clsHex.HexFileValidateDelegate(objHex_HexFileValidate);
                    objHex.HexFileParse += new clsHex.HexFileParseDelegate(objHex_HexFileParse);

                    objParseSettings.device = objDevice;
                    objHex.ParseHexFile(objParseSettings, false, 0, ref bParseResult);

                    if (bParseResult == false)
                    {
                        MessageBox.Show("Parse of hex file failed, write process aborted.", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        this.Cursor = Cursors.Default;
                        return;
                    }
                }
                // Download
                {
                    bool bDownloadResult = false;
                    myFocuser.Action("ForceHubDisconnect", "");
                    clsWriteSettings objDownloadSettings = new clsWriteSettings();
                    objDownloadSettings.portName = myFocuser.Action("GetCOMPortName", "");
                    objDownloadSettings.writeProgram = true;
                    objDownloadSettings.baudRate = 115200;
                    switch (TimeoutCB.Text)
                    {
                        default:
                        case "10 Sec":
                            objDownloadSettings.timeout = 10000;
                            break;
                        case "30 Sec":
                            objDownloadSettings.timeout = 30000;
                            break;
                        case "60 Sec":
                            objDownloadSettings.timeout = 60000;
                            break;
                    }
                    MessageBox.Show("Press 'OK' and then cycle the power to the FocusLynx device before the timeout period expires.",
                        "Bootloader", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    txtInfo.Text += "Waiting for device power cycle..." + Environment.NewLine;

                    //************************************************************************************************************************
                    // Before we start the write we have to make sure any garbage that is output form the device at power up is discarded first
                    //
                    using (SerialPort tempPort = new SerialPort(objDownloadSettings.portName, objDownloadSettings.baudRate))   // use same settigs as bootloader
                    {
                        tempPort.Open();
                        tempPort.DiscardInBuffer();
                        tempPort.DiscardOutBuffer();
                        string junk = tempPort.ReadExisting();
                        DateTime startTime = DateTime.UtcNow;
                        while (DateTime.UtcNow.Subtract(startTime).TotalMilliseconds < (objDownloadSettings.timeout - 2000))
                        {
                            if (tempPort.BytesToRead > 0)
                            {
                                System.Threading.Thread.Sleep(1000);     // Pause while the serial transciever powers up...
                                break;
                            }
                        }
                        EventLogger.LogMessage("Bootloader discarding " + tempPort.BytesToRead + " bytes of junk before bootload", TraceLevel.Info);
                        junk = tempPort.ReadExisting();
                        tempPort.DiscardInBuffer();
                        tempPort.Close();
                    }
                    //*************************************************************************************************************************

                    // Now it is okay to start the download
                    clsds30Loader.Write(objDevice, objHex, objDownloadSettings, 0, ref bDownloadResult);

                    if (bDownloadResult == false)
                    {
                        MessageBox.Show("Write failed", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        this.Cursor = Cursors.Default;
                        uploadSuccess = false;
                        return;
                    }
                    else
                    {
                        uploadSuccess = true;

                        // Delete the autodownloaded file
                        if (fileIsAutoDownloaded)
                        {
                            try
                            {
                                File.Delete(hexFileDestPath);
                                txtInfo.Text += "Temporary hex file removed" + Environment.NewLine;
                            }
                            catch
                            {
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occurred during firmware upload. " + ex.Message, "Error");
            }
            finally
            {
                uploadInProgress = false;
                this.Cursor = Cursors.Default;
            }
            if (uploadSuccess)
            {
                MessageBox.Show("The device firmware has been successfully upgraded!", "Upload Complete");
                // Close the form.
                //this.Close();
            }
            else
            {
                // Leave the form open incase they want to attempt the upload again.
            }
        }
예제 #8
0
 //---------------------------------------------------------------------
 // Constructor()
 //---------------------------------------------------------------------
 public clsHex()
 {
     objParsedSettings = new clsParseSettings();
 }        // Constructor()
예제 #9
0
        }//Property: NeedsParsing()

        //---------------------------------------------------------------------
        // UpdateParsedSettings()
        //---------------------------------------------------------------------
        protected void UpdateParsedSettings(clsParseSettings pobjSettings)
        {
            bIsParsed = true;
            objParsedSettings.CopyFrom(pobjSettings);
        }// UpdateParsedSettings()
        }//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()
        //---------------------------------------------------------------------
		// Constructor()
		//---------------------------------------------------------------------
		public clsHex()
		{
            objParsedSettings = new clsParseSettings();
		}// Constructor()
        //---------------------------------------------------------------------
        // 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;
        }
        }// CompareTo()


	    //---------------------------------------------------------------------
		// CopyFrom()
		//---------------------------------------------------------------------
		public void CopyFrom( clsParseSettings pobjSettings )
		{
            bootloaderSizeR = pobjSettings.bootloaderSizeR;
            device = pobjSettings.device;
            fileTimestamp = pobjSettings.fileTimestamp;
            allowBlOverwrite = pobjSettings.allowBlOverwrite;
            noGoto = pobjSettings.noGoto;
        }// CopyFrom()
        }//Property: noGoto   

        
	    //---------------------------------------------------------------------
		// CompareTo()
        // Returns: true if equal, false if not equal
		//---------------------------------------------------------------------
		public bool CompareTo( clsParseSettings pobjSettings )
		{
            return (
                bootloaderSizeR == pobjSettings.bootloaderSizeR &&
                device == pobjSettings.device &&
                fileTimestamp == pobjSettings.fileTimestamp &&
                allowBlOverwrite == pobjSettings.allowBlOverwrite &&
                noGoto == pobjSettings.noGoto
            );
        }// CompareTo()
        //---------------------------------------------------------------------
        // ParseHexFile()
        //---------------------------------------------------------------------
        public override void ParseHexFile( clsParseSettings pobjSettings, int iTabLevel, ref bool pbResult )
        {
            string strFileLine;
            int[] iInData = new int[ 256 ];
            string strLineData;
            int iLineByteCount;
            int iLineAddr;
            int iLineCode;
            int iOutAddr;
            int iLineAddrHigh = 0;
            TextReader textReader;
            int iIter;
            int iAddress;
            int iWordCount;

            //---------------------------------------------------------------------
            // Allready parsed?
            //---------------------------------------------------------------------
            pobjSettings.fileTimestamp = File.GetLastWriteTime( filename );
            if ( NeedsParsing(pobjSettings) == false ) {
                pbResult = true;
                return;
            }

            //
            OnHexFileParse( new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.started, "Parsing hexfile...", iTabLevel++) );

            //
            bIsParsed = false;
            bHasValidProgram = true;
            bHasValidEEPROM = false;
            bHasValidConfigs = true;

            //---------------------------------------------------------------------
            // Validate hex-file
            //---------------------------------------------------------------------
            bool bValidateResult = false;
            ValidateHexFile( iTabLevel, ref bValidateResult );
            if ( bValidateResult == false ) {
                OnHexFileParse( new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.failed, "Parsing of hex-file failed", iTabLevel++) );
                pbResult = false;
                return;
            }

            //--------------------------------------------------------------------------
            // Open hex-file
            //--------------------------------------------------------------------------
            textReader = new StreamReader( strFilename );

            //--------------------------------------------------------------------------
            // Initialize arrays to default values
            //--------------------------------------------------------------------------
            for ( iIter = 0; iIter < iProgPageUsedBufferSize; iIter++ ) bProgPageUsed[ iIter ] = false;
            for ( iIter = 0; iIter < iProgRowUsedBufferSize; iIter++ ) bProgRowUsed[ iIter ] = false;
            for ( iIter = 0; iIter < iProgMemBufferSize; iIter++ ) iProgMem[ iIter ] = 0xFF;

            for ( iIter = 0; iIter < iConfigWordsUsedBufferSize; iIter++ ) bConfigWordUsed[iIter] = false;
            for ( iIter = 0; iIter < iConfigMemBufferSize; iIter++ ) iConfigMem[iIter] = 255;

            //--------------------------------------------------------------------------
            // do actual parsing
            //
            // Hex-file format
            //
            // : 10 8000 00 0800 fa00 000f 8001
            // | |  |    |  |-Data
            // | |  |    |----Line code
            // | |  |---------Line address
            // | |------------Line data count
            // |--------------Just a simple colon
            //
            //--------------------------------------------------------------------------
            while ( textReader.Peek() != -1 ) {
                strFileLine = textReader.ReadLine();

                //Init the array with 0xFF
                for ( iIter = 0; iIter < 256; iIter++ ) {
                    iInData[ iIter ] = 255;
                }

                iLineCode = 0;
                if ( strFileLine.Substring( 0, 1 ) == ":" ) {
                    //Parse the line
                    iLineByteCount = int.Parse( strFileLine.Substring( 1, 2 ), System.Globalization.NumberStyles.HexNumber );
                    iLineAddr = ( int.Parse( strFileLine.Substring( 3, 4 ), System.Globalization.NumberStyles.HexNumber ) & 65535 );
                    iLineCode = int.Parse( strFileLine.Substring( 7, 2 ), System.Globalization.NumberStyles.HexNumber );
                    strLineData = strFileLine.Substring( 9, ( iLineByteCount * 2 ) );

                    iAddress = ( (iLineAddrHigh << 16) + iLineAddr ) / 2;

                    // Data record
                    if ( iLineCode == 0 ) {
                        iWordCount = iLineByteCount / 4;

                        // Regular program memory
                        if ( iAddress <= 0x02AC00 ) {
                            iOutAddr = (iAddress * 3) / 2;

                            for ( int iWord = 0; iWord < iWordCount; iWord++ ) {
                                //upper-low-high
                                iProgMem[iOutAddr + iWord*3 + 0] = int.Parse( strLineData.Substring(iWord*8 + 4, 2), System.Globalization.NumberStyles.HexNumber );
                                iProgMem[iOutAddr + iWord*3 + 1] = int.Parse( strLineData.Substring(iWord*8 + 0, 2), System.Globalization.NumberStyles.HexNumber );
                                iProgMem[iOutAddr + iWord*3 + 2] = int.Parse( strLineData.Substring(iWord*8 + 2, 2), System.Globalization.NumberStyles.HexNumber );
                                ++iProgWordsUsed;
                                bProgPageUsed[ (iAddress/2 + iWord) / ( pobjSettings.device.pageSizeR * pobjSettings.device.rowsizeW)  ] = true;
                                bProgRowUsed[ (iAddress/2 + iWord) / pobjSettings.device.rowsizeW  ] = true;
                            }

                        // Config memory
                        } else if ( iAddress >= 0xF80000 && iAddress <= 0xF8000E) {
                            iOutAddr = iAddress - 0xF80000;

                            for ( int iWord = 0; iWord < iWordCount; iWord++ ) {
                                iConfigMem[iOutAddr + iWord*2 + 0] = int.Parse( strLineData.Substring(iWord*8 + 0, 2), System.Globalization.NumberStyles.HexNumber );
                                iConfigMem[iOutAddr + iWord*2 + 1] = int.Parse( strLineData.Substring(iWord*8 + 2, 2), System.Globalization.NumberStyles.HexNumber );

                                bConfigWordUsed[iOutAddr/2 + iWord] = true;
                            }
                        }

                    // End Of File record
                    } else if ( iLineCode == 1 ) {
                        break;

                    // Extended Linear Address Record
                    // The two data bytes represent the upper 16 bits of the 32 bit address, when combined with the address of the 00 type record.
                    } else if ( iLineCode == 4 ) {
                        iLineAddrHigh = ( int.Parse( strFileLine.Substring( 9, 4 ), System.Globalization.NumberStyles.HexNumber ) & 65535 );
                    }
                }
            }

            //--------------------------------------------------------------------------
            // Close files
            //--------------------------------------------------------------------------
            textReader.Close();

            //--------------------------------------------------------------------------
            // Calculate adresses
            //--------------------------------------------------------------------------
            int iBootloaderStartRow = (pobjSettings.device.flashSizeP / 2 - pobjSettings.device.pageSizeR * pobjSettings.device.rowsizeW) / pobjSettings.device.rowsizeW;
            int iBootloaderEndRow = iBootloaderStartRow + pobjSettings.bootloaderSizeR - 1;
            int iBootloaderStartAdress = pobjSettings.device.flashSizeP - pobjSettings.device.pageSizeR * pobjSettings.device.rowsizeW * 2;   //bootloader is placed in 2nd last page

            int iBootloaderStartAdressB3 = (iBootloaderStartAdress / 2) * 3;	//starting index in buffer
            int iUserAppGotoAdressB3 = iBootloaderStartAdressB3 - 6;			//starting index in buffer

            //--------------------------------------------------------------------------
            // Check for code that would overwrite the bootloader
            //--------------------------------------------------------------------------
            bool bOk = true;

            for ( iIter = iBootloaderStartRow; iIter <= iBootloaderEndRow; iIter++ ) {
                if ( bProgRowUsed[ iIter ] == true ) {
                    bOk = false;
                    break;
                }
            }
            if ( bOk == false ) {
                OnHexFileParse( new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.warning, "The hex-file contains code that will overwrite the bootloader", iTabLevel) );
                if ( pobjSettings.allowBlOverwrite == false ) {
                    bHasValidProgram = false;
                }
            }

            //--------------------------------------------------------------------------
            // Check for GOTO at 0x00
            //--------------------------------------------------------------------------
            if ( pobjSettings.noGoto == false ) {
                bOk = false;
                for ( iIter = 0; iIter < 6; iIter++ ) {
                    if ( iProgMem[ iIter ] != 255 ) {
                        bOk = true;
                        break;
                    }
                }
                if ( bOk == false || bProgRowUsed[0] == false ) {
                    OnHexFileParse( new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.warning, "There's no GOTO at location 0x00", iTabLevel) );
                    bHasValidProgram = false;
                }

                //--------------------------------------------------------------------------
                // Swap user goto at 0x00 to bootloader usr:, se firmware code
                // It´s important that this instruction is placed just before a new program row
                //--------------------------------------------------------------------------
                for ( iIter = 0; iIter < 6; iIter++ ) {
                    iProgMem[iUserAppGotoAdressB3 + iIter] = iProgMem[iIter];
                }
                bProgPageUsed[iUserAppGotoAdressB3 / (pobjSettings.device.pageSizeR * pobjSettings.device.rowsizeW * 3)] = true;
                bProgRowUsed[iUserAppGotoAdressB3 / (pobjSettings.device.rowsizeW * 3)] = true;
            }

            //--------------------------------------------------------------------------
            // Find out how many pages are used
            //--------------------------------------------------------------------------
            iProgPagesUsed = 0;
            for ( iIter = 0; iIter < iProgPageUsedBufferSize; iIter++ ) {
                if ( bProgPageUsed[ iIter ] == true ) {
                    ++iProgPagesUsed;
                    if ( clsds30Loader.debugMode ) {
                        OnHexFileParse( new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.info, "program page " + iIter.ToString() + " is used", iTabLevel) );
                    }
                }
            }

            //--------------------------------------------------------------------------
            // Find out how many program rows are used
            //--------------------------------------------------------------------------
            iProgRowsUsed = 0;
            for ( iIter = 0; iIter < iProgRowUsedBufferSize; iIter++ ) {
                if ( bProgRowUsed[ iIter ] == true ) {
                    ++iProgRowsUsed;
                    if ( clsds30Loader.debugMode ) {
                        OnHexFileParse( new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.info, "program row " + iIter.ToString() + " is used", iTabLevel) );
                    }
                }
            }
            if ( iProgRowsUsed == 0 ) {
                bHasValidProgram = false;
            }

            //--------------------------------------------------------------------------
            // Find out how many configurations are used
            //--------------------------------------------------------------------------
            iConfigWordsUsed = 0;
            for ( iIter = 0; iIter < iConfigWordsUsedBufferSize; iIter++ ) {
                if ( bConfigWordUsed[iIter] == true ) {
                    ++iConfigWordsUsed;
                }
            }
            if ( iConfigWordsUsed > pobjSettings.device.configCount ) {
                OnHexFileParse( new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.warning, "hex-file contains more config locations than the device has", iTabLevel) );
                bHasValidConfigs = false;
            } else if ( iConfigWordsUsed == 0 ) {
                bHasValidConfigs = false;
            }

            //--------------------------------------------------------------------------
            // Set GOTO to bootloader at 0x0000
            //--------------------------------------------------------------------------
            if ( pobjSettings.noGoto == false ) {
                // First goto word
                iProgMem[0] = 0x04;												//goto instruction
                iProgMem[1] = ((iBootloaderStartAdress & 0x0000FE));			//low adress byte
                iProgMem[2] = ((iBootloaderStartAdress & 0x00FF00) >> 8);		//high adress byte
                // Second goto word
                iProgMem[3] = 0x00;												//not used by goto
                iProgMem[4] = ((iBootloaderStartAdress & 0x7F0000) >> 16);	    //upper adress byte
                iProgMem[5] = 0x00;												//not used by goto
            }

            //--------------------------------------------------------------------------
            // Return
            //--------------------------------------------------------------------------
            OnHexFileParse( new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.success, "Hex-file successfully parsed", iTabLevel) );

            bIsParsed = true;

            pbResult = true;
        }
        }// DoMagic()


		//---------------------------------------------------------------------
		// DoParse()
		// Description:
		//---------------------------------------------------------------------
		private void DoParse( clsParseSettings pobjParseSettings, clsDownloadSettings pobjDownloadSettings )
		{	
			int iBootLoaderSizeR = 0;
            bool bParseResult = false;

            // Here we only assume a bootloader size to be able to parse the hex-file            
            if ( objDevice.family.name == "PIC18F" ) {
                objHex = new clsHex18F( strFile );
                iBootLoaderSizeR = 5 * objDevice.pageSizeR;

             } else if ( objDevice.family.name == "PIC18FJ" ) {
                objHex = new clsHex18FJ( strFile );
                iBootLoaderSizeR = 16;
           
            } else if ( objDevice.family.name == "PIC24F" ) {
                objHex = new clsHex24F( strFile );
                iBootLoaderSizeR = 4;

            } else if ( objDevice.family.name == "PIC24FJ" ) {
                objHex = new clsHex24FJ( strFile );
                iBootLoaderSizeR = 8;
            
            } else if ( objDevice.family.name == "PIC24H" ) {
                objHex = new clsHex24H( strFile );
                iBootLoaderSizeR = 8;

            } else if ( objDevice.family.name == "dsPIC30F" ) {				
				objHex = new clsHex30F( strFile );
				iBootLoaderSizeR = 4;				
			
            } else if ( objDevice.family.name == "dsPIC33FJ" ) {
				objHex = new clsHex33FJ( strFile );				
				iBootLoaderSizeR = 8;
            
            } else {
				return;
			}
	        
            // Check file existence
            if ( File.Exists(strFile) == false ) {
                return;
            }

            // Enum events
            objHex.HexFileValidate += new clsHex.HexFileValidateDelegate( Hex_Validate );
            objHex.HexFileParse += new clsHex.HexFileParseDelegate( Hex_Parse );

            // Parse
			if ( objDevice != null ) {
				objHex.ParseHexFile( pobjParseSettings, 0, ref bParseResult );
				
				pobjDownloadSettings.writeProgram &= objHex.hasValidProgram;
                pobjDownloadSettings.writeEEPROM &= objHex.hasValidEEPROM;
                pobjDownloadSettings.writeConfigs &= objHex.hasValidConfigs;
			}		
		}//DoParse();
예제 #17
0
        }        // BytesToWrite()

        //---------------------------------------------------------------------
        // NeedsParsing()
        //---------------------------------------------------------------------
        protected bool NeedsParsing(clsParseSettings pobjSettings)
        {
            return(pobjSettings.CompareTo(objParsedSettings) == false || isParsed == false);
        }//Property: NeedsParsing()
        }// PrintHelp()


        //-------------------------------------------------------------------------
        // ValidateParseArgs()
        //-------------------------------------------------------------------------
        private void ValidateParseArgs( string[] pstrArgs, clsParseSettings pobjParseSettings, clsDownloadSettings pobjDownloadSettings, ref bool pbResult ) 
        {
            pbResult = false;

            //
            string [] strSplitArgs;
            string strOption;
            string strOptionValue;
            string strArgument;

            //
            bool bFileSpecified = false;
            bool bPortSpecified = false;
            bool bBaudrateSpecified = false;
            bool bDeviceSpecified = false;


            foreach ( string strArg in pstrArgs ) {
                //
                strArgument = strArg;
                if ( strArg.EndsWith("=") ) {
                    strArgument += "0";
                }
                strSplitArgs = strArgument.Split('=');
                
                // Argument                
                strOption = strSplitArgs[0].ToLower();
                
                // Argument value
                if ( strSplitArgs.Length == 2 ) {
                    strOptionValue = strSplitArgs[1];
                } else if (strSplitArgs.Length == 1 ) {
                    strOptionValue = "";
                } else {
                    Console.WriteLine( "Invalid argument: " + strArg );
                    return;
                }

                switch ( strOption ) {
                    //---------------------------------------------------------
                    // Misc
                    //---------------------------------------------------------

                    // Help
                    case "-h":
                    case "--help":
                        PrintHelp();
                        return;

                    // Debugmode
                    case "-l":
                    case "--debugmode":
                        clsds30Loader.debugMode = true;
                        return;

                    // Non-interactive
                    case "-o":
                    case "--non-interactive":
                        bNonInteractive = true;
                        return;

                    
                    //---------------------------------------------------------
                    // Basic
                    //---------------------------------------------------------

                    // Devicename
                    case "-d":
                    case "--device":
                        objDevice = clsDevices.DeviceGet( strOptionValue );
                        if ( objDevice == null ) {
                            Console.WriteLine( "Unknown device specified." );
                            return;
                        }
                        bDeviceSpecified = true;
                        break;

                    // Hex-file
                    case "-f":
                    case "--file":
                        strFile = strOptionValue;    
                        if ( File.Exists(strFile) == false ) {
                            Console.WriteLine( "Non-existing file specified." );
                            return;
                        }
                        bFileSpecified = true;
                        
                        break;                        

                    // Portname
                    case "-k":
                    case "--port":
                        strPort = strOptionValue;
                        bPortSpecified = true;
                        break; 
                    
                    // Baudrate
                    case "-r":
                    case "--baudrate":
                        try {
                            iBaudrate = int.Parse( strOptionValue );
                        } catch {
                            Console.WriteLine( "Invalid baudrate specified." );
                            return;
                        }
                        if ( iBaudrate <= 0 ) {
                            Console.WriteLine( "Invalid baudrate specified." );
                            return;
                        }
                        bBaudrateSpecified = true;
                        break;
                    
                    // Write program
                    case "-p":
                    case "--write-program":
                        pobjDownloadSettings.writeProgram = true;
                        break;
                    
                    // Write eeprom
                    case "-e":
                    case "--write-eeprom":
                        pobjDownloadSettings.writeEEPROM = true;
                        break;                    
                    

                    //---------------------------------------------------------
                    // Advanced
                    //---------------------------------------------------------

                    // Write configs
                    case "-c":
                    case "--write-configs":
                        pobjDownloadSettings.writeConfigs = true;
                        break;
                    
                    // Don't write goto
                    case "-g":
                    case "--no-goto":
                        pobjParseSettings.noGoto = true;
                        pobjDownloadSettings.noGoto = true;
                        break;
                     
                    // Allow overwrite of bootloader
                    case "-s":
                    case "--allow-bl-overwrite":
                        pobjParseSettings.allowBlOverwrite = true;
                        pobjDownloadSettings.allowBlOverwrite = true;
                        break;
                   

                    //---------------------------------------------------------
                    // Timing
                    //---------------------------------------------------------

                    // Polltime
                    case "-a":
                    case "--polltime":
                        int iPolltime;
                        try {
                            iPolltime = int.Parse( strOptionValue );
                        } catch {
                            Console.WriteLine( "Invalid polltime specified." );
                            return;
                        }
                        if ( iPolltime <= 0 ) {
                            Console.WriteLine( "Invalid polltime specified." );
                            return;
                        }
                        pobjDownloadSettings.polltime = iPolltime;
                        break;
                    
                    // Timeout
                    case "-t":
                    case "--timeout":
                        int iTimeout;
                        try {
                            iTimeout = int.Parse( strOptionValue );
                        } catch {
                            Console.WriteLine( "Invalid timeout specified." );
                            return;
                        }
                        if ( iTimeout <= 0 ) {
                            Console.WriteLine( "Invalid timeout specified." );
                            return;
                        }
                        pobjDownloadSettings.timeout = iTimeout;
                        break;


                    //---------------------------------------------------------
                    // Reset
                    //---------------------------------------------------------

                    // Reset by command
                    case "-q":
                    case "--reset-command":
                        pobjDownloadSettings.resetCommand = true;
                        pobjDownloadSettings.resetCommandSequence = strOptionValue;
                        break;

                     // Reset baudrate
                    case "-u":
                    case "--reset-baudrate":
                        int iResetBaudrate;
                        try {
                            iResetBaudrate = int.Parse( strOptionValue );
                        } catch {
                            Console.WriteLine( "Invalid reset baudrate specified." );
                            return;
                        }
                        if ( iResetBaudrate <= 0 ) {
                            Console.WriteLine( "Invalid reset baudrate specified." );
                            return;
                        }
                        pobjDownloadSettings.resetBaudrate = iResetBaudrate;
                        break;
                   
                    // Reset by dtr
                    case "-m":
                    case "--reset-dtr":
                        pobjDownloadSettings.resetDtr = true;
                        break;

                    // Reset by rts
                    case "-n":
                    case "--reset-rts":
                        pobjDownloadSettings.resetRts = true;
                        break;
                    
                    // Resettime
                    case "-b":
                    case "--resettime":
                        int iResettime;
                        try {
                            iResettime = int.Parse( strOptionValue );
                        } catch {
                            Console.WriteLine( "Invalid resettime specified." );
                            return;
                        }
                        if ( iResettime <= 0 ) {
                            Console.WriteLine( "Invalid resettime specified." );
                            return;
                        }
                        pobjDownloadSettings.resetTime = iResettime;
                        break;


                    //---------------------------------------------------------
                    // Activation
                    //---------------------------------------------------------

                    // Activate by dtr
                    case "-i":
                    case "--activate-dtr":
                        pobjDownloadSettings.activateDTR = true;
                        break;

                    // Activate by rts
                    case "-j":
                    case "--activate-rts":
                        pobjDownloadSettings.activateRTS = true;
                        break;


                    //---------------------------------------------------------
                    // Unknown option
                    //---------------------------------------------------------
                    default:
                        Console.WriteLine( "Unknown option \"" + strArg + "\"" );
                        Console.WriteLine( "" );
                        return;

                }
            }

            if ( bFileSpecified == false ) {
                Console.WriteLine( "File not specified" );
                return;
            }
            if ( bPortSpecified == false ) {
                Console.WriteLine( "Port not specified" );
                return;
            }
            if ( bBaudrateSpecified == false ) {
                Console.WriteLine( "Baudrate not specified" );
                return;
            }
            if ( bDeviceSpecified == false ) {
                Console.WriteLine( "Device not specified" );
                return;
            }

            pbResult = true;
        }// ValidateParseArgs()
예제 #19
0
        }// UpdateParsedSettings()

        //---------------------------------------------------------------------
        // ParseHexFile()
        //---------------------------------------------------------------------
        virtual public void ParseHexFile(clsParseSettings pobjSettings, int iTabLevel, ref bool pbResult)
        {
            pbResult = false;
            return;
        }        // ParseHexFile()
 //---------------------------------------------------------------------
 // ParseHexFile()
 //---------------------------------------------------------------------
 public virtual void ParseHexFile( clsParseSettings pobjSettings, int iTabLevel, ref bool pbResult )
 {
     pbResult = false;
     return;
 }
예제 #21
0
        }        // Constructor()

        //---------------------------------------------------------------------
        // Constructor()
        //---------------------------------------------------------------------
        public clsHex(string pstrFilename)
        {
            objParsedSettings = new clsParseSettings();
            strFilename       = pstrFilename;
        }        // Constructor()
 //---------------------------------------------------------------------
 // NeedsParsing()
 //---------------------------------------------------------------------
 protected bool NeedsParsing( clsParseSettings pobjSettings )
 {
     return ( pobjSettings.CompareTo(objParsedSettings) == false || isParsed == false );
 }
예제 #23
0
        }        // BytesToWrite()

        //---------------------------------------------------------------------
        // ParseHexFile()
        //---------------------------------------------------------------------
        override public void ParseHexFile(clsParseSettings pobjSettings, int iTabLevel, ref bool pbResult)
        {
            string strFileLine;

            int[]      iInData = new int[256];
            string     strLineData;
            int        iLineByteCount;
            int        iLineAddr;
            int        iLineCode;
            int        iOutAddr;
            int        iLineAddrHigh = 0;
            TextReader textReader;
            int        iIter;
            int        iAddress;
            int        iWordCount;


            //---------------------------------------------------------------------
            // Allready parsed?
            //---------------------------------------------------------------------
            pobjSettings.fileTimestamp = File.GetLastWriteTime(filename);
            if (NeedsParsing(pobjSettings) == false)
            {
                pbResult = true;
                return;
            }


            //
            OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.started, "Parsing hexfile...", iTabLevel++));

            //
            bIsParsed        = false;
            bHasValidProgram = true;
            bHasValidEEPROM  = false;
            bHasValidConfigs = false;


            //---------------------------------------------------------------------
            // Validate hex-file
            //---------------------------------------------------------------------
            bool bValidateResult = false;

            ValidateHexFile(iTabLevel, ref bValidateResult);
            if (bValidateResult == false)
            {
                OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.failed, "Parsing of hex-file failed", iTabLevel++));
                pbResult = false;
                return;
            }


            //--------------------------------------------------------------------------
            // Open hex-file
            //--------------------------------------------------------------------------
            textReader = new StreamReader(strFilename);


            //--------------------------------------------------------------------------
            // Initialize arrays to default values
            //--------------------------------------------------------------------------
            for (iIter = 0; iIter < iProgPageUsedBufferSize; iIter++)
            {
                bProgPageUsed[iIter] = false;
            }
            for (iIter = 0; iIter < iProgRowUsedBufferSize; iIter++)
            {
                bProgRowUsed[iIter] = false;
            }
            for (iIter = 0; iIter < iProgMemBufferSize; iIter++)
            {
                iProgMem[iIter] = 0xFF;
            }


            //--------------------------------------------------------------------------
            // do actual parsing
            //
            // Hex-file format
            //
            // : 10 8000 00 0800 fa00 000f 8001
            // | |  |    |  |-Data
            // | |  |    |----Line code
            // | |  |---------Line address
            // | |------------Line data count
            // |--------------Just a simple colon
            //
            //--------------------------------------------------------------------------
            while (textReader.Peek() != -1)
            {
                strFileLine = textReader.ReadLine();

                //Init the array with 0xFF
                for (iIter = 0; iIter < 256; iIter++)
                {
                    iInData[iIter] = 255;
                }

                iLineCode = 0;
                if (strFileLine.Substring(0, 1) == ":")
                {
                    //Parse the line
                    iLineByteCount = int.Parse(strFileLine.Substring(1, 2), System.Globalization.NumberStyles.HexNumber);
                    iLineAddr      = (int.Parse(strFileLine.Substring(3, 4), System.Globalization.NumberStyles.HexNumber) & 65535);
                    iLineCode      = int.Parse(strFileLine.Substring(7, 2), System.Globalization.NumberStyles.HexNumber);
                    strLineData    = strFileLine.Substring(9, (iLineByteCount * 2));

                    iAddress = (iLineAddrHigh << 16) + iLineAddr;

                    // Data record
                    if (iLineCode == 0)
                    {
                        // Regular program memory
                        if (iAddress <= pobjSettings.device.flashSizeP)
                        {
                            iWordCount = iLineByteCount / 2;
                            iOutAddr   = iAddress;

                            for (int iWord = 0; iWord < iWordCount; iWord++)
                            {
                                iProgMem[iOutAddr + iWord * 2 + 0] = int.Parse(strLineData.Substring(iWord * 4 + 0, 2), System.Globalization.NumberStyles.HexNumber);
                                iProgMem[iOutAddr + iWord * 2 + 1] = int.Parse(strLineData.Substring(iWord * 4 + 2, 2), System.Globalization.NumberStyles.HexNumber);
                                ++iProgWordsUsed;
                                bProgPageUsed[(iAddress / 2 + iWord) / (pobjSettings.device.pageSizeR * pobjSettings.device.rowsizeW)] = true;
                                bProgRowUsed[(iAddress / 2 + iWord) / pobjSettings.device.rowsizeW] = true;
                            }
                        }

                        // End Of File record
                    }
                    else if (iLineCode == 1)
                    {
                        break;

                        // Extended Linear Address Record
                        // The two data bytes represent the upper 16 bits of the 32 bit address, when combined with the address of the 00 type record.
                    }
                    else if (iLineCode == 4)
                    {
                        iLineAddrHigh = (int.Parse(strFileLine.Substring(9, 4), System.Globalization.NumberStyles.HexNumber) & 65535);
                    }
                }
            }


            //--------------------------------------------------------------------------
            // Close files
            //--------------------------------------------------------------------------
            textReader.Close();


            //--------------------------------------------------------------------------
            // Calculate addresses
            //--------------------------------------------------------------------------
            int iBootloaderStartAdress = pobjSettings.device.flashSizeP - 2 * pobjSettings.bootloaderSizeR * pobjSettings.device.rowsizeW * 2;  //bootloader is placed in 2nd last page
            int iBootloaderStartRow    = iBootloaderStartAdress / 2 / pobjSettings.device.rowsizeW;
            int iBootloaderEndRow      = iBootloaderStartRow + pobjSettings.bootloaderSizeR - 1;

            int iUserAppGotoAdress = iBootloaderStartAdress - 4;            //buffer index


            //--------------------------------------------------------------------------
            // Check for code that would overwrite the bootloader
            //--------------------------------------------------------------------------
            bool bOk = true;

            for (iIter = iBootloaderStartRow; iIter <= iBootloaderEndRow; iIter++)
            {
                if (bProgRowUsed[iIter] == true)
                {
                    bOk = false;
                    break;
                }
            }
            if (bOk == false)
            {
                OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.warning, "The hex-file contains code that will overwrite the bootloader", iTabLevel));
                if (pobjSettings.allowBlOverwrite == false)
                {
                    bHasValidProgram = false;
                }
            }


            //--------------------------------------------------------------------------
            // Check for GOTO at 0x00
            //--------------------------------------------------------------------------
            if (pobjSettings.noGoto == false)
            {
                bOk = false;
                for (iIter = 0; iIter < 4; iIter++)
                {
                    if (iProgMem[iIter] != 255)
                    {
                        bOk = true;
                        break;
                    }
                }
                if (bOk == false || bProgRowUsed[0] == false)
                {
                    OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.warning, "There's no GOTO at location 0x00", iTabLevel));
                    bHasValidProgram = false;
                }

                //--------------------------------------------------------------------------
                // Swap user goto at 0x00 to bootloader usr:, se firmware code
                // It´s important that this instruction is placed just before a new program row
                //--------------------------------------------------------------------------
                for (iIter = 0; iIter < 4; iIter++)
                {
                    iProgMem[iUserAppGotoAdress + iIter] = iProgMem[iIter];
                }
                bProgPageUsed[iUserAppGotoAdress / (pobjSettings.device.pageSizeR * pobjSettings.device.rowsizeW * 2)] = true;
                bProgRowUsed[iUserAppGotoAdress / (pobjSettings.device.rowsizeW * 2)] = true;
            }


            //--------------------------------------------------------------------------
            // Find out how many pages are used
            //--------------------------------------------------------------------------
            iProgPagesUsed = 0;
            for (iIter = 0; iIter < iProgPageUsedBufferSize; iIter++)
            {
                if (bProgPageUsed[iIter] == true)
                {
                    ++iProgPagesUsed;
                    if (clsds30Loader.debugMode)
                    {
                        OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.info, "program page " + iIter.ToString() + " is used", iTabLevel));
                    }
                }
            }


            //--------------------------------------------------------------------------
            // Find out how many program rows are used
            //--------------------------------------------------------------------------
            iProgRowsUsed = 0;
            for (iIter = 0; iIter < iProgRowUsedBufferSize; iIter++)
            {
                if (bProgRowUsed[iIter] == true)
                {
                    ++iProgRowsUsed;
                    if (clsds30Loader.debugMode)
                    {
                        OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.info, "program row " + iIter.ToString() + " is used", iTabLevel));
                    }
                }
            }
            if (iProgRowsUsed == 0)
            {
                bHasValidProgram = false;
            }


            //--------------------------------------------------------------------------
            // Set GOTO to bootloader at 0x0000
            //--------------------------------------------------------------------------
            if (pobjSettings.noGoto == false)
            {
                iBootloaderStartAdress /= 2;
                // First goto word
                iProgMem[0] = ((iBootloaderStartAdress & 0x0000FF));                                   //low address byte
                iProgMem[1] = 0xEF;                                                                    //goto instruction
                // Second goto word
                iProgMem[2] = ((iBootloaderStartAdress & 0x00FF00) >> 8);                              //high address byte
                iProgMem[3] = 0xF0 /*goto instruction*/ + ((iBootloaderStartAdress & 0x0F0000) >> 16); //upper address nibble
            }


            //--------------------------------------------------------------------------
            // Return
            //--------------------------------------------------------------------------
            OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.success, "Hex-file successfully parsed", iTabLevel));

            UpdateParsedSettings(pobjSettings);

            pbResult = true;
            return;
        } // ParseHexFile()
        }// BytesToWrite()

        //---------------------------------------------------------------------
        // ParseHexFile()
        //---------------------------------------------------------------------
        override public void ParseHexFile(clsParseSettings pobjSettings, int iTabLevel, ref bool pbResult)
        {
            string strFileLine;

            int[]      iInData = new int[256];
            string     strLineData;
            int        iLineByteCount;
            int        iLineAddr;
            int        iLineCode;
            int        iOutAddr;
            int        iLineAddrHigh = 0;
            TextReader textReader;
            int        iIter;
            int        iAddress;
            int        iWordCount;


            //---------------------------------------------------------------------
            // Allready parsed?
            //---------------------------------------------------------------------
            pobjSettings.fileTimestamp = File.GetLastWriteTime(filename);
            if (NeedsParsing(pobjSettings) == false)
            {
                pbResult = true;
                return;
            }


            //
            OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.started, "Parsing hexfile...", iTabLevel++));

            //
            bIsParsed        = false;
            bHasValidProgram = true;
            bHasValidEEPROM  = true;
            bHasValidConfigs = true;


            //---------------------------------------------------------------------
            // Validate hex-file
            //---------------------------------------------------------------------
            bool bValidateResult = false;

            ValidateHexFile(iTabLevel, ref bValidateResult);
            if (bValidateResult == false)
            {
                OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.failed, "Parsing of hex-file failed", iTabLevel++));
                pbResult = false;
                return;
            }


            //--------------------------------------------------------------------------
            // Open hex-file
            //--------------------------------------------------------------------------
            textReader = new StreamReader(strFilename);


            //--------------------------------------------------------------------------
            // Initialize arrays to default values
            //--------------------------------------------------------------------------
            for (iIter = 0; iIter < iProgRowUsedBufferSize; iIter++)
            {
                bProgRowUsed[iIter] = false;
            }
            for (iIter = 0; iIter < iProgMemBufferSize; iIter++)
            {
                iProgMem[iIter] = 0xFF;
            }

            for (iIter = 0; iIter < iEEWordsUsedBufferSize; iIter++)
            {
                bEEWordUsed[iIter] = false;
            }
            for (iIter = 0; iIter < iEEMemBufferSize; iIter++)
            {
                iEEMem[iIter] = 0xFF;
            }

            for (iIter = 0; iIter < iConfigWordsUsedBufferSize; iIter++)
            {
                bConfigWordUsed[iIter] = false;
            }
            for (iIter = 0; iIter < iConfigMemBufferSize; iIter++)
            {
                iConfigMem[iIter] = 255;
            }


            //--------------------------------------------------------------------------
            // do actual parsing
            //
            // Hex-file format
            //
            // : 10 8000 00 0800 fa00 000f 8001
            // | |  |    |  |-Data
            // | |  |    |----Line code
            // | |  |---------Line address
            // | |------------Line data count
            // |--------------Just a simple colon
            //
            //--------------------------------------------------------------------------
            while (textReader.Peek() != -1)
            {
                strFileLine = textReader.ReadLine();

                //Init the array with 0xFF
                for (iIter = 0; iIter < 256; iIter++)
                {
                    iInData[iIter] = 255;
                }

                iLineCode = 0;
                if (strFileLine.Substring(0, 1) == ":")
                {
                    //Parse the line
                    iLineByteCount = int.Parse(strFileLine.Substring(1, 2), System.Globalization.NumberStyles.HexNumber);
                    iLineAddr      = (int.Parse(strFileLine.Substring(3, 4), System.Globalization.NumberStyles.HexNumber) & 65535);
                    iLineCode      = int.Parse(strFileLine.Substring(7, 2), System.Globalization.NumberStyles.HexNumber);
                    strLineData    = strFileLine.Substring(9, (iLineByteCount * 2));

                    iAddress = ((iLineAddrHigh << 16) + iLineAddr) / 2;

                    // Data record
                    if (iLineCode == 0)
                    {
                        iWordCount = iLineByteCount / 4;

                        // Regular program memory
                        if (iAddress <= 0x002C00)
                        {
                            iOutAddr = (iAddress * 3) / 2;

                            for (int iWord = 0; iWord < iWordCount; iWord++)
                            {
                                //upper-low-high
                                iProgMem[iOutAddr + iWord * 3 + 0] = int.Parse(strLineData.Substring(iWord * 8 + 4, 2), System.Globalization.NumberStyles.HexNumber);
                                iProgMem[iOutAddr + iWord * 3 + 1] = int.Parse(strLineData.Substring(iWord * 8 + 0, 2), System.Globalization.NumberStyles.HexNumber);
                                iProgMem[iOutAddr + iWord * 3 + 2] = int.Parse(strLineData.Substring(iWord * 8 + 2, 2), System.Globalization.NumberStyles.HexNumber);
                                ++iProgWordsUsed;
                                bProgRowUsed[(iAddress / 2 + iWord) / pobjSettings.device.rowsizeW] = true;
                            }

                            // EEPROM memory
                        }
                        else if (iAddress >= (0x800000 - pobjSettings.device.eepromSizeB) && iAddress < 0x800000)
                        {
                            iOutAddr = iAddress - (0x800000 - pobjSettings.device.eepromSizeB);

                            for (int iWord = 0; iWord < iWordCount; iWord++)
                            {
                                iEEMem[iOutAddr + iWord * 2 + 0] = int.Parse(strLineData.Substring(iWord * 8 + 0, 2), System.Globalization.NumberStyles.HexNumber);
                                iEEMem[iOutAddr + iWord * 2 + 1] = int.Parse(strLineData.Substring(iWord * 8 + 2, 2), System.Globalization.NumberStyles.HexNumber);

                                bEEWordUsed[iOutAddr / 2 + iWord] = true;
                            }

                            // Config memory
                        }
                        else if (iAddress >= 0xF80000 && iAddress <= 0xF8000E)
                        {
                            iOutAddr = iAddress - 0xF80000;

                            for (int iWord = 0; iWord < iWordCount; iWord++)
                            {
                                iConfigMem[iOutAddr + iWord * 2 + 0] = int.Parse(strLineData.Substring(iWord * 8 + 0, 2), System.Globalization.NumberStyles.HexNumber);
                                iConfigMem[iOutAddr + iWord * 2 + 1] = int.Parse(strLineData.Substring(iWord * 8 + 2, 2), System.Globalization.NumberStyles.HexNumber);

                                bConfigWordUsed[iOutAddr / 2 + iWord] = true;
                            }
                        }

                        // End Of File record
                    }
                    else if (iLineCode == 1)
                    {
                        break;

                        // Extended Linear Address Record
                        // The two data bytes represent the upper 16 bits of the 32 bit address, when combined with the address of the 00 type record.
                    }
                    else if (iLineCode == 4)
                    {
                        iLineAddrHigh = (int.Parse(strFileLine.Substring(9, 4), System.Globalization.NumberStyles.HexNumber) & 65535);
                    }
                }
            }


            //--------------------------------------------------------------------------
            // Close files
            //--------------------------------------------------------------------------
            textReader.Close();


            //--------------------------------------------------------------------------
            // Calculate addresses
            //--------------------------------------------------------------------------
            int iBootloaderStartRow    = (pobjSettings.device.flashSizeP / 2 - pobjSettings.bootloaderSizeR * pobjSettings.device.rowsizeW) / pobjSettings.device.rowsizeW;
            int iBootloaderEndRow      = iBootloaderStartRow + pobjSettings.bootloaderSizeR - 1;
            int iBootloaderStartAdress = pobjSettings.device.flashSizeP - pobjSettings.bootloaderSizeR * pobjSettings.device.rowsizeW * 2; //bootloader is placed in 4th last row

            int iBootloaderStartAdressB3 = (iBootloaderStartAdress / 2) * 3;                                                               //starting index in buffer
            int iUserAppGotoAdressB3     = iBootloaderStartAdressB3 - 6;                                                                   //starting index in buffer


            //--------------------------------------------------------------------------
            // Check for code that would overwrite the bootloader
            //--------------------------------------------------------------------------
            bool bOk = true;

            for (iIter = iBootloaderStartRow; iIter <= iBootloaderEndRow; iIter++)
            {
                if (bProgRowUsed[iIter] == true)
                {
                    bOk = false;
                    break;
                }
            }
            if (bOk == false)
            {
                OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.warning, "The hex-file contains code that will overwrite the bootloader", iTabLevel));
                if (pobjSettings.allowBlOverwrite == false)
                {
                    bHasValidProgram = false;
                }
            }


            //--------------------------------------------------------------------------
            // Check for GOTO at 0x00
            //--------------------------------------------------------------------------
            if (pobjSettings.noGoto == false)
            {
                bOk = false;
                for (iIter = 0; iIter < 6; iIter++)
                {
                    if (iProgMem[iIter] != 255)
                    {
                        bOk = true;
                        break;
                    }
                }
                if (bOk == false || bProgRowUsed[0] == false)
                {
                    OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.warning, "There's no GOTO at location 0x00", iTabLevel));
                    bHasValidProgram = false;
                }

                //--------------------------------------------------------------------------
                // Swap user goto at 0x00 to bootloader usr:, se firmware code
                // It´s important that this instruction is placed just before a new program row
                //--------------------------------------------------------------------------
                for (iIter = 0; iIter < 6; iIter++)
                {
                    iProgMem[iUserAppGotoAdressB3 + iIter] = iProgMem[iIter];
                }
                bProgRowUsed[iUserAppGotoAdressB3 / (pobjSettings.device.rowsizeW * 3)] = true;
            }


            //--------------------------------------------------------------------------
            // Find out how many program rows are used
            //--------------------------------------------------------------------------
            iProgRowsUsed = 0;
            for (iIter = 0; iIter < iProgRowUsedBufferSize; iIter++)
            {
                if (bProgRowUsed[iIter] == true)
                {
                    ++iProgRowsUsed;
                    if (clsds30Loader.debugMode)
                    {
                        OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.info, "program row " + iIter.ToString() + " is used", iTabLevel));
                    }
                }
            }
            if (iProgRowsUsed == 0)
            {
                bHasValidProgram = false;
            }


            //--------------------------------------------------------------------------
            // Find out how many eeprom words are used
            //--------------------------------------------------------------------------
            iEEWordsUsed = 0;
            for (iIter = 0; iIter < iEEWordsUsedBufferSize; iIter++)
            {
                if (bEEWordUsed[iIter] == true)
                {
                    ++iEEWordsUsed;
                }
            }
            if (iEEWordsUsed == 0)
            {
                bHasValidEEPROM = false;
            }


            //--------------------------------------------------------------------------
            // Find out how many configurations are used
            //--------------------------------------------------------------------------
            iConfigWordsUsed = 0;
            //bConfigUsed[4] = false;		//CONFIG5(index 4)(primary oscillator) can not be writte to according to manual
            for (iIter = 0; iIter < iConfigWordsUsedBufferSize; iIter++)
            {
                if (bConfigWordUsed[iIter] == true)
                {
                    ++iConfigWordsUsed;
                }
            }
            if (iConfigWordsUsed > pobjSettings.device.configCount)
            {
                OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.warning, "hex-file contains more config locations than the device has", iTabLevel));
                bHasValidConfigs = false;
            }
            else if (iConfigWordsUsed == 0)
            {
                bHasValidConfigs = false;
            }


            //--------------------------------------------------------------------------
            // Set GOTO to bootloader at 0x0000
            //--------------------------------------------------------------------------
            if (pobjSettings.noGoto == false)
            {
                // First goto word
                iProgMem[0] = 0x04;                                                 //goto instruction
                iProgMem[1] = ((iBootloaderStartAdress & 0x0000FE));                //low adress byte
                iProgMem[2] = ((iBootloaderStartAdress & 0x00FF00) >> 8);           //high adress byte
                // Second goto word
                iProgMem[3] = 0x00;                                                 //not used by goto
                iProgMem[4] = ((iBootloaderStartAdress & 0x7F0000) >> 16);          //upper adress byte
                iProgMem[5] = 0x00;                                                 //not used by goto
            }


            //--------------------------------------------------------------------------
            // Return
            //--------------------------------------------------------------------------
            OnHexFileParse(new clsHexFileParseEventArgs(clsHexFileParseEventArgs.EventType.success, "Hex-file successfully parsed", iTabLevel));


            UpdateParsedSettings(pobjSettings);

            pbResult = true;
            return;
        } // ParseHexFile()