mirror of
https://github.com/rvtr/twl_wrapsdk.git
synced 2025-10-31 06:11:10 -04:00
肝心の新規マイクライブラリを追加
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@289 4ee2a332-4b2b-5046-8439-1ba90f034370
This commit is contained in:
parent
e48811bca0
commit
e7bc2d65d4
56
build/libraries/mic/ARM7/Makefile
Normal file
56
build/libraries/mic/ARM7/Makefile
Normal file
@ -0,0 +1,56 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: TwlSDK - libraries - camera/ARM7
|
||||
# File: Makefile
|
||||
#
|
||||
# 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: $
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# build ARM & THUMB libraries
|
||||
TWL_CODEGEN_ALL ?= True
|
||||
|
||||
# Codegen for sub processer
|
||||
TWL_PROC = ARM7
|
||||
|
||||
SRCDIR = ./src
|
||||
|
||||
SRCS = twl_mic_server.c twl_mic_api.c
|
||||
|
||||
TARGET_LIB = libtwlmic_sp$(TWL_LIBSUFFIX).a
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# DEBUG版ビルドの場合、RELEASE版でビルドして
|
||||
# DEBUG版のライブラリを装います。
|
||||
|
||||
ifdef NITRO_DEBUG
|
||||
NITRO_BUILD_TYPE = RELEASE
|
||||
endif
|
||||
|
||||
include $(TWLSDK_ROOT)/build/buildtools/commondefs
|
||||
|
||||
INSTALL_TARGETS = $(TARGETS)
|
||||
INSTALL_DIR = $(TWL_INSTALL_LIBDIR)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
do-build: $(TARGETS)
|
||||
|
||||
include $(TWLSDK_ROOT)/build/buildtools/modulerules
|
||||
|
||||
#===== End of Makefile =====
|
||||
481
build/libraries/mic/ARM7/src/twl_mic_api.c
Normal file
481
build/libraries/mic/ARM7/src/twl_mic_api.c
Normal file
@ -0,0 +1,481 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlSDK - library - twlmic
|
||||
File: twl_mic_api.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: $
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
現在未実装の機能として以下の2つがあります。
|
||||
・Auto Gain Control (ゲイン自動調節機能)
|
||||
・IIR Filter (音声入出力フィルタ : High/Low Pass Filter など)
|
||||
|
||||
但し、これらの機能は CODEC のセカンドソース品でも互換性を保てるか
|
||||
どうか確認がとれていないため、ボツる可能性もあります。
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
|
||||
≪TWLにおけるマイクデータの拾い方≫
|
||||
|
||||
現在は FIFO Half DMA起動方式 を実装。
|
||||
|
||||
|
||||
★★ FIFO Half DMA起動方式 ★★
|
||||
|
||||
ブロック転送サイズ :8ワード
|
||||
インターバル :0
|
||||
転送ワード :8ワード
|
||||
総転送ワード :バッファサイズ
|
||||
コンティニュアスモード:OFF
|
||||
|
||||
<解説>
|
||||
|
||||
FIFOに半分データが溜まる度にDMA起動要求がかかり
|
||||
8ワード転送される。
|
||||
バッファサイズ分の転送が完了後に割り込みがかかるので
|
||||
そこでDMAを再設定。
|
||||
|
||||
<メリット>
|
||||
・FIFOとDMAのタイミングがきっちりと合う。
|
||||
・色々な周波数に対応しやすい。
|
||||
|
||||
<デメリット>
|
||||
・DMAがどこまで進んだか分からないためMIC_GetLastSamplingAddress
|
||||
で正確なアドレスが取れない。チックを使用して大体の位置を
|
||||
予測することは可能。
|
||||
|
||||
★★ インターバル方式 ★★
|
||||
|
||||
ブロック転送サイズ :8ワード
|
||||
インターバル :適切値
|
||||
転送ワード :バッファサイズ
|
||||
総転送ワード :バッファサイズ
|
||||
コンティニュアスモード:ON
|
||||
|
||||
<解説>
|
||||
|
||||
周波数からFIFOにデータが溜まるタイミングを逆算し、
|
||||
インターバルを使って見込みでブロックDMAを実行する。
|
||||
すこしずつDMAとFIFOのタイミングがずれていく可能性
|
||||
があるが、バッファサイズ転送毎に再同期が可能。
|
||||
|
||||
<メリット>
|
||||
・DMAの再設定が必要ない
|
||||
|
||||
<デメリット>
|
||||
・他のDMAによりFIFOとのタイミングがずれていく可能性がある。
|
||||
・そのため大きなバッファサイズには向かない
|
||||
・DMAがどこまで進んだか分からないためMIC_GetLastSamplingAddress
|
||||
で正確なアドレスが取れない。チックを使用して大体の位置を
|
||||
予測することは可能。
|
||||
|
||||
★★ 割り込み頻発方式 ★★
|
||||
|
||||
<解説>
|
||||
|
||||
FIFOにデータが半分溜まる度にMIC割り込みを発生させ
|
||||
FIFOからCPUで8ワード取得する。
|
||||
|
||||
<メリット>
|
||||
・バッファのどの位置まで進んだかを正確に把握可能。
|
||||
MIC_GetLastSamplingAddressで正確なアドレスを返すことができる。
|
||||
|
||||
<デメリット>
|
||||
・頻繁に割り込みが発生する。といってもその頻度はDS時代の1/16になる。
|
||||
・そもそもMIC_GetLastSamplingAddressに有用性がないならこの方式はありえない。
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <twl.h>
|
||||
#include <twl/mic.h>
|
||||
#include <twl/cdc.h>
|
||||
#include <twl/snd/ARM7/i2s.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
マクロ定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#define TWL_MIC_TICK_INIT_VALUE 0
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
静的変数定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
static TWLMICParam sMicParam; // パラメータ保存用
|
||||
static OSTick sMicTickStart; // サンプリング開始時Tick
|
||||
static OSTick sMicTickStop; // サンプリング停止時Tick
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
内部関数定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
static void TWL_MICi_ExDmaRecvAsync( u32 dmaNo, void *dest, u32 size );
|
||||
static void TWL_MICi_ExDmaInterruptHandler( void );
|
||||
static void TWL_MICi_FifoInterruptHandler( void );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_DoSampling
|
||||
|
||||
Description: 単発(16bit)のサンプリングを行います。
|
||||
|
||||
Arguments: buffer : サンプリング結果を格納するバッファ
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
TWL_MIC_DoSampling( u16* buffer )
|
||||
{
|
||||
u32 word;
|
||||
const u32 WAIT_MAX = 100;
|
||||
u32 i;
|
||||
|
||||
// 引数チェック
|
||||
SDK_NULL_ASSERT( buffer );
|
||||
|
||||
// サウンド & I2S 回路ON
|
||||
SND_Enable();
|
||||
|
||||
// モノラルサンプリングスタート
|
||||
reg_SND_MICCNT = REG_SND_MICCNT_FIFO_CLR_MASK;
|
||||
reg_SND_MICCNT = (u16)(REG_SND_MICCNT_E_MASK | REG_SND_MICCNT_NR_MASK |
|
||||
MIC_INTR_DISABLE | MIC_SMP_ALL );
|
||||
|
||||
// データが2個以上入るのを待つ
|
||||
for (i=0;i<WAIT_MAX;i++)
|
||||
{
|
||||
if (!(reg_SND_MICCNT & REG_SND_MICCNT_FIFO_EMP_MASK))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// FIFOはワードアクセス
|
||||
word = reg_SND_MIC_FIFO;
|
||||
|
||||
// サンプリング停止
|
||||
reg_SND_MICCNT &= ~REG_SND_MICCNT_E_MASK;
|
||||
|
||||
// 16bit値を格納
|
||||
*buffer = (u16)(word & 0x0000ffff);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_StartAutoSampling
|
||||
|
||||
Description: オートサンプリングを開始します。
|
||||
現在モノラル固定のサンプリングになっています。
|
||||
|
||||
Arguments: param : オートサンプリング用のパラメータ
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
TWL_MIC_StartAutoSampling( TWLMICParam param )
|
||||
{
|
||||
OSIntrMode enabled;
|
||||
u32 ch;
|
||||
|
||||
// 引数チェック
|
||||
SDK_ASSERT( param.dmaNo >= MI_EXDMA_CH_MIN && param.dmaNo <= MI_EXDMA_CH_MAX );
|
||||
SDK_NULL_ASSERT( param.buffer );
|
||||
|
||||
// DMA停止
|
||||
TWL_MIC_StopAutoSampling();
|
||||
|
||||
// 割り込み禁止
|
||||
enabled = OS_DisableInterrupts();
|
||||
|
||||
// サウンド & I2S 回路ON
|
||||
SND_Enable();
|
||||
|
||||
// DMA設定
|
||||
TWL_MICi_ExDmaRecvAsync( param.dmaNo, param.buffer, param.size );
|
||||
|
||||
// DMA割り込みの設定
|
||||
ch = (u32)param.dmaNo - MI_EXDMA_CH_MIN;
|
||||
OS_SetIrqFunction( OS_IE_DMA4 << ch, TWL_MICi_ExDmaInterruptHandler );
|
||||
reg_OS_IF = (OS_IE_DMA4 << ch);
|
||||
reg_OS_IE |= (OS_IE_DMA4 << ch);
|
||||
|
||||
// マイクFIFO割り込みの設定
|
||||
OS_SetIrqFunction( OS_IE_MIC, TWL_MICi_FifoInterruptHandler );
|
||||
reg_OS_IF2 = (OS_IE_MIC >> 32);
|
||||
reg_OS_IE2 |= (OS_IE_MIC >> 32);
|
||||
|
||||
// スタートTick設定
|
||||
sMicTickStart = OS_GetTick();
|
||||
|
||||
// ストップTickクリア
|
||||
sMicTickStop = TWL_MIC_TICK_INIT_VALUE;
|
||||
|
||||
// モノラルサンプリングスタート
|
||||
reg_SND_MICCNT = REG_SND_MICCNT_FIFO_CLR_MASK; //
|
||||
reg_SND_MICCNT = (u16)( REG_SND_MICCNT_E_MASK | //
|
||||
REG_SND_MICCNT_NR_MASK | //
|
||||
MIC_INTR_OVERFLOW | // FIFO破綻で割り込み発生
|
||||
param.frequency );
|
||||
|
||||
// パラメータ保存
|
||||
sMicParam = param;
|
||||
|
||||
// 割り込み復帰
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_StopAutoSampling
|
||||
|
||||
Description: オートサンプリングを停止します。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
TWL_MIC_StopAutoSampling( void )
|
||||
{
|
||||
OSIntrMode enabled = OS_DisableInterrupts();
|
||||
u32 dmaNo = sMicParam.dmaNo;
|
||||
|
||||
// ストップTick設定
|
||||
sMicTickStop = OS_GetTick();
|
||||
|
||||
// マイク停止
|
||||
reg_SND_MICCNT &= ~REG_SND_MICCNT_E_MASK;
|
||||
|
||||
// マイクFIFO割り込み禁止
|
||||
reg_OS_IE2 &= ~(OS_IE_MIC >> 32);
|
||||
reg_OS_IF2 = (OS_IE_MIC >> 32);
|
||||
|
||||
if ( MI_EXDMA_CH_MIN <= dmaNo && dmaNo <= MI_EXDMA_CH_MAX )
|
||||
{
|
||||
u32 ch = dmaNo - MI_EXDMA_CH_MIN;
|
||||
|
||||
// DMA停止
|
||||
MIi_StopExDma( dmaNo );
|
||||
|
||||
// DMA割り込み禁止
|
||||
reg_OS_IE &= ~(OS_IE_DMA4 << ch);
|
||||
reg_OS_IF = (OS_IE_DMA4 << ch);
|
||||
}
|
||||
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_GetLastSamplingAddress
|
||||
|
||||
Description: 最新サンプリングデータの格納アドレスを返します。
|
||||
マイクFIFOからのデータ取得にはDMAを用いますが、
|
||||
DMAが現在どの位置を書き換え中かは知る手段がありません。
|
||||
そのためサンプリング経過時間より現在の位置を予想します。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: 最新サンプリングデータのアドレス(予想)
|
||||
*---------------------------------------------------------------------------*/
|
||||
void*
|
||||
TWL_MIC_GetLastSamplingAddress( void )
|
||||
{
|
||||
void* adress; // 最新データアドレス
|
||||
OSTick past_tick; // 経過チック
|
||||
u32 sampling_count; // 予想サンプリングカウント
|
||||
f32 one_sampling_tick;
|
||||
|
||||
// サンプリング停止状態
|
||||
if (sMicTickStop != TWL_MIC_TICK_INIT_VALUE)
|
||||
{
|
||||
past_tick = sMicTickStop - sMicTickStart;
|
||||
}
|
||||
// サンプリング進行状態
|
||||
else
|
||||
{
|
||||
past_tick = OS_GetTick() - sMicTickStart;
|
||||
}
|
||||
|
||||
/*
|
||||
サンプリングレート47.61kHzの場合、
|
||||
システムクロックが33.514MHz で
|
||||
Tickは64分周のタイマカウンタであるため
|
||||
1サンプリングに必要なチックは
|
||||
|
||||
33.514MHz / 47.61kHz / 64 = 10.9988 チック となる
|
||||
|
||||
FPGAボードではさらに半分にする必要がある
|
||||
*/
|
||||
|
||||
switch ( I2S_GetSamplingRate() )
|
||||
{
|
||||
case I2S_SAMPLING_RATE_32730:
|
||||
switch ( sMicParam.frequency )
|
||||
{
|
||||
case MIC_SMP_ALL: // 32.73 kHz
|
||||
one_sampling_tick = (f32)OS_SYSTEM_CLOCK * 1 / 32730 / 64;
|
||||
break;
|
||||
case MIC_SMP_1_2: // 16.36 kHz
|
||||
one_sampling_tick = (f32)OS_SYSTEM_CLOCK * 2 / 32730 / 64;
|
||||
break;
|
||||
case MIC_SMP_1_3: // 10.91 kHz
|
||||
one_sampling_tick = (f32)OS_SYSTEM_CLOCK * 3 / 32730 / 64;
|
||||
break;
|
||||
case MIC_SMP_1_4: // 8.18 kHz
|
||||
one_sampling_tick = (f32)OS_SYSTEM_CLOCK * 4 / 32730 / 64;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case I2S_SAMPLING_RATE_47610:
|
||||
switch ( sMicParam.frequency )
|
||||
{
|
||||
case MIC_SMP_ALL: // 47.61 kHz
|
||||
one_sampling_tick = (f32)OS_SYSTEM_CLOCK * 1 / 47610 / 64;
|
||||
break;
|
||||
case MIC_SMP_1_2: // 23.81 kHz
|
||||
one_sampling_tick = (f32)OS_SYSTEM_CLOCK * 2 / 47610 / 64;
|
||||
break;
|
||||
case MIC_SMP_1_3: // 15.87 kHz
|
||||
one_sampling_tick = (f32)OS_SYSTEM_CLOCK * 3 / 47610 / 64;
|
||||
break;
|
||||
case MIC_SMP_1_4: // 11.90 kHz
|
||||
one_sampling_tick = (f32)OS_SYSTEM_CLOCK * 4 / 47610 / 64;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 現在のサンプリング数を計算
|
||||
sampling_count = (u32)(past_tick / one_sampling_tick);
|
||||
|
||||
// サンプリング数よりアドレスを計算
|
||||
adress = (void*)((u16 *)sMicParam.buffer + sampling_count);
|
||||
|
||||
return adress;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_SetAmpGain
|
||||
|
||||
Description: TWLモードのマイクゲイン(PGAB)を設定します。
|
||||
PGABはAutoGainControlが無効になっているときのみ有効です。
|
||||
|
||||
Arguments: gain : 設定ゲイン(0~119 = 0~59.5dB)
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
TWL_MIC_SetAmpGain( u8 gain )
|
||||
{
|
||||
SDK_ASSERT( gain >= 0 && gain <= 119 );
|
||||
CDC_SetPGAB( gain );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_GetAmpGain
|
||||
|
||||
Description: TWLモードのマイクゲイン(PGAB)を取得します。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: 設定ゲイン
|
||||
*---------------------------------------------------------------------------*/
|
||||
u8
|
||||
TWL_MIC_GetAmpGain( void )
|
||||
{
|
||||
return CDC_GetPGAB();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MICi_ExDmaRecvAsync
|
||||
|
||||
Description: receive data with DMA
|
||||
async version
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
buffer : destination address
|
||||
size : size (byte)
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
TWL_MICi_ExDmaRecvAsync( u32 dmaNo, void *buffer, u32 size )
|
||||
{
|
||||
MIi_ExDmaRecvAsyncCore(
|
||||
dmaNo, // DMA番号
|
||||
(void*)REG_MIC_FIFO_ADDR, // 転送元アドレス
|
||||
buffer, // 転送先アドレス
|
||||
(u32)size, // 総転送バイト数
|
||||
(u32)32, // 転送バイト数
|
||||
MI_EXDMA_BLOCK_32B, // ブロック転送サイズ
|
||||
0, // インターバル
|
||||
MI_EXDMA_PRESCALER_1, // プリスケール1
|
||||
MI_EXDMA_CONTINUOUS_OFF, // 非コンティニュアス
|
||||
MI_EXDMA_SRC_RLD_OFF, // Source Reload Don't Care
|
||||
MI_EXDMA_DEST_RLD_OFF, // Destination Reload Off
|
||||
MI_EXDMA_TIMING_MIC ); // マイクFIFOハーフ起動
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MICi_ExDmaInterruptHandler
|
||||
|
||||
Description: interrupt handler
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
TWL_MICi_ExDmaInterruptHandler( void )
|
||||
{
|
||||
// ループする?
|
||||
if ( sMicParam.loop )
|
||||
{
|
||||
// DMAを再設定
|
||||
TWL_MICi_ExDmaRecvAsync( sMicParam.dmaNo, sMicParam.buffer, sMicParam.size );
|
||||
|
||||
// スタートTick再設定
|
||||
sMicTickStart = OS_GetTick();
|
||||
}
|
||||
|
||||
// DMA完了コールバックの呼び出し
|
||||
if ( sMicParam.callback )
|
||||
{
|
||||
sMicParam.callback( sMicParam.loop );
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MICi_FifoInterruptHandler
|
||||
|
||||
Description: マイクFIFO破綻時に呼び出される割り込みハンドラ
|
||||
現在の実装ではFIFOクリア後にサンプリングを再スタート
|
||||
させています。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
TWL_MICi_FifoInterruptHandler( void )
|
||||
{
|
||||
// マイク停止
|
||||
reg_SND_MICCNT &= ~REG_SND_MICCNT_E_MASK;
|
||||
|
||||
// マイクFIFOクリア
|
||||
reg_SND_MICCNT = REG_SND_MICCNT_FIFO_CLR_MASK;
|
||||
|
||||
// モノラルサンプリング再スタート
|
||||
reg_SND_MICCNT = (u16)( REG_SND_MICCNT_E_MASK |
|
||||
REG_SND_MICCNT_NR_MASK |
|
||||
MIC_INTR_OVERFLOW | // FIFO破綻で割り込み発生
|
||||
sMicParam.frequency );
|
||||
}
|
||||
|
||||
495
build/libraries/mic/ARM7/src/twl_mic_server.c
Normal file
495
build/libraries/mic/ARM7/src/twl_mic_server.c
Normal file
@ -0,0 +1,495 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlSDK - library - twlmic
|
||||
File: twl_mic_server.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: $
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
TWL Mic用に勝手にARM7側スレッドを作りました。
|
||||
都合よければSPIスレッドなどに吸収してください。
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <twl.h>
|
||||
#include <twl/mic.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
マクロ定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
// アライメント調整してコピーする
|
||||
#define MIC_UNPACK_U16(d, s) \
|
||||
(*(d) = (u16)((((u8*)s)[0] << 0) | (((u8*)s)[1] << 8)))
|
||||
#define MIC_UNPACK_U32(d, s) \
|
||||
(*(d) = (u32)((((u8*)s)[0] << 0) | (((u8*)s)[1] << 8) | (((u8*)s)[2] << 16) | (((u8*)s)[3] << 24)))
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
静的変数定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
static BOOL micInitialized; // 初期化確認フラグ
|
||||
static TWLMICServerWork micWork; // ワーク変数をまとめた構造体
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
内部関数定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
static void TWL_MICi_PxiCallback(PXIFifoTag tag, u32 data, BOOL err);
|
||||
static void TWL_MICi_ReturnResult(TWLMICPxiCommand command, TWLMICPxiResult result);
|
||||
static void TWL_MICi_ReturnResultEx(TWLMICPxiCommand command, TWLMICPxiResult result, u8 size, u8* data);
|
||||
static void TWL_MICi_Thread(void *arg);
|
||||
static void TWL_MICi_FullCallback( u8 loop );
|
||||
static BOOL TWL_MICi_SetEntry(TWLMICPxiCommand command, u16 args, ...);
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_InitServer
|
||||
|
||||
Description: ARM7側とやりとりを行うための準備を行います。
|
||||
|
||||
Arguments: priority
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
TWL_MIC_InitServer(u32 priority)
|
||||
{
|
||||
// 初期化済みを確認
|
||||
if (micInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
micInitialized = 1;
|
||||
|
||||
// 内部状態管理変数をクリア
|
||||
micWork.status = TWL_MIC_STATUS_READY;
|
||||
|
||||
// PXI関連を初期化
|
||||
PXI_Init();
|
||||
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_TWL_MIC, TWL_MICi_PxiCallback);
|
||||
|
||||
// 実処理を行うスレッドを作成&起動
|
||||
OS_InitMessageQueue(&micWork.msgQ, micWork.msgArray, TWL_MIC_MESSAGE_ARRAY_MAX);
|
||||
OS_CreateThread(&micWork.thread,
|
||||
TWL_MICi_Thread,
|
||||
0,
|
||||
(void *)(micWork.stack + (TWL_MIC_THREAD_STACK_SIZE / sizeof(u64))),
|
||||
TWL_MIC_THREAD_STACK_SIZE, priority);
|
||||
OS_WakeupThreadDirect(&micWork.thread);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MICi_SetEntry
|
||||
|
||||
Description: TWL MIC スレッドに操作要求を予約する。
|
||||
|
||||
Arguments: command - 行うべき操作のIDを指定。
|
||||
args - 操作に伴うパラメータの数を指定。
|
||||
... - 各パラメータをu32型で指定。
|
||||
|
||||
Returns: BOOL - 予約に成功した場合にTRUEを、失敗した場合にFALSEを返す。
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL
|
||||
TWL_MICi_SetEntry(TWLMICPxiCommand command, u16 args, ...)
|
||||
{
|
||||
OSIntrMode e;
|
||||
void *w;
|
||||
va_list vlist;
|
||||
s32 i;
|
||||
|
||||
// 引数の数をチェック
|
||||
if (args > TWL_MIC_MESSAGE_ARGS_MAX)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
e = OS_DisableInterrupts();
|
||||
micWork.entry[micWork.entryIndex].command = command;
|
||||
|
||||
// 指定数個の引数を追加
|
||||
va_start(vlist, args);
|
||||
for (i = 0; i < args; i++)
|
||||
{
|
||||
micWork.entry[micWork.entryIndex].arg[i] = va_arg(vlist, u32);
|
||||
}
|
||||
va_end(vlist);
|
||||
|
||||
w = &(micWork.entry[micWork.entryIndex]);
|
||||
micWork.entryIndex = (u32)((micWork.entryIndex + 1) % TWL_MIC_MESSAGE_ARRAY_MAX);
|
||||
(void)OS_RestoreInterrupts(e);
|
||||
return OS_SendMessage(&(micWork.msgQ), w, OS_MESSAGE_NOBLOCK);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MICi_PxiCallback
|
||||
|
||||
Description: PXI経由で受信したデータを解析する。
|
||||
|
||||
Arguments: tag - PXI種別を示すタグ。
|
||||
data - 受信したデータ。下位26bitが有効。
|
||||
err - PXI通信におけるエラーフラグ。
|
||||
ARM9側にて同種別のPXIが初期化されていないことを示す。
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void TWL_MICi_PxiCallback(PXIFifoTag tag, u32 data, BOOL err)
|
||||
{
|
||||
#pragma unused( tag )
|
||||
|
||||
// PXI通信エラーをチェック
|
||||
if (err)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 先頭データ
|
||||
if (data & TWL_MIC_PXI_START_BIT)
|
||||
{
|
||||
micWork.total = (u8)((data & TWL_MIC_PXI_DATA_NUMS_MASK) >> TWL_MIC_PXI_DATA_NUMS_SHIFT);
|
||||
micWork.current = 0;
|
||||
micWork.command = (TWLMICPxiCommand)((data & TWL_MIC_PXI_COMMAND_MASK) >> TWL_MIC_PXI_COMMAND_SHIFT);
|
||||
micWork.data[micWork.current++] = (u8)((data & TWL_MIC_PXI_1ST_DATA_MASK) >> TWL_MIC_PXI_1ST_DATA_SHIFT);
|
||||
}
|
||||
// 後続データ
|
||||
else
|
||||
{
|
||||
micWork.data[micWork.current++] = (u8)((data & 0x00FF0000) >> 16);
|
||||
micWork.data[micWork.current++] = (u8)((data & 0x0000FF00) >> 8);
|
||||
micWork.data[micWork.current++] = (u8)((data & 0x000000FF) >> 0);
|
||||
}
|
||||
|
||||
// パケット完成
|
||||
if (micWork.current >= micWork.total) // 最大で2バイト余分に取得する
|
||||
{
|
||||
// 受信したコマンドを解析
|
||||
switch (micWork.command)
|
||||
{
|
||||
// 単発サンプリング
|
||||
case TWL_MIC_PXI_COMMAND_ONE_SAMPLING:
|
||||
if (micWork.status != TWL_MIC_STATUS_READY)
|
||||
{
|
||||
// コマンドを実行できる状態ではない
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_ILLEGAL_STATUS);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TWL MIC スレッドに操作要求
|
||||
if (TWL_MICi_SetEntry( micWork.command, 0 ))
|
||||
{
|
||||
// 状態を"単発サンプリング開始待ち"へ
|
||||
micWork.status = TWL_MIC_STATUS_ONE_SAMPLING_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
// エントリー失敗(メッセージキューに空き無し)
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_FATAL_ERROR);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// オートサンプリング開始
|
||||
case TWL_MIC_PXI_COMMAND_AUTO_START:
|
||||
if (micWork.status != TWL_MIC_STATUS_READY)
|
||||
{
|
||||
// コマンドを実行できる状態ではない
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_ILLEGAL_STATUS);
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 dmaNo, buffer, size, frequency, loop;
|
||||
|
||||
dmaNo = micWork.data[0];
|
||||
MIC_UNPACK_U32(&buffer, &micWork.data[1]);
|
||||
MIC_UNPACK_U32(&size, &micWork.data[5]);
|
||||
frequency = (u32)(micWork.data[9] << REG_SND_MICCNT_FIFO_SMP_SHIFT);
|
||||
loop = micWork.data[10];
|
||||
|
||||
// TWL MIC スレッドに操作要求
|
||||
if (TWL_MICi_SetEntry( micWork.command, 5, dmaNo, buffer, size, frequency, loop ))
|
||||
{
|
||||
// 状態を"自動サンプリング開始待ち"へ
|
||||
micWork.status = TWL_MIC_STATUS_AUTO_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
// エントリー失敗(メッセージキューに空き無し)
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_FATAL_ERROR);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// オートサンプリング停止
|
||||
case TWL_MIC_PXI_COMMAND_AUTO_STOP:
|
||||
if (micWork.status != TWL_MIC_STATUS_AUTO_SAMPLING)
|
||||
{
|
||||
// コマンドを実行できる状態ではない
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_ILLEGAL_STATUS);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TWL MIC スレッドに操作要求
|
||||
if (TWL_MICi_SetEntry( micWork.command, 0 ))
|
||||
{
|
||||
// 状態を"自動サンプリング停止待ち"へ
|
||||
micWork.status = TWL_MIC_STATUS_AUTO_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
// エントリー失敗(メッセージキューに空き無し)
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_FATAL_ERROR);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// 最新サンプリングデータアドレス取得
|
||||
case TWL_MIC_PXI_COMMAND_GET_LAST_SAMPLING_ADDRESS:
|
||||
|
||||
// TWL MIC スレッドに操作要求
|
||||
if (!TWL_MICi_SetEntry( micWork.command, 0 ))
|
||||
{
|
||||
// エントリー失敗(メッセージキューに空き無し)
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_FATAL_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
// プログラマブルアンプゲイン設定
|
||||
case TWL_MIC_PXI_COMMAND_SET_AMP_GAIN:
|
||||
{
|
||||
u32 gain = micWork.data[0];
|
||||
|
||||
// TWL MIC スレッドに操作要求
|
||||
if (!TWL_MICi_SetEntry( micWork.command, 1, gain ))
|
||||
{
|
||||
// エントリー失敗(メッセージキューに空き無し)
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_FATAL_ERROR);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// プログラマブルアンプゲイン取得
|
||||
case TWL_MIC_PXI_COMMAND_GET_AMP_GAIN:
|
||||
|
||||
// TWL MIC スレッドに操作要求
|
||||
if (!TWL_MICi_SetEntry( micWork.command, 0 ))
|
||||
{
|
||||
// エントリー失敗(メッセージキューに空き無し)
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_FATAL_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
// 未知のコマンド
|
||||
default:
|
||||
TWL_MICi_ReturnResult(micWork.command, TWL_MIC_PXI_RESULT_INVALID_COMMAND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MICi_ReturnResult
|
||||
|
||||
Description: PXI経由で処理結果をARM9に送信する。
|
||||
|
||||
Arguments: command - 対象コマンド
|
||||
result - TWLMICPxiResultのひとつ
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
TWL_MICi_ReturnResult(TWLMICPxiCommand command, TWLMICPxiResult result)
|
||||
{
|
||||
u32 pxiData = (u32)(TWL_MIC_PXI_START_BIT | TWL_MIC_PXI_RESULT_BIT |
|
||||
((command << TWL_MIC_PXI_COMMAND_SHIFT) & TWL_MIC_PXI_COMMAND_MASK) |
|
||||
((1 << TWL_MIC_PXI_DATA_NUMS_SHIFT) & TWL_MIC_PXI_DATA_NUMS_MASK) |
|
||||
((result << TWL_MIC_PXI_1ST_DATA_SHIFT) & TWL_MIC_PXI_1ST_DATA_MASK));
|
||||
while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_TWL_MIC, pxiData, 0))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MICi_ReturnResultEx
|
||||
|
||||
Description: 指定後続データをPXI経由でARM9に送信する。
|
||||
|
||||
Arguments: command - 対象コマンド
|
||||
result - TWLMICPxiResultのひとつ
|
||||
size - 付加データサイズ
|
||||
data - 付加データ
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
TWL_MICi_ReturnResultEx(TWLMICPxiCommand command, TWLMICPxiResult result, u8 size, u8* data)
|
||||
{
|
||||
u32 pxiData = (u32)(TWL_MIC_PXI_START_BIT | TWL_MIC_PXI_RESULT_BIT |
|
||||
((command << TWL_MIC_PXI_COMMAND_SHIFT) & TWL_MIC_PXI_COMMAND_MASK) |
|
||||
(((size+1) << TWL_MIC_PXI_DATA_NUMS_SHIFT) & TWL_MIC_PXI_DATA_NUMS_MASK) |
|
||||
((result << TWL_MIC_PXI_1ST_DATA_SHIFT) & TWL_MIC_PXI_1ST_DATA_MASK));
|
||||
int i;
|
||||
while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_TWL_MIC, 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_TWL_MIC, pxiData, 0))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MICi_Thread
|
||||
|
||||
Description: MIC操作の実処理を行うスレッド。
|
||||
|
||||
Arguments: arg - 使用しない。
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void TWL_MICi_Thread(void *arg)
|
||||
{
|
||||
#pragma unused( arg )
|
||||
|
||||
OSMessage msg;
|
||||
TWLMICMessageData* entry;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
// メッセージが発行されるまで寝る
|
||||
(void)OS_ReceiveMessage(&(micWork.msgQ), &msg, OS_MESSAGE_BLOCK);
|
||||
entry = (TWLMICMessageData *) msg;
|
||||
|
||||
// コマンドに従って各種処理を実行
|
||||
switch (entry->command)
|
||||
{
|
||||
//--- 単発サンプリング開始
|
||||
case TWL_MIC_PXI_COMMAND_ONE_SAMPLING:
|
||||
if (micWork.status == TWL_MIC_STATUS_ONE_SAMPLING_START)
|
||||
{
|
||||
u16 temp;
|
||||
TWL_MIC_DoSampling( &temp );
|
||||
|
||||
TWL_MICi_ReturnResultEx(entry->command, TWL_MIC_PXI_RESULT_SUCCESS,
|
||||
2, (u8*)&temp ); // ARM9に処理の成功を通達
|
||||
|
||||
micWork.status = TWL_MIC_STATUS_READY; // 状態を"通常操作待ち"へ
|
||||
}
|
||||
else
|
||||
{
|
||||
TWL_MICi_ReturnResult(entry->command, TWL_MIC_PXI_RESULT_ILLEGAL_STATUS);
|
||||
}
|
||||
break;
|
||||
|
||||
//--- オートサンプリング開始
|
||||
case TWL_MIC_PXI_COMMAND_AUTO_START:
|
||||
if (micWork.status == TWL_MIC_STATUS_AUTO_START)
|
||||
{
|
||||
TWLMICParam param;
|
||||
|
||||
param.dmaNo = (u8)entry->arg[0];
|
||||
param.buffer = (void *)entry->arg[1];
|
||||
param.size = entry->arg[2];
|
||||
param.frequency = (MICSampleRate)entry->arg[3];
|
||||
param.loop = (u8)entry->arg[4];
|
||||
param.callback = TWL_MICi_FullCallback;
|
||||
TWL_MIC_StartAutoSampling( param );
|
||||
|
||||
TWL_MICi_ReturnResult(entry->command, TWL_MIC_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達
|
||||
micWork.status = TWL_MIC_STATUS_AUTO_SAMPLING; // 状態を"自動サンプリング中"へ
|
||||
}
|
||||
else
|
||||
{
|
||||
TWL_MICi_ReturnResult(entry->command, TWL_MIC_PXI_RESULT_ILLEGAL_STATUS);
|
||||
}
|
||||
break;
|
||||
|
||||
//--- オートサンプリング停止
|
||||
case TWL_MIC_PXI_COMMAND_AUTO_STOP:
|
||||
if ((micWork.status == TWL_MIC_STATUS_AUTO_END) || (micWork.status == TWL_MIC_STATUS_END_WAIT))
|
||||
{
|
||||
TWL_MIC_StopAutoSampling();
|
||||
|
||||
// ARM9に処理の成功を通達
|
||||
if (micWork.status == TWL_MIC_STATUS_AUTO_END)
|
||||
{
|
||||
TWL_MICi_ReturnResult(TWL_MIC_PXI_COMMAND_AUTO_STOP, TWL_MIC_PXI_RESULT_SUCCESS);
|
||||
}
|
||||
// 内部状態を更新
|
||||
micWork.status = TWL_MIC_STATUS_READY; // 状態を"通常操作待ち"へ
|
||||
}
|
||||
else
|
||||
{
|
||||
TWL_MICi_ReturnResult(entry->command, TWL_MIC_PXI_RESULT_ILLEGAL_STATUS);
|
||||
}
|
||||
break;
|
||||
|
||||
//--- 最新サンプリングデータアドレス取得
|
||||
case TWL_MIC_PXI_COMMAND_GET_LAST_SAMPLING_ADDRESS:
|
||||
{
|
||||
void* adress = TWL_MIC_GetLastSamplingAddress();
|
||||
|
||||
TWL_MICi_ReturnResultEx(entry->command, TWL_MIC_PXI_RESULT_SUCCESS,
|
||||
4, (u8*)&adress ); // ARM9に処理の成功を通達
|
||||
}
|
||||
break;
|
||||
|
||||
//--- プログラマブルアンプゲイン設定
|
||||
case TWL_MIC_PXI_COMMAND_SET_AMP_GAIN:
|
||||
{
|
||||
u8 gain = (u8)entry->arg[0];
|
||||
TWL_MIC_SetAmpGain( gain );
|
||||
TWL_MICi_ReturnResult(entry->command, TWL_MIC_PXI_RESULT_SUCCESS); // ARM9に処理の成功を通達
|
||||
}
|
||||
break;
|
||||
|
||||
//--- プログラマブルアンプゲイン取得
|
||||
case TWL_MIC_PXI_COMMAND_GET_AMP_GAIN:
|
||||
{
|
||||
u8 gain = TWL_MIC_GetAmpGain();
|
||||
TWL_MICi_ReturnResultEx(entry->command, TWL_MIC_PXI_RESULT_SUCCESS,
|
||||
1, (u8*)&gain ); // ARM9に処理の成功を通達
|
||||
}
|
||||
//--- サポートしないコマンド
|
||||
default:
|
||||
TWL_MICi_ReturnResult(entry->command, TWL_MIC_PXI_RESULT_INVALID_COMMAND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MICi_FullCallback
|
||||
|
||||
Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void TWL_MICi_FullCallback( u8 loop )
|
||||
{
|
||||
// FULL通知
|
||||
TWL_MICi_ReturnResult(TWL_MIC_PXI_COMMAND_MIC_BUFFER_FULL, TWL_MIC_PXI_RESULT_SUCCESS);
|
||||
|
||||
if ( !loop )
|
||||
{
|
||||
// 自動サンプリング停止
|
||||
if (TWL_MICi_SetEntry( TWL_MIC_PXI_COMMAND_AUTO_STOP, 0 ))
|
||||
{
|
||||
micWork.status = TWL_MIC_STATUS_END_WAIT; // 状態を"自動サンプリング完了待ち"へ
|
||||
}
|
||||
else
|
||||
{
|
||||
TWL_MICi_ReturnResult(TWL_MIC_PXI_COMMAND_AUTO_STOP, TWL_MIC_PXI_RESULT_FATAL_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
55
build/libraries/mic/ARM9/Makefile
Normal file
55
build/libraries/mic/ARM9/Makefile
Normal file
@ -0,0 +1,55 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: TwlSDK - libraries - camera/ARM9
|
||||
# File: Makefile
|
||||
#
|
||||
# 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: $
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# build ARM & THUMB libraries
|
||||
TWL_CODEGEN_ALL ?= True
|
||||
|
||||
SRCDIR = ../common ./src
|
||||
|
||||
SRCS = twl_mic_api.c \
|
||||
|
||||
TARGET_LIB = libtwlmic$(TWL_LIBSUFFIX).a
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# DEBUG版ビルドの場合、RELEASE版でビルドして
|
||||
# DEBUG版のライブラリを装います。
|
||||
|
||||
#ifdef NITRO_DEBUG
|
||||
#NITRO_BUILD_TYPE = RELEASE
|
||||
#endif
|
||||
|
||||
include $(TWLSDK_ROOT)/build/buildtools/commondefs
|
||||
|
||||
INSTALL_TARGETS = $(TARGETS)
|
||||
INSTALL_DIR = $(TWL_INSTALL_LIBDIR)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
do-build: $(TARGETS)
|
||||
|
||||
include $(TWLSDK_ROOT)/build/buildtools/modulerules
|
||||
|
||||
|
||||
#===== End of Makefile =====
|
||||
807
build/libraries/mic/ARM9/src/twl_mic_api.c
Normal file
807
build/libraries/mic/ARM9/src/twl_mic_api.c
Normal file
@ -0,0 +1,807 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlSDK - library - camera
|
||||
File: camera.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/mic.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
定数定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
// 詰めてコピーする
|
||||
#define MIC_PACK_U16(d, s) \
|
||||
((d)[0] = (u8)((*((u16*)s) >> 0) & 0xFF), \
|
||||
(d)[1] = (u8)((*((u16*)s) >> 8) & 0xFF))
|
||||
|
||||
#define MIC_PACK_U32(d, s) \
|
||||
((d)[0] = (u8)((*((u32*)s) >> 0) & 0xFF), \
|
||||
(d)[1] = (u8)((*((u32*)s) >> 8) & 0xFF), \
|
||||
(d)[2] = (u8)((*((u32*)s) >> 16) & 0xFF), \
|
||||
(d)[3] = (u8)((*((u32*)s) >> 24) & 0xFF))
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
型定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
typedef struct _TWLMICWork
|
||||
{
|
||||
BOOL lock;
|
||||
TwlMicCallback callback; // 非同期関数用コールバック
|
||||
void* callbackArg; // 上記関数用引数
|
||||
TwlMicCallback full_callback; // 非同期関数用コールバック
|
||||
void* full_arg; // 上記関数用引数
|
||||
TWLMICResult result; // 先頭データだけ別枠
|
||||
TWLMICPxiCommand command; // コマンド種別
|
||||
TWLMICPxiResult pxiResult; // 先頭データだけ別枠
|
||||
u16* pOneBuffer; // 単発サンプリングバッファ保存用
|
||||
void** pLastSamplingAddress; // 最新サンプリングデータ格納アドレス
|
||||
u8* pAmpGain; // アンプゲイン格納アドレス
|
||||
u8 current; // 受信済みデータ個数 (バイト単位) (先頭を除く!!)
|
||||
u8 total; // 最終データ個数 (1 + 後続コマンド*3)
|
||||
u8 data[TWL_MIC_PXI_DATA_SIZE_MAX]; // ARM7からのデータ保存用
|
||||
}
|
||||
TWLMICWork;
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
静的変数定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL micInitialized;
|
||||
static TWLMICWork micWork;
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
内部関数定義
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL TWLMICi_SendPxiCommand(TWLMICPxiCommand command, u8 size, u8 data);
|
||||
static void TWLMICi_SendPxiData(u8 *pData);
|
||||
static void TWLMICi_PxiCallback(PXIFifoTag tag, u32 data, BOOL err);
|
||||
static void TWLMICi_CallbackAndUnlock(TWLMICResult result);
|
||||
static void TWLMICi_GetResultCallback(TWLMICResult result, void *arg);
|
||||
static void TWLMICi_WaitBusy(void);
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_Init
|
||||
|
||||
Description: MICライブラリを初期化する。
|
||||
|
||||
Arguments: None.
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
void TWL_MIC_Init(void)
|
||||
{
|
||||
// 初期化済みを確認
|
||||
if (micInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
micInitialized = 1;
|
||||
|
||||
// 変数初期化
|
||||
micWork.lock = FALSE;
|
||||
micWork.callback = NULL;
|
||||
|
||||
// PXI関連を初期化
|
||||
PXI_Init();
|
||||
while (!PXI_IsCallbackReady(PXI_FIFO_TAG_TWL_MIC, PXI_PROC_ARM7))
|
||||
{
|
||||
}
|
||||
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_TWL_MIC, TWLMICi_PxiCallback);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_End
|
||||
|
||||
Description: MICライブラリを終了する。
|
||||
|
||||
Arguments: None.
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
void TWL_MIC_End(void)
|
||||
{
|
||||
// 初期化済みを確認
|
||||
if (micInitialized == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
micInitialized = 0;
|
||||
|
||||
// PXI関連停止
|
||||
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_TWL_MIC, NULL);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_DoSamplingAsync
|
||||
|
||||
Description: マイク単発サンプリング開始(非同期版)
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_DoSamplingAsync(u16* buf, TwlMicCallback callback, void* callbackArg)
|
||||
{
|
||||
const TWLMICPxiCommand command = TWL_MIC_PXI_COMMAND_ONE_SAMPLING;
|
||||
const u8 size = TWL_MIC_PXI_SIZE_ONE_SAMPLING; // バイト
|
||||
OSIntrMode enabled;
|
||||
|
||||
// buffer NULLチェック
|
||||
// ToDo: 適切なアドレスかどうかチェック
|
||||
if (buf == NULL)
|
||||
{
|
||||
return TWL_MIC_RESULT_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
// ロック
|
||||
enabled = OS_DisableInterrupts();
|
||||
if (micWork.lock)
|
||||
{
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
return TWL_MIC_RESULT_BUSY;
|
||||
}
|
||||
micWork.lock = TRUE;
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
|
||||
// 非同期関数用コールバック設定
|
||||
micWork.callback = callback;
|
||||
micWork.callbackArg = callbackArg;
|
||||
|
||||
// バッファアドレス保存
|
||||
micWork.pOneBuffer = buf;
|
||||
|
||||
// コマンド送信
|
||||
if (TWLMICi_SendPxiCommand(command, size, 0) == FALSE)
|
||||
{
|
||||
return TWL_MIC_RESULT_SEND_ERROR;
|
||||
}
|
||||
|
||||
return TWL_MIC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_DoSampling
|
||||
|
||||
Description: マイク単発サンプリング開始(同期版)
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_DoSampling(u16* buf)
|
||||
{
|
||||
micWork.result = TWL_MIC_DoSamplingAsync(buf, TWLMICi_GetResultCallback, 0);
|
||||
if (micWork.result == TWL_MIC_RESULT_SUCCESS)
|
||||
{
|
||||
TWLMICi_WaitBusy();
|
||||
}
|
||||
return micWork.result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_StartAutoSamplingAsync
|
||||
|
||||
Description: マイク自動サンプリング開始(非同期版)
|
||||
|
||||
Arguments: mic - one of MicSelect
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_StartAutoSamplingAsync(TwlMicAutoParam* param, TwlMicCallback callback, void* callbackArg)
|
||||
{
|
||||
const TWLMICPxiCommand command = TWL_MIC_PXI_COMMAND_AUTO_START;
|
||||
const u8 size = TWL_MIC_PXI_SIZE_AUTO_START; // バイト
|
||||
OSIntrMode enabled;
|
||||
u8 data[size+2];
|
||||
int i;
|
||||
|
||||
// DMA-Noチェック
|
||||
if ( param->dmaNo < MI_EXDMA_CH_MIN || MI_EXDMA_CH_MAX < param->dmaNo )
|
||||
{
|
||||
return TWL_MIC_RESULT_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
// buffer NULLチェック & 4バイトアライメントチェック
|
||||
// ToDo: 適切なアドレスかどうかチェック
|
||||
if (param->buffer == NULL || (u32)param->buffer & 0x03)
|
||||
{
|
||||
return TWL_MIC_RESULT_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
// size 4バイトの倍数チェック
|
||||
// ToDo: buffer + size が適切なメモリ範囲か
|
||||
if (param->size & 0x03)
|
||||
{
|
||||
return TWL_MIC_RESULT_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
// frequencyチェック
|
||||
if ( param->frequency > TWL_MIC_FREQUENCY_1_4 )
|
||||
{
|
||||
return TWL_MIC_RESULT_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
// ロック
|
||||
enabled = OS_DisableInterrupts();
|
||||
if (micWork.lock)
|
||||
{
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
return TWL_MIC_RESULT_BUSY;
|
||||
}
|
||||
micWork.lock = TRUE;
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
|
||||
// 非同期関数用コールバック設定
|
||||
micWork.callback = callback;
|
||||
micWork.callbackArg = callbackArg;
|
||||
|
||||
// FULLコールバック設定
|
||||
if (param->full_callback)
|
||||
{
|
||||
micWork.full_callback = param->full_callback;
|
||||
micWork.full_arg = param->full_arg;
|
||||
}
|
||||
|
||||
// データ作成
|
||||
data[0] = (u8)param->dmaNo;
|
||||
MIC_PACK_U32(&data[1], ¶m->buffer);
|
||||
MIC_PACK_U32(&data[5], ¶m->size);
|
||||
data[9] = (u8)param->frequency;
|
||||
data[10] = (u8)param->loop_enable;
|
||||
|
||||
// コマンド送信
|
||||
if (TWLMICi_SendPxiCommand(command, size, data[0]) == FALSE)
|
||||
{
|
||||
return TWL_MIC_RESULT_SEND_ERROR;
|
||||
}
|
||||
for (i = 1; i < size; i+=3) {
|
||||
TWLMICi_SendPxiData(&data[i]);
|
||||
}
|
||||
|
||||
return TWL_MIC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_StartAutoSampling
|
||||
|
||||
Description: マイク自動サンプリング開始(同期版)
|
||||
|
||||
Arguments: param
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_StartAutoSampling(TwlMicAutoParam* param)
|
||||
{
|
||||
micWork.result = TWL_MIC_StartAutoSamplingAsync(param, TWLMICi_GetResultCallback, 0);
|
||||
if (micWork.result == TWL_MIC_RESULT_SUCCESS)
|
||||
{
|
||||
TWLMICi_WaitBusy();
|
||||
}
|
||||
return micWork.result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_StopAutoSamplingAsync
|
||||
|
||||
Description: マイク自動サンプリング停止(非同期版)
|
||||
|
||||
Arguments: none
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_StopAutoSamplingAsync( TwlMicCallback callback, void* callbackArg )
|
||||
{
|
||||
const TWLMICPxiCommand command = TWL_MIC_PXI_COMMAND_AUTO_STOP;
|
||||
const u8 size = TWL_MIC_PXI_SIZE_AUTO_STOP; // バイト
|
||||
OSIntrMode enabled;
|
||||
|
||||
// ロック
|
||||
enabled = OS_DisableInterrupts();
|
||||
if (micWork.lock)
|
||||
{
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
return TWL_MIC_RESULT_BUSY;
|
||||
}
|
||||
micWork.lock = TRUE;
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
|
||||
// コールバック設定
|
||||
micWork.callback = callback;
|
||||
micWork.callbackArg = callbackArg;
|
||||
|
||||
// コマンド送信
|
||||
if (TWLMICi_SendPxiCommand(command, size, 0) == FALSE)
|
||||
{
|
||||
return TWL_MIC_RESULT_SEND_ERROR;
|
||||
}
|
||||
|
||||
return TWL_MIC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_StopAutoSampling
|
||||
|
||||
Description: マイク自動サンプリング停止(同期版)
|
||||
|
||||
Arguments: param
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_StopAutoSampling( void )
|
||||
{
|
||||
micWork.result = TWL_MIC_StopAutoSamplingAsync(TWLMICi_GetResultCallback, 0);
|
||||
if (micWork.result == TWL_MIC_RESULT_SUCCESS)
|
||||
{
|
||||
TWLMICi_WaitBusy();
|
||||
}
|
||||
return micWork.result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_GetLastSamplingAddressAsync
|
||||
|
||||
Description: 最新のサンプリングデータの格納アドレスを返します。
|
||||
但し、アドレスはサンプリング時間を元に理論的に計算された
|
||||
ものであるため誤差を含んでいます。
|
||||
(非同期版)
|
||||
|
||||
Arguments: adress : アドレス格納ポインタのアドレス
|
||||
callback :
|
||||
callbackArg :
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_GetLastSamplingAddressAsync( void** adress, TwlMicCallback callback, void* callbackArg )
|
||||
{
|
||||
const TWLMICPxiCommand command = TWL_MIC_PXI_COMMAND_GET_LAST_SAMPLING_ADDRESS;
|
||||
const u8 size = TWL_MIC_PXI_SIZE_GET_LAST_SAMPLING_ADDRESS; // バイト
|
||||
OSIntrMode enabled;
|
||||
|
||||
// ロック
|
||||
enabled = OS_DisableInterrupts();
|
||||
if (micWork.lock)
|
||||
{
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
return TWL_MIC_RESULT_BUSY;
|
||||
}
|
||||
micWork.lock = TRUE;
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
|
||||
// コールバック設定
|
||||
micWork.callback = callback;
|
||||
micWork.callbackArg = callbackArg;
|
||||
|
||||
// アドレス格納アドレス保存
|
||||
micWork.pLastSamplingAddress = adress;
|
||||
|
||||
// コマンド送信
|
||||
if (TWLMICi_SendPxiCommand(command, size, 0) == FALSE)
|
||||
{
|
||||
return TWL_MIC_RESULT_SEND_ERROR;
|
||||
}
|
||||
|
||||
return TWL_MIC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_GetLastSamplingAddress
|
||||
|
||||
Description: 最新のサンプリングデータの格納アドレスを返します。
|
||||
但し、アドレスはサンプリング時間を元に理論的に計算された
|
||||
ものであるため誤差を含んでいます。
|
||||
(同期版)
|
||||
|
||||
Arguments: adress : アドレス格納ポインタのアドレス
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_GetLastSamplingAddress( void** adress )
|
||||
{
|
||||
micWork.result = TWL_MIC_GetLastSamplingAddressAsync( adress, TWLMICi_GetResultCallback, 0);
|
||||
if (micWork.result == TWL_MIC_RESULT_SUCCESS)
|
||||
{
|
||||
TWLMICi_WaitBusy();
|
||||
}
|
||||
return micWork.result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_SetAmpGainAsync
|
||||
|
||||
Description: プログラマブルゲインアンプの設定を行います。(非同期版)
|
||||
この関数で設定したゲインはオートゲインコントロールが
|
||||
無効になっているときのみ有効となることに注意してください。
|
||||
|
||||
Arguments: gain : 設定ゲイン(0~119 = 0~59.5dB)
|
||||
callback :
|
||||
callbackArg :
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_SetAmpGainAsync( u8 gain, TwlMicCallback callback, void* callbackArg )
|
||||
{
|
||||
const TWLMICPxiCommand command = TWL_MIC_PXI_COMMAND_SET_AMP_GAIN;
|
||||
const u8 size = TWL_MIC_PXI_SIZE_SET_AMP_GAIN; // バイト
|
||||
u8 data[size+2];
|
||||
OSIntrMode enabled;
|
||||
|
||||
// 設定ゲイン範囲チェック
|
||||
if ( gain > 119)
|
||||
{
|
||||
return TWL_MIC_RESULT_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
// ロック
|
||||
enabled = OS_DisableInterrupts();
|
||||
if (micWork.lock)
|
||||
{
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
return TWL_MIC_RESULT_BUSY;
|
||||
}
|
||||
micWork.lock = TRUE;
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
|
||||
// コールバック設定
|
||||
micWork.callback = callback;
|
||||
micWork.callbackArg = callbackArg;
|
||||
|
||||
// データ作成
|
||||
data[0] = gain;
|
||||
|
||||
// コマンド送信
|
||||
if (TWLMICi_SendPxiCommand(command, size, data[0]) == FALSE)
|
||||
{
|
||||
return TWL_MIC_RESULT_SEND_ERROR;
|
||||
}
|
||||
|
||||
return TWL_MIC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_SetAmpGain
|
||||
|
||||
Description: プログラマブルゲインアンプの設定を行います。(同期版)
|
||||
この関数で設定したゲインはオートゲインコントロールが
|
||||
無効になっているときのみ有効となることに注意してください。
|
||||
|
||||
Arguments: gain : 設定ゲイン(0~119 = 0~59.5dB)
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_SetAmpGain( u8 gain )
|
||||
{
|
||||
micWork.result = TWL_MIC_SetAmpGainAsync( gain, TWLMICi_GetResultCallback, 0);
|
||||
if (micWork.result == TWL_MIC_RESULT_SUCCESS)
|
||||
{
|
||||
TWLMICi_WaitBusy();
|
||||
}
|
||||
return micWork.result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_GetAmpGainAsync
|
||||
|
||||
Description: TWLモードのマイクゲイン(PGAB)を取得します。
|
||||
(非同期版)
|
||||
|
||||
Arguments: gain : マイクゲイン値の格納アドレス
|
||||
callback :
|
||||
callbackArg :
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_GetAmpGainAsync( u8* gain, TwlMicCallback callback, void* callbackArg )
|
||||
{
|
||||
const TWLMICPxiCommand command = TWL_MIC_PXI_COMMAND_GET_AMP_GAIN;
|
||||
const u8 size = TWL_MIC_PXI_SIZE_GET_AMP_GAIN; // バイト
|
||||
OSIntrMode enabled;
|
||||
|
||||
// NULLチェック
|
||||
if ( gain == NULL)
|
||||
{
|
||||
return TWL_MIC_RESULT_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
// ロック
|
||||
enabled = OS_DisableInterrupts();
|
||||
if (micWork.lock)
|
||||
{
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
return TWL_MIC_RESULT_BUSY;
|
||||
}
|
||||
micWork.lock = TRUE;
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
|
||||
// コールバック設定
|
||||
micWork.callback = callback;
|
||||
micWork.callbackArg = callbackArg;
|
||||
|
||||
// ゲイン格納アドレス保存
|
||||
micWork.pAmpGain = gain;
|
||||
|
||||
// コマンド送信
|
||||
if (TWLMICi_SendPxiCommand(command, size, 0) == FALSE)
|
||||
{
|
||||
return TWL_MIC_RESULT_SEND_ERROR;
|
||||
}
|
||||
|
||||
return TWL_MIC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWL_MIC_GetAmpGain
|
||||
|
||||
Description: TWLモードのマイクゲイン(PGAB)を取得します。
|
||||
(同期版)
|
||||
|
||||
Arguments: gain : マイクゲイン値の格納アドレス
|
||||
|
||||
Returns: TWLMICResult
|
||||
*---------------------------------------------------------------------------*/
|
||||
TWLMICResult
|
||||
TWL_MIC_GetAmpGain( u8* gain )
|
||||
{
|
||||
micWork.result = TWL_MIC_GetAmpGainAsync( gain, TWLMICi_GetResultCallback, 0);
|
||||
if (micWork.result == TWL_MIC_RESULT_SUCCESS)
|
||||
{
|
||||
TWLMICi_WaitBusy();
|
||||
}
|
||||
return micWork.result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWLMICi_SendPxiCommand
|
||||
|
||||
Description: 指定先頭コマンドをPXI経由でARM7に送信する。
|
||||
|
||||
Arguments: command - 対象コマンド
|
||||
size - 送信データサイズ (バイト単位)
|
||||
data - 先頭データ (1バイトのみ)
|
||||
|
||||
Returns: BOOL - PXIに対して送信が完了した場合TRUEを、
|
||||
PXIによる送信に失敗した場合FALSEを返す。
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL TWLMICi_SendPxiCommand(TWLMICPxiCommand command, u8 size, u8 data)
|
||||
{
|
||||
u32 pxiData = (u32)(TWL_MIC_PXI_START_BIT |
|
||||
((command << TWL_MIC_PXI_COMMAND_SHIFT) & TWL_MIC_PXI_COMMAND_MASK) |
|
||||
((size << TWL_MIC_PXI_DATA_NUMS_SHIFT) & TWL_MIC_PXI_DATA_NUMS_MASK) |
|
||||
((data << TWL_MIC_PXI_1ST_DATA_SHIFT) & TWL_MIC_PXI_1ST_DATA_MASK));
|
||||
if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_TWL_MIC, pxiData, 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWLMICi_SendPxiData
|
||||
|
||||
Description: 指定後続データをPXI経由でARM7に送信する。
|
||||
|
||||
Arguments: pData - 3バイトデータの先頭へのポインタ
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void TWLMICi_SendPxiData(u8 *pData)
|
||||
{
|
||||
u32 pxiData = (u32)((pData[0] << 16) | (pData[1] << 8) | pData[2]);
|
||||
while (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_TWL_MIC, pxiData, 0))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWLMICi_PxiCallback
|
||||
|
||||
Description: 非同期関数用の共通コールバック関数。
|
||||
|
||||
Arguments: tag - PXI tag which show message type.
|
||||
data - message from ARM7.
|
||||
err - PXI transfer error flag.
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void TWLMICi_PxiCallback(PXIFifoTag tag, u32 data, BOOL err)
|
||||
{
|
||||
#pragma unused( tag )
|
||||
TWLMICResult result;
|
||||
|
||||
// PXI通信エラーを確認
|
||||
if (err)
|
||||
{
|
||||
// シーケンスを強制終了
|
||||
TWLMICi_CallbackAndUnlock(TWL_MIC_RESULT_FATAL_ERROR);
|
||||
return;
|
||||
}
|
||||
// 先頭データ
|
||||
if (data & TWL_MIC_PXI_START_BIT)
|
||||
{
|
||||
// 受信データを解析
|
||||
SDK_ASSERT((data & TWL_MIC_PXI_RESULT_BIT) == TWL_MIC_PXI_RESULT_BIT);
|
||||
micWork.total = (u8)((data & TWL_MIC_PXI_DATA_NUMS_MASK) >> TWL_MIC_PXI_DATA_NUMS_SHIFT);
|
||||
micWork.current = 0;
|
||||
micWork.command = (TWLMICPxiCommand)((data & TWL_MIC_PXI_COMMAND_MASK) >> TWL_MIC_PXI_COMMAND_SHIFT);
|
||||
micWork.pxiResult = (TWLMICPxiResult)((data & TWL_MIC_PXI_1ST_DATA_MASK) >> TWL_MIC_PXI_1ST_DATA_SHIFT);
|
||||
}
|
||||
// 後続データ
|
||||
else
|
||||
{
|
||||
if (micWork.current < TWL_MIC_PXI_DATA_SIZE_MAX)
|
||||
{
|
||||
micWork.data[micWork.current++] = (u8)((data & 0xFF0000) >> 16);
|
||||
}
|
||||
if (micWork.current < TWL_MIC_PXI_DATA_SIZE_MAX)
|
||||
{
|
||||
micWork.data[micWork.current++] = (u8)((data & 0x00FF00) >> 8);
|
||||
}
|
||||
if (micWork.current < TWL_MIC_PXI_DATA_SIZE_MAX)
|
||||
{
|
||||
micWork.data[micWork.current++] = (u8)((data & 0x0000FF) >> 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (micWork.current >= micWork.total-1) // > は無いはず
|
||||
{
|
||||
// 処理結果を確認
|
||||
switch (micWork.pxiResult)
|
||||
{
|
||||
case TWL_MIC_PXI_RESULT_SUCCESS:
|
||||
result = TWL_MIC_RESULT_SUCCESS;
|
||||
break;
|
||||
case TWL_MIC_PXI_RESULT_INVALID_COMMAND:
|
||||
result = TWL_MIC_RESULT_INVALID_COMMAND;
|
||||
break;
|
||||
case TWL_MIC_PXI_RESULT_INVALID_PARAMETER:
|
||||
result = TWL_MIC_RESULT_ILLEGAL_PARAMETER;
|
||||
break;
|
||||
case TWL_MIC_PXI_RESULT_ILLEGAL_STATUS:
|
||||
result = TWL_MIC_RESULT_ILLEGAL_STATUS;
|
||||
break;
|
||||
case TWL_MIC_PXI_RESULT_BUSY:
|
||||
result = TWL_MIC_RESULT_BUSY;
|
||||
break;
|
||||
default:
|
||||
result = TWL_MIC_RESULT_FATAL_ERROR;
|
||||
}
|
||||
|
||||
switch (micWork.command)
|
||||
{
|
||||
case TWL_MIC_PXI_COMMAND_MIC_BUFFER_FULL:
|
||||
// FULLコールバックの呼び出し
|
||||
if (micWork.full_callback)
|
||||
{
|
||||
micWork.full_callback( result, micWork.full_arg );
|
||||
}
|
||||
break;
|
||||
|
||||
case TWL_MIC_PXI_COMMAND_ONE_SAMPLING:
|
||||
// 単発サンプリング結果格納
|
||||
*micWork.pOneBuffer = (u16)(micWork.data[0] | (micWork.data[1] << 8));
|
||||
// 非同期関数用コールバックの呼び出し&ロック解除
|
||||
TWLMICi_CallbackAndUnlock(result);
|
||||
break;
|
||||
|
||||
case TWL_MIC_PXI_COMMAND_GET_LAST_SAMPLING_ADDRESS:
|
||||
// 最新サンプリングデータアドレス格納
|
||||
*micWork.pLastSamplingAddress = (void *)(micWork.data[0] | (micWork.data[1] << 8) | (micWork.data[2] << 16) | (micWork.data[3] << 24));
|
||||
// 非同期関数用コールバックの呼び出し&ロック解除
|
||||
TWLMICi_CallbackAndUnlock(result);
|
||||
break;
|
||||
|
||||
case TWL_MIC_PXI_COMMAND_GET_AMP_GAIN:
|
||||
// アンプゲイン格納
|
||||
*micWork.pAmpGain = micWork.data[0];
|
||||
// 非同期関数用コールバックの呼び出し&ロック解除
|
||||
TWLMICi_CallbackAndUnlock(result);
|
||||
break;
|
||||
|
||||
default:
|
||||
// 非同期関数用コールバックの呼び出し&ロック解除
|
||||
TWLMICi_CallbackAndUnlock(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWLMICi_CallbackAndUnlock
|
||||
|
||||
Description: コールバックの呼び出しとロックの解除を行う
|
||||
|
||||
Arguments: result - ARM7から送られた結果
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void TWLMICi_CallbackAndUnlock(TWLMICResult result)
|
||||
{
|
||||
TwlMicCallback cb;
|
||||
|
||||
// ロック解除
|
||||
if (micWork.lock)
|
||||
{
|
||||
micWork.lock = FALSE;
|
||||
}
|
||||
|
||||
// 非同期関数用コールバック呼び出し
|
||||
if (micWork.callback)
|
||||
{
|
||||
cb = micWork.callback;
|
||||
micWork.callback = NULL;
|
||||
cb(result, micWork.callbackArg);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWLMICi_GetResultCallback
|
||||
|
||||
Description: 同期関数が内部で実行する非同期関数の結果を取得するために
|
||||
使用する。
|
||||
|
||||
Arguments: result - 非同期関数の処理結果。
|
||||
arg - 使用しない。
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void TWLMICi_GetResultCallback(TWLMICResult result, void *arg)
|
||||
{
|
||||
#pragma unused( arg )
|
||||
|
||||
micWork.result = result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: TWLMICi_WaitBusy
|
||||
|
||||
Description: MICの非同期処理がロックされている間待つ。
|
||||
|
||||
Arguments: None.
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
#if 0
|
||||
#include <nitro/code32.h>
|
||||
static asm void TWLMICi_WaitBusy(void)
|
||||
{
|
||||
ldr r12, =micWork.lock
|
||||
loop:
|
||||
ldr r0, [ r12, #0 ]
|
||||
cmp r0, #TRUE
|
||||
beq loop
|
||||
bx lr
|
||||
}
|
||||
#include <nitro/codereset.h>
|
||||
#else
|
||||
extern void PXIi_HandlerRecvFifoNotEmpty(void);
|
||||
static void TWLMICi_WaitBusy(void)
|
||||
{
|
||||
volatile BOOL *p = &micWork.lock;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (OS_GetCpsrIrq() == OS_INTRMODE_IRQ_DISABLE)
|
||||
{
|
||||
PXIi_HandlerRecvFifoNotEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user