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 #define HIGHEST_ADDRESS_LINE 20
// Default setup
static ChipType curChipType = ChipType8BitData_4MBitSize;
// Private functions // Private functions
uint32_t ExternalMem_MaskForChips(uint8_t chips); uint32_t ExternalMem_MaskForChips(uint8_t chips);
void ExternalMem_WaitCompletion(uint8_t chipsMask); 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 // Use a mask so we don't unlock chips we don't want to talk with
uint32_t mask = ExternalMem_MaskForChips(chipsMask); uint32_t mask = ExternalMem_MaskForChips(chipsMask);
// First part of unlock sequence: // The unlock sequence changes depending on the chip
// Write 0x55555555 to the address bus and 0xAA to the data bus if (curChipType == ChipType8BitData_4MBitSize)
// (Some datasheets may only say 0x555 or 0x5555, but they ignore {
// the upper bits, so writing the alternating pattern to all address lines // First part of unlock sequence:
// should make it compatible with larger chips) // Write 0x55555555 to the address bus and 0xAA to the data bus
ExternalMem_WriteCycle(0x55555555UL, 0xAAAAAAAAUL & mask); // (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. // Second part of unlock sequence is the same thing, but reversed.
ExternalMem_WriteCycle(0xAAAAAAAAUL, 0x55555555UL & mask); 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) void ExternalMem_IdentifyChips(struct ChipID *chips)
@@ -180,7 +199,16 @@ void ExternalMem_IdentifyChips(struct ChipID *chips)
ExternalMem_UnlockChips(ALL_CHIPS); ExternalMem_UnlockChips(ALL_CHIPS);
// Write 0x90 to 0x55555555 for the identify command... // 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 // Now we can read the vendor and product ID
uint32_t result = ExternalMem_ReadCycle(0); uint32_t result = ExternalMem_ReadCycle(0);
@@ -204,9 +232,23 @@ void ExternalMem_IdentifyChips(struct ChipID *chips)
void ExternalMem_EraseChips(uint8_t chipsMask) void ExternalMem_EraseChips(uint8_t chipsMask)
{ {
ExternalMem_UnlockChips(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_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); 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); uint32_t mask = ExternalMem_MaskForChips(chipsMask);
ExternalMem_UnlockChips(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_WriteCycle(address, data & mask);
ExternalMem_WaitCompletion(chipsMask); 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); 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 IC4 (1 << 0)
#define ALL_CHIPS (IC1 | IC2 | IC3 | IC4) #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 // Initializes the (bit-banged) external memory interface
void ExternalMem_Init(void); 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) // 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); 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_ */ #endif /* EXTERNAL_MEM_H_ */

View File

@@ -41,7 +41,9 @@ typedef enum ProgrammerCommand
GetBootloaderState, GetBootloaderState,
EnterBootloader, EnterBootloader,
EnterProgrammer, EnterProgrammer,
BootloaderEraseAndWriteProgram BootloaderEraseAndWriteProgram,
SetSIMMTypePLCC32_2MB,
SetSIMMTypeLarger
} 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

@@ -208,6 +208,15 @@ void USBSerial_HandleWaitingForCommandByte(uint8_t byte)
// Already in the programmer // Already in the programmer
SendByte(CommandReplyOK); SendByte(CommandReplyOK);
break; 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. // We don't know what this command is, so reply that it was invalid.
default: default:
SendByte(CommandReplyInvalid); SendByte(CommandReplyInvalid);