diff --git a/Descriptors.c b/Descriptors.c index 79152b7..d005f10 100644 --- a/Descriptors.c +++ b/Descriptors.c @@ -67,7 +67,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = .VendorID = 0x03EB, .ProductID = 0x204B, - .ReleaseNumber = VERSION_BCD(00.01), + .ReleaseNumber = VERSION_BCD(00.02), .ManufacturerStrIndex = 0x01, .ProductStrIndex = 0x02, @@ -95,7 +95,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = .ConfigAttributes = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED), - .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) + .MaxPowerConsumption = USB_CONFIG_POWER_MA(500) }, .CDC_CCI_Interface = diff --git a/external_mem.c b/external_mem.c index 9b5960b..0eea697 100644 --- a/external_mem.c +++ b/external_mem.c @@ -45,9 +45,10 @@ void ExternalMem_Init(void) Ports_SetWEDDR(1); // Default all control lines to high (de-asserted) - ExternalMem_DeassertCS(); + /*ExternalMem_DeassertCS(); ExternalMem_DeassertOE(); - ExternalMem_DeassertWE(); + ExternalMem_DeassertWE();*/ + ExternalMem_Deassert(SIMM_CS | SIMM_OE | SIMM_WE); } void ExternalMem_SetAddress(uint32_t address) @@ -84,7 +85,7 @@ uint32_t ExternalMem_ReadData(void) //return (uint32_t)PINE | (((uint32_t)PINF) << 8); } -void ExternalMem_AssertCS(void) +/*void ExternalMem_AssertCS(void) { Ports_SetCSOut(0); } @@ -112,16 +113,18 @@ void ExternalMem_AssertOE(void) void ExternalMem_DeassertOE(void) { Ports_SetOEOut(1); -} +}*/ void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len) { // This is just a time saver if we know we will // be reading a complete block -- doesn't bother // playing with the control lines between each byte - ExternalMem_DeassertWE(); - ExternalMem_AssertCS(); - ExternalMem_AssertOE(); + //ExternalMem_DeassertWE(); + //ExternalMem_AssertCS(); + //ExternalMem_AssertOE(); + ExternalMem_Deassert(SIMM_WE); + ExternalMem_Assert(SIMM_CS | SIMM_OE); ExternalMem_SetDataAsInput(); 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) { - ExternalMem_AssertCS(); - ExternalMem_DeassertOE(); + /*ExternalMem_AssertCS(); + ExternalMem_DeassertOE();*/ + ExternalMem_Assert(SIMM_CS); + ExternalMem_Deassert(SIMM_OE | SIMM_WE); 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? // 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 - ExternalMem_DeassertWE(); + //ExternalMem_DeassertWE(); + ExternalMem_Deassert(SIMM_WE); } uint32_t ExternalMem_ReadCycle(uint32_t address) { - ExternalMem_DeassertWE(); - ExternalMem_AssertCS(); - ExternalMem_AssertOE(); + //ExternalMem_DeassertWE(); + //ExternalMem_AssertCS(); + //ExternalMem_AssertOE(); + ExternalMem_Deassert(SIMM_WE); + ExternalMem_Assert(SIMM_CS | SIMM_OE); ExternalMem_SetDataAsInput(); ExternalMem_SetAddress(address); uint32_t tmp = ExternalMem_ReadData(); - ExternalMem_DeassertOE(); + //ExternalMem_DeassertOE(); + ExternalMem_Deassert(SIMM_OE); return tmp; } @@ -248,15 +258,73 @@ void ExternalMem_EraseChips(uint8_t chipsMask) void ExternalMem_WaitCompletion(uint8_t chipsMask) { + //_delay_us(18); + + //#if 0 // Mark the chips not requested as already completed, // so we don't end up waiting for them... // (We probably wouldn't anyway, but this is just // to be safe) - uint8_t erasedChipsMask = ~chipsMask & 0x0F; + uint8_t doneChipsMask = ~chipsMask & 0x0F; + // Prime the loop... + //union + //{ + // uint32_t word; + // uint8_t bytes[4]; + //} lastBits, tmp; + 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 uint32_t tmp = ExternalMem_ReadCycle(0); uint32_t mask = 0x00000040UL; @@ -266,7 +334,7 @@ void ExternalMem_WaitCompletion(uint8_t chipsMask) // No toggle means erase completed 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 // without toggling } +//#endif } void ExternalMem_WriteByteToChips(uint32_t address, uint32_t data, uint8_t chipsMask) diff --git a/external_mem.h b/external_mem.h index 656d55b..34df692 100644 --- a/external_mem.h +++ b/external_mem.h @@ -25,6 +25,14 @@ struct ChipID #define IC4 (1 << 0) #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 void ExternalMem_Init(void); @@ -43,7 +51,7 @@ void ExternalMem_SetDataAsInput(void); // Reads back the value the chips are putting onto the data lines 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_DeassertCS(void); @@ -53,7 +61,13 @@ void ExternalMem_DeassertWE(void); // Sets the state of the output enable line 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 void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len); diff --git a/main.c b/main.c index d2424cb..3298db5 100644 --- a/main.c +++ b/main.c @@ -21,8 +21,8 @@ int main(void) ExternalMem_Init(); ExternalMem_SetAddress(0); - ExternalMem_AssertCS(); - ExternalMem_AssertOE(); + ExternalMem_Assert(SIMM_CS | SIMM_OE); + ExternalMem_Deassert(SIMM_WE); USBSerial_Init(); sei(); diff --git a/usb_serial/usb_serial.c b/usb_serial/usb_serial.c index 84769ec..9a21c0e 100644 --- a/usb_serial/usb_serial.c +++ b/usb_serial/usb_serial.c @@ -136,6 +136,19 @@ void USBSerial_Check(void) sprintf(tmp, "%d errors\r\n", result); 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"); + } } }