Finished implementing protocols for reading/writing portions of the SIMM

This commit is contained in:
Doug Brown
2012-10-17 21:31:00 -07:00
parent bf583bf65b
commit 0ebb9d2281
2 changed files with 77 additions and 10 deletions

View File

@@ -46,7 +46,9 @@ typedef enum ProgrammerCommand
SetSIMMTypeLarger, SetSIMMTypeLarger,
SetVerifyWhileWriting, SetVerifyWhileWriting,
SetNoVerifyWhileWriting, SetNoVerifyWhileWriting,
ErasePortion ErasePortion,
WriteChipsAt,
ReadChipsAt
} ProgrammerCommand; } ProgrammerCommand;
// After a command is sent, the programmer will always respond with // After a command is sent, the programmer will always respond with

View File

@@ -56,7 +56,9 @@ typedef enum ProgrammerCommandState
ReadingChips, ReadingChips,
ReadingChipsUnableSendError, ReadingChipsUnableSendError,
WritingChips, WritingChips,
ErasePortionReadingPosLength ErasePortionReadingPosLength,
ReadingChipsReadStartPos,
WritingChipsReadingStartPos,
} ProgrammerCommandState; } ProgrammerCommandState;
static ProgrammerCommandState curCommandState = WaitingForCommand; static ProgrammerCommandState curCommandState = WaitingForCommand;
@@ -79,6 +81,8 @@ void USBSerial_SendReadDataChunk(void);
void USBSerial_HandleWritingChipsByte(uint8_t byte); void USBSerial_HandleWritingChipsByte(uint8_t byte);
void USBSerial_ElectricalTest_Fail_Handler(uint8_t index1, uint8_t index2); void USBSerial_ElectricalTest_Fail_Handler(uint8_t index1, uint8_t index2);
void USBSerial_HandleErasePortionReadPosLengthByte(uint8_t byte); void USBSerial_HandleErasePortionReadPosLengthByte(uint8_t byte);
void USBSerial_HandleReadingChipsReadStartPosByte(uint8_t byte);
void USBSerial_HandleWritingChipsReadingStartPosByte(uint8_t byte);
// Read/write to USB serial macros -- easier than retyping // Read/write to USB serial macros -- easier than retyping
// CDC_Device_XXX(&VirtualSerial_CDC_Interface...) every time // CDC_Device_XXX(&VirtualSerial_CDC_Interface...) every time
@@ -115,6 +119,12 @@ void USBSerial_Check(void)
case ErasePortionReadingPosLength: case ErasePortionReadingPosLength:
USBSerial_HandleErasePortionReadPosLengthByte((uint8_t)recvByte); USBSerial_HandleErasePortionReadPosLengthByte((uint8_t)recvByte);
break; break;
case ReadingChipsReadStartPos:
USBSerial_HandleReadingChipsReadStartPosByte((uint8_t)recvByte);
break;
case WritingChipsReadingStartPos:
USBSerial_HandleWritingChipsReadingStartPosByte((uint8_t)recvByte);
break;
} }
} }
} }
@@ -166,7 +176,9 @@ void USBSerial_HandleWaitingForCommandByte(uint8_t byte)
byteAddressReceiveCount = 0; byteAddressReceiveCount = 0;
SendByte(CommandReplyOK); SendByte(CommandReplyOK);
break; break;
// Asked to read all four chips. Set the state, reply with the first chunk // Asked to read all four chips. Set the state, reply with the first chunk.
// This will read from the BEGINNING of the SIMM every time. Use
// ReadChipsAt to specify a start position
case ReadChips: case ReadChips:
curCommandState = ReadingChipsReadLength; curCommandState = ReadingChipsReadLength;
curReadIndex = 0; curReadIndex = 0;
@@ -174,6 +186,13 @@ void USBSerial_HandleWaitingForCommandByte(uint8_t byte)
readLength = 0; readLength = 0;
SendByte(CommandReplyOK); SendByte(CommandReplyOK);
break; break;
case ReadChipsAt:
curCommandState = ReadingChipsReadStartPos;
curReadIndex = 0;
readLengthByteIndex = 0;
readLength = 0;
SendByte(CommandReplyOK);
break;
// Erase the chips and reply OK. (TODO: Sometimes erase might fail) // Erase the chips and reply OK. (TODO: Sometimes erase might fail)
case EraseChips: case EraseChips:
ExternalMem_EraseChips(ALL_CHIPS); ExternalMem_EraseChips(ALL_CHIPS);
@@ -186,6 +205,13 @@ void USBSerial_HandleWaitingForCommandByte(uint8_t byte)
writePosInChunk = -1; writePosInChunk = -1;
SendByte(CommandReplyOK); SendByte(CommandReplyOK);
break; break;
case WriteChipsAt:
curCommandState = WritingChipsReadingStartPos;
curWriteIndex = 0;
readLengthByteIndex = 0;
writePosInChunk = -1;
SendByte(CommandReplyOK);
break;
// Asked for the current bootloader state. We are in the program right now, // Asked for the current bootloader state. We are in the program right now,
// so reply accordingly. // so reply accordingly.
case GetBootloaderState: case GetBootloaderState:
@@ -292,17 +318,19 @@ void USBSerial_HandleReadingChipsReadLengthByte(uint8_t byte)
if (++readLengthByteIndex >= 4) if (++readLengthByteIndex >= 4)
{ {
// Ensure it's within limits and a multiple of 1024 // Ensure it's within limits and a multiple of 1024
if ((readLength > NUM_CHIPS * MAX_CHIP_SIZE) || if ((curReadIndex + readLength > NUM_CHIPS * MAX_CHIP_SIZE) ||
(readLength % READ_CHUNK_SIZE_BYTES) || (readLength % READ_CHUNK_SIZE_BYTES) ||
(readLength == 0)) (curReadIndex % READ_CHUNK_SIZE_BYTES) ||
(readLength == 0))// Ensure it's within limits and a multiple of 1024
{ {
SendByte(ProgrammerReadError); SendByte(ProgrammerReadError);
curCommandState = WaitingForCommand; curCommandState = WaitingForCommand;
} }
else else
{ {
// Convert the length into the number of chunks we need to send // Convert the length/pos into the number of chunks we need to send
readLength /= READ_CHUNK_SIZE_BYTES; readLength /= READ_CHUNK_SIZE_BYTES;
curReadIndex /= READ_CHUNK_SIZE_BYTES;
curCommandState = ReadingChips; curCommandState = ReadingChips;
SendByte(ProgrammerReadOK); SendByte(ProgrammerReadOK);
USBSerial_SendReadDataChunk(); USBSerial_SendReadDataChunk();
@@ -366,14 +394,15 @@ void USBSerial_HandleWritingChipsByte(uint8_t byte)
case ComputerWriteMore: case ComputerWriteMore:
writePosInChunk = 0; writePosInChunk = 0;
// Make sure we don't write past the capacity of the chips. // Make sure we don't write past the capacity of the chips.
if (curWriteIndex < MAX_CHIP_SIZE / (WRITE_CHUNK_SIZE_BYTES/4)) if (curWriteIndex < MAX_CHIP_SIZE / (WRITE_CHUNK_SIZE_BYTES/NUM_CHIPS))
{ {
SendByte(ProgrammerWriteOK); SendByte(ProgrammerWriteOK);
} }
else else
{ {
LED_Off();
SendByte(ProgrammerWriteError); SendByte(ProgrammerWriteError);
// TODO: Enter waiting for command mode? curCommandState = WaitingForCommand;
} }
break; break;
// The computer said that it's done writing. // The computer said that it's done writing.
@@ -398,8 +427,8 @@ 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!
uint8_t writeResult = ExternalMem_Write(curWriteIndex * (WRITE_CHUNK_SIZE_BYTES/4), uint8_t writeResult = ExternalMem_Write(curWriteIndex * (WRITE_CHUNK_SIZE_BYTES/NUM_CHIPS),
chunks.writeChunks, WRITE_CHUNK_SIZE_BYTES/4, ALL_CHIPS, verifyDuringWrite); chunks.writeChunks, WRITE_CHUNK_SIZE_BYTES/NUM_CHIPS, ALL_CHIPS, verifyDuringWrite);
// But if we asked to verify, make sure it came out OK. // But if we asked to verify, make sure it came out OK.
if (verifyDuringWrite && (writeResult != 0)) if (verifyDuringWrite && (writeResult != 0))
@@ -501,6 +530,42 @@ void USBSerial_HandleErasePortionReadPosLengthByte(uint8_t byte)
} }
} }
void USBSerial_HandleReadingChipsReadStartPosByte(uint8_t byte)
{
// There will be four bytes, so count up until we know the position. If they
// have sent all four bytes, then start reading the length
curReadIndex |= (((uint32_t)byte) << (8*readLengthByteIndex));
if (++readLengthByteIndex >= 4)
{
readLengthByteIndex = 0;
curCommandState = ReadingChipsReadLength;
}
}
void USBSerial_HandleWritingChipsReadingStartPosByte(uint8_t byte)
{
// There will be four bytes, so count up until we know the position. If they
// have sent all four bytes, then confirm the write and begin
curWriteIndex |= (((uint32_t)byte) << (8*readLengthByteIndex));
if (++readLengthByteIndex >= 4)
{
// Got it...now, is it valid? If so, allow the write to begin
if ((curWriteIndex % WRITE_CHUNK_SIZE_BYTES) ||
(curWriteIndex >= NUM_CHIPS * MAX_CHIP_SIZE))
{
SendByte(ProgrammerWriteError);
curCommandState = WaitingForCommand;
}
else
{
// Convert write size into an index appropriate for rest of code
curWriteIndex /= WRITE_CHUNK_SIZE_BYTES;
SendByte(ProgrammerWriteOK);
curCommandState = WritingChips;
}
}
}
// LUFA event handler for when the USB configuration changes. // LUFA event handler for when the USB configuration changes.
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {