/*
 *	clipruds.h
 *
 *	パルスモーターの台形制御シーケンサ
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2014 Naoyuki Sawa
 *
 *	* Thu Apr 24 19:33:48 JST 2014 Naoyuki Sawa
 *	- 1st リリース。
 *	* Sat Apr 26 09:27:47 JST 2014 Naoyuki Sawa
 *	- シーケンサコンパイラを作成しました。⇒clip/tool/dRudSeqC/
 *	  もう命令コード定義用マクロを使ってデータを作成する必要はありません。
 *	  スクリプトを書いて、シーケンサコンパイラでデータを作成してください。
 *	* Mon May 05 19:19:03 JST 2014 Naoyuki Sawa
 *	- cliprudc.c に停止励磁時間を追加したことに伴い、「wait stop」の条件を変更しました。
 *	  [変更前] 停止中になるまで待つ。
 *	  [変更後] 停止中,かつ,停止励磁終了するまで待つ。
 */
#ifndef __CLIP_RUDS_H__
#define __CLIP_RUDS_H__

/****************************************************************************
 *	パルスモーターの台形制御シーケンサ
 ****************************************************************************/
//□命令セット仕様
//
//	[def]	(ラベル)
//
//		goto	(ラベル)
//		call	(ラベル)
//		repeat	[繰り返し回数]		省略値=0(無限)
//
//		speed	(分周比)
//		[move]	init
//		move	rel	(相対位置)
//		move	[abs]	(絶対位置)
//		[move]	stop
//
//		wait	[rel]	(相対時間)
//		wait	abs	(絶対時間)
//		wait	[stop]
//
//		user	(番号)
//
//	end					再生終了,call戻り,repeat戻り、いずれもendで表す。
//
/*--------------------------------------------------------------------------*/
//□命令コード仕様
//
//	end		0000 0000 0000 0000
//	[move] init	0000 0000 0000 0001
//	[move] stop	0000 0000 0000 0010
//	wait  [stop]	0000 0000 0000 0011
//	user       u	0000 0000 0000 0100	┬アプリケーション定義命令(0〜4091)						//今後、新しい命令を追加する必要が生じた場合、この範囲を狭める予定
//			0000 1111 1111 1111	┘
//	goto       s	0001 ssss ssss ssss	s:この命令の位置を基準とした相対位置						//「*次の*命令の位置を基準とした相対位置」*ではない*ことに注意せよ
//	call       s	0010 ssss ssss ssss	s:この命令の位置を基準とした相対位置						//「*次の*命令の位置を基準とした相対位置」*ではない*ことに注意せよ
//	repeat    [u]	0011 uuuu uuuu uuuu	u:0=無限,1〜=繰り返し回数
//	speed      u	0100 uuuu uuuu uuuu	u:分周比(0=最速)
//	move  rel  s	0101 ssss ssss ssss	s:相対位置
//	move [abs] s	0110 ssss ssss ssss	s:絶対位置
//	wait [rel] u	0111 uuuu uuuu uuuu	u:直前の命令完了からの相対時間
//	wait  abs  u	1uuu uuuu uuuu uuuu	u:データ再生開始からの絶対時間
//
/*--------------------------------------------------------------------------*/
//□命令コード定義用マクロ
#define RudSeq_Inst_end			((0<<12)|      0         )
#define RudSeq_Inst_move_init		((0<<12)|      1         )
#define RudSeq_Inst_move_stop		((0<<12)|      2         )
#define RudSeq_Inst_wait_stop		((0<<12)|      3         )
#define RudSeq_Inst_user(u)		((0<<12)|(((u)+4)&0x0FFF))	//u:0〜4091
#define RudSeq_Inst_goto(s)		((1<<12)|( (s)   &0x0FFF))
#define RudSeq_Inst_call(s)		((2<<12)|( (s)   &0x0FFF))
#define RudSeq_Inst_repeat(u)		((3<<12)|( (u)   &0x0FFF))
#define RudSeq_Inst_speed(u)		((4<<12)|( (u)   &0x0FFF))
#define RudSeq_Inst_move_rel(s)		((5<<12)|( (s)   &0x0FFF))
#define RudSeq_Inst_move_abs(s)		((6<<12)|( (s)   &0x0FFF))
#define RudSeq_Inst_wait_rel(u)		((7<<12)|( (u)   &0x0FFF))	//u: 4.096[秒]まで対応可能
#define RudSeq_Inst_wait_abs(u)		((1<<15)|( (u)   &0x7FFF))	//u:32.767[秒]まで対応可能
// * Sat Apr 26 09:27:47 JST 2014 Naoyuki Sawa
// - シーケンサコンパイラを作成しました。⇒clip/tool/dRudSeqC/
//   もう命令コード定義用マクロを使ってデータを作成する必要はありません。
//   スクリプトを書いて、シーケンサコンパイラでデータを作成してください。
/*--------------------------------------------------------------------------*/
#define RudSeqCh_Max RudCtlCh_Max	/* シーケンサチャネル番号の最大値(この値も含む) */					//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
#define RudSeqCh_StackSize 4		/* スタッサイズ */		//調整可
/*--------------------------------------------------------------------------*/
/* スタック */
typedef struct _ST_RudSeqCh_Stack {
	const uint16_t* pInst;		/* 戻り先の命令ポインタ */								//「call,repeatの次の命令」*ではなく*、「call,repeat命令自身」を指す。end命令による戻り処理時に、次の命令へ進める。実装上の都合である。
	int16_t Repeat;			/* 0=Callスタック,0以外=Repeatスタックの残り繰り返し回数(負=無限) */
} ST_RudSeqCh_Stack;
/*--------------------------------------------------------------------------*/
/* 台形制御シーケンサチャネル */
typedef struct _ST_RudSeqCh {
	const uint16_t* pInst;		/* 次に実行する命令ポインタ */
	uint16_t AbsTime;		/* データ再生開始からの絶対時間 */
	uint16_t RelTime;		/* 直前の命令完了からの相対時間 */
	uint16_t Speed;			/* 分周比(0=最速) */
	uint8_t StackLevel;		/* スタックレベル(0〜RudSeqCh_StackSize) */
	ST_RudSeqCh_Stack TBL_Stack[RudSeqCh_StackSize];	/* スタック */
} ST_RudSeqCh;
/*--- グローバル関数 ---*/
void RudSeqCh_Play(int iRudSeqCh, const uint16_t* pInst);
void RudSeqCh_Stop(int iRudSeqCh);
/*--------------------------------------------------------------------------*/
/* 台形制御シーケンサ */
typedef struct _ST_RudSeq {
	void (*fnUser)(int iRudSeqCh, int no);		/* アプリケーション定義命令処理関数(アプリケーション定義) */
	ST_RudSeqCh TBL_RudSeqCh[RudSeqCh_Max+1];	/* 台形制御シーケンサチャネル */
} ST_RudSeq;
/*--- グローバル変数 ---*/
extern ST_RudSeq stRudSeq;
/*--- グローバル関数 ---*/
void RudSeq_Init(void (*fnUser)(int iRudSeqCh, int no));
void RudSeq_Stop();
void RudSeq_Exec();

#endif/*__CLIP_RUDS_H__*/
