Skip to content

Commit

Permalink
Allow fractional revolutions and non-synced reading. Find more things…
Browse files Browse the repository at this point in the history
… which

need fixing in the firmware sampler.
  • Loading branch information
davidgiven committed Jan 27, 2020
1 parent 933ffe7 commit 29bdfc0
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 56 deletions.
44 changes: 22 additions & 22 deletions FluxEngine.cydsn/CortexM3/ARM_GCC_541/Release/FluxEngine.hex
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,35 @@
:4003000002F07AFD02A801F08AFF01F094FF13B05DF804EB04B0704710B5044601780648FFF7E5FF0420FFF7EFFE62782146BDE81040042001F080B83A36000007B50023B1
:40034000ADF804308DF80600032301A88DF80530FFF7E2FF03B05DF804FB0000F8B51D4C0646FFF733FF637F03B156B91A48FFF7BEFFFFF75EFF012000236077636302F048
:4003800099F83246616B1548FFF7B1FF114D0027636B9E4216D001F0D7FE00B16F63636B9E4205DD0020FFF72BFF6B6B013305E005DA0120FFF724FF6B6B013B6B6302F059
:4003C000A1F8E5E7322002F05FF8BDE8F8400448FFF78DBF8081FF1F473600004E3600006B3600002DE9F04F9BB062B602F0F4F8B449042002F018F9B34801F0B1FEB34881
:4004000002F0E4FBB24801F0E5FE02F0C5FA02F097F9002002F0B8FB01F000FF0221002000F0A4FFAB4D0321084602F04BF82E462C46DFF8C4B202F065F8AB7F73B12A6A5C
:40044000EB689B1A41F28832934207D9002001F075FE002002F098FB0023AB7700F0BEFF18B99D48FFF743FF04E000F0BDFF0028F7D109E000F0B2FF0028FBD09748FFF7F7
:4004800036FF032001F016F8032000F0B9FF0128D1D19348FFF764FE92490320FFF782FE94F838109048FFF722FF94F83830023B122B00F2F583DFE813F01300F3031C001E
:4004C000F3032200F3034400F3036800F303A001F3033503F3035403F3035A03F303650303238DF828308DF829300A238DF82A3044E394F83A00FFF731FF7C4B3BE3FFF7AE
:4003C000A1F8E5E7322002F05FF8BDE8F8400448FFF78DBF8081FF1F473600004E3600006B3600002DE9F04F9BB062B602F0F4F8B749042002F018F9B64801F0B1FEB64878
:4004000002F0E4FBB54801F0E5FE02F0C5FA02F097F9002002F0B8FB01F000FF0221002000F0A4FFAE4D0321084602F04BF82E462C46DFF8D4B202F065F8AB7F73B12A6A46
:40044000EB689B1A41F28832934207D9002001F075FE002002F098FB0023AB7700F0BEFF18B9A048FFF743FF04E000F0BDFF0028F7D109E000F0B2FF0028FBD09A48FFF7F1
:4004800036FF032001F016F8032000F0B9FF0128D1D19648FFF764FE95490320FFF782FE94F838109348FFF722FF94F83830023B122B00F2F583DFE813F01300F3031C0015
:4004C000F3032200F3034400F3036800F303A001F3033503F3035403F3035A03F303650303238DF828308DF829300B238DF82A3044E394F83A00FFF731FF7F4B3BE3FFF7AA
:4005000065FE00236372E068627A02F0FF0132B9EB681B1AB3F57A7FF6DD0B4608E03BB100227272F168627A12B9EB685B1AFAE707228DF8282004228DF82920ADF82A30A6
:400540001CE30220FFF7E0FD4FF000090DF1280A4FF480780027C8EB0903DA1907F80A200137402FF9D10220FFF7CEFD3A465146022000F061FFB8F10108EBD109F1010983
:40058000B9F1400FE4D15A4BC7E294F83A0001F0F9FD606BFFF7E2FE02F09AFB554BDFF85C811A78002742F004021A701A7842F001021A701A7802F0FE021A701A7802F0B8
:4005C000FE021A7002F088FB0220FFF79DFD41F6FF734FF480420121022002F0DBFA84F8780001F0FDFE08F807000137102FF8D1DFF80CA100270AF15D081FFA88F901378D
:40060000102F14BF3A4600221AF8010F2244062392F82420402101F017FF4A4646F242419AF8000001F022FF09F14009102F1FFA89F9E4D100237372637A002BFCD000275B
:40064000142239460AA8777202F0A2FB40230D934FF0FF333760736037723368DFF8A490334493F8241096F87800CDF8309001F06FFE96F8780001F02DFE012196F8780005
:4006800001F000FECDF81090236813B96B7A002BFAD0002794F83BA0676094F80890B9F1000F08D101F02EFF6B7A83B3BAF1010A85F809902BD1042194F8780001F054FE3D
:4006C0005CE000BF19010000F900000091000000C50000008081FF1F793600008C3600009881FF1FB881FF1F963600002C3600002E360000926400409C640040A481FF1F2D
:40070000A381FF1F0086FF1F2B7A002BD3D1626823689A42F8D04FF0000962680AA808EB82124A440A92C9F140020B9200F0DAFA0B9A0137C2F1400209EB02030D9A5FFAC9
:4007400083F95AB90220FFF7DFFC4022BC49022000F072FE049B0C9340230D93B9F13F0FDBD96268B74B01321340002BBEBF03F1FF3363F00F03013363608EE794F878002C
:4007800001F002FE0028F9D10AA800F0DFFA0220FFF7BAFC337A63B90D9A402A06D0C2F1400292B2A649022000F046FE0220FFF7ABFC0D9A32F0400206D10220114600F0D5
:4007C0003BFE0220FFF7A0FCFFF744FD237A33B19D48FFF78CFD0220FFF7B0FD06E09B4B09A81B88ADF82430FFF796FD627A3946237A9748FFF77BFD55E29648FFF777FDC5
:40058000B9F1400FE4D15D4BC7E294F83A0001F0F9FD606BFFF7E2FE02F09AFB584BDFF86C811A78002742F004021A701A7842F001021A701A7802F0FE021A701A7802F0A2
:4005C000FE021A7002F088FB0220FFF79DFD41F6FF734FF480420121022002F0DBFA84F8780001F0FDFE08F807000137102FF8D1DFF81CA100270AF15D081FFA88F901377D
:40060000102F14BF3A4600221AF8010F2244062392F82420402101F017FF4A4646F242419AF8000001F022FF09F14009102F1FFA89F9E4D196F83B3033B100237372637A9C
:40064000002BFCD000237372142200210AA802F09FFB40234FF0FF320D9300232360626023722368274F234493F8241094F878000C9701F06DFE94F8780001F02BFE01210C
:4006800094F8780001F0FEFD04972368002BFCD000277760D6F80CA0237A7BB901F032FFA98F04E0EB68CAEB03038B4206D2626823689A422ED12B7A002BF3D094F808801C
:4006C000042194F878005FFA88F801F04DFE54E019010000F900000091000000C50000008081FF1F793600008C3600009881FF1FB881FF1F963600002C3600002E3600006F
:40070000926400400086FF1F9C640040A481FF1FA381FF1F4FF0000962680AA808EB82124A440A92C9F140020B9200F0DBFA0B9A0137C2F1400209EB02030D9A5FFA83F900
:400740005AB90220FFF7E0FC4022BD49022000F073FE049B0C9340230D93B9F13F0FDBD96268B84B01321340002BBEBF03F1FF3363F00F03013363608EE794F8780001F0B3
:4007800003FE0028F9D10AA800F0E0FA0220FFF7BBFC0D9B402B07D002204022A84900F04BFE0220FFF7B0FC0D9B022033F040021DBFC3F1400292B2A149114600F03CFEEF
:4007C0000220FFF7A1FCFFF745FDB8F1000F06D09D48FFF78CFD0220FFF7B0FD06E09B4B09A81B88ADF82430FFF796FD627A3946237A9748FFF77BFD55E29648FFF777FDEF
:40080000E76B17F03F0701D003204AE2012001F0BFFC95F83A0001F0B5FC02F059FA9BF80030DFF8348203F0FB038BF800309BF8003043F001038BF800309BF8003003F027
:40084000FE038BF800309BF8003003F0FE038BF8003002F041FA686BFFF780FD01214FF4804341F6FF72084601F098FC85F8780001F0B6FD08F807000137102FF8D1DFF88D
:40088000DC91002709F15D031FFA83F807930137102F14BF3A46002219F8010F2244052392F82420402101F0CFFD414646F24C4299F8000001F0DAFD08F14008102F1FFA56
:4008C00088F8E4D10027B946BA46F36B4FF0FF389B09142239460AA837600593C6F80480377202F055FA402301200D9300F0E2FDCDF81880049701F005FE2268514B01322B
:4008C00088F8E4D10027B946BA46F36B4FF0FF389B09142239460AA837600493C6F80480377202F055FA402301200D9300F0E2FDCDF81880059701F005FE2268514B01322B
:400900001340002BBCBF03F1FF3363F00F036168B8BF01338B4200F0A380BAF1000F07D0237A002B40F0B0806B7A002B40F0AC800B9B002B34D1B9F1000F0BD07F22404926
:400940005A540133402BFAD10A910B9328E0BAF1000F06D1012000F053FD01288046F6D107E0237A002B40F08F806B7A002BF1D08AE03349FFF716FC8146314B0B90404665
:400980000A9300F097FDB9F13F0F07F1010706DD059BDB1BD3F1000949EB030900E0C1460B9BDBB12368079A0AA802EB83120D9BC3F1400313440C9300F0D7F90D9B6BB9FE
:400980000A9300F097FDB9F13F0F07F1010706DD049BDB1BD3F1000949EB030900E0C1460B9BDBB12368079A0AA802EB83120D9BC3F1400313440C9300F0D7F90D9B6BB9FF
:4009C0002A68204B01321340002BBEBF03F1FF3363F00F030133236040230D93636801333ED12B680F2B3BD14FF00008C5F8048001F002FC85F808806B6895F878002B44DD
:400A000093F8241001F0A4FC95F8780001F062FC012195F8780001F035FC85F80980637A002BFCD04FF00008012086F8098001F0EFFB404601F0ACFBCDF8188013E000BF78
:400A40000086FF1F0F000080A536000030360000BF360000D2360000A481FF1FA381FF1FBAF1000F05D0237A73B96B7A63B94FF0010A6368069A93423FF43DAF049B0133AB
:400A800004936B68069336E701F0BCFB012001F07FFB002001F0BCFB042194F8780001F063FC94F8780001F06FFC0028F9D196F8780001F0FDFB737A327A02930123039279
:400AC0000193CDF80090049B3A4605997A48FFF70EFCB9F1000F16D1059BBB420ADD012000F08EFC01288046F6D17449FFF75AFB3F2803DC012000F017FD04E0404600F04C
:400A40000086FF1F0F000080A536000030360000BF360000D2360000A481FF1FA381FF1FBAF1000F05D0237A73B96B7A63B94FF0010A6368069A93423FF43DAF059B0133AA
:400A800005936B68069336E701F0BCFB012001F07FFB002001F0BCFB042194F8780001F063FC94F8780001F06FFC0028F9D196F8780001F0FDFB737A327A02930123039278
:400AC0000193CDF80090059B3A4604997A48FFF70EFCB9F1000F16D1049BBB420ADD012000F08EFC01288046F6D17449FFF75AFB3F2803DC012000F017FD04E0404600F04D
:400B0000D9FC0137E8E7FFF7A5FB6D48FFF7EFFB237A0BB10220C4E06A4B1B8809A8ADF824302CE094F83A0001F02CFB606BFFF715FC6548FFF7DBFB00236372637A002B58
:400B4000FCD0012001F064FB00237372637A002BFCD0002001F05CFB5C48FFF7C8FB5C4B09E000206077FFF7F9FB5A4B03E05A48FFF7F6FA594B1B88ADF828300AA8FFF72A
:400B8000CBFB90E0A37F3BB1002001F0D7FA002001F0FAFF0023AB7701F07CFF002001F01FFF2A2701F04AFE002001F0EDFD3A4600210AA802F0ECF815238DF828308DF8DD
Expand Down Expand Up @@ -4615,12 +4615,12 @@
:0200000490105A
:04000000BC90ACAF55
:0200000490303A
:0200000004BC3E
:0200000001A954
:0200000490402A
:4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0
:400040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080
:400080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040
:4000C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
:0200000490501A
:0C00000000012E16106900002E3015259E
:0C00000000012E16106900002E301212B4
:00000001FF
49 changes: 27 additions & 22 deletions FluxEngine.cydsn/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,15 @@ static void cmd_read(struct read_frame* f)
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
init_capture_dma();

