#include <fx2lafw.h>
#include <gpif-acquisition.h>
-bit gpif_acquiring;
+__bit gpif_acquiring;
static void gpif_reset_waveforms(void)
{
gpif_acquiring = FALSE;
}
-void gpif_acquisition_start(const struct cmd_start_acquisition *cmd)
+static void gpif_make_delay_state(volatile BYTE *pSTATE, uint8_t delay)
{
- xdata volatile BYTE *pSTATE;
-
- /* Ensure GPIF is idle before reconfiguration. */
- while (!(GPIFTRIG & 0x80));
-
- /* Set IFCONFIG to the correct clock source. */
- if (cmd->flags & CMD_START_FLAGS_CLK_48MHZ) {
- IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmASYNC |
- bmGSTATE | bmIFGPIF;
- } else {
- IFCONFIG = bmIFCLKSRC | bmIFCLKOE | bmASYNC |
- bmGSTATE | bmIFGPIF;
- }
-
- /* GPIF terminology: DP = decision point, NDP = non-decision-point */
-
- /*
- * Populate WAVEDATA.
- *
- * This is the basic algorithm implemented in our GPIF state machine:
- *
- * State 0: NDP: Sample the FIFO data bus.
- * State 1: DP: If EP2 is full, go to state 7 (the IDLE state), i.e.,
- * end the current waveform. Otherwise, go to state 0 again,
- * i.e., sample data until EP2 is full.
- * State 2: Unused.
- * State 3: Unused.
- * State 4: Unused.
- * State 5: Unused.
- * State 6: Unused.
- */
-
- /* Populate S0. */
- pSTATE = &GPIF_WAVE_DATA;
-
/*
* DELAY
* Delay cmd->sample_delay clocks.
*/
- pSTATE[0] = cmd->sample_delay;
+ pSTATE[0] = delay;
/*
* OPCODE
- * SGL=0, GIN=0, INCAD=0, NEXT=0, DATA=1, DP=0
+ * SGL=0, GIN=0, INCAD=0, NEXT=0, DATA=0, DP=0
* Collect data in this state.
*/
- pSTATE[8] = 0x02;
+ pSTATE[8] = 0x00;
/*
* OUTPUT
* Not used.
*/
pSTATE[24] = 0x00;
+}
- /* Populate S1 - the decision point. */
- pSTATE = &GPIF_WAVE_DATA + 1;
-
+static void gpid_make_data_dp_state(volatile BYTE *pSTATE)
+{
/*
* BRANCH
* Branch to IDLE if condition is true, back to S0 otherwise.
/*
* OPCODE
- * SGL=0, GIN=0, INCAD=0, NEXT=0, DATA=0, DP=1
+ * SGL=0, GIN=0, INCAD=0, NEXT=0, DATA=1, DP=1
*/
- pSTATE[8] = (1 << 0);
+ pSTATE[8] = (1 << 1) | (1 << 0);
/*
* OUTPUT
* LFUNC=0 (AND), TERMA=6 (FIFO Flag), TERMB=6 (FIFO Flag)
*/
pSTATE[24] = (6 << 3) | (6 << 0);
+}
+
+bool gpif_acquisition_start(const struct cmd_start_acquisition *cmd)
+{
+ int i;
+ volatile BYTE *pSTATE = &GPIF_WAVE_DATA;
+
+ /* Ensure GPIF is idle before reconfiguration. */
+ while (!(GPIFTRIG & 0x80));
+
+ /* Configure the EP2 FIFO. */
+ if (cmd->flags & CMD_START_FLAGS_SAMPLE_16BIT) {
+ EP2FIFOCFG = bmAUTOIN | bmWORDWIDE;
+ } else {
+ EP2FIFOCFG = bmAUTOIN;
+ }
+ SYNCDELAY();
+
+ /* Set IFCONFIG to the correct clock source. */
+ if (cmd->flags & CMD_START_FLAGS_CLK_48MHZ) {
+ IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmASYNC |
+ bmGSTATE | bmIFGPIF;
+ } else {
+ IFCONFIG = bmIFCLKSRC | bmIFCLKOE | bmASYNC |
+ bmGSTATE | bmIFGPIF;
+ }
+
+ /* Populate delay states. */
+ if ((cmd->sample_delay_h == 0 && cmd->sample_delay_l == 0) ||
+ cmd->sample_delay_h >= 6)
+ return false;
+
+ for (i = 0; i < cmd->sample_delay_h; i++)
+ gpif_make_delay_state(pSTATE++, 0);
+
+ if (cmd->sample_delay_l != 0)
+ gpif_make_delay_state(pSTATE++, cmd->sample_delay_l);
+
+ /* Populate S1 - the decision point. */
+ gpid_make_data_dp_state(pSTATE++);
/* Execute the whole GPIF waveform once. */
gpif_set_tc16(1);
/* Update the status. */
gpif_acquiring = TRUE;
+
+ return true;
}
void gpif_poll(void)