'AVR'에 해당되는 글 6건

  1. 2014.10.22 AVR Serial/HID의 간단한 설명.
  2. 2014.10.21 AVR Serial HID 구현.
  3. 2014.10.20 USB CDC는 막힌 듯?
  4. 2014.10.17 USBTiny 실험.
  5. 2014.10.14 avr-gcc 4.9.2
  6. 2014.10.09 USBTinyISP 만들기.
2014.10.22 11:31

AVR Serial/HID의 간단한 설명.

 HID장치를 간단하게 시리얼 통신처럼 이용할 수 있는 방법은 CDC ACM 방법이 운영체제가 막아서 생기는 문제는 해결할 수 있다. 이 방법이 꼭 장점이 강한 것은 아니지만, 간단한 테스트를 위한 하드웨어에서의 응용은 나쁘지 않을거라고 생각된다.


 기본적으로 HID의 사용되는 프로그래밍 방법은 같고 단지 주의할 점만 존재한다. 호스트 컴퓨터에서 장치로 USB통해 정보는 받는 부분에 control전송과 인터럽트 전송을 모두 거치는 usbFunctionWriteOut을 쓰는데, 이것은 별로 문제가 되지 않는다. 단지 가끔 NULL데이터를 보내므로 펌웨어에서 체크를 하면 된다. 그리고 데이터의 길이가 버퍼의 길이와 맞추는 작업도 필요하다. 이것은 각각의 구현에 따른 변경이 다르므로 다른 게시물에 업로드한 소스를 확인하면 대충 이해하기 쉽다.


 가장 크게 주의할 점은 바로 HID 레포트 정보의 선언으로 장치에서 호스트 컴퓨터로 보내는 크기는 8바이트가 되어야 한다. 그렇지 않으면 데이터가 전혀 전송이 되지 않는다. 호스트 컴퓨터에서 장치로 전송되는 크기는 크게 문제가 없지만 64이하로 만들어주는 것이 좋다.


PROGMEM const char usbHidReportDescriptor[] = {
  0x06, 0xa0, 0xff, // USAGE_PAGE (Vendor Defined Page 1)
  0x09, 0x01,       // USAGE (Vendor Usage 1)
  0xa1, 0x01,       // COLLECTION (Application)

  // Input Report
  0x09, 0x02,       // Usage ID - vendor defined
  0x15, 0x00,       // Logical Minimum (0)
  0x26, 0xFF, 0x00, // Logical Maximum (255)
  0x75, 0x08,       // Report Size (8 bits)
  0x95, 0x08,       // Report Count (8 fields), must be 8
  0x81, 0x02,       // Input (Data, Variable, Absolute)

  // Output report
  0x09, 0x03,       // Usage ID - vendor defined
  0x15, 0x00,       // Logical Minimum (0)
  0x26, 0xFF, 0x00, // Logical Maximum (255)
  0x75, 0x08,       // Report Size (8 bits)
  0x95, 0x16,       // Report Count (16 fields)
  0x91, 0x02,       // Output (Data, Variable, Absolute)

  0xc0              // END_COLLECTION
};


 기본적인 레포트의 선언은 위와 같은데, 항상 명칭은 호스트 컴퓨터를 중심으로 표현된다. Input는 장치에서 컴퓨터로 보내는 것으로 Report Size와 Report Count는 반드시 8바이트가 되어야 한다. 하드웨어 지원이 된다면 이런 제한이 없다고 하는데 하드웨어 USB 지원이 안되는 AVR은 저속 장치로 인식되는 탓에 어쩔 수 없다.


 Output 레포트의 크기는 변화를 줘도 아무런 문제가 없다.


 레포트 선언은 이렇게 간단하고, v-usb의 선언에서 데이터 전송을 위한 부분을 처리하도록 작성하는데 몇개의 함수만 만들어주면 간단히 끝난다.


usbMsgLen_t usbFunctionSetup(uchar data[8])
{
    return 0;
}

uchar usbFunctionRead(uchar *data, uchar len)
{
    return 0;
}

