mirror of
https://github.com/dougg3/mac-rom-simm-programmer.git
synced 2025-08-15 18:27:36 +00:00
Added support for (untested yet) 8 MB ROM SIMM with chips that expect a
slightly different programming protocol.
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
@@ -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_ */
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user