diff options
Diffstat (limited to 'kstars/kstars/indi/apogee/ApnCamera.cpp')
-rw-r--r-- | kstars/kstars/indi/apogee/ApnCamera.cpp | 1890 |
1 files changed, 1890 insertions, 0 deletions
diff --git a/kstars/kstars/indi/apogee/ApnCamera.cpp b/kstars/kstars/indi/apogee/ApnCamera.cpp new file mode 100644 index 00000000..4e8c1b00 --- /dev/null +++ b/kstars/kstars/indi/apogee/ApnCamera.cpp @@ -0,0 +1,1890 @@ +// ApnCamera.cpp: implementation of the CApnCamera class. +// +// Copyright (c) 2003, 2004 Apogee Instruments, Inc. +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" + +#include "ApnCamera.h" +#include "ApnCamTable.h" + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CApnCamera::CApnCamera() +{ + m_ApnSensorInfo = NULL; +} + +CApnCamera::~CApnCamera() +{ + if ( m_ApnSensorInfo != NULL ) + { + delete m_ApnSensorInfo; + m_ApnSensorInfo = NULL; + } + CloseDriver(); +} + +bool CApnCamera::Expose( double Duration, bool Light ) +{ + ULONG ExpTime; + unsigned short BitsPerPixel(0); + unsigned short UnbinnedRoiX; + unsigned short UnbinnedRoiY; + unsigned short PreRoiSkip, PostRoiSkip; + unsigned short PreRoiRows, PostRoiRows; + unsigned short PreRoiVBinning, PostRoiVBinning; + + unsigned short RoiRegBuffer[12]; + unsigned short RoiRegData[12]; + + unsigned short TotalHPixels; + unsigned short TotalVPixels; + + + while ( read_ImagingStatus() != Apn_Status_Flushing ) + { + Sleep( 20 ); + } + + // Validate the "Duration" parameter + if ( Duration < APN_EXPOSURE_TIME_MIN ) + Duration = APN_EXPOSURE_TIME_MIN; + + // Validate the ROI params + UnbinnedRoiX = m_RoiPixelsH * m_RoiBinningH; + + PreRoiSkip = m_RoiStartX; + + PostRoiSkip = m_ApnSensorInfo->m_TotalColumns - + m_ApnSensorInfo->m_ClampColumns - + PreRoiSkip - + UnbinnedRoiX; + + TotalHPixels = UnbinnedRoiX + PreRoiSkip + PostRoiSkip + m_ApnSensorInfo->m_ClampColumns; + + if ( TotalHPixels != m_ApnSensorInfo->m_TotalColumns ) + return false; + + UnbinnedRoiY = m_RoiPixelsV * m_RoiBinningV; + + PreRoiRows = m_ApnSensorInfo->m_UnderscanRows + + m_RoiStartY; + + PostRoiRows = m_ApnSensorInfo->m_TotalRows - + PreRoiRows - + UnbinnedRoiY; + + TotalVPixels = UnbinnedRoiY + PreRoiRows + PostRoiRows; + + if ( TotalVPixels != m_ApnSensorInfo->m_TotalRows ) + return false; + + // Calculate the exposure time to program to the camera + ExpTime = ((unsigned long)(Duration / APN_TIMER_RESOLUTION)) + APN_TIMER_OFFSET_COUNT; + + Write( FPGA_REG_TIMER_LOWER, (unsigned short)(ExpTime & 0xFFFF)); + ExpTime = ExpTime >> 16; + Write( FPGA_REG_TIMER_UPPER, (unsigned short)(ExpTime & 0xFFFF)); + + m_pvtExposurePixelsV = m_RoiPixelsV; + m_pvtExposurePixelsH = m_RoiPixelsH; + + if ( m_DataBits == Apn_Resolution_SixteenBit ) + { + BitsPerPixel = 16; + } + else if ( m_DataBits == Apn_Resolution_TwelveBit ) + { + BitsPerPixel = 12; + } + + if ( PreStartExpose( BitsPerPixel ) != 0 ) + { + return false; + } + + // Calculate the vertical parameters + PreRoiVBinning = m_ApnSensorInfo->m_RowOffsetBinning; + + PostRoiVBinning = 1; + + // For interline CCDs, set "Fast Dump" mode if the particular array is NOT digitized + if ( m_ApnSensorInfo->m_InterlineCCD ) + { + // use the fast dump feature to get rid of the data quickly. + // one row, binning to the original row count + // note that we only are not digitized in arrays 1 and 3 + PreRoiVBinning = PreRoiRows; + PostRoiVBinning = PostRoiRows; + + PreRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; + PostRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; + + PreRoiRows = 1; + PostRoiRows = 1; + } + + // Set up the geometry for a full frame device + if ( m_ApnSensorInfo->m_EnableSingleRowOffset ) + { + PreRoiVBinning += PreRoiRows; + PostRoiVBinning = PostRoiRows; + + PreRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; + PostRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; + + PreRoiRows = 1; + PostRoiRows = 1; + } + + + // Issue the reset + RoiRegBuffer[0] = FPGA_REG_COMMAND_B; + RoiRegData[0] = FPGA_BIT_CMD_RESET; + + // Program the horizontal settings + RoiRegBuffer[1] = FPGA_REG_PREROI_SKIP_COUNT; + RoiRegData[1] = PreRoiSkip; + + RoiRegBuffer[2] = FPGA_REG_ROI_COUNT; + // Number of ROI pixels. Adjust the 12bit operation here to account for an extra + // 10 pixel shift as a result of the A/D conversion. + if ( m_DataBits == Apn_Resolution_SixteenBit ) + { + RoiRegData[2] = m_pvtExposurePixelsH + 1; + } + else if ( m_DataBits == Apn_Resolution_TwelveBit ) + { + RoiRegData[2] = m_pvtExposurePixelsH + 10; + } + + RoiRegBuffer[3] = FPGA_REG_POSTROI_SKIP_COUNT; + RoiRegData[3] = PostRoiSkip; + + // Program the vertical settings + RoiRegBuffer[4] = FPGA_REG_A1_ROW_COUNT; + RoiRegData[4] = PreRoiRows; + RoiRegBuffer[5] = FPGA_REG_A1_VBINNING; + RoiRegData[5] = PreRoiVBinning; + + RoiRegBuffer[6] = FPGA_REG_A2_ROW_COUNT; + RoiRegData[6] = m_RoiPixelsV; + RoiRegBuffer[7] = FPGA_REG_A2_VBINNING; + RoiRegData[7] = (m_RoiBinningV | FPGA_BIT_ARRAY_DIGITIZE); + + RoiRegBuffer[8] = FPGA_REG_A3_ROW_COUNT; + RoiRegData[8] = PostRoiRows; + RoiRegBuffer[9] = FPGA_REG_A3_VBINNING; + RoiRegData[9] = PostRoiVBinning; + + // Issue the reset + RoiRegBuffer[10] = FPGA_REG_COMMAND_B; + RoiRegData[10] = FPGA_BIT_CMD_RESET; + + switch ( m_pvtCameraMode ) + { + case Apn_CameraMode_Normal: + if ( Light ) + { + RoiRegBuffer[11] = FPGA_REG_COMMAND_A; + RoiRegData[11] = FPGA_BIT_CMD_EXPOSE; + } + else + { + RoiRegBuffer[11] = FPGA_REG_COMMAND_A; + RoiRegData[11] = FPGA_BIT_CMD_DARK; + } + break; + case Apn_CameraMode_TDI: + RoiRegBuffer[11] = FPGA_REG_COMMAND_A; + RoiRegData[11] = FPGA_BIT_CMD_TDI; + break; + case Apn_CameraMode_Test: + if ( Light ) + { + RoiRegBuffer[11] = FPGA_REG_COMMAND_A; + RoiRegData[11] = FPGA_BIT_CMD_EXPOSE; + } + else + { + RoiRegBuffer[11] = FPGA_REG_COMMAND_A; + RoiRegData[11] = FPGA_BIT_CMD_DARK; + } + break; + case Apn_CameraMode_ExternalTrigger: + RoiRegBuffer[11] = FPGA_REG_COMMAND_A; + RoiRegData[11] = FPGA_BIT_CMD_TRIGGER_EXPOSE; + break; + case Apn_CameraMode_ExternalShutter: + break; + } + + // Send the instruction sequence to the camera + WriteMultiMRMD( RoiRegBuffer, RoiRegData, 12 ); + + m_pvtImageInProgress = true; + m_pvtImageReady = false; + + return true; +} + +bool CApnCamera::ResetSystem() +{ + // Reset the camera engine + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); + + // Start flushing + Write( FPGA_REG_COMMAND_A, FPGA_BIT_CMD_FLUSH ); + + return true; +} + +bool CApnCamera::PauseTimer( bool PauseState ) +{ + unsigned short RegVal; + bool CurrentState; + + Read( FPGA_REG_OP_A, RegVal ); + + CurrentState = ( RegVal & FPGA_BIT_PAUSE_TIMER ) == FPGA_BIT_PAUSE_TIMER; + + if ( CurrentState != PauseState ) + { + if ( PauseState ) + { + RegVal |= FPGA_BIT_PAUSE_TIMER; + } + else + { + RegVal &= ~FPGA_BIT_PAUSE_TIMER; + } + Write ( FPGA_REG_OP_A, RegVal ); + } + + return true; +} + +bool CApnCamera::StopExposure( bool DigitizeData ) +{ + if ( m_pvtImageInProgress ) + { + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_END_EXPOSURE ); + + if ( PostStopExposure( DigitizeData ) != 0 ) + { + return false; + } + } + + return true; +} + + +unsigned short CApnCamera::GetExposurePixelsH() +{ + return m_pvtExposurePixelsH; +} + +unsigned short CApnCamera::GetExposurePixelsV() +{ + return m_pvtExposurePixelsV; +} + +double CApnCamera::read_InputVoltage() +{ + UpdateGeneralStatus(); + + return m_pvtInputVoltage; +} + +long CApnCamera::read_AvailableMemory() +{ + long AvailableMemory(0); + + switch( m_CameraInterface ) + { + case Apn_Interface_NET: + AvailableMemory = 28 * 1024; + break; + case Apn_Interface_USB: + AvailableMemory = 32 * 1024; + break; + default: + break; + } + + return AvailableMemory; +} + +unsigned short CApnCamera::read_FirmwareVersion() +{ + unsigned short FirmwareVersion; + Read( FPGA_REG_FIRMWARE_REV, FirmwareVersion ); + return FirmwareVersion; +} + +bool CApnCamera::read_ShutterState() +{ + UpdateGeneralStatus(); + + return m_pvtShutterState; +} + +bool CApnCamera::read_DisableShutter() +{ + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + return ( (RegVal & FPGA_BIT_DISABLE_SHUTTER) != 0 ); +} + +void CApnCamera::write_DisableShutter( bool DisableShutter ) +{ + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + + if ( DisableShutter ) + RegVal |= FPGA_BIT_DISABLE_SHUTTER; + else + RegVal &= ~FPGA_BIT_DISABLE_SHUTTER; + + Write( FPGA_REG_OP_A, RegVal ); +} + +bool CApnCamera::read_ForceShutterOpen() +{ + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + return ( (RegVal & FPGA_BIT_FORCE_SHUTTER) != 0 ); +} + +void CApnCamera::write_ForceShutterOpen( bool ForceShutterOpen ) +{ + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + + if ( ForceShutterOpen ) + RegVal |= FPGA_BIT_FORCE_SHUTTER; + else + RegVal &= ~FPGA_BIT_FORCE_SHUTTER; + + Write( FPGA_REG_OP_A, RegVal ); +} + +bool CApnCamera::read_ShutterAmpControl() +{ + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + return ( (RegVal & FPGA_BIT_SHUTTER_AMP_CONTROL ) != 0 ); +} + +void CApnCamera::write_ShutterAmpControl( bool ShutterAmpControl ) +{ + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + + if ( ShutterAmpControl ) + RegVal |= FPGA_BIT_SHUTTER_AMP_CONTROL; + else + RegVal &= ~FPGA_BIT_SHUTTER_AMP_CONTROL; + + Write( FPGA_REG_OP_A, RegVal ); +} + +bool CApnCamera::read_ExternalIoReadout() +{ + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + return ( (RegVal & FPGA_BIT_SHUTTER_MODE) != 0 ); +} + +void CApnCamera::write_ExternalIoReadout( bool ExternalIoReadout ) +{ + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + + if ( ExternalIoReadout ) + RegVal |= FPGA_BIT_SHUTTER_MODE; + else + RegVal &= ~FPGA_BIT_SHUTTER_MODE; + + Write( FPGA_REG_OP_A, RegVal ); +} + +bool CApnCamera::read_FastSequence() +{ + if ( m_ApnSensorInfo->m_InterlineCCD == false ) + return false; + + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + return ( (RegVal & FPGA_BIT_RATIO) != 0 ); +} + +void CApnCamera::write_FastSequence( bool FastSequence ) +{ + if ( m_ApnSensorInfo->m_InterlineCCD == false ) + return; + + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + + if ( FastSequence ) + { + RegVal |= FPGA_BIT_RATIO; + Write( FPGA_REG_SHUTTER_CLOSE_DELAY, 0x0 ); + } + else + { + RegVal &= ~FPGA_BIT_RATIO; + } + + Write( FPGA_REG_OP_A, RegVal ); +} + +Apn_NetworkMode CApnCamera::read_NetworkTransferMode() +{ + return m_pvtNetworkTransferMode; +} + +void CApnCamera::write_NetworkTransferMode( Apn_NetworkMode TransferMode ) +{ + SetNetworkTransferMode( TransferMode ); + + m_pvtNetworkTransferMode = TransferMode; +} + +Apn_CameraMode CApnCamera::read_CameraMode() +{ + return m_pvtCameraMode; +} + +void CApnCamera::write_CameraMode( Apn_CameraMode CameraMode ) +{ + unsigned short RegVal; + + + // If our state isn't going to change, do nothing + if ( m_pvtCameraMode == CameraMode ) + return; + + // If we didn't return already, then if we know our state is going to + // change. If we're in test mode, clear the appropriate FPGA bit(s). + switch( m_pvtCameraMode ) + { + case Apn_CameraMode_Normal: + break; + case Apn_CameraMode_TDI: + break; + case Apn_CameraMode_Test: + Read( FPGA_REG_OP_B, RegVal ); + RegVal &= ~FPGA_BIT_AD_SIMULATION; + Write( FPGA_REG_OP_B, RegVal ); + break; + case Apn_CameraMode_ExternalTrigger: + break; + case Apn_CameraMode_ExternalShutter: + Read( FPGA_REG_OP_A, RegVal ); + RegVal &= ~FPGA_BIT_SHUTTER_SOURCE; + Write( FPGA_REG_OP_A, RegVal ); + break; + } + + switch ( CameraMode ) + { + case Apn_CameraMode_Normal: + break; + case Apn_CameraMode_TDI: + break; + case Apn_CameraMode_Test: + Read( FPGA_REG_OP_B, RegVal ); + RegVal |= FPGA_BIT_AD_SIMULATION; + Write( FPGA_REG_OP_B, RegVal ); + break; + case Apn_CameraMode_ExternalTrigger: + Read( FPGA_REG_IO_PORT_ASSIGNMENT, RegVal ); + RegVal |= 0x01; + Write( FPGA_REG_IO_PORT_ASSIGNMENT, RegVal ); + break; + case Apn_CameraMode_ExternalShutter: + Read( FPGA_REG_OP_A, RegVal ); + RegVal |= FPGA_BIT_SHUTTER_SOURCE; + Write( FPGA_REG_OP_A, RegVal ); + break; + } + + m_pvtCameraMode = CameraMode; +} + +void CApnCamera::write_DataBits( Apn_Resolution BitResolution ) +{ + unsigned short RegVal; + + if ( m_CameraInterface == Apn_Interface_NET ) + { + // The network interface is 16bpp only. Changing the resolution + // for network cameras has no effect. + return; + } + + if ( m_DataBits != BitResolution ) + { + // Reset the camera + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); + + // Change bit setting after the reset + Read( FPGA_REG_OP_A, RegVal ); + + if ( BitResolution == Apn_Resolution_TwelveBit ) + RegVal |= FPGA_BIT_DIGITIZATION_RES; + + if ( BitResolution == Apn_Resolution_SixteenBit ) + RegVal &= ~FPGA_BIT_DIGITIZATION_RES; + + Write( FPGA_REG_OP_A, RegVal ); + + m_DataBits = BitResolution; + + LoadClampPattern(); + LoadSkipPattern(); + LoadRoiPattern( m_RoiBinningH ); + + // Reset the camera + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); + // Start flushing + Write( FPGA_REG_COMMAND_A, FPGA_BIT_CMD_FLUSH ); + } +} + +Apn_Status CApnCamera::read_ImagingStatus() +{ + bool Exposing, Active, Done, Flushing, WaitOnTrigger; + bool DataHalted, RamError; + + + UpdateGeneralStatus(); + + // Update the ImagingStatus + Exposing = false; + Active = false; + Done = false; + Flushing = false; + WaitOnTrigger = false; + DataHalted = false; + RamError = false; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_IMAGING_ACTIVE) != 0 ) + Active = true; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_IMAGE_EXPOSING) != 0 ) + Exposing = true; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_IMAGE_DONE) != 0 ) + Done = true; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_FLUSHING) != 0 ) + Flushing = true; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_WAITING_TRIGGER) != 0 ) + WaitOnTrigger = true; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_DATA_HALTED) != 0 ) + DataHalted = true; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_PATTERN_ERROR) != 0 ) + RamError = true; + + if ( RamError ) + { + m_pvtImagingStatus = Apn_Status_PatternError; + } + else + { + if ( DataHalted ) + { + m_pvtImagingStatus = Apn_Status_DataError; + } + else + { + if ( WaitOnTrigger ) + { + m_pvtImagingStatus = Apn_Status_WaitingOnTrigger; + } + else + { + if ( Done && m_pvtImageInProgress ) + { + m_pvtImageReady = true; + m_pvtImagingStatus = Apn_Status_ImageReady; + } + else + { + if ( Active ) + { + if ( Exposing ) + m_pvtImagingStatus = Apn_Status_Exposing; + else + m_pvtImagingStatus = Apn_Status_ImagingActive; + } + else + { + if ( Flushing ) + m_pvtImagingStatus = Apn_Status_Flushing; + else + m_pvtImagingStatus = Apn_Status_Idle; + } + } + } + } + } + + /* + switch( m_pvtImagingStatus ) + { + case Apn_Status_DataError: + OutputDebugString( "ImagingStatus: Apn_Status_DataError" ); + break; + case Apn_Status_PatternError: + OutputDebugString( "ImagingStatus: Apn_Status_PatternError" ); + break; + case Apn_Status_Idle: + OutputDebugString( "ImagingStatus: Apn_Status_Idle" ); + break; + case Apn_Status_Exposing: + OutputDebugString( "ImagingStatus: Apn_Status_Exposing" ); + break; + case Apn_Status_ImagingActive: + OutputDebugString( "ImagingStatus: Apn_Status_ImagingActive" ); + break; + case Apn_Status_ImageReady: + OutputDebugString( "ImagingStatus: Apn_Status_ImageReady" ); + break; + case Apn_Status_Flushing: + OutputDebugString( "ImagingStatus: Apn_Status_Flushing" ); + break; + case Apn_Status_WaitingOnTrigger: + OutputDebugString( "ImagingStatus: Apn_Status_WaitingOnTrigger" ); + break; + default: + OutputDebugString( "ImagingStatus: UNDEFINED!!" ); + break; + } + */ + + return m_pvtImagingStatus; +} + +Apn_LedMode CApnCamera::read_LedMode() +{ + return m_pvtLedMode; +} + +void CApnCamera::write_LedMode( Apn_LedMode LedMode ) +{ + unsigned short RegVal; + + Read( FPGA_REG_OP_A, RegVal ); + + switch ( LedMode ) + { + case Apn_LedMode_DisableAll: + RegVal |= FPGA_BIT_LED_DISABLE; + break; + case Apn_LedMode_DisableWhileExpose: + RegVal &= ~FPGA_BIT_LED_DISABLE; + RegVal |= FPGA_BIT_LED_EXPOSE_DISABLE; + break; + case Apn_LedMode_EnableAll: + RegVal &= ~FPGA_BIT_LED_DISABLE; + RegVal &= ~FPGA_BIT_LED_EXPOSE_DISABLE; + break; + } + + m_pvtLedMode = LedMode; + + Write( FPGA_REG_OP_A, RegVal ); +} + +Apn_LedState CApnCamera::read_LedState( unsigned short LedId ) +{ + Apn_LedState RetVal(0); + + if ( LedId == 0 ) // LED A + RetVal = m_pvtLedStateA; + + if ( LedId == 1 ) // LED B + RetVal = m_pvtLedStateB; + + return RetVal; +} + +void CApnCamera::write_LedState( unsigned short LedId, Apn_LedState LedState ) +{ + unsigned short RegVal; + + + RegVal = 0x0; + + if ( LedId == 0 ) // LED A + { + RegVal = (m_pvtLedStateB << 4); // keep the current settings for LED B + RegVal |= LedState; // program new settings + m_pvtLedStateA = LedState; + } + else if ( LedId == 1 ) // LED B + { + RegVal = m_pvtLedStateA; // keep the current settings for LED A + RegVal |= (LedState << 4); // program new settings + m_pvtLedStateB = LedState; + } + + Write( FPGA_REG_LED_SELECT, RegVal ); +} + +bool CApnCamera::read_CoolerEnable() +{ + return m_pvtCoolerEnable; +} + +void CApnCamera::write_CoolerEnable( bool CoolerEnable ) +{ + if ( CoolerEnable ) + { + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RAMP_TO_SETPOINT ); + } + else + { + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RAMP_TO_AMBIENT ); + } + + m_pvtCoolerEnable = CoolerEnable; +} + +Apn_CoolerStatus CApnCamera::read_CoolerStatus() +{ + bool CoolerAtTemp; + bool CoolerActive; + bool CoolerTempRevised; + + + UpdateGeneralStatus(); + + // Update CoolerStatus + CoolerActive = false; + CoolerAtTemp = false; + CoolerTempRevised = false; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_TEMP_AT_TEMP) != 0 ) + CoolerAtTemp = true; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_TEMP_ACTIVE) != 0 ) + CoolerActive = true; + + if ( (m_pvtStatusReg & FPGA_BIT_STATUS_TEMP_REVISION) != 0 ) + CoolerTempRevised = true; + + // Now derive our cooler state + if ( !CoolerActive ) + { + m_pvtCoolerStatus = Apn_CoolerStatus_Off; + } + else + { + if ( CoolerTempRevised ) + { + m_pvtCoolerStatus = Apn_CoolerStatus_Revision; + } + else + { + if ( CoolerAtTemp ) + m_pvtCoolerStatus = Apn_CoolerStatus_AtSetPoint; + else + m_pvtCoolerStatus = Apn_CoolerStatus_RampingToSetPoint; + + } + } + + return m_pvtCoolerStatus; +} + +double CApnCamera::read_CoolerSetPoint() +{ + unsigned short RegVal; + double TempVal; + + Read( FPGA_REG_TEMP_DESIRED, RegVal ); + + RegVal &= 0x0FFF; + + TempVal = ( RegVal - APN_TEMP_SETPOINT_ZERO_POINT ) * APN_TEMP_DEGREES_PER_BIT; + + return TempVal; +} + +void CApnCamera::write_CoolerSetPoint( double SetPoint ) +{ + unsigned short RegVal; + double TempVal; + + + TempVal = SetPoint; + + if ( SetPoint < (APN_TEMP_SETPOINT_MIN - APN_TEMP_KELVIN_SCALE_OFFSET) ) + TempVal = APN_TEMP_SETPOINT_MIN; + + if ( SetPoint > (APN_TEMP_SETPOINT_MAX - APN_TEMP_KELVIN_SCALE_OFFSET) ) + TempVal = APN_TEMP_SETPOINT_MAX; + + RegVal = (unsigned short)( (TempVal / APN_TEMP_DEGREES_PER_BIT) + APN_TEMP_SETPOINT_ZERO_POINT ); + + Write( FPGA_REG_TEMP_DESIRED, RegVal ); +} + +double CApnCamera::read_CoolerBackoffPoint() +{ + return ( m_pvtCoolerBackoffPoint ); +} + +void CApnCamera::write_CoolerBackoffPoint( double BackoffPoint ) +{ + unsigned short RegVal; + double TempVal; + + TempVal = BackoffPoint; + + // BackoffPoint must be a positive number! + if ( BackoffPoint < 0.0 ) + TempVal = 0.0; + + if ( BackoffPoint < (APN_TEMP_SETPOINT_MIN - APN_TEMP_KELVIN_SCALE_OFFSET) ) + TempVal = APN_TEMP_SETPOINT_MIN; + + if ( BackoffPoint > (APN_TEMP_SETPOINT_MAX - APN_TEMP_KELVIN_SCALE_OFFSET) ) + TempVal = APN_TEMP_SETPOINT_MAX; + + m_pvtCoolerBackoffPoint = TempVal; + + RegVal = (unsigned short)( TempVal / APN_TEMP_DEGREES_PER_BIT ); + + Write( FPGA_REG_TEMP_BACKOFF, RegVal ); +} + +double CApnCamera::read_CoolerDrive() +{ + UpdateGeneralStatus(); + + return m_pvtCoolerDrive; +} + +double CApnCamera::read_TempCCD() +{ + // UpdateGeneralStatus(); + + unsigned short TempReg; + unsigned short TempAvg; + unsigned long TempTotal; + int don; + + TempTotal = 0; + don = 8; + if ( m_CameraInterface == Apn_Interface_NET ) { + don = 1; + } + + for ( int i=0; i<don; i++ ) + { + Read( FPGA_REG_TEMP_CCD, TempReg ); + TempTotal += TempReg; + } + + TempAvg = (unsigned short)(TempTotal / don); + + m_pvtCurrentCcdTemp = ( (TempAvg - APN_TEMP_SETPOINT_ZERO_POINT) + * APN_TEMP_DEGREES_PER_BIT ); + + return m_pvtCurrentCcdTemp; +} + +double CApnCamera::read_TempHeatsink() +{ + // UpdateGeneralStatus(); + + unsigned short TempReg; + unsigned short TempAvg; + unsigned long TempTotal; + int don; + + TempTotal = 0; + don = 8; + if ( m_CameraInterface == Apn_Interface_NET ) { + don = 1; + } + + for ( int i=0; i<don; i++ ) + { + Read( FPGA_REG_TEMP_HEATSINK, TempReg ); + TempTotal += TempReg; + } + + TempAvg = (unsigned short)(TempTotal / don); + + m_pvtCurrentHeatsinkTemp = ( (TempAvg - APN_TEMP_HEATSINK_ZERO_POINT) + * APN_TEMP_DEGREES_PER_BIT ); + + return m_pvtCurrentHeatsinkTemp; +} + +Apn_FanMode CApnCamera::read_FanMode() +{ + return m_pvtFanMode; +} + +void CApnCamera::write_FanMode( Apn_FanMode FanMode ) +{ + unsigned short RegVal; + unsigned short OpRegA; + + + if ( m_pvtFanMode == FanMode ) + return; + + if ( m_pvtCoolerEnable ) + { + Read( FPGA_REG_OP_A, OpRegA ); + OpRegA |= FPGA_BIT_TEMP_SUSPEND; + Write( FPGA_REG_OP_A, OpRegA ); + + do + { + Read( FPGA_REG_GENERAL_STATUS, RegVal ); + } while ( (RegVal & FPGA_BIT_STATUS_TEMP_SUSPEND_ACK) == 0 ); + + } + + switch ( FanMode ) + { + case Apn_FanMode_Off: + RegVal = APN_FAN_SPEED_OFF; + break; + case Apn_FanMode_Low: + RegVal = APN_FAN_SPEED_LOW; + break; + case Apn_FanMode_Medium: + RegVal = APN_FAN_SPEED_MEDIUM; + break; + case Apn_FanMode_High: + RegVal = APN_FAN_SPEED_HIGH; + break; + } + + Write( FPGA_REG_FAN_SPEED_CONTROL, RegVal ); + + Read( FPGA_REG_OP_B, RegVal ); + RegVal |= FPGA_BIT_DAC_SELECT_ZERO; + RegVal &= ~FPGA_BIT_DAC_SELECT_ONE; + Write( FPGA_REG_OP_B, RegVal ); + + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_DAC_LOAD ); + + m_pvtFanMode = FanMode; + + if ( m_pvtCoolerEnable ) + { + OpRegA &= ~FPGA_BIT_TEMP_SUSPEND; + Write( FPGA_REG_OP_A, OpRegA ); + } +} + +double CApnCamera::read_ShutterStrobePosition() +{ + return m_pvtShutterStrobePosition; +} + +void CApnCamera::write_ShutterStrobePosition( double Position ) +{ + unsigned short RegVal; + + if ( Position < APN_STROBE_POSITION_MIN ) + Position = APN_STROBE_POSITION_MIN; + + RegVal = (unsigned short)((Position - APN_STROBE_POSITION_MIN) / APN_TIMER_RESOLUTION); + + Write( FPGA_REG_SHUTTER_STROBE_POSITION, RegVal ); + + m_pvtShutterStrobePosition = Position; +} + +double CApnCamera::read_ShutterStrobePeriod() +{ + return m_pvtShutterStrobePeriod; +} + +void CApnCamera::write_ShutterStrobePeriod( double Period ) +{ + unsigned short RegVal; + + if ( Period < APN_STROBE_PERIOD_MIN ) + Period = APN_STROBE_PERIOD_MIN; + + RegVal = (unsigned short)((Period - APN_STROBE_PERIOD_MIN) / APN_PERIOD_TIMER_RESOLUTION); + + Write( FPGA_REG_SHUTTER_STROBE_PERIOD, RegVal ); + + m_pvtShutterStrobePeriod = Period; +} + +double CApnCamera::read_SequenceDelay() +{ + return m_pvtSequenceDelay; +} + +void CApnCamera::write_SequenceDelay( double Delay ) +{ + unsigned short RegVal; + + if ( Delay > APN_SEQUENCE_DELAY_LIMIT ) + Delay = APN_SEQUENCE_DELAY_LIMIT; + + m_pvtSequenceDelay = Delay; + + RegVal = (unsigned short)(Delay / APN_SEQUENCE_DELAY_RESOLUTION); + + Write( FPGA_REG_SEQUENCE_DELAY, RegVal ); +} + +bool CApnCamera::read_VariableSequenceDelay() +{ + unsigned short RegVal; + Read( FPGA_REG_OP_A, RegVal ); + // variable delay occurs when the bit is 0 + return ( (RegVal & FPGA_BIT_DELAY_MODE) == 0 ); +} + +void CApnCamera::write_VariableSequenceDelay( bool VariableSequenceDelay ) +{ + unsigned short RegVal; + + Read( FPGA_REG_OP_A, RegVal ); + + if ( VariableSequenceDelay ) + RegVal &= ~FPGA_BIT_DELAY_MODE; // variable when zero + else + RegVal |= FPGA_BIT_DELAY_MODE; // constant when one + + Write( FPGA_REG_OP_A, RegVal ); +} + +unsigned short CApnCamera::read_ImageCount() +{ + return m_pvtImageCount; +} + +void CApnCamera::write_ImageCount( unsigned short Count ) +{ + if ( Count == 0 ) + Count = 1; + + Write( FPGA_REG_IMAGE_COUNT, Count ); + + m_pvtImageCount = Count; +} + +void CApnCamera::write_RoiBinningH( unsigned short BinningH ) +{ + // Check to see if we actually need to update the binning + if ( BinningH != m_RoiBinningH ) + { + // Reset the camera + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); + + LoadRoiPattern( BinningH ); + m_RoiBinningH = BinningH; + + // Reset the camera + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); + + // Start flushing + Write( FPGA_REG_COMMAND_A, FPGA_BIT_CMD_FLUSH ); + } +} + +void CApnCamera::write_RoiBinningV( unsigned short BinningV ) +{ + // Check to see if we actually need to update the binning + if ( BinningV != m_RoiBinningV ) + { + m_RoiBinningV = BinningV; + } +} + +void CApnCamera::write_RoiPixelsV( unsigned short PixelsV ) +{ + m_RoiPixelsV = PixelsV; +} + +void CApnCamera::write_RoiStartY( unsigned short StartY ) +{ + m_RoiStartY = StartY; +} + +unsigned short CApnCamera::read_OverscanColumns() +{ + return m_ApnSensorInfo->m_OverscanColumns; +} + +unsigned short CApnCamera::read_MaxBinningV() +{ + if ( m_ApnSensorInfo->m_ImagingRows < APN_VBINNING_MAX ) + return m_ApnSensorInfo->m_ImagingRows; + else + return APN_VBINNING_MAX; +} + +unsigned short CApnCamera::read_SequenceCounter() +{ + unsigned short RegVal; + Read( FPGA_REG_SEQUENCE_COUNTER, RegVal ); + return RegVal; +} + +unsigned short CApnCamera::read_TDICounter() +{ + unsigned short RegVal; + Read( FPGA_REG_TDI_COUNTER, RegVal ); + return RegVal; +} + +unsigned short CApnCamera::read_TDIRows() +{ + return m_pvtTDIRows; +} + +void CApnCamera::write_TDIRows( unsigned short TdiRows ) +{ + if ( TdiRows == 0 ) // Make sure the TDI row count is at least 1 + TdiRows = 1; + + Write( FPGA_REG_TDI_COUNT, TdiRows ); + m_pvtTDIRows = TdiRows; +} + +double CApnCamera::read_TDIRate() +{ + return m_pvtTDIRate; +} + +void CApnCamera::write_TDIRate( double TdiRate ) +{ + unsigned short RegVal; + + if ( TdiRate < APN_TDI_RATE_MIN ) + TdiRate = APN_TDI_RATE_MIN; + + if ( TdiRate > APN_TDI_RATE_MAX ) + TdiRate = APN_TDI_RATE_MAX; + + RegVal = (unsigned short)( TdiRate / APN_TDI_RATE_RESOLUTION ); + + Write( FPGA_REG_TDI_RATE, RegVal ); + + m_pvtTDIRate = TdiRate; +} + +unsigned short CApnCamera::read_IoPortAssignment() +{ + unsigned short RegVal; + Read( FPGA_REG_IO_PORT_ASSIGNMENT, RegVal ); + RegVal &= FPGA_MASK_IO_PORT_ASSIGNMENT; + return RegVal; +} + +void CApnCamera::write_IoPortAssignment( unsigned short IoPortAssignment ) +{ + IoPortAssignment &= FPGA_MASK_IO_PORT_ASSIGNMENT; + Write( FPGA_REG_IO_PORT_ASSIGNMENT, IoPortAssignment ); +} + +unsigned short CApnCamera::read_IoPortDirection() +{ + unsigned short RegVal; + Read( FPGA_REG_IO_PORT_DIRECTION, RegVal ); + RegVal &= FPGA_MASK_IO_PORT_DIRECTION; + return RegVal; +} + +void CApnCamera::write_IoPortDirection( unsigned short IoPortDirection ) +{ + IoPortDirection &= FPGA_MASK_IO_PORT_DIRECTION; + Write( FPGA_REG_IO_PORT_DIRECTION, IoPortDirection ); +} + +unsigned short CApnCamera::read_IoPortData() +{ + unsigned short RegVal; + Read( FPGA_REG_IO_PORT_READ, RegVal ); + RegVal &= FPGA_MASK_IO_PORT_DATA; + return RegVal; +} + +void CApnCamera::write_IoPortData( unsigned short IoPortData ) +{ + IoPortData &= FPGA_MASK_IO_PORT_DATA; + Write( FPGA_REG_IO_PORT_WRITE, IoPortData ); +} + +unsigned short CApnCamera::read_TwelveBitGain() +{ + return m_pvtTwelveBitGain; +} + +void CApnCamera::write_TwelveBitGain( unsigned short TwelveBitGain ) +{ + unsigned short NewVal; + unsigned short StartVal; + unsigned short FirstBit; + + NewVal = 0x0; + StartVal = TwelveBitGain & 0x3FF; + + for ( int i=0; i<10; i++ ) + { + FirstBit = ( StartVal & 0x0001 ); + NewVal |= ( FirstBit << (10-i) ); + StartVal = StartVal >> 1; + } + + NewVal |= 0x4000; + + Write( FPGA_REG_AD_CONFIG_DATA, NewVal ); + Write( FPGA_REG_COMMAND_B, 0x8000 ); + + m_pvtTwelveBitGain = TwelveBitGain & 0x3FF; +} + +double CApnCamera::read_MaxExposureTime() +{ + return APN_EXPOSURE_TIME_MAX; +} + +double CApnCamera::read_TestLedBrightness() +{ + return m_pvtTestLedBrightness; +} + +void CApnCamera::write_TestLedBrightness( double TestLedBrightness ) +{ + unsigned short RegVal; + unsigned short OpRegA; + + + if ( TestLedBrightness == m_pvtTestLedBrightness ) + return; + + if ( m_pvtCoolerEnable ) + { + Read( FPGA_REG_OP_A, OpRegA ); + OpRegA |= FPGA_BIT_TEMP_SUSPEND; + Write( FPGA_REG_OP_A, OpRegA ); + + do + { + Read( FPGA_REG_GENERAL_STATUS, RegVal ); + } while ( (RegVal & FPGA_BIT_STATUS_TEMP_SUSPEND_ACK) == 0 ); + + } + + RegVal = (unsigned short)( (double)FPGA_MASK_LED_ILLUMINATION * (TestLedBrightness/100.0) ); + + Write( FPGA_REG_LED_DRIVE, RegVal ); + + Read( FPGA_REG_OP_B, RegVal ); + RegVal &= ~FPGA_BIT_DAC_SELECT_ZERO; + RegVal |= FPGA_BIT_DAC_SELECT_ONE; + Write( FPGA_REG_OP_B, RegVal ); + + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_DAC_LOAD ); + + m_pvtTestLedBrightness = TestLedBrightness; + + if ( m_pvtCoolerEnable ) + { + OpRegA &= ~FPGA_BIT_TEMP_SUSPEND; + Write( FPGA_REG_OP_A, OpRegA ); + } +} + + + + + + + + +long CApnCamera::LoadVerticalPattern() +{ + unsigned short RegData; + + // Prime the RAM (Enable) + Read( FPGA_REG_OP_B, RegData ); + RegData |= FPGA_BIT_VRAM_ENABLE; + Write( FPGA_REG_OP_B, RegData ); + + WriteMultiSRMD( FPGA_REG_VRAM_INPUT, + m_ApnSensorInfo->m_VerticalPattern.PatternData, + m_ApnSensorInfo->m_VerticalPattern.NumElements ); + + // RAM is now loaded (Disable) + Read( FPGA_REG_OP_B, RegData ); + RegData &= ~FPGA_BIT_VRAM_ENABLE; + Write( FPGA_REG_OP_B, RegData ); + + return 0; +} + + +long CApnCamera::LoadClampPattern() +{ + unsigned short RegData; + + // Prime the RAM (Enable) + Read( FPGA_REG_OP_B, RegData ); + RegData |= FPGA_BIT_HCLAMP_ENABLE; + Write( FPGA_REG_OP_B, RegData ); + + if ( m_DataBits == Apn_Resolution_SixteenBit ) + { + WriteHorizontalPattern( &m_ApnSensorInfo->m_ClampPatternSixteen, + FPGA_REG_HCLAMP_INPUT, + 1 ); + } + else if ( m_DataBits == Apn_Resolution_TwelveBit ) + { + WriteHorizontalPattern( &m_ApnSensorInfo->m_ClampPatternTwelve, + FPGA_REG_HCLAMP_INPUT, + 1 ); + } + + // RAM is now loaded (Disable) + Read( FPGA_REG_OP_B, RegData ); + RegData &= ~FPGA_BIT_HCLAMP_ENABLE; + Write( FPGA_REG_OP_B, RegData ); + + return 0; +} + + +long CApnCamera::LoadSkipPattern() +{ + unsigned short RegData; + + // Prime the RAM (Enable) + Read( FPGA_REG_OP_B, RegData ); + RegData |= FPGA_BIT_HSKIP_ENABLE; + Write( FPGA_REG_OP_B, RegData ); + + if ( m_DataBits == Apn_Resolution_SixteenBit ) + { + WriteHorizontalPattern( &m_ApnSensorInfo->m_SkipPatternSixteen, + FPGA_REG_HSKIP_INPUT, + 1 ); + } + else if ( m_DataBits == Apn_Resolution_TwelveBit ) + { + WriteHorizontalPattern( &m_ApnSensorInfo->m_SkipPatternTwelve, + FPGA_REG_HSKIP_INPUT, + 1 ); + } + + // RAM is now loaded (Disable) + Read( FPGA_REG_OP_B, RegData ); + RegData &= ~FPGA_BIT_HSKIP_ENABLE; + Write( FPGA_REG_OP_B, RegData ); + + return 0; +} + + +long CApnCamera::LoadRoiPattern( unsigned short binning ) +{ + unsigned short RegData; + + // Prime the RAM (Enable) + Read( FPGA_REG_OP_B, RegData ); + RegData |= FPGA_BIT_HRAM_ENABLE; + Write( FPGA_REG_OP_B, RegData ); + + if ( m_DataBits == Apn_Resolution_SixteenBit ) + { + WriteHorizontalPattern( &m_ApnSensorInfo->m_RoiPatternSixteen, + FPGA_REG_HRAM_INPUT, + binning ); + } + else if ( m_DataBits == Apn_Resolution_TwelveBit ) + { + WriteHorizontalPattern( &m_ApnSensorInfo->m_RoiPatternTwelve, + FPGA_REG_HRAM_INPUT, + binning ); + } + + // RAM is now loaded (Disable) + Read( FPGA_REG_OP_B, RegData ); + RegData &= ~FPGA_BIT_HRAM_ENABLE; + Write( FPGA_REG_OP_B, RegData ); + + return 0; +} + + +long CApnCamera::WriteHorizontalPattern( APN_HPATTERN_FILE *Pattern, + unsigned short RamReg, + unsigned short Binning ) +{ + unsigned short i; + unsigned short DataCount; + unsigned short *DataArray; + unsigned short Index; + unsigned short BinNumber; + + + Index = 0; + BinNumber = Binning - 1; // arrays are zero-based + + DataCount = Pattern->RefNumElements + + Pattern->BinNumElements[BinNumber] + + Pattern->SigNumElements; + + DataArray = (unsigned short *)malloc(DataCount * sizeof(unsigned short)); + + for ( i=0; i<Pattern->RefNumElements; i++ ) + { + DataArray[Index] = Pattern->RefPatternData[i]; + Index++; + } + + for ( i=0; i<Pattern->BinNumElements[BinNumber]; i++ ) + { + DataArray[Index] = Pattern->BinPatternData[BinNumber][i]; + Index++; + } + + for ( i=0; i<Pattern->SigNumElements; i++ ) + { + DataArray[Index] = Pattern->SigPatternData[i]; + Index++; + } + + WriteMultiSRMD( RamReg, DataArray, DataCount ); + + // cleanup + free( DataArray ); + + return 0; +} + + +long CApnCamera::InitDefaults() +{ + unsigned short RegVal; + unsigned short CameraID; + unsigned short ShutterDelay; + + unsigned short PreRoiRows, PostRoiRows; + unsigned short PreRoiVBinning, PostRoiVBinning; + unsigned short UnbinnedRoiY; // Vertical ROI pixels + + + // Read the Camera ID register + Read( FPGA_REG_CAMERA_ID, CameraID ); + CameraID &= FPGA_MASK_CAMERA_ID; + + // Look up the ID and dynamically create the m_ApnSensorInfo object + switch ( CameraID ) + { + case APN_ALTA_KAF0401E_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF0401E; + break; + case APN_ALTA_KAF1602E_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF1602E; + break; + case APN_ALTA_KAF0261E_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF0261E; + break; + case APN_ALTA_KAF1301E_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF1301E; + break; + case APN_ALTA_KAF1401E_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF1401E; + break; + case APN_ALTA_KAF1001E_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF1001E; + break; + case APN_ALTA_KAF3200E_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF3200E; + break; + case APN_ALTA_KAF4202_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF4202; + break; + case APN_ALTA_KAF6303E_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF6303E; + break; + case APN_ALTA_KAF16801E_CAM_ID: + m_ApnSensorInfo = new CApnCamData_KAF16801E; + break; + case APN_ALTA_TH7899_CAM_ID: + m_ApnSensorInfo = new CApnCamData_TH7899; + break; + case APN_ALTA_CCD4710LS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4710LS; + break; + case APN_ALTA_CCD4710HS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4710HS; + break; + case APN_ALTA_CCD4240LS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4240LS; + break; + case APN_ALTA_CCD4240HS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4240HS; + break; + case APN_ALTA_CCD5710LS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD5710LS; + break; + case APN_ALTA_CCD5710HS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD5710HS; + break; + case APN_ALTA_CCD3011LS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD3011LS; + break; + case APN_ALTA_CCD3011HS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD3011HS; + break; + case APN_ALTA_CCD5520LS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD5520LS; + break; + case APN_ALTA_CCD5520HS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD5520HS; + break; + case APN_ALTA_CCD4720LS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4720LS; + break; + case APN_ALTA_CCD4720HS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4720HS; + break; + case APN_ALTA_CCD7700LS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD7700LS; + break; + case APN_ALTA_CCD7700HS_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD7700HS; + break; + case APN_ALTA_CCD4710LS2_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4710LS2; + break; + case APN_ALTA_CCD4710LS3_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4710LS3; + break; + case APN_ALTA_CCD4710LS4_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4710LS4; + break; + case APN_ALTA_CCD4710LS5_CAM_ID: + m_ApnSensorInfo = new CApnCamData_CCD4710LS5; + break; + default: + return 1; + break; + } + + // we created the object, now set everything + m_ApnSensorInfo->Initialize(); + + // Initialize public variables + m_DigitizeOverscan = false; + m_DataBits = Apn_Resolution_SixteenBit; + + // Initialize private variables + m_pvtCameraMode = Apn_CameraMode_Normal; + m_pvtNetworkTransferMode = Apn_NetworkMode_Tcp; + + // Initialize variables used for imaging + m_RoiStartX = 0; + m_RoiStartY = 0; + m_RoiPixelsH = m_ApnSensorInfo->m_ImagingColumns; + m_RoiPixelsV = m_ApnSensorInfo->m_ImagingRows; + + m_RoiBinningH = 1; + m_RoiBinningV = 1; + printf ("Camera ID is %u\n",CameraID); + printf("sensor = %s\n", m_ApnSensorInfo->m_Sensor); + printf("model = %s\n",m_ApnSensorInfo->m_CameraModel); + printf("interline = %u\n",m_ApnSensorInfo->m_InterlineCCD); + printf("serialA = %u\n",m_ApnSensorInfo->m_SupportsSerialA); + printf("serialB = %u\n",m_ApnSensorInfo->m_SupportsSerialB); + printf("ccdtype = %u\n",m_ApnSensorInfo->m_SensorTypeCCD); + printf("Tcolumns = %u\n",m_ApnSensorInfo->m_TotalColumns); + printf("ImgColumns = %u\n",m_ApnSensorInfo->m_ImagingColumns); + printf("ClampColumns = %u\n",m_ApnSensorInfo->m_ClampColumns); + printf("PreRoiSColumns = %u\n",m_ApnSensorInfo->m_PreRoiSkipColumns); + printf("PostRoiSColumns = %u\n",m_ApnSensorInfo->m_PostRoiSkipColumns); + printf("OverscanColumns = %u\n",m_ApnSensorInfo->m_OverscanColumns); + printf("TRows = %u\n",m_ApnSensorInfo->m_TotalRows); + printf("ImgRows = %u\n",m_ApnSensorInfo->m_ImagingRows); + printf("UnderscanRows = %u\n",m_ApnSensorInfo->m_UnderscanRows); + printf("OverscanRows = %u\n",m_ApnSensorInfo->m_OverscanRows); + printf("VFlushBinning = %u\n",m_ApnSensorInfo->m_VFlushBinning); + printf("HFlushDisable = %u\n",m_ApnSensorInfo->m_HFlushDisable); + printf("ShutterCloseDelay = %u\n",m_ApnSensorInfo->m_ShutterCloseDelay); + printf("PixelSizeX = %lf\n",m_ApnSensorInfo->m_PixelSizeX); + printf("PixelSizeY = %lf\n",m_ApnSensorInfo->m_PixelSizeY); + printf("Color = %u\n",m_ApnSensorInfo->m_Color); +// printf("ReportedGainTwelveBit = %lf\n",m_ApnSensorInfo->m_ReportedGainTwelveBit); + printf("ReportedGainSixteenBit = %lf\n",m_ApnSensorInfo->m_ReportedGainSixteenBit); + printf("MinSuggestedExpTime = %lf\n",m_ApnSensorInfo->m_MinSuggestedExpTime); + printf("CoolingSupported = %u\n",m_ApnSensorInfo->m_CoolingSupported); + printf("RegulatedCoolingSupported = %u\n",m_ApnSensorInfo->m_RegulatedCoolingSupported); + printf("TempSetPoint = %lf\n",m_ApnSensorInfo->m_TempSetPoint); +// printf("TempRegRate = %u\n",m_ApnSensorInfo->m_TempRegRate); + printf("TempRampRateOne = %u\n",m_ApnSensorInfo->m_TempRampRateOne); + printf("TempRampRateTwo = %u\n",m_ApnSensorInfo->m_TempRampRateTwo); + printf("TempBackoffPoint = %lf\n",m_ApnSensorInfo->m_TempBackoffPoint); + printf("DefaultGainTwelveBit = %u\n",m_ApnSensorInfo->m_DefaultGainTwelveBit); + printf("DefaultOffsetTwelveBit = %u\n",m_ApnSensorInfo->m_DefaultOffsetTwelveBit); + printf("DefaultRVoltage = %u\n",m_ApnSensorInfo->m_DefaultRVoltage); + + + + printf ("RoiPixelsH is %u\n",m_RoiPixelsH); + printf ("RoiPixelsV is %u\n",m_RoiPixelsV); + + + // Issue a clear command, so the registers are zeroed out + // This will put the camera in a known state for us. + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_CLEAR_ALL ); + + // Reset the camera + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); + + // Load Inversion Masks + Write( FPGA_REG_VRAM_INV_MASK, m_ApnSensorInfo->m_VerticalPattern.Mask ); + Write( FPGA_REG_HRAM_INV_MASK, m_ApnSensorInfo->m_RoiPatternSixteen.Mask ); + + // Load Pattern Files + LoadVerticalPattern(); + LoadClampPattern(); + LoadSkipPattern(); + LoadRoiPattern( m_RoiBinningH ); + + // Program default camera settings + Write( FPGA_REG_CLAMP_COUNT, m_ApnSensorInfo->m_ClampColumns ); + Write( FPGA_REG_PREROI_SKIP_COUNT, m_ApnSensorInfo->m_PreRoiSkipColumns ); + Write( FPGA_REG_ROI_COUNT, m_ApnSensorInfo->m_ImagingColumns ); + Write( FPGA_REG_POSTROI_SKIP_COUNT, m_ApnSensorInfo->m_PostRoiSkipColumns + + m_ApnSensorInfo->m_OverscanColumns ); + + // Since the default state of m_DigitizeOverscan is false, set the count to zero. + Write( FPGA_REG_OVERSCAN_COUNT, 0x0 ); + + // Now calculate the vertical settings + UnbinnedRoiY = m_RoiPixelsV * m_RoiBinningV; + + PreRoiRows = m_ApnSensorInfo->m_UnderscanRows + + m_RoiStartY; + + PostRoiRows = m_ApnSensorInfo->m_TotalRows - + PreRoiRows - + UnbinnedRoiY; + + PreRoiVBinning = 1; + PostRoiVBinning = 1; + + // For interline CCDs, set "Fast Dump" mode if the particular array is NOT digitized + if ( m_ApnSensorInfo->m_InterlineCCD ) + { + // use the fast dump feature to get rid of the data quickly. + // one row, binning to the original row count + // note that we only are not digitized in arrays 1 and 3 + PreRoiVBinning = PreRoiRows; + PostRoiVBinning = PostRoiRows; + + PreRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; + PostRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; + + PreRoiRows = 1; + PostRoiRows = 1; + } + + // Program the vertical settings + Write( FPGA_REG_A1_ROW_COUNT, PreRoiRows ); + Write( FPGA_REG_A1_VBINNING, PreRoiVBinning ); + + Write( FPGA_REG_A2_ROW_COUNT, m_RoiPixelsV ); + Write( FPGA_REG_A2_VBINNING, (m_RoiBinningV | FPGA_BIT_ARRAY_DIGITIZE) ); + + Write( FPGA_REG_A3_ROW_COUNT, PostRoiRows ); + Write( FPGA_REG_A3_VBINNING, PostRoiVBinning ); + + Write( FPGA_REG_VFLUSH_BINNING, m_ApnSensorInfo->m_VFlushBinning ); + + double CloseDelay = (double)m_ApnSensorInfo->m_ShutterCloseDelay / 1000; + ShutterDelay = (unsigned short) + ( (CloseDelay - APN_SHUTTER_CLOSE_DIFF) / APN_TIMER_RESOLUTION ); + + Write( FPGA_REG_SHUTTER_CLOSE_DELAY, ShutterDelay ); + + Write( FPGA_REG_IMAGE_COUNT, 1 ); + Write( FPGA_REG_SEQUENCE_DELAY, 0 ); + + if ( m_ApnSensorInfo->m_HFlushDisable ) + { + Read( FPGA_REG_OP_A, RegVal ); + + RegVal |= FPGA_BIT_DISABLE_H_CLK; + + Write( FPGA_REG_OP_A, RegVal ); + } + + // Reset the camera again + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); + + // Start flushing + Write( FPGA_REG_COMMAND_A, FPGA_BIT_CMD_FLUSH ); + + // If we are a USB2 camera, set all the 12bit variables for the 12bit + // A/D processor + if ( m_CameraInterface == Apn_Interface_USB ) + { + InitTwelveBitAD(); + write_TwelveBitGain( m_ApnSensorInfo->m_DefaultGainTwelveBit ); + WriteTwelveBitOffset(); + } + + // Set the Fan State. Setting the private var first to make sure the write_FanMode + // call thinks we're doing a state transition. + // On write_FanMode return, our state will be Apn_FanMode_Medium + m_pvtFanMode = Apn_FanMode_Off; // we're going to set this + write_FanMode( Apn_FanMode_Medium ); + + // Initialize the LED states and the LED mode. There is nothing to output + // to the device since we issued our CLEAR early in the init() process, and + // we are now in a known state. + m_pvtLedStateA = Apn_LedState_Expose; + m_pvtLedStateB = Apn_LedState_Expose; + m_pvtLedMode = Apn_LedMode_EnableAll; + + // Default value for test LED is 0% + m_pvtTestLedBrightness = 0.0; + + // Program our initial cooler values. The only cooler value that we reset + // at init time is the backoff point. Everything else is left untouched, and + // state information is determined from the camera controller. + m_pvtCoolerBackoffPoint = m_ApnSensorInfo->m_TempBackoffPoint; + write_CoolerBackoffPoint( m_pvtCoolerBackoffPoint ); + Write( FPGA_REG_TEMP_RAMP_DOWN_A, m_ApnSensorInfo->m_TempRampRateOne ); + Write( FPGA_REG_TEMP_RAMP_DOWN_B, m_ApnSensorInfo->m_TempRampRateTwo ); + // the collor code not only determines the m_pvtCoolerEnable state, but + // also implicitly calls UpdateGeneralStatus() as part of read_CoolerStatus() + if ( read_CoolerStatus() == Apn_CoolerStatus_Off ) + m_pvtCoolerEnable = false; + else + m_pvtCoolerEnable = true; + + m_pvtImageInProgress = false; + m_pvtImageReady = false; + + return 0; +} + +long CApnCamera::InitTwelveBitAD() +{ + Write( FPGA_REG_AD_CONFIG_DATA, 0x0028 ); + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_AD_CONFIG ); + + return 0; +} + +long CApnCamera::WriteTwelveBitOffset() +{ + unsigned short NewVal; + unsigned short StartVal; + unsigned short FirstBit; + + + NewVal = 0x0; + StartVal = m_ApnSensorInfo->m_DefaultOffsetTwelveBit & 0xFF; + + for ( int i=0; i<8; i++ ) + { + FirstBit = ( StartVal & 0x0001 ); + NewVal |= ( FirstBit << (10-i) ); + StartVal = StartVal >> 1; + } + + NewVal |= 0x2000; + + Write( FPGA_REG_AD_CONFIG_DATA, NewVal ); + Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_AD_CONFIG ); + + return 0; +} + +void CApnCamera::UpdateGeneralStatus() +{ + unsigned short StatusReg; + unsigned short HeatsinkTempReg; + unsigned short CcdTempReg; + unsigned short CoolerDriveReg; + unsigned short VoltageReg; + unsigned short TdiCounterReg; + unsigned short SequenceCounterReg; + + + + // Read the general status register of the device + QueryStatusRegs( StatusReg, + HeatsinkTempReg, + CcdTempReg, + CoolerDriveReg, + VoltageReg, + TdiCounterReg, + SequenceCounterReg ); + + m_pvtStatusReg = StatusReg; + + HeatsinkTempReg &= FPGA_MASK_TEMP_PARAMS; + CcdTempReg &= FPGA_MASK_TEMP_PARAMS; + CoolerDriveReg &= FPGA_MASK_TEMP_PARAMS; + VoltageReg &= FPGA_MASK_INPUT_VOLTAGE; + + if ( CoolerDriveReg > 3200 ) + m_pvtCoolerDrive = 100.0; + else + m_pvtCoolerDrive = ( (double)(CoolerDriveReg - 600) / 2600.0 ) * 100.0; + + m_pvtCurrentCcdTemp = ( (CcdTempReg - APN_TEMP_SETPOINT_ZERO_POINT) + * APN_TEMP_DEGREES_PER_BIT ); + + m_pvtCurrentHeatsinkTemp = ( (HeatsinkTempReg - APN_TEMP_HEATSINK_ZERO_POINT) + * APN_TEMP_DEGREES_PER_BIT ); + + m_pvtInputVoltage = VoltageReg * APN_VOLTAGE_RESOLUTION; + + // Update ShutterState + m_pvtShutterState = ( (m_pvtStatusReg & FPGA_BIT_STATUS_SHUTTER_OPEN) != 0 ); +} + + +bool CApnCamera::ImageReady() +{ + return m_pvtImageReady; +} + + +void CApnCamera::SignalImagingDone() +{ + m_pvtImageInProgress = false; +} + + + + + |