도와주세요!!
안녕하세요.
EZBOOT에서 외부 인터럽트를 사용하고자 다음과 같이 함수를 만들었습니다.
void Init_RTS_Interrupt(void)
{
int RegData = 0 ;
// Get GPH1 Control Reg to EINT11 ~ 13
RegData = REG_GPH1CON ;
RegData &= 0xFF000FFF ;
RegData |= 0x00FFF000 ;
REG_GPH1CON = RegData ;
// Set Interrupt Type is Falling Edge
RegData = REG_EXT_INT_1_CON ;
RegData &= 0xFF000FFF ;
RegData |= 0x00222000 ;
REG_EXT_INT_1_CON = RegData ;
irq_request(TRG1_INT, Trigger1_Interrupt_Handler) ;
irq_request(TRG2_INT, Trigger2_Interrupt_Handler) ;
irq_request(ENC_INT, Encoder_Interrupt_Handler) ;
irq_active(TRG1_INT) ;
irq_active(TRG2_INT) ;
irq_active(ENC_INT) ;
irq_enable() ;
}
이것을 실행하면
인터럽트가 모두 Enable되고 벡터 어드레스도 설정이 되는데,
인터럽트가 걸리지 않습니다.
무엇이 문제일까요?
다른 레지스터를 설정해 주어야 하는 것이 있나요?
인터럽트 트리거를 어떤 방법으로 하셨나요?
그리고 인터럽트가 완전하게 무한으로 걸리나요? 아니면 어느정도 걸리다 대기하나요?
인터럽트는 완전 무한으로 걸리고요. 트리거 방법은 일반적인 리셋 스위치로 생각하시면 됩니다.
물론 풀업은 되어있고, 스위치를 누르면 Low로 떨어지는 형태의...
그리고, EZBoot 소스 내부에 irq.c에서 irq_clear() 함수 내부에 아무것도 없더라고요.
do_irq() 함수를 보면 인터럽트를 서비스 하고 VIC0ADDRESS에 0을 쓰는 것 보니까 이곳에서 인터럽트를 클리어하는 것 같은데...
좀 더 분석을 해봐야지 알 것 같습니다...
해 보았습니다.
증상은 동일하고 내부에서 인터럽트 서비스 루틴 내에서 이 레지스터를 클리어 해 보았습니다.
그러나, 그 값이 변경되지 않습니다.
인터럽트 서비스 루틴은 다음과 같습니다.
void Trigger1_Interrupt_Handler(void)
{
int i, RData = 0 ;
printf("A : REG_EXT_INT_1_PEND : 0x%08X\n", REG_EXT_INT_1_PEND) ;
REG_EXT_INT_1_PEND = 0 ;
printf("B : REG_EXT_INT_1_PEND : 0x%08X\n", REG_EXT_INT_1_PEND) ;
Alarm2_LED_ON() ;
R1_DATA.CamerTrgPosition[0][R1_DATA.CameraReadIndex[0]] += ENC_COUNT + R1_DATA.CameraPosition1 ;
R1_DATA.CamerTrgPosition[1][R1_DATA.CameraReadIndex[1]] += ENC_COUNT + R1_DATA.CameraPosition2 ;
R1_DATA.CamerTrgPosition[2][R1_DATA.CameraReadIndex[2]] += ENC_COUNT + R1_DATA.CameraPosition3 ;
R1_DATA.CamerTrgPosition[3][R1_DATA.CameraReadIndex[3]] += ENC_COUNT + R1_DATA.CameraPosition4 ;
R1_DATA.CamerTrgPosition[4][R1_DATA.CameraReadIndex[4]] += ENC_COUNT + R1_DATA.CameraPosition5 ;
R1_DATA.CamerTrgPosition[5][R1_DATA.CameraReadIndex[5]] += ENC_COUNT + R1_DATA.CameraPosition6 ;
R1_DATA.CamerTrgPosition[6][R1_DATA.CameraReadIndex[6]] += ENC_COUNT + R1_DATA.CameraPosition7 ;
R1_DATA.CamerTrgPosition[7][R1_DATA.CameraReadIndex[7]] += ENC_COUNT + R1_DATA.CameraPosition8 ;
R1_DATA.EjectTrgPosition[0][R1_DATA.EjectReadIndex[0]] += ENC_COUNT + R1_DATA.GoodEjectPosition ;
R1_DATA.EjectTrgPosition[1][R1_DATA.EjectReadIndex[1]] += ENC_COUNT + R1_DATA.FailEjectPosition1 ;
R1_DATA.EjectTrgPosition[2][R1_DATA.EjectReadIndex[2]] += ENC_COUNT + R1_DATA.FailEjectPosition2 ;
R1_DATA.EjectTrgPosition[3][R1_DATA.EjectReadIndex[3]] += ENC_COUNT + R1_DATA.FailEjectPosition3 ;
R1_DATA.EjectTrgPosition[4][R1_DATA.EjectReadIndex[4]] += ENC_COUNT + R1_DATA.RetestEjectPosition ;
for(i = 0; i < 8; i++)
{
R1_DATA.CameraReadIndex[i]++ ;
if(R1_DATA.CameraReadIndex[i] == PARTS_MAX)
R1_DATA.CameraReadIndex[i] = 0 ;
}
for(i = 0; i < 5; i++)
{
R1_DATA.EjectReadIndex[i]++ ;
if(R1_DATA.EjectReadIndex[i] == PARTS_MAX)
R1_DATA.EjectReadIndex[i] = 0 ;
}
Alarm2_LED_OFF() ;
}
그리고, 터미널로 돌아오는 결과는 다음과 같습니다.
おおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお
Uart negotiation Error
Insert an OTG cable into the connector!
Enumeration TimeOut Error
BL1 1.00
NAND COPY ...
ADDR=24000000
SIZE=00040000
START MAIN
Detect vid=ec pid=dc cell=10 size=95
Samsung NAND 512M 3.3V 8-bit page=2048 erase=128KB oob=64 SLC
A : REG_EXT_INT_1_PEND : 0x00000008
B : REG_EXT_INT_1_PEND : 0x00000008
A : REG_EXT_INT_1_PEND : 0x00000008
B : REG_EXT_INT_1_PEND : 0x00000008
A : REG_EXT_INT_1_PEND : 0x00000008
B : REG_EXT_INT_1_PEND : 0x00000008
A : REG_EXT_INT_1_PEND : 0x00000008
B : REG_EXT_INT_1_PEND : 0x00000008
A : REG_EXT_INT_1_PEND : 0x00000008
B : REG_EXT_INT_1_PEND : 0x00000008
A : REG_EXT_INT_1_PEND : 0x00000008
B : REG_EXT_INT_1_PEND : 0x00000008
A : REG_EXT_INT_1_PEND : 0x00000008
B : REG_EXT_INT_1_PEND : 0x00000008
A : REG_EXT_INT_1_PEND : 0x00000008
B : REG_EXT_INT_1_PEND : 0x00000008
이런 상태가 계속 됩니다.
REG_EXT_INT_1_MASK 레지스터의 해당 비트를 클리어하고 난 후에 인터럽트는 동작이 됩니다.
하지만, 무한으로 인터럽트를 실행합니다.
즉, 인터럽트를 한 번 트리거하면 계속 그 루틴이 수행됩니다.
인터럽트 서비스 루틴을 돌고 나오면 다음 인터럽트를 기다려야 하는데, 다신 인터럽트 서비스 루틴으로 진입하는 것 같습니다.
인터럽트 서비스 루틴 내부에서, REG_VIC0ADDRESS를 0으로 만들어도 그 내용이 변경되지 않습니다.
왜 그럴까요?
메뉴얼에 보면 인터럽트 서비스 루틴의 종료에서 이 레지스터에 아무 값이나 넣으면, 인터럽트가 클리어 된다고 되어있는데,
이상합니다.
금일까지 답을 주신다고 해놓고....
기다리다가 퇴근 합니다. 내일은 답을 얻을 수 있기를 기대합니다.