📄 camera.c
字号:
return 0;
}
////////////////////////////////////////////////////////////////////////
// Deinitialize Device
////////////////////////////////////////////////////////////////////////
BOOL
CAM_Deinit(
DWORD hDeviceContext
)
{
DEVICE_CONTEXT *pDevice = (DEVICE_CONTEXT *) hDeviceContext;
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: CAM_Deinit\r\n")));
if ( pDevice )
{
CAM_Cleanup(&pDevice->cam_base);
Camera_pwr_down(pDevice);
if (pDevice->hInterruptEvent != 0)
{
if (pDevice->dwSysintr != SYSINTR_NOP)
{
InterruptDisable(pDevice->dwSysintr); // dissociate from the intr event
InterruptDisconnect(pDevice->dwSysintr); // dissociate from the hwintr
}
CloseHandle(pDevice->hInterruptEvent);
}
if ( pCim )
{
MmUnmapIoSpace((PVOID) pCim, sizeof(AU1200_CIM));
pCim = NULL;
}
if ( pBcsr )
{
MmUnmapIoSpace((PVOID) pBcsr, sizeof(BCSR));
pBcsr = NULL;
}
// Free the device context.
LocalFree(pDevice);
pDevice = NULL;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////
// Open Device
////////////////////////////////////////////////////////////////////////
DWORD
CAM_Open(
DWORD hDeviceContext,
DWORD AccessCode,
DWORD Sharemode
)
{
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: CAM_Open\r\n")));
// **** TBD: Increment read/write access counts?
// **** TBD: Enforce 1 write access?
return(hDeviceContext);
}
////////////////////////////////////////////////////////////////////////
// Close Device
////////////////////////////////////////////////////////////////////////
BOOL
CAM_Close(
DWORD hOpenContext
)
{
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: CAM_Close\r\n")));
// **** TBD: Decrement read/write access counts?
// **** TBD: If write access goes to 0, stop in-progress activity and
// power down camera?
return(TRUE);
}
////////////////////////////////////////////////////////////////////////
// Power Up
////////////////////////////////////////////////////////////////////////
void
CAM_PowerUp(
DWORD hDeviceContext
)
{
// **** TBD: Skip if camera not powered up?
// **** TBD: Restart paused activity?
bInPowerHandler = TRUE;
Camera_pwr_up((DEVICE_CONTEXT*)hDeviceContext);
bInPowerHandler = FALSE;
}
////////////////////////////////////////////////////////////////////////
// Power Down
////////////////////////////////////////////////////////////////////////
void
CAM_PowerDown(
DWORD hDeviceContext
)
{
// **** TBD: Pause any activity?
bInPowerHandler = TRUE;
Camera_pwr_down((DEVICE_CONTEXT*)hDeviceContext);
bInPowerHandler = FALSE;
}
////////////////////////////////////////////////////////////////////////
// I/O Control Device
////////////////////////////////////////////////////////////////////////
BOOL
CAM_IOControl(
DWORD hOpenContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
)
{
DWORD actual = 0;
DWORD result = ERROR_SUCCESS;
DEVICE_CONTEXT *pDevice = (DEVICE_CONTEXT *) hOpenContext;
if ( ! pDevice )
{
RETAILMSG(1, (TEXT("CAM_IOControl - Device context not allocated\r\n")));
result = ERROR_GEN_FAILURE;
goto error_exit;
}
DEBUGMSG(ZONE_TRACE,
(TEXT("CAM: CAM_IOControl(0x%X, 0x%X, %d, 0x%X, %d, 0x%X)\r\n"),
dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut));
//////////////////////////
// Process request.
//////////////////////////
switch ( dwCode )
{
case IOCTL_CAMERA_QUERY:
// **** TBD: Define parameters
// **** TBD: Verify parameters
// **** TBD: Return whatever we are returning
DEBUGMSG(ZONE_TRACE, (L" CAM QUERY Mode\r\n"));
if (dwLenOut < sizeof(CameraMode)) {
result = ERROR_INSUFFICIENT_BUFFER;
goto error_exit;
} else {
CAMERA *pcam = pDevice->cam_base.cmos_camera;
if (pcam) {
CameraMode *pmode = (CameraMode*) pBufOut;
pmode->mode = pcam->camera_resformat;
memcpy(pmode->modename, pcam->camera_mode, sizeof(pcam->camera_mode));
pmode->width = pcam->frame_width;
pmode->height = pcam->frame_height;
pmode->nPlanes = pcam->dbdma_channel;
actual = sizeof(*pmode);
} else {
// no configuration has been set so there's nothing to report
result = ERROR_NOT_CONNECTED; // for lack of a better choice
goto error_exit;
}
}
break;
case IOCTL_CAMERA_CONFIGURE:
{
int resmode, mode_index;
// BufIn is an int, identifying the camera mode to configure.
// A list of modes is enumerated in camera.h.
// Only modes 1 through 7 are known to work yet.
if (dwLenIn != sizeof(int)) {
result = ERROR_INVALID_DATA;
goto error_exit;
}
memcpy(&resmode, pBufIn, sizeof(int));
for (mode_index=0; mode_index<NUM_CAMERA_MODES; ++mode_index)
if (resmode == CameraModes[mode_index].camera_resformat)
break;
if (mode_index == NUM_CAMERA_MODES) {
result = ERROR_INVALID_INDEX;
goto error_exit;
}
DEBUGMSG(ZONE_TRACE, (L" CAM CONFIGURE Mode %d => Index %d\n", resmode, mode_index));
pDevice->dwCurrentMode = mode_index;
pDevice->cam_base.cmos_camera = &CameraModes[mode_index];
/* Configure CMOS Camera*/
if (!pDevice->bPowerIsOn) {
DEBUGMSG(ZONE_TRACE, (L" CAM CONFIGURE turning camera power on\n"));
Camera_pwr_up(pDevice);
}
pCim->enable &= ~CIM_ENABLE_EN;
if (Camera_Config(&pDevice->cam_base) == 0) {
Camera_pwr_down(pDevice);
Sleep(1);
Camera_pwr_up(pDevice);
Sleep(6);
} else {
result = ERROR_GEN_FAILURE;
}
}
break;
case IOCTL_CAMERA_CAPTURE:
{
CAMERA* pcam = pDevice->cam_base.cmos_camera;
DWORD camera_status;
PMDL mdl[MAX_DBDMA_CHANNEL]; // hold the MDLs until the capture completes
if (pcam == 0) {
// unconfigured cameras cannot take snapshots!
result = ERROR_NOT_CONNECTED; // would prefer NOT_CONFIGURED if it existed.
goto error_exit;
}
DEBUGMSG(ZONE_TRACE, (L"CAM CAPTURE: Camera Array Index # %d : %s (%d x %d = %d)\r\n",
pDevice->dwCurrentMode,
pcam->camera_mode,
pcam->frame_width,
pcam->frame_height,
pcam->frame_width * pcam->frame_height));
// Fetch and validate parameters
if (((DWORD)pBufOut & 3) != 0) {
// bad buffer alignment!
result = ERROR_INVALID_DATA;
}
if (dwLenOut < pcam->frame_width*pcam->frame_height) {
result = ERROR_INSUFFICIENT_BUFFER;
}
if (result != ERROR_SUCCESS)
goto error_exit;
// Make sure there is no stray interrupt pending
while (WaitForSingleObject(pDevice->hInterruptEvent, 0) == WAIT_OBJECT_0)
{
pCim->instat = 0x1ff; // ack all intrs; don't care what they are.
InterruptDone(pDevice->dwSysintr);
}
// Setup the DMA engine so we point directly to the user's buffer
{
int i;
DWORD count = 0;
for (i=0; i<pcam->dbdma_channel; ++i) {
mdl[i] = MmCreateMdl(NULL, pBufOut+count, pDevice->cam_base.nTransferSize[i]);
if (mdl[i] == NULL) {
RETAILMSG(1, (L"CAM CAPTURE: Cannot allocate a memory descriptor list\r\n"));
while (i > 0) {
MmFreeMdl(mdl[--i]);
}
goto error_exit;
}
count += pDevice->cam_base.nTransferSize[i];
mdl[i]->Next = 0; // necessary? (copied from sample code)
HalSetupMdlDMA(pDevice->cam_base.ChannelArray[i], mdl[i], TRUE);
}
for (i=0; i<pcam->dbdma_channel; ++i) {
HalStartMdlDMA(pDevice->cam_base.ChannelArray[i]);
}
}
#ifdef BLANKSCREEN // this alleviates memory bus contention while streaming from the camera
{ DWORD oldlcd = *(DWORD*)0xb5000024; *(DWORD*)0xb5000024 = 0;
#endif
Capture_Image(); // trigger the snapshot
DEBUGMSG(ZONE_TRACE, (L"CAM CAPTURE:Status Reg %x Capture Reg %x IntStat %x\r\n",
pCim->stat, pCim->capture, pCim->instat));
// wait for the snapshot to complete.
camera_status = 0;
do {
DWORD t;
WaitForSingleObject(pDevice->hInterruptEvent, INFINITE);
t = pCim->instat; // perform only one read
camera_status |= t; // and remember that the condition occurred
pCim->instat = t; // ack the interrupt/s
InterruptDone(pDevice->dwSysintr);
} while ( ! (camera_status & CIM_INTEN_CD) ); // repeat until done
DEBUGMSG(ZONE_TRACE, (L"CAM CAPTURE: cleaning\r\n"));
#ifdef BLANKSCREEN
*(DWORD*)0xb5000024 = oldlcd; }
#endif
{
int i;
DWORD count;
for (i=0; i<pcam->dbdma_channel; ++i) {
HalStopMdlDMA(pDevice->cam_base.ChannelArray[i], &count);
DEBUGMSG(ZONE_TRACE, (L"CAM CAPTURE: got %d bytes on channel %d\r\n", count, i));
HalCompleteMdlDMA(pDevice->cam_base.ChannelArray[i], mdl[i]);
MmFreeMdl(mdl[i]);
actual += count;
}
}
DEBUGMSG(ZONE_TRACE, (L"CAM CAPTURE:Status Reg %x Capture Reg %x IntStat %x\r\n",
pCim->stat, pCim->capture, camera_status));
DEBUGMSG(ZONE_TRACE, (L"CAM CAPTURE: Snapped %d bytes\r\n", actual));
}
break;
default:
result = ERROR_NOT_SUPPORTED;
break;
}
error_exit:
if ( pdwActualOut )
{
*pdwActualOut = actual;
}
if ( result != ERROR_SUCCESS )
{
SetLastError(result);
}
return(result == ERROR_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -