mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Allow fractional revolutions and non-synced reading. Find more things which
need fixing in the firmware sampler.
This commit is contained in:
@@ -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
|
||||
@@ -4615,12 +4615,12 @@
|
||||
:0200000490105A
|
||||
:04000000BC90ACAF55
|
||||
:0200000490303A
|
||||
:0200000004BC3E
|
||||
:0200000001A954
|
||||
:0200000490402A
|
||||
:4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0
|
||||
:400040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080
|
||||
:400080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040
|
||||
:4000C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
:0200000490501A
|
||||
:0C00000000012E16106900002E3015259E
|
||||
:0C00000000012E16106900002E301212B4
|
||||
:00000001FF
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -27,8 +27,9 @@ public:
|
||||
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
|
||||
|
||||
|
||||
@@ -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" },
|
||||
@@ -29,6 +35,10 @@ public:
|
||||
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()
|
||||
@@ -40,9 +50,10 @@ public:
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -59,13 +70,19 @@ public:
|
||||
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));
|
||||
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
enum
|
||||
{
|
||||
FLUXENGINE_VERSION = 10,
|
||||
FLUXENGINE_VERSION = 11,
|
||||
|
||||
FLUXENGINE_VID = 0x1209,
|
||||
FLUXENGINE_PID = 0x6e00,
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user