twl_wrapsdk/build/tests/camera/camera-4/ARM9/src/main.c
yutaka 1dadd63d17 divide standby/resume functions
support dual activation mode
fix result value
change camera intialization to without output

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@247 4ee2a332-4b2b-5046-8439-1ba90f034370
2007-08-23 01:02:49 +00:00

224 lines
6.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: TwlSDK - tests - camera
File: main.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Log: main.c,v $
$NoKeywords: $
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <twl/camera.h>
#define DMA_NO 5 // 使用するDMA番号(4-7)
#define WIDTH 256 // イメージの幅
#define HEIGHT 192 // イメージの高さ
#define LINES_AT_ONCE CAMERA_GET_MAX_LINES(WIDTH) // 一回の転送ライン数
#define BYTES_PER_LINE CAMERA_GET_LINE_BYTES(WIDTH) // 一ラインの転送バイト数
static void VBlankIntr(void);
static void CameraIntr(void);
static BOOL startRequest = FALSE;
#if 0
メインメモリにダブルバッファVRAM1枚の構成例
#endif
static int wp; // カメラからデータを取り込み中のバッファ
static int rp; // 最後のVRAMにコピーしたバッファ
static BOOL wp_pending; // 取り込みを中断した (再び同じバッファに取り込む)
static u16 buffer[2][WIDTH*HEIGHT] ATTRIBUTE_ALIGN(32);
static void DebugReport(void)
{
OS_TPrintf("\nCapture to No.%d\tDisplay from No.%d\n", wp, rp);
}
static void PendingCapture(void)
{
wp_pending = TRUE;
}
/*---------------------------------------------------------------------------*
Name: TwlMain
Description: main
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void TwlMain()
{
CAMERAResult result;
// 初期化
OS_Init();
OS_InitThread();
GX_Init();
OS_InitTick();
// Vブランク割り込み設定
OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
(void)OS_EnableIrqMask(OS_IE_V_BLANK);
(void)OS_EnableIrq();
(void)GX_VBlankIntr(TRUE);
(void)OS_EnableInterrupts();
// VRAM表示モード
GX_SetBankForLCDC(GX_VRAM_LCDC_A);
MI_CpuClearFast((void*)HW_LCDC_VRAM_A, BYTES_PER_LINE * HEIGHT); // clear display buffer
wp = 0;
rp = 1;
wp_pending = TRUE;
GX_SetGraphicsMode(GX_DISPMODE_VRAM_A, GX_BGMODE_0, GX_BG0_AS_2D);
//GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
OS_WaitVBlankIntr();
GX_DispOn();
// カメラ初期化
CAMERA_Init(); // wakeup camera module
result = CAMERA_I2CActivate(CAMERA_SELECT_IN);
if (result != CAMERA_RESULT_SUCCESS)
{
OS_TPrintf("CAMERA_I2CActivate was failed. (%d)\n", result);
}
#if 0
result = CAMERA_I2CResize(CAMERA_SELECT_IN, 320, 240);
if (result != CAMERA_RESULT_SUCCESS)
{
OS_TPrintf("CAMERA_I2CResize was failed. (%d)\n", result);
}
#endif
CAMERA_SetTrimmingParamsCenter(WIDTH, HEIGHT, 320, 240); // clipped by camera i/f
CAMERA_SetTrimming(TRUE);
CAMERA_SetOutputFormat(CAMERA_OUTPUT_RGB);
CAMERA_SetTransferLines(CAMERA_GET_MAX_LINES(WIDTH));
// カメラ割り込み設定
//CAMERA_SetVsyncIntrrupt(CAMERA_INTR_VSYNC_POSITIVE_EDGE); // almost end of vblank
CAMERA_SetVsyncIntrrupt(CAMERA_INTR_VSYNC_NEGATIVE_EDGE); // almost begin of vblank
CAMERA_SetBufferErrorIntrrupt(TRUE);
CAMERA_SetMasterIntrrupt(TRUE);
OS_SetIrqFunction(OS_IE_CAM, CameraIntr);
(void)OS_EnableIrqMask(OS_IE_CAM);
// カメラスタート (割り込みハンドラで代用)
startRequest = TRUE;
CameraIntr();
OS_TPrintf("Camera is shooting a movie...\n");
while (1)
{
u16 pad;
u16 trg;
static u16 old = 0xffff; // ignore the trigger by first data
OS_WaitVBlankIntr();
pad = PAD_Read();
trg = (u16)(pad & ~old);
old = pad;
if (trg & PAD_BUTTON_A)
{
DebugReport();
}
}
}
//--------------------------------------------------------------------------------
// Vブランク割り込み処理
//
void VBlankIntr(void)
{
OS_SetIrqCheckFlag(OS_IE_V_BLANK); // checking VBlank interrupt
if (wp == rp)
{
rp ^= 1;
// ここでは単純なコピーだが、フォーマット変換なども可能 (重いけど)
MI_CpuCopyFast(buffer[rp], (void*)HW_LCDC_VRAM_A, BYTES_PER_LINE * HEIGHT);
DC_InvalidateRange(buffer[rp], BYTES_PER_LINE * HEIGHT);
}
}
//--------------------------------------------------------------------------------
// カメラ割り込み処理 (エラー時とVsync時の両方で発生)
//
#define PRINT_RATE 32
void CameraIntr(void)
{
OS_SetIrqCheckFlag(OS_IE_CAM); // checking camera interrupt
if (CAMERA_GetErrorStatus()) // error?
{
OS_TPrintf("Error was occurred.\n");
// 停止処理
CAMERA_StopCapture(); // カメラ停止
CAMERA_ClearBuffer(); // クリア (すぐにできる?)
MIi_StopExDma(DMA_NO); // DMA停止
wp_pending = TRUE; // 次回も同じフレームを使用する
startRequest = TRUE; // カメラ再開要求
return; // waiting next frame (skip current frame)
}
// 以降はVsync時の処理
if (startRequest)
{
CAMERA_ClearBuffer();
CAMERA_StartCapture();
startRequest = FALSE;
}
if (CAMERA_IsBusy() == FALSE) // done to execute stop command?
{
//OS_TPrintf("while stopping the capture or just finished\n");
}
else
{
OS_TPrintf(".");
if (MIi_IsExDmaBusy(DMA_NO)) // NOT done to capture last frame?
{
OS_TPrintf("DMA was not done until VBlank.\n");
MIi_StopExDma(DMA_NO); // DMA停止
// return; // waiting next frame (skip current frame)
}
// start to capture for next frame
if (wp_pending)
{
wp_pending = FALSE;
}
else
{
wp ^= 1;
}
CAMERA_DmaRecvAsync(DMA_NO, buffer[wp], BYTES_PER_LINE * LINES_AT_ONCE, BYTES_PER_LINE * HEIGHT);
}
// debug print
{
static OSTick begin = 0;
static int count = 0;
if (begin == 0) // first time
{
begin = OS_GetTick();
}
else if (++count == PRINT_RATE)
{
OSTick uspf = OS_TicksToMicroSeconds(OS_GetTick() - begin) / count;
int mfps = (int)(1000000000LL / uspf);
OS_TPrintf("%2d.%03d fps\n", mfps / 1000, mfps % 1000);
count = 0;
begin = OS_GetTick();
}
}
}