void timer_handler(void)
{
volatile unsigned long dummy;
dummy = AT91C_BASE_TC0->TC_SR; //인터럽트 클리어
if(echo_flag) //@ if Echo ON State -> Trigger Off
{
BASE_PIO_TRIGGER->PIO_CODR = ULTRA_TRIGGER; //@Trigger Off
cnt++;
}
}
static void configure_tc(void)
{
volatile unsigned long dummy;
// 타이머카운터 0(TC0) 클록 공급
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);
// TC0의 클록공급을 금지
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
// TC0의 인터럽트를 전부 금지
AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;
// TC0의 상태 레지스터 Dummy 읽기
dummy = AT91C_BASE_TC0->TC_SR;
// TC0관련 인터럽트를 금지
AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_TC0);
// TC0관련 인터럽트가 오면 호출될 함수 등록
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long) timer_handler;
// TC0인터럽트의 타입과 우선순위 (High Level sensitive, 가장낮음
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | AT91C_AIC_PRIOR_LOWEST;
// TC0인터럽트의 엣지 검출기 클리어
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC0);
// 채널모드 레지스터 = (상승엣지가 캡쳐트리거 신호로 사용), (카운터 리셋후 클록공급 시작)
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV2_CLOCK | AT91C_TC_CPCTRG;
// TC_RC (Register C) 레지스터와 비교해서 인터럽트 발생 시작
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
// TC_CV레지스터와 비교될 카운터 값 (@6Mhz : 348count => 58us (58us == 1cm))
AT91C_BASE_TC0->TC_RC = 348;
// TC0관련 AIC인터럽트 허용
AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC0);
//CLKDIS가 1로 설정되지 않았다면 클록이 공급되도록 허용 (위에서 1로 설정되어 있으므로 무시)
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
// 해당채널의 카운터 리셋후 클록공급 시작
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
}