/*	
 *	clipir.h
 *
 *	赤外線通信 (24/48MHz両対応)
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2005 Naoyuki Sawa
 *
 *	* Sat Mar 05 15:53:00 JST 2005 Naoyuki Sawa
 *	- 作成開始。
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'〜'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 */
#ifndef __CLIP_IR_H__
#define __CLIP_IR_H__

#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus

/****************************************************************************
 *	
 ****************************************************************************/

/* 通信フォーマットを設定します。
 * [in]
 *	mode		1: P/ECE Kernelの赤外線通信と互換のフォーマット。
 *			   P/ECE標準APIのpceIRStartRx/Tx()と通信できます。
 *			0: P/ECE Kernelの赤外線通信と非互換のフォーマット。
 *			   P/ECE標準APIのpceIRStartRx/Tx()と通信できません。
 *			   その代わりに、少し高効率です。
 * [note]
 *	- 通信フォーマットの初期値は、1: 互換モード です。
 *	- 通信フォーマットは、ir_send/recv()で通信を開始する前に設定してください。
 *	  ir_stop()で通信を停止しても、通信フォーマットの設定は維持されます。
 *	- ir_send/recv()での通信中にモードを切り替えようとすると、アサートします。
 *	- 互換モードと非互換モードの違いは、次の通りです。
 *	  1. P/ECE Kernelの赤外線通信は、送信データの各バイトをそのままエンコードして送出するのではなく、
 *	     CRC32テーブルの値とのXorを取ってからエンコードしています。
 *	     このようにすることによって、どんな効果があるのか不明なのですが、そういう仕様になっています。
 *	     - 互換モードは、この仕様に合わせて、CRC32テーブルの値を求め、Xorを取ってからエンコードします。
 *	     - 非互換モードは、送信データの各バイトをそのままエンコードします。
 *	  2. P/ECE Kernelの赤外線通信は、送信側の送出バイト数が、受信側の要求バイト数よりも少なかった場合に、
 *	     受信側がデータブロックのトレーラを検出して、受信を中断できるようになっています。
 *	     ただし、赤外線通信APIからアプリケーションへ実際の受信バイト数を通知する機構が無いので、
 *	     通信データ内に実際のサイズを埋め込む必要があります。
 *	     - 互換モードは、この仕様に合わせるために、送信処理にてトレーラを送出しています。
 *	     - 非互換モードでは、送信側と受信側が同じバイト数であると仮定し、トレーラを送出しません。
 *	       受信側の要求バイト数の方が少ない場合は、ir_stop()で明示的に停止するまで、受信データを待ち続けます。
 *	       トレーラを送出しないぶん高速なので、小さなデータブロックを頻繁に通信する場合に有利です。
 *	     - 互換モードでは、受信側が受信完了したときに、まだ送信側はトレーラ送出中の可能性があります。
 *	       そのため、受信完了直後に返送データを送信すると、まだ相手側が受信準備できていない可能性があります。
 *	       非互換モードでは、受信側の受信完了時には必ず、送信側の送信も完了しています。
 *	       送信側の 送信完了→受信準備 の切り替えが充分に高速ならば、直ちに返送データを送信しても大丈夫です。
 *	       ★★★高速に送受信を交互に切り替えて通信を行う場合は、非互換モードを利用してください。★★★
 */
void ir_mode(int mode);

/* 赤外線でデータを送信します。
 * [in]
 *	data		送信するデータの先頭アドレス。
 *	len		送信するデータのバイト数。
 *			1バイト未満の通信は不可です。(アサートします)
 *	callback	送信完了コールバック。
 *			NULLを指定すると、コールバックは呼び出されません。
 * [note]
 *	- この関数は、通信完了を待たずにすぐに処理を返します。
 *	  通信完了は、コールバックか、またはir_stat()を呼び出して判定してください。
 *	  通信が完了するまで、dataの内容を破壊してはいけません。
 *	- 通信が完了すると、自動的にir_stop()が呼び出されます。
 *	  明示的にir_stop()を呼び出す必要は有りません。(呼んでも構いません。)
 *	- 通信完了前に通信処理を中断するには、ir_stop()を呼び出してください。
 *	  通信処理を中断した場合は、コールバックは呼び出されません。★注意!!★
 *	- コールバックを呼び出す前に、既に自動的にir_stop()が呼ばれています。
 *	  コールバックの中で、ir_stop()を呼ぶ必要はありません。(呼んでも構いません。)
 *	  また、コールバックの中で直ちに次の通信を開始することができます。
 *	- 24MHz/48MHzどちらのクロックでも使えます。
 *	  ただし、通信中はクロックを切り替えないで下さい。
 */
void ir_send(const void* data, int len, void (*callback)());

/* 赤外線でデータを受信します。
 * [in]
 *	data		受信したデータを格納するバッファの先頭アドレス。
 *	len		受信したデータを格納するバッファのバイト数。
 *			1バイト未満の通信は不可です。(アサートします)
 *	callback	送信完了コールバック。
 *			NULLを指定すると、コールバックは呼び出されません。
 * [note]
 *	- この関数は、通信完了を待たずにすぐに処理を返します。
 *	  通信完了は、コールバックか、またはir_stat()を呼び出して判定してください。
 *	  通信が完了するまで、dataバッファを維持しなければいけません。
 *	- 通信が完了すると、自動的にir_stop()が呼び出されます。
 *	  明示的にir_stop()を呼び出す必要は有りません。(呼んでも構いません。)
 *	- 通信完了前に通信処理を中断するには、ir_stop()を呼び出してください。
 *	  通信処理を中断した場合は、コールバックは呼び出されません。★注意!!★
 *	- コールバックを呼び出す前に、既に自動的にir_stop()が呼ばれています。
 *	  コールバックの中で、ir_stop()を呼ぶ必要はありません。(呼んでも構いません。)
 *	  また、コールバックの中で直ちに次の通信を開始することができます。
 *	- 24MHz/48MHzどちらのクロックでも使えます。
 *	  ただし、通信中はクロックを切り替えないで下さい。
 */
void ir_recv(void* data, int len, void (*callback)());

/* 赤外線通信機能を停止します。
 * [note]
 *	- ir_send()またはir_recv()を呼び出したアプリケーションは、
 *	  終了する前に必ずir_stop()を呼び出してください。
 *	- ir_send()またはir_recv()を呼び出していなくても、
 *	  ir_stop()を呼び出すことは常に安全です。
 */
void ir_stop();

/* 赤外線通信状況を取得します。
 * [out]
 *	戻り値		通信中ならば、0以外の値を返します。
 *			停止中、または、送受信が完了していたら、0を返します。
 */
int ir_stat();

#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus

#endif /*__CLIP_IR_H__*/
