/**
 * @brief           TIMR Manager Header
 * @author          AXELL CORPORATION
 * @description     TIMR Manager提供ヘッダ。<p>TIMR Manager使用時にincludeして下さい。
 * @note            none
 * @history         2017_02_22  初版
 * @history         2017_10_26  Ver2.0
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017-2019 AXELL CORPORATION, all rights reserved.
 */

#ifndef _TIMRMGR_H_
#define _TIMRMGR_H_
/* DOM-IGNORE-END */

#include <stdint.h>
#include "lib_common/AG903_common.h"

#ifdef __cplusplus
extern "C" {
#endif

/** chあたりの割込みハンドラ数(最大数はAG903_OSWprCreIsrAutoの実装に依存します) */
#define AG903_TIMR_INTHDR_NUM		(2)

/** タイマ入力端子種別 */
enum _AG903_TimrInputType {
	AG903_TIMR_INPUT_EXTIN0 = 0,	/** EXTIN[0]  */
	AG903_TIMR_INPUT_EXTIN1,		/** EXTIN[1]  */
	AG903_TIMR_INPUT_EXTIN2,		/** EXTIN[2]  */
	AG903_TIMR_INPUT_EXTIN3,		/** EXTIN[3]  */
	AG903_TIMR_INPUT_EXTOUT0,		/** EXTOUT[0] */
	AG903_TIMR_INPUT_EXTOUT1,		/** EXTOUT[1] */
	AG903_TIMR_INPUT_EXTOUT2,		/** EXTOUT[2] */
	AG903_TIMR_INPUT_EXTOUT3,		/** EXTOUT[3] */
	AG903_TIMR_INPUT_TYPENUM,		/** タイマ入力端子種別数 */
};

/** ロータリエンコーダ入力端子種別 */
enum _AG903_TimrInputTypeRotaryEncoder {
	AG903_TIMR_INPUT_REIN01 = 0,	/** A相 EXTIN[0], B相 EXTIN[1] */
	AG903_TIMR_INPUT_REIN23,		/** A相 EXTIN[2], B相 EXTIN[3] */
	AG903_TIMR_INPUT_REOUT01,		/** A相 EXTOUT[0], B相 EXTOUT[1] */
	AG903_TIMR_INPUT_REOUT23,		/** A相 EXTOUT[2], B相 EXTOUT[3] */
	AG903_TIMR_INPUT_RETYPENUM,		/** ロータリエンコーダ入力端子種別数 */
};

/** サンプリングクロック種別 */
enum _AG903_TimrCntClkType {
	AG903_TIMR_CNT_SYSCLK = 0,		/** システムクロック */
	AG903_TIMR_CNT_TICK0,			/** Tick0 */
	AG903_TIMR_CNT_TICK1,			/** Tick1 */
	AG903_TIMR_CNT_TYPENUM,			/** サンプリングクロック種別数 */
};

/** タイマ出力種別 */
enum _AG903_TimrOutMode {
	AG903_TIMR_OUT_PLUSE = 0,		/** パルス出力 */
	AG903_TIMR_OUT_LEVEL,			/** レベル出力 */
	AG903_TIMR_OUT_PWM,				/** PWM出力 */
	AG903_TIMR_OUT_MODENUM,			/** タイマ出力種別数 */
};

/** 極性種別 */
enum _AG903_TimrPolarityType {
	AG903_TIMR_POL_POSITIVE = 0,	/** 正論理 */
	AG903_TIMR_POL_NEGATIVE,		/** 負論理 */
	AG903_TIMR_POL_TYPENUM,			/** 極性種別数 */
};

/** リセットトリガ種別 */
enum _AG903_TimrResetTriggerType {
	AG903_TIMR_RSTTRG_EXTPORT = 0,	/** 外部端子 */
	AG903_TIMR_RSTTRG_EVENT,		/** 内部イベント */
	AG903_TIMR_RSTTRG_TYPENUM,		/** リセットトリガ種別数 */
};

/** 割込み検出ビット（コンペア・マッチ）*/
#define AG903_TIMR_COMPARE_BIT		(1<<1)

/** 割込み検出ビット（オーバーフロー）*/
#define AG903_TIMR_OVERFLOW_BIT		(1<<0)

/** TIMRハンドル */
typedef uint32_t	AG903_TIMRMgrHandle;

/** クロック・Tick計測モードOutputパラメータ<p>
    mode は右から指定します。 _AG903_TimrOutMode<p>
    portch は0〜3でタイマ入出力端子（TIO[3:0]）を選択します。<p>
    polarity は右から指定します。 _AG903_TimrPolarityType<p>
    mask はパルス、レベル出力時のコンペア・マッチ検出、オーバーフロー検出のマスクをbit単位で設定します。<p>
    Bit1:コンペア・マッチ検出<p>
    Bit0:オーバーフロー検出<p>
    ※0b：検出をマスクしません。 1b：検出をマスクします。*/
typedef struct _AG903_TIMRMgrTickCntOutput{
	uint32_t	plusewidth;		/** パルス幅 (パルス出力時) */
	uint8_t		mode;			/** 出力モード */
	uint8_t		portch;			/** 出力端子 */
	uint8_t		polarity;		/** 極性 */
	uint8_t		mask;			/** マスク */
} AG903_TIMRMgrTickCntOutput;

/** クロック・Tick計測モード設定パラメータ<p>
    出力端子制御を行わない場合は output をNULLとして下さい。<p>
    resolution は右から指定します。 _AG903_TimrCntClkType<p>
    oneshot は true=ワンショット、false=ピリオディック です。 */
typedef struct _AG903_TIMRMgrTickCntParam{
	AG903_TIMRMgrTickCntOutput* output;	/** Outputパラメータ */
	uint32_t	period;			/** 周期 */
	uint32_t	match;			/** 比較値 */
	uint8_t		resolution;		/** 分解能指定 */
	uint8_t		oneshot;		/** ワンショット指定 */
	uint8_t		reserve[2];		/** 予約 */
} AG903_TIMRMgrTickCntParam;

/** ロータリーエンコーダ入力モードOutputパラメータ<p>
    mode は右から指定します。 _AG903_TimrOutMode<p>
    portch は0〜3でタイマ入出力端子（TIO[3:0]）を選択します。<p>
    polarity は右から指定します。 _AG903_TimrPolarityType */
typedef struct _AG903_TIMRMgrRotaryEncOutput{
	uint32_t	plusewidth;		/** パルス幅 (パルス出力時) */
	uint8_t		mode;			/** 出力モード */
	uint8_t		portch;			/** 出力端子 */
	uint8_t		polarity;		/** 極性 */
	uint8_t		reserve;		/** 予約 */
} AG903_TIMRMgrRotaryEncOutput;

/** ロータリーエンコーダ入力モード設定パラメータ<p>
    出力端子制御を行わない場合は output をNULLとして下さい。<p>
    intype は右から指定します。  _AG903_TimrInputTypeRotaryEncoder<p>
    sampling は右から指定します。 _AG903_TimrCntClkType */
typedef struct _AG903_TIMRMgrRotaryEncParam{
	AG903_TIMRMgrRotaryEncOutput* output;	/** Outputパラメータ */
	uint32_t	range;			/** 値域 */
	uint32_t	match;			/** 比較値 */
	uint8_t		intype;			/** 入力タイプ指定 */
	uint8_t		sampling;		/** サンプリング間隔 */
	uint8_t		reserve[2];		/** 予約 */
} AG903_TIMRMgrRotaryEncParam;

/** PWM入力モードOutputパラメータ<p>
    mode は右から指定します。 _AG903_TimrOutMode<p>
    portch は0〜3でタイマ入出力端子（TIO[3:0]）を選択します。<p>
    polarity は右から指定します。 _AG903_TimrPolarityType */
typedef struct _AG903_TIMRMgrPwmInOutput{
	uint32_t	plusewidth;		/** パルス幅 (パルス出力時) */
	uint8_t		mode;			/** 出力モード */
	uint8_t		portch;			/** 出力端子 */
	uint8_t		polarity;		/** 極性 */
	uint8_t		reserve;		/** 予約 */
} AG903_TIMRMgrPwmInOutput;

/** PWM入力モード設定パラメータ<p>
    出力端子制御を行わない場合は output をNULLとして下さい。<p>
    intype は右から指定します。 _AG903_TimrInputType<p>
    resolution は右から指定します。 _AG903_TimrCntClkType<p>
    oneshot は true=ワンショット、false=ピリオディック です。 */
typedef struct _AG903_TIMRMgrPwmInParam{
	AG903_TIMRMgrPwmInOutput* output;	/** Outputパラメータ */
	uint8_t		intype;			/** 入力タイプ指定 */
	uint8_t		polarity;		/** 入力極性 */
	uint8_t		resolution;		/** 分解能指定 */
	uint8_t		oneshot;		/** ワンショット指定 */
} AG903_TIMRMgrPwmInParam;

/** 内部イベント計測モードOutputパラメータ<p>
    mode は右から指定します。 _AG903_TimrOutMode<p>
    portch は0〜3でタイマ入出力端子（TIO[3:0]）を選択します。<p>
    polarity は右から指定します。 _AG903_TimrPolarityType<p>
    mask はパルス、レベル出力時のコンペア・マッチ検出、オーバーフロー検出のマスクをbit単位で設定します。<p>
    Bit1:コンペア・マッチ検出<p>
    Bit0:オーバーフロー検出<p>
    ※0b：検出をマスクしません。 1b：検出をマスクします。*/
typedef struct _AG903_TIMRMgrEventCntOutput{
	uint32_t	plusewidth;		/** パルス幅 (パルス出力時) */
	uint8_t		mode;			/** 出力モード */
	uint8_t		portch;			/** 出力端子ch */
	uint8_t		polarity;		/** 極性 */
	uint8_t		mask;			/** マスク */
} AG903_TIMRMgrEventCntOutput;

/** 内部イベント計測モード設定パラメータ<p>
    出力端子制御を行わない場合は output をNULLとして下さい。<p>
    event は計測対象のイベントを指定します。イベント番号については『AX51903仕様書』を参照して下さい。<p>
    oneshot は true=ワンショット、false=ピリオディック です。 */
typedef struct _AG903_TIMRMgrEventCntParam{
	AG903_TIMRMgrEventCntOutput* output;	/** Outputパラメータ */
	uint32_t	period;			/** 周期 */
	uint32_t	match;			/** 比較値 */
	uint8_t		event;			/** イベント指定 */
	uint8_t		oneshot;		/** ワンショット指定 */
	uint8_t		reserve[2];		/** 予約 */
} AG903_TIMRMgrEventCntParam;

/** 入力端子パルス計測モードOutputパラメータ<p>
    mode は右から指定します。 _AG903_TimrOutMode<p>
    portch は0〜3でタイマ入出力端子（TIO[3:0]）を選択します。<p>
    polarity は右から指定します。 _AG903_TimrPolarityType<p>
    mask はパルス、レベル出力時のコンペア・マッチ検出、オーバーフロー検出のマスクをbit単位で設定します。<p>
    Bit1:コンペア・マッチ検出<p>
    Bit0:オーバーフロー検出<p>
    ※0b：検出をマスクしません。 1b：検出をマスクします。*/
typedef struct _AG903_TIMRMgrPulseCntOutput{
	uint32_t	plusewidth;		/** パルス幅 (パルス出力時) */
	uint8_t		mode;			/** 出力モード */
	uint8_t		portch;			/** 出力端子ch */
	uint8_t		polarity;		/** 極性 */
	uint8_t		mask;			/** マスク */
} AG903_TIMRMgrPulseCntOutput;

/** 入力端子パルス計測モード設定パラメータ<p>
    出力端子制御を行わない場合は output をNULLとして下さい。<p>
    intype は右から指定します。 _AG903_TimrInputType<p>
    polarity は右から指定します。 _AG903_TimrPolarityType<p>
    sampling は右から指定します。 _AG903_TimrCntClkType<p>
    oneshot は true=ワンショット、false=ピリオディック です。 */
typedef struct _AG903_TIMRMgrPulseCntParam{
	AG903_TIMRMgrPulseCntOutput* output;	/** Outputパラメータ */
	uint32_t	period;			/** 周期 */
	uint32_t	match;			/** 比較値 */
	uint8_t		intype;			/** 入力タイプ指定 */
	uint8_t		polarity;		/** 入力極性 */
	uint8_t		sampling;		/** サンプリング間隔 */
	uint8_t		oneshot;		/** ワンショット指定 */
} AG903_TIMRMgrPulseCntParam;

/** 入力端子レベル計測モードOutputパラメータ<p>
    mode は右から指定します。 _AG903_TimrOutMode<p>
    portch は0〜3でタイマ入出力端子（TIO[3:0]）を選択します。<p>
    polarity は右から指定します。 _AG903_TimrPolarityType<p>
    mask はパルス、レベル出力時のコンペア・マッチ検出、オーバーフロー検出のマスクをbit単位で設定します。<p>
    Bit1:コンペア・マッチ検出<p>
    Bit0:オーバーフロー検出<p>
    ※0b：検出をマスクしません。 1b：検出をマスクします。*/
typedef struct _AG903_TIMRMgrLevelCntOutput{
	uint32_t	plusewidth;		/** パルス幅 (パルス出力時) */
	uint8_t		mode;			/** 出力モード */
	uint8_t		portch;			/** 出力端子ch */
	uint8_t		polarity;		/** 極性 */
	uint8_t		mask;			/** マスク */
} AG903_TIMRMgrLevelCntOutput;

/** 入力端子レベル計測モード設定パラメータ<p>
    出力端子制御を行わない場合は output をNULLとして下さい。<p>
    intype は右から指定します。 _AG903_TimrInputType<p>
    polarity は右から指定します。 _AG903_TimrPolarityType<p>
    sampling は右から指定します。 _AG903_TimrCntClkType<p>
    oneshot は true=ワンショット、false=ピリオディック です。 */
typedef struct _AG903_TIMRMgrLevelCntParam{
	AG903_TIMRMgrLevelCntOutput* output;	/** Outputパラメータ */
	uint32_t	period;			/** 周期 */
	uint32_t	match;			/** 比較値 */
	uint8_t		intype;			/** 入力タイプ指定 */
	uint8_t		polarity;		/** 入力極性 */
	uint8_t		sampling;		/** サンプリング間隔  */
	uint8_t		oneshot;		/** ワンショット指定 */
} AG903_TIMRMgrLevelCntParam;

/** リセットトリガ設定パラメータ<p>
    trigger は右から指定します。 _AG903_TimrResetTriggerType<p>
    event は計測対象のイベントを指定します。イベント番号については『AX51903仕様書』を参照して下さい。<p>
    intype は右から指定します。 _AG903_TimrInputType<p>
    polarity は右から指定します。 _AG903_TimrPolarityType<p>
    sampling は右から指定します。 _AG903_TimrCntClkType */
typedef struct _AG903_TIMRMgrResetParam{
	uint8_t		trigger;		/** トリガ種別 */
	uint8_t		event;			/** 内部イベント指定 (内部イベントTrigger時) */
	uint8_t		intype;			/** 入力端子指定 (外部端子Trigger時) */
	uint8_t		polarity;		/** 極性 (外部端子Trigger時) */
	uint8_t		sampling;		/** サンプリング間隔 (外部端子Trigger時) */
	uint8_t		reserve[3];		/** 予約 */
} AG903_TIMRMgrResetParam;


int32_t	AG903_TIMRMgrInit(void);
int32_t	AG903_TIMRMgrGetHandle(AG903_TIMRMgrHandle** handle);
int32_t	AG903_TIMRMgrReleaseHandle(AG903_TIMRMgrHandle* handle);
int32_t	AG903_TIMRMgrSetIntHandler(AG903_TIMRMgrHandle* handle, void* func, void* param);
int32_t	AG903_TIMRMgrDeleteIntHandler(AG903_TIMRMgrHandle* handle, void* func);
int32_t	AG903_TIMRMgrSetRotaryEncoderMode(AG903_TIMRMgrHandle* handle, AG903_TIMRMgrRotaryEncParam* param);
int32_t	AG903_TIMRMgrSetPwmInMode(AG903_TIMRMgrHandle* handle, AG903_TIMRMgrPwmInParam* param);
int32_t	AG903_TIMRMgrSetTickCountMode(AG903_TIMRMgrHandle* handle, AG903_TIMRMgrTickCntParam* param);
int32_t	AG903_TIMRMgrSetEventCountMode(AG903_TIMRMgrHandle* handle, AG903_TIMRMgrEventCntParam* param);
int32_t	AG903_TIMRMgrSetPulseCountMode(AG903_TIMRMgrHandle* handle, AG903_TIMRMgrPulseCntParam* param);
int32_t	AG903_TIMRMgrSetLevelCountMode(AG903_TIMRMgrHandle* handle, AG903_TIMRMgrLevelCntParam* param);
int32_t	AG903_TIMRMgrStart(AG903_TIMRMgrHandle* handle);
int32_t	AG903_TIMRMgrStop(AG903_TIMRMgrHandle* handle);
int32_t	AG903_TIMRMgrStartMulti(uint8_t chbit);
int32_t	AG903_TIMRMgrEnableResetTrigger(AG903_TIMRMgrHandle* handle, AG903_TIMRMgrResetParam* param);
int32_t	AG903_TIMRMgrDisableResetTrigger(AG903_TIMRMgrHandle* handle);
int32_t	AG903_TIMRMgrEnableOneShot(AG903_TIMRMgrHandle* handle);
int32_t	AG903_TIMRMgrDisableOneShot(AG903_TIMRMgrHandle* handle);
int32_t	AG903_TIMRMgrEnableIntMask(AG903_TIMRMgrHandle* handle, uint8_t target);
int32_t	AG903_TIMRMgrDisableIntMask(AG903_TIMRMgrHandle* handle, uint8_t target);
int32_t	AG903_TIMRMgrEnableEventTrigger(AG903_TIMRMgrHandle* handle, uint8_t target);
int32_t	AG903_TIMRMgrDisableEventTrigger(AG903_TIMRMgrHandle* handle, uint8_t target);
int32_t	AG903_TIMRMgrEnableDmaRequest(AG903_TIMRMgrHandle* handle, uint8_t target);
int32_t	AG903_TIMRMgrDisableDmaRequest(AG903_TIMRMgrHandle* handle, uint8_t target);
int32_t	AG903_TIMRMgrGetStatus(AG903_TIMRMgrHandle* handle, uint32_t* status);
int32_t	AG903_TIMRMgrClearStatus(AG903_TIMRMgrHandle* handle, uint32_t target);
int32_t	AG903_TIMRMgrGetCount(AG903_TIMRMgrHandle* handle, uint32_t* count);
int32_t	AG903_TIMRMgrSetCount(AG903_TIMRMgrHandle* handle, uint32_t count);
int32_t	AG903_TIMRMgrGetPeriodValue(AG903_TIMRMgrHandle* handle, uint32_t* period);
int32_t	AG903_TIMRMgrSetPeriodValue(AG903_TIMRMgrHandle* handle, uint32_t period);
int32_t	AG903_TIMRMgrGetMatchValue(AG903_TIMRMgrHandle* handle, uint32_t* match);
int32_t	AG903_TIMRMgrSetMatchValue(AG903_TIMRMgrHandle* handle, uint32_t match);
int32_t	AG903_TIMRMgrGetChannel(AG903_TIMRMgrHandle* handle, uint8_t* ch);


#ifdef __cplusplus
}
#endif
#endif /* _TIMRMGR_H_ */
