티스토리 뷰

장난치기

Waveform 작성하기

알 수 없는 사용자 2008. 4. 1. 00:28

출처 : http://muosys.egloos.com/142813

 

Ori님이 지적해 주신대로 본좌가 제공한 UniHigh v1.7소스코드를 컴파일하려고 하면 에러가 발생할 것이다.
C:CypressUSBExamplesFX2UniHigh1.7gpif.c와 C:CypressUSBTargetIncfx2regs.h의 autopointer1에 대한 정의가 불일치하는 문제 땜에 발생한 에러이다.
gpif.c의 정의를 헤더파일에 맞추어 고쳐주는 것이 정석이겠으나, 우리가 waveform을 손봐서 새로 gpif.c를 생성할 때마다 이를 매번 고쳐주어야 하기 땜에, 본좌처럼 아예 fx2regs.h의 정의를 gpif.c의 정의에 맞추어 고쳐주는 것이 나중에 작업하기가 편할 것이다.
fx2regs.h의 AUTOPTR1H/L을 AUTOPTRH/L1으로 바꾸어 주시라.
(본좌는 바꾼 지가 오래돼서 어느 것이 원래 것이고, 어느 것이 바꿔놓은 것인지 헛갈린다. 틀렸다면 바로 지적 주시라. )
GPIF Designer를 프로그램한 사람하고, Development Kit을 패키징한 Cypress직원 둘 사이가 안 좋았었나 보다. ㅋㅋㅋ

전회에 작업한 바탕위에 waveform을 그려보자.
waveform을 그리는 것도 일종의 프로그래밍이므로, 먼저 flow diagram을 그려보는 것이 도움이 된다. (본좌가 설명하기에)

Array

(여담..
본좌가 왜 스스로 만든 허접떼기 프로토콜을 설명하는데 왜 일케 공을 들이는지 궁금해 할 행자들에게..
행자들이 Cypress FX2와 외부 디바이스간의 인테페이스를 하려고 할 때 이 허접 프로토콜의 형태를 크게 벗어나지 않을 것이기 때문.)

위 flow diagram은 이전 강의에서 보여준 (parallel port의 host측) flow diagram과 맞물려 돌아가는 놈이다.
바로 UniHigh v1.6의 TD_Poll()의 펌웨어가 위 logic을 구현해 놓은 예가 되겠다.
우리가 하고자 하는 일이 UniHigh v1.6의 TD_Poll()이 하는 일을 날랜 GPIF가 대신 하도록 waveform을 디자인하는 것이다.

위 flow diagram을 state diagram으로 바꾸어 그려놓은 것이 아래 그림 되것다.
logic flow의 어느 부분이 state diagram에서는 어떻게 기술되어 있는지를 잘 비교해보시라.

Array

구찮더라도 waveform 그리기에 익숙해지기 전까지는,
state diagram을 먼저 그려보는 것이 waveform을 작성할 때 실수를 줄여준다.

그렇다면 위의 state diagram을 waveform으로 옮겨 놓으면 GPIF가 잘 동작하느냐?
천만의 말씀 만만의 콩떡이다.
위의 logic 그 자체는 문제가 없으나, parallel port의 host측과 맞물려 돌아 갈 때에는 문제가 생긴다.
함 “Parallel” 어플리케이션의 SendData() 함수를 보자.

for( DWORD i=0; i<dwBufLen; i++ )
{
    ……
    // Set STROBE HIGH
    DlPortWritePortUchar( … );
}
// Set SELECT HIGH
DlPortWritePortUchar( …… );

( textarea라는 html 테그가 안먹혀서 xmp 테그를 사용했더니 br이 출력된다. 이론~. 개떡같이 보여도 찰떡같이 알아 드시라.)
데이터 전송이 마무리되는 시점에서 어플리케이션 쪽에서 STROBE를 high로 세팅한 다음, SELECT를 high로 세팅 할 때까지 약간의 시간 지연이 발생한다.
STROBE를 high로 세팅한 다음에 마지막으로 for문의 조건검사

(i<dwBufLen)

를 하고 나서야 SELECT를 high로 세팅하기 때문이다.
그런데 위쪽의 flow diagram처럼 STROBE가 high가 되면 S4 상태가 되고, 바로 SELECT의 상태에 따라 Idle상태로 갈 것인지 S2상태로 갈 것인지가 결정되는 경우에는 패러렐 호스트에서 STROBE high -> SELECT high의 시간지연 때문에 무조건 S2상태로 분기하게 된다.
그러면 호스트에서는 데이터를 다 보냈는데도, GPIF에서는 S2 상태에서 데이터를 기다리는 곤란한 시츄에이션이 발생하게 된다.
바꿔 말하면 호스트-슬레이브 시스템이 먹통이 된다.
본좌 이 문제 잡느라고 고민 좀 했다.

이 문제를 해결하기 위해 수정한 state diagram이 아래의 그림이다.
S1과 S2사이에 새로운 state를 추가 했다.

Array

이 그림의 state의 번호를 잘 메긴 것이 이전 강의에 보여 주었던 완성된 state diagram이다.

Array

쓰다보니 주저리 주저리 길어지기는 했지만, 이렇게 특정한 상황에서의 문제 해결방법을 설명하는데 시간을 많이 투자한다는 것은 별로 바람직하지는 않다.
만 본좌는 혹시라도 예제의 waveform을 이해하는데 행자들이 어려움을 겪을까봐 길게 설명했다.

이제까지는 변죽울리기였다면 본격적으로 waveform을 작성해 보자.
별거 없다. 위에서 작성한 state diagram을 마우스 클릭하여 그대로 그리면 된다.

한 state에서 다음 state로 바뀌는데 어떤 조건에 따라야 한다면, DP(Decision Point)를 추가하고, 그 조건을 세팅해 주면 된다.

Waveform의 “Status” 부분에 마우스를 클릭하면 DP(마름모꼴)가 생성되는데, 그 DP에서 오른버튼 클릭하면 조건을 입력할 수 있는 대화 창이 뜬다.

어떤 state에서 데이터버스(FD[15:0])의 데이터를 FIFO로 입력 받아야 한다면 “Data” 부분을 클릭하면 삼각형 모양이 생성되는데, 데이터가 유효한 시점에서 (오른 버튼 클릭하여) Activate Data를 지정해 주고, 데이터의 유효가 끝나는 지점에서 Deactivate Data를 지정해 주면 된다.

Array

* “Data”의 삼각형에서 오른 버튼 클릭했을 때 나타나는 메뉴에서 “Next FIFO Data”항목은 그 State에 머무는 동안 (우리의 경우에는 S3에) Clock이 한번 transition할 때마다 GPIF가 새로운 데이터를 읽거나 쓰는 것을 의미한다.
따라서 이런 경우는 GPIF를 Synchronous 모드로 동작시킬 경우에 쓸 수 있는 옵션이다.

우리의 경우에는 S3로 처음 들어 갈 때 한번 데이터를 읽어 들이고, 그 다음에 STROBE high 신호가 떨어지지 않아서 계속 S3를 돌아도 (=Clock이 계속 뛰어도 - Async모드여도 GPIF 내부적으로는 클럭에 맞추어 동작하므로 ) 한번 돌 때마다 데이터를 FIFO에 잡아 넣지 않는다.

Control 신호 또한 원하는 지점(state)에서 High <-> Low가 되도록 지정 할 수 있다.

그렇게 해서 그린 waveform이 아래의 그림이다.
(다운받아서 크게 보시라)

Array

해보면 하시겠지만 DP등을 추가함에 따라 state는 자동으로 생성된다.

'장난치기' 카테고리의 다른 글

"밥 할 능력 없으면 주는 대로 처 먹어!"  (0) 2008.04.06
인터넷의 의문점  (0) 2008.04.05
저는 사실 여자입니다.  (62) 2008.03.31
집중력을 높이는 방법  (0) 2008.03.31
잠을 쫒는 방법  (0) 2008.03.31