시리얼 통신(DBGU) 인터럽트
// 인터럽트를 이용한 echo 예제
// 일반적으로 시리얼 통신에서 데이터를 전송하는 시점은 정해져 있다. 반면 데이터를 수신하는 시점은 정해져 있는 것이 아니기때문에 인터럽트는 보통 RXRDY만을 사용한다.
// DBGU(디버그 유닛)은 System Controller로 장치 PID1를 사용한다.
// 시리얼 통신으로 LED를 ON시키는 예제
// PC 터미널에서 각각 1, 10, 100, 1000을 입력하고 Enter를 입력하면 LED를 ON,OFF 시킨다.
// 1 : 모든 LED OFF / 10 : LED 1개 ON / 100 : LED 2개 ON / 1000 : LED 3개 ON
// 이 예제는 전역 변수를 여러 함수가 공유하고 있다. 이는 공유데이터 문제를 야기할 수 있다. 하나의 함수가 공유 데이터를 사용하고 있는 도중에 다른 함수가 그 값을 바꾸면 문제가 발생한다.
// 인터럽트를 이용한 echo 예제
//---------- 디버그 유닛 관련 I/O 제어 레지스터
#define DBGU_CR (*(volatile unsigned int *) 0xFFFFF200) // DBGU Control Register
#define DBGU_MR (*(volatile unsigned int *) 0xFFFFF204) // DBGU Mode Register
#define DBGU_IER (*(volatile unsigned int *) 0xFFFFF208) // DBGU Interrupt Enable Register
#define DBGU_IDR (*(volatile unsigned int *) 0xFFFFF20C) // DBGU Interrupt Disalbe Register
#define DBGU_IMR (*(volatile unsigned int *) 0xFFFFF210) // DBGU Interrupt Disalbe Register
#define DBGU_SR (*(volatile unsigned int *) 0xFFFFF214) // DBGU Status Register
#define DBGU_RHR (*(volatile unsigned int *) 0xFFFFF218) // DBGU Receive Holding Register
#define DBGU_THR (*(volatile unsigned int *) 0xFFFFF21C) // DBGU Transmit Holding Register
#define DBGU_BRGR (*(volatile unsigned int *) 0xFFFFF220) // DBGU Baud Rate Generator Register
//---------- 인터럽트 제어기 IO설정
#define AIC_IECR (*(volatile unsigned int *) 0xFFFFF120) // 인터럽트 허
용 레지스터
#define AIC_IDCR (*(volatile unsigned int *) 0xFFFFF124) // 인터럽트 금지 레지스터
#define AIC_ICCR (*(volatile unsigned int *) 0xFFFFF128) // 인터럽트 클리어 레지스터
#define AIC_ISCR (*(volatile unsigned int *) 0xFFFFF12C) // 인터럽트 세트 레지스터
#define AIC_SMR ((volatile unsigned int *) 0xFFFFF000) // AIC 소스 모드 레지스터
#define AIC_SVR ((volatile unsigned int *) 0xFFFFF080) // AIC 소
스 벡터 레지스터
//---------- 입출
력 IO설정
#define PIO_PUDR (*(volatile unsigned int *) 0xFFFFF460) // PIO Pull-Up Disable Register
#define PIO_PUER (*(volatile unsigned int *) 0xFFFFF464) // PIO Pull-Up Enable Register
#define PIO_IER (*(volatile unsigned int *) 0xFFFFF440) // PIO Interrupt Enable Register
#define PIO_IDR (*(volatile unsigned int *) 0xFFFFF444) // PIO Interrupt Disable Register
#define PIO_IMR (*(volatile unsigned int *) 0xFFFFF448) // PIO Interrupt Mask Register
#define PIO_ISR (*(volatile unsigned int *) 0xFFFFF44C) // PIO Interrupt Status Register
#define PIO_ASR (*(volatile unsigned int *) 0xFFFFF470) // PIO Peripheral A Select Register
#define PIO_BSR (*(volatile unsigned int *) 0xFFFFF474) // PIO Peripheral B Select Register
#define PIO_IFER (*(volatile unsigned int *) 0xFFFFF420) // PIO Glitch Input Filter Enable Register
#define PIO_IFDR (*(volatile unsigned int *) 0xFFFFF424) // PIO Glitch Input Filter Disable Register
#define PIO_SODR (*(volatile unsigned int *) 0xFFFFF430) //출력
#define PIO_CODR (*(volatile unsigned int *) 0xFFFFF434) //출력 하지 않음
#define PIO_OER (*(volatile unsigned int *) 0xFFFFF410) //출력 방향 설정
#define PIO_ODR (*(volatile unsigned int *) 0xFFFFF414) //출력 방향 설정
#define PIO_PER (*(volatile unsigned int *) 0xFFFFF400) //병렬 입출력 제
어 레지스터 병렬 입출력 포트로 사용한다.
#define PIO_PDR (*(volatile unsigned int *) 0xFFFFF404) //병렬 입출력 제어 레지스터 병렬 입출력 포트로 사용한다.
//---------- 전력 제어 설정
#define PMC_PCER (*(volatile unsigned int *) 0xFFFFFC10)
#define PMC_PCDR (*(volatile unsigned int *) 0xFFFFFC14)
#define MASTERCLOCK 48000000
#define INTERR 0x00000100
#define LED 0x00000010
//--------- 전역 변수
unsigned char data;
void Delayms(unsigned int ms) //딜레이 함
수..
{
volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;
for(count = 0; count < countmax; count++);
}
void DBGU_write(char d) // 송신 함수
{
while(0 == (DBGU_SR & 0x0002));
DBGU_THR = d;
}
void DBGU_read() // 인
터럽트 처리 루틴
{
// echo 기능
data = DBGU_RHR;
DBGU_write(data);
}
int main(void)
{
// PMC setting
PMC_PCER = (unsigned int)1 << 2; // PMC_PCER = (unsigned int)1 << 2;
DBGU_CR = (1<<2)|(1<<3); // 송수신부 리셋 및 금지
AIC_IDCR = (1<<1); //인터럽트 금지
// PIO setting
PIO_PDR = (1<<9)|(1<<10); // 병렬 포트 사용 금지
PIO_ASR = (1<<9)|(1<<10); // 장치 A 사용
PIO_BSR = 0; // 장치 B 사용 금지
// DBGU setting
DBGU_IER = (1 << 0); // RXRDY enable
DBGU_MR = (1<<11); // Parity 사용하
지 않음
DBGU_BRGR = 313; // Baud rate = 9600
DBGU_CR = (1<<6)|(1<<4); // tx, rx enable
// AIC setting.
AIC_SMR[1] = (1<<5)|(1<<6)|(1<<2)|(1<<0); // Positive edge trigger, Prior = 5
AIC_SVR[1] = (unsigned int)DBGU_read; // 인터럽트 처리 루틴
AIC_ICCR = (1<<1);
AIC_IECR = (1<<1); // 인터럽트 활성화
while(1)
{
}
return 0;
} // End Main....
// DBGU(디버그 유닛)은 System Controller로 장치 PID1를 사용한다.
// 시리얼 통신으로 LED를 ON시키는 예제
//---------- 디버그 유닛 관련 I/O 제어 레지스터
#define DBGU_CR (*(volatile unsigned int *) 0xFFFFF200) // DBGU Control Register
#define DBGU_MR (*(volatile unsigned int *) 0xFFFFF204) // DBGU Mode Register
#define DBGU_IER (*(volatile unsigned int *) 0xFFFFF208) // DBGU Interrupt Enable Register
#define DBGU_IDR (*(volatile unsigned int *) 0xFFFFF20C) // DBGU Interrupt Disalbe Register
#define DBGU_IMR (*(volatile unsigned int *) 0xFFFFF210) // DBGU Interrupt Disalbe Register
#define DBGU_SR (*(volatile unsigned int *) 0xFFFFF214) // DBGU Status Register
#define DBGU_RHR (*(volatile unsigned int *) 0xFFFFF218) // DBGU Receive Holding Register
#define DBGU_THR (*(volatile unsigned int *) 0xFFFFF21C) // DBGU Transmit Holding Register
#define DBGU_BRGR (*(volatile unsigned int *) 0xFFFFF220) // DBGU Baud Rate Generator Register
//---------- 인터럽트 제어기 IO설정
#define AIC_IECR (*(volatile unsigned int *) 0xFFFFF120) // 인터럽트 허
용 레지스터
#define AIC_IDCR (*(volatile unsigned int *) 0xFFFFF124) // 인터럽트 금지 레지스터
#define AIC_ICCR (*(volatile unsigned int *) 0xFFFFF128) // 인터럽트 클리어 레지스터
#define AIC_ISCR (*(volatile unsigned int *) 0xFFFFF12C) // 인터럽트 세트 레지스터
#define AIC_SMR ((volatile unsigned int *) 0xFFFFF000) // AIC 소스 모드 레지스터
#define AIC_SVR ((volatile unsigned int *) 0xFFFFF080) // AIC 소
스 벡터 레지스터
//---------- 입출
력 IO설정
#define PIO_PUDR (*(volatile unsigned int *) 0xFFFFF460) // PIO Pull-Up Disable Register
#define PIO_PUER (*(volatile unsigned int *) 0xFFFFF464) // PIO Pull-Up Enable Register
#define PIO_IER (*(volatile unsigned int *) 0xFFFFF440) // PIO Interrupt Enable Register
#define PIO_IDR (*(volatile unsigned int *) 0xFFFFF444) // PIO Interrupt Disable Register
#define PIO_IMR (*(volatile unsigned int *) 0xFFFFF448) // PIO Interrupt Mask Register
#define PIO_ISR (*(volatile unsigned int *) 0xFFFFF44C) // PIO Interrupt Status Register
#define PIO_ASR (*(volatile unsigned int *) 0xFFFFF470) // PIO Peripheral A Select Register
#define PIO_BSR (*(volatile unsigned int *) 0xFFFFF474) // PIO Peripheral B Select Register
#define PIO_IFER (*(volatile unsigned int *) 0xFFFFF420) // PIO Glitch Input Filter Enable Register
#define PIO_IFDR (*(volatile unsigned int *) 0xFFFFF424) // PIO Glitch Input Filter Disable Register
#define PIO_SODR (*(volatile unsigned int *) 0xFFFFF430) //출력
#define PIO_CODR (*(volatile unsigned int *) 0xFFFFF434) //출력 하지 않음
#define PIO_OER (*(volatile unsigned int *) 0xFFFFF410) //출력 방향 설정
#define PIO_ODR (*(volatile unsigned int *) 0xFFFFF414) //출력 방향 설정
#define PIO_PER (*(volatile unsigned int *) 0xFFFFF400) //병렬 입출력 제
어 레지스터 병렬 입출력 포트로 사용한다.
#define PIO_PDR (*(volatile unsigned int *) 0xFFFFF404) //병렬 입출력 제어 레지스터 병렬 입출력 포트로 사용한다.
//---------- 전력 제어 설정
#define PMC_PCER (*(volatile unsigned int *) 0xFFFFFC10)
#define PMC_PCDR (*(volatile unsigned int *) 0xFFFFFC14)
#define MASTERCLOCK 48000000
#define INTERR 0x00000100
#define LED 0x00000010
//--------- 전역 변수
char data[20];
int index = 0;
void Delayms(unsigned int ms) //딜레이 함수..
{
volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;
for(count = 0; count < countmax; count++);
}
int atoi(char *c) // Charter to Integer
{
int result = 0;
int val = 1;
int i;
char *tmp = c;
while(*tmp != '\0')
{
val *= 10;
tmp++;
}
tmp = c;
for(i = (val / 10) ; 1 <= i ; i /= 10)
{
result += ((*tmp - 48) * i);
tmp++;
}
return result;
}
void LED_Decode() // 신
호 decode
{
int num;
num = atoi(data);
switch(num)
{
case 1:
PIO_CODR = 0xFF;
break;
case 10:
PIO_CODR = 0xFF;
PIO_SODR = 0x1;
break;
case 100:
PIO_CODR = 0xFF;
PIO_SODR = 0x3;
break;
case 1000:
PIO_CODR = 0xFF;
PIO_SODR = 0x7;
break;
default:
break;
}
}
void DBGU_write(char d) // 송신 함수
{
while(0 == (DBGU_SR & 0x0002));
DBGU_THR = d;
}
void DBGU_read() // 수
신 함수
{
char buf;
buf = DBGU_RHR;
if(buf != '\r')
{
data[index++] = buf;
}
else
{
data[index] = '\0';
index = 0;
LED_Decode();
}
}
int main(void)
{
// PMC setting
PMC_PCER = (unsigned int)1 << 2; // PMC_PCER = (unsigned int)1 << 2;
DBGU_CR = (1<<2)|(1<<3); // 송수신부 리셋 및 금지
AIC_IDCR = (1<<1); //인터럽트 금지
// PIO setting
PIO_PER = 0xFF; // Pin0 ~ Pin7 병렬포트 사용
PIO_OER = 0xFF; // Pin0 ~ Pin7 출력으로 설정
PIO_PDR = (1<<9)|(1<<10); // 병렬 포트 사용 금지
PIO_ASR = (1<<9)|(1<<10); // 장치 A 사용
PIO_BSR = 0; // 장치 B 사용 금지
// DBGU setting
DBGU_IER = (1 << 0); // RXRDY enable
DBGU_MR = (1<<11); // Parity 사용하
지 않음
DBGU_BRGR = 313; // Baud rate = 9600
DBGU_CR = (1<<6)|(1<<4); // tx, rx enable
// AIC setting.
AIC_SMR[1] = (1<<5)|(1<<6)|(1<<2)|(1<<0); // Positive edge trigger, Prior = 5
AIC_SVR[1] = (unsigned int)DBGU_read; // 인터럽트 처리 루틴
AIC_ICCR = (1<<1);
AIC_IECR = (1<<1); // 인터럽트 활성화
while(1)
{
}
return 0;
} // End Main....
// 1 : 모든 LED OFF / 10 : LED 1개 ON / 100 : LED 2개 ON / 1000 : LED 3개 ON
// 이 예제는 전역 변수를 여러 함수가 공유하고 있다. 이는 공유데이터 문제를 야기할 수 있다. 하나의 함수가 공유 데이터를 사용하고 있는 도중에 다른 함수가 그 값을 바꾸면 문제가 발생한다.