📄 camera.c
字号:
/*******************************************************
Clean Up Function (cleans memory, channel allocation etc)
********************************************************/
void CAM_Cleanup( CAMERA_RUNTIME *cim_cleanup)
{
CAMERA *cim_ptr;
DWORD frame_size;
int i;
cim_ptr = cim_cleanup->cmos_camera;
frame_size = cim_ptr->frame_width*cim_ptr->frame_height;
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: CAM_Cleanup: cleaning mode %s\r\n"),
cim_ptr->camera_mode));
for ( i= 0; i < cim_ptr->dbdma_channel; i++ )
{
if ( cim_cleanup->ChannelArray[i] )
{
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: Releasing ChannelArray[%d]\r\n"), i));
HalStopMdlDMA(cim_cleanup->ChannelArray[i], NULL);
HalFreeDMAChannel(cim_cleanup->ChannelArray[i]);
cim_cleanup->ChannelArray[i] = NULL;
}
}
cim_cleanup->cmos_camera = 0; // mark the camera "unconfigured"
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: DMA Channel and Memory Cleared Now!\r\nCAM: Ready to be reused\r\n")));
}
/****************************************************************************
DMA Channel COnfiguration
External Camera configuration using SMBus
Au1200 Comtrol Block configuration
****************************************************************************/
int Camera_Config(CAMERA_RUNTIME* cim_config )
{
int i;
CAMERA * const cim_config_ptr = cim_config->cmos_camera;
const DWORD frame_size = cim_config_ptr->frame_width * cim_config_ptr->frame_height;
int ErrorCheck = 0;
DWORD nCameraModeConfig = 0;
DWORD nClearSetInterrupt = 0;
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: Camera_Config: width %d, height %d, ch %d, DPS mode %d\r\n"),
cim_config_ptr->frame_width,
cim_config_ptr->frame_height,
cim_config_ptr->dbdma_channel,
cim_config_ptr->au1200_dpsmode));
/*************************************************
Setting up DBDMA Channel
*************************************************/
// To get rid of hard-coded number from Transfer Size,
// transfer size will be calulated on the fly:
// In YCbCr 4:2:2 data size is twice the frame size
// Y=Frame Size
// Cb=Frame Size/2
// Cr=Frame Size/2
// Total size of Frame: Y+Cb+Cr effectively 2*FrameSize
if ( cim_config_ptr->au1200_dpsmode == CIM_CONFIG_RAW )
{
if ( cim_config_ptr->cmos_output_format == CMOS_CCIR656 )
{
cim_config->nTransferSize[0] = frame_size * 2;
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: FIFO-A YCbCR Transfer Size in Raw mode %d \r\n"),
cim_config->nTransferSize[0]));
}
else
{
cim_config->nTransferSize[0] = frame_size;
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: FIFO-A RGB Transfer Size in Raw mode %d \r\n"),
cim_config->nTransferSize[0]));
}
}
else if ( cim_config_ptr->au1200_dpsmode == CIM_CONFIG_BAYER )
{
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: Bayer Mode (Planar) Memory Size Calculation\r\n")));
/* FIFO A Hold Red Pixels which is Total Pixels/4 */
cim_config->nTransferSize[0] = frame_size / 4;
cim_config->nTransferSize[1] = frame_size / 2;
cim_config->nTransferSize[2] = frame_size / 4;
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: Transfer Size of FIFO-A %d FIFO-B %d & FIFO-C in Bayer Mode %d\r\n"),
cim_config->nTransferSize[0],
cim_config->nTransferSize[1],
cim_config->nTransferSize[2]));
}
else
{
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: CCIR656 (Planar) Mode Memory Size Calculation\r\n")));
cim_config->nTransferSize[0] = frame_size;
cim_config->nTransferSize[1] = frame_size / 2;
cim_config->nTransferSize[2] = frame_size / 2;
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: Transfer Size of FIFO-A %d FIFO-B %d & FIFO-C in CCIR656 Mode %d\r\n"),
cim_config->nTransferSize[0],
cim_config->nTransferSize[1],
cim_config->nTransferSize[2]));
}
// Make sure that if cleanup is necessary, it won't be cleaning garbage.
for ( i=0; i< cim_config->cmos_camera->dbdma_channel;i++ )
{
cim_config->ChannelArray[i] = NULL;
}
ErrorCheck++; // we're initted now; error returns must clean up.
for ( i=0; i<cim_config->cmos_camera->dbdma_channel; i++ )
{
/* Allocate Channel */
cim_config->ChannelArray[i] = HalAllocateDMAChannel();
if (cim_config->ChannelArray[i] == NULL) {
RETAILMSG(1, (L"CAM: Cannot allocate a DMA channel for FIFO-%c\r\n", 'A'+i));
goto error_ch_alloc;
}
if (!HalInitDmaChannel(cim_config->ChannelArray[i], DMA_CIM_FIFOA+i, 0, FALSE)) {
RETAILMSG(1, (L"CAM: Cannot init the DMA channel for FIFO-%c\r\n", 'A'+i));
goto error_ch_alloc;
}
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: Channel # %d Allocated\r\n"), i));
}
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: DMA Successful\r\n")));
/****** END DBDMA****************/
/********************************
Configure CMOS CAMERA
**********************************/
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: CMOS Camera configuration \n")));
{
SMBUS_TRANSFER xfr;
HANDLE h = CreateFile(L"SMB1:", 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
{
DEBUGMSG(ZONE_TRACE, (L"CAM: cannot open a handle to the SMBus\r\n"));
goto error_ch_alloc;
}
xfr.Address = cim_config_ptr->device_addr;
xfr.DataSize = 1;
for ( i=0; i < cim_config_ptr->cmd_size; i++ )
{
int nwr = 0;
xfr.Register = cim_config_ptr->config_cmd[i][0];
xfr.Data[0] = cim_config_ptr->config_cmd[i][1];
if (!DeviceIoControl(h, IOCTL_SMBUS_WRITEDATA, &xfr, sizeof(SMBUS_TRANSFER), NULL, 0, &nwr, NULL))
{
DEBUGMSG(ZONE_ERROR, (TEXT("CAM: SMBUS: Camera count cannot be initialized -1 %d\r\n"), i));
break;
}
if ( i == 0 )
Sleep(1);
}
CloseHandle(h);
if ( i != cim_config_ptr->cmd_size )
{
DEBUGMSG(ZONE_ERROR, (TEXT("CAM: External CMOS camera not present or not properly connected!\r\n")));
goto error_ch_alloc;
}
}
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: CMOS camera configuration sucessful\r\n")));
/********************************
Configure CAMERA Interface
**********************************/
/* Enable the Camera Module*/
pCim->enable = CIM_ENABLE_EN;
pCim->capture = CIM_CAPTURE_CLR;
/* Config Register Setting */
nCameraModeConfig = CIM_CONFIG_DPS_N(cim_config_ptr->au1200_dpsmode) |
CIM_CONFIG_FS |
CIM_CONFIG_BAY_N(cim_config_ptr->au1200_baymode) |
CIM_CONFIG_BYT |
CIM_CONFIG_LEN_N(CIM_CONFIG_LEN_10BIT);
switch (cim_config_ptr->au1200_dpsmode) {
case 1: break;
case 0: nCameraModeConfig |= CIM_CONFIG_PM; break;
default: nCameraModeConfig |= CIM_CONFIG_FS_N(CIM_CONFIG_FIELD2); break;
}
pCim->config = nCameraModeConfig;
nClearSetInterrupt= CIM_INSTAT_CD | CIM_INSTAT_FD |
CIM_INSTAT_UFA | CIM_INSTAT_OFA |
CIM_INSTAT_UFB | CIM_INSTAT_OFB |
CIM_INSTAT_UFB | CIM_INSTAT_OFC;
// Clear Sticky Bit in the Interrupt Status Register.
pCim->instat = nClearSetInterrupt;
// Set Interrupt Bits in Interrupt Enable Register.
pCim->inten = nClearSetInterrupt;
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: Config register => 0x%08X \r\n"), pCim->config));
Sleep(6);
return 0;
error_ch_alloc:
if ( ErrorCheck )
{
CAM_Cleanup(cim_config);
}
return -1;
}
/***************************************************************
* Init Module
***************************************************************/
////////////////////////////////////////////////////////////////////////
// Driver Entry
////////////////////////////////////////////////////////////////////////
BOOL WINAPI
DllEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved)
{
switch ( Reason )
{
case DLL_PROCESS_ATTACH:
DEBUGREGISTER(DllInstance);
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: DllEntry: DLL_PROCESS_ATTACH\r\n")));
break;
case DLL_PROCESS_DETACH:
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: DllEntry: DLL_PROCESS_DETACH\r\n")));
break;
default:
break;
}
// return TRUE for success, FALSE for failure
return TRUE;
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Windows CE Device Driver Entry Points
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Initialize Device
////////////////////////////////////////////////////////////////////////
BOOL CAM_Deinit(DWORD hDeviceContext);
DWORD
CAM_Init(DWORD pContext)
{
DEVICE_CONTEXT *pDevice = 0;
PHYSICAL_ADDRESS PhysAddr;
DEBUGMSG(ZONE_TRACE, (TEXT("CAM: CAM_Init(%s)\r\n"), pContext));
// Allocate device context.
pDevice = LocalAlloc(LPTR, sizeof(DEVICE_CONTEXT));
if ( ! pDevice )
{
DEBUGMSG(ZONE_ERROR, (TEXT("CAM_Init: Failed to allocate device context\r\n")));
goto error_exit;
}
memset(pDevice, 0, sizeof(*pDevice));
// Map Camera Interface Module registers.
PhysAddr.HighPart = 0;
PhysAddr.LowPart = CIM_PHYS_ADDR;
pCim = MmMapIoSpace(PhysAddr, sizeof(AU1200_CIM), FALSE);
if ( pCim == NULL )
{
DEBUGMSG(ZONE_ERROR, (TEXT("CAM_Init: MmMapIoSpace 0x%08X Failed!\r\n"),
CIM_PHYS_ADDR));
goto error_exit;
}
DEBUGMSG(ZONE_TRACE, (TEXT("CAM_Init: CIM: physical 0x%08X => virtual 0x%08X\r\n"),
PhysAddr.LowPart, pCim));
// Map board contol registers.
PhysAddr.HighPart = 0;
PhysAddr.LowPart = BCSR_PHYSADDR;
pBcsr = MmMapIoSpace(PhysAddr, sizeof(BCSR), FALSE);
if ( pBcsr == NULL )
{
DEBUGMSG(ZONE_ERROR, (TEXT("CAM_Init: MmMapIoSpace 0x%08X Failed!\r\n"),
BCSR_PHYSADDR));
goto error_exit;
}
DEBUGMSG(ZONE_TRACE, (TEXT("CAM_Init: BCSR: physical 0x%08X => virtual 0x%08X\r\n"),
PhysAddr.LowPart, pBcsr));
// Hook the interrupt.
if ((pDevice->hInterruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == INVALID_HANDLE_VALUE)
{
DEBUGMSG(ZONE_ERROR, (TEXT("CAM_Init: cannot create the interrupt event!\r\n")));
pDevice->hInterruptEvent = 0; // so it looks like we didn't even try to create it
goto error_exit;
}
if ((pDevice->dwSysintr = InterruptConnect(Internal, 0, HWINTR_CIM, 0)) == SYSINTR_NOP)
{
DEBUGMSG(ZONE_ERROR, (TEXT("CAM_Init: cannot allocate a sysintr for the CIM!\r\n")));
goto error_exit;
}
if (!InterruptInitialize(pDevice->dwSysintr, pDevice->hInterruptEvent, NULL, 0))
{
DEBUGMSG(ZONE_ERROR, (TEXT("CAM_Init: cannot init the CIM interrupt!\r\n")));
goto error_exit;
}
// Initialize global flags.
pDevice->bPowerIsOn = FALSE;
pDevice->dwCurrentMode = 0;
// Done.
return((DWORD) pDevice);
error_exit:
if ( pDevice )
{
// This also frees the allocated memory for pDevice:
CAM_Deinit((DWORD) pDevice);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -