tstDevEEPROM.cpp revision ebadd079ca810bb81e096f06de95a734a500cef6
/* $Id$ */
/** @file
* EEPROM 93C46 unit tests.
*/
/*
* Copyright (C) 2007-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "../DevEEPROM.h"
static const uint16_t initialContent[] = {
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f
};
/**
* Test fixture for 93C46-compatible EEPROM device emulation.
*/
CPPUNIT_TEST( testRead );
private:
enum OpCodes {
READ_OPCODE = 0x6,
WRITE_OPCODE = 0x5,
ERASE_OPCODE = 0x7,
};
enum BitWidths {
READ_OPCODE_BITS = 3,
WRITE_OPCODE_BITS = 3,
ERASE_OPCODE_BITS = 3,
EWDS_OPCODE_BITS = 5,
WRAL_OPCODE_BITS = 5,
ERAL_OPCODE_BITS = 5,
EWEN_OPCODE_BITS = 5,
READ_ADDR_BITS = 6,
WRITE_ADDR_BITS = 6,
ERASE_ADDR_BITS = 6,
EWDS_ADDR_BITS = 4,
WRAL_ADDR_BITS = 4,
ERAL_ADDR_BITS = 4,
EWEN_ADDR_BITS = 4,
DATA_BITS = 16
};
// Helper methods
void getReady();
void standby();
void stop();
bool waitForCompletion();
public:
void setUp()
{
eeprom = new EEPROM93C46;
}
void tearDown()
{
delete eeprom;
}
void testSize()
{
}
void testRead()
{
getReady();
standby();
}
stop();
}
void testSequentialRead()
{
getReady();
}
stop();
}
void testWrite()
{
//unused: int i;
getReady();
// Enable write
standby();
//writeOpAddr(WRITE_OPCODE, WRITE_OPCODE_BITS, (uint16_t)wordAddr, WRITE_ADDR_BITS);
standby();
if (!waitForCompletion()) {
CPPUNIT_FAIL("EEPROM write was not completed");
stop();
return;
}
standby();
}
// Disable write
stop();
// Now check the result
getReady();
}
stop();
}
void testWriteDisabled()
{
getReady();
stop();
getReady();
// Write appears to be successful -- continue
}
else {
CPPUNIT_FAIL("EEPROM write was not completed");
}
stop();
}
void testErase()
{
int i;
getReady();
// Enable write
standby();
stop();
getReady();
// Write successful -- continue
stop();
getReady();
standby();
for (i = 0; i < 200; i++) {
break;
//usec_delay(50);
}
if (i == 200) {
CPPUNIT_FAIL("EEPROM erase was not completed");
stop();
return;
}
standby();
stop();
getReady();
}
else {
CPPUNIT_FAIL("EEPROM write was not completed");
}
stop();
}
void testWriteAll()
{
getReady();
// Enable write
standby();
// Fill all memory
writeData(0xABBA);
standby();
if (waitForCompletion()) {
stop();
getReady();
// Write successful -- verify all memory
}
}
else {
CPPUNIT_FAIL("EEPROM write was not completed");
}
stop();
}
void testEraseAll()
{
//unused: int i;
getReady();
// Enable write
standby();
// Fill all memory
writeData(0);
standby();
if (waitForCompletion()) {
stop();
getReady();
// Write successful -- verify random location
stop();
getReady();
standby();
if (!waitForCompletion()) {
CPPUNIT_FAIL("EEPROM erase was not completed");
stop();
return;
}
standby();
stop();
getReady();
}
}
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.
**/
do {
// Raise clock
// Lower clock
mask >>= 1;
} while (mask);
}
/**
* 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.
**/
{
uint32_t i;
data = 0;
for (i = 0; i < count; i++) {
data <<= 1;
// Raise clock
data |= 1;
// Lower clock
}
return data;
}
/**
*
* Setups the EEPROM for reading and writing.
**/
void EEPROMTest::getReady()
{
/* Clear SK and DI */
/* Set CS */
}
/**
* standby - Return EEPROM to standby state
*
* Return the EEPROM to a standby state.
**/
void EEPROMTest::standby()
{
// Raise clock
// Select EEPROM
// Lower clock
}
/**
* stop - Terminate EEPROM command
*
* Terminates the current command by inverting the EEPROM's chip select pin.
**/
void EEPROMTest::stop()
{
// Raise clock
// Lower clock
}
/**
* readAt - Read a word at specified address
* @addr: address to read
*
* Returns the value of the word specified in 'addr' parameter.
**/
{
getReady();
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
* EEPROM.
**/
{
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++) {
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
**/
{
}
// Create text test runner and run all tests.
{
}