Skip to content

Commit

Permalink
added mass erase & configurable page size options
Browse files Browse the repository at this point in the history
  • Loading branch information
twatorowski committed Sep 25, 2016
1 parent 9dab1cd commit edc2336
Show file tree
Hide file tree
Showing 5 changed files with 454 additions and 119 deletions.
221 changes: 215 additions & 6 deletions STBootLib/STBoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,21 @@ public async Task Initialize()
await GetID();
}

/* unprotect memory */
public async Task Unprotect()
{
/* no support for unprotect? */
if (!Commands.Contains(STCmds.WR_UNPROTECT))
throw new STBootException("Command not supported");

/* no support for unprotect? */
if (!Commands.Contains(STCmds.RD_UNPROTECT))
throw new STBootException("Command not supported");

await ReadUnprotect();
await WriteUnprotect();
}

/* read memory */
public async Task ReadMemory(uint address, byte[] buf, int offset,
int size, IProgress<int> p, CancellationToken ct)
Expand Down Expand Up @@ -165,6 +180,21 @@ public async Task ErasePage(uint pageNumber)
}
}

/* perform global erase */
public async Task GlobalErase()
{
/* 'classic' erase operation supported? */
if (Commands.Contains(STCmds.ERASE)) {
await EraseSpecial(STEraseMode.GLOBAL);
/* 'extended' erase operation supported? */
} else if (Commands.Contains(STCmds.EXT_ERASE)) {
await ExtendedEraseSpecial(STExtendedEraseMode.GLOBAL);
/* no operation supported */
} else {
throw new STBootException("Command not supported");
}
}

/* jump to user code */
public async Task Jump(uint address)
{
Expand Down Expand Up @@ -571,6 +601,54 @@ private async Task Erase(uint pageNumber)
sem.Release();
}

/* erase memory page */
private async Task EraseSpecial(STEraseMode mode)
{
/* command word */
var tx = new byte[4];
/* temporary storage for response bytes */
var tmp = new byte[1];

/* command code */
tx[0] = (byte)STCmds.ERASE;
/* checksum */
tx[1] = ComputeChecksum(tx, 0, 1);

/* erase single page */
tx[2] = (byte)((int)mode);
/* checksum */
tx[3] = (byte)~ComputeChecksum(tx, 2, 2);

/* try to send command and wait for response */
try {
/* send bytes */
await SerialWrite(tx, 0, 2);
/* wait for response code */
await SerialRead(tmp, 0, 1);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Command Rejected");

/* send address */
await SerialWrite(tx, 2, 2);
/* wait for response code */
await SerialRead(tmp, 0, 1);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Special Code Rejected");

/* oops, something baaad happened! */
} catch (Exception) {
/* release semaphore */
sem.Release();
/* re-throw */
throw;
}

/* release semaphore */
sem.Release();
}

/* extended erase memory page */
private async Task ExtendedErase(uint pageNumber)
{
Expand All @@ -588,8 +666,8 @@ private async Task ExtendedErase(uint pageNumber)
tx[2] = 0;
tx[3] = 0;
/* set page number */
tx[4] = 0;
tx[5] = (byte)pageNumber;
tx[4] = (byte)(pageNumber >> 8);
tx[5] = (byte)(pageNumber >> 0);
/* checksum */
tx[6] = (byte)~ComputeChecksum(tx, 2, 5);

Expand All @@ -605,12 +683,63 @@ private async Task ExtendedErase(uint pageNumber)

/* send address */
await SerialWrite(tx, 2, 5);
/* wait for response code */
await SerialRead(tmp, 0, 1);
/* wait for response code. use longer timeout, erase might
* take a while or two. */
await SerialRead(tmp, 0, 1, 3000);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Page Rejected");

/* oops, something baaad happened! */
} catch (Exception) {
/* release semaphore */
sem.Release();
/* re-throw */
throw;
}

/* release semaphore */
sem.Release();
}

/* extended erase memory page */
private async Task ExtendedEraseSpecial(STExtendedEraseMode mode)
{
/* command word */
var tx = new byte[5];
/* temporary storage for response bytes */
var tmp = new byte[1];

/* command code */
tx[0] = (byte)STCmds.EXT_ERASE;
/* checksum */
tx[1] = ComputeChecksum(tx, 0, 1);

/* erase single page */
tx[2] = (byte)((int)mode >> 8);
tx[3] = (byte)((int)mode >> 0);
/* checksum */
tx[4] = (byte)~ComputeChecksum(tx, 2, 3);

/* try to send command and wait for response */
try {
/* send bytes */
await SerialWrite(tx, 0, 2);
/* wait for response code */
await SerialRead(tmp, 0, 1);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Command Rejected");

/* send address */
await SerialWrite(tx, 2, 3);
/* wait for response code. use longer timeout, erase might
* take a while or two. */
await SerialRead(tmp, 0, 1, 10000);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Special code Rejected");

/* oops, something baaad happened! */
} catch (Exception) {
/* release semaphore */
Expand All @@ -623,6 +752,80 @@ private async Task ExtendedErase(uint pageNumber)
sem.Release();
}

/* unprotect flash before writing */
private async Task WriteUnprotect()
{
/* command word */
var tx = new byte[2];
/* temporary storage for response bytes */
var tmp = new byte[1];

/* command code */
tx[0] = (byte)STCmds.WR_UNPROTECT;
/* checksum */
tx[1] = ComputeChecksum(tx, 0, 1);

/* try to send command and wait for response */
try {
/* send bytes */
await SerialWrite(tx, 0, 2);
/* wait for response code */
await SerialRead(tmp, 0, 1);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Command Rejected");

/* wait for response code. use longer timeout, erase might
* take a while or two. */
await SerialRead(tmp, 0, 1);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Write Unprotect Rejected");

/* oops, something baaad happened! */
} finally {
/* release semaphore */
sem.Release();
}
}

/* unprotect flash before reading */
private async Task ReadUnprotect()
{
/* command word */
var tx = new byte[2];
/* temporary storage for response bytes */
var tmp = new byte[1];

/* command code */
tx[0] = (byte)STCmds.RD_UNPROTECT;
/* checksum */
tx[1] = ComputeChecksum(tx, 0, 1);

/* try to send command and wait for response */
try {
/* send bytes */
await SerialWrite(tx, 0, 2);
/* wait for response code */
await SerialRead(tmp, 0, 1);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Command Rejected");

/* wait for response code. use longer timeout, erase might
* take a while or two. */
await SerialRead(tmp, 0, 10000);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Write Unprotect Rejected");

/* oops, something baaad happened! */
} finally {
/* release semaphore */
sem.Release();
}
}

/* compute checksum */
private byte ComputeChecksum(byte[] data, int offset, int count)
{
Expand All @@ -646,8 +849,14 @@ private async Task SerialWrite(byte[] data, int offset, int count)
await bs.WriteAsync(data, offset, count);
}

/* read 'length' number of bytes from serial port */
/* standard read with timeout equal to 1s */
private async Task SerialRead(byte[] data, int offset, int count)
{
await SerialRead(data, offset, count, 1000);
}

/* read 'length' number of bytes from serial port */
private async Task SerialRead(byte[] data, int offset, int count, int timeout)
{
/* shorter name */
var bs = sp.BaseStream;
Expand All @@ -660,7 +869,7 @@ private async Task SerialRead(byte[] data, int offset, int count)
try {
/* prepare task */
br += await bs.ReadAsync(data, offset + br, count - br).
WithTimeout(1000);
WithTimeout(timeout);
/* got handling? */
} catch (OperationCanceledException) {
/* rethrow */
Expand Down
18 changes: 18 additions & 0 deletions STBootLib/STBootCmds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,22 @@ public enum STCmds
/* Disables the read protection */
RD_UNPROTECT = 0x92
}

/* special erase mode for normal erase command */
public enum STEraseMode
{
/* erase all sectors */
GLOBAL = 0xff,
}

/* special erase mode for normal erase command */
public enum STExtendedEraseMode
{
/* erase all sectors */
GLOBAL = 0xffff,
/* erase bank 1 */
BANK1 = 0xfffe,
/* erase bank 2 */
BANK2 = 0xfffd
}
}
6 changes: 6 additions & 0 deletions STM32 Flash Loader.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "STM32 Flash Loader", "STM32 Flash Loader\STM32 Flash Loader.csproj", "{975D7D83-56AE-4A64-865E-BCD9096B05C7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "STBootLib", "STBootLib\STBootLib.csproj", "{8EC66A52-5978-481D-A80D-D75CBC6DE918}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,6 +17,10 @@ Global
{975D7D83-56AE-4A64-865E-BCD9096B05C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{975D7D83-56AE-4A64-865E-BCD9096B05C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{975D7D83-56AE-4A64-865E-BCD9096B05C7}.Release|Any CPU.Build.0 = Release|Any CPU
{8EC66A52-5978-481D-A80D-D75CBC6DE918}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8EC66A52-5978-481D-A80D-D75CBC6DE918}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8EC66A52-5978-481D-A80D-D75CBC6DE918}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8EC66A52-5978-481D-A80D-D75CBC6DE918}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit edc2336

Please sign in to comment.