volatile __bit got_sud;
BYTE vendor_command;
-volatile WORD ledcounter = 1000;
-
-extern __bit gpif_acquiring;
+volatile WORD ledcounter = 0;
static void setup_endpoints(void)
{
/* Protocol implementation */
switch (cmd) {
case CMD_START:
+ /* Tell hardware we are ready to receive data. */
vendor_command = cmd;
EP0BCL = 0;
return TRUE;
CLEAR_SUDAV();
}
+/* IN BULK NAK - the host started requesting data. */
+void ibn_isr(void) __interrupt IBN_ISR
+{
+ /*
+ * If the IBN interrupt is not disabled, clearing
+ * does not work. See AN78446, 6.2.
+ */
+ BYTE ibnsave = IBNIE;
+ IBNIE = 0;
+ CLEAR_USBINT();
+
+ /*
+ * If the host sent the START command, start the GPIF
+ * engine. The host will repeat the BULK IN in the next
+ * microframe.
+ */
+ if ((IBNIRQ & bmEP2IBN) && (gpif_acquiring == PREPARED)) {
+ ledcounter = 1;
+ PA1 = 0;
+ gpif_acquisition_start();
+ }
+
+ /* Clear IBN flags for all EPs. */
+ IBNIRQ = 0xff;
+
+ NAKIRQ = bmIBN;
+ SYNCDELAY();
+
+ IBNIE = ibnsave;
+ SYNCDELAY();
+}
+
void usbreset_isr(void) __interrupt USBRESET_ISR
{
handle_hispeed(FALSE);
void timer2_isr(void) __interrupt TF2_ISR
{
/* Blink LED during acquisition, keep it on otherwise. */
- if (gpif_acquiring) {
+ if (gpif_acquiring == RUNNING) {
if (--ledcounter == 0) {
PA1 = !PA1;
ledcounter = 1000;
}
- } else {
+ } else if (gpif_acquiring == STOPPED) {
PA1 = 1; /* LED on. */
}
TF2 = 0;
/* TODO: Does the order of the following lines matter? */
ENABLE_SUDAV();
+ ENABLE_EP2IBN();
ENABLE_HISPEED();
ENABLE_USBRESET();
break;
if (EP0BCL == sizeof(struct cmd_start_acquisition)) {
- gpif_acquisition_start(
+ gpif_acquisition_prepare(
(const struct cmd_start_acquisition *)EP0BUF);
}
#include <fx2lafw.h>
#include <gpif-acquisition.h>
-__bit gpif_acquiring;
+enum gpif_status gpif_acquiring = STOPPED;
static void gpif_reset_waveforms(void)
{
gpif_init_flowstates();
/* Reset the status. */
- gpif_acquiring = FALSE;
+ gpif_acquiring = STOPPED;
}
static void gpif_make_delay_state(volatile BYTE *pSTATE, uint8_t delay, uint8_t output)
pSTATE[24] = (6 << 3) | (6 << 0);
}
-bool gpif_acquisition_start(const struct cmd_start_acquisition *cmd)
+bool gpif_acquisition_prepare(const struct cmd_start_acquisition *cmd)
{
int i;
volatile BYTE *pSTATE = &GPIF_WAVE_DATA;
/* Populate S1 - the decision point. */
gpif_make_data_dp_state(pSTATE++);
+ /* Update the status. */
+ gpif_acquiring = PREPARED;
+
+ return true;
+}
+
+void gpif_acquisition_start(void)
+{
/* Execute the whole GPIF waveform once. */
gpif_set_tc16(1);
gpif_fifo_read(GPIF_EP2);
/* Update the status. */
- gpif_acquiring = TRUE;
-
- return true;
+ gpif_acquiring = RUNNING;
}
void gpif_poll(void)
{
/* Detect if acquisition has completed. */
- if (gpif_acquiring && (GPIFTRIG & 0x80)) {
+ if ((gpif_acquiring == RUNNING) && (GPIFTRIG & 0x80)) {
/* Activate NAK-ALL to avoid race conditions. */
FIFORESET = 0x80;
SYNCDELAY();
FIFORESET = 0x00;
SYNCDELAY();
- gpif_acquiring = FALSE;
+ gpif_acquiring = STOPPED;
}
}
#include <stdbool.h>
#include <command.h>
+enum gpif_status {
+ STOPPED = 0,
+ PREPARED,
+ RUNNING,
+};
+extern enum gpif_status gpif_acquiring;
+
void gpif_init_la(void);
-bool gpif_acquisition_start(const struct cmd_start_acquisition *cmd);
+bool gpif_acquisition_prepare(const struct cmd_start_acquisition *cmd);
+void gpif_acquisition_start(void);
void gpif_poll(void);
#endif