}// 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()
//--------------------------------------------------------------------- // 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. } }
//--------------------------------------------------------------------- // Constructor() //--------------------------------------------------------------------- public clsHex() { objParsedSettings = new clsParseSettings(); } // Constructor()
}//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();
} // 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()
}// 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; }
} // 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 ); }
} // 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()