/* Wait for the beginning of a rotation. */
/* Wait for the beginning of a rotation, if requested. */

index_irq = false;
while (!index_irq)
;
index_irq = false;
if (f->synced)
{
index_irq = false;
while (!index_irq)
;
index_irq = false;
}

crunch_state_t cs = {};
cs.outputptr = usb_buffer;
Expand All @@ -365,32 +368,27 @@ static void cmd_read(struct read_frame* f)
/* Wait for the first DMA transfer to complete, after which we can start the
* USB transfer. */

while ((dma_writing_to_td == 0) && !index_irq)
while (dma_writing_to_td == 0)
;
dma_reading_from_td = 0;

/* Start transferring. */

int revolutions = f->revolutions;
uint32_t start_time = clock;
while (!dma_underrun)
{
CyWdtClear();

/* Have we reached the index pulse? */
if (index_irq)
{
index_irq = false;
revolutions--;
if (revolutions == 0)
break;
}

/* Wait for the next block to be read. */
while (dma_reading_from_td == dma_writing_to_td)
{
/* On an underrun, give up immediately. */
if (dma_underrun)
goto abort;

/* Also finish if the sample session is over. */
if ((clock - start_time) >= f->milliseconds)
goto abort;
}

uint8_t dma_buffer_usage = 0;
Expand All @@ -416,26 +414,33 @@ static void cmd_read(struct read_frame* f)
dma_reading_from_td = NEXT_BUFFER(dma_reading_from_td);
}
abort:;
bool saved_dma_underrun = dma_underrun;
CyDmaChSetRequest(dma_channel, CY_DMA_CPU_TERM_CHAIN);
while (CyDmaChGetRequest(dma_channel))
;

