mirror of
https://github.com/TomNisbet/TommyPROM.git
synced 2024-06-15 13:29:29 +00:00
Add support for SST27C0x0 flash chips
This commit is contained in:
parent
035b3412af
commit
7d5ab86275
|
@ -22,12 +22,13 @@ static void disableWrite() { digitalWrite(WE, HIGH);}
|
||||||
|
|
||||||
|
|
||||||
PromDevice27::PromDevice27(uint32_t size, E27C_PGM pgmType, unsigned long pulseWidthUsec,
|
PromDevice27::PromDevice27(uint32_t size, E27C_PGM pgmType, unsigned long pulseWidthUsec,
|
||||||
unsigned writeAttempts, unsigned overwriteMultiplier)
|
unsigned writeAttempts, unsigned overwriteMultiplier, bool verify)
|
||||||
: PromDevice(size, 0, 0, false),
|
: PromDevice(size, 0, 0, false),
|
||||||
mPgmType(pgmType),
|
mPgmType(pgmType),
|
||||||
mPulseWidthUsec(pulseWidthUsec),
|
mPulseWidthUsec(pulseWidthUsec),
|
||||||
mWriteAttempts(writeAttempts),
|
mWriteAttempts(writeAttempts),
|
||||||
mOverwriteMultiplier(overwriteMultiplier)
|
mOverwriteMultiplier(overwriteMultiplier),
|
||||||
|
mVerifyByte(verify)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,14 +100,12 @@ bool PromDevice27::burnByteWE(byte value, uint32_t address)
|
||||||
bool status = false;
|
bool status = false;
|
||||||
unsigned writeCount = 0;
|
unsigned writeCount = 0;
|
||||||
|
|
||||||
byte data = 0;
|
|
||||||
disableOutput();
|
disableOutput();
|
||||||
disableWrite();
|
disableWrite();
|
||||||
enableChip();
|
enableChip();
|
||||||
setAddress(address);
|
setAddress(address);
|
||||||
|
|
||||||
while (!status && (writeCount < mWriteAttempts))
|
while (!status && (writeCount < mWriteAttempts)) {
|
||||||
{
|
|
||||||
setDataBusMode(OUTPUT);
|
setDataBusMode(OUTPUT);
|
||||||
writeDataBus(value);
|
writeDataBus(value);
|
||||||
delayMicroseconds(1);
|
delayMicroseconds(1);
|
||||||
|
@ -115,15 +114,17 @@ bool PromDevice27::burnByteWE(byte value, uint32_t address)
|
||||||
disableWrite();
|
disableWrite();
|
||||||
++writeCount;
|
++writeCount;
|
||||||
|
|
||||||
setDataBusMode(INPUT);
|
if (mVerifyByte) {
|
||||||
enableOutput();
|
setDataBusMode(INPUT);
|
||||||
data = readDataBus();
|
enableOutput();
|
||||||
disableOutput();
|
status = readDataBus() == value;
|
||||||
status = (readDataBus() == value);
|
disableOutput();
|
||||||
|
} else {
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status && (mOverwriteMultiplier > 0))
|
if (status && (mOverwriteMultiplier > 0)) {
|
||||||
{
|
|
||||||
setDataBusMode(OUTPUT);
|
setDataBusMode(OUTPUT);
|
||||||
writeDataBus(value);
|
writeDataBus(value);
|
||||||
delayMicroseconds(1);
|
delayMicroseconds(1);
|
||||||
|
@ -132,8 +133,8 @@ bool PromDevice27::burnByteWE(byte value, uint32_t address)
|
||||||
disableWrite();
|
disableWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDataBusMode(INPUT);
|
||||||
disableChip();
|
disableChip();
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,14 +152,12 @@ bool PromDevice27::burnByteCE(byte value, uint32_t address)
|
||||||
bool status = false;
|
bool status = false;
|
||||||
unsigned writeCount = 0;
|
unsigned writeCount = 0;
|
||||||
|
|
||||||
byte data = 0;
|
|
||||||
disableOutput();
|
disableOutput();
|
||||||
disableWrite();
|
disableWrite();
|
||||||
disableChip();
|
disableChip();
|
||||||
setAddress(address);
|
setAddress(address);
|
||||||
|
|
||||||
while (!status && (writeCount < mWriteAttempts))
|
while (!status && (writeCount < mWriteAttempts)) {
|
||||||
{
|
|
||||||
setDataBusMode(OUTPUT);
|
setDataBusMode(OUTPUT);
|
||||||
writeDataBus(value);
|
writeDataBus(value);
|
||||||
delayMicroseconds(2);
|
delayMicroseconds(2);
|
||||||
|
@ -168,24 +167,24 @@ bool PromDevice27::burnByteCE(byte value, uint32_t address)
|
||||||
delayMicroseconds(2);
|
delayMicroseconds(2);
|
||||||
++writeCount;
|
++writeCount;
|
||||||
|
|
||||||
setDataBusMode(INPUT);
|
if (mVerifyByte) {
|
||||||
enableOutput();
|
setDataBusMode(INPUT);
|
||||||
data = readDataBus();
|
enableOutput();
|
||||||
disableOutput();
|
status = readDataBus() == value;
|
||||||
status = (readDataBus() == value);
|
disableOutput();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDataBusMode(INPUT);
|
||||||
|
disableChip();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ERET PromDevice27::erase(uint32_t start, uint32_t end)
|
ERET PromDevice27::erase(uint32_t start, uint32_t end)
|
||||||
{
|
{
|
||||||
if (mPgmType != E27C_PGM_CE) return RET_NOT_SUPPORT;
|
ERET status = RET_FAIL;
|
||||||
|
|
||||||
// Erase code for the 27E257 and 27C257. The Vpp and A9 pins are held at 14V for the
|
|
||||||
// erase and verify cycle. This erases the entire chip, so the start and end address
|
|
||||||
// parameters are ignored.
|
|
||||||
disableChip();
|
disableChip();
|
||||||
disableOutput();
|
disableOutput();
|
||||||
setAddress(0);
|
setAddress(0);
|
||||||
|
@ -193,30 +192,46 @@ ERET PromDevice27::erase(uint32_t start, uint32_t end)
|
||||||
writeDataBus(0xff);
|
writeDataBus(0xff);
|
||||||
delayMicroseconds(2);
|
delayMicroseconds(2);
|
||||||
|
|
||||||
unsigned writeCount = 0;
|
if (mPgmType == E27C_PGM_WE) {
|
||||||
ERET status = RET_FAIL;
|
// Erase code for the SST27C0x0. The Vpp and A9 pins are held at 12V for the
|
||||||
while ((status == RET_FAIL) && (writeCount < mWriteAttempts)) {
|
// erase cycle. This erases the entire chip, so the start and end address
|
||||||
setAddress(0);
|
// parameters are ignored. There is no erase verification for this chip.
|
||||||
setDataBusMode(OUTPUT);
|
enableChip();
|
||||||
writeDataBus(0xff);
|
delayMicroseconds(1);
|
||||||
delayMicroseconds(2);
|
enableWrite();
|
||||||
enableChip();
|
delayMicroseconds(100); // Hard coded for SST27F020
|
||||||
delay(100);
|
disableWrite();
|
||||||
disableChip();
|
disableChip();
|
||||||
delayMicroseconds(2);
|
setDataBusMode(INPUT);
|
||||||
|
status = RET_OK;
|
||||||
|
} else {
|
||||||
|
// Erase code for the 27E257 and 27C257. The Vpp and A9 pins are held at 14V for
|
||||||
|
// the erase and verify cycle. This erases the entire chip, so the start and end
|
||||||
|
// address parameters are ignored.
|
||||||
|
unsigned writeCount = 0;
|
||||||
|
while ((status == RET_FAIL) && (writeCount < mWriteAttempts)) {
|
||||||
|
setAddress(0);
|
||||||
|
setDataBusMode(OUTPUT);
|
||||||
|
writeDataBus(0xff);
|
||||||
|
delayMicroseconds(2);
|
||||||
|
enableChip();
|
||||||
|
delay(100);
|
||||||
|
disableChip();
|
||||||
|
delayMicroseconds(2);
|
||||||
|
|
||||||
// Read back the data to verify all cells are erased. Note That this is done
|
// Read back the data to verify all cells are erased. Note That this is done
|
||||||
// while CE is HIGH. This is the erase verify mode.
|
// while CE is HIGH. This is the erase verify mode.
|
||||||
setDataBusMode(INPUT);
|
setDataBusMode(INPUT);
|
||||||
for (uint32_t address = 0; (address < mSize); address++) {
|
for (uint32_t address = 0; (address < mSize); address++) {
|
||||||
setAddress(address);
|
setAddress(address);
|
||||||
enableOutput();
|
enableOutput();
|
||||||
uint8_t b = readDataBus();
|
uint8_t b = readDataBus();
|
||||||
disableOutput();
|
disableOutput();
|
||||||
if (b != 0xff) break;
|
if (b != 0xff) break;
|
||||||
}
|
}
|
||||||
status = RET_OK;
|
status = RET_OK;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -224,15 +239,12 @@ ERET PromDevice27::erase(uint32_t start, uint32_t end)
|
||||||
|
|
||||||
void PromDevice27::myDelay(unsigned int us)
|
void PromDevice27::myDelay(unsigned int us)
|
||||||
{
|
{
|
||||||
if (us > 16000)
|
if (us > 16000) {
|
||||||
{
|
|
||||||
// The delayMicroseconds code can't do delays longer than 16ms, so use the
|
// The delayMicroseconds code can't do delays longer than 16ms, so use the
|
||||||
// ms delay code for larger values. This rounds down to the nearest ms, so
|
// ms delay code for larger values. This rounds down to the nearest ms, so
|
||||||
// it is not possible to delay for 40.5 ms, for example.
|
// it is not possible to delay for 40.5 ms, for example.
|
||||||
delay(us / 1000);
|
delay(us / 1000);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
delayMicroseconds((unsigned int) us);
|
delayMicroseconds((unsigned int) us);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ class PromDevice27 : public PromDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PromDevice27(uint32_t size, E27C_PGM pgmType, unsigned long pulseWidthUsec,
|
PromDevice27(uint32_t size, E27C_PGM pgmType, unsigned long pulseWidthUsec,
|
||||||
unsigned writeAttempts, unsigned overwriteMultiplier);
|
unsigned writeAttempts, unsigned overwriteMultiplier, bool verify=true);
|
||||||
void begin();
|
void begin();
|
||||||
const char * getName() { return "27 series EPROM"; }
|
const char * getName() { return "27 series EPROM"; }
|
||||||
ERET erase(uint32_t start, uint32_t end);
|
ERET erase(uint32_t start, uint32_t end);
|
||||||
|
@ -54,6 +54,7 @@ class PromDevice27 : public PromDevice
|
||||||
unsigned long mPulseWidthUsec;
|
unsigned long mPulseWidthUsec;
|
||||||
unsigned mWriteAttempts;
|
unsigned mWriteAttempts;
|
||||||
unsigned mOverwriteMultiplier;
|
unsigned mOverwriteMultiplier;
|
||||||
|
bool mVerifyByte;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #define INCLUDE_PROM_DEVICE_27_H
|
#endif // #define INCLUDE_PROM_DEVICE_27_H
|
||||||
|
|
|
@ -189,7 +189,7 @@ bool PromDevice28C::waitForWriteCycleEnd(byte lastValue)
|
||||||
byte b1=0, b2=0;
|
byte b1=0, b2=0;
|
||||||
setDataBusMode(INPUT);
|
setDataBusMode(INPUT);
|
||||||
delayMicroseconds(1);
|
delayMicroseconds(1);
|
||||||
for (int readCount = 1; (readCount < (mMaxWriteTime * 100)); readCount++)
|
for (unsigned readCount = 1; (readCount < (mMaxWriteTime * 100)); readCount++)
|
||||||
{
|
{
|
||||||
enableChip();
|
enableChip();
|
||||||
enableOutput();
|
enableOutput();
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "XModem.h"
|
#include "XModem.h"
|
||||||
|
|
||||||
|
|
||||||
static const char * MY_VERSION = "3.2";
|
static const char * MY_VERSION = "3.3";
|
||||||
|
|
||||||
|
|
||||||
// Global status
|
// Global status
|
||||||
|
@ -44,11 +44,13 @@ PromDevice28C prom(32 * 1024L, 64, 10, true);
|
||||||
// 1000us (1ms) write pulse
|
// 1000us (1ms) write pulse
|
||||||
// 15 write attempts
|
// 15 write attempts
|
||||||
// 4x overwrite pulse
|
// 4x overwrite pulse
|
||||||
|
// (true) verify data byte after writing
|
||||||
//PromDevice27 prom(8 * 1024L, E27C_PGM_WE, 1000L, 15, 4); // 2764 with SEEQ intelligent programming
|
//PromDevice27 prom(8 * 1024L, E27C_PGM_WE, 1000L, 15, 4); // 2764 with SEEQ intelligent programming
|
||||||
//PromDevice27 prom(32 * 1024L, E27C_PGM_WE, 1000L, 25, 3); // 27C256 with SEEQ intelligent programming
|
//PromDevice27 prom(32 * 1024L, E27C_PGM_WE, 1000L, 25, 3); // 27C256 with SEEQ intelligent programming
|
||||||
//PromDevice27 prom(2 * 1024L, E27C_PGM_WE, 50000L, 1, 0); // 2716 with single 50ms write
|
//PromDevice27 prom(2 * 1024L, E27C_PGM_WE, 50000L, 1, 0); // 2716 with single 50ms write
|
||||||
//PromDevice27 prom(64 * 1024L, E27C_PGM_WE, 100L, 11, 0); // 27C040 with Atmel rapid programming
|
//PromDevice27 prom(512 * 1024L, E27C_PGM_WE, 100L, 11, 0); // 27C040 with Atmel rapid programming
|
||||||
PromDevice27 prom(32 * 1024L, E27C_PGM_CE, 100L, 25, 0); // 27C257/27E257 with 100uS program pulse on CE
|
//PromDevice27 prom(32 * 1024L, E27C_PGM_CE, 100L, 25, 0); // 27C257/27E257 with 100uS program pulse on CE
|
||||||
|
PromDevice27 prom(256 * 1024L, E27C_PGM_WE, 20L, 1, 0, false); // SST27SF020 with single 20us write, no verify
|
||||||
|
|
||||||
#elif defined(PROM_IS_SST39SF)
|
#elif defined(PROM_IS_SST39SF)
|
||||||
// Define a device for anSST39SF Flash with the following parameters:
|
// Define a device for anSST39SF Flash with the following parameters:
|
||||||
|
|
|
@ -161,7 +161,8 @@ The 8755 build of TommyPROM also has a circuit to control the 25V programming pu
|
||||||
|:--- |:--- |:--- |:--- |:--- |
|
|:--- |:--- |:--- |:--- |:--- |
|
||||||
|AT28C256 |Atmel, others|EEPROM |28C |Fully supported|
|
|AT28C256 |Atmel, others|EEPROM |28C |Fully supported|
|
||||||
|SST39SF040|Microchip |Flash |SST39SF|All SST39SF0x0 supported|
|
|SST39SF040|Microchip |Flash |SST39SF|All SST39SF0x0 supported|
|
||||||
|SST28SF040|SST |Flash | |All SST28SF0x0 supported|
|
|SST28SF040|SST |Flash |SST39SF|All SST28SF0x0 supported|
|
||||||
|
|SST27SF020|SST |Flash |27 |12V continuous for pgm/erase|
|
||||||
|WE27C257 |Winbond |EEPROM |27 |Continual 12V or 14V for program/erase|
|
|WE27C257 |Winbond |EEPROM |27 |Continual 12V or 14V for program/erase|
|
||||||
|AT29C010 |Atmel |Flash |28C |Only with 128 byte or less sector size|
|
|AT29C010 |Atmel |Flash |28C |Only with 128 byte or less sector size|
|
||||||
|8755A |Intel |EPROM |8755A |Requires 25V pulses to program|
|
|8755A |Intel |EPROM |8755A |Requires 25V pulses to program|
|
||||||
|
@ -195,6 +196,18 @@ This is an earlier version of the SST39SF series chips. They are pin compatible
|
||||||
flash chips support software data protection. The _Lock_ and _Unlock_ commands can be
|
flash chips support software data protection. The _Lock_ and _Unlock_ commands can be
|
||||||
used to enable and disable SDP from the command line.
|
used to enable and disable SDP from the command line.
|
||||||
|
|
||||||
|
#### SST27SF020
|
||||||
|
|
||||||
|
The Silicon Storage SST27SF0x0 are programmed similarly to the 27C257 in that a constant
|
||||||
|
voltage is applied for program and erase operations. Unlike the 27C257, these have a
|
||||||
|
dedicated WE pin that controls programming and erasing. Another difference is that they
|
||||||
|
do not have a verify operation to read back the programmed data.
|
||||||
|
|
||||||
|
These Flash chips have a _VPP_ pin that needs a constant 12V during programming. Unlike
|
||||||
|
the newer 28C EEPROMs, these chips do not automatically erase before writing to a
|
||||||
|
location. Instead, the entire chip is erased by applying 12V to _VPP_ and _A9_ and then
|
||||||
|
pulsing _WE_.
|
||||||
|
|
||||||
#### 27C257
|
#### 27C257
|
||||||
|
|
||||||
The Winbond WE27C257 and WE27E257 appear to be identical 32Kx8 EEPROMs. The 27C version
|
The Winbond WE27C257 and WE27E257 appear to be identical 32Kx8 EEPROMs. The 27C version
|
||||||
|
@ -228,4 +241,3 @@ for chips with the 256 byte buffer.
|
||||||
|Model |Manufacturer |Type |Module |Notes|
|
|Model |Manufacturer |Type |Module |Notes|
|
||||||
|:--- |:--- |:--- |:--- |:--- |
|
|:--- |:--- |:--- |:--- |:--- |
|
||||||
|M27C4001 |ST Micro |EEPROM | |VCC=6.5V, VPP=12.75V to pgm|
|
|M27C4001 |ST Micro |EEPROM | |VCC=6.5V, VPP=12.75V to pgm|
|
||||||
|SST27SF020|SST |Flash | |12V continuous for pgm/erase|
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user