mirror of
https://github.com/rvtr/twl_wrapsdk.git
synced 2025-10-31 06:11:10 -04:00
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
338 lines
14 KiB
C
338 lines
14 KiB
C
/*---------------------------------------------------------------------------*
|
|
Project: TwlSDK - library - camera
|
|
File: camera_sp.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: $
|
|
$NoKeywords: $
|
|
*---------------------------------------------------------------------------*/
|
|
#include <twl.h>
|
|
#include <twl/camera.h>
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
定数定義
|
|
*---------------------------------------------------------------------------*/
|
|
#define CAMERA_PXI_SIZE_CHECK(nums) \
|
|
if (cameraWork.total != (nums)) { \
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_INVALID_PARAMETER); \
|
|
break; \
|
|
}
|
|
|
|
// アライメント調整してコピーする
|
|
#define CAMERA_UNPACK_U16(d, s) \
|
|
(*(d) = (u16)((((u8*)s)[0] << 0) | (((u8*)s)[1] << 8)))
|
|
#define CAMERA_UNPACK_U32(d, s) \
|
|
(*(d) = (u32)((((u8*)s)[0] << 0) | (((u8*)s)[1] << 8) | (((u8*)s)[2] << 16) | (((u8*)s)[3] << 24)))
|
|
|
|
#define CAMERA_SET_GPIO(r) ((r) |= CAMERA_STBYN_MASK)
|
|
#define CAMERA_CLEAR_GPIO(r) ((r) &= ~CAMERA_STBYN_MASK)
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
型定義
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
静的変数定義
|
|
*---------------------------------------------------------------------------*/
|
|
static BOOL cameraInitialized; // 初期化確認フラグ
|
|
static CAMERAWork cameraWork; // ワーク変数をまとめた構造体
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
内部関数定義
|
|
*---------------------------------------------------------------------------*/
|
|
static void CameraPxiCallback(PXIFifoTag tag, u32 data, BOOL err);
|
|
static void CameraReturnResult(CAMERAPxiCommand command, CAMERAPxiResult result);
|
|
static void CameraReturnResultEx(CAMERAPxiCommand command, CAMERAPxiResult result, u8 size, u8* data);
|
|
static void CameraThread(void *arg);
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: CAMERA_Init
|
|
|
|
Description: CAMERAライブラリを初期化する。
|
|
|
|
Arguments: priority
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
void CAMERA_Init(u32 priority)
|
|
{
|
|
// 初期化済みを確認
|
|
if (cameraInitialized)
|
|
{
|
|
return;
|
|
}
|
|
cameraInitialized = 1;
|
|
|
|
// ワーク初期化
|
|
cameraWork.camera = CAMERA_SELECT_NONE;
|
|
|
|
// PXI関連を初期化
|
|
PXI_Init();
|
|
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CAMERA, CameraPxiCallback);
|
|
|
|
// 実処理を行うスレッドを作成
|
|
OS_InitMessageQueue(&cameraWork.msgQ, cameraWork.msgArray, CAMERA_MESSAGE_ARRAY_MAX);
|
|
OS_CreateThread(&cameraWork.thread,
|
|
CameraThread,
|
|
0,
|
|
(void *)(cameraWork.stack + (CAMERA_THREAD_STACK_SIZE / sizeof(u64))),
|
|
CAMERA_THREAD_STACK_SIZE, priority);
|
|
OS_WakeupThreadDirect(&cameraWork.thread);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: CameraPxiCallback
|
|
|
|
Description: PXI経由で受信したデータを解析する。
|
|
|
|
Arguments: tag - PXI種別を示すタグ。
|
|
data - 受信したデータ。下位26bitが有効。
|
|
err - PXI通信におけるエラーフラグ。
|
|
ARM9側にて同種別のPXIが初期化されていないことを示す。
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
static void CameraPxiCallback(PXIFifoTag tag, u32 data, BOOL err)
|
|
{
|
|
#pragma unused( tag )
|
|
|
|
// PXI通信エラーをチェック
|
|
if (err)
|
|
{
|
|
return;
|
|
}
|
|
// 先頭データ
|
|
if (data & CAMERA_PXI_START_BIT)
|
|
{
|
|
cameraWork.total = (u8)((data & CAMERA_PXI_DATA_NUMS_MASK) >> CAMERA_PXI_DATA_NUMS_SHIFT);
|
|
cameraWork.current = 0;
|
|
cameraWork.command = (CAMERAPxiCommand)((data & CAMERA_PXI_COMMAND_MASK) >> CAMERA_PXI_COMMAND_SHIFT);
|
|
cameraWork.data[cameraWork.current++] = (u8)((data & CAMERA_PXI_1ST_DATA_MASK) >> CAMERA_PXI_1ST_DATA_SHIFT);
|
|
//OS_TPrintf("START_BIT (total=%d, command=%X).\n", cameraWork.total, cameraWork.command);
|
|
}
|
|
// 後続データ
|
|
else
|
|
{
|
|
cameraWork.data[cameraWork.current++] = (u8)((data & 0xFF0000) >> 16);
|
|
cameraWork.data[cameraWork.current++] = (u8)((data & 0x00FF00) >> 8);
|
|
cameraWork.data[cameraWork.current++] = (u8)((data & 0x0000FF) >> 0);
|
|
}
|
|
|
|
// パケット完成
|
|
if (cameraWork.current >= cameraWork.total) // 最大で2つ余分に取得する
|
|
{
|
|
// 受信したコマンドを解析
|
|
switch (cameraWork.command)
|
|
{
|
|
// 既知のコマンド群
|
|
case CAMERA_PXI_COMMAND_INIT:
|
|
case CAMERA_PXI_COMMAND_ACTIVATE:
|
|
case CAMERA_PXI_COMMAND_OUTPUT_WITH_DUAL_ACTIVATION:
|
|
case CAMERA_PXI_COMMAND_RESIZE:
|
|
case CAMERA_PXI_COMMAND_FRAME_RATE:
|
|
case CAMERA_PXI_COMMAND_EFFECT:
|
|
case CAMERA_PXI_COMMAND_FLIP:
|
|
// スレッドを再開
|
|
if (!OS_SendMessage(&cameraWork.msgQ, NULL, OS_MESSAGE_NOBLOCK))
|
|
{
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_FATAL_ERROR);
|
|
}
|
|
break;
|
|
|
|
// 未知のコマンド
|
|
default:
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_INVALID_COMMAND);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: CameraReturnResult
|
|
|
|
Description: PXI経由で処理結果をARM9に送信する。
|
|
|
|
Arguments: command - 対象コマンド
|
|
result - CAMERAPxiResultのひとつ
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
static void CameraReturnResult(CAMERAPxiCommand command, CAMERAPxiResult result)
|
|
{
|
|
u32 pxiData = (u32)(CAMERA_PXI_START_BIT | CAMERA_PXI_RESULT_BIT |
|
|
((command << CAMERA_PXI_COMMAND_SHIFT) & CAMERA_PXI_COMMAND_MASK) |
|
|
((1 << CAMERA_PXI_DATA_NUMS_SHIFT) & CAMERA_PXI_DATA_NUMS_MASK) |
|
|
((result << CAMERA_PXI_1ST_DATA_SHIFT) & CAMERA_PXI_1ST_DATA_MASK));
|
|
while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_CAMERA, pxiData, 0))
|
|
{
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: CameraReturnResultEx
|
|
|
|
Description: 指定後続データをPXI経由でARM7に送信する。
|
|
|
|
Arguments: command - 対象コマンド
|
|
result - CAMERAPxiResultのひとつ
|
|
size - 付加データサイズ
|
|
data - 付加データ
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
static void CameraReturnResultEx(CAMERAPxiCommand command, CAMERAPxiResult result, u8 size, u8* data)
|
|
{
|
|
u32 pxiData = (u32)(CAMERA_PXI_START_BIT | CAMERA_PXI_RESULT_BIT |
|
|
((command << CAMERA_PXI_COMMAND_SHIFT) & CAMERA_PXI_COMMAND_MASK) |
|
|
(((size+1) << CAMERA_PXI_DATA_NUMS_SHIFT) & CAMERA_PXI_DATA_NUMS_MASK) |
|
|
((result << CAMERA_PXI_1ST_DATA_SHIFT) & CAMERA_PXI_1ST_DATA_MASK));
|
|
int i;
|
|
while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_CAMERA, pxiData, 0))
|
|
{
|
|
}
|
|
for (i = 0; i < size; i += 3)
|
|
{
|
|
pxiData = (u32)((data[i] << 16) | (data[i+1] << 8) | data[i+2]);
|
|
while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_CAMERA, pxiData, 0))
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*
|
|
Name: CameraThread
|
|
|
|
Description: CAMERA操作の実処理を行うスレッド。
|
|
|
|
Arguments: arg - 使用しない。
|
|
|
|
Returns: None.
|
|
*---------------------------------------------------------------------------*/
|
|
static void CameraThread(void *arg)
|
|
{
|
|
#pragma unused( arg )
|
|
|
|
OSMessage msg;
|
|
BOOL result;
|
|
u16 data16a;
|
|
u16 data16b;
|
|
|
|
while (TRUE)
|
|
{
|
|
// メッセージが発行されるまで寝る
|
|
(void)OS_ReceiveMessage(&(cameraWork.msgQ), &msg, OS_MESSAGE_BLOCK);
|
|
|
|
// コマンドに従って各種処理を実行
|
|
switch (cameraWork.command)
|
|
{
|
|
case CAMERA_PXI_COMMAND_INIT:
|
|
CAMERA_PXI_SIZE_CHECK(CAMERA_PXI_SIZE_INIT);
|
|
// 両方StandbyでなければStandby状態にする (TODO: 出力なしのまま初期化できるようになればいらなくなる!)
|
|
if (cameraWork.camera != CAMERA_SELECT_NONE)
|
|
{
|
|
if (FALSE == CAMERA_I2CStandby(cameraWork.camera))
|
|
{
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_ILLEGAL_STATUS); // ARM9に処理の失敗を通達
|
|
break;
|
|
}
|
|
}
|
|
result = CAMERA_I2CInit((CameraSelect)cameraWork.data[0]);
|
|
cameraWork.camera = CAMERA_SELECT_NONE; // 初期状態は両方Standby
|
|
CameraReturnResult(cameraWork.command, result ? CAMERA_PXI_RESULT_SUCCESS : CAMERA_PXI_RESULT_ILLEGAL_STATUS); // ARM9に処理の成功を通達
|
|
break;
|
|
|
|
case CAMERA_PXI_COMMAND_ACTIVATE:
|
|
CAMERA_PXI_SIZE_CHECK(CAMERA_PXI_SIZE_ACTIVATE);
|
|
// ここでは、BOTHは設定不可
|
|
if (CAMERA_SELECT_BOTH == cameraWork.data[0])
|
|
{
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_INVALID_PARAMETER); // ARM9に処理の失敗を通達
|
|
break;
|
|
}
|
|
// 変更があるなら切り替える
|
|
if (cameraWork.camera != cameraWork.data[0])
|
|
{
|
|
// 両方StandbyでなければStandby状態にする
|
|
if (cameraWork.camera != CAMERA_SELECT_NONE)
|
|
{
|
|
if (FALSE == CAMERA_I2CStandby(cameraWork.camera))
|
|
{
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_ILLEGAL_STATUS); // ARM9に処理の失敗を通達
|
|
break;
|
|
}
|
|
}
|
|
cameraWork.camera = (CameraSelect)cameraWork.data[0]; // アクティブなカメラの記録
|
|
// 両方Standbyにするのではなければ、指定された方をアクティブにする
|
|
if (cameraWork.camera != CAMERA_SELECT_NONE)
|
|
{
|
|
if (FALSE == CAMERA_I2CResume(cameraWork.camera)) // Standby解除
|
|
{
|
|
CAMERA_I2CStandby(CAMERA_SELECT_BOTH); // 中途半端な状態対策
|
|
cameraWork.camera = CAMERA_SELECT_NONE; // NONEに戻しておく
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_ILLEGAL_STATUS); // ARM9に処理の失敗を通達
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達
|
|
break;
|
|
|
|
case CAMERA_PXI_COMMAND_OUTPUT_WITH_DUAL_ACTIVATION:
|
|
CAMERA_PXI_SIZE_CHECK(CAMERA_PXI_SIZE_OUTPUT_WITH_DUAL_ACTIVATION);
|
|
// ここでは、IN/OUTのみ設定可
|
|
if (CAMERA_SELECT_IN != cameraWork.data[0] && CAMERA_SELECT_OUT != cameraWork.data[0])
|
|
{
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_INVALID_PARAMETER); // ARM9に処理の失敗を通達
|
|
break;
|
|
}
|
|
// (いちいち状態を保存せず) 常に設定する
|
|
cameraWork.camera = CAMERA_SELECT_BOTH; // アクティブなカメラの記録
|
|
if (FALSE == CAMERA_I2CResumeBoth((CameraSelect)cameraWork.data[0]))
|
|
{
|
|
CAMERA_I2CStandby(CAMERA_SELECT_BOTH); // 中途半端な状態対策
|
|
cameraWork.camera = CAMERA_SELECT_NONE; // NONEに戻しておく
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_ILLEGAL_STATUS); // ARM9に処理の失敗を通達
|
|
break;
|
|
}
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達
|
|
break;
|
|
|
|
case CAMERA_PXI_COMMAND_RESIZE:
|
|
CAMERA_PXI_SIZE_CHECK(CAMERA_PXI_SIZE_RESIZE);
|
|
CAMERA_UNPACK_U16(&data16a, &cameraWork.data[1]);
|
|
CAMERA_UNPACK_U16(&data16b, &cameraWork.data[3]);
|
|
result = CAMERA_I2CResize((CameraSelect)cameraWork.data[0], data16a, data16b);
|
|
CameraReturnResult(cameraWork.command, result ? CAMERA_PXI_RESULT_SUCCESS : CAMERA_PXI_RESULT_ILLEGAL_STATUS); // ARM9に処理の成否を通達
|
|
break;
|
|
|
|
case CAMERA_PXI_COMMAND_FRAME_RATE:
|
|
CAMERA_PXI_SIZE_CHECK(CAMERA_PXI_SIZE_FRAME_RATE);
|
|
result = CAMERA_I2CFrameRate((CameraSelect)cameraWork.data[0], cameraWork.data[1]);
|
|
CameraReturnResult(cameraWork.command, result ? CAMERA_PXI_RESULT_SUCCESS : CAMERA_PXI_RESULT_ILLEGAL_STATUS); // ARM9に処理の成否を通達
|
|
break;
|
|
|
|
case CAMERA_PXI_COMMAND_EFFECT:
|
|
CAMERA_PXI_SIZE_CHECK(CAMERA_PXI_SIZE_EFFECT);
|
|
result = CAMERA_I2CEffect((CameraSelect)cameraWork.data[0], (CameraEffect)cameraWork.data[1]);
|
|
CameraReturnResult(cameraWork.command, result ? CAMERA_PXI_RESULT_SUCCESS : CAMERA_PXI_RESULT_ILLEGAL_STATUS); // ARM9に処理の成否を通達
|
|
break;
|
|
|
|
case CAMERA_PXI_COMMAND_FLIP:
|
|
CAMERA_PXI_SIZE_CHECK(CAMERA_PXI_SIZE_FLIP);
|
|
result = CAMERA_I2CFlip((CameraSelect)cameraWork.data[0], (CameraFlip)cameraWork.data[1]);
|
|
CameraReturnResult(cameraWork.command, result ? CAMERA_PXI_RESULT_SUCCESS : CAMERA_PXI_RESULT_ILLEGAL_STATUS); // ARM9に処理の成否を通達
|
|
break;
|
|
|
|
// サポートしないコマンド
|
|
default:
|
|
CameraReturnResult(cameraWork.command, CAMERA_PXI_RESULT_INVALID_COMMAND);
|
|
}
|
|
}
|
|
}
|