📄 cameraimagic.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2006,2007, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
// File: CameraImagicClass.cpp
//
// Definitions for Imagic camera module specific
//
//------------------------------------------------------------------------------
#include <windows.h>
#include "cameradbg.h"
#include "bsp.h"
#include "i2cbus.h"
#include "ipu.h"
#include "CsiClass.h"
#include "bspcsi.h"
#include "CameraImagic.h"
//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------
// External Variables
extern csiSensorId gSensorInUse;
//------------------------------------------------------------------------------
// Defines
//#define IM8803_I2C_WR_ADDRESS 0xB8 // MT9V143 only allows writes to this address
#define IM8803_I2C_ADDRESS 0x48 // MT9V143 only allows writes to this address
#define IM8803_I2C_SPEED 81000
#define IM8201_I2C_ADDRESS 0x48 // MT9V111 only allows writes to this address
#define IM8201_I2C_SPEED 81000
#define CAMERA_FUNCTION_ENTRY() \
DEBUGMSG(ZONE_FUNCTION, (TEXT("++%s\r\n"), __WFUNCTION__))
#define CAMERA_FUNCTION_EXIT() \
DEBUGMSG(ZONE_FUNCTION, (TEXT("--%s\r\n"), __WFUNCTION__))
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
// Local Variables
HANDLE hI2C;
//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------
//
// Function: CameraImagicInit
//
// Initializes the Imagic camera sensor.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void CameraImagicInit(void)
{
INT iResult;
DWORD dwFrequency;
BYTE bySlaveAddr, byCsiAddr;
CAMERA_FUNCTION_ENTRY();
byCsiAddr = CSI_I2C_ADDRESS;
switch (gSensorInUse)
{
case csiSensorId_Imagic8803:
dwFrequency = IM8803_I2C_SPEED;
bySlaveAddr = IM8803_I2C_ADDRESS;
break;
case csiSensorId_Imagic8201:
dwFrequency = IM8201_I2C_SPEED;
bySlaveAddr = IM8201_I2C_ADDRESS;
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("%s: We don't support this kind of sensor!\r\n"), __WFUNCTION__));
return;
}
hI2C = CreateFile(I2C_FID_CAM, // name of device
GENERIC_READ|GENERIC_WRITE, // desired access
FILE_SHARE_READ|FILE_SHARE_WRITE, // sharing mode
NULL, // security attributes (ignored)
OPEN_EXISTING, // creation disposition
FILE_FLAG_RANDOM_ACCESS, // flags/attributes
NULL);
if (hI2C == INVALID_HANDLE_VALUE)
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s: CreateFile for I2C failed!\r\n"), __WFUNCTION__));
}
// Initialize the device internal fields
if (!I2C_MACRO_SET_FREQUENCY(hI2C, dwFrequency))
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s: Set I2C frequency failed!\r\n"), __WFUNCTION__));
}
if (!I2C_MACRO_SET_SELF_ADDR(hI2C, byCsiAddr))
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s: Set I2C self address failed!\r\n"), __WFUNCTION__));
}
// switch to sensor registers
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x01, 0x00, 0x04, &iResult);
if (iResult != I2C_NO_ERROR)
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s: I2C communication with camera sensor failed! Result = %x\r\n"), __WFUNCTION__, iResult));
}
//soft reset
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x0D, 0x00, 0x01, &iResult);
Sleep(10);
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x0D, 0x00, 0x00, &iResult);
// Output Control register
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x07, 0x00, 0x03, &iResult); // enable changes
// Shutter width
// I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x09, 0xB9, 0x01, &iResult);
// Pixel clock speed
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x0A, 0x00, 0x00, &iResult); // min PIXCLK
// Read Mode
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x20, 0xD0, 0xA1, &iResult); // read from top to bottom (rotate by 180 deg)
// Zoom
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x1E, 0x00, 0x00, &iResult); // 1x
/*
// First Row
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x08, 0x00, 0x08, &iResult); // 8
// First Column
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x02, 0x00, 0x14, &iResult); // 20
// Window Height
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x03, 0x01, 0xDF, &iResult); // 479
// Window Width
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x04, 0x02, 0x7F, &iResult); // 639
// Zoom Colstart
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x12, 0x00, 0x00, &iResult); // 0
// Zoom Rowstart
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x13, 0x00, 0x00, &iResult); // 0
*/
// Min H-blank
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x05, 0x00, 0x7B, &iResult); // 123
// Min V-blank
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x06, 0x00, 0x03, &iResult); // 3
// Changes effective
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x07, 0x00, 0x02, &iResult); // changes become effective
// Switch to IFP registers
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x01, 0x00, 0x01, &iResult);
// Operation Mode Control
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x06, 0x70, 0x8E, &iResult);
// Output Format
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x08, 0xC8, 0x00, &iResult);
/*
// Output Format 2
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x3A, 0x00, 0x00, &iResult);
//workaround for read mode control
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x37, 0x00, 0x01, &iResult); // fix for flickering
*/
CAMERA_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: CameraImagicDeinit
//
// Deinitialize the Imagic Sensor.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void CameraImagicDeinit(void)
{
CAMERA_FUNCTION_ENTRY();
CloseHandle(hI2C);
CAMERA_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: CameraImagicSetOutputFormat
//
// Set interface to configure camera output format.
//
// Parameters:
// outputFormat
// [in] structure indicating the sensor output format:
// csiSensorOutputFormat_CCIR656 - CCIR656
// csiSensorOutputFormat_RGB565 - RGB565
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void CameraImagicSetOutputFormat(cameraOutputFormat outputFormat)
{
WORD data;
INT iResult;
BYTE bySlaveAddr;
CAMERA_FUNCTION_ENTRY();
if (gSensorInUse == csiSensorId_Imagic8803)
{
bySlaveAddr = IM8803_I2C_ADDRESS;
}
else
{
bySlaveAddr = IM8201_I2C_ADDRESS;
}
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x01, 0x00, 0x01, &iResult); // select IFP register
data = I2CReadTwoBytes(hI2C, bySlaveAddr, 0x08, &iResult);
switch (outputFormat)
{
case cameraOutputFormat_CCIR656:
data &= ~0x1000; // Clear bit 12
break;
case cameraOutputFormat_RGB565:
data |= 0x1000; // Set bit 12
break;
}
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x08, (BYTE)data, *((BYTE *)&data + 1), &iResult); // select IFP register
CAMERA_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: CameraImagicSetOutputResolution
//
// Set interface to configure camera output resolution.
//
// Parameters:
// outputResolution
// [in] Structure indicating the camera output resolution:
// csiSensorOutputResolution outputResolution :
// csiSensorOutputResolution_VGA - VGA 640x480
// csiSensorOutputResolution_QVGA - QVGA 320x240
// csiSensorOutputResolution_CIF - CIF 352x288
// csiSensorOutputResolution_QCIF - QCIF 176x144
// csiSensorOutputResolution_QQVGA - QQVGA 160x120
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void CameraImagicSetOutputResolution(csiSensorOutputResolution outputResolution)
{
INT iResult;
BYTE bySlaveAddr;
CAMERA_FUNCTION_ENTRY();
if (gSensorInUse == csiSensorId_Imagic8803)
{
bySlaveAddr = IM8803_I2C_ADDRESS;
}
else
{
bySlaveAddr = IM8201_I2C_ADDRESS;
}
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x01, 0x00, 0x01, &iResult); // select IFP register
switch (outputResolution)
{
case csiSensorOutputResolution_VGA:
if (gSensorInUse == csiSensorId_Imagic8803)
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x46, 0x00, 0x00, &iResult); // VGA
}
else
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xA7, 0x02, 0x80, &iResult); // VGA
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xAA, 0x01, 0xE0, &iResult);
}
break;
case csiSensorOutputResolution_QVGA:
if (gSensorInUse == csiSensorId_Imagic8803)
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x46, 0x00, 0x01, &iResult); // QVGA
}
else
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xA7, 0x01, 0x40, &iResult); // QVGA
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xAA, 0x00, 0xF0, &iResult);
}
break;
case csiSensorOutputResolution_CIF:
if (gSensorInUse == csiSensorId_Imagic8803)
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x46, 0x00, 0x02, &iResult); // CIF
}
else
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xA7, 0x01, 0x60, &iResult); // CIF
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xAA, 0x01, 0x20, &iResult);
}
break;
case csiSensorOutputResolution_QCIF:
if (gSensorInUse == csiSensorId_Imagic8803)
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x46, 0x00, 0x03, &iResult); // QCIF
}
else
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xA7, 0x00, 0xB0, &iResult); // QCIF
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xAA, 0x00, 0x90, &iResult);
}
break;
case csiSensorOutputResolution_QQVGA:
if (gSensorInUse == csiSensorId_Imagic8803)
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x46, 0x00, 0x04, &iResult); // QQVGA
}
else
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xA7, 0x00, 0xA0, &iResult); // QQVGA
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0xAA, 0x00, 0x78, &iResult);
}
break;
}
CAMERA_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: CameraImagicSetDigitalZoom
//
// Sets the camera digital zoom level to 1x or 2x zoom.
//
// Parameters:
// zoom
// [in] Camera zoom value that will be set
// 2 - 2x zoom
// 1 - 1x zoom
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void CameraImagicSetDigitalZoom(DWORD zoom)
{
INT iResult;
BYTE bySlaveAddr;
CAMERA_FUNCTION_ENTRY();
if (gSensorInUse == csiSensorId_Imagic8803)
{
bySlaveAddr = IM8803_I2C_ADDRESS;
}
else
{
bySlaveAddr = IM8201_I2C_ADDRESS;
}
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x01, 0x00, 0x04, &iResult); // select IC register
if (2 == zoom)
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x1E, 0x00, 0x01, &iResult);
}
else
{
I2CWriteTwoBytes(hI2C, bySlaveAddr, 0x1E, 0x00, 0x00, &iResult);
}
CAMERA_FUNCTION_EXIT();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -