AXI TimerでPWMを使い、さらにPWMの立ち上がりと立ち下がりで別のハンドラを使う

1. 立ち上がりか立ち下がりかは、TCSR0(TCSR1)の8ビット目、
TINT0(TINT1)を読んで判定する。
2. XTC_CSR_ENABLE_PWM_MASK | XTC_CSR_EXT_GENERATE_MASKをONに入れる。
pwm0だけでなくgenerateout0, generateout1にも信号が出るが、使わなくて良い

#include <stdio.h>
#include "platform.h"
#include "xil_types.h"
#include "xtmrctr.h"
#include "xparameters.h"
#include "xil_io.h"
#include "xil_exception.h"
#include "xscugic.h"
#include <stdbool.h>

#define XTC_CSR_ENABLE_PWM_MASK		0x00000200
#define XTC_CSR_EXT_GENERATE_MASK	0x00000004

XScuGic InterruptController; /* Instance of the Interrupt Controller */
XTmrCtr TimerInstancePtr;
#define _CHK(TARGET,BIT) ((TARGET >> BIT) & 1)
static XScuGic_Config *GicConfig;/* The configuration parameters of the controller */
void Timer_InterruptHandler(void *data, u8 TmrCtrNumber)
{
	u32 reg0 = Xil_In32(TimerInstancePtr.BaseAddress + XTmrCtr_Offsets[0] + XTC_TCSR_OFFSET);
	u32 reg1 = Xil_In32(TimerInstancePtr.BaseAddress + XTmrCtr_Offsets[1] + XTC_TCSR_OFFSET);
	if(_CHK(reg0,8)){
		printf("PWM ON\r\n");
	} else if(_CHK(reg1,8)){
		printf("PWM OFF\r\n");
	}
}

int SetUpInterruptSystem(XScuGic *XScuGicInstancePtr)
{
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			(Xil_ExceptionHandler) XScuGic_InterruptHandler,
			XScuGicInstancePtr);
	Xil_ExceptionEnable();
	return XST_SUCCESS;
}
int ScuGicInterrupt_Init(u16 DeviceId,XTmrCtr *TimerInstancePtr)
{
	int Status;
	GicConfig = XScuGic_LookupConfig(DeviceId);
	if (NULL == GicConfig) {
		return XST_FAILURE;
	}
	Status = XScuGic_CfgInitialize(&InterruptController, GicConfig,
			GicConfig->CpuBaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	Status = SetUpInterruptSystem(&InterruptController);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	Status = XScuGic_Connect(&InterruptController,
			XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR,
			(Xil_ExceptionHandler)XTmrCtr_InterruptHandler,
			(void *)TimerInstancePtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	XScuGic_Enable(&InterruptController,XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR);
	return XST_SUCCESS;
}
int main()
{
	int xStatus;

	print("##### Application Starts #####\n\r");
	print("\r\n");
	xStatus = XTmrCtr_Initialize(&TimerInstancePtr,XPAR_AXI_TIMER_0_DEVICE_ID);
	if(XST_SUCCESS != xStatus)
		print("TIMER INIT FAILED \n\r");

	XTmrCtr_SetHandler(&TimerInstancePtr,
			Timer_InterruptHandler,
			&TimerInstancePtr);

	//enable interrupt & auto reload
	XTmrCtr_SetOptions(&TimerInstancePtr,
			0,
			(XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION));

	u32 CounterControlReg = Xil_In32(TimerInstancePtr.BaseAddress + XTmrCtr_Offsets[0] + XTC_TCSR_OFFSET);
	CounterControlReg = CounterControlReg | XTC_CSR_ENABLE_PWM_MASK | XTC_CSR_EXT_GENERATE_MASK;
	Xil_Out32(TimerInstancePtr.BaseAddress + XTmrCtr_Offsets[0] + XTC_TCSR_OFFSET, CounterControlReg);

	XTmrCtr_SetOptions(&TimerInstancePtr,
			1,
			(XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION));

	CounterControlReg = Xil_In32(TimerInstancePtr.BaseAddress + XTmrCtr_Offsets[1] + XTC_TCSR_OFFSET);
	CounterControlReg = CounterControlReg | XTC_CSR_ENABLE_PWM_MASK | XTC_CSR_EXT_GENERATE_MASK;
	Xil_Out32(TimerInstancePtr.BaseAddress + XTmrCtr_Offsets[1] + XTC_TCSR_OFFSET, CounterControlReg);

	XTmrCtr_SetResetValue(&TimerInstancePtr,
			0, //Change with generic value
			0x11e1a300);
		XTmrCtr_SetResetValue(&TimerInstancePtr,
				1, //Change with generic value
				0x5f5e100);

	xStatus=ScuGicInterrupt_Init(XPAR_PS7_SCUGIC_0_DEVICE_ID,&TimerInstancePtr);
	if(XST_SUCCESS != xStatus)
		print(" :( SCUGIC INIT FAILED \n\r");

	XTmrCtr_Start(&TimerInstancePtr,0);
	print("timer start \n\r");
	XTmrCtr_Start(&TimerInstancePtr,1);
	print("timer 2 start \n\r");

	print("Wait for the Timer interrupt to tigger \r\n");
	print("########################################\r\n");
	print(" \r\n");

	while(1)
	{
	}
	cleanup_platform();
	return 0;
}