Started working on more optimizations, but something weird is happening and it's crashing...not sure why yet.

This commit is contained in:
Doug Brown 2011-12-11 21:48:26 -08:00
parent 1c07518ab0
commit 4adb0c4980
5 changed files with 120 additions and 24 deletions

View File

@ -67,7 +67,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x204B, .ProductID = 0x204B,
.ReleaseNumber = VERSION_BCD(00.01), .ReleaseNumber = VERSION_BCD(00.02),
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
@ -95,7 +95,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(500)
}, },
.CDC_CCI_Interface = .CDC_CCI_Interface =

View File

@ -45,9 +45,10 @@ void ExternalMem_Init(void)
Ports_SetWEDDR(1); Ports_SetWEDDR(1);
// Default all control lines to high (de-asserted) // Default all control lines to high (de-asserted)
ExternalMem_DeassertCS(); /*ExternalMem_DeassertCS();
ExternalMem_DeassertOE(); ExternalMem_DeassertOE();
ExternalMem_DeassertWE(); ExternalMem_DeassertWE();*/
ExternalMem_Deassert(SIMM_CS | SIMM_OE | SIMM_WE);
} }
void ExternalMem_SetAddress(uint32_t address) void ExternalMem_SetAddress(uint32_t address)
@ -84,7 +85,7 @@ uint32_t ExternalMem_ReadData(void)
//return (uint32_t)PINE | (((uint32_t)PINF) << 8); //return (uint32_t)PINE | (((uint32_t)PINF) << 8);
} }
void ExternalMem_AssertCS(void) /*void ExternalMem_AssertCS(void)
{ {
Ports_SetCSOut(0); Ports_SetCSOut(0);
} }
@ -112,16 +113,18 @@ void ExternalMem_AssertOE(void)
void ExternalMem_DeassertOE(void) void ExternalMem_DeassertOE(void)
{ {
Ports_SetOEOut(1); Ports_SetOEOut(1);
} }*/
void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len) void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len)
{ {
// This is just a time saver if we know we will // This is just a time saver if we know we will
// be reading a complete block -- doesn't bother // be reading a complete block -- doesn't bother
// playing with the control lines between each byte // playing with the control lines between each byte
ExternalMem_DeassertWE(); //ExternalMem_DeassertWE();
ExternalMem_AssertCS(); //ExternalMem_AssertCS();
ExternalMem_AssertOE(); //ExternalMem_AssertOE();
ExternalMem_Deassert(SIMM_WE);
ExternalMem_Assert(SIMM_CS | SIMM_OE);
ExternalMem_SetDataAsInput(); ExternalMem_SetDataAsInput();
while (len--) while (len--)
@ -144,25 +147,32 @@ void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len)
void ExternalMem_WriteCycle(uint32_t address, uint32_t data) void ExternalMem_WriteCycle(uint32_t address, uint32_t data)
{ {
ExternalMem_AssertCS(); /*ExternalMem_AssertCS();
ExternalMem_DeassertOE(); ExternalMem_DeassertOE();*/
ExternalMem_Assert(SIMM_CS);
ExternalMem_Deassert(SIMM_OE | SIMM_WE);
ExternalMem_SetAddressAndData(address, data); ExternalMem_SetAddressAndData(address, data);
ExternalMem_AssertWE(); ExternalMem_Assert(SIMM_WE);
//ExternalMem_AssertWE();
//_delay_us(1); // Give it a small amount of time needed? Could I do this with some NOP instructions instead of waiting 1us? //_delay_us(1); // Give it a small amount of time needed? Could I do this with some NOP instructions instead of waiting 1us?
// The minimum pulse time is 50 ns or so, and since one clock cycle is // The minimum pulse time is 50 ns or so, and since one clock cycle is
// 62.5 ns, this should be fine to assert and deassert immediately // 62.5 ns, this should be fine to assert and deassert immediately
ExternalMem_DeassertWE(); //ExternalMem_DeassertWE();
ExternalMem_Deassert(SIMM_WE);
} }
uint32_t ExternalMem_ReadCycle(uint32_t address) uint32_t ExternalMem_ReadCycle(uint32_t address)
{ {
ExternalMem_DeassertWE(); //ExternalMem_DeassertWE();
ExternalMem_AssertCS(); //ExternalMem_AssertCS();
ExternalMem_AssertOE(); //ExternalMem_AssertOE();
ExternalMem_Deassert(SIMM_WE);
ExternalMem_Assert(SIMM_CS | SIMM_OE);
ExternalMem_SetDataAsInput(); ExternalMem_SetDataAsInput();
ExternalMem_SetAddress(address); ExternalMem_SetAddress(address);
uint32_t tmp = ExternalMem_ReadData(); uint32_t tmp = ExternalMem_ReadData();
ExternalMem_DeassertOE(); //ExternalMem_DeassertOE();
ExternalMem_Deassert(SIMM_OE);
return tmp; return tmp;
} }
@ -248,15 +258,73 @@ void ExternalMem_EraseChips(uint8_t chipsMask)
void ExternalMem_WaitCompletion(uint8_t chipsMask) void ExternalMem_WaitCompletion(uint8_t chipsMask)
{ {
//_delay_us(18);
//#if 0
// Mark the chips not requested as already completed, // Mark the chips not requested as already completed,
// so we don't end up waiting for them... // so we don't end up waiting for them...
// (We probably wouldn't anyway, but this is just // (We probably wouldn't anyway, but this is just
// to be safe) // to be safe)
uint8_t erasedChipsMask = ~chipsMask & 0x0F; uint8_t doneChipsMask = ~chipsMask & 0x0F;
// Prime the loop... // Prime the loop...
//union
//{
// uint32_t word;
// uint8_t bytes[4];
//} lastBits, tmp;
uint32_t lastBits = ExternalMem_ReadCycle(0); uint32_t lastBits = ExternalMem_ReadCycle(0);
while (erasedChipsMask != 0x0F)
//lastBits.word = ExternalMem_ReadCycle(0);
while (doneChipsMask != 0x0F)
{ {
/*#define TOGGLE_BIT 0x40
tmp.word = ExternalMem_ReadCycle(0);
// Note: The following assumes little endian byte ordering
// (e.g. tmpBytes[0] is the least significant byte of tmpWord
// Has this chip completed its operation? No?
if ((doneChipsMask & (1 << 0)) == 0)
{
// No toggle means erase completed
if ((tmp.bytes[0] & TOGGLE_BIT) == (lastBits.bytes[0] & TOGGLE_BIT))
{
doneChipsMask |= (1 << 0);
}
}
if ((doneChipsMask & (1 << 1)) == 0)
{
// No toggle means erase completed
if ((tmp.bytes[1] & TOGGLE_BIT) == (lastBits.bytes[1] & TOGGLE_BIT))
{
doneChipsMask |= (1 << 1);
}
}
if ((doneChipsMask & (1 << 2)) == 0)
{
// No toggle means erase completed
if ((tmp.bytes[2] & TOGGLE_BIT) == (lastBits.bytes[2] & TOGGLE_BIT))
{
doneChipsMask |= (1 << 2);
}
}
if ((doneChipsMask & (1 << 3)) == 0)
{
// No toggle means erase completed
if ((tmp.bytes[3] & TOGGLE_BIT) == (lastBits.bytes[3] & TOGGLE_BIT))
{
doneChipsMask |= (1 << 3);
}
}
lastBits.word = tmp.word;*/
// Compare the toggle bit to see if it didn't toggle // Compare the toggle bit to see if it didn't toggle
uint32_t tmp = ExternalMem_ReadCycle(0); uint32_t tmp = ExternalMem_ReadCycle(0);
uint32_t mask = 0x00000040UL; uint32_t mask = 0x00000040UL;
@ -266,7 +334,7 @@ void ExternalMem_WaitCompletion(uint8_t chipsMask)
// No toggle means erase completed // No toggle means erase completed
if ((tmp & mask) == (lastBits & mask)) if ((tmp & mask) == (lastBits & mask))
{ {
erasedChipsMask |= (1 << x); doneChipsMask |= (1 << x);
} }
} }
@ -276,6 +344,7 @@ void ExternalMem_WaitCompletion(uint8_t chipsMask)
// Keep going until all four chips have gone // Keep going until all four chips have gone
// without toggling // without toggling
} }
//#endif
} }
void ExternalMem_WriteByteToChips(uint32_t address, uint32_t data, uint8_t chipsMask) void ExternalMem_WriteByteToChips(uint32_t address, uint32_t data, uint8_t chipsMask)