void usbFunctionWriteOut(uchar *data, uchar len)
{
uchar i,c;
    if(len>0) {
        if( (*data==0x0d) || (*data==0x0a) )
            return;
        if(len>HIDSERIAL_INBUFFER_SIZE) len=HIDSERIAL_INBUFFER_SIZE;
        i=0;
        while(i<len) {
            c=data[i];
            inBuffer[i]=c;
            i++;
            if(c==0) break;
        }
        received=1;
        recv_len=i;
    }
}


 usbFunctionSetup은 컴퓨터에 장치의 정보들을 설정하고 주고 받거나 컨트롤 전송을 위해 쓰이는데, 이 구현에서는 따로 크게 코딩할 부분이 없다.


 usbFunctionRead는 장치로 데이터를 보내는 방법을 위한 것으로 마찬가지로 컨트롤 전송을 위한 것으로 인터럽트 전송을 하는 이 방법에서는 쓸모가 없다.


 usbFunctionWriteOut은 호스트 컴퓨터에서 장치로 보내는 데이터를 처리할 때 쓰이는데, 이곳에서 장치의 버퍼에 데이터를 저장하면 된다. 설명에는 컨트롤 전송도 이 함수를 통해 데이터를 받을 수 있다고 되어 있다. 데이터가 다 전송되었다는 것을 확인할 방법을 구현하는게 좋다.


int main(void)
{
    odDebugInit();
    hardwareInit();
    usbInit();

    sei();
    for(;;){    /* main event loop */
        wdt_reset();
        usbPoll();

        if( usbInterruptIsReady() && (received != 0) )
          Translate_buffer(inBuffer);

...

    if(iwptr>0) {
        rx_buf[iwptr]=0;
        usbSetInterrupt(rx_buf,8);
        if(iwptr>8) {
            while(!usbInterruptIsReady()) {
                wdt_reset();
                usbPoll();
            }
            usbSetInterrupt(rx_buf+8,8);
        }
        iwptr=0;
    }

    }
...

    return 0;
}


 이렇게 간단히 선언하고 위와 같이 usbPoll()과 usbInterruptIsReady() 함수로 계속 상태를 확인하고 데이터의 전송에는 usbSetInterrupt(data, 8)과 같이 사용하면 된다. 8로 고정된 이유는 이미 설명했다. 만약 데이터가 길다면 usbPoll()과 usbInterruptIsReady()로 상태를 체크한 후에 usbSetInterrupt(...,8)로 다시 보내주면 된다. 8바이트씩 보내는 것이라 계속 보내준다면 크게 길이의 제한은 없다고 생각된다.


그리고 usbconfig.h의 내용들은 대충 이렇다.

...

#define USB_CFG_HAVE_INTRIN_ENDPOINT    1

#define USB_CFG_HAVE_INTROUT_ENDPOINT   1 

#define USB_CFG_IMPLEMENT_FN_WRITEOUT   1

...

#define USB_CFG_INTERFACE_CLASS     3       /* HID class */
#define USB_CFG_INTERFACE_SUBCLASS  0     
#define USB_CFG_INTERFACE_PROTOCOL  0    

...

#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    34

...



 특별한 것은 없는 방법론이기 때문에 그냥 따라하면 끝이다. 탐구를 하고 싶다면 삽질을 해봐도 좋을 일이다. =_=;



cdcio.2009-07-15-serhid-4313.zip


추가적인 비트 쓰기/읽기 기능의 추가.

portb.7 portb.1 [  읽기 msb, 첫번째는 데이터, 두번째는 클럭.

portb.0 portb.3 ]  읽기 lsb,

ff portb.1 portb.0 > 쓰기 lsb

ff portb.2. portb1 / 쓰기 msb ( 터미널 오류로 다른 문자를 사용 )



cdcio.2009-07-15-serhid-addfuncs1.zip


'하드웨어' 카테고리의 다른 글

12F675를 이용한 ADC를 가져오기.  (0) 2014.11.21
간단한 승압 회로.  (0) 2014.10.29
AVR Serial/HID의 간단한 설명.  (0) 2014.10.22
AVR Serial HID 구현.  (0) 2014.10.21
USB CDC는 막힌 듯?  (0) 2014.10.20
USBTiny 실험.  (0) 2014.10.17
Trackback 0 Comment 0
2014.10.21 23:28

AVR Serial HID 구현.

