I got the device identification working, and I'm in the middle of breaking it into its own set of functions for write cycles, read cycles, unlock sequence, etc.

This commit is contained in:
Doug Brown 2011-12-10 18:40:30 -08:00
parent 1540bcadd1
commit 8865d0c00f
4 changed files with 164 additions and 108 deletions

View File

@ -41,9 +41,8 @@
<listOptionValue builtIn="false" value="FIXED_NUM_CONFIGURATIONS=1"/>
<listOptionValue builtIn="false" value="USE_FLASH_DESCRIPTORS"/>
<listOptionValue builtIn="false" value="USE_STATIC_OPTIONS=&quot;(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)&quot;"/>
<listOptionValue builtIn="false" value="INTERRUPT_CONTROL_ENDPOINT"/>
</option>
<option id="de.innot.avreclipse.compiler.option.otherflags.1513967861" superClass="de.innot.avreclipse.compiler.option.otherflags" value="-ffunction-sections -fdata-sections" valueType="string"/>
<option id="de.innot.avreclipse.compiler.option.otherflags.1513967861" name="Other flags" superClass="de.innot.avreclipse.compiler.option.otherflags" value="-ffunction-sections -fdata-sections" valueType="string"/>
<inputType id="de.innot.avreclipse.compiler.winavr.input.1367172122" name="C Source Files" superClass="de.innot.avreclipse.compiler.winavr.input"/>
</tool>
<tool id="de.innot.avreclipse.tool.cppcompiler.app.debug.24092953" name="AVR C++ Compiler" superClass="de.innot.avreclipse.tool.cppcompiler.app.debug">
@ -51,7 +50,7 @@
<option id="de.innot.avreclipse.cppcompiler.option.optimize.1022518531" name="Optimization Level" superClass="de.innot.avreclipse.cppcompiler.option.optimize"/>
</tool>
<tool id="de.innot.avreclipse.tool.linker.winavr.app.debug.806884166" name="AVR C Linker" superClass="de.innot.avreclipse.tool.linker.winavr.app.debug">
<option id="de.innot.avreclipse.linker.option.otherlinkargs.1714687929" superClass="de.innot.avreclipse.linker.option.otherlinkargs" value="-Wl,--relax,--gc-sections" valueType="string"/>
<option id="de.innot.avreclipse.linker.option.otherlinkargs.1714687929" name="Other Arguments" superClass="de.innot.avreclipse.linker.option.otherlinkargs" value="-Wl,--relax,--gc-sections" valueType="string"/>
<inputType id="de.innot.avreclipse.tool.linker.input.1020880987" name="OBJ Files" superClass="de.innot.avreclipse.tool.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
@ -423,9 +422,8 @@
<listOptionValue builtIn="false" value="FIXED_NUM_CONFIGURATIONS=1"/>
<listOptionValue builtIn="false" value="USE_FLASH_DESCRIPTORS"/>
<listOptionValue builtIn="false" value="USE_STATIC_OPTIONS=&quot;(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)&quot;"/>
<listOptionValue builtIn="false" value="INTERRUPT_CONTROL_ENDPOINT"/>
</option>
<option id="de.innot.avreclipse.compiler.option.otherflags.1566165436" superClass="de.innot.avreclipse.compiler.option.otherflags" value="-ffunction-sections -fdata-sections" valueType="string"/>
<option id="de.innot.avreclipse.compiler.option.otherflags.1566165436" name="Other flags" superClass="de.innot.avreclipse.compiler.option.otherflags" value="-ffunction-sections -fdata-sections" valueType="string"/>
<inputType id="de.innot.avreclipse.compiler.winavr.input.2084198580" name="C Source Files" superClass="de.innot.avreclipse.compiler.winavr.input"/>
</tool>
<tool id="de.innot.avreclipse.tool.cppcompiler.app.release.912002244" name="AVR C++ Compiler" superClass="de.innot.avreclipse.tool.cppcompiler.app.release">
@ -433,7 +431,7 @@
<option id="de.innot.avreclipse.cppcompiler.option.optimize.1657124646" name="Optimization Level" superClass="de.innot.avreclipse.cppcompiler.option.optimize" value="de.innot.avreclipse.cppcompiler.optimize.size" valueType="enumerated"/>
</tool>
<tool id="de.innot.avreclipse.tool.linker.winavr.app.release.381852607" name="AVR C Linker" superClass="de.innot.avreclipse.tool.linker.winavr.app.release">
<option id="de.innot.avreclipse.linker.option.otherlinkargs.270243458" superClass="de.innot.avreclipse.linker.option.otherlinkargs" value="-Wl,--relax,--gc-sections" valueType="string"/>
<option id="de.innot.avreclipse.linker.option.otherlinkargs.270243458" name="Other Arguments" superClass="de.innot.avreclipse.linker.option.otherlinkargs" value="-Wl,--relax,--gc-sections" valueType="string"/>
<inputType id="de.innot.avreclipse.tool.linker.input.567763029" name="OBJ Files" superClass="de.innot.avreclipse.tool.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>

View File

@ -8,6 +8,7 @@
#include "external_mem.h"
#include "ports.h"
#include <avr/io.h>
#include <avr/delay.h>
#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);
}

View File

@ -11,6 +11,13 @@
#include <stdint.h>
#include <stdbool.h>
// 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_ */

View File

@ -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);