⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 camera.c

📁 au1200的在wince5.0下的摄像头驱动.
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -