// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "usbdpi.h"

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "usb_utils.h"
#include "usbdpi_test.h"

// Indexed directly by ctx->state (ST_)
static const char *st_states[] = {"ST_IDLE 0", "ST_SEND 1", "ST_GET 2",
                                  "ST_SYNC 3", "ST_EOP 4",  "ST_EOP0 5"};

// Indexed directly by ct-x>hostSt (HS_)
static const char *hs_states[] = {
    "HS_STARTFRAME 0", "HS_WAITACK 1",   "HS_SET_DATASTAGE 2", "HS_DS_RXDATA 3",
    "HS_DS_SENDACK 4", "HS_DONEDADR 5",  "HS_REQDATA 6",       "HS_WAITDATA 7",
    "HS_SENDACK 8",    "HS_WAIT_PKT 9",  "HS_ACKIFDATA 10",    "HS_SENDHI 11",
    "HS_EMPTYDATA 12", "HS_WAITACK2 13", "HS_STREAMOUT 14",    "HS_STREAMIN 15",
    "HS_NEXTFRAME 16"};

static const char *decode_usb[] = {"SE0", "0-K", "1-J", "SE1"};

// Optionally invert the signals the host is driving, according to bus
// configuration
static uint32_t inv_driving(usbdpi_ctx_t *ctx, uint32_t d2p);

// Request IN transfer. Get back NAK or DATA0/DATA1.
static void pollRX(usbdpi_ctx_t *ctx, uint8_t endpoint, bool send_hi,
                   bool nak_data);
// Get Baud (Vendor-specific)
static void readBaud(usbdpi_ctx_t *ctx, uint8_t endpoint);

// Get Test Configuration (Vendor-specific)
static void getTestConfig(usbdpi_ctx_t *ctx, uint16_t desc_len);

// Get Descriptor
static void getDescriptor(usbdpi_ctx_t *ctx, uint8_t desc_type,
                          uint8_t desc_idx, uint16_t desc_len);
// Set Baud (Vendor-specific)
static void setBaud(usbdpi_ctx_t *ctx, uint8_t endpoint);

// Set device address (with null data stage)
static void setDeviceAddress(usbdpi_ctx_t *ctx, uint8_t dev_addr);

// Set device configuration
static void setDeviceConfiguration(usbdpi_ctx_t *ctx, uint8_t config);

// Set test status, reporting progress/success/failure (Vendor-specific)
static void setTestStatus(usbdpi_ctx_t *ctx, uint32_t status, const char *msg);

// Change DP and DN outputs from host
static uint32_t set_driving(usbdpi_ctx_t *ctx, uint32_t d2p, uint32_t newval);

// Try to send OUT transfer. Optionally expect Status packet (eg. ACK|NAK) in
// response
static void tryTX(usbdpi_ctx_t *ctx, uint8_t endpoint, bool expect_status);

// Test the ischronous transfers (without ACKs)
// static void testIso(usbdpi_ctx_t *ctx);
#define testIso(ctx) tryTX((ctx), ENDPOINT_ISOCHRONOUS, false)

// Callback for USB data detection
static void usbdpi_data_callback(void *ctx_v, usbmon_data_type_t type,
                                 uint8_t d);

/**
 * Create a USB DPI instance, returning a 'chandle' for later use
 */
void *usbdpi_create(const char *name, int loglevel) {
  // Use calloc for zero-initialisation
  usbdpi_ctx_t *ctx = (usbdpi_ctx_t *)calloc(1, sizeof(usbdpi_ctx_t));
  assert(ctx);

  // Note: calloc has initialized most of the fields for us
  // ctx->tick = 0;
  // ctx->tick_bits = 0;
  // ctx->frame = 0;
  // ctx->framepend = 0;
  // ctx->frame_start = 0;
  // ctx->last_pu = 0;
  // ctx->driving = 0;
  // ctx->baudrate_set_successfully = 0;

  // Initialize state for each endpoint and direction
  for (unsigned ep = 0U; ep < USBDPI_MAX_ENDPOINTS; ep++) {
    // First DATAx received shall be DATA0
    ctx->ep_in[ep].next_data = USB_PID_DATA0;

    // First DATAx transmitted shall be DATA0 because it must follow a SETUP
    // transaction
    ctx->ep_out[ep].next_data = USB_PID_DATA0;
  }

  ctx->state = ST_IDLE;
  ctx->hostSt = HS_NEXTFRAME;
  ctx->loglevel = loglevel;

  ctx->step = STEP_BUS_RESET;

  char cwd[FILENAME_MAX];
  char *cwd_rv;
  const char *test_out_dir = getenv("TEST_UNDECLARED_OUTPUTS_DIR");
  if (test_out_dir) {
    cwd_rv = strncpy(cwd, test_out_dir, sizeof(cwd));
  } else {
    cwd_rv = getcwd(cwd, sizeof(cwd));
  }
  assert(cwd_rv != NULL);

  // Monitor log file
  int rv = snprintf(ctx->mon_pathname, FILENAME_MAX, "%s/%s.log", cwd, name);
  assert(rv <= FILENAME_MAX && rv > 0);

  ctx->mon = usb_monitor_init(ctx->mon_pathname, usbdpi_data_callback, ctx);

  // Prepare the transfer descriptors for use
  usb_transfer_setup(ctx);

  return (void *)ctx;
}

