#include <stdio.h>
 
#include <vector>
 
#include "VmUsbStack.h"
 
 
 
VmUsbStack::VmUsbStack(){
 
        fStack.push_back(0x1);
 
        fStack.push_back(0x0);
 
}
 
 
 
VmUsbStack::~VmUsbStack(){
 
        fStack.clear();
 
}
 
 
 
int VmUsbStack::Get(int maxn, int *stack){
 
  for (int i=0;i<fStack.size();i++){
 
                        if (i<maxn) stack[i]=fStack[i]; else return -1;
 
  }
 
  return fStack[0];
 
}
 
 
 
 
 
void VmUsbStack::Append(int cmd, int addr ){
 
  fStack.push_back(cmd & 0xFFFF);
 
  fStack.push_back(cmd >> 16);
 
  fStack.push_back(addr&0xFFFF);
 
  fStack.push_back((addr >> 16)& 0xFFFF);
 
  fStack[0]=fStack.size()-1;
 
}
 
 
 
void VmUsbStack::Append(int cmd, int addr , int data){
 
  Append( cmd, addr );
 
  fStack.push_back(data&0xFFFF);
 
  fStack.push_back((data >> 16)&0xFFFF);
 
  fStack[0] = fStack.size()-1;
 
}
 
 
 
void VmUsbStack::ReadA24D16(int addr ){
 
        Append(CMD_READ | CMD_A24 , CMD_D16 | addr);
 
}
 
 
 
void VmUsbStack::WriteA24D16(int addr, int data){
 
  return Append(CMD_WRITE | CMD_A24,CMD_D16 | addr, data);
 
}
 
 
 
void VmUsbStack::ReadA24D32(int addr ){
 
        Append(CMD_READ | CMD_A24 , CMD_D32 | addr);
 
}
 
 
 
void VmUsbStack::WriteA24D32(int addr, int data){
 
  return Append(CMD_WRITE | CMD_A24 , CMD_D32 | addr, data);
 
}
 
 
 
void VmUsbStack::ReadA32D16(int addr ){
 
        Append(CMD_READ | CMD_A32 , CMD_D16| addr);
 
}
 
 
 
void VmUsbStack::WriteA32D16(int addr, int data){
 
  return Append(CMD_WRITE | CMD_A32 , CMD_D16 | addr, data);
 
}
 
 
 
void VmUsbStack::ReadA32D32(int addr ){
 
        Append(CMD_READ | CMD_A32 , CMD_D32 | addr);
 
}
 
 
 
void VmUsbStack::WriteA32D32(int addr, int data){
 
  return Append(CMD_WRITE | CMD_A32 , CMD_D32| addr, data);
 
}
 
 
 
 
 
void VmUsbStack::Marker(int marker){
 
  return Append(CMD_MRK, marker);
 
}
 
 
 
void VmUsbStack::ConditionalRead(int adr_mod,int d16d32, int addr, int bmask){
 
        Append(CMD_READ| CMD_HD | adr_mod ,addr);
 
        Append(CMD_READ| CMD_HD | CMD_HM |adr_mod, d16d32 |addr,bmask);
 
}
 
 
 
void VmUsbStack::RepeatRead(int adr_mod,int d16d32, int baseaddr, int n, int increment){
 
        for (int i=0;i<n;i++) Append( adr_mod | CMD_READ, d16d32 +baseaddr + i*increment);
 
}
 
void VmUsbStack::RepeatWrite(int adr_mod,int d16d32,int baseaddr, int n, int increment, int data){
 
        for (int i=0;i<n;i++)  Append( adr_mod | CMD_WRITE,d16d32 + baseaddr+i*increment, data);
 
}
 
 
 
void VmUsbStack::Print(){
 
        for (int i
=0; i 
< fStack.
size();i
++) printf("0x%04x\n",fStack
[i
]);  
   printf("%d %d __________________________________\n",fStack.
size(),fStack
[0]);  
}
 
 
 
#ifdef MAIN
 
#include "CAENV965_DEF.h"
 
#define CAEN_V965    0x340000
 
 
 
int main(){
 
// INIT stackdata
 
int geo=1,fPedestal=255;
 
VmUsbStack *init=new VmUsbStack();
 
init->Write(CAEN_V965 + CAENV965_CRN, 0x0);
 
init->Write(CAEN_V965 + CAENV965_GEO, geo);
 
init->RepeatWrite( CAEN_V965 + CAENV965_THM, 32, 0x02,0x0); // threshold/kill for 32 channels, 2*i addr increment
 
init->Write( CAEN_V965 + CAENV965_BS1, 0x80 ); // soft reset
 
init->Write( CAEN_V965 + CAENV965_BC1, 0x80 ); // soft reset
 
init->Write( CAEN_V965 + CAENV965_PED, fPedestal ); // pedestal
 
init->Write(CAEN_V965 + CAENV965_BS2,0x5000); 
 
init->Write(CAEN_V965 + CAENV965_BS2,0x4);  // clear module
 
init->Write(CAEN_V965 + CAENV965_BC2,0x4);
 
init->Print(); 
 
 
 
// READOUT stackdata
 
VmUsbStack *stack=new VmUsbStack();
 
stack->Write(CAEN_V965 + CAENV965_BS2,0x4);  // clear module
 
stack->Write(CAEN_V965 + CAENV965_BC2,0x4);  
 
stack->ConditionalRead(CAEN_V965 + CAENV965_SR1,0x1);        // TRG wait : loop until bit 0 is on
 
stack->ConditionalRead(CAEN_V965 + CAENV965_OB ,0x4000000) ; // loop until bit 26 is on, read data 
 
stack->Marker(0xFAFB); 
 
stack->Print();
 
 
 
 int st[1000];
 
 int nb= stack->Get(1000,st);
 
 for (int i
=0;i
<nb
;i
++) if (st
[i
]!=stack
->fStack
[i
]) printf("error i=%d 0x%04x 0x%04x \n",i
,st
[i
],stack
->fStack
[i
] );  
 return 0;
 
}
 
#endif