Added support for (untested yet) 8 MB ROM SIMM with chips that expect a

slightly different programming protocol.
This commit is contained in:
Doug Brown 2012-09-02 15:56:49 -07:00
parent 533813e949
commit 7acb3ffcc3
4 changed files with 89 additions and 13 deletions

View File

@ -29,6 +29,9 @@
#define HIGHEST_ADDRESS_LINE 20
// Default setup
static ChipType curChipType = ChipType8BitData_4MBitSize;
// Private functions
uint32_t ExternalMem_MaskForChips(uint8_t chips);
void ExternalMem_WaitCompletion(uint8_t chipsMask);
@ -163,15 +166,31 @@ void ExternalMem_UnlockChips(uint8_t chipsMask)
// Use a mask so we don't unlock chips we don't want to talk with
uint32_t mask = ExternalMem_MaskForChips(chipsMask);
// First part of unlock sequence:
// Write 0x55555555 to the address bus and 0xAA to the data bus
// (Some datasheets may only say 0x555 or 0x5555, but they ignore
// the upper bits, so writing the alternating pattern to all address lines
// should make it compatible with larger chips)
ExternalMem_WriteCycle(0x55555555UL, 0xAAAAAAAAUL & mask);
// The unlock sequence changes depending on the chip
if (curChipType == ChipType8BitData_4MBitSize)
{
// First part of unlock sequence:
// Write 0x55555555 to the address bus and 0xAA to the data bus
// (Some datasheets may only say 0x555 or 0x5555, but they ignore
// the upper bits, so writing the alternating pattern to all address lines
// should make it compatible with larger chips)
ExternalMem_WriteCycle(0x55555555UL, 0xAAAAAAAAUL & mask);
// Second part of unlock sequence is the same thing, but reversed.
ExternalMem_WriteCycle(0xAAAAAAAAUL, 0x55555555UL & mask);
// Second part of unlock sequence is the same thing, but reversed.
ExternalMem_WriteCycle(0xAAAAAAAAUL, 0x55555555UL & mask);
}
// The protocol is slightly different for 8/16-bit devices in 8-bit mode:
else if (curChipType == ChipType8Bit16BitData_16MBitSize)
{
// First part of unlock sequence:
// Write 0xAAAAAAAA to the address bus and 0xAA to the data bus
ExternalMem_WriteCycle(0xAAAAAAAAUL, 0xAAAAAAAAUL & mask);
// Second part of unlock sequence is the reversed pattern.
ExternalMem_WriteCycle(0x55555555UL, 0x55555555UL & mask);
}
// shouldn't ever be a value other than those two, so I'm not writing
// any extra code for that case.
}
void ExternalMem_IdentifyChips(struct ChipID *chips)
@ -180,7 +199,16 @@ void ExternalMem_IdentifyChips(struct ChipID *chips)
ExternalMem_UnlockChips(ALL_CHIPS);
// Write 0x90 to 0x55555555 for the identify command...
ExternalMem_WriteCycle(0x55555555UL, 0x90909090UL);
if (curChipType == ChipType8BitData_4MBitSize)
{
ExternalMem_WriteCycle(0x55555555UL, 0x90909090UL);
}
else if (curChipType == ChipType8Bit16BitData_16MBitSize)
{
ExternalMem_WriteCycle(0xAAAAAAAAUL, 0x90909090UL);
}
// shouldn't ever be a value other than those two, so I'm not writing
// any extra code for that case.
// Now we can read the vendor and product ID
uint32_t result = ExternalMem_ReadCycle(0);
@ -204,9 +232,23 @@ void ExternalMem_IdentifyChips(struct ChipID *chips)
void ExternalMem_EraseChips(uint8_t chipsMask)
{
ExternalMem_UnlockChips(chipsMask);
ExternalMem_WriteCycle(0x55555555UL, 0x80808080UL);
if (curChipType == ChipType8BitData_4MBitSize)
{
ExternalMem_WriteCycle(0x55555555UL, 0x80808080UL);
}
else if (curChipType == ChipType8Bit16BitData_16MBitSize)
{
ExternalMem_WriteCycle(0xAAAAAAAAUL, 0x80808080UL);
}
ExternalMem_UnlockChips(chipsMask);
ExternalMem_WriteCycle(0x55555555UL, 0x10101010UL);
if (curChipType == ChipType8BitData_4MBitSize)
{
ExternalMem_WriteCycle(0x55555555UL, 0x10101010UL);
}
else if (curChipType == ChipType8Bit16BitData_16MBitSize)
{
ExternalMem_WriteCycle(0xAAAAAAAAUL, 0x10101010UL);
}
ExternalMem_WaitCompletion(chipsMask);
}
@ -282,7 +324,14 @@ void ExternalMem_WriteByteToChips(uint32_t address, uint32_t data, uint8_t chips
uint32_t mask = ExternalMem_MaskForChips(chipsMask);
ExternalMem_UnlockChips(chipsMask);
ExternalMem_WriteCycle(0x55555555UL, 0xA0A0A0A0UL & mask);
if (curChipType == ChipType8BitData_4MBitSize)
{
ExternalMem_WriteCycle(0x55555555UL, 0xA0A0A0A0UL & mask);
}
else if (curChipType == ChipType8Bit16BitData_16MBitSize)
{
ExternalMem_WriteCycle(0xAAAAAAAAUL, 0xA0A0A0A0UL & mask);
}
ExternalMem_WriteCycle(address, data & mask);
ExternalMem_WaitCompletion(chipsMask);
}
@ -294,3 +343,8 @@ void ExternalMem_Write(uint32_t startAddress, uint32_t *buf, uint32_t len, uint8
ExternalMem_WriteByteToChips(startAddress++, *buf++, chipsMask);
}
}
void ExternalMem_SetChipType(ChipType type)
{
curChipType = type;
}

