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; }
/**\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; }
/**\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; }
/**\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; }
/**\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; }
/**\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; }
/**\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; }