mirror of
https://github.com/dougg3/mac-rom-simm-programmer.git
synced 2025-01-14 18:29:45 +00:00
Added verify during write. It seems to mostly work except when the chip
is completely removed from the SIMM -- in that case, the verification still passes for some reason. I'm still debugging this one. Maybe the data I had just written is still essentially on the bus because of the floating pins and it reads it too fast? Maybe turning on pull-ups would help with that?
This commit is contained in:
parent
ff1f213b6f
commit
667c2c5a2d
@ -336,12 +336,69 @@ void ExternalMem_WriteByteToChips(uint32_t address, uint32_t data, uint8_t chips
|
|||||||
ExternalMem_WaitCompletion(chipsMask);
|
ExternalMem_WaitCompletion(chipsMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalMem_Write(uint32_t startAddress, uint32_t *buf, uint32_t len, uint8_t chipsMask)
|
uint8_t ExternalMem_Write(uint32_t startAddress, uint32_t *buf, uint32_t len, uint8_t chipsMask, bool doVerify)
|
||||||
{
|
{
|
||||||
|
// Use a mask so we don't worry about chips we don't want to talk with
|
||||||
|
uint32_t mask = ExternalMem_MaskForChips(chipsMask);
|
||||||
|
|
||||||
while (len--)
|
while (len--)
|
||||||
{
|
{
|
||||||
ExternalMem_WriteByteToChips(startAddress++, *buf++, chipsMask);
|
ExternalMem_WriteByteToChips(startAddress, *buf, chipsMask);
|
||||||
|
if (doVerify)
|
||||||
|
{
|
||||||
|
#define VERIFY_EXTRA_READ_TRIES 2
|
||||||
|
|
||||||
|
// Read back the word we just wrote to make sure it's OK...
|
||||||
|
uint32_t readback = ExternalMem_ReadCycle(startAddress) & mask;
|
||||||
|
if (readback != (*buf & mask))
|
||||||
|
{
|
||||||
|
// We found a failure, but don't despair yet. Let's try reading
|
||||||
|
// two more times in case it a fluke of the data toggle polling
|
||||||
|
// algorithm.
|
||||||
|
bool secondFailureFound = false;
|
||||||
|
int try = 0;
|
||||||
|
|
||||||
|
while ((try < VERIFY_EXTRA_READ_TRIES) && !secondFailureFound)
|
||||||
|
{
|
||||||
|
try++;
|
||||||
|
readback = ExternalMem_ReadCycle(startAddress) & mask;
|
||||||
|
if (readback != (*buf & mask))
|
||||||
|
{
|
||||||
|
secondFailureFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we re-read it a few times and it failed again, the write
|
||||||
|
// failed. Otherwise, it was probably just the data toggle
|
||||||
|
// polling algorithm giving us fits.
|
||||||
|
if (secondFailureFound)
|
||||||
|
{
|
||||||
|
uint8_t failMask = 0;
|
||||||
|
// Figure out the mask of chip(s) acting up
|
||||||
|
int x;
|
||||||
|
for (x = 0; x < NUM_CHIPS; x++)
|
||||||
|
{
|
||||||
|
// Is this a chip we're working with?
|
||||||
|
if (chipsMask & (1 << x))
|
||||||
|
{
|
||||||
|
if ((readback & (0xFFUL << (8*x))) != (*buf & (0xFFUL << (8*x))))
|
||||||
|
{
|
||||||
|
// Save the failMask in reverse order
|
||||||
|
// (so bit 0 refers to IC1 rather than IC4)
|
||||||
|
failMask |= (1 << ((NUM_CHIPS - 1) - x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return failMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startAddress++;
|
||||||
|
buf++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalMem_SetChipType(ChipType type)
|
void ExternalMem_SetChipType(ChipType type)
|
||||||
|
@ -101,7 +101,9 @@ void ExternalMem_WriteByteToChips(uint32_t address, uint32_t data, uint8_t chips
|
|||||||
// Writes a buffer to the requested chips simultaneously
|
// Writes a buffer to the requested chips simultaneously
|
||||||
// (each uint32_t contains an 8-bit portion for each chip,
|
// (each uint32_t contains an 8-bit portion for each chip,
|
||||||
// which is masked away if the chip is not requested)
|
// which is masked away if the chip is not requested)
|
||||||
void ExternalMem_Write(uint32_t startAddress, uint32_t *buf, uint32_t len, uint8_t chipsMask);
|
// returns a mask representing the chips acting up (if requested with doVerify)
|
||||||
|
// or 0 on success (or if verification was not requested)
|
||||||
|
uint8_t ExternalMem_Write(uint32_t startAddress, uint32_t *buf, uint32_t len, uint8_t chipsMask, bool doVerify);
|
||||||
|
|
||||||
// Tells which flash command protocol to use
|
// Tells which flash command protocol to use
|
||||||
void ExternalMem_SetChipType(ChipType type);
|
void ExternalMem_SetChipType(ChipType type);
|
||||||
|
@ -43,7 +43,9 @@ typedef enum ProgrammerCommand
|
|||||||
EnterProgrammer,
|
EnterProgrammer,
|
||||||
BootloaderEraseAndWriteProgram,
|
BootloaderEraseAndWriteProgram,
|
||||||
SetSIMMTypePLCC32_2MB,
|
SetSIMMTypePLCC32_2MB,
|
||||||
SetSIMMTypeLarger
|
SetSIMMTypeLarger,
|
||||||
|
SetVerifyWhileWriting,
|
||||||
|
SetNoVerifyWhileWriting
|
||||||
} ProgrammerCommand;
|
} ProgrammerCommand;
|
||||||
|
|
||||||
// After a command is sent, the programmer will always respond with
|
// After a command is sent, the programmer will always respond with
|
||||||
@ -115,6 +117,11 @@ typedef enum ComputerReadReply
|
|||||||
// this one, and then the computer can send a 1024-byte chunk of data.
|
// this one, and then the computer can send a 1024-byte chunk of data.
|
||||||
// The programmer will reply with ProgrammerWriteOK, and then the cycle can
|
// The programmer will reply with ProgrammerWriteOK, and then the cycle can
|
||||||
// continue (the computer sends another request in this enum)
|
// continue (the computer sends another request in this enum)
|
||||||
|
//
|
||||||
|
// If the programmer was asked to verify while writing and a verification error
|
||||||
|
// occurs, it will respond with ProgrammerWriteVerificationError ORed with a bit
|
||||||
|
// mask of chips that are acting up (so it could be 0x81 if IC1 is acting up,
|
||||||
|
// for example)
|
||||||
typedef enum ComputerWriteRequest
|
typedef enum ComputerWriteRequest
|
||||||
{
|
{
|
||||||
ComputerWriteMore = 0,
|
ComputerWriteMore = 0,
|
||||||
@ -126,7 +133,8 @@ typedef enum ProgrammerWriteReply
|
|||||||
{
|
{
|
||||||
ProgrammerWriteOK = 0,
|
ProgrammerWriteOK = 0,
|
||||||
ProgrammerWriteError,
|
ProgrammerWriteError,
|
||||||
ProgrammerWriteConfirmCancel
|
ProgrammerWriteConfirmCancel,
|
||||||
|
ProgrammerWriteVerificationError = 0x80 /* high bit signifies verify error, low bits signify which chips are bad */
|
||||||
} ProgrammerWriteReply;
|
} ProgrammerWriteReply;
|
||||||
|
|
||||||
// ------------------------- BOOTLOADER STATE PROTOCOL -------------------------
|
// ------------------------- BOOTLOADER STATE PROTOCOL -------------------------
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "../tests/simm_electrical_test.h"
|
#include "../tests/simm_electrical_test.h"
|
||||||
#include "../programmer_protocol.h"
|
#include "../programmer_protocol.h"
|
||||||
#include "../led.h"
|
#include "../led.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define MAX_CHIP_SIZE (2UL * 1024UL * 1024UL)
|
#define MAX_CHIP_SIZE (2UL * 1024UL * 1024UL)
|
||||||
#define READ_CHUNK_SIZE_BYTES 1024UL
|
#define READ_CHUNK_SIZE_BYTES 1024UL
|
||||||
@ -64,6 +65,7 @@ static uint32_t readLength;
|
|||||||
static uint8_t readLengthByteIndex;
|
static uint8_t readLengthByteIndex;
|
||||||
static int16_t writePosInChunk = -1;
|
static int16_t writePosInChunk = -1;
|
||||||
static uint16_t curWriteIndex = 0;
|
static uint16_t curWriteIndex = 0;
|
||||||
|
static bool verifyDuringWrite = false;
|
||||||
|
|
||||||
// Private functions
|
// Private functions
|
||||||
void USBSerial_HandleWaitingForCommandByte(uint8_t byte);
|
void USBSerial_HandleWaitingForCommandByte(uint8_t byte);
|
||||||
@ -217,6 +219,14 @@ void USBSerial_HandleWaitingForCommandByte(uint8_t byte)
|
|||||||
ExternalMem_SetChipType(ChipType8Bit16BitData_16MBitSize);
|
ExternalMem_SetChipType(ChipType8Bit16BitData_16MBitSize);
|
||||||
SendByte(CommandReplyOK);
|
SendByte(CommandReplyOK);
|
||||||
break;
|
break;
|
||||||
|
case SetVerifyWhileWriting:
|
||||||
|
verifyDuringWrite = true;
|
||||||
|
SendByte(CommandReplyOK);
|
||||||
|
break;
|
||||||
|
case SetNoVerifyWhileWriting:
|
||||||
|
verifyDuringWrite = false;
|
||||||
|
SendByte(CommandReplyOK);
|
||||||
|
break;
|
||||||
// We don't know what this command is, so reply that it was invalid.
|
// We don't know what this command is, so reply that it was invalid.
|
||||||
default:
|
default:
|
||||||
SendByte(CommandReplyInvalid);
|
SendByte(CommandReplyInvalid);
|
||||||
@ -373,12 +383,25 @@ void USBSerial_HandleWritingChipsByte(uint8_t byte)
|
|||||||
{
|
{
|
||||||
// We filled up the chunk, write it out and confirm it, then wait
|
// We filled up the chunk, write it out and confirm it, then wait
|
||||||
// for the next command from the computer!
|
// for the next command from the computer!
|
||||||
ExternalMem_Write(curWriteIndex * (WRITE_CHUNK_SIZE_BYTES/4),
|
uint8_t writeResult = ExternalMem_Write(curWriteIndex * (WRITE_CHUNK_SIZE_BYTES/4),
|
||||||
chunks.writeChunks, WRITE_CHUNK_SIZE_BYTES/4, ALL_CHIPS);
|
chunks.writeChunks, WRITE_CHUNK_SIZE_BYTES/4, ALL_CHIPS, verifyDuringWrite);
|
||||||
SendByte(ProgrammerWriteOK);
|
|
||||||
curWriteIndex++;
|
// But if we asked to verify, make sure it came out OK.
|
||||||
writePosInChunk = -1;
|
if (verifyDuringWrite && (writeResult != 0))
|
||||||
LED_Toggle();
|
{
|
||||||
|
// Uh oh -- verification failure.
|
||||||
|
LED_Off();
|
||||||
|
// Send the fail bit along with a mask of failed chips.
|
||||||
|
SendByte(ProgrammerWriteVerificationError | writeResult);
|
||||||
|
curCommandState = WaitingForCommand;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendByte(ProgrammerWriteOK);
|
||||||
|
curWriteIndex++;
|
||||||
|
writePosInChunk = -1;
|
||||||
|
LED_Toggle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user