Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

//-------------------------------------------------------------------------
// WINNT driver for PCICC32 interface from ARW Elektronik, Germany --------
// all around recognition and basic services of VMEMM
//
// (c) 2000-2002 ARW Elektronik
//
// this source code is published under GPL (Open Source). You can use, redistrubute and
// modify it unless this header   is not modified or deleted. No warranty is given that
// this software will work like expected.
// This product is not authorized for use as critical component in life support systems
// wihout the express written approval of ARW Elektronik Germany.
//
// Please announce changes and hints to ARW Elektronik
//
// what                                            who          when
// started from pcivme_v.c                         AR           02.07.2000
// changed making procedure (only VCC > 6.0)       AR           30.05.2002
//

//-------------------------------------------------------------------------
// INCLUDES
//
#include <ntddk.h>
#include <pcicc32_drv.h>
#include <pcicc32_v.h>
#include <pcicc32_local.h>  // all around the pciada interface

#ifndef WORD                            // don't touch include files of WIN95 driver
#define WORD USHORT
#endif

#ifndef DWORD
#define DWORD ULONG
#endif

//------------------------------------------------------------------------
// PROTOTYPES
//

//------------------------------------------------------------------------
// GLOBALS
//

//------------------------------------------------------------------------
// FUNCTIONS
//

//------------------------------------------------------------------------
// test connection to VMEMM devices without disturbing anything
//
//---------------------------------------------------------------------
// checks a connection with a small test pattern
//
NTSTATUS TestConnection(PCIADA *pciada)
{
        USHORT *pwADRH = (USHORT *)_WORD_NAF(pciada->pvVirtIfr, 30, 1, 0);
        USHORT *pwADRL = (USHORT *)_WORD_NAF(pciada->pvVirtIfr, 30, 0, 0);
        int i;
        USHORT wRet;
    USHORT wADRHContent;
    USHORT wADRLContent;

       
        KdPrint(("TestConnection()\n"));
       
        wADRHContent = READ_REGISTER_USHORT(pwADRH);    // save previous content
        wADRLContent = READ_REGISTER_USHORT(pwADRL);

        for (i = 0; i < 10000; i++)
        {
                WRITE_REGISTER_USHORT(pwADRH, 0x5555);
                WRITE_REGISTER_USHORT(pwADRL, 0xAAAA);
                wRet = READ_REGISTER_USHORT(pwADRH);
                if (wRet != 0x5555) return STATUS_UNSUCCESSFUL;
   
                WRITE_REGISTER_USHORT(pwADRH, 0xAAAA);
                WRITE_REGISTER_USHORT(pwADRL, 0x5555);
                wRet = READ_REGISTER_USHORT(pwADRH);
                if (wRet != 0xAAAA) return STATUS_UNSUCCESSFUL;

                WRITE_REGISTER_USHORT(pwADRH, 0x0000);
                WRITE_REGISTER_USHORT(pwADRL, 0xFFFF);
                wRet = READ_REGISTER_USHORT(pwADRH);
                if (wRet != 0x0000) return STATUS_UNSUCCESSFUL;

                WRITE_REGISTER_USHORT(pwADRH, 0xFFFF);
                WRITE_REGISTER_USHORT(pwADRL, 0x0000);
                wRet = READ_REGISTER_USHORT(pwADRH);
                if (wRet != 0xFFFF) return STATUS_UNSUCCESSFUL;
        }

        WRITE_REGISTER_USHORT(pwADRH, wADRHContent);    // restore previous content
        WRITE_REGISTER_USHORT(pwADRL, wADRLContent);

        KdPrint(("TestConnection() OK.\n"));

        return STATUS_SUCCESS;
}
 
