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

#ifdef __linux__
#include <pty.h>
#elif __APPLE__
#include <util.h>
#endif

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

#include "spidpi.h"
#include "verilator_sim_ctrl.h"

// Enable this define to stop tracing at cycle 4
// and resume at the first SPI packet
// #define CONTROL_TRACE

extern VerilatorSimCtrl *simctrl;

static void finish(void) {
  if (!simctrl) {
    return;
  }
  simctrl->RequestStop(true);
}

#ifdef CONTROL_TRACE
static void trace(int enable) {
  if (!simctrl) {
    return;
  }
  if (enable) {
    simctrl->TraceOn();
  } else {
    simctrl->TraceOff();
  }
}
#endif

void *spidpi_create(const char *name, int mode, int loglevel) {
  int i;
  struct spidpi_ctx *ctx =
      (struct spidpi_ctx *)calloc(1, sizeof(struct spidpi_ctx));
  assert(ctx);

  ctx->loglevel = loglevel;
  ctx->mon = monitor_spi_init(mode);
  ctx->tick = 0;
  ctx->msbfirst = 1;
  ctx->nmax = MAX_TRANSACTION;
  ctx->nin = 0;
  ctx->nout = 0;
  ctx->bout = 0;
  ctx->state = SP_IDLE;
  /* mode is CPOL << 1 | CPHA
   * cpol = 0 --> external clock matches internal
   * cpha = 0 --> drive on internal falling edge, capture on rising
   */
  ctx->cpol = ((mode == 0) || (mode == 2)) ? 0 : 1;
  ctx->cpha = ((mode == 1) || (mode == 3)) ? 1 : 0;
  /* CPOL = 1 for clock idle high */
  ctx->driving = P2D_CSB | ((ctx->cpol) ? P2D_SCK : 0);
  char cwd[PATH_MAX];
  char *cwd_rv;
  cwd_rv = getcwd(cwd, sizeof(cwd));
  assert(cwd_rv != NULL);

  int rv;
  struct termios tty;
  cfmakeraw(&tty);

  rv = openpty(&ctx->master, &ctx->slave, 0, &tty, 0);
  assert(rv != -1);

  rv = ttyname_r(ctx->slave, ctx->ptyname, 64);
  assert(rv == 0 && "ttyname_r failed");

  int cur_flags = fcntl(ctx->master, F_GETFL, 0);
  assert(cur_flags != -1 && "Unable to read current flags.");
  int new_flags = fcntl(ctx->master, F_SETFL, cur_flags | O_NONBLOCK);
  assert(new_flags != -1 && "Unable to set FD flags");

  printf(
      "\n"
      "SPI: Created %s for %s. Connect to it with any terminal program, e.g.\n"
      "$ screen %s\n"
      "NOTE: a SPI transaction is run for every 4 characters entered.\n",
      ctx->ptyname, name, ctx->ptyname);

  rv = snprintf(ctx->mon_pathname, PATH_MAX, "%s/%s.log", cwd, name);
  assert(rv <= PATH_MAX && rv > 0);
  ctx->mon_file = fopen(ctx->mon_pathname, "w");
  if (ctx->mon_file == NULL) {
    fprintf(stderr, "SPI: Unable to open file at %s: %s\n", ctx->mon_pathname,
            strerror(errno));
    return NULL;
  }
  // more useful for tail -f
  setlinebuf(ctx->mon_file);
  printf(
      "SPI: Monitor output file created at %s. Works well with tail:\n"
      "$ tail -f %s\n",
      ctx->mon_pathname, ctx->mon_pathname);

  return (void *)ctx;
}

