// CameraIO.cpp: implementation of the CCameraIO class. // // Copyright (c) 2000 Apogee Instruments Inc. ////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #define HANDLE int #define FALSE 0 #define DWORD long #define _ASSERT assert #define REALTIME_PRIORITY_CLASS 1 #define GetCurrentProcess getpid #define LOBYTE(x) ((x) & 0xff) #define HIBYTE(x) ((x >> 8) & 0xff) #define MIRQ1 0x21 #define MIRQ2 0xA1 #include "time.h" //#include "tcl.h" //#include "ccd.h" #include "CameraIO_Linux.h" #include "ApogeeLinux.h" const int NUM_POSITIONS = 6; const int NUM_STEPS_PER_FILTER = 48; const int STEP_DELAY = 10; const unsigned char Steps[] = { 0x10, 0x30, 0x20, 0x60, 0x40, 0xc0, 0x80, 0x90 }; const int NUM_STEPS = sizeof ( Steps ); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// void CCameraIO::InitDefaults() { //////////////////////////////////////////////////////////// // Camera Settings m_HighPriority = true; m_PPRepeat = 1; m_DataBits = 16; m_FastShutter = false; m_MaxBinX = 8; m_MaxBinY = 63; m_MaxExposure = 10485.75; m_MinExposure = 0.01; m_GuiderRelays = false; m_Timeout = 2.0; //////////////////////////////////////////////////////////// // Cooler Settings m_TempControl = true; m_TempCalibration = 160; m_TempScale = 2.1; //////////////////////////////////////////////////////////// // Exposure Settings m_BinX = 1; m_BinY = 1; m_StartX = 0; m_StartY = 0; m_NumX = 1; m_NumY = 1; //////////////////////////////////////////////////////////// // Geometry Settings m_Columns = 0; m_Rows = 0; m_SkipC = 0; m_SkipR = 0; m_HFlush = 1; m_VFlush = 1; m_BIC = 4; m_BIR = 4; m_ImgColumns = 0; m_ImgRows = 0; //////////////////////////////////////////////////////////// // CCD Settings memset( m_Sensor, 0, 256 ); m_Color = false; m_Noise = 0.0; m_Gain = 0.0; m_PixelXSize = 0.0; m_PixelYSize = 0.0; //////////////////////////////////////////////////////////// // Internal variables fileHandle = 0; m_RegisterOffset = 0; m_Interface = Camera_Interface_PPI; m_SensorType = Camera_SensorType_CCD; } bool CCameraIO::InitDriver(unsigned short camnum) { char deviceName[64]; sprintf(deviceName,"%s%d",APOGEE_PPI_DEVICE,camnum); fileHandle = ::open(deviceName,O_RDONLY); if (fileHandle == -1) return false; return true; } long CCameraIO::Write( unsigned short reg, unsigned short val ) { int status; struct apIOparam request; unsigned short realreg = ( reg << 1 ) & 0xE; // limit input to our address range request.reg = realreg; request.param1=(int)val; request.param2=(int)m_PPRepeat; status=ioctl(fileHandle,APPPI_WRITE_USHORT,(unsigned long)&request); return 0; } long CCameraIO::Read( unsigned short reg, unsigned short& val ) { unsigned short realreg; int retval, status; struct apIOparam request; switch ( reg ) { case Reg_ImageData: realreg = RegISA_ImageData; break; case Reg_TempData: realreg = RegISA_TempData; break; case Reg_Status: realreg = RegISA_Status; break; case Reg_CommandReadback: realreg = RegISA_CommandReadback; break; default: assert( 1 ); // application program bug val = 0; return 0; } request.reg = realreg; request.param1=(unsigned long)&retval; request.param2=(int)m_PPRepeat; status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); val = (unsigned short)retval; return 0; } // Returns 0 if successfull, 1 if Line_Done poll timed out. long CCameraIO::ReadLine( long SkipPixels, long Pixels,unsigned short* pLineBuffer ) { int j; int retval, status; struct apIOparam request; if ( !m_TDI ) { ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// } request.reg = RegISA_ImageData; request.param1=(unsigned long)&retval; request.param2=(int)m_PPRepeat; for (j = 0; j < SkipPixels; j++) { status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); } for (j = 0; j < Pixels; j++) { status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); *pLineBuffer++ = (unsigned short)retval; } ///////////////////////////////////// // Assert done reading line m_RegShadow[ Reg_Command ] |= RegBit_DoneReading; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_DoneReading; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// if ( !m_TDI ) { ///////////////////////////////////// // Wait until camera is done clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break;// Line done if ( clock() > StopTime ) return 1; // Timed out } } return 0; } long CCameraIO::ReadImage( unsigned short* pImageBuffer ) { m_RegShadow[ Reg_Command ] |= RegBit_FIFOCache; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); long XEnd = long( m_ExposureNumX ); long SkipC = long( m_ExposureSkipC ); for (long i = 0; i < m_ExposureSkipR; i++) { if( InternalReadLine( false, SkipC, XEnd, NULL ) ) return 1; } long YEnd = long( m_ExposureNumY ); unsigned short* pLineBuffer = pImageBuffer; for (long i = 0; i < YEnd; i++) { if ( InternalReadLine( true, SkipC, XEnd, pLineBuffer ) ) return 1; pLineBuffer += XEnd; } m_RegShadow[ Reg_Command ] &= !RegBit_FIFOCache; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); return 0; } // Returns 0 if successfull, 1 if Line_Done poll timed out. long CCameraIO::InternalReadLine( bool KeepData, long SkipC, long XEnd, unsigned short* pLineBuffer ) { struct apIOparam request; int retval, status; ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= !RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// request.reg = RegISA_ImageData; request.param1=(unsigned long)&retval; request.param2=(int)m_PPRepeat; for (long j = 0; j < SkipC; j++) status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); if ( KeepData ) { for (long j = 0; j < XEnd; j++) { status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); *pLineBuffer++ = (unsigned short)retval; } } else { for (long j = 0; j < XEnd; j++) status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); } ///////////////////////////////////// // Assert done reading line m_RegShadow[ Reg_Command ] |= RegBit_DoneReading; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= !RegBit_DoneReading; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// ///////////////////////////////////// // Wait until camera is done clocking clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break;// Line done clock_t CurrentTime = clock(); if ( CurrentTime > StopTime ) return 1; // Timed out } return 0; }