void usbdpi_device_to_host(void *ctx_void, const svBitVecVal *usb_d2p) {
  usbdpi_ctx_t *ctx = (usbdpi_ctx_t *)ctx_void;
  assert(ctx);

  // Ascertain the state of the D+/D- signals from the device
  // TODO - migrate to a simple function
  uint32_t d2p = usb_d2p[0];
  unsigned dp, dn;
  if (d2p & D2P_TX_USE_D_SE0) {
    // Single-ended mode uses D and SE0
    if (d2p & D2P_D_EN) {
      if (d2p & D2P_DNPU) {
        // Pullup says swap i.e. D is inverted
        dp = (d2p & D2P_SE0) ? 0 : ((d2p & D2P_D) ? 0 : 1);
        dn = (d2p & D2P_SE0) ? 0 : ((d2p & D2P_D) ? 1 : 0);
      } else {
        dp = (d2p & D2P_SE0) ? 0 : ((d2p & D2P_D) ? 1 : 0);
        dn = (d2p & D2P_SE0) ? 0 : ((d2p & D2P_D) ? 0 : 1);
      }
    } else {
      dp = (d2p & D2P_PU) ? 1 : 0;
      dn = 0;
    }
  } else {
    // Normal D+/D- mode
    if (d2p & D2P_DNPU) {
      // Assertion of DN pullup suggests DP and DN are swapped
      dp = ((d2p & D2P_DN_EN) && (d2p & D2P_DN)) ||
           (!(d2p & D2P_DN_EN) && (d2p & D2P_DNPU));
      dn = (d2p & D2P_DP_EN) && (d2p & D2P_DP);
    } else {
      // No DN pullup so normal orientation
      dp = ((d2p & D2P_DP_EN) && (d2p & D2P_DP)) ||
           (!(d2p & D2P_DP_EN) && (d2p & D2P_DPPU));
      dn = (d2p & D2P_DN_EN) && (d2p & D2P_DN);
    }
  }

  // TODO - check the timing of the device responses to ensure compliance with
  // the specification; the response time of acknowledgements, for example, has
  // a hard real time requirement that is specified in terms of bit intervals
  if (d2p & (D2P_DP_EN | D2P_DN_EN | D2P_D_EN)) {
    switch (ctx->state) {
      // Host to device transmission
      case ST_SYNC:
      case ST_SEND:
      case ST_EOP:
      case ST_EOP0:
        printf(
            "[usbdpi] frame 0x%x tick_bits 0x%x error state %s hs %s and "
            "device "
            "drives\n",
            ctx->frame, ctx->tick_bits, st_states[ctx->state],
            hs_states[ctx->hostSt]);
        break;

      // Device to host transmission; collect the bits
      case ST_GET:
        // TODO - perform bit-level decoding and packet construction here rather
        // than relying upon usb_monitor to do that
        // TODO - synchronize with the device transmission and check that the
        // signals remain stable across all 4 cycles of the bit interval
        break;

      case ST_IDLE:
        // Nothing to do
        break;

      default:
        assert(!"Invalid/unknown state");
        break;
    }

    ctx->state = ST_GET;
  } else {
    if (ctx->state == ST_GET) {
      ctx->state = ST_IDLE;
    }
  }

  if ((d2p & D2P_DNPU) && (d2p & D2P_DPPU)) {
    printf("[usbdpi] frame 0x%x tick_bits 0x%x error both pullups are driven\n",
           ctx->frame, ctx->tick_bits);
  }
  if ((d2p & D2P_PU) != ctx->last_pu) {
    usb_monitor_log(ctx->mon, "0x%-3x 0x%-8x Pullup change to %s%s%s\n",
                    ctx->frame, ctx->tick_bits,
                    (d2p & D2P_DPPU) ? "DP Pulled up " : "",
                    (d2p & D2P_DNPU) ? "DN Pulled up " : "",
                    (d2p & D2P_TX_USE_D_SE0) ? "SingleEnded" : "Differential");

    ctx->last_pu = d2p & D2P_PU;
  }

  // TODO - prime candidate for a function
  if (ctx->loglevel & LOG_BIT) {
    char raw_str[D2P_BITS + 1];
    {
      int i;
      for (i = 0; i < D2P_BITS; i++) {
        raw_str[D2P_BITS - i - 1] = d2p & (1 << i) ? '1' : '0';
      }
    }
    raw_str[D2P_BITS] = 0;

    const char *pullup = (d2p & D2P_PU) ? "PU" : "  ";
    const char *state =
        (ctx->state == ST_GET) ? decode_usb[dp << 1 | dn] : "ZZ ";
    usb_monitor_log(ctx->mon, "0x%-3x 0x%-8x %s %s %s %x\n", ctx->frame,
                    ctx->tick_bits, raw_str, pullup, state, d2p);
  }

  // Device-to-Host EOP
  if (ctx->state == ST_GET && dp == 0 && dn == 0) {
    switch (ctx->bus_state) {
      // Control Transfers
      case kUsbControlSetup:
        ctx->bus_state = kUsbControlSetupAck;
        break;
      case kUsbControlDataOut:
        ctx->bus_state = kUsbControlDataOutAck;
        break;
      case kUsbControlStatusInToken:
        ctx->bus_state = kUsbControlStatusInData;
        break;
      case kUsbControlDataInToken:
        ctx->bus_state = kUsbControlDataInData;
        break;
      case kUsbControlStatusOut:
        ctx->bus_state = kUsbControlStatusOutAck;
        break;

      // Bulk Transfers
      case kUsbBulkOut:
        ctx->bus_state = kUsbBulkOutAck;
        break;
      case kUsbBulkInToken:
        ctx->bus_state = kUsbBulkInData;
        break;

      default:
        break;
    }
  }
}

// Callback for USB data detection
// - the DPI host model presently does not duplicate the bit-level decoding and
//   packet construction of the usb_monitor, so we piggyback on its decoding and
//   trust it to be neutral.
//
// Note: this is invoked for any byte transferred over the USB; both
// host-to-device and device-to-host traffic
void usbdpi_data_callback(void *ctx_v, usbmon_data_type_t type, uint8_t d) {
  usbdpi_ctx_t *ctx = (usbdpi_ctx_t *)ctx_v;
  assert(ctx);
  if (!ctx->recving) {
    ctx->recving = transfer_alloc(ctx);
  }

  // We are interested only in the packets from device to host
  if (ctx->state != ST_GET) {
    return;
  }

  usbdpi_transfer_t *tr = ctx->recving;
  // TODO - commute to run time error indicating buffer exhaustion
  assert(tr);
  if (tr) {
    if (false) {  // ctx->loglevel & LOG_MON) {
      printf("[usbdpi] data type %u d 0x%02x\n", type, d);
    }

    bool ok = false;
    switch (type) {
      case UsbMon_DataType_Sync:
        // Initialize/rewind the received transfer
        transfer_init(tr);
        ok = true;
        break;
      case UsbMon_DataType_EOP:
        ok = true;
        break;
      // Collect the PID and any subsequent data bytes
      case UsbMon_DataType_PID:
        switch (d) {
          case USB_PID_DATA0:
          case USB_PID_DATA1: {
            // TODO - this records the start of the data field with the
            // current transfer descriptors
            uint8_t *dp = transfer_data_start(tr, d, 0U);
            ok = (dp != NULL);
          } break;
          default:
            ok = transfer_append(tr, &d, 1);
            break;
        }
        break;
      // Collect data field
      case UsbMon_DataType_Byte:
        ok = transfer_append(tr, &d, 1);
        break;
      default:
        assert(!"Unknown/unhandled rx type from monitor");
        break;
    }

    // TODO - commute to run time error indicating excessive packet length
    assert(ok);
  }
}

// Set device address (with null data stage)
void setDeviceAddress(usbdpi_ctx_t *ctx, uint8_t dev_addr) {
  usbdpi_transfer_t *tr = ctx->sending;
  uint8_t *dp;
  switch (ctx->hostSt) {
    case HS_STARTFRAME:
      // Setting device address, uses address 0 initially
      transfer_token(tr, USB_PID_SETUP, 0, ENDPOINT_ZERO);

      dp = transfer_data_start(tr, USB_PID_DATA0, 8);
      if (INSERT_ERR_PID) {
        *(dp - 1) = 0xc4U;
      }
      dp[0] = 0;  // h2d, std, device
      dp[1] = USB_REQ_SET_ADDRESS;
      dp[2] = dev_addr;  // device address
      dp[3] = 0;
      // Trigger bitstuffing, technically the device
      // behavior is unspecified with wIndex != 0
      dp[4] = 0xFF;  // wIndex = 0xFF00
      dp[5] = 0;
      dp[6] = 0;  // wLength = 0
      dp[7] = 0;
      transfer_data_end(tr, dp + 8);
      if (INSERT_ERR_CRC) {
        // Flip the last CRC bit to emulate a CRC error
        dp[9] ^= 0x01u;
      }
      transfer_send(ctx, tr);
      ctx->bus_state = kUsbControlSetup;
      ctx->hostSt = HS_WAITACK;
      break;
    case HS_WAITACK:
      ctx->wait = ctx->tick_bits + 532;  // HACK
      ctx->hostSt = HS_SET_DATASTAGE;
      break;
    case HS_SET_DATASTAGE:
      if (ctx->bus_state == kUsbControlSetupAck &&
          ctx->tick_bits >= ctx->wait) {
        transfer_token(tr, USB_PID_IN, 0, 0);
        transfer_send(ctx, tr);
        ctx->bus_state = kUsbControlStatusInToken;
        ctx->hostSt = HS_DS_RXDATA;
      }
      break;
    case HS_DS_RXDATA:
      ctx->wait = ctx->tick_bits + 24;  // HACK -- 2 bytes
      ctx->hostSt = HS_DS_SENDACK;
      break;
    case HS_DS_SENDACK:
      if (ctx->bus_state == kUsbControlStatusInData ||
          ctx->tick_bits >= ctx->wait) {
        transfer_status(ctx, tr, USB_PID_ACK);
        ctx->bus_state = kUsbIdle;
        ctx->hostSt = HS_NEXTFRAME;

        // Remember the assigned device address
        ctx->dev_address = dev_addr;

        printf("[usbdpi] setDeviceAddress done\n");
      }
      break;
    default:
      break;
  }
}

// Set device configuration
void setDeviceConfiguration(usbdpi_ctx_t *ctx, uint8_t config) {
  usbdpi_transfer_t *tr = ctx->sending;
  uint8_t *dp;
  switch (ctx->hostSt) {
    case HS_STARTFRAME:
      transfer_token(tr, USB_PID_SETUP, ctx->dev_address, ENDPOINT_ZERO);

      dp = transfer_data_start(tr, USB_PID_DATA0, 8);
      dp[0] = 0;  // h2d, std, device
      dp[1] = USB_REQ_SET_CONFIGURATION;
      dp[2] = config;
      dp[3] = 0;
      dp[4] = 0;  // wIndex = 0
      dp[5] = 0;
      dp[6] = 0;  // wLength = 0
      dp[7] = 0;
      transfer_data_end(tr, dp + 8);

      transfer_send(ctx, tr);
      ctx->bus_state = kUsbControlSetup;
      ctx->hostSt = HS_WAITACK;
      break;
    case HS_WAITACK:
      ctx->wait = ctx->tick_bits + 532;  // HACK
      ctx->hostSt = HS_SET_DATASTAGE;
      break;
    case HS_SET_DATASTAGE:
      if (ctx->bus_state == kUsbControlSetupAck &&
          ctx->tick_bits >= ctx->wait) {
        transfer_token(tr, USB_PID_IN, ctx->dev_address, ENDPOINT_ZERO);
        transfer_send(ctx, tr);
        ctx->bus_state = kUsbControlStatusInToken;
        ctx->hostSt = HS_DS_RXDATA;
      }
      break;
    case HS_DS_RXDATA:
      ctx->wait = ctx->tick_bits + 24;  // HACK -- 2 bytes
      ctx->hostSt = HS_DS_SENDACK;
      break;
    case HS_DS_SENDACK:
      if (ctx->bus_state == kUsbControlStatusInData ||
          ctx->tick_bits >= ctx->wait) {
        transfer_status(ctx, tr, USB_PID_ACK);
        ctx->bus_state = kUsbIdle;
        ctx->hostSt = HS_NEXTFRAME;
        printf("[usbdpi] setDeviceConfiguration done\n");
      }
      break;
    default:
      break;
  }
}

// Get Descriptor
void getDescriptor(usbdpi_ctx_t *ctx, uint8_t desc_type, uint8_t desc_idx,
                   uint16_t desc_len) {
  usbdpi_transfer_t *tr = ctx->sending;
  uint8_t *dp;
  switch (ctx->hostSt) {
    case HS_STARTFRAME: {
      // TODO - build the bmRequestType by ORing values
      const uint8_t bmRequestType = 0x80;  // d2h, vendor, endpoint
      uint16_t wValue = (desc_type << 8) | (uint8_t)desc_idx;
      transfer_setup(ctx, tr, bmRequestType, USB_REQ_GET_DESCRIPTOR, wValue, 0U,
                     desc_len);
    } break;
    case HS_WAITACK:
      ctx->wait = ctx->tick_bits + 1164;  // HACK
      ctx->hostSt = HS_REQDATA;
      break;
    case HS_REQDATA:
      // TODO - we must wait before trying the IN because we currently
      // do not retry after a NAK response, but the CPU software can be tardy
      if (ctx->tick_bits >= ctx->wait &&
          ctx->bus_state == kUsbControlSetupAck) {
        transfer_token(tr, USB_PID_IN, ctx->dev_address, ENDPOINT_ZERO);

        transfer_send(ctx, tr);
        ctx->bus_state = kUsbControlDataInToken;
        ctx->hostSt = HS_WAITDATA;
      }
      break;
    case HS_WAITDATA:
      ctx->wait = ctx->tick_bits + 2000;  // HACK
      ctx->hostSt = HS_SENDACK;
      break;
    case HS_SENDACK:
      if (ctx->bus_state == kUsbControlDataInData) {
        if (ctx->step == STEP_GET_CONFIG_DESCRIPTOR) {
          // Check the GET_DESCRIPTOR response
          assert(ctx->recving);

          // TODO - detect when the returned data falls short of the requested
          // transfer length
          uint8_t *dp = transfer_data_field(ctx->recving);
          assert(dp);
          // Collect the returned values
          // uint8_t  bLength = dp[0];
          // uint8_t  bDescriptorType = dp[1];
          uint16_t wTotalLength = dp[2] | (dp[3] << 8);
          // uint8_t  bNumInterfaces = dp[4];

          ctx->cfg_desc_len = wTotalLength;
        }

        transfer_token(tr, USB_PID_ACK, ctx->dev_address, ENDPOINT_ZERO);

        transfer_send(ctx, tr);
        ctx->bus_state = kUsbControlDataInAck;
        ctx->hostSt = HS_WAIT_PKT;

        ctx->wait = ctx->tick_bits + 200;  // HACK
      } else if (ctx->tick_bits >= ctx->wait) {
        printf("[usbdpi] Timed out waiting for device\n");
        ctx->hostSt = HS_NEXTFRAME;
        ctx->bus_state = kUsbIdle;
      }
      break;
    case HS_WAIT_PKT:
      // TODO - introduce support for multiple packets when we've requested
      // longer transfers
      if (ctx->tick_bits >= ctx->wait) {
        ctx->hostSt = HS_EMPTYDATA;
      }
      break;
    case HS_EMPTYDATA:
      // Status stage of Control Read
      // Transmit zero-length data packet and await handshake
      transfer_token(tr, USB_PID_OUT, ctx->dev_address, ENDPOINT_ZERO);

      dp = transfer_data_start(tr, USB_PID_DATA1, 0);
      transfer_data_end(tr, dp);
      transfer_send(ctx, tr);
      ctx->bus_state = kUsbControlStatusOut;
      ctx->hostSt = HS_WAITACK2;
      ctx->wait = ctx->tick_bits + 200;  // HACK
      break;
    case HS_WAITACK2:
      if (ctx->bus_state == kUsbControlStatusOutAck) {
        switch (ctx->lastrxpid) {
          case USB_PID_ACK:
            ctx->ep_out[ENDPOINT_ZERO].next_data =
                DATA_TOGGLE_ADVANCE(ctx->ep_out[ENDPOINT_ZERO].next_data);
            ctx->hostSt = HS_NEXTFRAME;
            break;

          case USB_PID_NAK:
            // TODO - this means that the device is still busy
            ctx->hostSt = HS_WAITACK2;
            ctx->wait = ctx->tick_bits + 200;  // HACK
            break;

          // TODO - commute these other responses into test failures
          case USB_PID_STALL:
            printf("[usbdpi] Device stalled\n");
            ctx->hostSt = HS_NEXTFRAME;
            break;
          default:
            printf("[usbdpi] Unexpected handshake response 0x%02x\n",
                   ctx->lastrxpid);
            ctx->hostSt = HS_NEXTFRAME;
            break;
        }
      } else if (ctx->tick_bits >= ctx->wait) {
        printf(
            "[usbdpi] Time out waiting for device response in Status Stage\n");
        ctx->hostSt = HS_NEXTFRAME;
      }
      break;
    default:
      break;
  }
}