AVR의 소프트웨어 CDC는 운영체제에서 저속이기 때문에 장치의 연결을 끊는 것으로 확인. 그래서 cdc-io를 포기하려 했으나 YAT란 터미널 프로그램에 Serial HID라는 기능이 존재. 구현을 아무리 찾아봐도 없고 결국 삽질을 해가며 직접 구현.


 입으로 설명하기엔 너무 많이 모르기 때문에 곤란하고 완성된 소스를 첨부. 이 소스에는 V-USB에서 인터럽트 OUT이 가능한 수정이 담겨있다. 이 수정이 약간 틀려서 교정을 봤다.

 예제 4번만 수정되어 있고 출처는 http://lackawanna.hackhut.com/2011/10/06/using-v-usb-and-the-hid-class-part-iiiiii/


avr-all_examples-serhid.zip


 USB HID의 레포트를 만드는게 어렵다면 그냥 복사해서 사용하면 된다. 설정시 압축파일에 들어있는 usbconfig의 내용도 중요하다. YAT로 입력받은 문자를 16진수로 변환해서 다시 보여주는 예제. YAT를 실행에는 관리자 권한이 필요하다. 그냥 띄우면 HID가 장치가 목록에 안보인다.


 중요한 것은 cdc-io를 이 기능에 맞게 다시 변환하는 것. 그리고 2313A의 용량 증설판인 ATtiny4313을 사용해서 기능을 확장. 4096워드를 사용하니 정말 편하다. 백번 정도 굽고 지우고를 반복했는데 고장이 안났다. 그리고 한번은 전원을 거꾸로 연결했는데 열이 펄펄 =_=; 다시 제대로 연결하니 생생했다. PIC는 바로 고장나던데;


 그렇게 CDC-IO의 2313용의 펌웨어 소스에 많은 수정을 가해서 비트 단위나 몇몇 기능의 확장을 꾀했다.

 둘다 GPL이라 =ㅅ=;



cdcio.2009-07-15-serhid-portfix.zip

 (4313의 구현에서 포트 이름의 레지스터 부분이 잘못되어서 수정.)

 결과물은 이렇다.



 명령의 입력은 "<16진 데이터> <공백> <레지스터명 혹은 16진수> <공백> <명령>" 이런 식이다.

 ?는 값을 알아보고(비트 가능), =는 값을 대입하고(비트 가능), &는 AND연산, ^는 XOR 연산, |는 OR연산. 논리 연산은 비트를 구현하지 않았다. @만 입력하면 "cdc-io"문자열이 표시된다.


 또하나의 삽질 끝. 노하우 하나 획득.



'하드웨어' 카테고리의 다른 글

간단한 승압 회로.  (0) 2014.10.29
AVR Serial/HID의 간단한 설명.  (0) 2014.10.22
AVR Serial HID 구현.  (0) 2014.10.21
USB CDC는 막힌 듯?  (0) 2014.10.20
USBTiny 실험.  (0) 2014.10.17
avr-gcc 4.9.2  (0) 2014.10.14
Trackback 0 Comment 0
2014.10.20 08:37

USB CDC는 막힌 듯?

 USB 구현에 CDC라는게 있는데 통신장치 구현에 사용되는 표준으로 USB의 장치에 기입되는 정보는 바탕으로 ACM으로 모뎀처럼 사용할 수 있는게 있었는데, 최신의 운영체제에서는 막힌 것 같다. 윈도우즈의 경우에는 usbser.sys라는 표준 드라이버가 있는데 인식을 못하는 현상이 발생. 망했다.


 이 문제는 해결하는 가장 좋은 방법은 HID로 설정을 변경하는 것. 마우스나 키보드, 조이스틱이 구현이 가능하다. USBTinyISP 조차도 드라이버는 libusb를 통해서 사용을 하고 있다. USB-Serial의 경우도 대부분 CDC-ACM은 피하고 있는 것을 보니 안되나보다.


 좀 더 확인을 해보고 설정을 바꿔야 할 듯.


'하드웨어' 카테고리의 다른 글

