CApnCamera::CApnCamera()
{
AltaDebugOutputString( "APOGEE.DLL - CApnCamera::CApnCamera()" );
m_pvtPlatformType = Apn_Platform_Unknown;
m_ApnSensorInfo = NULL;
}
CApnCamera::~CApnCamera()
{
AltaDebugOutputString( "APOGEE.DLL - CApnCamera::~CApnCamera()" );
if ( m_ApnSensorInfo != NULL )
{
delete m_ApnSensorInfo;
m_ApnSensorInfo = NULL;
CloseDriver();
}
}
bool CApnCamera::Expose( double Duration, bool Light )
{
unsigned long ExpTime;
unsigned short BitsPerPixel;
unsigned short UnbinnedRoiX;
unsigned short UnbinnedRoiY;
unsigned short PreRoiSkip, PostRoiSkip;
unsigned short PreRoiRows, PostRoiRows;
unsigned short PreRoiVBinning, PostRoiVBinning;
unsigned short RegVal;
unsigned short RoiRegBuffer[15];
unsigned short RoiRegData[15];
unsigned short TotalHPixels;
unsigned short TotalVPixels;
unsigned long TestImageSize;
unsigned long WaitCounter;
char szOutputText[128];
UnbinnedRoiY = m_pvtRoiPixelsV * m_pvtRoiBinningV;
PreRoiRows = m_ApnSensorInfo->m_UnderscanRows +
m_pvtRoiStartY;
PostRoiRows = m_ApnSensorInfo->m_TotalRows -
PreRoiRows -
UnbinnedRoiY;
TotalVPixels = UnbinnedRoiY + PreRoiRows + PostRoiRows;
// 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_pvtDataBits == Apn_Resolution_SixteenBit )
{
RoiRegData[2] = m_pvtExposurePixelsH + 1;
}
else if ( m_pvtDataBits == Apn_Resolution_TwelveBit )
{
RoiRegData[2] = m_pvtExposurePixelsH + 12;
}
RoiRegBuffer[3] = FPGA_REG_POSTROI_SKIP_COUNT;
RoiRegData[3] = PostRoiSkip;
// Program the vertical settings
if ( m_pvtFirmwareVersion < 11 )
{
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_pvtRoiPixelsV;
RoiRegBuffer[7] = FPGA_REG_A2_VBINNING;
RoiRegData[7] = (m_pvtRoiBinningV | FPGA_BIT_ARRAY_DIGITIZE);
RoiRegBuffer[8] = FPGA_REG_A3_ROW_COUNT;
RoiRegData[8] = PostRoiRows;
RoiRegBuffer[9] = FPGA_REG_A3_VBINNING;
RoiRegData[9] = PostRoiVBinning;
RoiRegBuffer[10] = FPGA_REG_SCRATCH;
RoiRegData[10] = 0;
RoiRegBuffer[11] = FPGA_REG_SCRATCH;
RoiRegData[11] = 0;
RoiRegBuffer[12] = FPGA_REG_SCRATCH;
RoiRegData[12] = 0;
RoiRegBuffer[13] = FPGA_REG_SCRATCH;
RoiRegData[13] = 0;
}
else
{
if ( m_ApnSensorInfo->m_EnableSingleRowOffset )
{
RoiRegBuffer[4] = FPGA_REG_A1_ROW_COUNT;
RoiRegData[4] = 0;
RoiRegBuffer[5] = FPGA_REG_A1_VBINNING;
RoiRegData[5] = 0;
RoiRegBuffer[6] = FPGA_REG_A2_ROW_COUNT;
RoiRegData[6] = PreRoiRows;
RoiRegBuffer[7] = FPGA_REG_A2_VBINNING;
RoiRegData[7] = PreRoiVBinning;
RoiRegBuffer[8] = FPGA_REG_A3_ROW_COUNT;
RoiRegData[8] = m_pvtRoiPixelsV;
RoiRegBuffer[9] = FPGA_REG_A3_VBINNING;
RoiRegData[9] = (m_pvtRoiBinningV | FPGA_BIT_ARRAY_DIGITIZE);
RoiRegBuffer[10] = FPGA_REG_A4_ROW_COUNT;
RoiRegData[10] = 0;
RoiRegBuffer[11] = FPGA_REG_A4_VBINNING;
RoiRegData[11] = 0;
RoiRegBuffer[12] = FPGA_REG_A5_ROW_COUNT;
RoiRegData[12] = PostRoiRows;
RoiRegBuffer[13] = FPGA_REG_A5_VBINNING;
RoiRegData[13] = PostRoiVBinning;
}
else
{
if ( PreRoiRows > 70 )
{
RoiRegBuffer[4] = FPGA_REG_A1_ROW_COUNT;
RoiRegData[4] = 1;
RoiRegBuffer[5] = FPGA_REG_A1_VBINNING;
RoiRegData[5] = (PreRoiRows-70);
RoiRegBuffer[6] = FPGA_REG_A2_ROW_COUNT;
RoiRegData[6] = 70;
RoiRegBuffer[7] = FPGA_REG_A2_VBINNING;
RoiRegData[7] = 1;
}
else
{
RoiRegBuffer[4] = FPGA_REG_A1_ROW_COUNT;
RoiRegData[4] = 0;
RoiRegBuffer[5] = FPGA_REG_A1_VBINNING;
RoiRegData[5] = 0;
RoiRegBuffer[6] = FPGA_REG_A2_ROW_COUNT;
RoiRegData[6] = PreRoiRows;
RoiRegBuffer[7] = FPGA_REG_A2_VBINNING;
RoiRegData[7] = PreRoiVBinning;
}
RoiRegBuffer[8] = FPGA_REG_A3_ROW_COUNT;
RoiRegData[8] = m_pvtRoiPixelsV;
RoiRegBuffer[9] = FPGA_REG_A3_VBINNING;
RoiRegData[9] = (m_pvtRoiBinningV | FPGA_BIT_ARRAY_DIGITIZE);
if ( PostRoiRows > 70 )
{
RoiRegBuffer[10] = FPGA_REG_A4_ROW_COUNT;
RoiRegData[10] = 1;
RoiRegBuffer[11] = FPGA_REG_A4_VBINNING;
RoiRegData[11] = (PostRoiRows-70);
RoiRegBuffer[12] = FPGA_REG_A5_ROW_COUNT;
RoiRegData[12] = 70;
RoiRegBuffer[13] = FPGA_REG_A5_VBINNING;
RoiRegData[13] = 1;
}
else
{
RoiRegBuffer[10] = FPGA_REG_A4_ROW_COUNT;
RoiRegData[10] = 0;
RoiRegBuffer[11] = FPGA_REG_A4_VBINNING;
RoiRegData[11] = 0;
RoiRegBuffer[12] = FPGA_REG_A5_ROW_COUNT;
RoiRegData[12] = PostRoiRows;
RoiRegBuffer[13] = FPGA_REG_A5_VBINNING;
RoiRegData[13] = PostRoiVBinning;
}
}
}
// Issue the reset
RoiRegBuffer[14] = FPGA_REG_COMMAND_B;
RoiRegData[14] = FPGA_BIT_CMD_RESET;
// Send the instruction sequence to the camera
AltaDebugOutputString( "APOGEE.DLL - CApnCamera::Expose() -> Issue WriteMultiMRMD() for Exposure setup" );
WriteMultiMRMD( RoiRegBuffer, RoiRegData, 15 );
// Handle the IR PreFlash, if enabled
if ( m_pvtPreFlashEnable )
{
double strobeVal = read_ShutterStrobePosition();
double preflashVal = m_ApnSensorInfo->m_IRPreflashTime / 1000;
// v22 only
preflashVal = 110/1000;
write_ShutterStrobePosition( preflashVal );
// set the preflash bit
Read( FPGA_REG_OP_B, RegVal );
RegVal |= FPGA_BIT_IR_PREFLASH_ENABLE;
Write( FPGA_REG_OP_B, RegVal );
// dark frame duration is based on our sensor's specified preflash time
TakeNoDataDarkExposure( preflashVal + 0.050 );
// set the preflash bit back to zero
Read( FPGA_REG_OP_B, RegVal );
RegVal &= ~FPGA_BIT_IR_PREFLASH_ENABLE;
Write( FPGA_REG_OP_B, RegVal );
// set our shutter strobe back
write_ShutterStrobePosition( strobeVal );
// Re-calculate the exposure time to program to the camera
ExpTime = ((unsigned long)(Duration / m_PlatformTimerResolution)) + m_PlatformTimerOffsetCount;
// reprogram the timer
Write( FPGA_REG_TIMER_LOWER, (unsigned short)(ExpTime & 0xFFFF));
ExpTime = ExpTime >> 16;
Write( FPGA_REG_TIMER_UPPER, (unsigned short)(ExpTime & 0xFFFF));
ResetSystemNoFlush();
// Send the instruction sequence to the camera
AltaDebugOutputString( "APOGEE.DLL - CApnCamera::Expose() -> Issue WriteMultiMRMD() for Exposure setup" );
WriteMultiMRMD( RoiRegBuffer, RoiRegData, 15 );
}
// Issue the flush for interlines, or if using the external shutter
if ( (m_ApnSensorInfo->m_InterlineCCD && m_pvtFastSequence) ||
(m_pvtExternalShutter) ||
(m_pvtTriggerNormalGroup) || (m_pvtTriggerTdiKineticsGroup) )
{
// Make absolutely certain that flushing starts first
// in order to use Progressive Scan/Ratio Mode
Write( FPGA_REG_COMMAND_A, FPGA_BIT_CMD_FLUSH );
for ( int i=0; i<2; i++ )
{
Write( FPGA_REG_SCRATCH, 0x8086 );
Write( FPGA_REG_SCRATCH, 0x8088 );
}
}
m_pvtExposureExternalShutter = m_pvtExternalShutter;
IssueExposeCommand( Light );
// Set our flags to mark the start of a new exposure
m_pvtImageInProgress = true;
m_pvtImageReady = false;
// Debug output for leaving this function
sprintf( szOutputText, "APOGEE.DLL - CApnCamera::Expose( Duration = %f, Light = %d ) -> END", Duration, Light );
AltaDebugOutputString( szOutputText );
return true;
}
Bookmarks