예제 #1
0
bool FirewirePort::WriteAllBoards(void)
{
    if (!handle) {
        outStr << "WriteAllBoards: handle for port " << PortNum << " is NULL" << std::endl;
        return false;
    }
    bool allOK = true;
    bool noneWritten = true;
    for (int board = 0; board < max_board; board++) {
        if (BoardList[board]) {
            quadlet_t *buf = BoardList[board]->GetWriteBuffer();
            unsigned int numBytes = BoardList[board]->GetWriteNumBytes();
            unsigned int numQuads = numBytes/4;
            // Currently (Rev 1 firmware), the last quadlet (Status/Control register)
            // is done as a separate quadlet write.
            bool ret = WriteBlock(board, 0, buf, numBytes-4);
            if (ret) noneWritten = false;
            else allOK = false;
            quadlet_t ctrl = buf[numQuads-1];  // Get last quadlet
            bool ret2 = true;
            if (ctrl) {    // if anything non-zero, write it
                ret2 = WriteQuadlet(board, 0, ctrl);
                if (ret2) noneWritten = false;
                else allOK = false;
            }
            // SetWriteValid clears the buffer if the write was valid
            BoardList[board]->SetWriteValid(ret&&ret2);
        }
    }
    if (noneWritten)
        PollEvents();
    return allOK;
}
예제 #2
0
/**\brief Change the Camera's Power Control Setting
 * \return Same as WriteQuadlet()
 */
int  C1394Camera::SetPowerControl(BOOL on)
{
	int ret;
	if((ret = WriteQuadlet(0x610,0x80000000)) != CAM_SUCCESS)
		return ret;
	ReadQuadlet(0x610,&m_StatusPowerControl);
	return CAM_SUCCESS;
}
예제 #3
0
/**\brief Trigger the transfer of exactly one frame from the camera
 * \ingroup camcore
 * \return CAM_SUCCESS if successful, CAM_ERROR otherwise
 *
 *   This function is a wrapper for an otherwise simple procedure.  Maybe it should
 *   be inlined and just return whatever the WriteRegister returns
 *
 *   This function is currently not used by anything at all because it does not integrate
 *   cleanly with the acquisition code.
 */
int C1394Camera::OneShot()
{
	ULONG ulRet;
	int retval = CAM_SUCCESS;

	DllTrace(DLL_TRACE_ENTER,"ENTER OneShot\n");
	if((ulRet = WriteQuadlet(0x61c,0x80000000)) != 0)
	{
		DllTrace(DLL_TRACE_ERROR,"OneShot: error %08x on WriteQuadlet(0x61c)\n",ulRet);
		retval = CAM_ERROR;
	}
	DllTrace(DLL_TRACE_EXIT,"EXIT OneShot (%d)\n",retval);
	return retval;
}
예제 #4
0
/**\brief Disable continuous streaming of camera data.
 * \ingroup camcore
 * \return CAM_SUCCESS if successful, CAM_ERROR otherwise
 *
 * This is essentially a one-liner that is referenced from one place and may soon be removed
 */
int C1394Camera::StopVideoStream()
{
	ULONG ulRet;
	int retval = CAM_SUCCESS;

	DllTrace(DLL_TRACE_ENTER,"ENTER StopVideoStream\n");
	if((ulRet = WriteQuadlet(0x614,0x00000000)) != 0)
	{
		DllTrace(DLL_TRACE_ERROR,"StopVideoStream: error %08x on WriteQuadlet(0x614)\n",ulRet);
		retval = CAM_ERROR;
	}
	DllTrace(DLL_TRACE_EXIT,"EXIT StopVideoStream (%d)\n",retval);
	return retval;
}
예제 #5
0
/**\brief Trigger the transfer of exactly <i>N</i> frames from the camera
 * \param count The number of frames to transfer (0 to stop a running multishot)
 * \ingroup camcore
 * \return CAM_SUCCESS if successful, CAM_ERROR otherwise
 *
 *   This function is a wrapper for an otherwise simple procedure.  Maybe it should
 *   be inlined and just return whatever the WriteRegister returns
 *
 *   This function is currently not used by anything at all because it does not integrate
 *   cleanly with the acquisition code.
 *
 *   Also, MultiShot() should be implemented
 */
