Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions FluxEngine.cydsn/FluxEngine.cyprj
Original file line number Diff line number Diff line change
Expand Up @@ -1058,27 +1058,27 @@
<CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFolderSerialize" version="3">
<CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtBaseContainerSerialize" version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="DSKCHG" persistent="">
<Hidden v="False" />
<Hidden v="True" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<CyGuid_0820c2e7-528d-4137-9a08-97257b946089 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemListSerialize" version="2">
<dependencies>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="DSKCHG_aliases.h" persistent="Generated_Source\PSoC5\DSKCHG_aliases.h">
<Hidden v="False" />
<Hidden v="True" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="HEADER;;;;" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="DSKCHG.c" persistent="Generated_Source\PSoC5\DSKCHG.c">
<Hidden v="False" />
<Hidden v="True" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="SOURCE_C;CortexM3;;;" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="DSKCHG.h" persistent="Generated_Source\PSoC5\DSKCHG.h">
<Hidden v="False" />
<Hidden v="True" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="HEADER;;;;" />
<PropertyDeltas />
Expand Down Expand Up @@ -3282,6 +3282,39 @@
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
<filters />
</CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0>
<CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFolderSerialize" version="3">
<CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtBaseContainerSerialize" version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="READY" persistent="">
<Hidden v="False" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<CyGuid_0820c2e7-528d-4137-9a08-97257b946089 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemListSerialize" version="2">
<dependencies>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="READY_aliases.h" persistent="Generated_Source\PSoC5\READY_aliases.h">
<Hidden v="False" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="HEADER;;;;" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="READY.c" persistent="Generated_Source\PSoC5\READY.c">
<Hidden v="False" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="SOURCE_C;CortexM3;;;" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
<CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtFileSerialize" version="3" xml_contents_version="1">
<CyGuid_31768f72-0253-412b-af77-e7dba74d1330 type_name="CyDesigner.Common.ProjMgmt.Model.CyPrjMgmtItemSerialize" version="2" name="READY.h" persistent="Generated_Source\PSoC5\READY.h">
<Hidden v="False" />
</CyGuid_31768f72-0253-412b-af77-e7dba74d1330>
<build_action v="HEADER;;;;" />
<PropertyDeltas />
</CyGuid_8b8ab257-35d3-4473-b57b-36315200b38b>
</dependencies>
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
<filters />
</CyGuid_ebc4f06d-207f-49c2-a540-72acf4adabc0>
</dependencies>
</CyGuid_0820c2e7-528d-4137-9a08-97257b946089>
</CyGuid_2f73275c-45bf-46ba-b3b1-00a2fe0c8dd8>
Expand Down
Binary file modified FluxEngine.cydsn/TopDesign/TopDesign.cysch
Binary file not shown.
209 changes: 143 additions & 66 deletions FluxEngine.cydsn/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#define STEP_SETTLING_TIME 50 /* ms */

#define DISKSTATUS_WPT 1
#define DISKSTATUS_DSKCHG 2
#define DISKSTATUS_READY 2 /* Only used on QuickDisk drives */

#define STEP_TOWARDS0 1
#define STEP_AWAYFROM0 0
Expand All @@ -37,6 +37,7 @@ static uint8_t dma_channel;
static volatile int dma_writing_to_td = 0;
static volatile int dma_reading_from_td = 0;
static volatile bool dma_underrun = false;
static crunch_state_t cs = {};

#define DECLARE_REPLY_FRAME(STRUCT, TYPE) \
STRUCT r = {.f = { .type = TYPE, .size = sizeof(STRUCT) }}
Expand Down Expand Up @@ -269,13 +270,8 @@ static void init_capture_dma(void)
}
}

static void cmd_read(struct read_frame* f)
static void init_capture(void)
{
SIDE_REG_Write(f->side);
seek_to(current_track);

/* Do slow setup *before* we go into the real-time bit. */

SAMPLER_CONTROL_Write(1); /* reset */

{
Expand All @@ -288,110 +284,187 @@ 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. */

print("wait");
index_irq = false;
while (!index_irq)
;
index_irq = false;

crunch_state_t cs = {};
static void start_capture(void)
{
memset(&cs, 0, sizeof(crunch_state_t));
cs.outputptr = usb_buffer;
cs.outputlen = BUFFER_SIZE;

dma_writing_to_td = 0;
dma_reading_from_td = -1;
dma_underrun = false;
int count = 0;
SAMPLER_CONTROL_Write(0); /* !reset */
CAPTURE_CONTROL_Write(1);
CyDmaChSetInitialTd(dma_channel, td[dma_writing_to_td]);
CyDmaClearPendingDrq(dma_channel);
CyDmaChEnable(dma_channel, 1);

/* Wait for the first DMA transfer to complete, after which we can start the
* USB transfer. */
/* 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;
while (!dma_underrun)
/* returns true if capture is aborted */
static bool do_capture_chunk(void)
{
/* Wait for the next block to be read. */
while (dma_reading_from_td == dma_writing_to_td)
{
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;
}
/* On an underrun, give up immediately. */
if (dma_underrun)
return true;
}

uint8_t dma_buffer_usage = 0;
while (dma_buffer_usage < BUFFER_SIZE)
uint8_t dma_buffer_usage = 0;
while (dma_buffer_usage < BUFFER_SIZE)
{
cs.inputptr = dma_buffer[dma_reading_from_td] + dma_buffer_usage;
cs.inputlen = BUFFER_SIZE - dma_buffer_usage;
crunch(&cs);
dma_buffer_usage += BUFFER_SIZE - cs.inputlen;
if (cs.outputlen == 0)
{
cs.inputptr = dma_buffer[dma_reading_from_td] + dma_buffer_usage;
cs.inputlen = BUFFER_SIZE - dma_buffer_usage;
crunch(&cs);
dma_buffer_usage += BUFFER_SIZE - cs.inputlen;
count++;
if (cs.outputlen == 0)
while (USBFS_GetEPState(FLUXENGINE_DATA_IN_EP_NUM) != USBFS_IN_BUFFER_EMPTY)
{
while (USBFS_GetEPState(FLUXENGINE_DATA_IN_EP_NUM) != USBFS_IN_BUFFER_EMPTY)
{
if (index_irq || dma_underrun)
goto abort;
}

USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, usb_buffer, BUFFER_SIZE);
cs.outputptr = usb_buffer;
cs.outputlen = BUFFER_SIZE;
if (dma_underrun)
return true;
}

USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, usb_buffer, BUFFER_SIZE);
cs.outputptr = usb_buffer;
cs.outputlen = BUFFER_SIZE;
}
dma_reading_from_td = NEXT_BUFFER(dma_reading_from_td);
}
abort:;
dma_reading_from_td = NEXT_BUFFER(dma_reading_from_td);

return false;
}