// Get Test Configuration (Vendor-specific)
void getTestConfig(usbdpi_ctx_t *ctx, uint16_t desc_len) {
  usbdpi_transfer_t *tr = ctx->sending;
  uint8_t *dp;
  assert(tr);
  switch (ctx->hostSt) {
    case HS_STARTFRAME: {
      const uint8_t bmRequestType = 0xc2;  // d2h, vendor, endpoint
      transfer_setup(ctx, tr, bmRequestType, USBDPI_VENDOR_TEST_CONFIG, 0U, 0U,
                     desc_len);
    } break;
    case HS_WAITACK:
      ctx->wait = ctx->tick_bits + 1164;  // HACK
      ctx->hostSt = HS_REQDATA;
      break;
    case HS_REQDATA:
      // TODO - we must wait before trying the IN because we currently
      // do not retry after a NAK response, but the CPU software can be tardy
      if (ctx->tick_bits >= ctx->wait &&
          ctx->bus_state == kUsbControlSetupAck) {
        transfer_token(tr, USB_PID_IN, ctx->dev_address, ENDPOINT_ZERO);

        transfer_send(ctx, tr);
        ctx->bus_state = kUsbControlDataInToken;
        ctx->hostSt = HS_WAITDATA;
      }
      break;
    case HS_WAITDATA:
      ctx->wait = ctx->tick_bits + 2000;  // HACK
      ctx->hostSt = HS_SENDACK;
      break;
    case HS_SENDACK:
      if (ctx->bus_state == kUsbControlDataInData) {
        switch (ctx->lastrxpid) {
          case USB_PID_DATA1: {
            usbdpi_transfer_t *rx = ctx->recving;
            assert(rx);
            // TODO - check the length of the received data field!
            uint8_t *dp = transfer_data_field(rx);
            assert(dp);
            // Validate the first part of the test descriptor
            printf("[usbdpi] Test descriptor 0x%.8X\n", get_le32(dp));

            transfer_dump(rx, stdout);

            // Check the header signature
            const uint8_t test_sig_head[] = {0x7eu, 0x57u, 0xc0u, 0xf1u};
            const uint8_t test_sig_tail[] = {0x1fu, 0x0cu, 0x75u, 0xe7u};
            if (!memcmp(dp, test_sig_head, 4) && 0x10 == get_le16(&dp[4]) &&
                !memcmp(&dp[12], test_sig_tail, 4)) {
              ctx->test_number = get_le16(&dp[6]);
              ctx->test_arg[0] = dp[8];
              ctx->test_arg[1] = dp[9];
              ctx->test_arg[2] = dp[10];
              ctx->test_arg[3] = dp[11];

              printf("[usbdpi] Test number 0x%04x args %02x %02x %02x %02x\n",
                     ctx->test_number, ctx->test_arg[0], ctx->test_arg[1],
                     ctx->test_arg[2], ctx->test_arg[3]);

              usbdpi_test_init(ctx);
            } else {
              printf(
                  "[usbdpi] Invalid/unrecognised test descriptor received\n");
              assert(!"Cannot proceed without test descriptor");
            }
          } break;

          case USB_PID_NAK:
            // TODO - we should retry the request in this case
            printf("[usbdpi] Unable to retrieve test config\n");
            assert(!"DPI is unable to retrieve test config");
            ctx->hostSt = HS_NEXTFRAME;
            break;

          case USB_PID_STALL:
            printf("[usbdpi] Device stalled\n");
            assert(!"Device is stalled");
            ctx->hostSt = HS_NEXTFRAME;
            break;
          default:
            printf("[usbdpi] Unexpected handshake response 0x%02x\n",
                   ctx->lastrxpid);
            assert(!"Unexpected handshake response");
            ctx->hostSt = HS_NEXTFRAME;
            break;
        }
        transfer_token(tr, USB_PID_ACK, ctx->dev_address, ENDPOINT_ZERO);

        transfer_send(ctx, tr);
        ctx->bus_state = kUsbControlDataInAck;
        ctx->hostSt = HS_WAIT_PKT;

        ctx->wait = ctx->tick_bits + 200;  // HACK
      } else if (ctx->tick_bits >= ctx->wait) {
        printf("[usbdpi] Timed out waiting for device\n");
        ctx->hostSt = HS_NEXTFRAME;
        ctx->bus_state = kUsbIdle;
      }
      break;
    case HS_WAIT_PKT:
      if (ctx->tick_bits >= ctx->wait) {
        ctx->hostSt = HS_EMPTYDATA;
      }
      break;
    case HS_EMPTYDATA:
      // Status stage of Control Read
      // Transmit zero-length data packet and await handshake
      transfer_token(tr, USB_PID_OUT, ctx->dev_address, ENDPOINT_ZERO);

      dp = transfer_data_start(tr, USB_PID_DATA1, 0);
      transfer_data_end(tr, dp);
      transfer_send(ctx, tr);
      ctx->bus_state = kUsbControlStatusOut;
      ctx->hostSt = HS_WAITACK2;
      ctx->wait = ctx->tick_bits + 200;  // HACK
      break;
    case HS_WAITACK2:
      if (ctx->bus_state == kUsbControlStatusOutAck) {
        switch (ctx->lastrxpid) {
          case USB_PID_ACK:
            ctx->ep_out[ENDPOINT_ZERO].next_data =
                DATA_TOGGLE_ADVANCE(ctx->ep_out[ENDPOINT_ZERO].next_data);
            ctx->hostSt = HS_NEXTFRAME;
            break;

          case USB_PID_NAK:
            // TODO - this means that the device is still busy
            ctx->hostSt = HS_WAITACK2;
            ctx->wait = ctx->tick_bits + 200;  // HACK
            break;

          // TODO - commute these other responses into test failures
          case USB_PID_STALL:
            printf("[usbdpi] Device stalled\n");
            ctx->hostSt = HS_NEXTFRAME;
            break;
          default:
            printf("[usbdpi] Unexpected handshake response 0x%02x\n",
                   ctx->lastrxpid);
            ctx->hostSt = HS_NEXTFRAME;
            break;
        }
      } else if (ctx->tick_bits >= ctx->wait) {
        printf(
            "[usbdpi] Time out waiting for device response in Status Stage\n");
        ctx->hostSt = HS_NEXTFRAME;
      }
      break;
    default:
      break;
  }
}

