• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kstars

CameraIO_Linux.cpp

Go to the documentation of this file.
00001 // CameraIO.cpp: implementation of the CCameraIO class.
00002 //
00003 // Copyright (c) 2000 Apogee Instruments Inc.
00005 
00006 #include <assert.h>
00007 #include <sys/time.h>
00008 #include <sys/resource.h>
00009 #include <sys/ioctl.h>
00010 #include <sys/types.h>
00011 #include <sys/stat.h>
00012 #include <string.h>
00013 #include <sched.h>
00014 #include <unistd.h>
00015 #include <fcntl.h>
00016 #define HANDLE int
00017 #define FALSE 0
00018 #define DWORD long
00019 #define _ASSERT assert
00020 #define REALTIME_PRIORITY_CLASS 1  
00021 #define GetCurrentProcess getpid
00022 #define LOBYTE(x) ((x) & 0xff)
00023 #define HIBYTE(x) ((x >> 8) & 0xff)
00024 
00025 #define MIRQ1   0x21
00026 #define MIRQ2   0xA1
00027 
00028 #include "time.h"
00029 //#include "tcl.h"
00030 //#include "ccd.h"
00031 #include "CameraIO_Linux.h"
00032 #include "ApogeeLinux.h"
00033 
00034 const int NUM_POSITIONS = 6;
00035 const int NUM_STEPS_PER_FILTER = 48;
00036 const int STEP_DELAY = 10;
00037 
00038 const unsigned char Steps[] = { 0x10, 0x30, 0x20, 0x60, 0x40, 0xc0, 0x80, 0x90 };
00039 const int NUM_STEPS = sizeof ( Steps );
00040 
00042 // Construction/Destruction
00044 
00045 CCameraIO::CCameraIO()
00046 {
00047     InitDefaults();
00048 
00049     m_TDI = false;
00050 
00051     m_Shutter = false;
00052     m_FilterPosition = 0;
00053     m_FilterStepPos = 0;
00054 
00055     m_WaitingforImage = false;
00056     m_WaitingforLine = false;
00057 
00058     m_WaitingforTrigger = false;
00059     m_Status = Camera_Status_Idle;
00060     m_CoolerStatus = Camera_CoolerStatus_Off;   
00061 
00062     m_ExposureBinX = 0;
00063     m_ExposureBinY = 0;     
00064     m_ExposureStartX = 0;
00065     m_ExposureStartY = 0;
00066     m_ExposureNumX = 0;
00067     m_ExposureNumY = 0; 
00068     m_ExposureColumns = 0; 
00069     m_ExposureRows = 0;
00070     m_ExposureSkipC = 0;
00071     m_ExposureSkipR = 0;    
00072     m_ExposureHFlush = 0;
00073     m_ExposureVFlush = 0;
00074     m_ExposureBIC = 0;
00075     m_ExposureBIR = 0;      
00076     m_ExposureAIC = 0;                  
00077     m_ExposureRemainingLines = 0;
00078     m_ExposureAIR = 0;                  
00079 
00080     m_RegShadow[ Reg_Command ] = 0;
00081     m_RegShadow[ Reg_Timer ] = 0;
00082     m_RegShadow[ Reg_VBinning ] = 0;
00083     m_RegShadow[ Reg_AICCounter ] = 0;
00084     m_RegShadow[ Reg_TempSetPoint ] = 0;
00085     m_RegShadow[ Reg_PixelCounter ] = 0;
00086     m_RegShadow[ Reg_LineCounter ] = 0;
00087     m_RegShadow[ Reg_BICCounter ] = 0;
00088 
00089     m_FastShutterBits_Mode = 0;
00090     m_FastShutterBits_Test = 0;
00091         m_IRQMask = 0;
00092         saveIRQS = 0;
00093 
00094 }
00095 
00096 CCameraIO::~CCameraIO()
00097 {
00098 
00099   //::close(fileHandle);
00100   close(fileHandle);
00101 }
00102 
00104 // System methods
00105 
00106 int  GetPriorityClass ( HANDLE /*hProcess*/ )
00107 {
00108     int i;
00109     i = sched_getscheduler(0);
00110     return(i);
00111 }
00112 
00113 int  SetPriorityClass ( HANDLE /*hProcess*/, int hPriority)
00114 {
00115     int i;
00116     sched_param p;
00117 
00118     if (hPriority) {
00119        i = sched_setscheduler(0,SCHED_RR,&p);
00120     } else {
00121        i = sched_setscheduler(0,SCHED_OTHER,&p);
00122     }
00123     return(i);
00124 }
00125 
00126 void Sleep (int hTime)
00127 {
00128     timespec t;
00129     t.tv_sec= 0;
00130     t.tv_nsec = hTime*1000000;
00131 //    nanosleep(&t);
00132 }
00133 
00134 
00135 
00136 void ATLTRACE (char * /*msg*/)
00137 {
00138 }
00139 
00140 
00141 void CCameraIO::Reset()
00142 {
00143     unsigned short val = 0;
00144     Read( Reg_CommandReadback, val );   // Take snapshot of currrent status
00145     m_RegShadow[ Reg_Command ] = val;   // remember it in our write shadow
00146     
00147     // In case these were left on, turn them off
00148     m_RegShadow[ Reg_Command ] &= ~RegBit_FIFOCache;    // set bit to 0
00149     m_RegShadow[ Reg_Command ] &= ~RegBit_TDIMode;      // set bit to 0
00150 
00151     m_RegShadow[ Reg_Command ] |= RegBit_ResetSystem;   // set bit to 1
00152     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00153     
00154     m_RegShadow[ Reg_Command ] &= ~RegBit_ResetSystem;  // set bit to 0
00155     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00156 
00157     m_WaitingforImage = false;
00158     m_WaitingforLine = false;
00159     m_WaitingforTrigger = false;
00160 }
00161 
00162 void CCameraIO::AuxOutput( unsigned char val )
00163 {   
00164     // clear bits to 0
00165     m_RegShadow[ Reg_TempSetPoint ] &= ~( RegBitMask_PortControl << RegBitShift_PortControl );
00166     
00167     // set our new bits
00168     m_RegShadow[ Reg_TempSetPoint ] |= val << RegBitShift_PortControl;
00169     
00170     Write( Reg_TempSetPoint, m_RegShadow[ Reg_TempSetPoint ] );
00171 }
00172 
00173 // Input reg is from 0 to 7, val is any 16 bit number
00174 void CCameraIO::RegWrite( short reg, unsigned short val )
00175 {
00176     Write( reg, val );
00177     
00178     // Update our shadow register
00179     switch ( reg )
00180     {
00181     case Reg_Command:
00182         m_RegShadow[ Reg_Command ] = val;
00183         break;
00184     case Reg_Timer:
00185         m_RegShadow[ Reg_Timer ] = val;
00186         break;
00187     case Reg_VBinning:
00188         m_RegShadow[ Reg_VBinning ] = val;
00189         break;
00190     case Reg_AICCounter:
00191         m_RegShadow[ Reg_AICCounter ] = val;
00192         break;
00193     case Reg_TempSetPoint:
00194         m_RegShadow[ Reg_TempSetPoint ] = val;
00195         break;
00196     case Reg_PixelCounter:
00197         m_RegShadow[ Reg_PixelCounter ] = val;
00198         break;
00199     case Reg_LineCounter:
00200         m_RegShadow[ Reg_LineCounter ] = val;
00201         break;
00202     case Reg_BICCounter:
00203         m_RegShadow[ Reg_BICCounter ] = val;
00204         break;
00205     default:
00206         _ASSERT( FALSE );   // application program bug
00207     }
00208 }
00209 
00210 // Input reg is from 8 to 12, returned val is any 16 bit number
00211 void CCameraIO::RegRead( short reg, unsigned short& val )
00212 {
00213     Read( reg, val );
00214 }
00215 
00216 bool CCameraIO::FilterHome()
00217 {
00218     HANDLE hProcess(0);
00219     DWORD Class(0);
00220 
00221     if ( m_HighPriority )
00222     {   // Store current process class and priority
00223         hProcess = GetCurrentProcess();
00224         Class = GetPriorityClass ( hProcess );
00225         SetPriorityClass ( hProcess, REALTIME_PRIORITY_CLASS );
00226     }
00227 
00228     // Find the home position
00229     m_FilterPosition = 0;
00230     int Safety = 0;
00231     for (int I = 0; I < NUM_POSITIONS * NUM_STEPS_PER_FILTER * 2; I++)
00232     {
00233         // Advance the filter one step
00234         m_FilterStepPos += 1;
00235         if (m_FilterStepPos >= NUM_STEPS) m_FilterStepPos = 0;
00236         unsigned char Step = Steps[ m_FilterStepPos ];
00237                 
00238         AuxOutput( Step );
00239         Sleep ( STEP_DELAY );
00240 
00241         // Check for strobe
00242         unsigned short val = 0;
00243         Read( Reg_Status, val );
00244         if ( val & RegBit_GotTrigger )
00245         {
00246             // Cycle all the way around if it's on the first time
00247             if (I < NUM_STEPS_PER_FILTER) 
00248             {
00249                 if (++Safety > NUM_STEPS_PER_FILTER * 2) 
00250                 {
00251                     // Restore normal priority
00252                     if ( m_HighPriority ) SetPriorityClass ( hProcess, Class );
00253                     return false;
00254                 }
00255                 I = 0;
00256                 continue;
00257             }
00258 
00259             // Continue cycling until we get clear of the opto mirror
00260             for (int J = 0; J < NUM_STEPS_PER_FILTER; J++)
00261             {
00262                 // Advance the filter one step
00263                 m_FilterStepPos += 1;
00264                 if (m_FilterStepPos >= NUM_STEPS) m_FilterStepPos = 0;
00265                 unsigned char Step = Steps[ m_FilterStepPos ];
00266                 
00267                 AuxOutput( Step );
00268                 Sleep ( STEP_DELAY );
00269 
00270                 val = 0;
00271                 Read( Reg_Status, val );
00272                 if ( val & RegBit_GotTrigger )
00273                 {
00274                     Sleep ( 10 );
00275                     
00276                     val = 0;
00277                     Read( Reg_Status, val );
00278                     if ( val & RegBit_GotTrigger )
00279                     {
00280                         // Restore normal priority
00281                         if ( m_HighPriority ) SetPriorityClass ( hProcess, Class );
00282                         return true;
00283                     }
00284                 }
00285             }
00286 
00287             // Restore normal priority
00288             if ( m_HighPriority ) SetPriorityClass ( hProcess, Class );
00289             return true;
00290         }
00291     }
00292 
00293     // Restore normal priority
00294     if ( m_HighPriority ) SetPriorityClass ( hProcess, Class );
00295     return false;
00296 }
00297 
00298 void CCameraIO::FilterSet( short Slot )
00299 {
00300     // Determine how far we have to move
00301     int Pos = Slot - m_FilterPosition;
00302     if (Pos < 0) Pos += NUM_POSITIONS;
00303 
00304     HANDLE hProcess(0);
00305     DWORD Class(0);
00306 
00307     if ( m_HighPriority )
00308     {   // Store current process class and priority
00309         hProcess = GetCurrentProcess();
00310         Class = GetPriorityClass ( hProcess );
00311         SetPriorityClass ( hProcess, REALTIME_PRIORITY_CLASS );
00312     }
00313 
00314     for (int I = 0; I < Pos; I++)
00315     {
00316         // Advance one position
00317         for (int J = 0; J < NUM_STEPS_PER_FILTER; J++)
00318         {
00319             m_FilterStepPos += 1;
00320             if (m_FilterStepPos >= NUM_STEPS) m_FilterStepPos = 0;
00321             unsigned char Step = Steps[ m_FilterStepPos ];
00322         
00323             AuxOutput( Step );
00324             Sleep ( STEP_DELAY );
00325         }
00326     }
00327 
00328     if ( m_HighPriority ) SetPriorityClass ( hProcess, Class );
00329 
00330     m_FilterPosition = Slot;
00331 }
00332 
00334 // Normal exposure methods
00335 
00336 bool CCameraIO::Expose( double Duration, bool Light )
00337 {
00338     if ( !m_TDI && ( Duration < m_MinExposure || Duration > m_MaxExposure ) ) return false;
00339 
00340     // Validate all input variables
00341     if ( m_Columns < 1 || m_Columns > MAXCOLUMNS ) return false;
00342     m_ExposureColumns = m_Columns; 
00343     
00344     if ( m_Rows < 1 || m_Rows > MAXROWS ) return false;
00345     m_ExposureRows = m_Rows;
00346     
00347     if ( m_SkipC < 0 ) return false;
00348     m_ExposureSkipC = m_SkipC;
00349     
00350     if ( m_SkipR < 0 ) return false;
00351     m_ExposureSkipR = m_SkipR;  
00352     
00353     if ( m_HFlush < 1 || m_HFlush > MAXHBIN ) return false;
00354     m_ExposureHFlush = m_HFlush;
00355     
00356     if ( m_VFlush < 1 || m_VFlush > MAXVBIN ) return false;
00357     m_ExposureVFlush = m_VFlush;
00358 
00359     if ( m_BIC < 1 || m_BIC > MAXCOLUMNS ) return false;
00360     m_ExposureBIC = m_BIC;
00361     
00362     if ( m_BIR < 1 || m_BIR > MAXROWS ) return false;
00363     m_ExposureBIR = m_BIR;      
00364 
00365     // Validate all input variables
00366     if ( m_BinX < 1 || m_BinX > MAXHBIN ) return false;
00367     m_ExposureBinX = m_BinX;
00368 
00369     if ( m_StartX < 0 || m_StartX >= MAXCOLUMNS ) return false;
00370     m_ExposureStartX = m_StartX;
00371 
00372     if ( m_NumX < 1 || m_NumX * m_BinX > m_ImgColumns ) return false;
00373     m_ExposureNumX = m_NumX;
00374 
00375     // Calculate BIC, RawPixelCount, AIC
00376     unsigned short BIC = m_ExposureBIC + m_ExposureStartX;      // unbinned columns
00377     unsigned short RawPixelCount = m_ExposureNumX * m_ExposureBinX;
00378     m_ExposureAIC = m_ExposureColumns - BIC - RawPixelCount;    // unbinned columns
00379 
00380     if ( m_BinY < 1 || m_BinY > MAXVBIN ) return false;
00381     m_ExposureBinY = m_BinY;        
00382         
00383     unsigned short VBin(0), row_offset(0);
00384 
00385     if ( m_TDI )
00386     {   // row_offset is the drift time in milliseconds when in TDI mode
00387         row_offset = (unsigned short) (Duration * 1000 + 0.5);
00388         Duration = 0.0;
00389     }
00390     else
00391     {
00392         if ( m_StartY < 0 || m_StartX >= MAXROWS ) return false;
00393         m_ExposureStartY = m_StartY;
00394             
00395         if ( m_NumY < 1 || m_NumY * m_BinY > m_ImgRows ) return false;
00396         m_ExposureNumY = m_NumY;    
00397 
00398         unsigned short BIR = m_ExposureBIR + m_ExposureStartY;      // unbinned rows
00399         if ( BIR >= MAXROWS ) return false;
00400         m_ExposureAIR = m_ExposureRows - BIR - m_ExposureNumY * m_ExposureBinY; // unbinned rows
00401 
00402         if ( m_VFlush > BIR )
00403         {
00404             VBin = BIR;
00405             m_ExposureRemainingLines = 0;
00406         }
00407         else
00408         {
00409             VBin = m_VFlush;
00410             m_ExposureRemainingLines = BIR % VBin;  // unbinned rows
00411         }
00412         row_offset = BIR - m_ExposureRemainingLines; // unbinned rows
00413     }   
00414     
00415     StopFlushing();
00416     Reset();
00417 
00418     LoadColumnLayout( m_ExposureAIC, BIC, (unsigned short) m_ExposureNumX + m_ExposureSkipC );
00419     LoadTimerAndBinning( Duration, (unsigned short) m_ExposureHFlush, VBin );
00420     LoadLineCounter( row_offset );
00421 
00422     if ( m_TDI )
00423     {
00424         // Turn on TDI
00425         m_RegShadow[ Reg_Command ] |= RegBit_TDIMode;       // set bit to 1
00426         
00427         // Disable FIFO cache
00428         m_RegShadow[ Reg_Command ] &= ~RegBit_FIFOCache;    // set bit to 0
00429 
00430         // Set shutter override
00431         if ( Light )
00432             m_RegShadow[ Reg_Command ] |= RegBit_ShutterOverride;       // set bit to 1
00433         else
00434             m_RegShadow[ Reg_Command ] &= ~RegBit_ShutterOverride;      // set bit to 0
00435 
00436         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00437         
00438         // Update our status
00439         m_Shutter = Light;
00440         m_WaitingforTrigger = false;
00441         m_WaitingforLine = false;
00442     }
00443     else
00444     {
00445         // Set shutter
00446         if ( Light )
00447             m_RegShadow[ Reg_Command ] |= RegBit_ShutterEnable;     // set bit to 1
00448         else
00449             m_RegShadow[ Reg_Command ] &= ~RegBit_ShutterEnable;    // set bit to 0
00450 
00451         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00452 
00453         // Update our status
00454         unsigned short val = 0;
00455         Read( Reg_CommandReadback, val );
00456         if ( val & RegBit_ShutterOverride )
00457             m_Shutter = true;
00458         else
00459             m_Shutter = Light;
00460 
00461         if ( ( val & RegBit_TriggerEnable ) )
00462             m_WaitingforTrigger = true;
00463         else
00464             m_WaitingforTrigger = false;
00465 
00466         // Start the exposure
00467         m_RegShadow[ Reg_Command ] |= RegBit_StartTimer;    // set bit to 1
00468         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00469         
00470         m_RegShadow[ Reg_Command ] &= ~RegBit_StartTimer;   // set bit to 0
00471         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00472     
00473         m_WaitingforImage = true;
00474     }
00475 
00476     return true;
00477 }
00478 
00479 /*bool CCameraIO::BufferImage(char *bufferName )
00480 {
00481     unsigned short *pImageData;
00482     bool status; 
00483     short cols,rows,hbin,vbin;
00484     short xSize, ySize;
00485 
00486     cols = m_NumX*m_BinX;
00487     rows = m_NumY*m_BinY;
00488     hbin = m_BinX;
00489     vbin = m_BinY;
00490 
00491     pImageData = (unsigned short *)CCD_locate_buffer(bufferName, 2 , cols, rows, hbin, vbin );
00492     if (pImageData == NULL) {
00493        return 0;
00494     }
00495     
00496     status = GetImage(pImageData, xSize, ySize);
00497     return status;
00498 }*/
00499 
00500 bool CCameraIO::GetImage( unsigned short* pImageData, short& xSize, short& ySize )
00501 {
00502         int i;
00503     unsigned short BIC = m_ExposureBIC + m_ExposureStartX;
00504 
00505     // Update internal variables in case application did not poll read_Status
00506     m_WaitingforTrigger = false;
00507     m_WaitingforLine = false;
00508 
00509     if ( m_WaitingforImage )
00510     {   // In case application did not poll read_Status
00511         m_WaitingforImage = false;
00512 
00514         // Wait until camera is done flushing
00515         clock_t StopTime = clock() + long( m_Timeout * CLOCKS_PER_SEC );    // wait at most m_Timeout seconds
00516         while ( true )
00517         {
00518             unsigned short val = 0;
00519             Read( Reg_Status, val );
00520             if ( ( val & RegBit_FrameDone ) != 0 ) break;
00521             
00522             if ( clock() > StopTime ) return false;     // Timed out
00523         }
00524     }
00525 
00526 //        MaskIrqs();
00527 
00529     // Update our internal status
00530     unsigned short val = 0;
00531     Read( Reg_CommandReadback, val );
00532     if ( !( val & RegBit_ShutterOverride ) ) m_Shutter = false;
00533 
00534     StopFlushing();
00535     LoadColumnLayout( m_ExposureAIC, BIC, (unsigned short) m_ExposureNumX + m_ExposureSkipC );
00536 
00537     if ( m_ExposureRemainingLines > 0 )
00538     {
00539         LoadTimerAndBinning( 0.0, m_ExposureHFlush, m_ExposureRemainingLines );
00540 
00542         // Clock out the remaining lines
00543         m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine;     // set bit to 1
00544         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00545         
00546         m_RegShadow[ Reg_Command ] &= ~RegBit_StartNextLine;    // set bit to 0
00547         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00549 
00551         // Wait until camera is done clocking
00552         clock_t StopTime = clock() + CLOCKS_PER_SEC;    // wait at most one second
00553         while ( true )
00554         {
00555             unsigned short val = 0;
00556             Read( Reg_Status, val );
00557             if ( ( val & RegBit_LineDone ) != 0 ) break;    // Line done
00558             
00559             if ( clock() > StopTime )
00560             {
00561                 Flush();
00562                 return false;       // Timed out, no image available
00563             }
00564         }
00565     }
00566 
00567     LoadTimerAndBinning( 0.0, m_ExposureBinX, m_ExposureBinY );
00568     
00569     bool ret = false;   // assume failure
00570 
00571     // NB Application must have allocated enough memory or else !!!
00572     if ( pImageData != NULL )
00573     {
00574             HANDLE hProcess(0);
00575         DWORD Class(0);
00576         
00577         if ( m_HighPriority )
00578         {   // Store current process class and priority
00579             hProcess = GetCurrentProcess();
00580             Class = GetPriorityClass ( hProcess );
00581             SetPriorityClass ( hProcess, REALTIME_PRIORITY_CLASS );
00582         }
00583 
00584         m_RegShadow[ Reg_Command ] |= RegBit_FIFOCache;     // set bit to 1
00585         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00586 
00587         long XPixels = long( m_ExposureNumX );
00588         long SkipPixels = long( m_ExposureSkipC );
00589         for (i = 0; i < m_ExposureSkipR; i++)
00590         {
00591             if ( ReadLine( SkipPixels, XPixels, pImageData ) ) break;
00592         }
00593         
00594         if ( i == m_ExposureSkipR )
00595         {   // We have skipped all the lines
00596             long YPixels = long( m_ExposureNumY );
00597             unsigned short* pLineBuffer = pImageData;
00598             for (i = 0; i < YPixels; i++)
00599             {
00600                 if ( ReadLine( SkipPixels, XPixels, pLineBuffer ) ) break;
00601                 pLineBuffer += XPixels;
00602             }
00603 
00604             if ( i == YPixels ) ret = true;     // We have read all the lines
00605         }
00606         
00607         m_RegShadow[ Reg_Command ] &= ~RegBit_FIFOCache;    // set bit to 0
00608         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00609 
00610         //Restore priority
00611         if ( m_HighPriority ) SetPriorityClass ( hProcess, Class );
00612     }
00613 
00614 //        UnmaskIrqs();
00615 
00616     if ( ret )
00617     {   // We were successfull
00618         Flush( m_ExposureAIR ); // flush after imaging rows
00619 
00620         xSize = m_ExposureNumX;
00621         ySize = m_ExposureNumY;
00622 
00623         if ( m_DataBits == 16 )
00624         {   // Take care of two's complement converters
00625             unsigned short *Ptr = pImageData;
00626             short *Ptr2 = (short *) pImageData;
00627             long Size = m_ExposureNumX * m_ExposureNumY;
00628             for (i = 0; i < Size; i++)
00629             {
00630                 *Ptr++ = (unsigned short) *Ptr2++ + 32768 ;
00631             }
00632         }
00633 
00634     }
00635     else
00636     {   // Something went wrong
00637         xSize = 0;
00638         ySize = 0;
00639     }
00640     
00641     Flush();        // start normal flushing
00642     
00643     return ret;
00644 }
00645 
00647 // Drift scan methods
00648 
00649 bool CCameraIO::DigitizeLine()
00650 {
00652     // All of these are done just in case
00653     // since they are called in Expose()
00654     StopFlushing();
00655     
00656     unsigned short BIC = m_ExposureBIC + m_ExposureStartX;
00657     LoadColumnLayout( m_ExposureAIC, BIC, (unsigned short) m_ExposureNumX + m_ExposureSkipC );
00658     LoadTimerAndBinning( 0.0, m_ExposureBinX, m_ExposureBinY );
00659 
00660     // Disable FIFO cache
00661     m_RegShadow[ Reg_Command ] &= ~RegBit_FIFOCache;    // set bit to 0
00663 
00665     // Clock out the line
00666     m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine;     // set bit to 1
00667     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00668     
00669     m_RegShadow[ Reg_Command ] &= ~RegBit_StartNextLine;    // set bit to 0
00670     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00672     
00673     m_WaitingforLine = true;
00674     return true;
00675 }
00676 
00677 bool CCameraIO::GetLine( unsigned short* pLineData, short& xSize )
00678 {
00679         int i;
00680 
00681     if ( m_WaitingforLine )
00682     {   // In case application did not poll read_Status
00683         m_WaitingforLine = false;
00684         
00686         // Wait until camera is done clocking
00687         clock_t StopTime = clock() + CLOCKS_PER_SEC;    // wait at most one second
00688         while ( true )
00689         {
00690             unsigned short val = 0;
00691             Read( Reg_Status, val );
00692             if ( ( val & RegBit_LineDone ) != 0 ) break;    // Line done
00693             
00694             if ( clock() > StopTime )
00695             {
00696                 Flush();
00697                 return false;       // Timed out, no line available
00698             }
00699         }
00700     }
00701 
00702     bool ret = false;   // assume failure
00703 
00704 //        MaskIrqs();
00705 
00706     // NB Application must have allocated enough memory or else !!!
00707     if ( pLineData != NULL )
00708     {
00709             HANDLE hProcess(0);
00710         DWORD Class(0);
00711         
00712         if ( m_HighPriority )
00713         {   // Store current process class and priority
00714             hProcess = GetCurrentProcess();
00715             Class = GetPriorityClass ( hProcess );
00716             SetPriorityClass ( hProcess, REALTIME_PRIORITY_CLASS );
00717         }
00718 
00719         long XPixels = long( m_ExposureNumX );
00720         long SkipPixels = long( m_ExposureSkipC );
00721         
00722         if ( ReadLine( SkipPixels, XPixels, pLineData ) )
00723         {   // Something went wrong
00724             xSize = 0;
00725             ret = false;
00726         }
00727         else
00728         {
00729             xSize = m_ExposureNumX;
00730 
00731             if ( m_DataBits == 16 )
00732             {   // Take care of two's complement converters
00733                 unsigned short *Ptr = pLineData;
00734                 short *Ptr2 = (short *) pLineData;
00735                 long Size = m_ExposureNumX;
00736                 for (i = 0; i < Size; i++)
00737                 {
00738                     *Ptr++ = (unsigned short) *Ptr2++ + 32768 ;
00739                 }
00740             }
00741             
00742             ret = true;
00743         }
00744         
00745         //Restore priority
00746         if ( m_HighPriority ) SetPriorityClass ( hProcess, Class );
00747     }
00748     
00749 //        UnmaskIrqs();
00750     return ret;
00751 }
00752 
00754 // Easy to use methods
00755 
00756 bool CCameraIO::Snap( double Duration, bool Light, unsigned short* pImageData, short& xSize, short& ySize )
00757 {
00758     // NB This also demonstrates how an application might use the
00759     // Expose and GetImage routines.
00760 
00761     bool ret = Expose( Duration, Light );
00762     if ( !ret  ) return false;
00763 
00764     if ( m_WaitingforTrigger )
00765     {
00766         Camera_Status stat;
00767         while ( true )
00768         {   // This will wait forever if no trigger happens
00769             stat = read_Status();
00770             if ( stat == Camera_Status_Exposing ) break;
00771             Sleep( 220 );   // dont bog down the CPU while polling
00772         }
00773         m_WaitingforTrigger = false;
00774     }
00775 
00776     // Only wait a time slightly greater than the duration of the exposure
00777     // but enough for the BIR to flush out
00778     clock_t StopTime = clock() + long( ( 1.2 * Duration + m_Timeout ) * CLOCKS_PER_SEC );
00779     while ( true )
00780     {
00781         Camera_Status stat = read_Status();
00782         if ( stat == Camera_Status_ImageReady ) break;
00783         
00784         if ( clock() > StopTime ) return false; // Timed out, no image available
00785         Sleep( 220 );   // dont bog down the CPU while polling
00786     }
00787 
00788     return GetImage( pImageData, xSize, ySize );
00789 }
00790 
00792 // Camera Settings
00793 
00794 Camera_Status CCameraIO::read_Status()
00795 {
00796     unsigned short val = 0;
00797     Read( Reg_Status, val );
00798 
00799     if ( val & RegBit_Exposing )        //11.0
00800     {
00801         ATLTRACE( "Exposing\r\n" );
00802         m_WaitingforTrigger = false;
00803         m_Status = Camera_Status_Exposing;
00804     }
00805 
00806     else if ( m_WaitingforTrigger )
00807         m_Status = Camera_Status_Waiting;
00808 
00809     else if ( m_WaitingforImage && ( val & RegBit_FrameDone ) ) //11.11
00810     {
00811         ATLTRACE( "ImageReady\r\n" );
00812         m_WaitingforImage = false;
00813         m_Status = Camera_Status_ImageReady;
00814     }
00815 
00816     else if ( m_WaitingforLine && ( val & RegBit_LineDone ) )   //11.1
00817     {
00818         ATLTRACE( "LineReady\r\n" );
00819         m_WaitingforLine = false;
00820         m_Status = Camera_Status_LineReady;
00821     }
00822     else if ( m_WaitingforImage || m_WaitingforLine )
00823     {
00824         ATLTRACE( "Flushing\r\n" );
00825         m_Status = Camera_Status_Flushing;
00826     }
00827     else
00828         m_Status = Camera_Status_Idle;
00829 
00830     return m_Status;
00831 }
00832 
00833 bool CCameraIO::read_Present()
00834 {
00835 // This does not work on all cameras
00836 /*
00837     m_RegShadow[ Reg_BICCounter ] |= RegBit_LoopbackTest;   // set bit to 1
00838     Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] );
00839 
00840     bool FailedLoopback = false;
00841     unsigned short val = 0;
00842     Read( Reg_Status, val );
00843     if ( !( val & RegBit_LoopbackTest ) ) FailedLoopback = true;
00844 
00845     m_RegShadow[ Reg_BICCounter ] &= ~RegBit_LoopbackTest;  // clear bit to 0
00846     Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] );
00847 
00848     Read( Reg_Status, val );
00849     if ( val & RegBit_LoopbackTest ) FailedLoopback = true;
00850 */
00851 
00852     unsigned short val = 0;
00853     Read( Reg_CommandReadback, val );   // Take snapshot of currrent status
00854     m_RegShadow[ Reg_Command ] = val;   // remember it in our write shadow
00855     
00856     bool TriggerEnabled = ( val & RegBit_TriggerEnable ) != 0;
00857         
00858     m_RegShadow[ Reg_Command ] &= ~RegBit_TriggerEnable;// clear bit to 0
00859     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00860 
00861     Read( Reg_CommandReadback, val );   // get currrent status
00862     if ( val & RegBit_TriggerEnable ) return false;
00863 
00864     m_RegShadow[ Reg_Command ] |= RegBit_TriggerEnable; // set bit to 1
00865     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00866 
00867     Read( Reg_CommandReadback, val );   // get currrent status
00868     if ( !(val & RegBit_TriggerEnable) ) return false;
00869 
00870     m_RegShadow[ Reg_Command ] &= ~RegBit_TriggerEnable;// clear bit to 0
00871     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00872 
00873     Read( Reg_CommandReadback, val );   // get currrent status
00874     if ( val & RegBit_TriggerEnable ) return false;
00875 
00876     if ( TriggerEnabled )
00877     {   // Set it back the way it was
00878         m_RegShadow[ Reg_Command ] |= RegBit_TriggerEnable; // set bit to 1
00879         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00880     }
00881     return true;
00882 }
00883 
00884 bool CCameraIO::read_Shutter()
00885 {
00886     unsigned short regval = 0;
00887     Read( Reg_Status, regval );
00888     if ( !( regval & RegBit_Exposing ) )
00889     {   // We are not exposing, but might have finnshed an exposure
00890         // and have not called GetImage yet, so update our internal variable
00891         regval = 0;
00892         Read( Reg_CommandReadback, regval );
00893         if ( !( regval & RegBit_ShutterOverride ) )
00894             // The shutter override is not on, so the shutter must be closed
00895             m_Shutter = false;
00896     }
00897 
00898     return m_Shutter;
00899 }
00900 
00901 bool CCameraIO::read_ForceShutterOpen()
00902 {
00903     unsigned short val = 0;
00904     Read( Reg_CommandReadback, val );
00905     return ( ( val & RegBit_ShutterOverride ) != 0 );
00906 }
00907 
00908 void CCameraIO::write_ForceShutterOpen( bool val )
00909 {
00910     if ( val )
00911     {
00912         m_RegShadow[ Reg_Command ] |= RegBit_ShutterOverride;   // set bit to 1
00913         m_Shutter = true;   // shutter will open immediately now matter what is going on
00914     }
00915     else
00916     {
00917         m_RegShadow[ Reg_Command ] &= ~RegBit_ShutterOverride;  // clear bit to 0
00918 
00919         unsigned short regval = 0;
00920         Read( Reg_Status, regval );
00921         if ( ( regval & RegBit_Exposing ) )
00922         {   
00923             // Shutter will remain open if a Light frame is being taken
00924             // however if a dark frame was being exposed while the
00925             // override was on or the override is turned on during the exposure
00926             // and now is turned off (dumb idea but some app might do it!)
00927             // we must update our variable since the shutter will close
00928             // when override gets turned off below
00929             regval = 0;
00930             Read( Reg_CommandReadback, regval );
00931             if ( !( regval & RegBit_ShutterEnable ) ) m_Shutter = false;
00932         }
00933         else
00934         {   // Not currently exposing so shutter will close
00935             // once override is turned off, update our variable
00936             m_Shutter = false;
00937         }
00938     }
00939     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00940 }
00941 
00942 
00943 
00944 bool CCameraIO::read_LongCable()
00945 {
00946     unsigned short val = 0;
00947     Read( Reg_CommandReadback, val );
00948     return ( ( val & RegBit_CableLength ) != 0 );
00949 }
00950 
00951 void CCameraIO::write_Shutter( bool val )           
00952 {
00953     if ( val )
00954         m_RegShadow[ Reg_Command ] |= RegBit_ShutterEnable; // set bit to 1
00955     else
00956         m_RegShadow[ Reg_Command ] &= ~RegBit_ShutterEnable;    // clear bit to 0
00957 
00958     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
00959 }
00960 
00961 void CCameraIO::write_LongCable( bool val )          
00962 { 
00963     if ( val ) 
00964         m_RegShadow[ Reg_Command ] |= RegBit_CableLength;   // set bit to 1 
00965     else 
00966         m_RegShadow[ Reg_Command ] &= ~RegBit_CableLength;  // clear bit to 0 
00967  
00968     Write( Reg_Command, m_RegShadow[ Reg_Command ] ); 
00969 } 
00970 
00971 
00972 short CCameraIO::read_Mode()
00973 {
00974     return ( ( m_RegShadow[ Reg_LineCounter ] >> RegBitShift_Mode ) & RegBitMask_Mode );
00975 }
00976 
00977 void CCameraIO::write_Mode( short val )
00978 {
00979     // clear bits to 0
00980     m_RegShadow[ Reg_LineCounter ] &= ~( RegBitMask_Mode << RegBitShift_Mode );
00981     
00982     // set our new bits
00983     m_RegShadow[ Reg_LineCounter ] |= ( (unsigned short) val  & RegBitMask_Mode ) << RegBitShift_Mode;
00984     
00985     Write( Reg_LineCounter, m_RegShadow[ Reg_LineCounter ] );
00986 }
00987 
00988 short CCameraIO::read_TestBits()
00989 {
00990     return ( ( m_RegShadow[ Reg_BICCounter ] >> RegBitShift_Test ) & RegBitMask_Test );
00991 }
00992 
00993 void CCameraIO::write_TestBits( short val )
00994 {
00995     // clear bits to 0
00996     m_RegShadow[ Reg_BICCounter ] &= ~( RegBitMask_Test << RegBitShift_Test );
00997     
00998     // set our new bits
00999     m_RegShadow[ Reg_BICCounter ] |= ( (unsigned short) val  & RegBitMask_Test ) << RegBitShift_Test;
01000     
01001     Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] );
01002 }
01003 
01004 
01005 short CCameraIO::read_Test2Bits()
01006 {
01007     return ( ( m_RegShadow[ Reg_AICCounter ] >> RegBitShift_Test2 ) & RegBitMask_Test2 );
01008 }
01009 
01010 void CCameraIO::write_Test2Bits( short val )
01011 {
01012     // clear bits to 0
01013     m_RegShadow[ Reg_AICCounter ] &= ~( RegBitMask_Test2 << RegBitShift_Test2 );
01014     
01015     // set our new bits
01016     m_RegShadow[ Reg_AICCounter ] |= ( (unsigned short) val  & RegBitMask_Test2 ) << RegBitShift_Test2;
01017     
01018     Write( Reg_AICCounter, m_RegShadow[ Reg_AICCounter ] );
01019 }
01020 
01021 bool CCameraIO::read_FastReadout()
01022 {
01023     unsigned short val = 0;
01024     Read( Reg_CommandReadback , val );
01025     return ( ( val & RegBit_Focus ) != 0 );
01026 }
01027 
01028 void CCameraIO::write_FastReadout( bool val )
01029 {
01030     if ( val )
01031         m_RegShadow[ Reg_Command ] |= RegBit_Focus;     // set bit to 1
01032     else
01033         m_RegShadow[ Reg_Command ] &= ~RegBit_Focus;    // clear bit to 0
01034 
01035     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
01036 }
01037 
01038 bool CCameraIO::read_UseTrigger()
01039 {
01040     unsigned short val = 0;
01041     Read( Reg_CommandReadback , val );
01042     return ( ( val & RegBit_TriggerEnable ) != 0 );
01043 }
01044 
01045 void CCameraIO::write_UseTrigger( bool val )
01046 {
01047     if ( val )
01048         m_RegShadow[ Reg_Command ] |= RegBit_TriggerEnable;     // set bit to 1
01049     else
01050         m_RegShadow[ Reg_Command ] &= ~RegBit_TriggerEnable;    // clear bit to 0
01051 
01052     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
01053 }
01054 
01056 // Cooler Settings
01057 
01058 double CCameraIO::read_CoolerSetPoint()
01059 {
01060     // Get the setting from the shadow registers
01061     short DACunits = short( ( m_RegShadow[ Reg_TempSetPoint ] >> RegBitShift_TempSetPoint ) & RegBitMask_TempSetPoint );
01062     return ( DACunits - m_TempCalibration ) / m_TempScale;
01063 }
01064 
01065 void CCameraIO::write_CoolerSetPoint( double val )
01066 {
01067     // clear bits to 0
01068     m_RegShadow[ Reg_TempSetPoint ] &= ~( RegBitMask_TempSetPoint << RegBitShift_TempSetPoint );
01069     
01070     // Calculate DAC units from degrees Celcius
01071     unsigned short DACunits = (unsigned )( m_TempScale * val ) + m_TempCalibration ;
01072 
01073     // set our new bits
01074     m_RegShadow[ Reg_TempSetPoint ] |= ( DACunits & RegBitMask_TempSetPoint ) << RegBitShift_TempSetPoint;
01075     
01076     Write( Reg_TempSetPoint, m_RegShadow[ Reg_TempSetPoint ] );
01077 }
01078 
01079 Camera_CoolerStatus CCameraIO::read_CoolerStatus()
01080 {
01081     unsigned short val = 0;
01082     Read( Reg_CommandReadback, val );
01083 
01084     if ( val & RegBit_CoolerEnable )                //12.15
01085     {
01086         unsigned short val2 = 0;
01087         Read( Reg_Status, val2 );
01088         
01089         if ( val & RegBit_CoolerShutdown )          //12.8
01090         {
01091             if ( val2 & RegBit_ShutdownComplete )   //11.6
01092                 m_CoolerStatus = Camera_CoolerStatus_AtAmbient;
01093             else
01094                 m_CoolerStatus = Camera_CoolerStatus_RampingToAmbient;
01095         }
01096         else
01097         {
01098             if ( val2 & RegBit_TempAtMax )          //11.5
01099                 m_CoolerStatus = Camera_CoolerStatus_AtMax;
01100             else if ( val2 & RegBit_TempAtMin )     //11.4
01101                 m_CoolerStatus = Camera_CoolerStatus_AtMin;
01102             else if ( val2 & RegBit_TempAtSetPoint )    //11.7
01103                 m_CoolerStatus = Camera_CoolerStatus_AtSetPoint;
01104             // Check against last known cooler status
01105             else if ( m_CoolerStatus == Camera_CoolerStatus_AtSetPoint )
01106                 m_CoolerStatus = Camera_CoolerStatus_Correcting;
01107             else
01108                 m_CoolerStatus = Camera_CoolerStatus_RampingToSetPoint;
01109         }
01110     }
01111     else
01112         m_CoolerStatus = Camera_CoolerStatus_Off;
01113 
01114     return m_CoolerStatus;
01115 }
01116 
01117 Camera_CoolerMode CCameraIO::read_CoolerMode()
01118 {
01119     unsigned short val = 0;
01120     Read( Reg_CommandReadback, val );
01121 
01122     if ( val & RegBit_CoolerShutdown )
01123         return Camera_CoolerMode_Shutdown;
01124     else if ( val & RegBit_CoolerEnable )
01125         return Camera_CoolerMode_On;
01126     else
01127         return Camera_CoolerMode_Off;
01128 }
01129 
01130 void CCameraIO::write_CoolerMode( Camera_CoolerMode val )
01131 {
01132     switch ( val )
01133     {
01134     case Camera_CoolerMode_Off:
01135         m_RegShadow[ Reg_Command ] &= ~( RegBit_CoolerEnable );     // clear bit to 0
01136         m_RegShadow[ Reg_Command ] &= ~( RegBit_CoolerShutdown );   // clear bit to 0
01137         break;
01138     case Camera_CoolerMode_On:
01139         m_RegShadow[ Reg_Command ] |= RegBit_CoolerEnable;      // set bit to 1
01140         break;
01141     case Camera_CoolerMode_Shutdown:
01142         m_RegShadow[ Reg_Command ] |= RegBit_CoolerShutdown;    // set bit to 1
01143         break;
01144     default:
01145         return;
01146     }
01147 
01148     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
01149 }
01150 
01151 double CCameraIO::read_Temperature()
01152 {
01153     if ( m_TempScale == 0.0 )
01154         return 0.0;
01155     else
01156     {
01157         unsigned short val = 0;
01158         Read( Reg_TempData, val );
01159 
01160         short DACunits = short( ( val >> RegBitShift_TempData ) & RegBitMask_TempData );
01161     
01162         return ( DACunits - m_TempCalibration ) / m_TempScale;
01163     }
01164 }
01165 
01166 // Load line counter
01167 void CCameraIO::LoadLineCounter( unsigned short rows ) 
01168 {
01170     // Write out Line_Count  - in unbinned rows
01171     // clear bits to 0
01172     m_RegShadow[ Reg_LineCounter ] &= ~( RegBitMask_LineCounter << RegBitShift_LineCounter );
01173     // set our new bits
01174     m_RegShadow[ Reg_LineCounter ] |= ( rows & RegBitMask_LineCounter ) << RegBitShift_LineCounter;
01175     
01176     Write( Reg_LineCounter, m_RegShadow[ Reg_LineCounter ] );
01178 }
01179 
01180 // Load AIC, BIC and pixel count into registers
01181 void CCameraIO::LoadColumnLayout( unsigned short aic, unsigned short bic, unsigned short pixels ) 
01182 {
01184     // Write out AIC - in unbinned columns
01185     // clear bits to 0
01186     m_RegShadow[ Reg_AICCounter ] &= ~( RegBitMask_AICCounter << RegBitShift_AICCounter );
01187     // set our new bits
01188     m_RegShadow[ Reg_AICCounter ] |= ( aic & RegBitMask_AICCounter ) << RegBitShift_AICCounter;
01189     
01190     Write( Reg_AICCounter, m_RegShadow[ Reg_AICCounter ] );
01192 
01194     // Write out BIC - in unbinned columns
01195     // clear bits to 0
01196     m_RegShadow[ Reg_BICCounter ] &= ~( RegBitMask_BICCounter << RegBitShift_BICCounter );
01197     // set our new bits
01198     m_RegShadow[ Reg_BICCounter ] |= ( bic & RegBitMask_BICCounter ) << RegBitShift_BICCounter;
01199     
01200     Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] );
01202 
01204     // Write out pixel count - in binned columns
01205     // clear bits to 0
01206     m_RegShadow[ Reg_PixelCounter ] &= ~( RegBitMask_PixelCounter << RegBitShift_PixelCounter );
01207     // set our new bits
01208     m_RegShadow[ Reg_PixelCounter ] |= ( pixels & RegBitMask_PixelCounter ) << RegBitShift_PixelCounter;
01209     
01210     Write( Reg_PixelCounter, m_RegShadow[ Reg_PixelCounter ] );
01212 }
01213 
01214 // Load timer, vertical binning and horizontal binning in to registers
01215 // If Duration parameter is 0 the current timer value will be retained.
01216 // The VBin and HBin parameters are one based, the HBin value
01217 // is converted to zero base inside this routine.
01218 void CCameraIO::LoadTimerAndBinning( double Duration, unsigned short HBin, unsigned short VBin )
01219 {
01221     // Write out HBin for flushing
01222     // clear bits to 0
01223     m_RegShadow[ Reg_PixelCounter ] &= ~( RegBitMask_HBinning << RegBitShift_HBinning );
01224     // set our new bits
01225     m_RegShadow[ Reg_PixelCounter ] |= ( ( HBin - 1 ) & RegBitMask_HBinning ) << RegBitShift_HBinning;
01226     
01227     Write( Reg_PixelCounter, m_RegShadow[ Reg_PixelCounter ] );
01229 
01231     // Write out VBin for flushing and Timer
01232     if ( Duration > 0.0 )
01233     {
01234         if ( Duration > m_MaxExposure ) Duration = m_MaxExposure;
01235         
01236         long valTimer;
01237         if ( m_FastShutter && Duration <= 1048.575 )
01238         {   // Automatically switch to high precision mode
01239             valTimer = long( ( Duration * 1000 ) + 0.5 );
01240             m_RegShadow[ Reg_LineCounter ] |= ( m_FastShutterBits_Mode & RegBitMask_Mode ) << RegBitShift_Mode;
01241             m_RegShadow[ Reg_BICCounter ] |= ( m_FastShutterBits_Test & RegBitMask_Test ) << RegBitShift_Test;
01242         }
01243         else
01244         {
01245             valTimer = long( ( Duration * 100 ) + 0.5 );
01246             if ( m_FastShutter )
01247             {   // Disable high precision mode
01248                 m_RegShadow[ Reg_LineCounter ] &= ~( m_FastShutterBits_Mode & RegBitMask_Mode ) << RegBitShift_Mode;
01249                 m_RegShadow[ Reg_BICCounter ] &= ~( m_FastShutterBits_Test & RegBitMask_Test ) << RegBitShift_Test;
01250             }
01251         }
01252         
01253         if ( m_FastShutter )
01254         {
01255             Write( Reg_LineCounter, m_RegShadow[ Reg_LineCounter ] );
01256             Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] );
01257         }
01258 
01259         if ( valTimer <= 0 ) valTimer = 1;      // Safety since firmware doesnt like zero
01260 
01261         unsigned short valTimerLow = (unsigned short) (valTimer & 0x0000FFFF);
01262         unsigned short valTimerHigh = (unsigned short) (valTimer >> 16);
01263 
01264         // Enable loading of timer values
01265         m_RegShadow[ Reg_Command ] |= RegBit_TimerLoad; // set bit to 1
01266         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
01267 
01268             // clear bits to 0
01269             m_RegShadow[ Reg_Timer ] = 0;
01270             // set our new bits
01271             m_RegShadow[ Reg_Timer ] |= ( valTimerLow & RegBitMask_Timer )<< RegBitShift_Timer;
01272             Write( Reg_Timer, m_RegShadow[ Reg_Timer ] );
01273 
01274             // clear bits to 0
01275             m_RegShadow[ Reg_VBinning ] = 0;
01276 
01277             // set our new bits
01278             m_RegShadow[ Reg_VBinning ] |= ( VBin & RegBitMask_VBinning ) << RegBitShift_VBinning;
01279             m_RegShadow[ Reg_VBinning ] |= ( valTimerHigh & RegBitMask_Timer2 ) << RegBitShift_Timer2;
01280             Write( Reg_VBinning, m_RegShadow[ Reg_VBinning ] );
01281 
01282         // Disable loading of timer values
01283         m_RegShadow[ Reg_Command ] &= ~RegBit_TimerLoad;    // set bit to 0
01284         Write( Reg_Command, m_RegShadow[ Reg_Command ] );
01286     }
01287     else
01288     {
01289         // clear bits to 0
01290         m_RegShadow[ Reg_VBinning ] &= ~( RegBitMask_VBinning << RegBitShift_VBinning );
01291 
01292         // set our new bits
01293         m_RegShadow[ Reg_VBinning ] |= ( VBin & RegBitMask_VBinning ) << RegBitShift_VBinning;
01294         Write( Reg_VBinning, m_RegShadow[ Reg_VBinning ] );
01295     }
01296 
01297 }
01298 
01299 // Start flushing the entire CCD (rows = -1) or a specific number or rows
01300 void CCameraIO::Flush( short Rows )
01301 {
01302     if ( Rows == 0 ) return;
01303 
01304     unsigned short AIC = (unsigned short) ( m_Columns - m_BIC - m_ImgColumns );
01305     unsigned short Pixels = (unsigned short) ( m_ImgColumns / m_HFlush );
01306     if ( m_ImgColumns % m_HFlush > 0 ) Pixels++;    // round up if necessary
01307     LoadColumnLayout( AIC, (unsigned short) m_BIC, Pixels );
01308 
01309     LoadTimerAndBinning( 0.0, m_HFlush, m_VFlush );
01310 
01311     if ( Rows > 0 )
01312     {       
01313         LoadLineCounter( (unsigned short) Rows );   
01314         StartFlushing();
01315 
01317         // Wait until camera is done flushing
01318         clock_t StopTime = clock() + long( m_Timeout * CLOCKS_PER_SEC );    // wait at most m_Timeout seconds
01319         while ( true )
01320         {
01321             unsigned short val = 0;
01322             Read( Reg_Status, val );
01323             if ( ( val & RegBit_FrameDone ) != 0 ) break;
01324             
01325             if ( clock() > StopTime ) break;        // Timed out
01326         }
01327     }
01328     else
01329     {
01330         LoadLineCounter( (unsigned short) m_ImgRows );
01331         StartFlushing();
01332     }
01333 }
01334 
01335 void CCameraIO::StartFlushing()
01336 {
01338     // Start flushing
01339     m_RegShadow[ Reg_Command ] |= RegBit_StartFlushing; // set bit to 1
01340     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
01341     
01342     m_RegShadow[ Reg_Command ] &= ~RegBit_StartFlushing;// set bit to 0
01343     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
01345 }
01346 
01347 void CCameraIO::StopFlushing()
01348 {
01350     // Stop flushing
01351     m_RegShadow[ Reg_Command ] |= RegBit_StopFlushing;  // set bit to 1
01352     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
01353     
01354     m_RegShadow[ Reg_Command ] &= ~RegBit_StopFlushing; // set bit to 0
01355     Write( Reg_Command, m_RegShadow[ Reg_Command ] );
01357 }
01358 
01359 
01360 
01361 
01362 

kstars

Skip menu "kstars"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • keduca
  • kstars
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal