예제 #1
0
파일: C2.Flash.cs 프로젝트: x893/C2.Flash
		private void writeFileToFlash(bool setAddresses)
		{
			if (!selectC2Device())
				return;

			if (FileName.Text.Length == 0)
			{
				if (openFileDialog.ShowDialog() == DialogResult.OK)
				{
					FileName.Text = openFileDialog.FileName;
					setAddresses = true;
				}
				else
					return;
			}

			try
			{
				int flashSize = CurrentC2Device.Bottom;

				byte[] flash_buffer = new byte[flashSize];
				for (int idx = 0; idx < flash_buffer.Length; idx++)
					flash_buffer[idx] = 0xFF;

				List<HexRange> ranges = new List<HexRange>();
				bool enableFlash = false;

				int startAddress = -1, endAddress = -1;
				if (!validInt(StartAddr.Text, out startAddress) || !validInt(EndAddr.Text, out endAddress))
					return;

				if (Path.GetExtension(FileName.Text).Equals(".hex", StringComparison.InvariantCultureIgnoreCase))
				{
					int minAddress = int.MaxValue, maxAddress = int.MinValue;
					bool fail = false;

					#region Load HEX file 
					using (TextReader s = new StreamReader(FileName.Text))
					{
						string line;
						int lineNumber = 0;
						int count = 0;
						int ext_address = 0, seg_address = 0, address = 0;
						byte command = 0;
						byte checksum = 0;
						int pos;
						byte data;

						while ((line = s.ReadLine()) != null)
						{
							++lineNumber;
							line = line.Trim();
							if (line.Length == 0 || !line.StartsWith(":"))
								continue;

							if (line.Length < 11)
							{
								fail = true;
							}
							else
							{
								fail |= !int.TryParse(line.Substring(1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out count);
								fail |= !int.TryParse(line.Substring(3, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out address);
								fail |= !byte.TryParse(line.Substring(7, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out command);
								fail |= !byte.TryParse(line.Substring(line.Length - 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out checksum);
							}

							if (fail)
							{
								MessageBox.Show(string.Format("Can't parse line {0}", lineNumber));
								break;
							}

							int calculatedCheckSum = count + ((address >> 8) & 0xFF) + (address & 0xFF) + command;
							pos = 9;

							if (command == 2 || command == 4)
							{
								if (line.Length != 15)
									fail = true;
								else if(command == 2)
									fail |= !int.TryParse(line.Substring(pos, 4), NumberStyles.HexNumber, null, out seg_address);
								else
									fail |= !int.TryParse(line.Substring(pos, 4), NumberStyles.HexNumber, null, out ext_address);

								if (fail)
								{
									if(command == 2)
										MessageBox.Show(string.Format("Bad extended segment address record at line {0}.", lineNumber));
									else
										MessageBox.Show(string.Format("Bad extended linear address record at line {0}.", lineNumber));
								}
							}
							else if (command == 0)
							{
								if (count > 0)
								{
									int next = address + count;
									bool add = true;
									foreach (HexRange range in ranges)
									{
										if (range.Next == address)
										{
											range.Count += count;
											add = false;
											break;
										}
										else if (next == range.Address)
										{
											range.Address = address;
											range.Count += count;
											add = false;
											break;
										}
										fail = range.IsInner(address) || range.IsInner(next);
										if (fail)
											break;
									}

									if (fail)
									{
										MessageBox.Show(string.Format("Address range overlapped at line {0}.", lineNumber));
										break;
									}
									if (add)
										ranges.Add(new HexRange(address, count));
								}

								for (; count > 0; --count)
								{
									if (address >= flashSize)
									{
										MessageBox.Show(string.Format("Address {0} outside flash size at line {1}.", addressToText(address), lineNumber));
										fail = true;
										break;
									}

									if (CurrentC2Device.LockType == "FLT_SINGLE" && address == CurrentC2Device.SingleLock)
									{
										if (MessageBox.Show(string.Format("File write to LOCK byte ({0:X4}).\nAre you sure ?", address), "Attention", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) != DialogResult.OK)
										{
											fail = true;
											break;
										}
									}

									if (address < minAddress)
										minAddress = address;
									if (address > maxAddress)
										maxAddress = address;

									fail |= !byte.TryParse(line.Substring(pos, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out data);
									pos += 2;
									if (fail)
									{
										MessageBox.Show(string.Format("Bad data \"{0}\" at line {1}.", line.Substring(pos, 2), lineNumber));
										break;
									}
									flash_buffer[address++] = data;
									calculatedCheckSum += (int)data;
								}
							}

							if (fail)
								break;

							fail |= (((calculatedCheckSum + checksum) & 0xFF) != 0);
							if (fail)
							{
								MessageBox.Show(string.Format("Bad checksum {0:X2}:{1:X2} at line {2}.", checksum, calculatedCheckSum, lineNumber));
								break;
							}

							// EOF record
							if (command == 1)
								break;
						}
						s.Close();
					}
					#endregion

					#region Collapse HEX ranges and check overlap 
					if (!fail)
					{
						if (ranges.Count == 0)
						{
							MessageBox.Show("No data to write in file");
							fail = true;
						}
						else
						{
							for (int i = 0; i < ranges.Count; i++)
							{
								HexRange rangeI = ranges[i];
								for (int j = 0; j < ranges.Count; j++)
								{
									if (i == j)
										continue;
									HexRange rangeJ = ranges[j];
									if (rangeI.Next == rangeJ.Address)
									{
										rangeI.Count += rangeJ.Count;
										ranges.RemoveAt(j);
										i = -1;
										break;
									}
									if (rangeJ.Next == rangeI.Address)
									{
										rangeJ.Count += rangeI.Count;
										ranges.RemoveAt(i);
										i = -1;
										break;
									}
									fail = rangeI.IsInner(rangeJ.Address) || rangeI.IsInner(rangeJ.Next);
									if (fail)
									{
										MessageBox.Show(string.Format("Addresses overlapped {0}:{1} and {2}:{3}",
											addressToText(rangeI.Address),
											addressToText(rangeI.Next),
											addressToText(rangeJ.Address),
											addressToText(rangeJ.Next)
											));
										break;
									}
								}
								if (fail)
									break;
							}
						}
					}
					#endregion

					#region Check Addresses and ranges 
					if (!fail)
					{
						if (setAddresses)
						{
							if (ranges.Count > 0)
							{
								startAddress = minAddress;
								endAddress = maxAddress;
								StartAddr.Text = addressToText(minAddress);
								EndAddr.Text = addressToText(maxAddress);
							}
						}
						else if (endAddress > maxAddress || startAddress < minAddress)
						{
							MessageBox.Show("File data less than bytes to write");
							fail = true;
						}
						else
						{
							HexRange range = new HexRange(startAddress, endAddress - startAddress + 1);
							for (int i = 0; i < ranges.Count; ++i)
							{
								HexRange rangeS = ranges[i];
								if (!range.IsOverlapped(rangeS))
								{
									ranges.RemoveAt(i);
									--i;
								}
							}
						}
					}
					if (!fail)
					{
						if (ranges.Count == 0)
						{
							MessageBox.Show("No data to write in file");
							fail = true;
						}
						else
							enableFlash = true;
					}
					#endregion
				}
				else if (Path.GetExtension(FileName.Text).Equals(".bin", StringComparison.InvariantCultureIgnoreCase))
				{
					#region Load BIN file 
					using (Stream s = File.OpenRead(FileName.Text))
					{
						enableFlash = true;
						int fileLength = (int)s.Length;
						if (setAddresses)
						{
							endAddress = startAddress + fileLength - 1;
							if (startAddress >= flashSize)
							{
								MessageBox.Show("Invalid start address");
									enableFlash = false;
							}
							else if (endAddress >= flashSize)
							{
								if (MessageBox.Show("File data more than available flash.\nWrite partial content ?", "Attension", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) != DialogResult.OK)
									enableFlash = false;
								else
								{
									endAddress = flashSize - startAddress - 1;
									fileLength = flashSize - startAddress;
								}

							}
							else
								EndAddr.Text = addressToText(endAddress);
						}
						else if ((endAddress - startAddress + 1) > fileLength)
						{
							MessageBox.Show("File data less than bytes to write");
							enableFlash = false;
						}
						if (enableFlash)
							s.Read(flash_buffer, startAddress, fileLength);
						s.Close();
					}
					#endregion
				}
				else
				{
					MessageBox.Show("Insupported file type");
				}

				if (enableFlash)
				{
					if (startAddress < 0 ||
						endAddress < 0 ||
						startAddress >= flashSize ||
						endAddress >= flashSize
						)
						MessageBox.Show("File data more than available flash.");
					else
					{
						int byteCount = endAddress - startAddress + 1;
						if (MessageBox.Show(
							string.Format(
								"Continue write {0} bytes\nfrom {1} to {2}",
								addressToText(byteCount),
								addressToText(startAddress),
								addressToText(endAddress)),
								"Attention", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
						{
							float delta = ((float)(progress.Maximum - progress.Minimum)) / (float)byteCount;
							int writtenBytes = 0;
							Response response = null;
							int addressAt = startAddress;
							int totalBytes = byteCount;
							ranges.Clear();
							while (byteCount > 0)
							{
								int count = (byteCount > 128) ? 128 : byteCount;

								#region Auto erase page
								if (cbAutoErase.Checked)
								{
									// Check for page erase
									bool erase = true;
									foreach (HexRange range in ranges)
									{
										if (range.IsInner(startAddress))
										{
											erase = false;
											break;
										}
									}
									if (erase)
									{
										response = sendCommand(0, C2_ERASE_PAGE, (byte)((startAddress >> 9) & 0xFF));
										if (response.Result != ResponseCode.COMMAND_OK)
											break;
										ranges.Add(new HexRange(startAddress & ~(CurrentC2Device.FlashSectorSize - 1), CurrentC2Device.FlashSectorSize));
									}

									// Also check end address to erase
									erase = true;
									endAddress = startAddress + count - 1;
									foreach (HexRange range in ranges)
									{
										if (range.IsInner(endAddress))
										{
											erase = false;
											break;
										}
									}
									if (erase)
									{
										response = sendCommand(0, C2_ERASE_PAGE, (byte)((endAddress >> 9) & 0xFF));
										if (response.Result != ResponseCode.COMMAND_OK)
											break;
										ranges.Add(new HexRange(endAddress & ~(CurrentC2Device.FlashSectorSize - 1), CurrentC2Device.FlashSectorSize));
									}
								}
								#endregion

								response = sendCommand(0, flash_buffer, startAddress, count, C2_WRITE_FLASH, (byte)(startAddress & 0xFF), (byte)((startAddress >> 8) & 0xFF), (byte)count);
								if (response.Result != ResponseCode.COMMAND_OK)
									break;

								startAddress += count;
								byteCount -= count;
								writtenBytes += count;
								if (writtenBytes % 512 == 0)
								{
									progress.Value = (int)(delta * ((float)(writtenBytes)));
									status.Text = string.Format("Writing {0} bytes at {1} ({2}%)...", addressToText(count), addressToText(startAddress), (int)(100 * writtenBytes / totalBytes));
									Application.DoEvents();
								}
							}
							progress.Value = progress.Minimum;

							if (C2_Disconnect_Target() && C2_Connect_Target() && C2_Device_Info() && response != null)
							{
								if(response.Result != ResponseCode.COMMAND_OK)
									setStatus("C2_WRITE_FLASH", response);
								else
									status.Text = string.Format("Writing {0} bytes at {1} complete.", addressToText(totalBytes), addressToText(addressAt));
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}
예제 #2
0
파일: C2.Flash.cs 프로젝트: x893/C2.Flash
		public bool IsOverlapped(HexRange range)
		{
			if (range.Address >= next)
				return false;
			if (range.Next <= address)
				return false;
			if (this.IsInner(range.Address) || this.IsInner(range.Next - 1))
				return true;
			if (range.IsInner(address) || range.IsInner(next - 1))
				return true;
			return false;
		}