📄 ewl.c
字号:
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- In the event of publication, the following notice is applicable: --
-- --
-- (C) COPYRIGHT 2005 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced on all copies. --
-- --
--------------------------------------------------------------------------------
--
-- Project : 1200s
--
-- Abstract : Encoder wrapper for 5251_encoder in WinCE 5.0/MX31
--
-------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of context
1. Include headers
2. Module defines
3. Local static data
4. Local function prototypes
5. Functions
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
// WinCE and MX31 BSP
#include <windows.h>
#include <pkfuncs.h>
#include <ceddk.h>
#include <csp.h>
// mp4enc
#include "ewl.h"
#include "enchw.h"
/*------------------------------------------------------------------------------
2. Module defines
------------------------------------------------------------------------------*/
typedef struct
{
EncHw_t* EncHw; // handle to encoder HW abstraction
u32* MemBase; // virtual base address for memory pool
u32 MemBus; // bus address for memory pool
u32 MemSize; // size of memory pool
u32* FreeMem; // next free memory
HANDLE InterruptEvent; // event triggered by interrupt
DWORD SysIntr; // system-level interrupt id
DDK_CLOCK_GATE_MODE SavedClockMode; // saved clock gating settings
HANDLE InstanceMutex; // ensure there is only one encoder instance
} enc_t;
#define ENC_MEM_SIZE 1<<20 // reserve 1 MB for linear allocation pool
#define ENC_INTR_IRQ IRQ_MPEG4_ENCODE // IRQ number defined in CSP
#define ENC_INTR_TIMEOUT 2000 // timeout for encoder ready interrupt
#define ENC_ENCHW_TIMEOUT 10000 // timeout for encoder hw access
#define ENC_INSTANCE_MUTEX _T("ENC_INSTANCE_MUTEX")
#define ENC_DEBUG 1 // define to non-zero to enable debug messages
#define ENC_DEBUG_EXTRA 0 // enables verbose debug messages
/*------------------------------------------------------------------------------
3. Local static data
------------------------------------------------------------------------------*/
static enc_t* gEnc = NULL;
static HANDLE gSingleInstance = NULL;
/*------------------------------------------------------------------------------
4. Local function prototypes
------------------------------------------------------------------------------*/
static enc_t* AllocSingleEncInstance(void);
static i32 FreeSingleEncInstance( enc_t* );
static i32 SetupInterrupt(void);
/*------------------------------------------------------------------------------
5. Functions
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
EWL_Init
------------------------------------------------------------------------------*/
i32 EWL_Init(void)
{
BOOL status;
// 1. Allocate encoder wrapper instance
gEnc = AllocSingleEncInstance();
if( gEnc == NULL )
{
// NULL is returned for both memory exhausted and not single instance
DEBUGMSG( ENC_DEBUG, (_T("EWL_Init: AllocSingleEncInstance failed %d\r\n"), GetLastError()) );
return EWL_NOK;
}
// 2. Init encoder HW
gEnc->EncHw = EncHw_Init();
if( gEnc->EncHw == NULL )
{
EWL_Release();
return EWL_NOK;
}
// 3. Reset encoder HW
status = ENCHW_LOCK( gEnc->EncHw, ENC_ENCHW_TIMEOUT );
if( !status )
{
DEBUGMSG( ENC_DEBUG, (_T("EWL_Init: ENCHW_LOCK failed\r\n")) );
EWL_Release();
return EWL_NOK;
}
EncHw_Reset( gEnc->EncHw );
ENCHW_UNLOCK( gEnc->EncHw );
// 4. Allocate memory pool LinearMalloc
gEnc->MemBase = AllocPhysMem( ENC_MEM_SIZE, PAGE_READWRITE, 0, 0, &gEnc->MemBus );
if( gEnc->MemBase == NULL )
{
DEBUGMSG( ENC_DEBUG, (_T("EWL_Init: AllocPhysMem failed %d\r\n"), GetLastError()) );
EWL_Release();
return EWL_NOK;
}
gEnc->FreeMem = gEnc->MemBase;
gEnc->MemSize = ENC_MEM_SIZE;
// 5. Setup interrupt and event handler
if( SetupInterrupt() != EWL_OK )
{
EWL_Release();
return EWL_NOK;
}
DEBUGMSG( ENC_DEBUG_EXTRA, (_T("EWL_Init: Ok!\r\n")) );
return EWL_OK;
}
/*------------------------------------------------------------------------------
EWL_Release
------------------------------------------------------------------------------*/
i32 EWL_Release(void)
{
ASSERT( gEnc != NULL );
// 5.b. Release interrupt
if( gEnc->SysIntr != 0 )
{
InterruptDisable( gEnc->SysIntr );
KernelIoControl( IOCTL_HAL_RELEASE_SYSINTR, &gEnc->SysIntr, sizeof(DWORD), NULL, 0, NULL) ;
gEnc->SysIntr = 0;
}
// 5.a. Release interrupt event
if( gEnc->InterruptEvent != NULL )
{
CloseHandle( gEnc->InterruptEvent );
gEnc->InterruptEvent = NULL;
}
// 4. Release memory pool
if( gEnc->MemBase != NULL )
{
FreePhysMem( gEnc->MemBase );
gEnc->MemBase = NULL;
gEnc->MemBus = 0;
gEnc->MemSize = 0;
gEnc->FreeMem = NULL;
}
// 3. Nothing to be for HW reset!
// 2. Release encoder HW
if( gEnc->EncHw != NULL )
{
EncHw_Release( gEnc->EncHw );
gEnc->EncHw = NULL;
}
// 1. Release encoder wrapper
(void)FreeSingleEncInstance( gEnc );
gEnc = NULL;
DEBUGMSG( ENC_DEBUG_EXTRA, (_T("EWL_Release: Ok!\r\n")) );
return EWL_OK;
}
/*------------------------------------------------------------------------------
EWL_WriteReg
------------------------------------------------------------------------------*/
void EWL_WriteReg( u32 offset, u32 val )
{
BOOL status;
ASSERT( gEnc!=NULL && gEnc->EncHw!=NULL );
// Lock access to encoder hw registers
status = ENCHW_LOCK( gEnc->EncHw, ENC_ENCHW_TIMEOUT );
if( !status )
{
DEBUGMSG( ENC_DEBUG, (_T("EWL_WriteReg: ENCHW_LOCK failed. PowerDown failed?\r\n")) );
return; // EWL_NOK
}
// Actual register write
EncHw_WriteReg( gEnc->EncHw, offset, val );
ENCHW_UNLOCK( gEnc->EncHw );
DEBUGMSG( ENC_DEBUG_EXTRA, (_T("EWL_WriteReg: Offset=%02X val=%08X\r\n"), offset, val) );
}
/*------------------------------------------------------------------------------
EWL_ReadReg
------------------------------------------------------------------------------*/
u32 EWL_ReadReg( u32 offset )
{
BOOL status;
u32 val;
ASSERT( gEnc!=NULL && gEnc->EncHw!=NULL );
// Lock access to encoder hw registers
status = ENCHW_LOCK( gEnc->EncHw, ENC_ENCHW_TIMEOUT );
if( !status )
{
DEBUGMSG( ENC_DEBUG, (_T("EWL_ReadReg: ENCHW_LOCK failed. PowerDown failed?\r\n")) );
return (u32)-1; // EWL_NOK
}
// Actual register read
val = EncHw_ReadReg( gEnc->EncHw, offset );
ENCHW_UNLOCK( gEnc->EncHw );
DEBUGMSG( ENC_DEBUG_EXTRA, (_T("EWL_ReadReg: Offset=%02X val=%08X\r\n"), offset, val) );
return val;
}
/*------------------------------------------------------------------------------
EWL_MallocLinear
------------------------------------------------------------------------------*/
u32* EWL_MallocLinear( u32 size )
{
u32* pNextFree;
u32* pAlloc;
ASSERT( gEnc!=NULL && size>0 && size<=gEnc->MemSize );
// round up to a 4 multiple
size = (size + 3) & (~0x03);
pNextFree = gEnc->FreeMem + size/4;
if( pNextFree >= gEnc->MemBase + gEnc->MemSize/4 )
{
DEBUGMSG( ENC_DEBUG, (_T("EWL_MallocLinear: failed, no free memory\r\n")) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -