mirror of
https://github.com/dougg3/mac-rom-simm-programmer.git
synced 2024-12-28 13:30:48 +00:00
Added provisions to communication protocol for specifying readback size.
This commit is contained in:
parent
6f24f97df5
commit
7d1888dab8
@ -60,7 +60,10 @@ typedef enum ProgrammerIdentifyReply
|
||||
} ProgrammerIdentifyReply;
|
||||
|
||||
// ------------------------- READ PROTOCOL -------------------------
|
||||
// After CommandReplyOK, the programmer will send a chunk of data.
|
||||
// After CommandReplyOK, the requester will send a 4-byte value containing
|
||||
// the number of bytes requested to read (should be a multiple of the read
|
||||
// chunk size of 1024 bytes, though). The programmer will reply with OK or
|
||||
// error, and if OK, also send a chunk of data.
|
||||
// The computer will send a reply (see the enum below this one)
|
||||
// The programmer will then reply to *that* reply (see this enum)
|
||||
typedef enum ProgrammerReadReply
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "../tests/simm_electrical_test.h"
|
||||
#include "../programmer_protocol.h"
|
||||
|
||||
#define CHIP_SIZE (512UL * 1024UL)
|
||||
#define MAX_CHIP_SIZE (512UL * 1024UL)
|
||||
#define READ_CHUNK_SIZE_BYTES 1024UL
|
||||
#define WRITE_CHUNK_SIZE_BYTES 1024UL
|
||||
#if ((READ_CHUNK_SIZE_BYTES % 4) != 0)
|
||||
@ -32,6 +32,7 @@ typedef enum ProgrammerCommandState
|
||||
{
|
||||
WaitingForCommand = 0,
|
||||
ReadingByteWaitingForAddress,
|
||||
ReadingChipsReadLength,
|
||||
ReadingChips,
|
||||
ReadingChipsUnableSendError,
|
||||
WritingChips
|
||||
@ -41,12 +42,15 @@ static ProgrammerCommandState curCommandState = WaitingForCommand;
|
||||
// State info for reading/writing
|
||||
static uint8_t byteAddressReceiveCount = 0;
|
||||
static uint16_t curReadIndex;
|
||||
static uint32_t readLength;
|
||||
static uint8_t readLengthByteIndex;
|
||||
static int16_t writePosInChunk = -1;
|
||||
static uint16_t curWriteIndex = 0;
|
||||
|
||||
// Private functions
|
||||
void USBSerial_HandleWaitingForCommandByte(uint8_t byte);
|
||||
void USBSerial_HandleReadingChipsByte(uint8_t byte);
|
||||
void USBSerial_HandleReadingChipsReadLengthByte(uint8_t byte);
|
||||
void USBSerial_SendReadDataChunk(void);
|
||||
void USBSerial_HandleWritingChipsByte(uint8_t byte);
|
||||
void USBSerial_ElectricalTest_Fail_Handler(uint8_t index1, uint8_t index2);
|
||||
@ -74,6 +78,9 @@ void USBSerial_Check(void)
|
||||
case WaitingForCommand:
|
||||
USBSerial_HandleWaitingForCommandByte((uint8_t)recvByte);
|
||||
break;
|
||||
case ReadingChipsReadLength:
|
||||
USBSerial_HandleReadingChipsReadLengthByte((uint8_t)recvByte);
|
||||
break;
|
||||
case ReadingChips:
|
||||
USBSerial_HandleReadingChipsByte((uint8_t)recvByte);
|
||||
break;
|
||||
@ -133,10 +140,11 @@ void USBSerial_HandleWaitingForCommandByte(uint8_t byte)
|
||||
break;
|
||||
// Asked to read all four chips. Set the state, reply with the first chunk
|
||||
case ReadChips:
|
||||
curCommandState = ReadingChips;
|
||||
curCommandState = ReadingChipsReadLength;
|
||||
curReadIndex = 0;
|
||||
readLengthByteIndex = 0;
|
||||
readLength = 0;
|
||||
SendByte(CommandReplyOK);
|
||||
USBSerial_SendReadDataChunk();
|
||||
break;
|
||||
// Erase the chips and reply OK. (TODO: Sometimes erase might fail)
|
||||
case EraseChips:
|
||||
@ -197,7 +205,7 @@ void USBSerial_HandleReadingChipsByte(uint8_t byte)
|
||||
case ComputerReadOK:
|
||||
// If they have confirmed the final data chunk, let them know
|
||||
// that they have finished, and enter command state.
|
||||
if (curReadIndex >= (CHIP_SIZE / (READ_CHUNK_SIZE_BYTES/4)))
|
||||
if (curReadIndex >= readLength)
|
||||
{
|
||||
SendByte(ProgrammerReadFinished);
|
||||
curCommandState = WaitingForCommand;
|
||||
@ -217,6 +225,33 @@ void USBSerial_HandleReadingChipsByte(uint8_t byte)
|
||||
}
|
||||
}
|
||||
|
||||
// If we're figuring out the length to read, grab it now...
|
||||
void USBSerial_HandleReadingChipsReadLengthByte(uint8_t byte)
|
||||
{
|
||||
// There will be four bytes, so count up until we know the length. If they
|
||||
// have sent all four bytes, send the first read chunk.
|
||||
readLength |= (((uint32_t)byte) << (8*readLengthByteIndex));
|
||||
if (++readLengthByteIndex >= 4)
|
||||
{
|
||||
// Ensure it's within limits and a multiple of 1024
|
||||
if ((readLength > NUM_CHIPS * MAX_CHIP_SIZE) ||
|
||||
(readLength % READ_CHUNK_SIZE_BYTES) ||
|
||||
(readLength == 0))
|
||||
{
|
||||
SendByte(ProgrammerReadError);
|
||||
curCommandState = WaitingForCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert the length into the number of chunks we need to send
|
||||
readLength /= READ_CHUNK_SIZE_BYTES;
|
||||
curCommandState = ReadingChips;
|
||||
SendByte(ProgrammerReadOK);
|
||||
USBSerial_SendReadDataChunk();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read the next chunk of data from the SIMM and send it off over the serial.
|
||||
void USBSerial_SendReadDataChunk(void)
|
||||
{
|
||||
@ -226,14 +261,14 @@ void USBSerial_SendReadDataChunk(void)
|
||||
// with other functions, but I'm not bothering with that for now.
|
||||
static union
|
||||
{
|
||||
uint32_t readChunks[READ_CHUNK_SIZE_BYTES / 4];
|
||||
uint32_t readChunks[READ_CHUNK_SIZE_BYTES / NUM_CHIPS];
|
||||
uint8_t readChunkBytes[READ_CHUNK_SIZE_BYTES];
|
||||
} chunks;
|
||||
|
||||
// Read the next chunk of data, send it over USB, and make sure
|
||||
// we sent it correctly.
|
||||
ExternalMem_Read(curReadIndex * (READ_CHUNK_SIZE_BYTES/4),
|
||||
chunks.readChunks, READ_CHUNK_SIZE_BYTES/4);
|
||||
ExternalMem_Read(curReadIndex * (READ_CHUNK_SIZE_BYTES/NUM_CHIPS),
|
||||
chunks.readChunks, READ_CHUNK_SIZE_BYTES/NUM_CHIPS);
|
||||
uint8_t retVal = SendData((const char *)chunks.readChunkBytes,
|
||||
READ_CHUNK_SIZE_BYTES);
|
||||
|
||||
@ -273,7 +308,7 @@ void USBSerial_HandleWritingChipsByte(uint8_t byte)
|
||||
case ComputerWriteMore:
|
||||
writePosInChunk = 0;
|
||||
// Make sure we don't write past the capacity of the chips.
|
||||
if (curWriteIndex < CHIP_SIZE / (WRITE_CHUNK_SIZE_BYTES/4))
|
||||
if (curWriteIndex < MAX_CHIP_SIZE / (WRITE_CHUNK_SIZE_BYTES/4))
|
||||
{
|
||||
SendByte(ProgrammerWriteOK);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user