mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Replace the Error() object with an error() function which takes fmt
formatspecs, making for much cleaner code. Reformatted everything. This actually happened in multiple steps but then I corrupted my local repository and I had to recover from the working tree.
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
#include "protocol.h"
|
||||
#include "fluxmap.h"
|
||||
#include "bytes.h"
|
||||
#include "fmt/format.h"
|
||||
#include "lib/usb/usb.pb.h"
|
||||
#include "greaseweazle.h"
|
||||
#include "serial.h"
|
||||
@@ -12,25 +11,38 @@ static const char* gw_error(int e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case ACK_OKAY: return "OK";
|
||||
case ACK_BAD_COMMAND: return "Bad command";
|
||||
case ACK_NO_INDEX: return "No index";
|
||||
case ACK_NO_TRK0: return "No track 0";
|
||||
case ACK_FLUX_OVERFLOW: return "Overflow";
|
||||
case ACK_FLUX_UNDERFLOW: return "Underflow";
|
||||
case ACK_WRPROT: return "Write protected";
|
||||
case ACK_NO_UNIT: return "No unit";
|
||||
case ACK_NO_BUS: return "No bus";
|
||||
case ACK_BAD_UNIT: return "Invalid unit";
|
||||
case ACK_BAD_PIN: return "Invalid pin";
|
||||
case ACK_BAD_CYLINDER: return "Invalid track";
|
||||
default: return "Unknown error";
|
||||
case ACK_OKAY:
|
||||
return "OK";
|
||||
case ACK_BAD_COMMAND:
|
||||
return "Bad command";
|
||||
case ACK_NO_INDEX:
|
||||
return "No index";
|
||||
case ACK_NO_TRK0:
|
||||
return "No track 0";
|
||||
case ACK_FLUX_OVERFLOW:
|
||||
return "Overflow";
|
||||
case ACK_FLUX_UNDERFLOW:
|
||||
return "Underflow";
|
||||
case ACK_WRPROT:
|
||||
return "Write protected";
|
||||
case ACK_NO_UNIT:
|
||||
return "No unit";
|
||||
case ACK_NO_BUS:
|
||||
return "No bus";
|
||||
case ACK_BAD_UNIT:
|
||||
return "Invalid unit";
|
||||
case ACK_BAD_PIN:
|
||||
return "Invalid pin";
|
||||
case ACK_BAD_CYLINDER:
|
||||
return "Invalid track";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t ss_rand_next(uint32_t x)
|
||||
{
|
||||
return (x&1) ? (x>>1) ^ 0x80000062 : x>>1;
|
||||
return (x & 1) ? (x >> 1) ^ 0x80000062 : x >> 1;
|
||||
}
|
||||
|
||||
class GreaseWeazleUsb : public USB
|
||||
@@ -41,10 +53,8 @@ private:
|
||||
uint8_t buffer[4];
|
||||
_serial->read(buffer, sizeof(buffer));
|
||||
|
||||
return ((buffer[0] & 0xfe) >> 1)
|
||||
| ((buffer[1] & 0xfe) << 6)
|
||||
| ((buffer[2] & 0xfe) << 13)
|
||||
| ((buffer[3] & 0xfe) << 20);
|
||||
return ((buffer[0] & 0xfe) >> 1) | ((buffer[1] & 0xfe) << 6) |
|
||||
((buffer[2] & 0xfe) << 13) | ((buffer[3] & 0xfe) << 20);
|
||||
}
|
||||
|
||||
void do_command(const Bytes& command)
|
||||
@@ -55,16 +65,20 @@ private:
|
||||
_serial->read(buffer, sizeof(buffer));
|
||||
|
||||
if (buffer[0] != command[0])
|
||||
Error() << fmt::format("command returned garbage (0x{:x} != 0x{:x} with status 0x{:x})",
|
||||
buffer[0], command[0], buffer[1]);
|
||||
error(
|
||||
"command returned garbage (0x{:x} != 0x{:x} with status "
|
||||
"0x{:x})",
|
||||
buffer[0],
|
||||
command[0],
|
||||
buffer[1]);
|
||||
if (buffer[1])
|
||||
Error() << fmt::format("GreaseWeazle error: {}", gw_error(buffer[1]));
|
||||
error("GreaseWeazle error: {}", gw_error(buffer[1]));
|
||||
}
|
||||
|
||||
public:
|
||||
GreaseWeazleUsb(const std::string& port, const GreaseWeazleProto& config):
|
||||
_serial(SerialPort::openSerialPort(port)),
|
||||
_config(config)
|
||||
_serial(SerialPort::openSerialPort(port)),
|
||||
_config(config)
|
||||
{
|
||||
int version = getVersion();
|
||||
if (version >= 29)
|
||||
@@ -75,18 +89,21 @@ public:
|
||||
_version = V22;
|
||||
else
|
||||
{
|
||||
Error() << "only GreaseWeazle firmware versions 22 and 24 or above are currently "
|
||||
<< "supported, but you have version " << version << ". Please file a bug.";
|
||||
error(
|
||||
"only GreaseWeazle firmware versions 22 and 24 or above are "
|
||||
"currently "
|
||||
"supported, but you have version {}. Please file a bug.",
|
||||
version);
|
||||
}
|
||||
|
||||
/* Configure the hardware. */
|
||||
|
||||
do_command({ CMD_SET_BUS_TYPE, 3, (uint8_t)config.bus_type() });
|
||||
do_command({CMD_SET_BUS_TYPE, 3, (uint8_t)config.bus_type()});
|
||||
}
|
||||
|
||||
int getVersion()
|
||||
{
|
||||
do_command({ CMD_GET_INFO, 3, GETINFO_FIRMWARE });
|
||||
do_command({CMD_GET_INFO, 3, GETINFO_FIRMWARE});
|
||||
|
||||
Bytes response = _serial->readBytes(32);
|
||||
ByteReader br(response);
|
||||
@@ -103,16 +120,16 @@ public:
|
||||
{
|
||||
seek(0);
|
||||
}
|
||||
|
||||
|
||||
void seek(int track)
|
||||
{
|
||||
do_command({ CMD_SEEK, 3, (uint8_t)track });
|
||||
do_command({CMD_SEEK, 3, (uint8_t)track});
|
||||
}
|
||||
|
||||
|
||||
nanoseconds_t getRotationalPeriod(int hardSectorCount)
|
||||
{
|
||||
if (hardSectorCount != 0)
|
||||
Error() << "hard sectors are currently unsupported on the GreaseWeazel";
|
||||
error("hard sectors are currently unsupported on the GreaseWeazel");
|
||||
|
||||
/* The GreaseWeazle doesn't have a command to fetch the period directly,
|
||||
* so we have to do a flux read. */
|
||||
@@ -120,7 +137,7 @@ public:
|
||||
switch (_version)
|
||||
{
|
||||
case V22:
|
||||
do_command({ CMD_READ_FLUX, 2 });
|
||||
do_command({CMD_READ_FLUX, 2});
|
||||
break;
|
||||
|
||||
case V24:
|
||||
@@ -130,8 +147,8 @@ public:
|
||||
cmd.writer()
|
||||
.write_8(CMD_READ_FLUX)
|
||||
.write_8(cmd.size())
|
||||
.write_le32(0) //ticks default value (guessed)
|
||||
.write_le16(2);//revolutions
|
||||
.write_le32(0) // ticks default value (guessed)
|
||||
.write_le16(2); // revolutions
|
||||
do_command(cmd);
|
||||
}
|
||||
}
|
||||
@@ -164,7 +181,7 @@ public:
|
||||
break;
|
||||
|
||||
default:
|
||||
Error() << "bad opcode in GreaseWeazle stream";
|
||||
error("bad opcode in GreaseWeazle stream");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -173,24 +190,26 @@ public:
|
||||
ticks_gw += b;
|
||||
else
|
||||
{
|
||||
int delta = 250 + (b-250)*255 + _serial->readByte() - 1;
|
||||
int delta = 250 + (b - 250) * 255 + _serial->readByte() - 1;
|
||||
ticks_gw += delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (secondindex == ~0)
|
||||
Error() << "unable to determine disk rotational period (is a disk in the drive?)";
|
||||
do_command({ CMD_GET_FLUX_STATUS, 2 });
|
||||
error(
|
||||
"unable to determine disk rotational period (is a disk in the "
|
||||
"drive?)");
|
||||
do_command({CMD_GET_FLUX_STATUS, 2});
|
||||
|
||||
_revolutions = (nanoseconds_t)(secondindex - firstindex) * _clock;
|
||||
return _revolutions;
|
||||
}
|
||||
|
||||
|
||||
void testBulkWrite()
|
||||
{
|
||||
std::cout << "Writing data: " << std::flush;
|
||||
const int LEN = 10*1024*1024;
|
||||
const int LEN = 10 * 1024 * 1024;
|
||||
Bytes cmd;
|
||||
switch (_version)
|
||||
{
|
||||
@@ -220,24 +239,27 @@ public:
|
||||
|
||||
Bytes junk(LEN);
|
||||
uint32_t seed = 0;
|
||||
for (int i=0; i<LEN; i++)
|
||||
for (int i = 0; i < LEN; i++)
|
||||
{
|
||||
junk[i] = seed;
|
||||
seed = ss_rand_next(seed);
|
||||
}
|
||||
double start_time = getCurrentTime();
|
||||
double start_time = getCurrentTime();
|
||||
_serial->write(junk);
|
||||
_serial->readBytes(1);
|
||||
double elapsed_time = getCurrentTime() - start_time;
|
||||
double elapsed_time = getCurrentTime() - start_time;
|
||||
|
||||
std::cout << fmt::format("transferred {} bytes from PC -> device in {} ms ({} kb/s)\n",
|
||||
LEN, int(elapsed_time * 1000.0), int((LEN / 1024.0) / elapsed_time));
|
||||
std::cout << fmt::format(
|
||||
"transferred {} bytes from PC -> device in {} ms ({} kb/s)\n",
|
||||
LEN,
|
||||
int(elapsed_time * 1000.0),
|
||||
int((LEN / 1024.0) / elapsed_time));
|
||||
}
|
||||
|
||||
|
||||
void testBulkRead()
|
||||
{
|
||||
std::cout << "Reading data: " << std::flush;
|
||||
const int LEN = 10*1024*1024;
|
||||
const int LEN = 10 * 1024 * 1024;
|
||||
Bytes cmd;
|
||||
switch (_version)
|
||||
{
|
||||
@@ -265,26 +287,32 @@ public:
|
||||
}
|
||||
do_command(cmd);
|
||||
|
||||
double start_time = getCurrentTime();
|
||||
double start_time = getCurrentTime();
|
||||
_serial->readBytes(LEN);
|
||||
double elapsed_time = getCurrentTime() - start_time;
|
||||
double elapsed_time = getCurrentTime() - start_time;
|
||||
|
||||
std::cout << fmt::format("transferred {} bytes from device -> PC in {} ms ({} kb/s)\n",
|
||||
LEN, int(elapsed_time * 1000.0), int((LEN / 1024.0) / elapsed_time));
|
||||
std::cout << fmt::format(
|
||||
"transferred {} bytes from device -> PC in {} ms ({} kb/s)\n",
|
||||
LEN,
|
||||
int(elapsed_time * 1000.0),
|
||||
int((LEN / 1024.0) / elapsed_time));
|
||||
}
|
||||
|
||||
Bytes read(int side, bool synced, nanoseconds_t readTime, nanoseconds_t hardSectorThreshold)
|
||||
Bytes read(int side,
|
||||
bool synced,
|
||||
nanoseconds_t readTime,
|
||||
nanoseconds_t hardSectorThreshold)
|
||||
{
|
||||
if (hardSectorThreshold != 0)
|
||||
Error() << "hard sectors are currently unsupported on the GreaseWeazel";
|
||||
error("hard sectors are currently unsupported on the GreaseWeazel");
|
||||
|
||||
do_command({ CMD_HEAD, 3, (uint8_t)side });
|
||||
do_command({CMD_HEAD, 3, (uint8_t)side});
|
||||
|
||||
switch (_version)
|
||||
{
|
||||
case V22:
|
||||
{
|
||||
int revolutions = (readTime+_revolutions-1) / _revolutions;
|
||||
int revolutions = (readTime + _revolutions - 1) / _revolutions;
|
||||
Bytes cmd(4);
|
||||
cmd.writer()
|
||||
.write_8(CMD_READ_FLUX)
|
||||
@@ -301,13 +329,14 @@ public:
|
||||
cmd.writer()
|
||||
.write_8(CMD_READ_FLUX)
|
||||
.write_8(cmd.size())
|
||||
.write_le32((readTime + (synced ? _revolutions : 0)) / _clock)
|
||||
.write_le32(
|
||||
(readTime + (synced ? _revolutions : 0)) / _clock)
|
||||
.write_le16(0);
|
||||
do_command(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
Bytes buffer;
|
||||
Bytes buffer;
|
||||
ByteWriter bw(buffer);
|
||||
for (;;)
|
||||
{
|
||||
@@ -317,7 +346,7 @@ public:
|
||||
bw.write_8(b);
|
||||
}
|
||||
|
||||
do_command({ CMD_GET_FLUX_STATUS, 2 });
|
||||
do_command({CMD_GET_FLUX_STATUS, 2});
|
||||
|
||||
Bytes fldata = greaseWeazleToFluxEngine(buffer, _clock);
|
||||
if (synced)
|
||||
@@ -328,32 +357,32 @@ public:
|
||||
void write(int side, const Bytes& fldata, nanoseconds_t hardSectorThreshold)
|
||||
{
|
||||
if (hardSectorThreshold != 0)
|
||||
Error() << "hard sectors are currently unsupported on the GreaseWeazel";
|
||||
error("hard sectors are currently unsupported on the GreaseWeazel");
|
||||
|
||||
do_command({ CMD_HEAD, 3, (uint8_t)side });
|
||||
do_command({CMD_HEAD, 3, (uint8_t)side});
|
||||
switch (_version)
|
||||
{
|
||||
case V22:
|
||||
do_command({ CMD_WRITE_FLUX, 3, 1 });
|
||||
do_command({CMD_WRITE_FLUX, 3, 1});
|
||||
break;
|
||||
|
||||
case V24:
|
||||
case V29:
|
||||
do_command({ CMD_WRITE_FLUX, 4, 1, 1 });
|
||||
do_command({CMD_WRITE_FLUX, 4, 1, 1});
|
||||
break;
|
||||
}
|
||||
_serial->write(fluxEngineToGreaseWeazle(fldata, _clock));
|
||||
_serial->readByte(); /* synchronise */
|
||||
|
||||
do_command({ CMD_GET_FLUX_STATUS, 2 });
|
||||
do_command({CMD_GET_FLUX_STATUS, 2});
|
||||
}
|
||||
|
||||
void erase(int side, nanoseconds_t hardSectorThreshold)
|
||||
{
|
||||
if (hardSectorThreshold != 0)
|
||||
Error() << "hard sectors are currently unsupported on the GreaseWeazel";
|
||||
error("hard sectors are currently unsupported on the GreaseWeazel");
|
||||
|
||||
do_command({ CMD_HEAD, 3, (uint8_t)side });
|
||||
do_command({CMD_HEAD, 3, (uint8_t)side});
|
||||
|
||||
Bytes cmd(6);
|
||||
ByteWriter bw(cmd);
|
||||
@@ -363,18 +392,20 @@ public:
|
||||
do_command(cmd);
|
||||
_serial->readByte(); /* synchronise */
|
||||
|
||||
do_command({ CMD_GET_FLUX_STATUS, 2 });
|
||||
do_command({CMD_GET_FLUX_STATUS, 2});
|
||||
}
|
||||
|
||||
|
||||
void setDrive(int drive, bool high_density, int index_mode)
|
||||
{
|
||||
do_command({ CMD_SELECT, 3, (uint8_t)drive });
|
||||
do_command({ CMD_MOTOR, 4, (uint8_t)drive, 1 });
|
||||
do_command({ CMD_SET_PIN, 4, 2, (uint8_t)(high_density ? 1 : 0) });
|
||||
do_command({CMD_SELECT, 3, (uint8_t)drive});
|
||||
do_command({CMD_MOTOR, 4, (uint8_t)drive, 1});
|
||||
do_command({CMD_SET_PIN, 4, 2, (uint8_t)(high_density ? 1 : 0)});
|
||||
}
|
||||
|
||||
void measureVoltages(struct voltages_frame* voltages)
|
||||
{ Error() << "unsupported operation on the GreaseWeazle"; }
|
||||
{
|
||||
error("unsupported operation on the GreaseWeazle");
|
||||
}
|
||||
|
||||
private:
|
||||
enum
|
||||
@@ -383,7 +414,7 @@ private:
|
||||
V24,
|
||||
V29
|
||||
};
|
||||
|
||||
|
||||
std::unique_ptr<SerialPort> _serial;
|
||||
const GreaseWeazleProto& _config;
|
||||
int _version;
|
||||
@@ -391,7 +422,8 @@ private:
|
||||
nanoseconds_t _revolutions;
|
||||
};
|
||||
|
||||
USB* createGreaseWeazleUsb(const std::string& port, const GreaseWeazleProto& config)
|
||||
USB* createGreaseWeazleUsb(
|
||||
const std::string& port, const GreaseWeazleProto& config)
|
||||
{
|
||||
return new GreaseWeazleUsb(port, config);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user