# PM_GoSleepMode

## 構文

      #include <nitro/spi.h>

      void PM_GoSleepMode( PMWakeUpTrigger trigger, PMLogic logic, u16 keyPattern );

## 引数

trigger | スリープ状態からの復帰要因
logic | キー割り込みで復帰する場合のキーの組み合わせ論理
keyPattern | キー割り込みで復帰する場合のキー

## 返り値

なし。

## 説明

ARM9、ARM7 ともにスリープ状態に移行します。

> 注意：
> ・プログラミングガイドラインで、ワイヤレス通信をONにしたままでスリープには入るのは禁止されています。
> かならずOFFにして下さい。
> ・DSP をロードした状態でスリープに入るのは禁止されています。
> 必ず動作を終了して下さい。( `DSP_UnloadG711()` などを呼んでください )
> ・割り込みハンドラから呼ばないで下さい。

ARM7にスリープコマンドを送り、ARM9自身も`OS_Halt()` でホールト状態に入ります。trigger は `PMWakeUpTrigger` 列挙型で、スリープ状態からの復帰要因を指定します。要因は論理和を取ることで複数のものを指定することが出来ます。以下のものが指定可能です。

プラットフォーム | 値 | 復帰要因内容
--- | --- | ---
| PM_TRIGGER_KEY | キー割り込み発生
| PM_TRIGGER_RTC_ALARM | RTCのアラーム割り込み発生
| PM_TRIGGER_COVER_OPEN | ふたを開く
| PM_TRIGGER_CARD | カード割り込み発生 またはカードを抜く
| PM_TRIGGER_CARTRIDGE (注1) | カートリッジ割り込み発生 またはカートリッジを抜く
| PM_TRIGGER_SDIO | SDIO 割り込み

(注1) カートリッジ抜けによってスリープから復帰する方法はガイドラインで禁止されています。

> (例)　ふたを開くか、カードを抜くと復帰するスリープを行う場合
> `PM_GoSleepMode( PM_TRIGGER_COVER_OPEN | PM_TRIGGER_CARD ,0 ,0 );`

ハード上の仕様で言えばこれらの復帰要因はレベルトリガであり、エッジトリガではありません。PM_TRIGGER_CARTRIDGE を例に取ると、正確に言えば「カートリッジを抜いたこと」を検知するのではなく「抜かれている状態」を検知して復帰します。(もっと正確にいえば、OS_IE_CARTRIDGE_IREQ 割り込みが掛かっているという状態を検知します。)　従って、カートリッジがささっていない状態でカートリッジ割り込みを復帰要因としてスリープに入ろうとしても(すでに抜かれているとみなして) 即座に復帰します。

ただし、カードとカートリッジ割り込みについては、実際に刺さっているかどうかを関数内部で調べますので、ささっていない状態で復帰要因に入れようとしてもそのトリガは破棄されます。

キー割り込みによる復帰

キー割り込みを復帰要因に含めた場合、復帰するためのキーとその組み合わせ論理を keyPattern と logic で指定します。組み合わせ論理は`PM_PAD_LOGIC_AND` (すべてのキー入力が行われた) 、 `PM_PAD_LOGIC_OR` (いずれかのキー入力が行われた) のどちらかです。
例えば、AボタンとSTARTボタンを同時に押さなければ復帰出来ないようにするには

`PM_GoSleepMode( PM_TRIGGER_KEY, PM_PAD_LOGIC_AND, PAD_BUTTON_A | PAD_BUTTON_START );`

となり、AボタンとSTARTボタンのいずれかを押せば復帰するようにするには

`PM_GoSleepMode( PM_TRIGGER_KEY, PM_PAD_LOGIC_OR, PAD_BUTTON_A | PAD_BUTTON_START );`

となります。

キー割り込みを復帰要因に含めない場合、keyPattern および logic の指定には意味がありません。また、キーの指定が一つしかない場合は組み合わせ論理 logic は `PM_PAD_LOGIC_AND とPM_PAD_LOGIC_OR` のどちらでも構いません。

SDIO割り込みによる復帰

SDIO割り込みによる復帰は　TWLプラットフォーム上で用いることが出来ます。この割り込みは将来の拡張のために用意されており、SDカードスロットに対応のデバイスを接続した場合などが想定されています。また無線通信で使用する可能性もあります。通常は指定しないようにしてください。

コールバック関数

スリープモードに移行する前と、スリープモードから復帰したときに呼ばれるコールバック関数を設定することが出来ます。スリープモードに移行するときのコールバック関数は `PM_GoSleepMode()` の先頭で、復帰したときのコールバック関数は `PM_GoSleepMode()` の末尾で呼び出されますので、実質的に `PM_GoSleepMode()` の直前・直後で呼び出すのと変わりません。

コールバック関数は `PMSleepCallback` 型 ( void* 引数を１つとる、返り値を持たない関数型 ) で、複数の関数を登録することが出来ます。登録された複数の関数は順に呼ばれますので、順序の依存関係があるものを登録する際には注意が必要です。

コールバックを登録する際には、コールバック関数やその引数を含んだコールバック情報で指定します。詳細は `PM_AppendPreSleepCallback()` のリファレンスを参照してください。

割り込みハンドラからの呼び出し

`PM_GoSleepMode()` が割り込みハンドラから呼ばれることは想定していません。割り込みハンドラからは呼ばないようにしてください。

遅延の可能性

`PM_GoSleepMode()` では、内部でいくつかの PM 関数を呼び出しています。他のデバイスに SPI が占有されていて BUSY 状態だった場合には成功するまで PM 関数を呼び出し続けます。従って、実際にスリープに入るタイミングが関数呼び出しからは遅れる場合があります。

## 参照

`PM_Init,
PM_AppendPreSleepCallback, PM_PrependPreSleepCallback,
PM_AppendPostSleepCallback, PM_PrependPostSleepCallback,
PM_DeletePreSleepCallback, PM_DeletePostSleepCallback,`
`PM_SetSleepCallbackInfo`

## 履歴

2009/06/03 `PM_Init()` についての記述を削除 (`OS_Init()` が必須となったため)
2008/09/11 DSP を動作させてスリープすることが禁止であると追記
2008/08/23 遅延の可能性について追記
2008/03/13 SDIO 要因追加と、割り込みハンドラからの呼び出し不可を明記
2006/05/16 復帰要因のカートリッジ抜けについての説明変更
2005/09/14 `PM_SetSleepCallback` → `PM_SetSleepCallbackInfo
` 2005/03/08 用語統一 [割込み] → [割り込み]
2004/10/06 コールバックを複数登録できるように修正
2004/10/05 コールバックについての記述を追加
2004/08/07 組み合わせ論理を引数に分離
2004/08/02 初版