USB를 해 봅시다.
USB 세번째 입니다. 저번 시간까지는 기본적인 USB의 통신 프로토콜에 대해 공부했습니다. 오늘 원래 기본적인
소프트웨어 구조체나 함수를 정의해보려고 했으나 집에서 조금 더 문서를 보니깐 산넘어 산입니다. ㅋㅋ 그래서
이번 시간에는 천천히 어떤 플로우로 통신이 되는지 살펴보고 Device 측면에서의 초기화가 되는 과정을 공부하려고
합니다. 자 스타스~
자 USB Device가 있습니다. 컴퓨터에 연결하면 컴퓨터는 바로 인식하죠? 이 때 어떤 과정을 거치는지 살펴봅시다.
USB는 초기화의 과정을 몇개의 State를 사용해 표시합니다. 아래 도표를 보시면 그 상태와 순서가 나열되어 있습니다.
각 State는 위 도표에 있는 것처럼 Attached , Powered , Default , Address , Configured ,Suspended입니다. 각 State를
살펴봅시다. 먼저 Attached는 말 그대로 연결입니다. Powered도 뭐 큰 특징이 없습니다만 베터리를 가지고 있는 Device
입장에서는 전원을 선택할 수 있다는 점?정도가 특징이 되겠습니다. Powered 과정이 끝나도 Device는 어떤 USB 통신에도
응하면 안됩니다. 통신을 하기전에 bus를 통해 Reset 신호를 받아야 합니다. Reset 을 받은 후에 어드레스를 받을 수 있는
Default Address(00H) 상태가 되어야 합니다. 이 상태가 Default 상태입니다. 그 다음 State는 Address State입니다.
Address State는 호스트로부터 Address를 할당받은 상태를 말합니다. Address를 할당받은 이후에 Device는 반드시
Configuration 되어야 Device의 기능이 동작할 수 있는 상태가 됩니다. 이 상태가 Configured입니다. 마지막으로 Suspended
State가 있는데 장비는 어떤 상태에서도 일정 시간 동안 bus traffic이 없으면 Suspended 상태에 진입해야 합니다. 만약 bus가
활성화 되면 Suspended 상태에서 빠져나와 정상적인 통신을 거쳐야 합니다.
자 여기서 저는 궁금한 점이 생겼는데요. Powered 다음에 Reset 신호를 받아야 한다는데 도대체 리셋이 뭘까요?
USB2.0 문서에서 RESET으로 검색해보니 위와 같은 표가 나옵니다. 버스가 Reset state에 들어가려면 D+와 D-가 VIL(max)
보다 작은 상태로 10ms 이상 있어야 한다는 군요. ㅎㅎ 그냥 단순히 D+와 D-를 Low 상태로 10ms 이상 만들어 주면 Reset
Signal이랍니다. 뭐 간단하네요. ㅎ
다시 순서대로 곱씹어 보겠습니다. ㅎㅎ
1. USB 연결한다. -> Attached ,Powered
2. Reset! 신호를 받은 후(D+,D-라인이 10ms 동안 LOW) 자신의 address를 00H로 만든다. -> Default
3. 주소를 받는다. -> Addressed
4. Configuration을 받는다. -> Configured
5. 준비 끝~
이렇게 초기화를 하네요. 그럼 Reset까지는 프로그램 측면에서 할게 없습니다. 물론 Device입장에서 Reset을 받으면
Pipe를 초기화하고 모든 데이터를 없애버리는 등의 USB를 초기화시키는 프로그램이 있어야겠죠. 하지만 지금은 프로토콜만
보고 있는 중이니깐 Reset은 넘기고 주소를 받는 부분부터 시작합시다.
1. 리셋을 시킨 후에 호스트는 00H를 가진 아이에게 주소 설정을 하라는 토큰을 날릴거에요.
(*address에 d가 하나 없네요. -_-;; 수정하기 귀찮으니 고냥 갑시다. ㅋㅋ)
2. 토큰을 날린 후에는 Data를 날린다고 했었죠?
자 Data 패킷의 PID는 DATA0와 DATA1이 있다고 했습니다. DATA0는 0011B 이었으니까 PID는 11000011이 되겠죠?
그럼 PID는 해결되었고 DATA를 날려야하는데 어떤 데이터를 날릴까요? 물론 디바이스 표준이 있습니다.
위 표는 Setup Data의 포멧입니다. 모든 디바이스들은 위 요청에 대해 Default Control Pipe를 통해 응답해야한다고 되어
있습니다. Default Control Pipe는 EP0를 말하는 것이며 Setup Data는 총 8byte입니다. 그러면 한개씩 살펴봅시당.
bmRequestType은 어떻게 보내야 할까요? D7은 방향이네요. 당연히 요청이니까 Host-to-Device가 될 것 같습니다. D6,5는
Type인데 Class와 Vendor는 공부하면서 아직 접해본바가 없군요? 그럼 당연히 Standard라고 생각합니다. 마지막 D4~0는
Recipient(받는 놈)인데 당연히 Device가 받아야 하겠죠? 그럼 결국 bmRequestType = 0이 되겠네요.
자 다음은 bRequest입니다. 옆을 보니까 Table 9-3을 보라고 되어 있군요. 그럼 봅시다.
<Table 9-3>
쓰읍 bmRequestType까지 전부 나와 있군요!! 쳇. 뭐 어쨋든 표를 보시면 bRequest도 내용이 있습니다. bRequest는 1 byte
짜린데 무슨 문자가 길게 되어 있는데 당연히 문자가 들어가지는 않겠죠? 이것도 표로 되어 있습니다.
위 표를 보시면 bRequest의 SET_ADDRESS의 value가 5 라고 되어 있네요. bRequest까지 되었네요.
다음은 wValue입니다. 워드 사이즈의 필드로 요청에 따라 달라질 수 있다고 설명이 되어 있습니다. 어떻게 달라지는지는
Table 9-3에 나타나 있습니다. SET_ADDRESS의 wValue 파트를 보면 Device Address라고 되어 있습니다. Host는 이 필드를
통해서 Device에게 앞으로 사용할 Address 주소를 건네줍니다. Table 9-3을 보면 나머지 필드는 전부 zero 아님 None입니다.
더 이상 할게 없다는 소리겠죠? 참고로 Table 9-3의 마지막에 Data field가 있는데 만약 데이터가 있을 때는 wLength에 해당
데이터의 길이를 담고 전달하게 됩니다. 암튼 SET_ADDRESS의 요청으로 전달되는 데이터는 다음과 같겠네요.
3. 주소도 전부 전달했겠다. 그럼 남은 일은 Device가 Host로 HandShake로 ACK를 보내는 일만 남았습니다.
복습하자면 HandShake는 딱 1 Byte로 PID만 전달합니다. 그 PID 표는 전 시간에 나타내었습니다. 아래 링크.
2012/10/04 - [Protocol] - USB.02
ACK는 0010B 이고 NAK는 1010이므로 디바이스의 상태에 따라 11010010B or 01011010B를 보내면 SET_ADDRESS에 관한
통신을 완료하게 됩니다. 이쪽저쪽 표 보느라고 정신없군요. ㅎㅎ 이렇게 표가 많은 걸 보니 프로그램에서 #DEFINE 이나
Structure, ENUM 등등을 잘 활용해야겠습니다.
이제야 Device의 주소 설정까지 달려왔네요. ㅎㅎ 하지만 아직 갈길이 멀죠. 그래도 이것 저것 신경쓰지 말자구요~ 머리만
아파요. ㅋㅋ 음.. 너무 이론만 하니까 정신이 없는 것 같아요. 그래서 다음 시간에는 실제로 이런 통신이 이루어지는지 확인을
해 보려고 합니다. MCU를 사용할 거구요. 사용할 MCU는 TI의 CC2540F256입니다. 원래 Bluetooth Low Energy 용도로 출시된
SOC이지만 USB도 내장되어 있습니다. 아래 사진의 오른쪽 상단 정사각형 IC가 CC2540입니다. 귀엽습니다. -_-+ 으흐흐
그럼 내일은 USB Device에 주소가 설정되는 모습을 볼 수 있겠군요. ^^ 으흐흐흐흐 기대됩니다. 으흐흐흫흐 으르흐흐
그럼 이만 전 미리 실습하러 갑니다.~ 내일봐여~ - Dwarp -
!!!!!추신!!!!!
-_-+ 저를 "보드팔이"라고 생각하시는 분들이 계실지 모르겠지만 저는 절대로 제품를 판매하거나 홍보할 목적이 없음을
분명하게 밝힙니다. 시작하는 글에도 말씀드렸다시피 다른 엔지니어 분들에게 조금이나마 도움이 되고자 블로그를 오픈한
것입니다. (그렇다고 무료로 드린다는 소리는 아닙니다. 회사 자산이므로 권한이 없습니다.)