/* --------------------------------------------------------------
Compact Flash device file: XJEase device file
CF_CARD.xje Revision: 1.15
(c)2003-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 Memory Card using Test()(INT result)
--------------------------------------------------------------- */
DEVICE NAME := "Compact Flash Card"
  COMPAT_VERSION := 1;
  DESCRIPTION := "";

  PINS
    ADDR := 8, 10, 11,
            12, 14, 15, 16, 17, 18, 19, 20;
    DATA := 31, 30, 29, 28, 27, 49, 48, 47,
            6, 5, 4, 3, 2, 23, 22, 21;
    BVD1 := 46;
    NSTSCHG := 46;
    NPDIAG := 46;
    BVD2 := 45;
    NSPKR := 45;
    NDASP := 45;
    NCD1 := 26;
    NCD2 := 25;
    NCE1 := 7;
    NCE2 := 32;
    NCSEL := 39;
    NINPACK := 43;
    NIORD := 34;
    NIOWR := 35;
    NOE := 9;
    NATASEL := 9;
    READY := 37;
    NIREQ := 37;
    INTRQ := 37;
    NREG := 44;
    RESET := 41;
    NRESET := 41;
    NVS1 := 33;
    NVS2 := 40;
    NWAIT := 42;
    IORDY := 42;
    NWE := 36;
    WP := 24;
    NIOIS16 := 24;
    NIOCS16 := 24;
  END;

  DISABLE DEVICE
    NCE1 := 1;
    NCE2 := 1;
  END;

  TEST COVERAGE
    ADDR := OPEN SHORTS LO HI;
    DATA := OPEN SHORTS LO HI;
    NCD1 := OPEN LO HI;
    NCD2 := OPEN LO HI;
    NCE1 := OPEN LO HI;
    NCE2 := OPEN LO HI;
    NIORD := OPEN LO HI;
    NIOWR := OPEN LO HI;
    NOE := OPEN LO HI;
    NWAIT := OPEN LO HI;
    NWE := OPEN LO HI;
  END;
END;

//------------------------------------------
// Constants
//------------------------------------------

CONST INT RESULT_PASS := FALSE;
CONST INT RESULT_FAIL := TRUE;

//------------------------------------------
// Test
//------------------------------------------

Test()(INT result)

  INT address;
  INT i;
  INT data;
  INT cardPresent;
  INT errorCount := 0;

  PRINT("Testing compact flash (", DEVICE_REF, ") ...\n");

  IsPresent()(cardPresent);
  IF (cardPresent) THEN
    PRINT("\tRemove CF card.\n");
    DO
      IsPresent()(cardPresent);
    WHILE (cardPresent) && (GETKEY() = 0)
    END;

    IF (cardPresent) THEN
      PRINT("\tCard removal not detected.\n");
      result := RESULT_FAIL;
      RETURN;
    END;
    PRINT("\tCard not present.\n");
  END;

  PRINT("\tInsert CF card.\n");
  DO
    IsPresent()(cardPresent);
  WHILE (!cardPresent) && (GETKEY() = 0)
  END;

  IF (!cardPresent) THEN
    PRINT("\tCard not detected.\n");
    result := RESULT_FAIL;
    RETURN;
  END;
  PRINT("\tCard detected.\n");

  DecodeAttributes()(result); IF result != RESULT_PASS THEN errorCount := errorCount + 1; END;

  IF errorCount = 0 THEN
    result := RESULT_PASS;
  ELSE
    result := RESULT_FAIL;
  END;
END;

//------------------------------------------
// Decode card attribute registers
//------------------------------------------

DecodeAttributes()(INT result)

  INT data WIDTH 8;

  result := 0;

  PRINT("\tConfiguration Options:\n");
  ReadAttribute(0)(data);
  IF data[5..0] = 0 THEN
    PRINT("\t\tMemory mapped\n");
  ELSIF data[5..0] = 1 THEN
    PRINT("\t\tIO Mapped at any 16-byte boundary\n");
  ELSIF data[5..0] = 2 THEN
    PRINT("\t\tIO Mapped at 0x1f0-0x1f7 / 0x3f6-0x3f7\n");
  ELSIF data[5..0] = 3 THEN
    PRINT("\t\tIO Mapped at 0x170-0x177 / 0x376-0x377\n");
  ELSE
    PRINT("\t\tInvalid config in register 0\n");
    result := result + 1;
  END;

  IF data[6] = 0 THEN
    PRINT("\t\tEdge mode interrupt\n");
  ELSE
    PRINT("\t\tLevel mode interrupt\n");
  END;
  IF data[7] = 0 THEN
    PRINT("\t\tSoft reset inactive\n");
  ELSE
    PRINT("\t\tSoft reset active\n");
  END;

  PRINT("\tConfig and Status:\n");
  ReadAttribute(2)(data);
  IF data[2] = 0 THEN
    PRINT("\t\tPowerdown inactive\n");
  ELSE
    PRINT("\t\tPowerdown active\n");
  END;
  IF data[3] = 0 THEN
    PRINT("\t\tAudio disabled\n");
  ELSE
    PRINT("\t\tAudio enabled\n");
  END;
  IF data[4] = 0 THEN
    PRINT("\t\tPower level 1 commands enabled\n");
  ELSE
    PRINT("\t\tPower level 1 commands disabled\n");
  END;
  IF data[5] = 0 THEN
    PRINT("\t\t16-bit IO\n");
  ELSE
    PRINT("\t\t8-bit IO\n");
  END;