donecrunch(&cs);
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
if (!dma_underrun)
/* If there's a complete packet waiting, send it. */
if (cs.outputlen != BUFFER_SIZE)
{
if (cs.outputlen != BUFFER_SIZE)
USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, usb_buffer, BUFFER_SIZE-cs.outputlen);
USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, usb_buffer, BUFFER_SIZE);
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
}
if ((cs.outputlen == BUFFER_SIZE) || (cs.outputlen == 0))
if ((cs.outputlen != 0) && (cs.outputlen != BUFFER_SIZE))
{
/* If there's a partial packet waiting, send it; this will also terminate the transfer. */
USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, usb_buffer, BUFFER_SIZE-cs.outputlen);
}
else
{
/* Otherwise just terminate the transfer. */
USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, NULL, 0);
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
}
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
deinit_dma();

if (dma_underrun)
if (saved_dma_underrun)
{
print("underrun after %d packets");
send_error(F_ERROR_UNDERRUN);
Expand Down
3 changes: 2 additions & 1 deletion lib/fluxsource/fluxsource.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ class FluxSource
virtual bool retryable() { return false; }
};

extern void setHardwareFluxSourceRevolutions(int revolutions);
extern void setHardwareFluxSourceRevolutions(double revolutions);
extern void setHardwareFluxSourceDensity(bool high_density);
extern void setHardwareFluxSourceSynced(bool synced);

