TommyPROM/HardwareVerify/PromDevice.cpp

110 lines
2.8 KiB
C++

#include "Configure.h"
#include "PromDevice.h"
PromDevice::PromDevice(unsigned long size, word blockSize, unsigned maxWriteTime, bool polling)
: mSize(size),
mBlockSize(blockSize),
mMaxWriteTime(maxWriteTime),
mSupportsDataPoll(polling)
{
}
// Write a block of data to the device. If the device supports block writes,
// the data will be broken into chunks and written using the block mode.
// Otherwise, each byte will be individually written and verified.
bool PromDevice::writeData(byte data[], word len, word address)
{
bool status = true;
if (mBlockSize == 0)
{
// Device does not support block writes.
for (word ix = 0; (ix < len); ix++)
{
if (burnByte(data[ix], address + ix) == false)
{
status = false;
break;
}
}
}
else
{
word offset = 0;
word chunkSize;
if (address & (mBlockSize - 1))
{
// Address does not start on a block boundary. Adjust the size of
// the first block to fit within a single block.
chunkSize = mBlockSize - (address & (mBlockSize - 1));
chunkSize = (chunkSize > len) ? len : chunkSize;
if (burnBlock(data, chunkSize, address) == false)
{
return false;
}
offset += chunkSize;
len -= chunkSize;
}
// All writes are now aligned to block boundaries, so write full blocks
// or remaining length, whichever is smaller.
while (len > 0)
{
chunkSize = (len > mBlockSize) ? mBlockSize : len;
if (burnBlock(data + offset, chunkSize, address + offset) == false)
{
status = false;
break;
}
offset += chunkSize;
len -= chunkSize;
}
}
return status;
}
// BEGIN PRIVATE METHODS
//
// Set the I/O state of the data bus.
// The first two bits of port D are used for serial, so the 8 bits data bus are
// on pins D2..D9.
void PromDevice::setDataBusMode(uint8_t mode)
{
// On the Uno and Nano, D2..D9 maps to the upper 6 bits of port D and the
// lower 2 bits of port B.
if (mode == OUTPUT)
{
DDRB |= 0x03;
DDRD |= 0xfc;
}
else
{
DDRB &= 0xfc;
DDRD &= 0x03;
}
}
// Read a byte from the data bus. The caller must set the bus to input_mode
// before calling this or no useful data will be returned.
byte PromDevice::readDataBus()
{
return (PINB << 6) | (PIND >> 2);
}
// Write a byte to the data bus. The caller must set the bus to output_mode
// before calling this or no data will be written.
void PromDevice::writeDataBus(byte data)
{
PORTB = (PORTB & 0xfc) | (data >> 6);
PORTD = (PORTD & 0x03) | (data << 2);
}