기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.
안녕하세요~
16c554칩을 컨트롤하다가 질문이 있어서 글을 올립니다.
먼저 제가 작업하고 있는 환경은 이솝보드는 아니구요, smdk2440에 16c554칩을 이용해서 포트를 4개 추가하는 중입니다.
smdk2440에서 제공하는 포트 3개가 다 잡혀있는 상태구요. 추가적으로 4개를 더 사용해야 합니다.
현재는 하드웨어적으로 16c554칩에 문제가 없는지 확인하는 단계인데 정상 작동을 판단하기 위해서
디바이스 드라이버가 아닌 일반 어플로 직접 칩을 제어하려고 합니다.
제가 아직 리눅스 초보라 디바이스 드라이버를 만드는 작업보다 일반 어플에서 작업을 해보려구 하는데요.
먼저 제가 작성한 코드입니다.
여긴 선언부분 이구요..
#define UART_BASE (0x20000000+0x2000) //GCS4 + 10000000000000(2)
#define UARTA (0) //10000000000000(2)
#define UARTB (0x100) //10000100000000(2)
#define UARTC (0x200) //10001000000000(2)
#define UARTD (0x300) //10001100000000(2)
#define RHR 0x0
#define THR 0x0
#define IER 0x1
#define FCR 0x2
#define ISR 0x2
#define LCR 0x3
#define MCR 0x4
#define LSR 0x5
#define MSR 0x6
#define SPR 0x7
#define DLL 0x0
#define DLM 0x1
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)
....
이쪽은 main함수입니다.
iFd = open("/dev/mem", O_RDWR | O_SYNC);
if(iFd < 0)
{
printf("open errn");
return -1;
}
(void*)pMap = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, iFd, UART_BASE & ~MAP_MASK);
pAddr = pMap + UARTA;
*(pAddr + IER) = 0x0F;
*(pAddr + FCR) = 0xC7;
//_nop_();
int i = 100;
while(i--);
printf("startn");
*(pAddr + FCR) = 0xC1;
*(pAddr + LCR) = 0x83;
*pAddr = 12; // 9600 //DLL
*(pAddr+1) = 0; // 9600 //DLM
*(pAddr + LCR) = 0x03;
temp = (char)(*pAddr);
for(int i=0; i<600000; i++)
{
// 수신
temp = *(pAddr + LSR);
while(temp & 0x01)
{
*(pAddr + MCR) = 0x08; //0x0
temp = (char)(*pAddr);
printf("read [%d]n", temp);
sleep(1);
}
// 전송
temp = *(pAddr + LSR);
if(temp & (1<<5))
{
*(pAddr + MCR) = 0xA; //0x2
*pAddr = 'a';
printf("write 'a'n");
sleep(1);
}
}
하드웨어는 RTS가 high상태가 되면 출력상태로 인식하게 되있구요,
그래서 위와 같이 칩을 직접 제어하도록 해봤습니다.
RTS신호선에 low, high는 제어가 되는걸 보면 칩셀까진 성공한거 같은데요,
칩셀하고 패리티비트나 보레이트 등을 설정하고 RTS에 high 준 다음에 바로 데이타를 쓰면
신호선에 데이타가 깨지던지 말던지 아무신호나 뜰줄 알았는데 반응이 없습니다.
제가 뭔가 착각을 하고 있는거 같은데 uart쪽은 처음이라 뭐가 빠진건지 모르겠네요.
조언 부탁드리겠습니다~
리눅스의 어플리케이션에서는 /dev/ttyS0 장치 열고 C 라이브러리에서 제공하는 함수를 써서 프로그래밍 합니다.
리눅스에서는 리눅스에서 제공하는 방식대로 프로그래밍 하셔야 합니다.
유닉스/리눅스상에서의 시리얼포트를 써서 프로그래밍하는 방법은 다음 문서를 참고하시기 바랍니다.
http://www.easysw.com/~mike/serial/serial.html
위의 내용처럼 시리얼 포트를 직접 콘트롤하는 방법은 펌웨어나 RTOS에서 device driver를 짤때 사용되는 방법이겠죠?
리눅스 커널에서 16C554 관련 Device Driver 를 수정하시려면 다음글을 참고하세요.
http://www.aesop.or.kr/?document_srl=22538
16C554 칩 리눅스 커널에 포팅 -> 부팅시 /dev/tty??? 장치명 자동으로 생성 -> 어플리케이션에서 open() 함수를 써서 /dev/tty??? 장치 열고
C 함수를 써서 프로그래밍 -- 대충 순서가 이렇게 되겠네요.
타겟보드가 없다면 데스크탑 컴퓨터에 리눅스를 설치하고 "어플리케이션에서 open() 함수를 써서 /dev/tty??? 장치 열고 C 함수를 써서 프로그래밍" <- 이부분만 우선 진행하신 다음 나중에 장비에 올릴때 크로스 컴파일만 하셔서 올리면 됩니다.