// Start TApi
gSystem->Load("libTApi.so");
TApi tapi;
tapi.initialiseAll()

// Variable definitions
unsigned int length;
unsigned int *body;

// Send echo prim list
unsigned long echoData[2] = {0xDEADF00D,0};
tapi.echo(0, 0, 0, 2, echoData);
tapi.awaitResponse(0, 0, 0);

// First read outlist
body = tapi.getResponse(0, 0, 0 ,&length);
tapi.status();

// Do slave echo test
tapi.createDebugPrimList();
const int ECHO = 0;
const int R_ECHO = 100;
tapi.addDebugPrimList(4 + 2, 1, ECHO, R_ECHO, echoData);
tapi.sendDebugSlavePrimList(0, 0, 0, 0, 1, 1);

// Send master prim list
tapi.sendDebugPrimList(0, 0, 0);

// Write to a buffer
tapi.createDebugPrimList();

char stringBuffer [] = "Hello world";
unsigned long writeData[] = {1, 0, 0, 0, 0, 0, 0 ,0};
for(int i=0; i<3; i++) {
        unsigned long word = 0;
        for(int j=0; j<4; j++) {
                word += stringBuffer[i*4+j] << (8*j);
        }

        writeData[i+1] = word;
}

const int WRITE_BUFFER = 15;
const int R_WRITE_BUFFER = 101;
tapi.addDebugPrimList(4 + 4, 1, WRITE_BUFFER, R_WRITE_BUFFER, writeData);
tapi.sendDebugPrimList(0, 0, 0);

tapi.awaitResponse(0, 0, 0);
body = tapi.getResponse(0, 0, 0, &length);

 tapi->flashLED(0, 0, 0, 0, 1000, 10); 

// Look at the info buffer
tapi.dspBlockRead(0, 0, 0, 0x02028000, 0x60, -1)
tapi.status()

// Check status
tapi.dspBlockRead(0, 0, 0, 0x80000000, 0x20, -1)

// Check Mdsp counter
tapi.dspSingleRead(0, 0, 0, 0x8000001c, -1)

// Clear the command register
tapi.dspSingleWrite(0, 0, 0, 0x8000000c, 0, -1)
tapi.status()

// Dma access request
tapi.dspSingleWrite(0, 0, 0, 0x8000000c, 0x400, -1);
tapi.dspSingleWrite(0, 0, 0, 0x8000000c, 0, -1)

// Flash led
unsigned long ledFlash[2] = {1000, 10};
tapi.createDebugPrimList();
tapi.addDebugPrimList(4 + 2, 1, 8, 102, ledFlash);
tapi.sendDebugSlavePrimList(0, 0, 0, 0, 1, 1);
tapi.awaitResponse(0, 0, 0);
body = tapi.getResponse(0, 0, 0, &length);

// Read slave memory        address                 numwords
unsigned long rwSlaveMem[5] = {0, 1, 0x80000000, 0xffffffff, 0x40};
tapi.createDebugPrimList();
tapi.addDebugPrimList(4 + 5, 1, 8192, 100, rwSlaveMem);
tapi.sendDebugPrimList(0, 0, 0);
tapi.awaitResponse(0, 0, 0);
body = tapi.getResponse(0, 0, 0, &length);

{
 for(int i=0; i<64; i++) {
  if(i && ((i%8) == 0)) printf("\n");
  printf("%08x ", body[8+i]);
 }
 printf("\n");
}

// Run calibration
calib_init();
tapi.setABCDModule(0, 0);
tapi.setABCDModule(0, 1);
tapi.sendABCDModule(0, 0);

{
 for(int s=0; s<4; s++) {
  // Rev C
//  clearSlaveMemory(s, 0x80008000, 8192);
  // Rev E
  clearSlaveMemory(s, 0x18000, 8192);
 }
}


// Clear histogram memory
clearSlaveMemory(0, 0xa00e2000, 0x1000*12*128);

// Error trapping
setupEvTrap(0, 0);    // Normal mode
startEvTrap(0);
setupEvTrap(1, 1);    // Error mode
startEvTrap(1);

//{
// for(int s=0; s<4; s++) {
//  histoSetup(s);
// }
//}
histoSetup(0); 
histoStart();
histoStatus(-1);
tapi.awaitResponse(0, 0, 0, 0);

stopEvTrap(0);

taskOp(16, 0, 0, -1);    // Stop histogram control task

taskOp(32, 0, 0, 0);     // Stop histogram task
histoSetup2(0);          // Start it again
histoStart2();