int C1394Camera::MultiShot(unsigned short count)
{
	ULONG ulRet,ulData;
	int retval = CAM_SUCCESS;
	
	DllTrace(DLL_TRACE_ENTER,"ENTER MultiShot\n");
	ulData = (ULONG) count; // count in the low 16 bits
	if(count != 0)(ulData |= 0x40000000); // bit 1 (second-to-highest) enables multishot
	DllTrace(DLL_TRACE_CHECK,"MultiShot: Writing 0x%08x to %03x\n",ulData,0x61c);
	if((ulRet = WriteQuadlet(0x61c,ulData)) != 0)
	{
		DllTrace(DLL_TRACE_ERROR,"MultiShot: error %08x on WriteQuadlet(0x61c)\n",ulRet);
		retval = CAM_ERROR;
	}
	DllTrace(DLL_TRACE_EXIT,"EXIT MultiShot (%d)\n",retval);
	return retval;
}
예제 #6
0
/**\brief (de-)activate 1394b support in a compliant camera
 * \param on Whether to turn 1394b support on (TRUE) or off (FALSE)
 * \return
 *  - CAM_ERROR_BUSY if in the middle of image acquisition
 *  - CAM_ERROR_UNSUPPORTED if the camera does not support 1394b
 *  - Other errors: Bad things happened in Register I/O
 *
 * After successfully changing 1394b support, we must re-read all the
 * format, mode, rate, etc registers
 */
int C1394Camera::Set1394b(BOOL on)
{
	int ret;
	if(this->m_hDeviceAcquisition != INVALID_HANDLE_VALUE)
		return CAM_ERROR_BUSY;
	
	if(Has1394b())
	{
		unsigned long ulData;
		if((ret = ReadQuadlet(0x60c, &ulData)) != CAM_SUCCESS)
			return ret;
		if(on)
			ulData |= 0x00008000;
		else
			ulData &= ~0x00008000;
		if((ret = WriteQuadlet(0x60c, ulData)) != CAM_SUCCESS)
			return ret;
		// by changing this setting, other random stuff may change as well
		return InitCamera();
	}
	return CAM_ERROR_UNSUPPORTED;
}
bool FirewirePort::WriteAllBoardsBroadcast(void)
{
    // check hanle
    if (!handle) {
        outStr << "WriteAllBoardsBroadcast: handle for port " << PortNum << " is NULL" << std::endl;
        return false;
    }

    // sanity check vars
    bool allOK = true;
    bool noneWritten = true;

    // loop 1: broadcast write block

    // construct broadcast write buffer
    const int numOfChannel = 4;
    quadlet_t bcBuffer[numOfChannel * MAX_NODES];
    memset(bcBuffer, 0, sizeof(bcBuffer));
    int bcBufferOffset = 0; // the offset for new data to be stored in bcBuffer (bytes)
    int numOfBoards = 0;

    for (int board = 0; board < max_board; board++) {
        if (BoardList[board]) {
            numOfBoards++;
            quadlet_t *buf = BoardList[board]->GetWriteBuffer();
            unsigned int numBytes = BoardList[board]->GetWriteNumBytes();
            memcpy(bcBuffer + bcBufferOffset/4, buf, numBytes-4); // -4 for ctrl offset
            // bcBufferOffset equals total numBytes to write, when the loop ends
            bcBufferOffset = bcBufferOffset + numBytes - 4;
        }
    }

    // now broadcast out the huge packet
    bool ret = true;

#if FAKEBC
    ret = !raw1394_write(handle,
                         baseNodeId,
                         0xffffffff0000,
                         bcBufferOffset,
                         bcBuffer);
#else
    ret = WriteBlockBroadcast(0xffffff000000,  // now the address is hardcoded
                              bcBuffer,
                              bcBufferOffset);
#endif

    // loop 2: send out control quadlet if necessary
    for (int board = 0; board < max_board; board++) {
        if (BoardList[board]) {
            quadlet_t *buf = BoardList[board]->GetWriteBuffer();
            unsigned int numBytes = BoardList[board]->GetWriteNumBytes();
            unsigned int numQuads = numBytes/4;
            quadlet_t ctrl = buf[numQuads-1];  // Get last quedlet
            bool ret2 = true;
            if (ctrl) {  // if anything non-zero, write it
                ret2 = WriteQuadlet(board, 0x00, ctrl);
                if (ret2) noneWritten = false;
                else allOK = false;
            }
            // SetWriteValid clears the buffer if the write was valid
            BoardList[board]->SetWriteValid(ret&&ret2);
        }
    }

    // pullEvents
    if (noneWritten) {
        PollEvents();
    }

    // return
    return allOK;
}
예제 #8
0
/**\brief Performs General initialization of the C1394Camera class for the currently selected camera
 * \ingroup camcore
 * \param reset If TRUE, this will poke the camera init register to restore it to powerup defaults
 * \return
 *  CAM_SUCCESS: The camera is ready to start capturing Frames.
 *  CAM_ERROR_NOT_INITIALIZED: No camera selected (this is poorly named and may be changed)
 *  CAM_ERROR_BUSY: Usualy indicates broken invariants, but in and of itself prevents an
 *    init in the middle of image acquisition
 *  CAM_ERROR: Some register IO failed, GetLastError will tell why
 *
 * This Function currently causes a lot of I/O on the 1394 bus to populate the configuration and capability
 * information about the camera and all the available controllable features.  If there are any standard video
 * formats available (e.g. not format 7), then the first available format, mode and rate are selected by default.
 */