// Set Test Status, reporting progress/success/failure (Vendor-specific)
void setTestStatus(usbdpi_ctx_t *ctx, uint32_t status, const char *msg) {
  // TODO - placeholder for reporting of test status reporting and termination
}

// Get Baud (Vendor-specific)
void readBaud(usbdpi_ctx_t *ctx, uint8_t endpoint) {
  usbdpi_transfer_t *tr = ctx->sending;
  uint8_t *dp;
  switch (ctx->hostSt) {
    case HS_STARTFRAME:
      transfer_token(tr, USB_PID_SETUP, ctx->dev_address, endpoint);

      dp = transfer_data_start(tr, USB_PID_DATA0, 0);
      dp[0] = 0xc2;  // d2h, vendor, endpoint
      dp[1] = 2;     // get baud
      dp[2] = 0;     // index 0
      dp[3] = 0;     // type device
      dp[4] = 0;     // wIndex = 0
      dp[5] = 0;
      dp[6] = 0x2;  // wLength = 2
      dp[7] = 0;
      transfer_data_end(tr, dp + 8);

      transfer_send(ctx, tr);
      ctx->bus_state = kUsbControlSetup;
      ctx->hostSt = HS_WAITACK;
      break;
    case HS_WAITACK:
      ctx->wait = ctx->tick_bits + 32;  // HACK
      ctx->hostSt = HS_REQDATA;
      break;
    case HS_REQDATA:
      if (ctx->tick_bits >= ctx->wait) {
        // NOTE: This IN request produces a NAK from the device because there is
        //       nothing available, at which point a REAL host should surely
        //       retry the request at a later time!
        transfer_token(tr, USB_PID_IN, ctx->dev_address, endpoint);

        transfer_send(ctx, tr);
        ctx->hostSt = HS_WAITDATA;
      }
      break;
    case HS_WAITDATA:
      ctx->wait = ctx->tick_bits + 200;  // HACK
      ctx->hostSt = HS_SENDACK;
      break;
    case HS_SENDACK:
      // TODO - are we not ACKing the NAK at this point?
      if (ctx->tick_bits >= ctx->wait) {
        transfer_status(ctx, tr, USB_PID_ACK);
        ctx->hostSt = HS_EMPTYDATA;
      }
      break;
    case HS_EMPTYDATA:
      // Transmit OUT transaction with zero-length DATA packet
      transfer_token(tr, USB_PID_OUT, ctx->dev_address, endpoint);
      if (INSERT_ERR_DATA_TOGGLE) {
        // NOTE: This raises a LinkOutErr on the USBDEV because it is expecting
        //       DATA0
        uint8_t bad_pid = DATA_TOGGLE_ADVANCE(ctx->ep_out[endpoint].next_data);
        dp = transfer_data_start(tr, bad_pid, 0);
      } else {
        dp = transfer_data_start(tr, ctx->ep_out[endpoint].next_data, 0);
      }
      transfer_data_end(tr, dp);

      transfer_send(ctx, tr);
      ctx->bus_state = kUsbControlStatusOut;
      ctx->hostSt = HS_WAITACK2;

      ctx->wait = ctx->tick_bits + 200;  // HACK
      break;
    case HS_WAITACK2:
      if (ctx->tick_bits >= ctx->wait ||
          ctx->bus_state == kUsbControlStatusOutAck) {
        if (ctx->lastrxpid == USB_PID_ACK) {
          ctx->ep_out[endpoint].next_data =
              DATA_TOGGLE_ADVANCE(ctx->ep_out[endpoint].next_data);
        }
        ctx->hostSt = HS_NEXTFRAME;
        printf("[usbdpi] readBaud done\n");
      }
      break;
    default:
      break;
  }
}

// Set Baud (Vendor-specific)
void setBaud(usbdpi_ctx_t *ctx, uint8_t endpoint) {
  usbdpi_transfer_t *tr = ctx->sending;
  uint8_t *dp;
  switch (ctx->hostSt) {
    case HS_STARTFRAME:
      transfer_token(tr, USB_PID_SETUP, ctx->dev_address, endpoint);

      dp = transfer_data_start(tr, USB_PID_DATA0, 0);
      dp[0] = 0x42;  // h2d, vendor, endpoint
      dp[1] = 3;     // set baud
      dp[2] = 96;    // index 0
      dp[3] = 0;     // type device
      dp[4] = 0;     // wIndex = 0
      dp[5] = 0;
      dp[6] = 0;  // wLength = 0
      dp[7] = 0;
      transfer_data_end(tr, dp + 8);

      transfer_send(ctx, tr);
      ctx->bus_state = kUsbControlSetup;
      ctx->hostSt = HS_WAITACK;
      break;
    case HS_WAITACK:
      ctx->wait = ctx->tick_bits + 32;  // HACK
      ctx->hostSt = HS_REQDATA;
      break;
    case HS_REQDATA:
      if (ctx->tick_bits >= ctx->wait) {
        transfer_token(tr, USB_PID_IN, ctx->dev_address, endpoint);

        transfer_send(ctx, tr);
        ctx->hostSt = HS_WAITDATA;
      }
      break;
    case HS_WAITDATA:
      ctx->wait = ctx->tick_bits + 40;  // HACK
      ctx->hostSt = HS_SENDACK;
      break;
    case HS_SENDACK:
      if (ctx->tick_bits >= ctx->wait) {
        transfer_status(ctx, tr, USB_PID_ACK);
        ctx->hostSt = HS_NEXTFRAME;
        ctx->baudrate_set_successfully = 1;
        printf("[usbdpi] setBaud done\n");
      }
      break;
    default:
      break;
  }
}