// Do reports (very verbose)
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x800000, -1);
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x0, -1);
// And "info display"
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x810000, -1);
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x0, -1);

// Do Doug's special register dump
tapi.dspSingleWrite(0, 0, 0, 0x80000010, (1<<29) + (1<<30), -1);

// Auto stall (stop on an error)
tapi.dspSingleWrite(0, 0, 0, 0x80000010, (1<<21), -1);

// Setup histogramming step
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x810040, -1);
// Do step
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x8100c0, -1); tapi.awaitResponse(0, 0, 0, 0);
// Turn off stepping
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x810080, -1); tapi.awaitResponse(0, 0, 0, 0);

// Without reports as well!
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x000040, -1);
{ for(int i=0; i<10; i++) { tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0xc0, -1); gSystem->Sleep(1); } }

// Setup histogram delay
tapi.dspSingleWrite(0, 0, 0, 0x80000030, 10*20, -1);
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x100, -1);

 histoStatus(0); histoStatus(1); histoStatus(2); histoStatus(3);
 // Stop histogramming
 stopEvTrap(0); stopEvTrap(1); stopEvTrap(2); stopEvTrap(3);
 taskOp(16, 0, 0, -1);    // Stop histogram control task
 taskOp(32, 0, 0, 0); taskOp(32, 0, 0, 1); taskOp(32, 0, 0, 2); taskOp(32, 0, 0, 3);

// Set delay stream 1
tapi.dspSingleWrite(0, 0, 0, 0x408804, 21, -1);
// Set laser current
tapi.dspSingleWrite(0, 0, 0, 0x408600, 0xa0, -1);

// Mute messages
tapi.dspSingleWrite(0, 0, 0, 0x80000010, 0x400, -1);

printSlave(0,0x20d2000, 0x2000); // Histogram buffer
printSlave(0,0x80008000, 0x2000);  // Event buffer

tapi.modifyABCDVar(0, 14, 1.0);     // Send mask bit
tapi.modifyABCDVar(0, 9, 64.0);     // NMask = 64

{
  for(int i=0; i<12; i++) {
    tapi.modifyABCDVar(0, i, 18, 1.0);
    tapi.modifyABCDVar(0, i, 1, 200.0);
    tapi.modifyABCDVar(0, i, 9, 128.0);
  }
}

{
  for(int i=0; i<9; i++) {
    tapi.modifyABCDVar(0, i, 18, 1.0);
    tapi.modifyABCDVar(0, i, 1, 200.0);
    tapi.modifyABCDVar(0, i, 9, 0.0);
    tapi.modifyABCDVar(0, i, 18, 0.0);
  }
}

{
  for(int i=0; i<10000; i++) {
    sendL1A();
  }
}


// Where the text buffers are
//                  info         buffer
// Text buffer 0 at 0x800052a8   0x02020000
// Text buffer 1 at 0x800052d0   0x02028000
// Text buffer 2 at 0x800052f8   0x02030000
// Text buffer 3 at 0x80005320   0x02038000

unsigned long triggerStream[] = {0x700066, 0x640065, 0x640064, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0, 1, 63, 0x0, 0x0, 0x0, 0x1, 2};

unsigned long l1aStream[] = {0x650064, 0x640064, 0x640064, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0, 1, 63, 0x0, 0x0, 0x0, 0x1, 2};

tapi.createDebugPrimList();
tapi.addDebugPrimList(4 + 17, 2, 8202, 101, l1aStream);
l1aStream[0] = 2;
l1aStream[1] = 0;
tapi.addDebugPrimList(4 + 2, 3, 8203, 100, l1aStream);
tapi.sendDebugPrimList(0, 0, 0);
tapi.awaitResponse(0, 0, 0);


// Read event buffer
printSlave(0, 0x80008000, 0x8000/4);


// Print module configuration
unsigned long *config = tapi.retrieveModule(0);
{
 for(int i=0; i<542; i++) {
  printf("%08x ", config[i]);
 }
 printf("\n");
}

// Find UID for module
#include <string>
string sn("20220170100001");
tapi.findModule(sn)

// Read reply buffer from Master DSP
tapi.dspBlockRead(0, 0, 0, 0x02082000, 0x60, -1)


// Sync init all slaves
unsigned long dspReset[4] = {8, 1, 10, 0xc3500};
tapi.createDebugPrimList();
tapi.addDebugPrimList(4 + 4, 1, 8206, 100, dspReset);
tapi.sendDebugPrimList(0, 0, 0);
tapi.awaitResponse(0, 0, 0);