View File

@ -25,6 +25,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)
// I feel kind of sick making these available to the outside world, but
// I'm doing it for efficiency.
// These are the bits on port B corresponding to the control signals.
// Pass them to ExternalMem_Assert() or ExternalMem_Deassert().
#define SIMM_WE (1 << 6)
#define SIMM_OE (1 << 5)
#define SIMM_CS (1 << 4)
// Initializes the (bit-banged) external memory interface // Initializes the (bit-banged) external memory interface
void ExternalMem_Init(void); void ExternalMem_Init(void);
@ -43,7 +51,7 @@ void ExternalMem_SetDataAsInput(void);
// Reads back the value the chips are putting onto the data lines // Reads back the value the chips are putting onto the data lines
uint32_t ExternalMem_ReadData(void); uint32_t ExternalMem_ReadData(void);
// Sets the state of the chip select line /*// Sets the state of the chip select line
void ExternalMem_AssertCS(void); void ExternalMem_AssertCS(void);
void ExternalMem_DeassertCS(void); void ExternalMem_DeassertCS(void);
@ -53,7 +61,13 @@ void ExternalMem_DeassertWE(void);
// Sets the state of the output enable line // Sets the state of the output enable line
void ExternalMem_AssertOE(void); void ExternalMem_AssertOE(void);
void ExternalMem_DeassertOE(void); void ExternalMem_DeassertOE(void);*/
// This is not the nicest-looking software engineering practice
// in the world, but it saves needlessly wasted CPU cycles
// that would be wasted in layers upon layers of abstraction
#define ExternalMem_Assert(assertMask) PORTB &= ~(assertMask);
#define ExternalMem_Deassert(assertMask) PORTB |= (assertMask);
// Reads a set of data from all 4 chips simultaneously // Reads a set of data from all 4 chips simultaneously
void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len); void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len);

4
main.c
View File

@ -21,8 +21,8 @@ int main(void)
ExternalMem_Init(); ExternalMem_Init();
ExternalMem_SetAddress(0); ExternalMem_SetAddress(0);
ExternalMem_AssertCS(); ExternalMem_Assert(SIMM_CS | SIMM_OE);
ExternalMem_AssertOE(); ExternalMem_Deassert(SIMM_WE);
USBSerial_Init(); USBSerial_Init();
sei(); sei();

View File

@ -136,6 +136,19 @@ void USBSerial_Check(void)
sprintf(tmp, "%d errors\r\n", result); sprintf(tmp, "%d errors\r\n", result);
CDC_Device_SendString(&VirtualSerial_CDC_Interface, tmp); CDC_Device_SendString(&VirtualSerial_CDC_Interface, tmp);
} }
else if (rb == 'a')
{
uint32_t x;
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "Reading...\r\n");
CDC_Device_Flush(&VirtualSerial_CDC_Interface);
for (x = 0; x < 512UL*1024UL; x++)
{
ExternalMem_ReadCycle(x);
}
CDC_Device_SendString(&VirtualSerial_CDC_Interface, "Finished\r\n");
}
} }
} }