AVR Serial/HID의 간단한 설명.  (0) 2014.10.22
AVR Serial HID 구현.  (0) 2014.10.21
USB CDC는 막힌 듯?  (0) 2014.10.20
USBTiny 실험.  (0) 2014.10.17
avr-gcc 4.9.2  (0) 2014.10.14
USBTinyISP 만들기.  (0) 2014.10.09
Trackback 0 Comment 0
2014.10.17 22:26

USBTiny 실험.

 ATTiny4313에 cdc-io라는 펌웨어를 2313용을 4313으로 확장해서 기능을 추가한 펌웨어를 실험삼아 구워봤다. cdc-io는 정리대는 대로 소스를 업로드할 예정. 대화형식으로 AVR의 기능을 접근하는 것인데 레지스터와 기능들(인터럽트등은 제외)을 활성화할 수 있다. 대부분의 레지스터의 접근이 가능. 주로 데이터 신호의 ON/OFF이니 복잡한 기능은 사용하지 않을 것이지만 문자 명령으로 조정할 수 있다는 뭔가 매력적인 부분이 있다.


 처음 시도에서는 칩을 프로그램하는데 몇몇 문제가 생겼다. 구워지기는 하는데 검증과정에서 어느 부분에 자꾸 오류가 생기는 것 그래서 새로 도착한 0.5W 제너로 교체하고 연결저항을 62(원래는 68)로 풀업을 1.5K로 다시 교체하니 정상적으로 동작. 브레드보드에 올려서 하느라 아마 접촉 불량이 문제가 되었던 듯 싶은데 그냥 무식하게 교환했다. 정말 되는지 궁금해서 =ㅅ=; 커넥터로 소켓을 올리고 끼워서 작업하니 아무런 문제가 없이 제대로 구워졌다.


 연결저항이 68인것은 갑자기 솟아오르는 신호가 넘치는 것을 방지하기 위한 것으로 어느 해외 블로그를 보니 68정도가 가장 피크 전압을 막을 수 있는 최적값이었다. 1.5K는 대기시 전류량을 위한 것으로 이는 USB규정에 따른 것. USB의 직접 연결부는 역시 68과 1.5K와 0.5W 3.6V제너(1N5227B를 구입)를 연결해줘야 정신건강에 이로운 것 같다.


 여튼 몇번을 칩을 프로그래밍하는 실험해보고 스샷을 만들었다.



 MCU 인식이나 퓨즈값 저장. 검증등. 기능상엔 아무런 문제가 없었고 편했다.


(추가) 이래저래 실험한 결과. USB인터페이스엔 큰 문제가 없었다. 쓰기오류가 발생한 원인은 쓰기를 하는 경우에 신호가 불안정해서 발생. Bit clock값을 32정도로 하면 안정적이다. 높은 수치일수록 느려진다. 32에선 쓰기는 30초 정도 읽기는 10초 정도가 소요. 만능기판에 날림 배선이라 신호간섭이 조금 있는 듯.


 USBTiny사이트에서 제공하는 소스는 오래되어서 최신의 컴파일러(4.7이상)로 다시 펌웨어를 만들 수 없다. 경고문구에 에러까지. 사소한 경고문에도 펌웨어는 제대로 동작하지 않았던 듯. 컴파일하지 않아도 미리 컴파일된 펌웨어가 포함되어 있다.


정식 배포판은 업데이트 기록에 1.3까지인데  https://github.com/jwatte/usbtiny 에서 받은 것은 1.6으로 되어 있다. 친절하게 USBTinyISP라는 폴더에 담겨있다. 4.9.2로 컴파일하면 always_line에 경고문이 뜨는데 간단히 뒤에 공백과 함께 inline이라고 넣어주기만 하면 된다. 인터럽트 핸들러등을 손을 봐서 펌웨어의 안정성이 향상된 것 같다.


usbtiny-master.zip


 USBTiny의 탐구는 이것으로 끝.


avrstudio 4.19의 프로젝트로 작업한 내용이 있는 압축파일.

usbtiny-master-1.6-4.9.2.zip


'하드웨어' 카테고리의 다른 글

AVR Serial HID 구현.  (0) 2014.10.21
USB CDC는 막힌 듯?  (0) 2014.10.20
USBTiny 실험.  (0) 2014.10.17
avr-gcc 4.9.2  (0) 2014.10.14
USBTinyISP 만들기.  (0) 2014.10.09
아두이노 전원 문제.  (0) 2014.09.27
Trackback 0 Comment 0
2014.10.14 14:53