#endif

25 changes: 21 additions & 4 deletions lib/fluxsource/hardwarefluxsource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
#include "fluxmap.h"
#include "usb.h"
#include "fluxsource/fluxsource.h"
#include "fmt/format.h"

FlagGroup hardwareFluxSourceFlags;

static IntFlag revolutions(
static DoubleFlag revolutions(
{ "--revolutions" },
"read this many revolutions of the disk",
1);
1.25);

static BoolFlag synced(
{ "--sync-with-index" },
"whether to wait for an index pulse before started to read",
false);

static IntFlag indexMode(
{ "--index-mode" },
Expand All @@ -29,6 +35,10 @@ class HardwareFluxSource : public FluxSource
HardwareFluxSource(unsigned drive):
_drive(drive)
{
usbSetDrive(_drive, high_density, indexMode);
std::cerr << "Measuring rotational speed... " << std::flush;
_oneRevolution = usbGetRotationalPeriod();
std::cerr << fmt::format("{}ms\n", _oneRevolution / 1e6);
}

~HardwareFluxSource()
Expand All @@ -40,9 +50,10 @@ class HardwareFluxSource : public FluxSource
{
usbSetDrive(_drive, high_density, indexMode);
usbSeek(track);
Bytes crunched = usbRead(side, revolutions);
Bytes crunched = usbRead(side, synced, revolutions * _oneRevolution);
auto fluxmap = std::make_unique<Fluxmap>();
fluxmap->appendBytes(crunched.uncrunch());
std::cerr << "return fluxmap\n";
return fluxmap;
}

Expand All @@ -59,13 +70,19 @@ class HardwareFluxSource : public FluxSource
private:
unsigned _drive;
unsigned _revolutions;
nanoseconds_t _oneRevolution;
};

