Zybo > TTC > Triple Timer Counterを試用 > ポート作成失敗 / 制約の未消化 > ポート作成成功した

```txt:動作確認
Vivado 2015.4 on Windows 8.1 pro
```

TTC (Triple Timer Counter)を使ってみる

参考 https://forums.xilinx.com/t5/Xcell-Daily-Blog/Introduction-to-the-Zynq-Triple-Timer-Counter-Part-Two-Adam/ba-p/410361

## Vivadoでの作業

### TTCを有効化

- Block DesignのDiagram画面においてprocessing_system7_0をダブルクリック
- 中央上部のTTCをダブルクリック
- Application Processor Unit > Timer 0 をチェック
  - IO: EMIOのまま

### Clock Configuration設定

- Block DesignのDiagram画面においてprocessing_system7_0をダブルクリック
- Page NavigatorのClock Configurationをクリック
- Timers > TTC0 を展開
  - しかし設定は変更せず (Clock Source: CPU 1Xなど)

### ~~Create Port~~

<font color=red>以下で手順で作成したポート関連でbitstream生成にエラーが出る。対処方法が不明なので、今回はポート作成はやめた。</font>

- Block DesignのDiagram画面においてprocessing_system7_0上で右クリック
- Create Port選択
- Create Port画面で設定
  - Port name: EMIO_WaveOut (としてみた)
  - Direction: Output (出力を見るため)
  - その他変更なし

### 作成したポートを配線

<font color=red>以下で手順で作成したポート関連でbitstream生成にエラーが出る。対処方法が不明なので、今回はポート作成はやめた。</font>

- TTC0_WAVE0_OUT と EMIO_WaveOut を配線


### 不明

Constraintsを作るようだが、まだその概念を把握してない。

Constraintsは未設定。

### XSDKへExport

bistreamを生成し、XSDKへExportした。

## XSDKでの作業

New -> Application Projectにてプロジェクトを作成

[adam Taylorブログ](https://forums.xilinx.com/t5/Xcell-Daily-Blog/Introduction-to-the-Zynq-Triple-Timer-Counter-Part-Three-Adam/ba-p/413105)の
`helloworld - Adam taylor Part 19.docx ‏16 KB`
のソースに変更。


TickHandlerの処理でevent文字列の前にカウント値を表示する用に変更した。

```
static void TickHandler(void *CallBackRef)
{
	u32 StatusEvent;
	static u32 cnt = 0;

	StatusEvent = XTtcPs_GetInterruptStatus((XTtcPs *)CallBackRef);
	XTtcPs_ClearInterruptStatus((XTtcPs *)CallBackRef, StatusEvent);

	printf("%d,",cnt);
	printf("event\n\r");
	cnt++;

}
```

Program FPGAをして、プログラムを実行すると以下のような結果となった。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/57251c03-b411-d6d3-a4ca-c3d5b44a95a0.png)


## ソース

改変後のソース
変数名の変更などもしている。

```helloworld.c
#include <stdio.h>
#include "platform.h"
#include "Xscugic.h"
#include "Xil_exception.h"
#include "xttcps.h"

#define TTC_DEVICE_ID	    XPAR_XTTCPS_0_DEVICE_ID
#define TTC_INTR_ID		    XPAR_XTTCPS_0_INTR
#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID

typedef struct {
	u32 OutputHz;	/* Output frequency */
	u16 Interval;	/* Interval value */
	u8 Prescaler;	/* Prescaler value */
	u16 Options;	/* Option settings */
} TmrCntrSetup;

static TmrCntrSetup SettingsTable = {
	{10, 0, 0, 0},	/* Ticker timer counter initial setup, only output freq */
};

static XScuGic GicInst;

static void SetupInterruptSystem(XScuGic *GicInstancePtr, XTtcPs *TtcPsInt);
static void TickHandler(void *CallBackRef);

int main()
{
	XTtcPs_Config *ttcCfg;
	XTtcPs tmrInst;
	TmrCntrSetup *tmrSetup;

	init_platform();

	tmrSetup = &SettingsTable;

	XTtcPs_Stop(&tmrInst);

 	printf("\n\rAdam Edition MicroZed Using Vivado \n\r");

 	//initialise the timer
 	ttcCfg = XTtcPs_LookupConfig(TTC_DEVICE_ID);
 	XTtcPs_CfgInitialize(&tmrInst, ttcCfg, ttcCfg->BaseAddress);

 	tmrSetup->Options |= (XTTCPS_OPTION_INTERVAL_MODE |
 						      XTTCPS_OPTION_WAVE_DISABLE);

 	XTtcPs_SetOptions(&tmrInst, tmrSetup->Options);
 	XTtcPs_CalcIntervalFromFreq(&tmrInst, tmrSetup->OutputHz,&(tmrSetup->Interval), 
 		&(tmrSetup->Prescaler));

    XTtcPs_SetInterval(&tmrInst, tmrSetup->Interval);
    XTtcPs_SetPrescaler(&tmrInst, tmrSetup->Prescaler);

    SetupInterruptSystem(&GicInst, &tmrInst);

	while(1)
		;

	return 0;
}

static void SetupInterruptSystem(XScuGic *GicPtr, XTtcPs *TtcPsInt)
{
	XScuGic_Config *gicCfg;

	Xil_ExceptionInit();

	//initialise
	gicCfg = XScuGic_LookupConfig(INTC_DEVICE_ID);
	XScuGic_CfgInitialize(GicPtr, gicCfg, gicCfg->CpuBaseAddress);

	//connect to the hardware
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
				(Xil_ExceptionHandler)XScuGic_InterruptHandler, GicPtr);
	XScuGic_Connect(GicPtr, TTC_INTR_ID,
			(Xil_ExceptionHandler)TickHandler, (void *)TtcPsInt);
	XScuGic_Enable(GicPtr, TTC_INTR_ID);
	XTtcPs_EnableInterrupts(TtcPsInt, XTTCPS_IXR_INTERVAL_MASK);

	XTtcPs_Start(TtcPsInt);

	// Enable interrupts
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
}

static void TickHandler(void *CallBackRef)
{
	u32 StatusEvent;
	static u32 cnt = 0;

	StatusEvent = XTtcPs_GetInterruptStatus((XTtcPs *)CallBackRef);
	XTtcPs_ClearInterruptStatus((XTtcPs *)CallBackRef, StatusEvent);

	printf("%d,",cnt);
	printf("event\n\r");
	cnt++;
}
```

### プログラムの停止

上記で実行したプログラムの停止方法
http://qiita.com/7of9/items/d2b17fcd6f63aa185d73

## Create Portの成功

(追記 2016/06/30)
XDCファイルの記載について
https://forums.xilinx.com/t5/Xcell-Daily-Blog/Introduction-to-the-Zynq-Triple-Timer-Counter-Part-Two-Adam/ba-p/410361
においては[EMIO_Wave_out]という記載であったが、VivadoのBlock Designを見ると[EMIO_WaveOut]という名前になっていた。
上記修正をすることでbitstream作成まで成功するようになった。