avr-gcc 4.9.2

 우짜다보니 avr-gcc 까지 최신을 찾게 되었다. =_=; mikro 제품처럼 2k워드 제한은 avr쪽에서는 약간 답답한 면이 있을 듯 싶어 avr-studio 4.1x버전과 같이 찾아서 사용. 프로젝트 옵션에 보면 avr-gcc를 따로 선택할 수 있게 되어있다.


http://sourceforge.net/projects/mobilechessboar/files/avr-gcc%20snapshots%20%28Win32%29/


 4.8버전이하는 컴파일러 버그에 대한 이야기가 있고 avr-libc가 1.8.0이하여서 그냥 4.9.2로 선택. 펌웨어 크기로는 4.8버전이 더 작다는 비교도 있었지만 tiny2313과 4313의 버그가 없는 것은 avr-libc 1.8.1버전이라서 어쩔 수가 없는 것 같다.


 USB장난감들을 만들기 위한 작업으로 사용 예정. winavr등은 4.4.3인가 버전이 그렇고, 라이브러리는 1.7.1인 것으로 기억.


 cdc-io라는 것을 만들어본 후, 다른 구상을 해봐야겠다.


 스냅샷 파일엔 make.exe가 없다. 그냥 mingw에서 make를 찾아서 그냥 넣어주면 되니 걱정할 일은 아니다.


 부품이 도착하는대로 구워서 잘 되었으면 하는 바램. =ㅅ=;


 그리고 새로 찾은 avrdude의 gui 프론트엔드.


http://blog.zakkemble.co.uk/avrdudess-a-gui-for-avrdude/




'하드웨어' 카테고리의 다른 글

USB CDC는 막힌 듯?  (0) 2014.10.20
USBTiny 실험.  (0) 2014.10.17
avr-gcc 4.9.2  (0) 2014.10.14
USBTinyISP 만들기.  (0) 2014.10.09
아두이노 전원 문제.  (0) 2014.09.27
간단한 순차점등 LED회로.  (0) 2014.09.22
Trackback 0 Comment 0
2014.10.09 11:03

USBTinyISP 만들기.

 이런저런 내용을 뒤지다가 새로운 것을 발견. AVR을 프로그래밍하는 도구로 AVR로 만드는 것으로 저렴하고 몇몇 프로그램이 지원된다. 아두이노도 지원한다는 이야기를 읽은 것도 같다. 1.0.5에서 부트로더를 굽는데 사용한다는 이야기가 있었다. 여튼 새로움과 삽질의 시작이었다.


 홈페이지 : https://learn.adafruit.com/usbtinyisp/overview


 일단 부품은 간단한데, 2.0리버전은 ATTiny2313과 74AHC125의 칩셋, 그리고 부수적인 부품들이 필요했다. 이 회로의 장점은 ATTiny2313을 이용해서 따로 인터페이스가 없이 USB통신이 가능한 것으로 가격이 저렴한 편. ATTiny2313과 ATTiny2313A은 약간 다르다. 하지만 USBTinyISP는 부가적인 기능을 사용하지 않아서 다행히 둘의 구분은 무의미하다. 일단 2313A는 가격이 2313보다 착하다. 부품리스트는 partlist라는 메뉴를 누르면 확인할 수 있고 맨아래에는 회로도가 있다.


 그리고 ATTiny2313A는 미리 프로그램되어 있어야 한다. 처음 만드는 사람들은 어디선가 칩에 프로그램을 업로드해야만 한다는 난점이 있다. 하지만 이미 만들어놓은 OpenProg를 이용해서 간단하게 프로그램했다. 이미 프로그래밍할 수 있는 기기가 있는데 왜 다시 만드는지는 모르겠다 =ㅅ=; 펌웨어 파일은 2.0버전용을 다운로드하면 되고 안에 폴더에 ISP라는 폴더의 main.hex를 사용하면 된다. fuse값은 makefile에 있다. 혹시나 다시 컴파일하는 것은 삽질로 이어진다는 교훈을 얻음. 만들어진 펌웨어를 쓰는게 정신건강에 좋다.