char spidpi_tick(void *ctx_void, const svLogicVecVal *d2p_data) {
  struct spidpi_ctx *ctx = (struct spidpi_ctx *)ctx_void;
  assert(ctx);
  int d2p = d2p_data->aval;

  // Will tick at the master clock
  ctx->tick++;

#ifdef CONTROL_TRACE
  if (ctx->tick == 4) {
    trace(0);
  }
#endif

  monitor_spi(ctx->mon, ctx->mon_file, ctx->loglevel, ctx->tick, ctx->driving,
              d2p);

  if (ctx->state == SP_IDLE) {
    int n = read(ctx->master, &(ctx->buf[ctx->nin]), ctx->nmax - ctx->nin);
    if (n == -1) {
      if (errno != EAGAIN) {
        fprintf(stderr, "Read on SPI FIFO gave %s\n", strerror(errno));
      }
    } else {
      ctx->nin += n;
      if (ctx->nin == ctx->nmax) {
        ctx->nout = 0;
        ctx->nin = 0;
        ctx->bout = ctx->msbfirst ? 0x80 : 0x01;
        ctx->bin = ctx->msbfirst ? 0x80 : 0x01;
        ctx->din = 0;
        ctx->state = SP_CSFALL;
#ifdef CONTROL_TRACE
        trace(1);
#endif
      }
    }
  }
  // SPI clock toggles every 4th tick (i.e. freq=master/8)
  if ((ctx->tick & 3) || (ctx->state == SP_IDLE)) {
    return ctx->driving;
  }

  // Only get here on sck edges when active
  int internal_sck = (ctx->tick & 4) ? 1 : 0;
  int set_sck = (internal_sck ? P2D_SCK : 0);
  if (ctx->cpol) {
    set_sck ^= P2D_SCK;
  }

  if (internal_sck == ctx->cpha) {
    // master driving edge (falling for mode 0)
    switch (ctx->state) {
      case SP_DMOVE:
        // SCLK low, CSB low
        ctx->driving =
            set_sck | (ctx->buf[ctx->nout] & ctx->bout) ? P2D_MOSI : 0;
        ctx->bout = (ctx->msbfirst) ? ctx->bout >> 1 : ctx->bout << 1;
        if ((ctx->bout & 0xff) == 0) {
          ctx->bout = ctx->msbfirst ? 0x80 : 0x01;
          ctx->nout++;
          if (ctx->nout == ctx->nmax) {
            ctx->state = SP_LASTBIT;
          }
        }
        break;
      case SP_LASTBIT:
        ctx->state = SP_CSRISE;
        // fallthrough
      default:
        ctx->driving = set_sck | (ctx->driving & ~P2D_SCK);
        break;
    }
  } else {
    // master other edge (rising for mode 0)
    switch (ctx->state) {
        // Read input data (opposite edge to sending)
        // both DMOVE and LASTBIT states are data moving ones!
      case SP_DMOVE:
      case SP_LASTBIT:
        ctx->din = ctx->din | ((d2p & D2P_MISO) ? ctx->bin : 0);
        ctx->bin = (ctx->msbfirst) ? ctx->bin >> 1 : ctx->bin << 1;
        if (ctx->bin == 0) {
          int rv = write(ctx->master, &(ctx->din), 1);
          assert(rv == 1 && "write() failed.");
          ctx->bin = (ctx->msbfirst) ? 0x80 : 0x01;
          ctx->din = 0;
        }
        ctx->driving = set_sck | (ctx->driving & ~P2D_SCK);
        break;
      case SP_CSFALL:
        // CSB low, drive MOSI to first bit
        ctx->driving =
            (set_sck | (ctx->buf[ctx->nout] & ctx->bout) ? P2D_MOSI : 0);
        ctx->state = SP_DMOVE;
        break;
      case SP_CSRISE:
        // CSB high, clock stopped
        ctx->driving = P2D_CSB;
        ctx->state = SP_IDLE;
        break;
      case SP_FINISH:
        finish();
        break;
      default:
        ctx->driving = set_sck | (ctx->driving & ~P2D_SCK);
        break;
    }
  }
  return ctx->driving;
}

void spidpi_close(void *ctx_void) {
  struct spidpi_ctx *ctx = (struct spidpi_ctx *)ctx_void;
  if (!ctx) {
    return;
  }
  fclose(ctx->mon_file);
  free(ctx);
}
