시리얼 통신(DBGU) 인터럽트

 // 인터럽트를 이용한 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....
// 일반적으로 시리얼 통신에서 데이터를 전송하는 시점은 정해져 있다. 반면 데이터를 수신하는 시점은 정해져 있는 것이 아니기때문에 인터럽트는 보통 RXRDY만을 사용한다.
// 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....
// PC 터미널에서 각각 1, 10, 100, 1000을 입력하고 Enter를 입력하면 LED를 ON,OFF 시킨다.
// 1 : 모든 LED OFF / 10 : LED 1개 ON / 100 : LED 2개 ON / 1000 : LED 3개 ON
// 이 예제는 전역 변수를 여러 함수가 공유하고 있다. 이는 공유데이터 문제를 야기할 수 있다. 하나의 함수가 공유 데이터를 사용하고 있는 도중에 다른 함수가 그 값을 바꾸면 문제가 발생한다.

+ Recent posts