END;

//------------------------------------------
// Detect Card Presence
//------------------------------------------

IsPresent()(INT present)
  INT CardDetect WIDTH 2;
  INT count, testable, tested;
  
  tested := FALSE;
  
  FOR count := 1 FOR 2
    IF count = 1 THEN
      IF READABLE(NCD1) THEN
        SET CardDetect:=NCD1;
        testable := TRUE;
      ELSE
        testable := FALSE;
      END;
    ELSE
      IF READABLE(NCD2) THEN
        SET CardDetect := NCD2;
        testable := TRUE;
      ELSE
        testable := FALSE;
      END;
    END;
    IF testable THEN
      IF (CardDetect = 0) THEN
        IF tested = FALSE THEN
          present := TRUE;
        END;
      ELSE
        present := FALSE;
      END;
      tested  := TRUE;
    END;
  END;
  IF tested = FALSE THEN
    PRINT("Unable to check for card presence as nCD there is no access to nCD signals.\n");
    present := TRUE;
  END;
END;

//------------------------------------------
// Read Attribute Memory
//------------------------------------------

ReadAttribute(INT address)(INT data)
  SET ADDR:=address[10..0], NREG:=0, NCE1:=0, NCE2:=0, NOE:=0, NWE:=1, NIORD:=1, NIOWR:=1;
  SET DATA:=I, data:=DATA, NCE1:=1, NCE2:=1, NOE:=1;
  data := data & 0xff;
END;

//------------------------------------------
// Write Attribute Memory
//------------------------------------------

WriteAttribute(INT address)(INT data)
  SET ADDR:=address[10..0], NREG:=0, NCE1:=0, NCE2:=1, NOE:=1, NWE:=0, DATA:=data[15..0], NIORD:=1, NIOWR:=1;
  SET NCE1:=1, NCE2:=1, NOE:=1, NWE:=1;
END;

//------------------------------------------
// Read Common Memory
//------------------------------------------

ReadCommon(INT address)(INT data)
  INT nwait;
  SET ADDR:=address[10..0], NREG:=1, NCE1:=0, NCE2:=0, NOE:=0, NWE:=1, NIORD:=1, NIOWR:=1;
  DO
    SET nwait:=NWAIT;
  WHILE nwait=0
  END;
  SET DATA:=I, data:=DATA, NCE1:=1, NCE2:=1, NOE:=1;
END;

//------------------------------------------
// Write Common Memory
//------------------------------------------

WriteCommon(INT address)(INT data)
  INT nwait;
  SET ADDR:=address[10..0], NREG:=1, NCE1:=0, NCE2:=0, NOE:=1, NWE:=0, DATA:=data[15..0], NIORD:=1, NIOWR:=1;
  DO
    SET nwait:=NWAIT;
  WHILE nwait=0
  END;
  SET NCE1:=1, NCE2:=1, NOE:=1, NWE:=1;
END;

//------------------------------------------
// Read IO
//------------------------------------------

ReadIO(INT address)(INT data)
  INT nwait;
  SET ADDR:=address[10..0], NREG:=0, NCE1:=0, NCE2:=0, NOE:=1, NWE:=1, NIORD:=0, NIOWR:=1;
  DO
    SET nwait:=NWAIT;
  WHILE nwait=0
  END;
  SET DATA:=I, data:=DATA, NCE1:=1, NCE2:=1, NIORD:=1, NIOWR:=1;
END;

//------------------------------------------
// Write IO
//------------------------------------------

WriteIO(INT address)(INT data)
  INT nwait;
  SET ADDR:=address[10..0], NREG:=0, NCE1:=0, NCE2:=0, NOE:=1, NWE:=1, DATA:=data[15..0], NIORD:=1, NIOWR:=0;
  DO
    SET nwait:=NWAIT;
  WHILE nwait = 0
  END;
  SET NCE1:=1, NCE2:=1, NIORD:=1, NIOWR:=1;
END;