int C1394Camera::InitCamera(BOOL reset)
{
	GET_MAX_SPEED_BETWEEN_DEVICES maxSpeed;
	DWORD dwRet;
	int ret = CAM_ERROR;
	ULONG maxSpeedNotLocal, maxSpeedLocal;
	
	DllTrace(DLL_TRACE_ENTER,"ENTER InitCamera\n");
	
	if(m_cameraInitialized)
		// this isn't really an error, but should be reported
		DllTrace(DLL_TRACE_WARNING,"InitCamera: Warning: Duplicate Call to InitCamera\n");
	
	// clear it for another pass
	m_cameraInitialized = false;
	
	if(!m_pName)
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: Error: no camera selected\n");
		ret = CAM_ERROR_NOT_INITIALIZED;
		goto _exit;
	}
	
	if(m_hDeviceAcquisition != INVALID_HANDLE_VALUE)
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: Error: Camera is busy, stop image acquisition first\n");
		ret = CAM_ERROR_BUSY;
		goto _exit;
	}
	
	// this frees up any isoch resources that may be left behind
	// from a previous program that didn't clean up after itself
	// properly (i.e. crashed)
	
	// This is an ugly way to deal with it, but will have to work for now
	t1394IsochTearDownStream(m_pName);
	
	// determine max speed
	// this is used for allocating bandwidth and stuff
	maxSpeed.fulFlags = 0;
	maxSpeed.ulNumberOfDestinations = 0;
	if (dwRet = GetMaxSpeedBetweenDevices(m_pName, &maxSpeed))
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: Error %08x on GetMaxSpeedBetweenDevices (NotLocal)\n",dwRet);
		goto _exit;
	}
	maxSpeedNotLocal = maxSpeed.fulSpeed;
	
	maxSpeed.fulFlags = 1;
	if (dwRet = GetMaxSpeedBetweenDevices(m_pName, &maxSpeed))
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: Error %08x on GetMaxSpeedBetweenDevices (Local)\n",dwRet);
		goto _exit;
	}
	maxSpeedLocal = maxSpeed.fulSpeed;
	
	// select the smaller of the two
	m_maxSpeed = (maxSpeedLocal < maxSpeedNotLocal ? maxSpeedLocal : maxSpeedNotLocal);
	
	// reset to defaults if we want
	if(reset == TRUE)
	{
		if(WriteQuadlet(0x000,0x80000000) != CAM_SUCCESS)
			DllTrace(DLL_TRACE_WARNING,"InitCamera: Warning: Reset to defaults failed: %08x\n",GetLastError());
	}
	
	// determine video formats/modes/rates
	// private functions return bools and do their own respective tracing
	if(!InquireVideoFormats())
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: Error on InquireVideoFormats\n");
		goto _exit;
	}
	
	if(!InquireVideoModes())
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: Error on InquireVideoModes\n");
		goto _exit;
	}
	
	if(!InquireVideoRates())
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: Error on InquireVideoRates\n");
		goto _exit;
	}
	
	if(CAM_SUCCESS != (dwRet = ReadQuadlet(0x400,&m_InqBasicFunc)))
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x on ReadQuadlet(0x400)\n",dwRet);
		goto _exit;
	}
	
	if(CAM_SUCCESS != (dwRet = ReadQuadlet(0x404,&m_InqFeatureHi)))
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x on ReadQuadlet(0x404)\n",dwRet);
		goto _exit;
	}
	
	if(CAM_SUCCESS != (dwRet = ReadQuadlet(0x408,&m_InqFeatureLo)))
	{
		DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x on ReadQuadlet(0x408)\n",dwRet);
		goto _exit;
	}
	
	// Poke the error bits, if available
	this->StatusVideoErrors(TRUE);
	this->StatusFeatureError(FEATURE_BRIGHTNESS,TRUE);
	
	// the core registers have been updated, so it's safe to set this here
	// NOTE: this flag is very hackish, and should be replaced by explicitly nuking
	// the toplevel registers on Construction and SelectCamera()
	m_cameraInitialized = true;
	
	if(this->HasPowerControl())
	{
		if(CAM_SUCCESS != (dwRet = ReadQuadlet(0x610,&this->m_StatusPowerControl)))
		{
			DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x reading Power Register\n");
			goto _exit;
		}
	}
	
	if(this->HasAdvancedFeature())
	{
		if(CAM_SUCCESS != (dwRet = ReadQuadlet(0x480,&this->m_AdvFuncOffset)))
		{
			DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x on ReadQuadlet(0x480)\n",dwRet);
			goto _exit;
		}
		m_AdvFuncOffset <<= 2;
		m_AdvFuncOffset |= 0xf0000000;
	}
	
	if(this->HasOptionalFeatures())
	{
		// Read the Optional Function Bitmask
		if(CAM_SUCCESS != (dwRet = ReadQuadlet(0x40C,&m_InqOptionalFunc)))
		{
			DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x on ReadQuadlet(0x40C)\n",dwRet);
			goto _exit;
		}
		
		// And Check the Individual Features
		if(this->HasPIO())
		{
			if(CAM_SUCCESS != (dwRet = ReadQuadlet(0x484,&this->m_PIOFuncOffset)))
			{
				DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x on ReadQuadlet(0x484)\n",dwRet);
				goto _exit;
			}
			m_PIOFuncOffset <<= 2;
			m_PIOFuncOffset |= 0xf0000000;
		}
		
		if(this->HasSIO())
		{
			if(CAM_SUCCESS != (dwRet = ReadQuadlet(0x488,&this->m_SIOFuncOffset)))
			{
				DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x on ReadQuadlet(0x488)\n",dwRet);
				goto _exit;
			}
			m_SIOFuncOffset <<= 2;
			m_SIOFuncOffset |= 0xf0000000;
		}
		
		if(this->HasStrobe())
		{
			if(CAM_SUCCESS != (dwRet = ReadQuadlet(0x48C,&this->m_StrobeFuncOffset)))
			{
				DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x on ReadQuadlet(0x48C)\n",dwRet);
				goto _exit;
			}
			m_StrobeFuncOffset <<= 2;
			m_StrobeFuncOffset |= 0xf0000000;
			if(CAM_SUCCESS != (dwRet = ReadQuadlet(this->m_StrobeFuncOffset,&this->m_StrobeRootCaps)))
			{
				DllTrace(DLL_TRACE_ERROR,"InitCamera: error %08x on ReadQuadlet(0x%08x)\n",
					dwRet,this->m_StrobeFuncOffset);
				goto _exit;
			}
		}
	}
	
	RefreshControlRegisters(FALSE);
	UpdateParameters();
	ret = CAM_SUCCESS;
	
_exit:
	if(ret != CAM_SUCCESS)
		m_cameraInitialized = false;
	
	DllTrace(DLL_TRACE_EXIT,"EXIT InitCamera (%d)\n",ret);
	return ret;
}