//----------------------------------------------------------
// Maxim MAX1281 8-Channel ADC: XJEase device file
// Max1281.xje Revision: 1.14
// (c)2001-2007 XJTAG Limited
//
// Disclaimer: XJTAG makes no guarantees whatsoever
// about this code.  You use it at your own risk ...
// This code requires XJTAG version 1.4 or later.
//
// This file tests Non-JTAG ADC
//----------------------------------------------------------

DEVICE NAME := "MAX1281"
  PINS
    SDOUT := 14;
    SDIN  := 16;
    NCS   := 17;
    SSTRB := 14;
    SCLK  := 18;
    AIN   := 1, 2, 3, 4, 5, 6, 7, 8, 9;
    nSHDN := 10;
  END;

  DISABLE DEVICE
    NCS := 1;
  END;

  TEST COVERAGE
    SDOUT := OPEN HI LO;
    SDIN  := OPEN HI LO;
    NCS   := OPEN HI;
    SCLK  := OPEN HI LO;
  END;
END;

//---------------------------------------------
// Constants and globals
//---------------------------------------------

CONST INT DEBUG     := TRUE;
CONST INT VREF_MV   := 2500;

//---------------------------------------------
// Test
//    Value read is multiplied by 'factor' to
//    allow for external voltage dividers
//
//---------------------------------------------

Test(INT factor WIDTH 8)(INT result WIDTH 1)

  INT i     WIDTH 8;
  INT value WIDTH 12;

  PRINT("\tReading ADC values from ", DEVICE_REF, "...\n");
  FOR i := 0 TO 7
    ReadChannel(i, factor)(value);
  END;

  result := 0;
  PRINT("\n");

END;

//---------------------------------------------
//
// ReadChannel
//    Read a channel value
//
//---------------------------------------------

ReadChannel(INT channel WIDTH 3, INT factor WIDTH 8)(INT result WIDTH 12)

  INT data   WIDTH 8;
  INT value1 WIDTH 8;
  INT value2 WIDTH 8;
  INT mV     WIDTH 32;
  INT sel    WIDTH 3;

  sel[2] := channel[0];
  sel[1] := channel[2];
  sel[0] := channel[1];
  data[7..0] := 0x8f | (sel[2..0] << 4);  // Unipolar, Single-ended, normal operation

  // Dummy read to bring unit out of power-down
  SET NCS := 0;
  SPI_WriteSerial(data)();
  SPI_WriteSerial(0)();
  SPI_WriteSerial(0)();
  SET NCS := 1;

  // Now read the values
  SET NCS := 0;
  SPI_WriteSerial(data)();
  SPI_ReadSerial()(value1);
  SPI_ReadSerial()(value2);
  SET NCS := 1;

  result[11..0] := value1[5..0] : value2[7..2];

  mV := (factor * VREF_MV * result) / 4096;

  IF DEBUG THEN
    PRINT("\tChannel ", channel, " (0x", HEX(result), ") = ", mV, " mV\n");
  ELSE
    PRINT("\tChannel ", channel, " = ", mV, " mV\n");
  END;

END;

//---------------------------------------------
//
// SPI Serial IO
//
//---------------------------------------------

// Write to the SPI peripheral (N.B. MSB first).
SPI_WriteSerial(INT value WIDTH 8)()
  INT i WIDTH 32;
  FOR i := 1 FOR 8
    SET SDIN := value[8 - i];
    SET SCLK := 1;
    SET SCLK := 0;
  END;
END;

// Read bits from the SPI peripheral (N.B. MSB first).
SPI_ReadSerial()(INT value WIDTH 8)
  INT bit WIDTH 1;
  INT i WIDTH 32;
  value := 0;

  SET SDIN := 0;

  FOR i := 0 FOR 8
    SET SCLK := 1;
    SET SCLK := 0;
    SET bit := SDOUT;
    value := (value << 1) | bit;
  END;
END;