diff --git a/docs/specs.odt b/docs/specs.odt index bd88ac76..c62c22cc 100644 Binary files a/docs/specs.odt and b/docs/specs.odt differ diff --git a/docs/specs.pdf b/docs/specs.pdf index 3da40ad2..4fc71db2 100644 Binary files a/docs/specs.pdf and b/docs/specs.pdf differ diff --git a/firmware/usbflashprog/modules/device.cpp b/firmware/usbflashprog/modules/device.cpp index 735b7f2f..43563a09 100644 --- a/firmware/usbflashprog/modules/device.cpp +++ b/firmware/usbflashprog/modules/device.cpp @@ -22,19 +22,34 @@ // --------------------------------------------------------------------------- -/* @brief Command sequence to Unprotect an EEPROM 28C/X28 (ST/Atmel/Xicor). */ // clang-format off -constexpr Device::TDeviceCommand kDeviceCmdUnprotect28C[] = { - {0x1555, 0xAA}, {0xAAA, 0x55}, {0x1555, 0x80}, - {0x1555, 0xAA}, {0xAAA, 0x55}, {0x1555, 0x20} + +/* @brief Command sequence to Unprotect an EEPROM 28C/X28 64 + (ST/Atmel/Xicor). */ +constexpr Device::TDeviceCommand kDeviceCmdUnprotect28C64[] = { + {0x1555, 0xAA}, {0x0AAA, 0x55}, {0x1555, 0x80}, + {0x1555, 0xAA}, {0x0AAA, 0x55}, {0x1555, 0x20} }; -// clang-format on -/* @brief Command sequence to Protect an EEPROM 28C/X28 (ST/Atmel/Xicor). */ -// clang-format off -constexpr Device::TDeviceCommand kDeviceCmdProtect28C[] = { - {0x1555, 0xAA}, {0xAAA, 0x55}, {0x1555, 0xA0} +/* @brief Command sequence to Protect an EEPROM 28C/X28 64 + (ST/Atmel/Xicor). */ +constexpr Device::TDeviceCommand kDeviceCmdProtect28C64[] = { + {0x1555, 0xAA}, {0x0AAA, 0x55}, {0x1555, 0xA0} +}; + +/* @brief Command sequence to Unprotect an EEPROM 28C/X28 256 + (ST/Atmel/Xicor). */ +constexpr Device::TDeviceCommand kDeviceCmdUnprotect28C256[] = { + {0x5555, 0xAA}, {0x2AAA, 0x55}, {0x5555, 0x80}, + {0x5555, 0xAA}, {0x2AAA, 0x55}, {0x5555, 0x20} }; + +/* @brief Command sequence to Protect an EEPROM 28C/X28 256 + (ST/Atmel/Xicor). */ +constexpr Device::TDeviceCommand kDeviceCmdProtect28C256[] = { + {0x5555, 0xAA}, {0x2AAA, 0x55}, {0x5555, 0xA0} +}; + // clang-format on // --------------------------------------------------------------------------- @@ -488,8 +503,10 @@ bool Device::erase27E_() { bool Device::unprotect(uint8_t algo) { // Unprotect entire chip switch (algo) { - case kCmdDeviceAlgorithm28C: - return protect28C_(false); + case kCmdDeviceAlgorithm28C64: + return protect28C_(false, false); + case kCmdDeviceAlgorithm28C256: + return protect28C_(false, true); default: return false; } @@ -498,28 +515,44 @@ bool Device::unprotect(uint8_t algo) { bool Device::protect(uint8_t algo) { // Protect entire chip switch (algo) { - case kCmdDeviceAlgorithm28C: - return protect28C_(true); + case kCmdDeviceAlgorithm28C64: + return protect28C_(true, false); + case kCmdDeviceAlgorithm28C256: + return protect28C_(true, true); default: return false; } } -bool Device::protect28C_(bool protect) { +bool Device::protect28C_(bool protect, bool is256) { // EEPROM 28C/X28/AT28 Algorithm bool success = true; // ~CE is LO setCE(true); // write command - if (protect) { - for (const TDeviceCommand& cmd : kDeviceCmdProtect28C) { + if (protect && !is256) { + for (const TDeviceCommand& cmd : kDeviceCmdProtect28C64) { if (!writeAtAddr_(cmd.addr, cmd.data)) { success = false; break; } } - } else { - for (const TDeviceCommand& cmd : kDeviceCmdUnprotect28C) { + } else if (protect && is256) { + for (const TDeviceCommand& cmd : kDeviceCmdProtect28C256) { + if (!writeAtAddr_(cmd.addr, cmd.data)) { + success = false; + break; + } + } + } else if (!protect && !is256) { + for (const TDeviceCommand& cmd : kDeviceCmdUnprotect28C64) { + if (!writeAtAddr_(cmd.addr, cmd.data)) { + success = false; + break; + } + } + } else if (!protect && is256) { + for (const TDeviceCommand& cmd : kDeviceCmdUnprotect28C256) { if (!writeAtAddr_(cmd.addr, cmd.data)) { success = false; break; diff --git a/firmware/usbflashprog/modules/device.hpp b/firmware/usbflashprog/modules/device.hpp index 44ac3786..3aa206ab 100644 --- a/firmware/usbflashprog/modules/device.hpp +++ b/firmware/usbflashprog/modules/device.hpp @@ -421,9 +421,11 @@ class Device { /* * @brief Runs the device protect/unprotect (EEPROM 28C algorithm). * @param protect If true, protects device. Otherwise, unprotects device. + * @param is256 If true, uses the 28C256 algorithm. + * Otherwise, uses the 28C64 algorithm. * @return True if sucessfull. False otherwise. */ - bool protect28C_(bool protect); + bool protect28C_(bool protect, bool is256); private: /* diff --git a/firmware/usbflashprog/modules/opcodes.hpp b/firmware/usbflashprog/modules/opcodes.hpp index 4ac7b443..3f81422b 100644 --- a/firmware/usbflashprog/modules/opcodes.hpp +++ b/firmware/usbflashprog/modules/opcodes.hpp @@ -260,11 +260,12 @@ enum kCmdOpCodeEnum { * @details The parameter (one byte) represents the algorithm, and * follows the table: *
- * +------------------------------+ - * |Algorithm| Description | - * | 0x01 | EPROM 27E/W27/27SF | - * | 0x02 | EEPROM 28C | - * +------------------------------+ + * +-------------------------------+ + * |Algorithm| Description | + * | 0x01 | EPROM 27E/W27/27SF | + * | 0x02 | EEPROM 28C64 | + * | 0x03 | EEPROM 28C256/upper | + * +-------------------------------+ ** @see kCmdDeviceAlgorithmEnum */ @@ -274,11 +275,12 @@ enum kCmdOpCodeEnum { * @details The parameter (one byte) represents the algorithm, and * follows the table: *
- * +------------------------------+ - * |Algorithm| Description | - * | 0x01 | EPROM 27E/W27/27SF | - * | 0x02 | EEPROM 28C | - * +------------------------------+ + * +-------------------------------+ + * |Algorithm| Description | + * | 0x01 | EPROM 27E/W27/27SF | + * | 0x02 | EEPROM 28C64 | + * | 0x03 | EEPROM 28C256/upper | + * +-------------------------------+ ** @see kCmdDeviceAlgorithmEnum */ @@ -288,11 +290,12 @@ enum kCmdOpCodeEnum { * @details The parameter (one byte) represents the algorithm, and * follows the table: *
- * +------------------------------+ - * |Algorithm| Description | - * | 0x01 | EPROM 27E/W27/27SF | - * | 0x02 | EEPROM 28C | - * +------------------------------+ + * +-------------------------------+ + * |Algorithm| Description | + * | 0x01 | EPROM 27E/W27/27SF | + * | 0x02 | EEPROM 28C64 | + * | 0x03 | EEPROM 28C256/upper | + * +-------------------------------+ ** @see kCmdDeviceAlgorithmEnum */ @@ -328,8 +331,10 @@ enum kCmdDeviceAlgorithmEnum { kCmdDeviceAlgorithmUnknown = 0x00, /** @brief CMD / DEVICE : Defines an algorithm EPROM 27E/SF/W27. */ kCmdDeviceAlgorithm27E = 0x01, - /** @brief CMD / DEVICE : Defines an algorithm EEPROM 28C. */ - kCmdDeviceAlgorithm28C = 0x02 + /** @brief CMD / DEVICE : Defines an algorithm EEPROM 28C64. */ + kCmdDeviceAlgorithm28C64 = 0x02, + /** @brief CMD / DEVICE : Defines an algorithm EEPROM 28C256 or upper. */ + kCmdDeviceAlgorithm28C256 = 0x03 }; // --------------------------------------------------------------------------- diff --git a/reference/datasheets/eeprom/eepromAT28c/AT28C010.pdf b/reference/datasheets/eeprom/eepromAT28c/AT28C010.pdf new file mode 100644 index 00000000..31ab1d0c Binary files /dev/null and b/reference/datasheets/eeprom/eepromAT28c/AT28C010.pdf differ diff --git a/reference/datasheets/eeprom/eepromAT28c/AT28C040.pdf b/reference/datasheets/eeprom/eepromAT28c/AT28C040.pdf new file mode 100644 index 00000000..c2401136 Binary files /dev/null and b/reference/datasheets/eeprom/eepromAT28c/AT28C040.pdf differ diff --git a/reference/datasheets/eeprom/eepromAT28c/AT28C256.pdf b/reference/datasheets/eeprom/eepromAT28c/AT28C256.pdf new file mode 100644 index 00000000..368395c3 Binary files /dev/null and b/reference/datasheets/eeprom/eepromAT28c/AT28C256.pdf differ diff --git a/reference/datasheets/eeprom/eeprom28c/CAT28C256.pdf b/reference/datasheets/eeprom/eepromAT28c/CAT28C256.pdf similarity index 100% rename from reference/datasheets/eeprom/eeprom28c/CAT28C256.pdf rename to reference/datasheets/eeprom/eepromAT28c/CAT28C256.pdf diff --git a/reference/datasheets/eeprom/eepromAT28c/CAT28C512.pdf b/reference/datasheets/eeprom/eepromAT28c/CAT28C512.pdf new file mode 100644 index 00000000..80f9c2e6 Binary files /dev/null and b/reference/datasheets/eeprom/eepromAT28c/CAT28C512.pdf differ diff --git a/software/usbflashprog/CMakeLists.txt b/software/usbflashprog/CMakeLists.txt index e2f949d8..752a4bae 100644 --- a/software/usbflashprog/CMakeLists.txt +++ b/software/usbflashprog/CMakeLists.txt @@ -54,45 +54,26 @@ elseif(NORMAL_BUILD) ) set(PROJECT_SOURCES - config.hpp backend/opcodes.cpp - backend/opcodes.hpp backend/runner.cpp - backend/runner.hpp backend/epromfile/qepromfilebase.cpp - backend/epromfile/qepromfilebase.hpp backend/epromfile/qbinfile.cpp - backend/epromfile/qbinfile.hpp backend/epromfile/qsrecfile.cpp - backend/epromfile/qsrecfile.hpp backend/epromfile/qhexfile.cpp - backend/epromfile/qhexfile.hpp backend/epromfile/qatmelfile.cpp - backend/epromfile/qatmelfile.hpp backend/epromfile/qepromfile.cpp - backend/epromfile/qepromfile.hpp backend/devices/device.cpp - backend/devices/device.hpp backend/devices/parallel/pdevice.cpp - backend/devices/parallel/pdevice.hpp backend/devices/parallel/dummy.cpp - backend/devices/parallel/dummy.hpp backend/devices/parallel/sram.cpp - backend/devices/parallel/sram.hpp backend/devices/parallel/eprom.cpp - backend/devices/parallel/eprom.hpp backend/devices/parallel/eeprom.cpp - backend/devices/parallel/eeprom.hpp ui/qhexeditor.cpp - ui/qhexeditor.hpp ui/mainwindow.cpp - ui/mainwindow.hpp ui/mainwindow.ui ui/settings.cpp - ui/settings.hpp ui/settings.ui main.cpp - main.hpp ) set(PROJECT_RESOURCES diff --git a/software/usbflashprog/backend/devices/parallel/eeprom.cpp b/software/usbflashprog/backend/devices/parallel/eeprom.cpp index 5354fbc3..f612f3af 100644 --- a/software/usbflashprog/backend/devices/parallel/eeprom.cpp +++ b/software/usbflashprog/backend/devices/parallel/eeprom.cpp @@ -46,7 +46,7 @@ EEPROM::EEPROM(QObject *parent) : ParDevice(parent) { size_ = 2048; twp_ = 2; twc_ = 10000; - protectAlgo_ = kCmdDeviceAlgorithm28C; + protectAlgo_ = kCmdDeviceAlgorithm28C64; maxAttemptsProg_ = 3; DEBUG << info_.toString(); } @@ -55,6 +55,8 @@ EEPROM::~EEPROM() {} void EEPROM::setSize(uint32_t value) { ParDevice::setSize(value); + protectAlgo_ = (size_ <= 0x2000) ? kCmdDeviceAlgorithm28C64 + : kCmdDeviceAlgorithm28C256; bool oldValue = info_.capability.hasUnprotect; bool newValue = (size_ >= 0x2000); // >= 8KB if (oldValue != newValue) { @@ -96,11 +98,28 @@ EEPROM28AT::~EEPROM28AT() {} void EEPROM28AT::setSize(uint32_t value) { EEPROM::setSize(value); + switch (size_) { + case 0x02000: // 8KB + case 0x04000: // 16KB + case 0x08000: // 32KB + sectorSize_ = 64; + break; + case 0x10000: // 64KB + case 0x20000: // 128KB + sectorSize_ = 128; + break; + case 0x40000: // 256KB + sectorSize_ = 256; + break; + default: + if (size_ < 0x02000) sectorSize_ = 0; + if (size_ > 0x40000) sectorSize_ = 256; + break; + } bool oldValue = info_.capability.hasSectorSize; bool newValue = (size_ >= 0x2000); // >= 8KB if (oldValue != newValue) { info_.capability.hasSectorSize = newValue; - sectorSize_ = newValue ? 64 : 0; DEBUG << info_.toString(); } } diff --git a/software/usbflashprog/backend/opcodes.hpp b/software/usbflashprog/backend/opcodes.hpp index b12a704d..f44daff7 100644 --- a/software/usbflashprog/backend/opcodes.hpp +++ b/software/usbflashprog/backend/opcodes.hpp @@ -270,11 +270,12 @@ enum kCmdOpCodeEnum { * @details The parameter (one byte) represents the algorithm, and * follows the table: *
- * +------------------------------+ - * |Algorithm| Description | - * | 0x01 | EPROM 27E/W27/27SF | - * | 0x02 | EEPROM 28C | - * +------------------------------+ + * +-------------------------------+ + * |Algorithm| Description | + * | 0x01 | EPROM 27E/W27/27SF | + * | 0x02 | EEPROM 28C64 | + * | 0x03 | EEPROM 28C256/upper | + * +-------------------------------+ ** @see kCmdDeviceAlgorithmEnum */ @@ -284,11 +285,12 @@ enum kCmdOpCodeEnum { * @details The parameter (one byte) represents the algorithm, and * follows the table: *
- * +------------------------------+ - * |Algorithm| Description | - * | 0x01 | EPROM 27E/W27/27SF | - * | 0x02 | EEPROM 28C | - * +------------------------------+ + * +-------------------------------+ + * |Algorithm| Description | + * | 0x01 | EPROM 27E/W27/27SF | + * | 0x02 | EEPROM 28C64 | + * | 0x03 | EEPROM 28C256/upper | + * +-------------------------------+ ** @see kCmdDeviceAlgorithmEnum */ @@ -298,11 +300,12 @@ enum kCmdOpCodeEnum { * @details The parameter (one byte) represents the algorithm, and * follows the table: *
- * +------------------------------+ - * |Algorithm| Description | - * | 0x01 | EPROM 27E/W27/27SF | - * | 0x02 | EEPROM 28C | - * +------------------------------+ + * +-------------------------------+ + * |Algorithm| Description | + * | 0x01 | EPROM 27E/W27/27SF | + * | 0x02 | EEPROM 28C64 | + * | 0x03 | EEPROM 28C256/upper | + * +-------------------------------+ ** @see kCmdDeviceAlgorithmEnum */ @@ -341,8 +344,10 @@ enum kCmdDeviceAlgorithmEnum { kCmdDeviceAlgorithmUnknown = 0x00, /** @brief CMD / DEVICE : Defines an algorithm EPROM 27E/SF/W27. */ kCmdDeviceAlgorithm27E = 0x01, - /** @brief CMD / DEVICE : Defines an algorithm EEPROM 28C. */ - kCmdDeviceAlgorithm28C = 0x02 + /** @brief CMD / DEVICE : Defines an algorithm EEPROM 28C64. */ + kCmdDeviceAlgorithm28C64 = 0x02, + /** @brief CMD / DEVICE : Defines an algorithm EEPROM 28C256 or upper. */ + kCmdDeviceAlgorithm28C256 = 0x03 }; // --------------------------------------------------------------------------- diff --git a/software/usbflashprog/test/CMakeLists.txt b/software/usbflashprog/test/CMakeLists.txt index c98afa2f..7c1e964b 100644 --- a/software/usbflashprog/test/CMakeLists.txt +++ b/software/usbflashprog/test/CMakeLists.txt @@ -27,35 +27,22 @@ FetchContent_MakeAvailable(googletest) set(PROJ_NAME ufprog_test) set(PROJECT_SOURCES - ../config.hpp ../backend/opcodes.cpp - ../backend/opcodes.hpp ../backend/runner.cpp - ../backend/runner.hpp - ../backend/devices/device.hpp ../backend/devices/device.cpp - ../backend/devices/parallel/pdevice.hpp ../backend/devices/parallel/pdevice.cpp - ../backend/devices/parallel/sram.hpp ../backend/devices/parallel/sram.cpp - ../backend/devices/parallel/eprom.hpp ../backend/devices/parallel/eprom.cpp + ../backend/devices/parallel/eeprom.cpp mock/qserialport.hpp emulator/emulator.cpp - emulator/emulator.hpp emulator/chip.cpp - emulator/chip.hpp emulator/sram.cpp - emulator/sram.hpp emulator/eprom.cpp - emulator/eprom.hpp - backend/chip_test.hpp + emulator/eeprom.cpp backend/chip_test.cpp - backend/runner_test.hpp backend/runner_test.cpp - backend/opcodes_test.hpp backend/opcodes_test.cpp - main.hpp main.cpp ) diff --git a/software/usbflashprog/test/backend/chip_test.cpp b/software/usbflashprog/test/backend/chip_test.cpp index 4f352eed..e5637d62 100644 --- a/software/usbflashprog/test/backend/chip_test.cpp +++ b/software/usbflashprog/test/backend/chip_test.cpp @@ -25,10 +25,12 @@ #include "emulator/emulator.hpp" #include "emulator/sram.hpp" #include "emulator/eprom.hpp" +#include "emulator/eeprom.hpp" #include "../../backend/devices/device.hpp" #include "../../backend/devices/parallel/sram.hpp" #include "../../backend/devices/parallel/eprom.hpp" +#include "../../backend/devices/parallel/eeprom.hpp" // --------------------------------------------------------------------------- @@ -123,6 +125,28 @@ TEST_F(ChipTest, epromW27E_test) { delete device; } +TEST_F(ChipTest, eeprom28C_test) { + ChipEEPROM *emuChip = new ChipEEPROM(); + Emulator::setChip(emuChip); + EEPROM28C *device = new EEPROM28C(); + runChipTests(emuChip, device, 0x000800); // 2KB + runChipTests(emuChip, device, 0x002000); // 8KB + runChipTests(emuChip, device, 0x008000); // 32KB + delete emuChip; + delete device; +} + +TEST_F(ChipTest, eeprom28AT_test) { + ChipEEPROM *emuChip = new ChipEEPROM(); + Emulator::setChip(emuChip); + EEPROM28AT *device = new EEPROM28AT(); + runChipTests(emuChip, device, 0x000800); // 2KB + runChipTests(emuChip, device, 0x002000); // 8KB + runChipTests(emuChip, device, 0x008000); // 32KB + delete emuChip; + delete device; +} + // --------------------------------------------------------------------------- void runChipTests(BaseChip *emuChip, Device *device, uint32_t size) { @@ -230,6 +254,24 @@ void runChipTests(BaseChip *emuChip, Device *device, uint32_t size) { EXPECT_EQ(device->program(buffer), true); device->setFastProg(false); } + if (cap.hasProtect || cap.hasUnprotect) { + if (cap.hasProtect) { + GTEST_COUT << "Protect" << std::endl; + EXPECT_EQ(device->protect(), true); + } + if (cap.hasProgram) { + GTEST_COUT << "Program" << std::endl; + EXPECT_EQ(device->program(buffer), true); + } + if (cap.hasUnprotect) { + GTEST_COUT << "Unprotect" << std::endl; + EXPECT_EQ(device->unprotect(), true); + } + if (cap.hasProgram) { + GTEST_COUT << "Program" << std::endl; + EXPECT_EQ(device->program(buffer), true); + } + } if (cap.hasSectorSize && cap.hasProgram && cap.hasErase) { device->setSectorSize(64); GTEST_COUT << "Erase" << std::endl; diff --git a/software/usbflashprog/test/emulator/chip.hpp b/software/usbflashprog/test/emulator/chip.hpp index 63121b7b..aaffaee6 100644 --- a/software/usbflashprog/test/emulator/chip.hpp +++ b/software/usbflashprog/test/emulator/chip.hpp @@ -26,6 +26,32 @@ // --------------------------------------------------------------------------- +/** @ingroup UnitTests + @brief Chip Special Command Structure. */ +typedef struct TChipCommand { + /** @brief Command Address. */ + unsigned long addr; + /** @brief Command Data. */ + unsigned char data; +} TChipCommand; + +// --------------------------------------------------------------------------- + +/** @ingroup UnitTests + @brief Chip Special Command Operation. */ +enum TChipCommandOperation { + /** @brief Unknown Operation. */ + ChipOperationUnknown, + /** @brief Erase Operation. */ + ChipOperationErase, + /** @brief Unprotect Operation. */ + ChipOperationUnprotect, + /** @brief Protect Operation. */ + ChipOperationProtect +}; + +// --------------------------------------------------------------------------- + /** @ingroup UnitTests @brief Chip Emulator Base Abstract Class. @details This is a base class for Chip Emulator.