//------------------------------------------------------------------------
// scan VMEMM devices without disturbing anything
//
NTSTATUS PCICC32ScanCC32(PDEVICE_OBJECT deviceObj)
{
        int i;
        int nPCIADAs = ((DEVICE_EXT*)(deviceObj->DeviceExtension))->nPCIADAs;
        PCIADA           *pciada;
        USHORT           wCntrl;
        USHORT                   wIntCSR;
        USHORT                   wModuleStatus;

        KdPrint(("PCICC32ScanCC32(nPCIADAs = %d)\n", nPCIADAs));

    for (i = 0; i < nPCIADAs; i++)
    {
                pciada = &((DEVICE_EXT*)(deviceObj->DeviceExtension))->pciada[i];
               
                wCntrl  = READ_REGISTER_USHORT(pciada->pwCntrl);   // save it for later use
        wIntCSR = READ_REGISTER_USHORT(pciada->pwIntCSR);

                KdPrint(("wCntrl = 0x%04x, wIntCSR = 0x%04x\n", wCntrl, wIntCSR));

                WRITE_REGISTER_USHORT(pciada->pwCntrl, INHIBIT_CC32);  // switch off before open
                WRITE_REGISTER_USHORT(pciada->pwIntCSR, DISABLE_PCIADA_IRQS);
                WRITE_REGISTER_USHORT(pciada->pwCntrl, RELEASE_CC32);  // open it for test

                if (wCntrl & 0x0800)
                {
                        if (TestConnection(pciada) == STATUS_SUCCESS)
                        {      
                                wModuleStatus  = READ_REGISTER_USHORT(pciada->pvVirtIfr);

                                pciada->bConnected              = TRUE;

                                // interpret the content
                                pciada->wModuleNumber   = (wModuleStatus & MASK_MODNR)   >> 4;
                                pciada->wFPGAVersion    = (wModuleStatus & MASK_FPGA)    >> 8;
                                pciada->wModuleType             = (wModuleStatus & MASK_MODTYPE) >> 12;

                                KdPrint(("PCIADA %d <-> CC32 %d\n", i, pciada->wModuleNumber));
                        }
                        else
                                pciada->wModuleNumber = 0xFFFF;  // not recognized, take it out
                }
                else
                        pciada->wModuleNumber = 0xFFFF;  // not recognized, take it out

                if (pciada->wModuleNumber != 0xFFFF)
                  WRITE_REGISTER_USHORT(pciada->pwCntrl,  wCntrl);   // restore state
                else
                  WRITE_REGISTER_USHORT(pciada->pwCntrl,  INHIBIT_CC32);  

                WRITE_REGISTER_USHORT(pciada->pwIntCSR, wIntCSR);    // restore interrupt masks
    }

        return STATUS_SUCCESS;
}

 
//------------------------------------------------------------------------
// deinit all PCIADAs in a passive state
//
NTSTATUS PCICC32DeInitPCIADAs(PDEVICE_OBJECT deviceObj)
{
        int              i;
        DEVICE_EXT       *pDevExt = (DEVICE_EXT*)deviceObj->DeviceExtension;
        int                              nPCIADAs = pDevExt->nPCIADAs;
        PCIADA           *pciada;

        KdPrint(("PCICC32DeInitPCIADAs()\n"));

        // dis connect the interrupts to service routines
        for (i = 0; i < nPCIADAs; i++)
        {
                pciada = &pDevExt->pciada[i];

                WRITE_REGISTER_USHORT(pciada->pwCntrl,  INHIBIT_CC32);
                // this is the same as globalInterruptDisable(pciada);
                WRITE_REGISTER_USHORT(pciada->pwIntCSR, DISABLE_PCIADA_IRQS);
        }
 
        return STATUS_SUCCESS;
}

//------------------------------------------------------------------------
// switches pciada on or off
//
void enableCC32(PCIADA *pciada)
{
        WRITE_REGISTER_USHORT(pciada->pwCntrl,  RELEASE_CC32);
}

void disableCC32(PCIADA *pciada)
{
        WRITE_REGISTER_USHORT(pciada->pwCntrl,  INHIBIT_CC32);
}