From cb8bc643c413250711d882c261d7d5c13770fd53 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sun, 23 Jul 2017 16:54:12 +1000 Subject: [PATCH] Adding support for boot up Logo's (#32) This brings across a set of commits to support loading boot up images from a specific location in flash. And also creating a generator tool to make files to put images in said position. --- .gitignore | 2 + .../.vs/TS100 Logo Editor/v15/.suo | Bin 0 -> 49664 bytes .../TS100 Logo Editor/TS100 Logo Editor.sln | 22 ++ .../TS100 Logo Editor/App.config | 6 + .../TS100 Logo Editor/Form1.Designer.cs | 209 +++++++++++ .../TS100 Logo Editor/Form1.cs | 169 +++++++++ .../TS100 Logo Editor/Form1.resx | 120 ++++++ .../TS100 Logo Editor/IntelHex.cs | 96 +++++ .../TS100 Logo Editor/Program.cs | 22 ++ .../Properties/AssemblyInfo.cs | 36 ++ .../Properties/Resources.Designer.cs | 63 ++++ .../Properties/Resources.resx | 117 ++++++ .../Properties/Settings.Designer.cs | 26 ++ .../Properties/Settings.settings | 7 + .../TS100 Logo Editor.csproj | 87 +++++ README.md | 120 ++++-- TS100.png | Bin 82801 -> 0 bytes workspace/ts100/LinkerScript.ld | 2 +- .../ts100/StdPeriph_Driver/Release_Notes.html | 342 ------------------ workspace/ts100/inc/Oled.h | 2 +- workspace/ts100/inc/Settings.h | 1 + workspace/ts100/src/Main.c | 24 +- workspace/ts100/src/Settings.c | 42 ++- 23 files changed, 1123 insertions(+), 392 deletions(-) create mode 100644 Logo GUI/TS100 Logo Editor/.vs/TS100 Logo Editor/v15/.suo create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor.sln create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/App.config create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.Designer.cs create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.cs create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.resx create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/IntelHex.cs create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Program.cs create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/AssemblyInfo.cs create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Resources.Designer.cs create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Resources.resx create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Settings.Designer.cs create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Settings.settings create mode 100644 Logo GUI/TS100 Logo Editor/TS100 Logo Editor/TS100 Logo Editor.csproj delete mode 100644 TS100.png delete mode 100644 workspace/ts100/StdPeriph_Driver/Release_Notes.html diff --git a/.gitignore b/.gitignore index cdbe355d..493a802b 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ workspace/.metadata/* workspace/ts100/.settings/language.settings.xml workspace/ts100/.cproject TS100/KiCad/TS100.bak +Logo GUI/TS100 Logo Editor/TS100 Logo Editor/obj/ +Logo GUI/TS100 Logo Editor/TS100 Logo Editor/bin/ \ No newline at end of file diff --git a/Logo GUI/TS100 Logo Editor/.vs/TS100 Logo Editor/v15/.suo b/Logo GUI/TS100 Logo Editor/.vs/TS100 Logo Editor/v15/.suo new file mode 100644 index 0000000000000000000000000000000000000000..a6a468db11f26637d531f7fbdd2d5cef3257e9c2 GIT binary patch literal 49664 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 literal 0 HcmV?d00001 diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor.sln b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor.sln new file mode 100644 index 00000000..ae3cea0a --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.15 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TS100 Logo Editor", "TS100 Logo Editor\TS100 Logo Editor.csproj", "{206C8AEF-3BE6-44E9-A1B0-25BF3805F1CB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {206C8AEF-3BE6-44E9-A1B0-25BF3805F1CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {206C8AEF-3BE6-44E9-A1B0-25BF3805F1CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {206C8AEF-3BE6-44E9-A1B0-25BF3805F1CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {206C8AEF-3BE6-44E9-A1B0-25BF3805F1CB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/App.config b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/App.config new file mode 100644 index 00000000..74ade9db --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.Designer.cs b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.Designer.cs new file mode 100644 index 00000000..f067f2c4 --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.Designer.cs @@ -0,0 +1,209 @@ +namespace TS100_Logo_Editor +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.btnLoadImage = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.cbInvertImage = new System.Windows.Forms.CheckBox(); + this.gbScaling = new System.Windows.Forms.GroupBox(); + this.rbScaleStretch = new System.Windows.Forms.RadioButton(); + this.rbScaleFit = new System.Windows.Forms.RadioButton(); + this.pbImage = new System.Windows.Forms.PictureBox(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.btnSaveHex = new System.Windows.Forms.Button(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.gbScaling.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pbImage)).BeginInit(); + this.groupBox3.SuspendLayout(); + this.SuspendLayout(); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.btnLoadImage); + this.groupBox1.Location = new System.Drawing.Point(20, 20); + this.groupBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.groupBox1.Size = new System.Drawing.Size(300, 217); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "1. Load source Image"; + // + // btnLoadImage + // + this.btnLoadImage.Location = new System.Drawing.Point(10, 31); + this.btnLoadImage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnLoadImage.Name = "btnLoadImage"; + this.btnLoadImage.Size = new System.Drawing.Size(280, 35); + this.btnLoadImage.TabIndex = 0; + this.btnLoadImage.Text = "Load Image"; + this.btnLoadImage.UseVisualStyleBackColor = true; + this.btnLoadImage.Click += new System.EventHandler(this.btnLoadImage_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.cbInvertImage); + this.groupBox2.Controls.Add(this.gbScaling); + this.groupBox2.Controls.Add(this.pbImage); + this.groupBox2.Location = new System.Drawing.Point(330, 20); + this.groupBox2.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.groupBox2.Size = new System.Drawing.Size(300, 217); + this.groupBox2.TabIndex = 1; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "2. Adjust image"; + // + // cbInvertImage + // + this.cbInvertImage.AutoSize = true; + this.cbInvertImage.Location = new System.Drawing.Point(138, 122); + this.cbInvertImage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.cbInvertImage.Name = "cbInvertImage"; + this.cbInvertImage.Size = new System.Drawing.Size(75, 24); + this.cbInvertImage.TabIndex = 2; + this.cbInvertImage.Text = "Invert"; + this.cbInvertImage.UseVisualStyleBackColor = true; + this.cbInvertImage.CheckedChanged += new System.EventHandler(this.cbInvertImage_CheckedChanged); + // + // gbScaling + // + this.gbScaling.Controls.Add(this.rbScaleStretch); + this.gbScaling.Controls.Add(this.rbScaleFit); + this.gbScaling.Location = new System.Drawing.Point(9, 91); + this.gbScaling.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.gbScaling.Name = "gbScaling"; + this.gbScaling.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.gbScaling.Size = new System.Drawing.Size(120, 117); + this.gbScaling.TabIndex = 1; + this.gbScaling.TabStop = false; + this.gbScaling.Text = "Scaling"; + // + // rbScaleStretch + // + this.rbScaleStretch.AutoSize = true; + this.rbScaleStretch.Location = new System.Drawing.Point(10, 68); + this.rbScaleStretch.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rbScaleStretch.Name = "rbScaleStretch"; + this.rbScaleStretch.Size = new System.Drawing.Size(86, 24); + this.rbScaleStretch.TabIndex = 1; + this.rbScaleStretch.Text = "Stretch"; + this.rbScaleStretch.UseVisualStyleBackColor = true; + this.rbScaleStretch.CheckedChanged += new System.EventHandler(this.rbScaleStretch_CheckedChanged); + // + // rbScaleFit + // + this.rbScaleFit.AutoSize = true; + this.rbScaleFit.Checked = true; + this.rbScaleFit.Location = new System.Drawing.Point(10, 31); + this.rbScaleFit.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rbScaleFit.Name = "rbScaleFit"; + this.rbScaleFit.Size = new System.Drawing.Size(52, 24); + this.rbScaleFit.TabIndex = 0; + this.rbScaleFit.TabStop = true; + this.rbScaleFit.Text = "Fit"; + this.rbScaleFit.UseVisualStyleBackColor = true; + this.rbScaleFit.CheckedChanged += new System.EventHandler(this.rbScaleFit_CheckedChanged); + // + // pbImage + // + this.pbImage.BackColor = System.Drawing.Color.Black; + this.pbImage.Location = new System.Drawing.Point(4, 31); + this.pbImage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.pbImage.Name = "pbImage"; + this.pbImage.Size = new System.Drawing.Size(192, 32); + this.pbImage.TabIndex = 0; + this.pbImage.TabStop = false; + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.btnSaveHex); + this.groupBox3.Location = new System.Drawing.Point(640, 20); + this.groupBox3.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.groupBox3.Size = new System.Drawing.Size(300, 217); + this.groupBox3.TabIndex = 2; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "3. Export"; + // + // btnSaveHex + // + this.btnSaveHex.Location = new System.Drawing.Point(8, 91); + this.btnSaveHex.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnSaveHex.Name = "btnSaveHex"; + this.btnSaveHex.Size = new System.Drawing.Size(280, 35); + this.btnSaveHex.TabIndex = 0; + this.btnSaveHex.Text = "Save DFU File"; + this.btnSaveHex.UseVisualStyleBackColor = true; + this.btnSaveHex.Click += new System.EventHandler(this.btnSaveHex_Click); + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(963, 265); + this.Controls.Add(this.groupBox3); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.DoubleBuffered = true; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.Name = "Form1"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "TS100 Custom Logo editor"; + this.groupBox1.ResumeLayout(false); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.gbScaling.ResumeLayout(false); + this.gbScaling.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pbImage)).EndInit(); + this.groupBox3.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button btnLoadImage; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.CheckBox cbInvertImage; + private System.Windows.Forms.GroupBox gbScaling; + private System.Windows.Forms.RadioButton rbScaleStretch; + private System.Windows.Forms.RadioButton rbScaleFit; + private System.Windows.Forms.PictureBox pbImage; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.Button btnSaveHex; + } +} + diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.cs b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.cs new file mode 100644 index 00000000..5067c509 --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.cs @@ -0,0 +1,169 @@ + +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace TS100_Logo_Editor +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + } + Image sourceImage; + const int LCDWidth = 96; + Bitmap PureBMP; + private void btnLoadImage_Click(object sender, EventArgs e) + { + //load in an image + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Title = "Select Image"; + dlg.Filter = "Image files (*.jpg, *.jpeg, *.bmp, *.png) | *.jpg; *.jpeg; *.bmp; *.png"; + if (dlg.ShowDialog() == DialogResult.OK) + { + //user has selected an image + string filename = dlg.FileName; + sourceImage = Image.FromFile(filename); + reDrawPreview(); + } + + } + + private void reDrawPreview() + { + PureBMP = new Bitmap(LCDWidth, 16); + //scale mode + if (rbScaleFit.Checked) + { + //fit + float scalefactor = Math.Min((float)PureBMP.Width / (float)sourceImage.Width, (float)PureBMP.Height / (float)sourceImage.Height); + using (Graphics g = Graphics.FromImage(PureBMP)) + { + g.DrawImage(sourceImage, new RectangleF(0, 0, sourceImage.Width * scalefactor, sourceImage.Height * scalefactor)); + } + } + else + { + //draw image stretched + using (Graphics g = Graphics.FromImage(PureBMP)) + { + g.DrawImage(sourceImage, new RectangleF(0, 0, LCDWidth, 16)); + } + } + //We now have our downsampled colour image + //apply inversion + if (cbInvertImage.Checked) + { + for (int y = 0; (y <= (PureBMP.Height - 1)); y++) + { + for (int x = 0; (x <= (PureBMP.Width - 1)); x++) + { + Color inv = PureBMP.GetPixel(x, y); + inv = Color.FromArgb(255, (255 - inv.R), (255 - inv.G), (255 - inv.B)); + PureBMP.SetPixel(x, y, inv); + } + } + } + + //Threshold image + PureBMP = GrayScale(PureBMP); + //draw image at 2x scale + Bitmap bBig = new Bitmap(pbImage.Width, pbImage.Height); + using (Graphics g = Graphics.FromImage(bBig)) + { + g.DrawImage(PureBMP, new RectangleF(0, 0, pbImage.Width, pbImage.Height)); + } + pbImage.Image = bBig; + } + public Bitmap GrayScale(Bitmap Bmp) + { + int rgb; + Color c; + + for (int y = 0; y < Bmp.Height; y++) + for (int x = 0; x < Bmp.Width; x++) + { + c = Bmp.GetPixel(x, y); + rgb = (int)((c.R + c.G + c.B) / 3); + if (rgb > 128) + rgb = 0xFF; + else + rgb = 0x00; + Bmp.SetPixel(x, y, Color.FromArgb(rgb, rgb, rgb)); + } + return Bmp; + } + + private void rbScaleStretch_CheckedChanged(object sender, EventArgs e) + { + reDrawPreview(); + } + + private void rbScaleFit_CheckedChanged(object sender, EventArgs e) + { + reDrawPreview(); + } + + private void cbInvertImage_CheckedChanged(object sender, EventArgs e) + { + reDrawPreview(); + } + + private void btnSaveHex_Click(object sender, EventArgs e) + { + Bitmap bmp = PureBMP; + //convert image to byte array + byte[] data = new byte[1024]; + data[0] = 0xAA; + data[1] = 0x55; + data[2] = 0xF0; + data[3] = 0x0D; + + for (int i = 0; i < (LCDWidth * 16 / 8); i++) + { + //loop through all the bytes + byte b = 0;//local byte + //i sets the starting column + for (int y = 0; y < 8; y++) + { + var px = bmp.GetPixel(i % LCDWidth, (i / LCDWidth) == 1 ? 8 + y : y); + //we loop down the picture + //LSB is the top, MSB is the bottom + if (px.R >= 128) + { + //pixel is white + b |= (byte)(1 << y); + } + } + data[i + 4] = b; + } + //We should now have the byte array that represents the image in the LCD format. + //We now send this off to be encoded by the Intel Encoder + //Flip all uint16_t pairs + for (int i = 0; i < data.Length; i += 2) + { + //we need to swap each pair + byte temp = data[i]; + data[i] = data[i + 1]; + data[i + 1] = temp; + } + string outputHexFile = IntelHex.IntelHex.encode(data, 0x0800B800, 16, true, true);//16 bytes is the only format the DFU seems to support //0x0800B800 + //^ This string now just needs to be written out to a text file :) + SaveFileDialog dlg = new SaveFileDialog(); + dlg.Title = "Save DFU File"; + dlg.AddExtension = true; + dlg.DefaultExt = ".hex"; + dlg.Filter = "Hex Files(*.hex)|*.hex"; + if (dlg.ShowDialog() == DialogResult.OK) + { + //The user has selected where they want to save the file + using (var fs = new System.IO.StreamWriter(dlg.FileName)) + { + fs.Write(outputHexFile); + } + } + + } + } +} diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.resx b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/IntelHex.cs b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/IntelHex.cs new file mode 100644 index 00000000..f1206cac --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/IntelHex.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; + +namespace IntelHex +{ + public class IntelHex + { + public static string encode(byte[] data, UInt32 startingAddress, int bytesPerLine, bool header = true,bool Addbloat=false) + { + //We are taking the byte array and encoding it into the wanted hex file contents (aka string of data). + //First create the starting base address record + //:020000040800F2 + string Output = ""; + if (header) + { + //Set the upper 16 bits of the address space + Output += getHighAddressSetLine((UInt16)(startingAddress >> 16)); + } + + //Now loop through all the data that we were given + for (UInt32 index = 0; index < data.Length; index = (UInt32)(index + bytesPerLine)) + { + //We want to read from data[index] to data[index+bytesPerLine-1] + UInt32 currentAddress = (UInt32)(startingAddress + index); + if ((currentAddress >> 16) != (startingAddress >> 16)) + { + Output += getHighAddressSetLine((UInt16)(currentAddress >> 16)); + //The address has rolled over the 64K boundry, so write a new high address change line + } + //We should now be good for the higher part of the address + Output += encodeDataLine((UInt16)(currentAddress & 0xFFFF), data, index, bytesPerLine); + } + if(Addbloat) + { + //Repeat the instructs a stack of times to get around filesize minimums + for(int x=0;x<3;x++) + { + for (UInt32 index = 0; index < data.Length; index = (UInt32)(index + bytesPerLine)) + { + //We want to read from data[index] to data[index+bytesPerLine-1] + UInt32 currentAddress = (UInt32)(startingAddress + index); + if ((currentAddress >> 16) != (startingAddress >> 16)) + { + Output += getHighAddressSetLine((UInt16)(currentAddress >> 16)); + //The address has rolled over the 64K boundry, so write a new high address change line + } + //We should now be good for the higher part of the address + Output += encodeDataLine((UInt16)(currentAddress & 0xFFFF), data, index, bytesPerLine); + } + } + } + //We have now written out all the data lines + Output += ":00000001FF\r\n";//End of file marker + + return Output; + } + private static string encodeDataLine(UInt16 address, byte[] data, UInt32 startindex, int bytes) + { + string line = ":"; + line += bytes.ToString("X2");//add the marker of line length + line += address.ToString("X4");//write the address + line += "00";//Data line + //Next copy bytes bytes + for (int i = 0; i < bytes; i++) + { + if ((startindex + i) < data.Length) + line += data[startindex + i].ToString("X2"); + else + line += "FF";//pad images out with FF + } + line += checksumLine(line);//Adds checksum and EOL + return line; + } + private static string getHighAddressSetLine(UInt16 HighAddress) + { + string Output = ""; + Output += ":02000004" + (HighAddress).ToString("X4"); + Output += checksumLine(Output); + return Output; + } + private static string checksumLine(string line) + { + //We want to convert the string line to each byte and sum. + byte sum = 0; + for (int i = 1; i < line.Length; i += 2) + { + byte b = byte.Parse((line.Substring(i, 2)), System.Globalization.NumberStyles.HexNumber); + sum += b; + } + byte checksum = (byte)(((byte)0) - sum);//invert + return checksum.ToString("X2") + "\r\n"; + } + } +} diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Program.cs b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Program.cs new file mode 100644 index 00000000..bee62adc --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace TS100_Logo_Editor +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/AssemblyInfo.cs b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..b330f110 --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TS100 Logo Editor")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TS100 Logo Editor")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("206c8aef-3be6-44e9-a1b0-25bf3805f1cb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Resources.Designer.cs b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Resources.Designer.cs new file mode 100644 index 00000000..60db1d43 --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace TS100_Logo_Editor.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TS100_Logo_Editor.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Resources.resx b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Resources.resx new file mode 100644 index 00000000..af7dbebb --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Settings.Designer.cs b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Settings.Designer.cs new file mode 100644 index 00000000..94e873e5 --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace TS100_Logo_Editor.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.1.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Settings.settings b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Settings.settings new file mode 100644 index 00000000..39645652 --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/TS100 Logo Editor.csproj b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/TS100 Logo Editor.csproj new file mode 100644 index 00000000..31abe7f4 --- /dev/null +++ b/Logo GUI/TS100 Logo Editor/TS100 Logo Editor/TS100 Logo Editor.csproj @@ -0,0 +1,87 @@ + + + + + Debug + AnyCPU + {206C8AEF-3BE6-44E9-A1B0-25BF3805F1CB} + WinExe + TS100_Logo_Editor + TS100 Logo Editor + v4.0 + 512 + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + + + prompt + 4 + + + TS100_Logo_Editor.Program + + + + + + + + + + + + + + + + Form + + + Form1.cs + + + + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 797197f6..73bedc0a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # TS100 -This is a complete re-write of the open source software for the ts100 soldering iron. +This is a complete re*write of the open source software for the ts100 soldering iron. This project is feature complete for use as a soldering iron, *so please suggest any feature improvements you would like!* This project was started to remove the need for USB for changing system settings. In the latest official firmware they have also added a settings menu system, so it is still worth comparing the two firmwares to select your preferred option. -**Please note that when running the iron off a Lithium battery pack, the Iron is only rated to 24V input. So using a fully charged 6S battery exceeds this rating, and is done so at your own risk. Please calibrate your irons voltage reading when you are using a lithium battery after any firmware upgrades.** +**Please note that when running the iron off a Lithium battery pack, the Iron is only rated to 24V input. So using a fully charged 6S battery exceeds this rating, and is done so at your own risk. +Please calibrate your irons voltage reading when you are using a lithium battery after any firmware upgrades.** ## Features * Soldering / Temperature control @@ -21,10 +22,12 @@ In the latest official firmware they have also added a settings menu system, so * Calibration of the temperature offset * Boost mode lets you temporarily change the temperature when soldering * Battery charge level indicatior if power source set to a lipo cell count. +* Custom bootup logo support # Upgrading your ts100 iron + This is completely safe, if it goes wrong just put the .hex file from the official website onto the unit and your back to the old firmware. Downloads for the hex files to flash are available on the [releases page.](https://github.com/Ralim/ts100/releases) -Officially the bootloader on the iron only works under windows. However, users have reported that it does work under Mac, and can be made to work under Linux. Details over on the [wiki page](https://github.com/Ralim/ts100/wiki/Upgrading-Firmware). +Officially the bootloader on the iron only works under windows. However, users have reported that it does work under Mac, and can be made to work under Linux *sometimes*. Details over on the [wiki page](https://github.com/Ralim/ts100/wiki/Upgrading*Firmware). 1. Hold the button closest to the tip, and plug in the USB to the computer. 2. The unit will appear as a USB drive. @@ -38,17 +41,38 @@ For the more adventurerous out there, you can also load this firmware onto the d On the bottom of the MCU riser pcb, there are 4 pads for programming. There is a complete device flash backup included in this repository. (Note this includes the bootloader, so will need a SWD programmer to load onto the unit). Please do not use the backup of the bootloader for anything malicious, its only saved here for those who are tinkering with their iron and decide to replace it. -# New Menu System +## Setting a custom bootup image + +This firmware uses a different method of updating the bootup image. +This removes the need for emulating a USB drive on the iron just to allow for a bootup image to be setup. +At this point in time you will need a windows machine to make the required .hex file for you image. + +1. On the [releases page](https://github.com/Ralim/ts100/releases) you will need to download the latest copy of the GUI Tool (*TS100 Logo Editor.exe*). +2. Launch the TS100 Logo Editor, you will need to have .NET 4.0 installed on your machine +3. On the tool open the source image that you would like to use as your bootup screen. A resolution of 96x16 is ideal, but you can fill or stretch your logo to fit +4. Colour images are okay, the software will convert them to B&W for you. +5. You can also invert colours if you would prefer. +6. Save the created file as a *.hex* file somewhere. +7. Connect your iron to your computer in DFU mode (same as you would to upgrade firmware). +8. Drag the created .hex file for the logo onto the iron to update it with the file. +9. You should be good to go. +10. The image will stay through future updates, but if it ever wont I will put a warning in the update download on the releases page. + +## New Menu System + This new firmware uses a new menu system to allow access to the settings on the device. When on the main screen, the unit shows prompts for the two most common operations. --> Pressing the button near the tip enters soldering mode --> Pressing the button near the power input enters the settings menu. --> Pressing both buttons together enters the Extras menu +* Pressing the button near the tip enters soldering mode +* Pressing the button near the power input enters the settings menu. +* Pressing both buttons together enters the Extras menu + ## Soldering mode + In this mode the iron works as you would expect, pressing either button will take you to a temperature change screen. Use each button to go up and down in temperature. Pressing both buttons will exit you from the temperature menu (or wait 3 seconds and it will time out). Pressing both buttons will also exit the soldering mode. ## Settings Menu + This menu allows you to cycle through all the options and set their values. The button near the tip cycles through the options, and the one near the usb changes the selected option. Note that settings are not saved until you exit the menu, and some settings such as screen flip do not apply until a power cycle is applied. @@ -58,7 +82,7 @@ If you leave the unit alone (ie don't press any buttons) on a setting, after 3 s * STMP -> The temperature the unit drops to in sleep mode * SLTME -> Sleep time, how long it takes before the unit goes to sleep * SHTME -> Shutdown Time, how long the unit will wait after movement before shutting down completely -* MSENSE -> Motion Sensitivity,0-9,0 means motion sensing is turned off, 9 is most sensitive, 1 is least sensitive (ie takes more movement to trigger) +* MSENSE -> Motion Sensitivity,0*9,0 means motion sensing is turned off, 9 is most sensitive, 1 is least sensitive (ie takes more movement to trigger) * TMPUNIT -> Temperature unit, C or F * TMPRND -> Temperature Rounding, {1,5,10} * TMPSPD -> How fast the temperature should update in the soldering status screen. @@ -67,13 +91,16 @@ If you leave the unit alone (ie don't press any buttons) on a setting, after 3 s * BTMP -> Set the temperature for the boost mode Temperature rounding means that the unit will round off the temperature before displaying. This can helpt to reduce the flickering of the temperature when the unit oscillates between two temperatures. + ## Extras Menu + This menu defaults to showing the current temperature on the tip. Pressing the button near the iron tip will show the current input voltage. Pressing the other button while this is show will allow you to calibrate the reading if your iron is like mine and is not overly accurate out of the factory. (Press buttons to change measurement up and down, press both to exit and save). Pressing the button near the usb enters the temperature offset setting menu, when the iron is cold, pressing the other button will start the unit calibrating for any offset in the tip temperature. -## Calibrating input voltage +### Calibrating input voltage + Due to the tolerance on the resistors used for the input voltage divider, some irons can be up to 0.6V out on the voltage measurement. Please, Please, calibrate your iron if you have any issues with the cutoff voltage. This is more critical than before with the new cell count based cutout voltage. @@ -95,7 +122,8 @@ To calibrate your Iron: 14. Press both buttons at once to exit back to the idle screen. 15. You're done. Enjoy your iron. -## Calibrating tip offset +### Calibrating tip offset + Some tips will have an offset on their readings, to calibrate this out perform the following steps: 1. Connect power to your iron @@ -110,58 +138,78 @@ Some tips will have an offset on their readings, to calibrate this out perform t 10. Press both buttons at the same time to return to the idle screen. 11. You're done. Enjoy your iorn. -## Boost mode +### Boost mode + This allows you to change the front key (one near the tip) to become a boost button instead of going to temperature editing when in soldering mode. This allows you to set this button to change the soldering temperature for short periods. For example when soldering a big joint and you want to boost the temperature a bit. The boost temperature is set in the settings menu. -# Version Changes: + +## Version Changes + +V1.15 + +* Added support for a custom bootup logo to be programmed via the DFU bootloader. + V1.14 -- Changed input voltage cutoff to be based on cell count rather than voltage. + +* Changed input voltage cutoff to be based on cell count rather than voltage. V1.13 -- Swapped buttons for menu to prevent accidentally changing first menu item -- Added auto key repeat. + +* Swapped buttons for menu to prevent accidentally changing first menu item +* Added auto key repeat. V1.12 -- Increases sensitivity options to be 1-9 with 0 off state -- Fixes issue where going from COOL -> soldering can leave screen off. + +* Increases sensitivity options to be 1*9 with 0 off state +* Fixes issue where going from COOL *> soldering can leave screen off. V1.11 -- Boost mode -- Change sensitivity options to be 1-8 + +* Boost mode +* Change sensitivity options to be 1*8 V1.10 -- Adds help text to settings -- Improves settings for the display update rate + +* Adds help text to settings +* Improves settings for the display update rate V1.09 -- Adds display modes, for slowing down or simplifying the display + +* Adds display modes, for slowing down or simplifying the display V1.08 -- Fix settings menu not showing flip display + +* Fix settings menu not showing flip display V1.07 -- Adds shutdown time to automatically shutdown the iron after inactivity + +* Adds shutdown time to automatically shutdown the iron after inactivity V1.06 -- Changes H and C when the iron is heating to the minidso chevron like images + +* Changes H and C when the iron is heating to the minidso chevron like images V1.05 -- Adds ability to calibrate the input voltage measurement + +* Adds ability to calibrate the input voltage measurement V1.04 -- Increased accuracy of the temperature control -- Improved PID response slightly -- Allows temperature offset calibration -- Nicer idle screen + +* Increased accuracy of the temperature control +* Improved PID response slightly +* Allows temperature offset calibration +* Nicer idle screen V1.03 -- Improved Button handling -- Ability to set motion sensitivity -- DC voltmeter page shows input voltage + +* Improved Button handling +* Ability to set motion sensitivity +* DC voltmeter page shows input voltage V1.02 -- Adds hold both buttons on IDLE to access the therometer mode. -- Changes the exit soldering mode to be holding both buttons (Like original firmware). -If you _really_ loved this firmware and want to continue my caffine addiction, you can do so here (or email me) : https://paypal.me/RalimTek +* Adds hold both buttons on IDLE to access the therometer mode. +* Changes the exit soldering mode to be holding both buttons (Like original firmware). + +If you love this firmware and want to continue my caffine addiction, you can do so here (or email me) : https://paypal.me/RalimTek diff --git a/TS100.png b/TS100.png deleted file mode 100644 index 00b8fcb04bd26d4d8aa6003e610569a91576259f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82801 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 KYL4 - - - - - - - - - - - -Release Notes for STM32F10x Standard Peripherals Library Drivers - - - - - -

-


-

-
- - - - - - -
- - - - - - - - - -
Back to Release page
-

Release -Notes for STM32F10x Standard Peripherals Library Drivers -(StdPeriph_Driver)

-

Copyright 2011 STMicroelectronics

-

-
-

 

- - - - - - -
-

Contents

-
    -
  1. STM32F10x Standard Peripherals Library -Drivers update History
  2. -
  3. License
  4. -
- - -

STM32F10x Standard -Peripherals Library Drivers  update History


-

V3.5.0 / 11-March-2011

-

Main -Changes

- -
    -
  • stm32f10x_can.h/.c files:
  • -
      -
    • Add 5 new functions
    • -
        -
      • 3 -new functions controlling the counter errors: CAN_GetLastErrorCode(), -CAN_GetReceiveErrorCounter() and CAN_GetLSBTransmitErrorCounter().
      • -
      -
        -
      • 1 new function to select the CAN operating mode: CAN_OperatingModeRequest().
      • -
      -
        -
      • 1 new function to support CAN TT mode: CAN_TTComModeCmd().
        -
      • -
      -
    • CAN_TransmitStatus() function updated to support all CAN transmit intermediate states
      -
    • -
    -
  • stm32f10x_i2c.h/.c files:
  • -
      -
    • Add 1 new function:
    • -
        -
      • I2C_NACKPositionConfig(): -This function configures the same bit (POS) as I2C_PECPositionConfig() -but is intended to be used in I2C mode while I2C_PECPositionConfig() is -intended to used in SMBUS mode.
      • -
      -
    -
  • stm32f10x_tim.h/.c files:
  • -
      -
    • Change the TIM_DMABurstLength_xBytes definitions to TIM_DMABurstLength_xTansfers
      -
    • -
    - - -
- -

3.4.0 -- 10/15/2010

- -
    -
  1. General
  2. -
- -
    -
  • Add support for STM32F10x High-density value line devices.
  • -
- -
    -
  1. STM32F10x_StdPeriph_Driver
  2. -
- - -
    - -
  • stm32f10x_bkp.h/.c
  • -
      -
    • Delete BKP registers definition from stm32f10x_bkp.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_can.h/.c
  • -
      -
    • Delete CAN registers definition from stm32f10x_can.c and use defines within stm32f10x.h file.
      -
    • -
    • Update the wording of some defines and Asserts macro.
      -
    • -
    • CAN_GetFlagStatus() -and CAN_ClearFlag() functions: updated to support new flags (were not -supported in previous version). These flags are:  CAN_FLAG_RQCP0, -CAN_FLAG_RQCP1, CAN_FLAG_RQCP2, CAN_FLAG_FMP1, CAN_FLAG_FF1, -CAN_FLAG_FOV1, CAN_FLAG_FMP0, CAN_FLAG_FF0,   CAN_FLAG_FOV0, -CAN_FLAG_WKU, CAN_FLAG_SLAK and CAN_FLAG_LEC.
      -
    • -
    • CAN_GetITStatus() -function: add a check of the interrupt enable bit before getting the -status of corresponding interrupt pending bit.
      -
    • -
    • CAN_ClearITPendingBit() function: correct the procedure to clear the interrupt pending bit.
      -
    • -
    -
  • stm32f10x_crc.h/.c
  • -
      -
    • Delete CRC registers definition from stm32f10x_crc.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_dac.h/.c
  • -
      -
    • Delete DAC registers definition from stm32f10x_dac.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_dbgmcu.h/.c
  • -
      -
    • Delete DBGMCU registers definition from stm32f10x_dbgmcu.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_dma.h/.c
  • -
      -
    • Delete DMA registers definition from stm32f10x_dma.c and use defines within stm32f10x.h file.
    • -
    • Add new function "void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber);"
      -
    • -
    -
  • stm32f10x_flash.h/.c
  • -
      -
    • FLASH functions (Erase and Program) updated to always clear the "PG", "MER" and "PER" bits even in case of TimeOut Error.
    • -
    -
  • stm32f10x_fsmc.h/.c
  • -
      -
    • Add new member "FSMC_AsynchronousWait" in "FSMC_NORSRAMInitTypeDef" structure.
    • -
    -
  • stm32f10x_gpio.h/.c
  • -
      -
    • GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for TIM6, TIM7 and DAC DMA requests, TIM12 and DAC Triggers / DMA2_Channel5 Interrupt mapping.
    • -
    -
  • stm32f10x_pwr.h/.c
  • -
      -
    • Delete PWR registers definition from stm32f10x_pwr.c and use defines within stm32f10x.h and core_cm3.h files.
    • -
    -
  • stm32f10x_rtc.h/.c
  • -
      -
    • Delete RTC registers definition from stm32f10x_rtc.c and use defines within stm32f10x.h file.
    • -
    -
  • stm32f10x_spi.h/.c
  • -
      -
    • Add new definition for I2S Audio Clock frequencies "I2S_AudioFreq_192k".
    • -
    -
  • stm32f10x_tim.h/.c
  • -
    • Add new definition for TIM Input Capture Polarity "TIM_ICPolarity_BothEdge".
    - -
- -

3.3.0 -- 04/16/2010

- -
  1. General
-
  • Add support for STM32F10x XL-density devices.
  • I2C driver: events description and management enhancement.
-
  1. STM32F10x_StdPeriph_Driver
-
  • stm32f10x_dbgmcu.h/.c
    • DBGMCU_Config() function: add new values DBGMCU_TIMx_STOP (x: 9..14) for DBGMCU_Periph parameter.
  • stm32f10x_flash.h/.c: -updated to support Bank2 of XL-density devices (up to 1MByte of Flash -memory). For more details, refer to the description provided within -stm32f10x_flash.c file.
  • stm32f10x_gpio.h/.c
    • GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for FSMC_NADV pin and TIM9..11,13,14.
  • stm32f10x_i2c.h/.c: I2C events description and management enhancement.
    • I2C_CheckEvent() -function: updated to check whether the last event contains the -I2C_EVENT  (instead of check whether the last event is equal to -I2C_EVENT)
    • Add -detailed description of I2C events and how to manage them using the -functions provided by this driver. For more information, refer to -stm32f10x_i2c.h and stm32f10x_i2c.c files.
  • stm32f10x_rcc.h/.c: updated to support TIM9..TIM14 APB clock and reset configuration
  • stm32f10x_tim.h/.c: updated to support new Timers TIM9..TIM14.
  • stm32f10x_sdio.h: 
    • SDIO_SetSDIOReadWaitMode() function: correct values of SDIO_ReadWaitMode parameter
      change
        -#define -SDIO_ReadWaitMode_CLK               -  ((uint32_t)0x00000000)
        #define -SDIO_ReadWaitMode_DATA2             -((uint32_t)0x00000001)
      by
        #define -SDIO_ReadWaitMode_CLK               -  ((uint32_t)0x00000001)
        #define -SDIO_ReadWaitMode_DATA2             -((uint32_t)0x00000000)
-

3.2.0 -- 03/01/2010

-
    -
  1. General
  2. -
-
    - -
  • Add support -for STM32 Low-density Value line (STM32F100x4/6) and -Medium-density Value line (STM32F100x8/B) devices.
  • -
  • Almost -peripherals drivers were updated to support Value -line devices features
  • -
  • Drivers limitations fix and enhancements.
  • - -
-
    -
  1. STM32F10x_StdPeriph_Driver
  2. -
-
    -
  • Add new -firmware driver for CEC peripheral: stm32f10x_cec.h and stm32f10x_cec.c
  • -
  • Timers drivers stm32f10x_tim.h/.c: add support for new General Purpose Timers: TIM15, TIM16 and TIM17.
  • -
  • RCC driver: add support for new Value peripherals: HDMI-CEC, TIM15, TIM16 and TIM17.
  • -
  • GPIO driver: add new remap parameters for TIM1, TIM15, TIM16, TIM17 and HDMI-CEC: GPIO_Remap_TIM1_DMA, GPIO_Remap_TIM15, GPIO_Remap_TIM16, GPIO_Remap_TIM17, GPIO_Remap_CEC.
  • -
  • USART -driver: add support for Oversampling by 8 mode and onebit method. 2 -functions has been added: USART_OverSampling8Cmd() and -USART_OneBitMethodCmd().
    -
  • -
  • DAC -driver: add new functions handling the DAC under run feature: -DAC_ITConfig(), DAC_GetFlagStatus(), DAC_ClearFlag(), DAC_GetITStatus() -and DAC_ClearITPendingBit().
  • -
  • DBGMCU driver: add new parameters for TIM15, TIM16 and TIM17: DBGMCU_TIM15_STOP, DBGMCU_TIM16_STOP, DBGMCU_TIM17_STOP.
    -
  • -
  • FLASH -driver: the FLASH_EraseOptionBytes() function updated. This is now just -erasing the option bytes without modifying the RDP status either -enabled or disabled.
  • -
  • PWR -driver: the PWR_EnterSTOPMode() function updated. When woken up from -STOP mode, this function resets again the SLEEPDEEP bit in the -Cortex-M3 System Control register to allow Sleep mode entering.
  • - - -
-

License

-

The -enclosed firmware and all the related documentation are not covered by -a License Agreement, if you need such License you can contact your -local STMicroelectronics office.

-

THE -PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO -SAVE TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR -ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY -CLAIMS ARISING FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY -CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH -THEIR PRODUCTS.

-

 

-
-
-

For -complete documentation on STM32(CORTEX M3) 32-Bit Microcontrollers -visit www.st.com/STM32

-
-

-
-
-

 

-
- \ No newline at end of file diff --git a/workspace/ts100/inc/Oled.h b/workspace/ts100/inc/Oled.h index 664e933b..4bee73aa 100644 --- a/workspace/ts100/inc/Oled.h +++ b/workspace/ts100/inc/Oled.h @@ -2,7 +2,7 @@ * Oled.h * Functions for writing to the OLED screen * Basically wraps drawing text and numbers to the OLED - * Uses font.h -> 14 pixel wide fixed width + * Uses font.h -> 12 pixel wide fixed width */ #ifndef _OLED_SSD1306_H #define _OLED_SSD1306_H diff --git a/workspace/ts100/inc/Settings.h b/workspace/ts100/inc/Settings.h index 3c16125b..e85301e5 100644 --- a/workspace/ts100/inc/Settings.h +++ b/workspace/ts100/inc/Settings.h @@ -46,4 +46,5 @@ void saveSettings(); void restoreSettings(); uint8_t lookupVoltageLevel(uint8_t level); void resetSettings(); +void showBootLogoIfavailable(); #endif /* SETTINGS_H_ */ diff --git a/workspace/ts100/src/Main.c b/workspace/ts100/src/Main.c index 87ac5567..c5563b8f 100644 --- a/workspace/ts100/src/Main.c +++ b/workspace/ts100/src/Main.c @@ -9,6 +9,7 @@ #include "Oled.h" #include "Settings.h" #include "I2C.h" + void setup(); int main(void) { @@ -18,28 +19,29 @@ int main(void) { ProcessUI(); DrawUI(); delayMs(50); //Slow the system down a little bit - if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==Bit_RESET) - { + if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == Bit_RESET) { lastMovement = millis(); + //This is a workaround for the line staying low as the user is still moving. (ie sensitivity is too high for their amount of movement) } } } void setup() { RCC_Config(); //setup system clock - NVIC_Config(0x4000); //this shifts the NVIC table to be offset, for the usb bootloader's size - GPIO_Config(); //setup all the GPIO pins + NVIC_Config(0x4000); //this shifts the NVIC table to be offset, for the usb bootloader's size + GPIO_Config(); //setup all the GPIO pins Init_EXTI(); //Init the EXTI inputs - Init_Timer3(); //Used for the soldering iron tip + Init_Timer3(); //Used for the soldering iron tip Adc_Init(); //Init adc and DMA I2C_Configuration(); //Start the I2C hardware - GPIO_Init_OLED(); //Init the GPIO ports for the OLED + GPIO_Init_OLED(); //Init the GPIO ports for the OLED restoreSettings(); //Load settings - StartUp_Accelerometer(systemSettings.sensitivity); //Start the accelerometer + StartUp_Accelerometer(systemSettings.sensitivity); //Start the accelerometer setupPID(); //Init the PID values - readIronTemp(systemSettings.tempCalibration, 0,0); //load the default calibration value + readIronTemp(systemSettings.tempCalibration, 0, 0); //load the default calibration value Init_Oled(systemSettings.flipDisplay); //Init the OLED display - OLED_DrawString("VER 1.14", 8); //Version Number - delayMs(500); //Pause to show version number - Start_Watchdog(1000); //start the system watch dog as 1 second timeout + OLED_DrawString("VER 1.15", 8); //Version Number + delayMs(300); //Pause to show version number + showBootLogoIfavailable(); + Start_Watchdog(1000); //start the system watch dog as 1 second timeout } diff --git a/workspace/ts100/src/Settings.c b/workspace/ts100/src/Settings.c index d08bf121..473704ef 100644 --- a/workspace/ts100/src/Settings.c +++ b/workspace/ts100/src/Settings.c @@ -8,7 +8,8 @@ */ #include "Settings.h" -#define FLASH_ADDR (0x8000000|48896)/*Flash start OR'ed with the maximum amount of flash - 256 bytes*/ +#define FLASH_ADDR (0x8000000|0xBC00)/*Flash start OR'ed with the maximum amount of flash - 1024 bytes*/ +#define FLASH_LOGOADDR (0x8000000|0xB800) /*second last page of flash set aside for logo image*/ void saveSettings() { //First we erase the flash FLASH_Unlock(); //unlock flash writing @@ -71,3 +72,42 @@ void resetSettings() { systemSettings.BoostTemp = 4000; //default to 400C } +void showBootLogoIfavailable() { + //check if the header is there (0xAA,0x55,0xF0,0x0D) + //If so display logo + uint16_t temp[98]; + + for (uint8_t i = 0; i < (98); i++) { + temp[i] = *(uint16_t *) (FLASH_LOGOADDR + (i * 2)); + } + uint8_t temp8[98 * 2]; + for (uint8_t i = 0; i < 98; i++) { + temp8[i * 2] = temp[i] >> 8; + temp8[i * 2 + 1] = temp[i] & 0xFF; + + } + /*char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', + 'C', 'D', 'E', 'F' }; + + OLED_DrawChar(hex[(temp8[0] >> 4) & 0x0F], 0); + OLED_DrawChar(hex[(temp8[0] >> 0) & 0x0F], 1); + OLED_DrawChar(hex[(temp8[1] >> 4) & 0x0F], 2); + OLED_DrawChar(hex[(temp8[1] >> 0) & 0x0F], 3); + OLED_DrawChar(hex[(temp8[2] >> 4) & 0x0F], 4); + OLED_DrawChar(hex[(temp8[2] >> 0) & 0x0F], 5); + OLED_DrawChar(hex[(temp8[3] >> 4) & 0x0F], 6); + OLED_DrawChar(hex[(temp8[3] >> 0) & 0x0F], 7);*/ + if (temp8[0] != 0xAA) + return; + if (temp8[1] != 0x55) + return; + if (temp8[2] != 0xF0) + return; + if (temp8[3] != 0x0D) + return; + + + Oled_DrawArea(0, 0, 96, 16, (uint8_t*) (temp8 + 4)); + + delayMs(1000); +}