http://learn.adafruit.com/system/assets/assets/000/010/327/original/usbtiny_v2.0_firm.zip


 지원되는 프로그램은 avrdude라는 것이 별로도 있다. 상위버전(5.5이상)의 avrdude는 usbtiny를 지원한다. 최신 버전은 6.1이다. 그리고 윈도우즈답게 드라이버가 필요하다. 32비트 드라이버와 64비트가 같이 있는 것을 다운로드하면 된다. 리눅스는 따로 드라이버를 설치할 필요가 없다.


 avrdude의 다운로드는 이곳. 정식 사이트는 접속시간 초과 에러가 =ㅅ=;

 http://mirrors.zerg.biz/nongnu/avrdude/


 준비와 조립에는 문제가 없었다. 하지만 이제부터가 문제의 삽질이 시작 =ㅅ=; 문제의 핵심은 V-USB이란 라이브러리를 통해 소프트웨어 USB를 지원하다보니 신호안정성의 문제가 있었던 것. 회로도의 6번과 7번의 접속은 민감한 부분으로 만약 이 부분이 틀려지면 USB인식은 커녕 LED가 들어오지도 않는다. 그렇게 인식은 되었는데 몇번 명령을 보내면 avrdude가 에러를 뺐어내면서 불만을 호소한다.


 이 6번과 7번핀은 3.6V 제너다이오드를 통해 전압이 제한되는데, 만약에 레귤레이터로 3.6정도의 전압으로 동작한다면 그냥 저항만 연결하면 되는 부분이지만, 5V로 동작시키려한다면 꼭 필요한 부분이다. 그냥 연결만 되면 다행인데 제너다이오드를 1W급으로 구입하는 바람에 문제가 발생. 제너다이오드의 소비전력이 커지면 캐패시던스도 증가해서 신호를 제대로 보내고 받을 수 없게 된다. 캐패시던스는 높은 클럭을 가지는 신호의 적이랄까 그렇게 몇몇 다른 V-USB구현 회로를 보니, 0.5W이하를 사용하도록 권장하고 되도록이면 0.25W급을 써라고 되어 있었다. 헉 =ㅅ=; 다른 응용 구현을 보니 0.5W급 조차도 많은 문제를 발생시키고 있었다.


 다시 구입할려고 찾는 0.25W급은 다 SMD이고 '이런 망했어'라고 생각하고 있었는데, USB키보드는 만든 글에 다른 사람들이 댓글이 달렸는데, 키보드가 자주 인식 불량인데 풀업 저항을 1.5K에서 470으로 바꾸니 잘 된다는 내용이 똭. 얼른 따라해보니 확실하게 된다. USB의 대기시 표준 전류량을 어기는 방법이지만 동작이 목적이니 그냥 사용하기로 했다. 그렇게 다행히도 USB로의 통신은 백발백중이 되었다.


 이제 프로그래밍이 되는지 확인만 하면 될 것 같다.




 이 구성의 단점은 리눅스에서는 주기적으로 삐삑하며 장치의 인식이 반복된다는 것. USB로 데이터가 이동되고 있는 경우엔 문제가 되지 않는 것으로 확인.




 명칭이 USBtinyISP인데 만능기판에서 만들어진 것이라서 Tiny하지는 않게되었다; 전원분리 점퍼를 포함시켜야 하는데 빼서 훨씬 간단해졌고, 1.5저항들을 많이 사용했는데, 비슷한 값을 만들기 위해서 2.7k나 100을 병렬로 연결해서 좀더 지저분하다. USB 헤더 가까운 쪽에 띠가 있는 것이 제너 다이오드. 커넥터도 10핀이 표준인데 그냥 있는 12핀 헤더를 연결.

'하드웨어' 카테고리의 다른 글

USBTiny 실험.  (0) 2014.10.17
avr-gcc 4.9.2  (0) 2014.10.14
USBTinyISP 만들기.  (0) 2014.10.09
아두이노 전원 문제.  (0) 2014.09.27
간단한 순차점등 LED회로.  (0) 2014.09.22
아두이노를 이용한 원격 리모트 컨트롤.  (0) 2014.09.22
Trackback 0 Comment 0