// Possibly byte swapped?
unsigned long emifData[4] = {0x3f33ffff, 0x3f33ffff, 0xc0000744, 0xa4000001};

// Change static L1ID
writeRegister(0x229, 0x0, 24, 0x1);   // Serial port 0
writeRegister(0x22a, 0x0, 24, 0x1);   // Serial port 1

// Set raw mode on formatter 0
{
  for(int i=0; i<8; i++) {
    writeRegister(0x60+12*i, 2, 1, 1);
  }
}

// Read histogram
{
  ofstream histoout("histogram.bin", ios::binary);
  int bins = 7;

  for(int i=0; i<bins; i++) {
    long *chunk = readSlave(0, 0x20d2000+0x800*4*i, 0x800);
    histoout.write((char*)&chunk[0], 0x800*4);
  }
}

 // Clear output mask
 writeRegister(0x1c7, 20, 1, 1);
 writeRegister(0x1ca, 0, 32, 0);
 writeRegister(0x1cb, 0, 16, 0);
 writeRegister(0x1cc, 0, 32, 0);
 writeRegister(0x1cd, 0, 16, 0);
 writeRegister(0x1c7, 2, 1, 1);

 writeRegister(0x1c7, 20, 1, 1);
 writeRegister(0x1ca, 0, 32, 0x20);
 writeRegister(0x1cb, 0, 16, 0);
 writeRegister(0x1cc, 0, 32, 0);
 writeRegister(0x1cd, 0, 16, 0);
 writeRegister(0x1c7, 2, 1, 1);

 // Router dist
 setupEvTrap(0,2); setupEvTrap(1,2); setupEvTrap(2,2); setupEvTrap(3,2);
 // DSP dist
 setupEvTrap(0,3); setupEvTrap(1,3); setupEvTrap(2,3); setupEvTrap(3,3);

 setupEvTrap(0); setupEvTrap(1); setupEvTrap(2); setupEvTrap(3);
 startEvTrap(0); startEvTrap(1); startEvTrap(2); startEvTrap(3);
 histoStatus(0); histoStatus(1); histoStatus(2); histoStatus(3);

 stopEvTrap(0); stopEvTrap(1); stopEvTrap(2); stopEvTrap(3);


writeSlaveFile(0, "/usera/sctrod/SlaveImages/test-pxl/sdsp6713_IPRAM.bin", 0, 16384)
writeSlaveFile(0, "/usera/sctrod/SlaveImages/test-pxl/sdsp6713_IDRAM.bin", 0x10000, 16384)
writeSlaveFile(0, "/usera/sctrod/SlaveImages/test-pxl/sdsp6713_xcode.bin", 0xa0000000, 65536)

readSlaveFile(0, 0xa0000000, 65536, "dumpExt.bin")
readSlaveFile(0, 0x10000, 16384, "dumpIDRAM.bin")
readSlaveFile(0, 0x0, 16384, "dumpIPRAM.bin")


// Read text buffer (whichever comes first...)
char *buffer = new char[10000]
unsigned long length
tapi.getRodMessage(0, 0, 0, buffer, length)
printf(buffer)

// Turn off l1 and bcid checks
for(int i=0; i<48; i++) { writeRegister(0x140 + i, 5, 2, 3); writeRegister(0x170 + i, 5, 2, 3);}

// Try setting  H/T and Rod Busy limits
for(int i=0; i<8; i++) { writeRegister(0x30 + i, 0, 10, 0x3ff); writeRegister(0x38 + i, 0, 10, 0x3ff); }

// Put all modules in send all mask mode
tapi.modifyABCDVar(11, 1.0);
tapi.modifyABCDVar(13, 0.0);
tapi.modifyABCDVar(14, 1.0);   
tapi.modifyABCDVar(9, 0.0);
tapi.setABCDModules(0);
tapi.sendABCDModules(0);

// Put all modules in clk/2 mode
tapi.modifyABCDVar(16, 0.0);
tapi.setABCDModules(0);
tapi.sendABCDModules(0);

// Take all modules out of clk/2 mode
tapi.modifyABCDVar(16, 1.0);
tapi.setABCDModules(0);
tapi.sendABCDModules(0);

// Manually send TIM FER
tapi.timRegLoad(0, 0, 2, 0x20); tapi.timRegLoad(0, 0, 2, 0x0);
// Manually send TIM BCR
tapi.timRegLoad(0, 0, 2, 0x08); tapi.timRegLoad(0, 0, 2, 0x0);
// Manually send TIM ECR
tapi.timRegLoad(0, 0, 2, 0x04); tapi.timRegLoad(0, 0, 2, 0x0);
