diff --git a/.cproject b/.cproject
index 59505e1..d441d93 100644
--- a/.cproject
+++ b/.cproject
@@ -41,9 +41,8 @@
-
-
+
@@ -51,7 +50,7 @@
-
+
@@ -423,9 +422,8 @@
-
-
+
@@ -433,7 +431,7 @@
-
+
diff --git a/external_mem.c b/external_mem.c
index 409dcde..4ca2ccf 100644
--- a/external_mem.c
+++ b/external_mem.c
@@ -8,6 +8,7 @@
#include "external_mem.h"
#include "ports.h"
#include
+#include
#define HIGHEST_ADDRESS_LINE 20
@@ -124,3 +125,64 @@ void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len)
*buf++ = tmp;
}
}
+
+void ExternalMem_WriteCycle(uint32_t address, uint32_t data)
+{
+ ExternalMem_SetAddressAndData(address, data);
+ 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?
+ ExternalMem_DeassertWE();
+}
+
+void ExternalMem_UnlockAllChips(void)
+{
+ // Disable the chips completely and wait for a short time...
+ ExternalMem_DeassertCS();
+ ExternalMem_DeassertOE();
+ ExternalMem_DeassertWE();
+ _delay_us(1);
+ ExternalMem_AssertCS();
+
+ // 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);
+
+ // Second part of unlock sequence is the same thing, but reversed.
+ ExternalMem_WriteCycle(0xAAAAAAAAUL, 0x55555555UL);
+}
+
+void ExternalMem_IdentifyChips(struct ChipID *chips)
+{
+ ExternalMem_UnlockAllChips();
+
+ // Write 0x90 to 0x55555555 for the identify command...
+ ExternalMem_WriteCycle(0x55555555UL, 0x90909090UL);
+
+ // Now we can read the vendor and product ID
+ ExternalMem_SetAddress(0);
+ ExternalMem_SetDataAsInput();
+ ExternalMem_AssertOE();
+
+ uint32_t result = ExternalMem_ReadData();
+
+ chips[3].manufacturerID = (uint8_t)result;
+ chips[2].manufacturerID = (uint8_t)(result >> 8);
+ chips[1].manufacturerID = (uint8_t)(result >> 16);
+ chips[0].manufacturerID = (uint8_t)(result >> 24);
+
+ ExternalMem_SetAddress(1);
+ result = ExternalMem_ReadData();
+
+ chips[3].deviceID = (uint8_t)result;
+ chips[2].deviceID = (uint8_t)(result >> 8);
+ chips[1].deviceID = (uint8_t)(result >> 16);
+ chips[0].deviceID = (uint8_t)(result >> 24);
+
+ // Exit software ID mode
+ ExternalMem_DeassertOE();
+ ExternalMem_WriteCycle(0, 0xF0F0F0F0UL);
+}
diff --git a/external_mem.h b/external_mem.h
index 09bcd6a..641b269 100644
--- a/external_mem.h
+++ b/external_mem.h
@@ -11,6 +11,13 @@
#include
#include
+// Holds info about the chip (retrieved with JEDEC standards)
+struct ChipID
+{
+ uint8_t manufacturerID;
+ uint8_t deviceID;
+};
+
// Initializes the (bit-banged) external memory interface
void ExternalMem_Init(void);
@@ -44,4 +51,13 @@ void ExternalMem_DeassertOE(void);
// Reads a set of data...
void ExternalMem_Read(uint32_t startAddress, uint32_t *buf, uint32_t len);
+// Performs a write cycle
+void ExternalMem_WriteCycle(uint32_t address, uint32_t data);
+
+// Does an unlock sequence on the chips
+void ExternalMem_UnlockAllChips(void);
+
+// Identifies the chips that are currently in the SIMM
+void ExternalMem_IdentifyChips(struct ChipID *chips);
+
#endif /* EXTERNAL_MEM_H_ */
diff --git a/usb_serial/usb_serial.c b/usb_serial/usb_serial.c
index 3eb3e1b..056fab1 100644
--- a/usb_serial/usb_serial.c
+++ b/usb_serial/usb_serial.c
@@ -43,30 +43,8 @@ void USBSerial_Check(void)
if (CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface))
{
CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
- //CDC_Device_SendString(&VirtualSerial_CDC_Interface, "Reading...");
- //CDC_Device_Flush(&VirtualSerial_CDC_Interface);
- /*uint32_t mem = ExternalMem_ReadData();
-
- char dataString[11];
-
- sprintf(dataString, "%08lX\r\n", mem);
-
- CDC_Device_SendString(&VirtualSerial_CDC_Interface, dataString);
-
- sprintf(dataString, "%02X%02X%02X%02X\r\n",
- (uint8_t)(mem>>24),
- (uint8_t)(mem>>16),
- (uint8_t)(mem>>8),
- (uint8_t)(mem>>0));
-
- CDC_Device_SendString(&VirtualSerial_CDC_Interface, dataString);
-
- sprintf(dataString, "%02X %02X %02X\r\n", DDRA, DDRC, DDRD);
-
- CDC_Device_SendString(&VirtualSerial_CDC_Interface, dataString);*/
-
-#define BUFSIZE 128UL
+ /*#define BUFSIZE 128UL
static uint32_t readBuf[BUFSIZE];
int x;
for (x = 0; x < 512UL * 1024UL / BUFSIZE; x++)
@@ -77,86 +55,88 @@ void USBSerial_Check(void)
{
PORTD |= (1 << 7);
}
-
- //int y;
- //for (y = 0; y < BUFSIZE; y++)
- //{
- //if ((y % 4) == 0) CDC_Device_SendString(&VirtualSerial_CDC_Interface, ".\r\n");
-
- //char tmpBuf[20];
- //sprintf(tmpBuf, "%02X %02X %02X %02X ",
- // (uint8_t)(readBuf[y] >> 24),
- // (uint8_t)(readBuf[y] >> 16),
- // (uint8_t)(readBuf[y] >> 8),
- // (uint8_t)(readBuf[y] >> 0));
- //CDC_Device_SendString(&VirtualSerial_CDC_Interface, tmpBuf);
- //}
- //if ((x % 64) == 0) CDC_Device_SendString(&VirtualSerial_CDC_Interface, "\r\n");
- //CDC_Device_SendString(&VirtualSerial_CDC_Interface, ".");
- //CDC_Device_Flush(&VirtualSerial_CDC_Interface);
- }
-
- //CDC_Device_SendString(&VirtualSerial_CDC_Interface, "\r\nDone\r\n");
- }
-
- /*int16_t rb = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
- if (rb >= 0)
- {
- if (rb == '.')
- {
- gotChar = 0;
- }
- else
- {
- gotChar = 1;
- }
- }
-
- if (gotChar)
- {*/
- //if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface, 'A') != ENDPOINT_READYWAIT_NoError)
- /*if (CDC_Device_SendData(&VirtualSerial_CDC_Interface,
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- "ASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDFASDF"
- , 2048) != ENDPOINT_RWSTREAM_NoError)
- {
- PORTD |= (1 << 7);
- }
- else
- {
- PORTD &= ~(1 << 7);
}*/
- //}
+
+ // Start out in programming state...
+ ExternalMem_DeassertCS();
+ ExternalMem_DeassertOE();
+ ExternalMem_DeassertWE();
+ _delay_us(1);
+
+ // Write 0xAA to 0x555 (first byte of unlock sequence)
+ // (The SST39SF040 asks for 0x5555 here -- but it doesn't matter, it's
+ // just an alternating pattern of 1s and 0s and the chips will ignore
+ // the bits above the value it asks for -- so I can just write a huge
+ // alternating pattern and it will work with most/all chips)
+ ExternalMem_SetAddressAndData(0x55555555UL, 0xAAAAAAAAUL);
+ ExternalMem_AssertCS();
+ ExternalMem_AssertWE();
+ _delay_us(1);
+ ExternalMem_DeassertWE();
+ _delay_us(1);
+
+ // Write 0x55 to 0x2AA (second byte of unlock sequence)
+ ExternalMem_SetAddressAndData(0xAAAAAAAAUL, 0x55555555UL);
+ ExternalMem_AssertWE();
+ _delay_us(1);
+ ExternalMem_DeassertWE();
+ _delay_us(1);
+
+ // Write 0x90 to 0x555 (autoselect command)
+ ExternalMem_SetAddressAndData(0x55555555UL, 0x90909090UL);
+ ExternalMem_AssertWE();
+ _delay_us(1);
+ ExternalMem_DeassertWE();
+ //ExternalMem_DeassertCS();
+ _delay_us(1);
+
+ // Now we can start reading...
+ ExternalMem_SetAddress(0x0);
+ ExternalMem_SetDataAsInput();
+ ExternalMem_AssertOE();
+ //ExternalMem_AssertCS();
+
+ _delay_us(1);
+
+ uint32_t result = ExternalMem_ReadData();
+
+ char test[20];
+ sprintf(test, "%08lX ", result);
+ CDC_Device_SendString(&VirtualSerial_CDC_Interface, test);
+
+ ExternalMem_SetAddress(0x1);
+ result = ExternalMem_ReadData();
+ sprintf(test, "%08lX\r\n", result);
+ CDC_Device_SendString(&VirtualSerial_CDC_Interface, test);
+
+ // Exit back to normal mode...
+ ExternalMem_DeassertOE();
+ ExternalMem_SetAddressAndData(0x0, 0xF0F0F0F0UL);
+ //ExternalMem_AssertCS();
+ ExternalMem_AssertWE();
+ _delay_us(1);
+ ExternalMem_DeassertWE();
+ //ExternalMem_DeassertCS();
+ _delay_us(1);
+
+ // Now do normal read cycle to confirm we exited
+ ExternalMem_SetAddress(0x0);
+ ExternalMem_SetDataAsInput();
+ ExternalMem_AssertOE();
+ //ExternalMem_AssertCS();
+
+ _delay_us(1);
+
+ result = ExternalMem_ReadData();
+
+ sprintf(test, "%08lX ", result);
+ CDC_Device_SendString(&VirtualSerial_CDC_Interface, test);
+
+ ExternalMem_SetAddress(0x1);
+ result = ExternalMem_ReadData();
+ sprintf(test, "%08lX\r\n", result);
+ CDC_Device_SendString(&VirtualSerial_CDC_Interface, test);
+ }
}
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);