// File: AD5940_Platform.c
#include "App_Common.h"
#include "rp2040port.h"

// --- Platform Interface Implementation ---
// NOTE: Low-level hardware interface functions are now in rp2040port.c

int32_t AD5940PlatformCfg(void) {
  CLKCfg_Type clk_cfg;
  FIFOCfg_Type fifo_cfg;
  AGPIOCfg_Type gpio_cfg;

  clk_cfg.ADCClkDiv = ADCCLKDIV_1;
  clk_cfg.ADCCLkSrc = ADCCLKSRC_HFOSC;
  clk_cfg.SysClkDiv = SYSCLKDIV_1;
  clk_cfg.SysClkSrc = SYSCLKSRC_HFOSC;
  clk_cfg.HfOSC32MHzMode = bFALSE;
  clk_cfg.HFOSCEn = bTRUE;
  clk_cfg.HFXTALEn = bFALSE;
  clk_cfg.LFOSCEn = bTRUE;
  AD5940_CLKCfg(&clk_cfg);

  fifo_cfg.FIFOEn = bFALSE;
  fifo_cfg.FIFOMode = FIFOMODE_FIFO;
  fifo_cfg.FIFOSize = FIFOSIZE_4KB;
  fifo_cfg.FIFOSrc = FIFOSRC_DFT;
  fifo_cfg.FIFOThresh = 6;
  AD5940_FIFOCfg(&fifo_cfg);
  fifo_cfg.FIFOEn = bTRUE;
  AD5940_FIFOCfg(&fifo_cfg);

  AD5940_INTCCfg(AFEINTC_1, AFEINTSRC_ALLINT, bTRUE);
  AD5940_INTCClrFlag(AFEINTSRC_ALLINT);
  AD5940_INTCCfg(AFEINTC_0, AFEINTSRC_DATAFIFOTHRESH | AFEINTSRC_CUSTOMINT0,
                 bTRUE);
  AD5940_INTCClrFlag(AFEINTSRC_ALLINT);

  gpio_cfg.FuncSet = GP0_INT;
  gpio_cfg.InputEnSet = 0;
  gpio_cfg.OutputEnSet = AGPIO_Pin0;
  gpio_cfg.OutVal = 0;
  gpio_cfg.PullEnSet = 0;
  AD5940_AGPIOCfg(&gpio_cfg);

  AD5940_SleepKeyCtrlS(SLPKEY_UNLOCK);
  return 0;
}

void SystemReset(void) {
  sleep_ms(100);
  AD5940_SoftRst();
  sleep_ms(1);
  AD5940_Initialize();
  AD5940PlatformCfg();
}

// --- Helpers ---
uint32_t GetHSTIARtia(uint32_t val) {
  switch (val) {
  case 100:
    return HSTIARTIA_200; // Map 100 request to 200 Internal
  case 200:
    return HSTIARTIA_200;
  case 1000:
    return HSTIARTIA_1K;
  case 5000:
    return HSTIARTIA_5K;
  case 10000:
    return HSTIARTIA_10K;
  case 20000:
    return HSTIARTIA_20K;
  case 40000:
    return HSTIARTIA_40K;
  case 80000:
    return HSTIARTIA_80K;
  case 160000:
    return HSTIARTIA_160K;
  default:
    return HSTIARTIA_1K;
  }
}

uint32_t GetLPTIARtia(uint32_t val) {
  switch (val) {
  case 200:
    return LPTIARTIA_200R;
  case 1000:
    return LPTIARTIA_1K;
  case 2000:
    return LPTIARTIA_2K;
  case 3000:
    return LPTIARTIA_3K;
  case 4000:
    return LPTIARTIA_4K;
  case 6000:
    return LPTIARTIA_6K;
  case 8000:
    return LPTIARTIA_8K;
  case 10000:
    return LPTIARTIA_10K;
  case 12000:
    return LPTIARTIA_12K;
  case 16000:
    return LPTIARTIA_16K;
  case 20000:
    return LPTIARTIA_20K;
  case 24000:
    return LPTIARTIA_24K;
  case 30000:
    return LPTIARTIA_30K;
  case 32000:
    return LPTIARTIA_32K;
  case 40000:
    return LPTIARTIA_40K;
  case 48000:
    return LPTIARTIA_48K;
  case 64000:
    return LPTIARTIA_64K;
  case 85000:
    return LPTIARTIA_85K;
  case 96000:
    return LPTIARTIA_96K;
  case 100000:
    return LPTIARTIA_100K;
  case 120000:
    return LPTIARTIA_120K;
  case 128000:
    return LPTIARTIA_128K;
  case 160000:
    return LPTIARTIA_160K;
  case 196000:
    return LPTIARTIA_196K;
  case 256000:
    return LPTIARTIA_256K;
  case 512000:
    return LPTIARTIA_512K;
  default:
    return LPTIARTIA_1K;
  }
}

uint32_t GetLPTIARload(uint32_t val) {
  if (val <= 200)
    return LPTIARLOAD_10R;
  return LPTIARLOAD_100R;
}

void AmperometricShowResult(float *pData, uint32_t DataCount) {
  for (int i = 0; i < DataCount; i++) {
    printf("AMP,%d,%.4f\n", g_AmpIndex++, pData[i]);
  }
}

void RampShowResult(float *pData, uint32_t DataCount) {
  for (int i = 0; i < DataCount; i++) {
    printf("RAMP,%d,%.4f\n", g_RampIndex++, pData[i]);
  }
}