void setHardwareFluxSourceRevolutions(int revolutions)
void setHardwareFluxSourceRevolutions(double revolutions)
{
::revolutions.setDefaultValue(revolutions);
}

void setHardwareFluxSourceSynced(bool synced)
{
::synced.setDefaultValue(synced);
}

std::unique_ptr<FluxSource> FluxSource::createHardwareFluxSource(unsigned drive)
{
return std::unique_ptr<FluxSource>(new HardwareFluxSource(drive));
Expand Down
9 changes: 6 additions & 3 deletions lib/usb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ nanoseconds_t usbGetRotationalPeriod(void)
usb_cmd_send(&f, f.f.size);

auto r = await_reply<struct speed_frame>(F_FRAME_MEASURE_SPEED_REPLY);
return r->period_ms * 1000;
return r->period_ms * 1000000;
}

static int large_bulk_transfer(int ep, Bytes& bytes)
Expand Down Expand Up @@ -202,13 +202,16 @@ void usbTestBulkTransport()
await_reply<struct any_frame>(F_FRAME_BULK_TEST_REPLY);
}

Bytes usbRead(int side, int revolutions)
Bytes usbRead(int side, bool synced, nanoseconds_t readTime)
{
struct read_frame f = {
.f = { .type = F_FRAME_READ_CMD, .size = sizeof(f) },
.side = (uint8_t) side,
.revolutions = (uint8_t) revolutions
.synced = (uint8_t) synced
};
uint16_t milliseconds = readTime / 1e6;
((uint8_t*)&f.milliseconds)[0] = milliseconds;
((uint8_t*)&f.milliseconds)[1] = milliseconds >> 8;
usb_cmd_send(&f, f.f.size);

auto fluxmap = std::unique_ptr<Fluxmap>(new Fluxmap);
Expand Down
2 changes: 1 addition & 1 deletion lib/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extern void usbRecalibrate();
extern void usbSeek(int track);
extern nanoseconds_t usbGetRotationalPeriod();
extern void usbTestBulkTransport();
extern Bytes usbRead(int side, int revolutions);
extern Bytes usbRead(int side, bool synced, nanoseconds_t readTime);
extern void usbWrite(int side, const Bytes& bytes);
extern void usbErase(int side);
extern void usbSetDrive(int drive, bool high_density, int index_mode);
Expand Down
5 changes: 3 additions & 2 deletions protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

enum
{
FLUXENGINE_VERSION = 10,
FLUXENGINE_VERSION = 11,

FLUXENGINE_VID = 0x1209,
FLUXENGINE_PID = 0x6e00,
Expand Down Expand Up @@ -133,7 +133,8 @@ struct read_frame
{
struct frame_header f;
uint8_t side;
uint8_t revolutions;
uint8_t synced;
uint16_t milliseconds;
};

struct write_frame
Expand Down
2 changes: 1 addition & 1 deletion src/fe-rpm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ int mainRpm(int argc, const char* argv[])
usbSetDrive(spec.drive, false, F_INDEX_REAL);
nanoseconds_t period = usbGetRotationalPeriod();
if (period != 0)
std::cout << "Rotational period is " << period/1000 << " ms (" << 60e6/period << " rpm)" << std::endl;
std::cout << "Rotational period is " << period/1000000 << " ms (" << 60e3/period << " rpm)" << std::endl;
else
{
std::cout << "No index pulses detected from the disk. Common causes of this are:\n"
Expand Down

0 comments on commit 29bdfc0

Please sign in to comment.