tstDevEEPROM.cpp revision 627bf68711ac042ab548c6085bc0c7e5c8b91c41
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna/* $Id$ */
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna/** @file
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna * EEPROM 93C46 unit tests.
5f5d1b4cc970b7f06ff8ef6526128e9a27303d88nd */
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna/*
031b91a62d25106ae69d4693475c79618dd5e884fielding * Copyright (C) 2007-2010 Oracle Corporation
031b91a62d25106ae69d4693475c79618dd5e884fielding *
031b91a62d25106ae69d4693475c79618dd5e884fielding * Oracle Corporation confidential
031b91a62d25106ae69d4693475c79618dd5e884fielding * All rights reserved
031b91a62d25106ae69d4693475c79618dd5e884fielding */
031b91a62d25106ae69d4693475c79618dd5e884fielding
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna#include <cppunit/ui/text/TestRunner.h>
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna#include <cppunit/extensions/HelperMacros.h>
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna#include "../DevEEPROM.h"
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquernastatic const uint16_t initialContent[] = {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
3ca6ee111e6044cb463e6dc45b9adcfa3050ff00rbowen 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna};
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna/**
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna * Test fixture for 93C46-compatible EEPROM device emulation.
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna */
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquernaclass EEPROMTest : public CppUnit::TestFixture {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_TEST_SUITE( EEPROMTest );
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_TEST( testRead );
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_TEST( testSequentialRead );
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_TEST( testWrite );
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_TEST( testWriteAll );
397e9a692c0255ea1581b5427894c5fe0da68f83jerenkrantz CPPUNIT_TEST( testWriteDisabled );
9b68f730221daaa1d7576a157b93358f62e70533takashi CPPUNIT_TEST( testErase );
9b68f730221daaa1d7576a157b93358f62e70533takashi CPPUNIT_TEST( testEraseAll );
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz CPPUNIT_TEST_SUITE_END();
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantzprivate:
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna enum Wires { DO=8, DI=4, CS=2, SK=0x01 };
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna enum OpCodes {
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin READ_OPCODE = 0x6,
1a2bc936a6b4aaf5713c98a230a449fd878d1f06takashi WRITE_OPCODE = 0x5,
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd ERASE_OPCODE = 0x7,
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin EWDS_OPCODE = 0x10, // erase/write disable
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd WRAL_OPCODE = 0x11, // write all
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna ERAL_OPCODE = 0x12, // erase all
8da42f0eb0217374d9519e9c9ca8fc3b90ccbaf6colm EWEN_OPCODE = 0x13 // erase/write enable
8da42f0eb0217374d9519e9c9ca8fc3b90ccbaf6colm };
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun enum BitWidths {
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun READ_OPCODE_BITS = 3,
c9c3d339c0f2b9485326e059b6ec9c081ae9565ecolm WRITE_OPCODE_BITS = 3,
8da42f0eb0217374d9519e9c9ca8fc3b90ccbaf6colm ERASE_OPCODE_BITS = 3,
b09705acacab4c960c608c71377aa3ec2bf9e8a1colm EWDS_OPCODE_BITS = 5,
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun WRAL_OPCODE_BITS = 5,
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun ERAL_OPCODE_BITS = 5,
2a869ee6594f1e3e9039af332cd73f939509483acolm EWEN_OPCODE_BITS = 5,
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun READ_ADDR_BITS = 6,
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun WRITE_ADDR_BITS = 6,
b09705acacab4c960c608c71377aa3ec2bf9e8a1colm ERASE_ADDR_BITS = 6,
b09705acacab4c960c608c71377aa3ec2bf9e8a1colm EWDS_ADDR_BITS = 4,
b09705acacab4c960c608c71377aa3ec2bf9e8a1colm WRAL_ADDR_BITS = 4,
b09705acacab4c960c608c71377aa3ec2bf9e8a1colm ERAL_ADDR_BITS = 4,
b09705acacab4c960c608c71377aa3ec2bf9e8a1colm EWEN_ADDR_BITS = 4,
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna DATA_BITS = 16
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun };
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna EEPROM93C46 *eeprom;
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
44ee9a92415caf6322119d0ca2d20e169e3a1525takashi // Helper methods
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna void shiftOutBits(uint16_t data, uint16_t count);
6b797d6bd26bbf8589eb0e2b6cfa2fa808f456b1pquerna uint16_t shiftInBits(uint16_t count);
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun void getReady();
6b797d6bd26bbf8589eb0e2b6cfa2fa808f456b1pquerna void standby();
91be90604bd426eb406711cf00e1380966bdcf81jorton void stop();
91be90604bd426eb406711cf00e1380966bdcf81jorton uint16_t readAt(uint16_t addr);
91be90604bd426eb406711cf00e1380966bdcf81jorton bool writeTo(uint16_t addr, uint16_t value);
6b797d6bd26bbf8589eb0e2b6cfa2fa808f456b1pquerna void writeOpAddr(int opCode, int opCodeBits, uint16_t addr, int addrBits);
7248fa34fc5d506ec1f37a929f939fe075c1a030niq void writeData(uint16_t value) { shiftOutBits(value, DATA_BITS); }
7248fa34fc5d506ec1f37a929f939fe075c1a030niq bool waitForCompletion();
7248fa34fc5d506ec1f37a929f939fe075c1a030niq
7248fa34fc5d506ec1f37a929f939fe075c1a030niqpublic:
7248fa34fc5d506ec1f37a929f939fe075c1a030niq void setUp()
7248fa34fc5d506ec1f37a929f939fe075c1a030niq {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna eeprom = new EEPROM93C46;
88505bf463771d152b14e5d513a4562175183e31jorton eeprom->init(initialContent);
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun }
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun void tearDown()
88505bf463771d152b14e5d513a4562175183e31jorton {
ea8572f0df1c69b398e9d677648a0fa5f31b2d60pquerna delete eeprom;
e678e297836a60ee5a456f110cac71377763b96etakashi }
ea8572f0df1c69b398e9d677648a0fa5f31b2d60pquerna
ea8572f0df1c69b398e9d677648a0fa5f31b2d60pquerna void testSize()
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun {
ea8572f0df1c69b398e9d677648a0fa5f31b2d60pquerna CPPUNIT_ASSERT_EQUAL( sizeof(initialContent), (size_t)EEPROM93C46::SIZE );
ea8572f0df1c69b398e9d677648a0fa5f31b2d60pquerna }
5c915a9a86688ef70d4e17a5a459f85e9f0e5d00niq
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun void testRead()
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun {
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun getReady();
5c915a9a86688ef70d4e17a5a459f85e9f0e5d00niq for ( uint32_t wordAddr=0; wordAddr < EEPROM93C46::SIZE; wordAddr++ ) {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna shiftOutBits(READ_OPCODE, READ_OPCODE_BITS);
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna shiftOutBits(wordAddr, READ_ADDR_BITS);
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_ASSERT_EQUAL( initialContent[wordAddr], (uint16_t)wordAddr );
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_ASSERT_EQUAL( initialContent[wordAddr], shiftInBits(DATA_BITS) );
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna standby();
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz }
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz stop();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun }
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun void testSequentialRead()
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun {
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun getReady();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun shiftOutBits(READ_OPCODE, READ_OPCODE_BITS);
9b68f730221daaa1d7576a157b93358f62e70533takashi shiftOutBits(0, READ_ADDR_BITS);
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz for ( int wordAddr=0; wordAddr < EEPROM93C46::SIZE; wordAddr++ ) {
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz CPPUNIT_ASSERT_EQUAL( initialContent[wordAddr], shiftInBits(DATA_BITS) );
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz }
a6fc6b44b7f8ad7390864b3555341d3abf867f7end stop();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun }
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun void testWrite()
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun {
9cd3b05d7b70f07a742bbaf548fa4fa2bdbe5ce6noodl //unused: int i;
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna uint16_t wordAddr;
e678e297836a60ee5a456f110cac71377763b96etakashi
e678e297836a60ee5a456f110cac71377763b96etakashi getReady();
e678e297836a60ee5a456f110cac71377763b96etakashi // Enable write
e678e297836a60ee5a456f110cac71377763b96etakashi writeOpAddr(EWEN_OPCODE, EWEN_OPCODE_BITS, 0, EWEN_ADDR_BITS);
e678e297836a60ee5a456f110cac71377763b96etakashi standby();
e678e297836a60ee5a456f110cac71377763b96etakashi
e678e297836a60ee5a456f110cac71377763b96etakashi for ( wordAddr=0; wordAddr < EEPROM93C46::SIZE; wordAddr++ ) {
e678e297836a60ee5a456f110cac71377763b96etakashi //writeOpAddr(WRITE_OPCODE, WRITE_OPCODE_BITS, (uint16_t)wordAddr, WRITE_ADDR_BITS);
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna writeTo(wordAddr, 0x3F00 - (wordAddr<<8));
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna standby();
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun if (!waitForCompletion()) {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_FAIL("EEPROM write was not completed");
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna stop();
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna return;
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna }
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna standby();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun }
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna // Disable write
82d4a929c9d891a758667c94e09c871358acf6ecjerenkrantz writeOpAddr(EWDS_OPCODE, EWDS_OPCODE_BITS, 0, EWDS_ADDR_BITS);
82d4a929c9d891a758667c94e09c871358acf6ecjerenkrantz
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun stop();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna // Now check the result
82d4a929c9d891a758667c94e09c871358acf6ecjerenkrantz getReady();
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna writeOpAddr(READ_OPCODE, READ_OPCODE_BITS, 0, READ_ADDR_BITS);
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna for ( wordAddr=0; wordAddr < EEPROM93C46::SIZE; wordAddr++ ) {
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna CPPUNIT_ASSERT_EQUAL((uint16_t)(0x3F00 - (wordAddr<<8)), shiftInBits(DATA_BITS) );
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna }
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna stop();
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna }
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna void testWriteDisabled()
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna {
5b6890f4bf64eff2abec93f06ad5b5cb7560f780pquerna getReady();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
ae98487433ef989150195609ec88ba323b46bb51pquerna uint16_t addr = 0;
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun uint16_t oldValue = readAt(addr);
362f98329c05da7b953ca60d0ad9045412e5f9d6pquerna stop();
362f98329c05da7b953ca60d0ad9045412e5f9d6pquerna getReady();
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna if (writeTo(addr, ~oldValue)) {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna // Write appears to be successful -- continue
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_ASSERT_EQUAL(oldValue, readAt(addr));
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna }
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna else {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_FAIL("EEPROM write was not completed");
1d9308ed0075062953a246d16bcda888a1be1adeslive }
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna stop();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun }
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun void testErase()
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna int i;
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz uint16_t addr = 0x1F;
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz getReady();
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz // Enable write
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun shiftOutBits(EWEN_OPCODE, EWEN_OPCODE_BITS);
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun shiftOutBits(0, EWEN_ADDR_BITS);
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun standby();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun if (writeTo(addr, addr)) {
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun stop();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun getReady();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun // Write successful -- continue
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz CPPUNIT_ASSERT_EQUAL(addr, readAt(addr));
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz stop();
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz getReady();
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz
5c3c22e3324f26848c1782e711c24faf28136012jerenkrantz shiftOutBits(ERASE_OPCODE, ERASE_OPCODE_BITS);
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna shiftOutBits(addr, ERASE_ADDR_BITS);
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna standby();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna for (i = 0; i < 200; i++) {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna if (eeprom->read() & DO)
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna break;
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna //usec_delay(50);
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna }
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd if (i == 200) {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna CPPUNIT_FAIL("EEPROM erase was not completed");
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna stop();
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna return;
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun }
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna standby();
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna shiftOutBits(EWDS_OPCODE, EWDS_OPCODE_BITS);
7248fa34fc5d506ec1f37a929f939fe075c1a030niq shiftOutBits(0, EWDS_ADDR_BITS);
7248fa34fc5d506ec1f37a929f939fe075c1a030niq
7248fa34fc5d506ec1f37a929f939fe075c1a030niq stop();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun getReady();
7248fa34fc5d506ec1f37a929f939fe075c1a030niq CPPUNIT_ASSERT_EQUAL((uint16_t)0xFFFF, readAt(addr));
7248fa34fc5d506ec1f37a929f939fe075c1a030niq }
7248fa34fc5d506ec1f37a929f939fe075c1a030niq else {
7248fa34fc5d506ec1f37a929f939fe075c1a030niq CPPUNIT_FAIL("EEPROM write was not completed");
7248fa34fc5d506ec1f37a929f939fe075c1a030niq }
5c915a9a86688ef70d4e17a5a459f85e9f0e5d00niq stop();
5c915a9a86688ef70d4e17a5a459f85e9f0e5d00niq }
5c915a9a86688ef70d4e17a5a459f85e9f0e5d00niq
5c915a9a86688ef70d4e17a5a459f85e9f0e5d00niq void testWriteAll()
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun {
91be90604bd426eb406711cf00e1380966bdcf81jorton uint16_t addr;
91be90604bd426eb406711cf00e1380966bdcf81jorton
91be90604bd426eb406711cf00e1380966bdcf81jorton getReady();
91be90604bd426eb406711cf00e1380966bdcf81jorton // Enable write
91be90604bd426eb406711cf00e1380966bdcf81jorton writeOpAddr(EWEN_OPCODE, EWEN_OPCODE_BITS, 0, EWEN_ADDR_BITS);
91be90604bd426eb406711cf00e1380966bdcf81jorton standby();
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun // Fill all memory
91be90604bd426eb406711cf00e1380966bdcf81jorton writeOpAddr(WRAL_OPCODE, WRAL_OPCODE_BITS, 0, WRAL_ADDR_BITS);
26be97276918b2dbf2b49852c4c9203552e5e40eniq writeData(0xABBA);
91be90604bd426eb406711cf00e1380966bdcf81jorton standby();
7dd2be584ba36c686d9f748b55451f54f0043bccniq
7dd2be584ba36c686d9f748b55451f54f0043bccniq if (waitForCompletion()) {
7dd2be584ba36c686d9f748b55451f54f0043bccniq stop();
7dd2be584ba36c686d9f748b55451f54f0043bccniq getReady();
7dd2be584ba36c686d9f748b55451f54f0043bccniq // Write successful -- verify all memory
7dd2be584ba36c686d9f748b55451f54f0043bccniq for ( addr=0; addr < EEPROM93C46::SIZE; addr++ ) {
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun CPPUNIT_ASSERT_EQUAL((uint16_t)0xABBA, readAt(addr));
98f1378491b66e5383a5340d9afe91dabf7f5010colm }
7dd2be584ba36c686d9f748b55451f54f0043bccniq }
98f1378491b66e5383a5340d9afe91dabf7f5010colm else {
7dd2be584ba36c686d9f748b55451f54f0043bccniq CPPUNIT_FAIL("EEPROM write was not completed");
d875a16355b0db5971788e6374841ea5aa6e6b86nilgun }
7dd2be584ba36c686d9f748b55451f54f0043bccniq stop();
7dd2be584ba36c686d9f748b55451f54f0043bccniq }
7dd2be584ba36c686d9f748b55451f54f0043bccniq
7dd2be584ba36c686d9f748b55451f54f0043bccniq void testEraseAll()
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna {
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna //unused: int i;
0c294487ab3a4e567dc574bb2ad81c7ce07cfd31pquerna uint16_t addr = 0x1F;
getReady();
// Enable write
writeOpAddr(EWEN_OPCODE, EWEN_OPCODE_BITS, 0, EWEN_ADDR_BITS);
standby();
// Fill all memory
writeOpAddr(WRITE_OPCODE, WRITE_OPCODE_BITS, addr, WRITE_ADDR_BITS);
writeData(0);
standby();
if (waitForCompletion()) {
stop();
getReady();
// Write successful -- verify random location
CPPUNIT_ASSERT_EQUAL((uint16_t)0, readAt(addr));
stop();
getReady();
writeOpAddr(ERAL_OPCODE, ERAL_OPCODE_BITS, addr, ERAL_ADDR_BITS);
standby();
if (!waitForCompletion()) {
CPPUNIT_FAIL("EEPROM erase was not completed");
stop();
return;
}
standby();
writeOpAddr(EWDS_OPCODE, EWDS_OPCODE_BITS, 0, EWDS_ADDR_BITS);
stop();
getReady();
for ( addr=0; addr < EEPROM93C46::SIZE; addr++ ) {
CPPUNIT_ASSERT_EQUAL((uint16_t)0xFFFF, readAt(addr));
}
}
else {
CPPUNIT_FAIL("EEPROM write was not completed");
}
stop();
}
};
/**
* shiftOutBits - Shift data bits our to the EEPROM
* @hw: pointer to the EEPROM object
* @data: data to send to the EEPROM
* @count: number of bits to shift out
*
* We need to shift 'count' bits out to the EEPROM. So, the value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
**/
void EEPROMTest::shiftOutBits(uint16_t data, uint16_t count) {
uint32_t wires = eeprom->read();
uint32_t mask;
mask = 0x01 << (count - 1);
wires &= ~DO;
do {
wires &= ~DI;
if (data & mask)
wires |= DI;
eeprom->write(wires);
// Raise clock
eeprom->write(wires |= SK);
// Lower clock
eeprom->write(wires &= ~SK);
mask >>= 1;
} while (mask);
wires &= ~DI;
eeprom->write(wires);
}
/**
* shiftInBits - Shift data bits in from the EEPROM
* @count: number of bits to shift in
*
* In order to read a register from the EEPROM, we need to shift 'count' bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the data out
* "DO" bit. During this "shifting in" process the data in "DI" bit should
* always be clear.
**/
uint16_t EEPROMTest::shiftInBits(uint16_t count)
{
uint32_t wires;
uint32_t i;
uint16_t data;
wires = eeprom->read();
wires &= ~(DO | DI);
data = 0;
for (i = 0; i < count; i++) {
data <<= 1;
// Raise clock
eeprom->write(wires |= SK);
wires = eeprom->read();
wires &= ~DI;
if (wires & DO)
data |= 1;
// Lower clock
eeprom->write(wires &= ~SK);
}
return data;
}
/**
* getReady - Prepares EEPROM for read/write
*
* Setups the EEPROM for reading and writing.
**/
void EEPROMTest::getReady()
{
unsigned wires = eeprom->read();
/* Clear SK and DI */
eeprom->write(wires &= ~(DI | SK));
/* Set CS */
eeprom->write(wires | CS);
}
/**
* standby - Return EEPROM to standby state
*
* Return the EEPROM to a standby state.
**/
void EEPROMTest::standby()
{
unsigned wires = eeprom->read();
eeprom->write(wires &= ~(CS | SK));
// Raise clock
eeprom->write(wires |= SK);
// Select EEPROM
eeprom->write(wires |= CS);
// Lower clock
eeprom->write(wires &= ~SK);
}
/**
* stop - Terminate EEPROM command
*
* Terminates the current command by inverting the EEPROM's chip select pin.
**/
void EEPROMTest::stop()
{
unsigned wires = eeprom->read();
eeprom->write(wires &= ~(CS | DI));
// Raise clock
eeprom->write(wires |= SK);
// Lower clock
eeprom->write(wires &= ~SK);
}
/**
* readAt - Read a word at specified address
* @addr: address to read
*
* Returns the value of the word specified in 'addr' parameter.
**/
uint16_t EEPROMTest::readAt(uint16_t addr)
{
getReady();
shiftOutBits(READ_OPCODE, READ_OPCODE_BITS);
shiftOutBits(addr, READ_ADDR_BITS);
uint16_t value = shiftInBits(DATA_BITS);
stop();
return value;
}
/**
* writeTo - Write a word to specified address
* @addr: address to write to
* @value: value to store
*
* Returns false if write did not complete.
*
* Note: Make sure EEPROM is selected and writable before attempting
* to write. Use getReady() and stop() to select/deselect
* EEPROM.
**/
bool EEPROMTest::writeTo(uint16_t addr, uint16_t value)
{
writeOpAddr(WRITE_OPCODE, WRITE_OPCODE_BITS, addr, WRITE_ADDR_BITS);
writeData(value);
standby();
return waitForCompletion();
}
/**
* waitForCompletion - Wait until EEPROM clears the busy bit
*
* Returns false if the EEPROM is still busy.
*/
bool EEPROMTest::waitForCompletion() {
for (int i = 0; i < 200; i++) {
if (eeprom->read() & DO) {
standby();
return true;
}
// Wait 50 usec;
}
return false;
}
/**
* writeOpAddr - Write an opcode and address
* @opCode: operation code
* @opCodeBits: number of bits in opCode
* @addr: address to write to
* @addrBits: number of bits in address
**/
void EEPROMTest::writeOpAddr(int opCode, int opCodeBits, uint16_t addr, int addrBits)
{
shiftOutBits(opCode, opCodeBits);
shiftOutBits(addr, addrBits);
}
// Create text test runner and run all tests.
int main( int argc, char **argv)
{
CppUnit::TextUi::TestRunner runner;
runner.addTest( EEPROMTest::suite() );
return runner.run() ? 0 : 1;
}