static void stop_capture(void)
{
CAPTURE_CONTROL_Write(0);
CyDmaChSetRequest(dma_channel, CY_DMA_CPU_TERM_CHAIN);
while (CyDmaChGetRequest(dma_channel))
;

donecrunch(&cs);
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
unsigned zz = cs.outputlen;
if (cs.outputlen != BUFFER_SIZE)
USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, usb_buffer, BUFFER_SIZE-cs.outputlen);
if ((cs.outputlen == BUFFER_SIZE) || (cs.outputlen == 0))
USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, NULL, 0);
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
deinit_dma();
}

if (dma_underrun)
static void cmd_read(struct read_frame* f)
{
SIDE_REG_Write(f->side);
seek_to(current_track);

/* Do slow setup *before* we go into the real-time bit. */

init_capture();

/* Wait for the beginning of a rotation. */

index_irq = false;
while (!index_irq)
;
index_irq = false;

/* Start transferring. */

start_capture();
int revolutions = f->revolutions;
while (!dma_underrun)
{
print("underrun after %d packets");
send_error(F_ERROR_UNDERRUN);
CyWdtClear();

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

if (do_capture_chunk())
goto abort;
}
abort:;
stop_capture();

if (dma_underrun)
send_error(F_ERROR_UNDERRUN);
else
{
DECLARE_REPLY_FRAME(struct any_frame, F_FRAME_READ_REPLY);
send_reply(&r);
}
print("count=%d i=%d d=%d zz=%d", count, index_irq, dma_underrun, zz);
}

static void cmd_read_qd(struct read_frame* f)
{
SIDE_REG_Write(f->side);

/* Do slow setup *before* we go into the real-time bit. */

init_capture();

/* Reset the drive. */

STEP_REG_Write(2);
CyDelay(10); /* ms */
STEP_REG_Write(0);

/* Motor on, and wait for ready. */

MOTOR_REG_Write(1);
while (!(DISKSTATUS_REG_Read() & DISKSTATUS_READY))
;

/* Turning the motor off has no effect until the head hits the stop,
* at which point it'll stop automatically. */

MOTOR_REG_Write(0);

/* Start transferring. */

start_capture();
while (!dma_underrun)
{
CyWdtClear();

/* Have we reached the end? */
if (!(DISKSTATUS_REG_Read() & DISKSTATUS_READY))
break;

if (do_capture_chunk())
goto abort;
}
abort:;
stop_capture();

/* Reset the drive again to ensure the motor stops. */

STEP_REG_Write(2);
CyDelay(10); /* ms */
STEP_REG_Write(0);

if (dma_underrun)
send_error(F_ERROR_UNDERRUN);
else
{
DECLARE_REPLY_FRAME(struct any_frame, F_FRAME_READ_QD_REPLY);
send_reply(&r);
}
}

static void init_replay_dma(void)
Expand Down Expand Up @@ -647,6 +720,10 @@ static void handle_command(void)
cmd_read((struct read_frame*) f);
break;

case F_FRAME_READ_QD_CMD:
cmd_read_qd((struct read_frame*) f);
break;

case F_FRAME_WRITE_CMD:
cmd_write((struct write_frame*) f);
break;
Expand Down
3 changes: 2 additions & 1 deletion lib/dataspec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ FluxSpec::FluxSpec(const DataSpec& spec)

locations.clear();

quickdisk = spec.has("qd") && spec.at("qd").only();
const auto& drives = spec.at("d").data;
if (drives.size() != 1)
Error() << "you must specify exactly one drive";
Expand All @@ -128,7 +129,7 @@ FluxSpec::FluxSpec(const DataSpec& spec)
for (const auto& e : spec.modifiers)
{
const auto name = e.second.name;
if ((name != "t") && (name != "s") && (name != "d"))
if ((name != "t") && (name != "s") && (name != "d") && (name != "qd"))
Error() << fmt::format("unknown fluxspec modifier '{}'", name);
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/dataspec.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class FluxSpec
std::string filename;
std::vector<Location> locations;
unsigned drive;
bool quickdisk : 1;
};

class ImageSpec
Expand Down
Loading