View File

@ -45,6 +45,14 @@ struct ChipID
#define IC4 (1 << 0)
#define ALL_CHIPS (IC1 | IC2 | IC3 | IC4)
// Type of SIMM currently being addressed -- determines command protocol used
// to talk to the chips
typedef enum ChipType
{
ChipType8BitData_4MBitSize, /* 512Kbit to 2Mbit flash, 8-bit */
ChipType8Bit16BitData_16MBitSize /* 16Mbit flash, 8/16-bit in 8-bit mode */
} ChipType;
// Initializes the (bit-banged) external memory interface
void ExternalMem_Init(void);
@ -95,4 +103,7 @@ void ExternalMem_WriteByteToChips(uint32_t address, uint32_t data, uint8_t chips
// 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);
// Tells which flash command protocol to use
void ExternalMem_SetChipType(ChipType type);
#endif /* EXTERNAL_MEM_H_ */

View File

@ -41,7 +41,9 @@ typedef enum ProgrammerCommand
GetBootloaderState,
EnterBootloader,
EnterProgrammer,
BootloaderEraseAndWriteProgram
BootloaderEraseAndWriteProgram,
SetSIMMTypePLCC32_2MB,
SetSIMMTypeLarger
} ProgrammerCommand;
// After a command is sent, the programmer will always respond with

View File

@ -208,6 +208,15 @@ void USBSerial_HandleWaitingForCommandByte(uint8_t byte)
// Already in the programmer
SendByte(CommandReplyOK);
break;
// Set the SIMM type to the older, smaller chip size (2MB and below)
case SetSIMMTypePLCC32_2MB:
ExternalMem_SetChipType(ChipType8BitData_4MBitSize);
SendByte(CommandReplyOK);
break;
case SetSIMMTypeLarger:
ExternalMem_SetChipType(ChipType8Bit16BitData_16MBitSize);
SendByte(CommandReplyOK);
break;
// We don't know what this command is, so reply that it was invalid.
default:
SendByte(CommandReplyInvalid);