// Try an OUT transfer to the device, optionally expecting a Status
//   packet (eg. ACK|NAK) in response; this is not expected for
//   Isochronous transfers
void tryTX(usbdpi_ctx_t *ctx, uint8_t endpoint, bool expect_status) {
  const uint8_t pattern[] = {
      "AbCdEfGhIjKlMnOpQrStUvWxYz+0123456789-aBcDeFgHiJkLmNoPqRsTuVwXyZ"};
  usbdpi_transfer_t *tr = ctx->sending;
  uint8_t *dp;
  switch (ctx->hostSt) {
    case HS_STARTFRAME:
      transfer_token(tr, USB_PID_OUT, ctx->dev_address, endpoint);

      dp = transfer_data_start(tr, ctx->ep_out[endpoint].next_data, 0);
      memcpy(dp, pattern, sizeof(pattern));
      transfer_data_end(tr, dp + sizeof(pattern));

      transfer_send(ctx, tr);
      ctx->bus_state = kUsbBulkOut;
      ctx->hostSt = HS_WAITACK;
      break;
    case HS_WAITACK:  // no actual ACK if Isochronous transfer
      ctx->wait = ctx->tick_bits + 32;
      ctx->hostSt = HS_REQDATA;
      break;
    case HS_REQDATA:
      if (ctx->tick_bits >= ctx->wait) {
        // Note: Isochronous transfers are not acknowledged and do not employ
        //       Data Toggle Synchronization
        if (expect_status && ctx->lastrxpid == USB_PID_ACK) {
          ctx->ep_out[endpoint].next_data =
              DATA_TOGGLE_ADVANCE(ctx->ep_out[endpoint].next_data);
        }

        transfer_token(tr, USB_PID_IN, ctx->dev_address, endpoint);
        transfer_send(ctx, tr);

        ctx->hostSt = HS_WAITDATA;
      }
      break;
    case HS_WAITDATA:
      ctx->wait = ctx->tick_bits + 40;  // HACK
      ctx->hostSt = HS_NEXTFRAME;
      printf("[usbdpi] testIso done\n");
    default:
      break;
  }
}

// Request IN. Get back DATA0/DATA1 or NAK.
//
// send_hi  -> also send OUT packet
// nak_data -> send NAK instead of ACK if there is data
void pollRX(usbdpi_ctx_t *ctx, uint8_t endpoint, bool send_hi, bool nak_data) {
  usbdpi_transfer_t *tr = ctx->sending;
  uint8_t *dp;
  switch (ctx->hostSt) {
    case HS_STARTFRAME:
      transfer_token(tr, USB_PID_IN, ctx->dev_address, endpoint);

      transfer_send(ctx, tr);
      ctx->bus_state = kUsbBulkInToken;
      ctx->hostSt = HS_WAIT_PKT;
      ctx->lastrxpid = 0;
      break;
    case HS_WAIT_PKT:
      // Wait max time for a response + packet
      ctx->wait = ctx->tick_bits + 18 + 8 + 8 + 64 * 8 + 16;
      ctx->hostSt = HS_ACKIFDATA;
      break;
    case HS_ACKIFDATA:
      if (ctx->bus_state == kUsbBulkInData) {
        // TODO - have we got a LFSR-generated data packet?
        if (ctx->lastrxpid != USB_PID_NAK) {
          transfer_status(ctx, tr, nak_data ? USB_PID_NAK : USB_PID_ACK);
        }
        ctx->hostSt = HS_SENDHI;
      } else if (ctx->tick_bits >= ctx->wait) {
        printf("[usbdpi] Timed out waiting for IN response\n");
        ctx->hostSt = HS_SENDHI;
      }
      break;
    case HS_SENDHI:
      if (send_hi) {
        transfer_token(tr, USB_PID_OUT, ctx->dev_address, endpoint);

        dp = transfer_data_start(tr, ctx->ep_out[endpoint].next_data, 0);
        dp[0] = 0x48;  // "H"
        dp[1] = 0x69;  // "i"
        dp[2] = 0x21;  // "!"
        transfer_data_end(tr, dp + 3);

        transfer_send(ctx, tr);
        ctx->wait = ctx->tick_bits + 532;  // HACK
        ctx->hostSt = HS_WAITACK;
      } else {
        ctx->hostSt = HS_NEXTFRAME;
      }
      break;
    case HS_WAITACK:
      if (ctx->tick_bits >= ctx->wait) {
        if (ctx->lastrxpid == USB_PID_ACK) {
          ctx->ep_out[endpoint].next_data =
              DATA_TOGGLE_ADVANCE(ctx->ep_out[endpoint].next_data);
        }
        ctx->hostSt = HS_NEXTFRAME;
      }
      break;
    default:
      break;
  }
}

// Test behavior in (non-)response to other device and unimplemented endpoints
void testUnimplEp(usbdpi_ctx_t *ctx, uint8_t pid, uint8_t device,
                  uint8_t endpoint) {
  usbdpi_transfer_t *tr = ctx->sending;
  uint8_t *dp;
  switch (ctx->hostSt) {
    case HS_STARTFRAME:
      if ((pid == USB_PID_SETUP) || (pid == USB_PID_OUT)) {
        transfer_token(tr, pid, device, endpoint);

        dp = transfer_data_start(tr, USB_PID_DATA0, 0);
        dp[0] = 0;  // h2d, std, device
        dp[1] = 5;  // set address
        dp[2] = 2;  // device address
        dp[3] = 0;
        // Trigger bitstuffing, technically the device
        // behavior is unspecified with wIndex != 0
        dp[4] = 0xFF;  // wIndex = 0xFF00
        dp[5] = 0;
        dp[6] = 0;  // wLength = 0
        dp[7] = 0;
        transfer_data_end(tr, dp + 8);

        transfer_send(ctx, tr);
        ctx->hostSt = HS_WAITACK;
        break;
      } else if (pid == USB_PID_IN) {
        transfer_token(tr, pid, device, endpoint);
        transfer_send(ctx, tr);

        // Since the endpoint is not implemented, the device should respond with
        // a STALL packet (not DATA0/1 or NAK).
        ctx->hostSt = HS_WAITACK;
        break;
      } else {
        ctx->hostSt = HS_NEXTFRAME;
        printf(
            "[usbdpi] testUnimplEp supports SETUP, OUT and IN transactions "
            "only\n");
        break;
      }
    case HS_WAITACK:
      // Note: We currently can't observe the responses sent by the device, but
      // usb_monitor() does log all transactions from host and device and does
      // some basic decoding.
      // Depending on the transaction type to unimplemented endpoints, we would
      // expect the following response:
      // - SETUP: no response (must be ignored by the device)
      // - OUT/IN: a STALL packet from the device
      ctx->wait = ctx->tick_bits + 32;  // HACK
      ctx->hostSt = HS_NEXTFRAME;
      printf("[usbdpi] testUnimplEp done\n");
      break;
    default:
      break;
  }
}

// Change DP and DN outputs from host
uint32_t set_driving(usbdpi_ctx_t *ctx, uint32_t d2p, uint32_t newval) {
  // Always maintain the current state of VBUS
  uint32_t driving = ctx->driving & P2D_SENSE;
  if (d2p & D2P_DNPU) {
    // Have dn pull-up, so must be flipping pins
    if (newval & P2D_DP) {
      driving |= P2D_DN | P2D_D;
    } else if (newval & P2D_DN) {
      driving |= P2D_DP;
    }
  } else {
    if (newval & P2D_DP) {
      driving |= P2D_DP | P2D_D;
    } else if (newval & P2D_DN) {
      driving |= P2D_DN;
    }
  }
  return driving;
}

// Optionally invert the signals the host is driving, according to bus
// configuration
uint32_t inv_driving(usbdpi_ctx_t *ctx, uint32_t d2p) {
  // works for either orientation
  return ctx->driving ^ (P2D_DP | P2D_DN | P2D_D);
}

uint8_t usbdpi_host_to_device(void *ctx_void, const svBitVecVal *usb_d2p) {
  usbdpi_ctx_t *ctx = (usbdpi_ctx_t *)ctx_void;
  assert(ctx);
  int d2p = usb_d2p[0];
  uint32_t last_driving = ctx->driving;
  int force_stat = 0;
  int dat;

  // The 48MHz clock runs at 4 times the bus clock for a full speed (12Mbps)
  // device
  //
  // TODO - vary the phase over the duration of the test to check device
  //        synchronization
  ctx->tick++;
  ctx->tick_bits = ctx->tick >> 2;
  if (ctx->tick & 3) {
    return ctx->driving;
  }

  // Monitor, analyse and record USB bus activity
  usb_monitor(ctx->mon, ctx->loglevel, ctx->tick_bits,
              (ctx->state != ST_IDLE) && (ctx->state != ST_GET), ctx->driving,
              d2p, &(ctx->lastrxpid));

  if (ctx->tick_bits == SENSE_AT) {
    ctx->driving |= P2D_SENSE;
  }

  if ((d2p & D2P_PU) == 0) {
    ctx->recovery_time = ctx->tick + 4 * 48;
    return ctx->driving;
  }

  // Are allowed to start transmitting yet; device recovery time elapsed?
  if (ctx->tick < ctx->recovery_time) {
    ctx->frame_start = ctx->tick_bits;
    return ctx->driving;
  }

  // Time to commence a new bus frame?
  if ((ctx->tick_bits - ctx->frame_start) >= FRAME_INTERVAL) {
    if (ctx->state != ST_IDLE) {
      if (ctx->framepend == 0) {
        printf(
            "[usbdpi] frame 0x%x tick_bits 0x%x error state %d at frame 0x%x "
            "time\n",
            ctx->frame, ctx->tick, ctx->state, ctx->frame + 1);
      }
      ctx->framepend = 1;
    } else {
      if (ctx->framepend == 1) {
        printf("[usbdpi] frame 0x%x tick_bits 0x%x can send frame 0x%x SOF\n",
               ctx->frame, ctx->tick, ctx->frame + 1);
      }
      ctx->framepend = 0;
      ctx->frame++;
      ctx->frame_start = ctx->tick_bits;

      if (ctx->step >= STEP_IDLE_START && ctx->step < STEP_IDLE_END) {
        // Test suspend behavior by dropping the SOF signalling
        ctx->state = ST_IDLE;
        printf("[usbdpi] idle frame 0x%x\n", ctx->frame);
      } else {
        // Ensure that a buffer is available for constructing a transfer
        usbdpi_transfer_t *tr = ctx->sending;
        if (!tr) {
          tr = transfer_alloc(ctx);
          assert(tr);

          ctx->sending = tr;
        }

        transfer_frame_start(ctx, tr, ctx->frame);
        ctx->state = ST_SYNC;
      }
      printf("[usbdpi] frame 0x%x tick_bits 0x%x CRC5 0x%x\n", ctx->frame,
             ctx->tick, CRC5(ctx->frame, 11));

      if (ctx->hostSt == HS_NEXTFRAME) {
        ctx->step = usbdpi_test_seq_next(ctx, ctx->step);
        ctx->hostSt = HS_STARTFRAME;
      } else {
        // TODO - this surely means that something went wrong;
        // but what shall we do at this point?!
        assert(!"DPI Host not ready to start new frame");
      }
    }
  }

  switch (ctx->state) {
    // Host state machine advances when the bit-level activity is idle
    case ST_IDLE: {
      // Ensure that a buffer is available for constructing a transfer
      usbdpi_transfer_t *tr = ctx->sending;
      if (!tr) {
        tr = transfer_alloc(ctx);
        assert(tr);
        ctx->sending = tr;
      }

      switch (ctx->step) {
        case STEP_SET_DEVICE_ADDRESS:
          setDeviceAddress(ctx, USBDEV_ADDRESS);
          break;

          // TODO - an actual host issues a number of GET_DESCRIPTOR control/
          //        transfers to read descriptions of the configurations,
          //        interfaces and endpoints

        case STEP_GET_DEVICE_DESCRIPTOR:
          // Initially we fetch just the minimal descriptor length of 0x12U
          // bytes and the returned information will indicate the full length
          //
          // TODO - Set the descriptor length to the minimum because the DPI
          // model does not yet catch and report errors properly
          ctx->cfg_desc_len = 12U;
          getDescriptor(ctx, USB_DESC_TYPE_DEVICE, 0U, 0x12U);
          break;

        case STEP_GET_CONFIG_DESCRIPTOR:
          getDescriptor(ctx, USB_DESC_TYPE_CONFIGURATION, 0U, 0x9U);
          break;

        case STEP_GET_FULL_CONFIG_DESCRIPTOR: {
          uint16_t wLength = ctx->cfg_desc_len;
          if (wLength >= USBDEV_MAX_PACKET_SIZE) {
            // Note: getDescriptor cannot yet receive multiple packets
            wLength = USBDEV_MAX_PACKET_SIZE;
          }
          getDescriptor(ctx, USB_DESC_TYPE_CONFIGURATION, 0U, wLength);
        } break;

          // TODO - we must receive and respond to test configuration at some
          //        point; perhaps we can make the software advertise itself
          //        with different vendor/device combinations to indicate the
          //        testing we must do

        case STEP_SET_DEVICE_CONFIG:
          setDeviceConfiguration(ctx, 1);
          break;

        // Test configuration and status
        case STEP_GET_TEST_CONFIG:
          getTestConfig(ctx, 0x10U);
          break;

        case STEP_SET_TEST_STATUS:
          setTestStatus(ctx, ctx->test_status, ctx->test_msg);
          break;

          // These should be at 3 and 4 but the read needs the host
          // not to be sending (until skip fifo is implemented in in_pe engine)
          // so for now push later when things are quiet (could also adjust
          // hello_world to not use the uart until frame 4)

        case STEP_FIRST_READ:
          pollRX(ctx, ENDPOINT_SERIAL0, true, true);
          break;
        case STEP_READ_BAUD:
          readBaud(ctx, ENDPOINT_ZERO);
          break;
        case STEP_SECOND_READ:
          pollRX(ctx, ENDPOINT_SERIAL0, true, false);
          break;
        case STEP_SET_BAUD:
          setBaud(ctx, ENDPOINT_ZERO);
          break;
        case STEP_THIRD_READ:
          pollRX(ctx, ENDPOINT_SERIAL0, false, true);
          break;
        case STEP_TEST_ISO1:
          testIso(ctx);
          break;
        case STEP_TEST_ISO2:
          testIso(ctx);
          break;

        // Test each of SETUP, OUT and IN to an unimplemented endpoint
        case STEP_ENDPT_UNIMPL_SETUP:
          testUnimplEp(ctx, USB_PID_SETUP, ctx->dev_address,
                       ENDPOINT_UNIMPLEMENTED);
          break;
        case STEP_ENDPT_UNIMPL_OUT:
          testUnimplEp(ctx, USB_PID_OUT, ctx->dev_address,
                       ENDPOINT_UNIMPLEMENTED);
          break;
        case STEP_ENDPT_UNIMPL_IN:
          testUnimplEp(ctx, USB_PID_IN, ctx->dev_address,
                       ENDPOINT_UNIMPLEMENTED);
          break;
        case STEP_DEVICE_UK_SETUP:
          testUnimplEp(ctx, USB_PID_SETUP, UKDEV_ADDRESS, 1u);
          break;

        case STEP_STREAM_SERVICE:
          // After the initial testing of the (current) fixed DPI behavior,
          // we repeatedly try IN transfers, checking and scrambling any
          // data packets that we received before sending them straight back
          // to the device for software to check
          streams_service(ctx);
          break;

        default:
          if (ctx->step < STEP_IDLE_START || ctx->step >= STEP_IDLE_END) {
            pollRX(ctx, ENDPOINT_SERIAL0, false, false);
          }
          break;
      }
    } break;

    case ST_SYNC:
      dat = ((USB_SYNC & ctx->bit)) ? P2D_DP : P2D_DN;
      ctx->driving = set_driving(ctx, d2p, dat);
      force_stat = 1;
      ctx->bit <<= 1;
      if (ctx->bit == 0x100) {
        ctx->bit = 1;
        ctx->linebits = 1;  // The KK at end of SYNC counts for bit stuffing!
        ctx->state = ST_SEND;
      }
      break;

    case ST_SEND: {
      usbdpi_transfer_t *sending = ctx->sending;
      assert(sending);
      if ((ctx->linebits & 0x3f) == 0x3f &&
          !INSERT_ERR_BITSTUFF) {  // sent 6 ones
        // bit stuff and force a transition
        ctx->driving = inv_driving(ctx, d2p);
        force_stat = 1;
        ctx->linebits = (ctx->linebits << 1);
      } else if (ctx->byte >= sending->num_bytes) {
        ctx->state = ST_EOP;
        ctx->driving = set_driving(ctx, d2p, 0);  // SE0
        ctx->bit = 1;
        force_stat = 1;
      } else {
        int nextbit = (sending->data[ctx->byte] & ctx->bit) ? 1 : 0;
        if (nextbit == 0) {
          ctx->driving = inv_driving(ctx, d2p);
        }
        ctx->linebits = (ctx->linebits << 1) | nextbit;
        force_stat = 1;
        ctx->bit <<= 1;
        if (ctx->bit == 0x100) {
          ctx->bit = 1;
          ctx->byte++;
          if (ctx->byte == sending->data_start) {
            ctx->state = ST_EOP0;
          }
        }
      }
    } break;

    case ST_EOP0:
      ctx->driving = set_driving(ctx, d2p, 0);  // SE0
      ctx->state = ST_EOP;
      break;

    case ST_EOP:  // SE0 SE0 J
      if (ctx->bit == 4) {
        ctx->driving = set_driving(ctx, d2p, P2D_DP);  // J
      }
      if (ctx->bit == 8) {
        usbdpi_transfer_t *sending = ctx->sending;
        assert(sending);
        // Stop driving: host pulldown to SE0 unless there is a pullup on DP
        ctx->driving = set_driving(ctx, d2p, (d2p & D2P_PU) ? P2D_DP : 0);
        if (ctx->byte == sending->data_start) {
          ctx->bit = 1;
          ctx->state = ST_SYNC;
        } else {
          ctx->state = ST_IDLE;
        }
      }
      ctx->bit <<= 1;
      break;

    case ST_GET:
      // Device is driving the bus; nothing to do here
      break;

    default:
      assert(!"Unknown/invalid USBDPI drive state");
      break;
  }

  if ((ctx->loglevel & LOG_BIT) &&
      (force_stat || (ctx->driving != last_driving))) {
    usb_monitor_log(
        ctx->mon, "0x%-3x 0x-%8x              %s %s %s\n", ctx->frame,
        ctx->tick_bits, ctx->driving & P2D_SENSE ? "VBUS" : "    ",
        (ctx->state != ST_IDLE) ? decode_usb[(ctx->driving >> 1) & 3] : "ZZ ",
        (ctx->driving & P2D_D) ? "1" : "0");
  }
  return ctx->driving;
}

// Export some internal diagnostic state for visibility in waveforms
void usbdpi_diags(void *ctx_void, svBitVecVal *diags) {
  usbdpi_ctx_t *ctx = (usbdpi_ctx_t *)ctx_void;

  // Check for overflow, which would cause confusion in waveform interpretation;
  // if an assertion fires, the mapping from fields to svBitVecVal will need
  // to be changed, both here and in usbdpi.sv
  assert(ctx->state <= 0xfU);
  assert(ctx->hostSt <= 0x1fU);
  assert(ctx->bus_state <= 0x3fU);
  assert(ctx->step <= 0x7fU);

  diags[2] = usb_monitor_diags(ctx->mon);
  diags[1] =
      (ctx->step << 25) | (ctx->bus_state << 20) | (ctx->tick_bits >> 12);
  diags[0] = (ctx->tick_bits << 20) | ((ctx->frame & 0x7ffU) << 9) |
             ((ctx->hostSt & 0x1fU) << 4) | (ctx->state & 0xfU);
}

// Close the USBDPI model and release resources
void usbdpi_close(void *ctx_void) {
  usbdpi_ctx_t *ctx = (usbdpi_ctx_t *)ctx_void;
  if (!ctx) {
    return;
  }
  usb_monitor_fin(ctx->mon);
  free(ctx);
}
