아트메가/ATMEGA32U4 Breakout

ATMEGA32U4 breakout-보드 사용하기 3편(USB CDC)

원원 2024. 3. 30. 22:03

안녕하세요. 오늘은 기존의 프로젝트에 USB CDC를 추가해보겠습니다.

CDC는 Communication Device Class를 의미합니다. UART통신과처럼 시리얼포트가 잡히고 터미널프로그램을 이용해서 데이터를 송수신합니다. USB CDC를 사용하면 UART JIG를 사용하지않아도 되므로 편리합니다.
ATMEGA32u4 breakout보드는 USB커넥터에 D+, D-가 연결되어 있습니다. 그리고 USB 2.0을 지원합니다.


*일반적인 USB CDC 통신 순서
1. USB ENABLE 및 기본 세팅
2. Endpoint 데이터 송수신코드 작성
3. HOST에 연결했을때 셋업EP에 응답하는 표준 디스크립터 작성
4. 셋업 EP로 오는 CDC CLASS에 관한 디스크립터 작성
5. 셋업 EP로 오는 디바이스 디스크립터 작성
6. 데이터EP로 오는 시리얼데이터 제어(반복)


*사용하는 USB관련 레지스터
1) UHWCON(USB Hardware Configuration)

0번비트-USB 패드 레귤레이터란 USB장치의 전원을 안정화시키고 전압을 제어하는 장치입니다.
1로 set합니다. (블럭다이어그램에보면 USB PAD REGULATOR가 있습니다.)


2) PLLCSR(PLL Control and Status Register)

4번비트-16MHz가 소스이므로 1로 set 합니다 

1번비트- PLL enable해야하므로 1로 합니다
0번비트- PLL가 LOCK인지 감시하는 레지스터입니다. PLL을 세팅하고 PLL lock인지 기다리기위해서 사용하면 됩니다
PLL lock가 1이면 주파수가 안정적인 상태를 의미합니다. while(!(PLLCSR & (1<<PLOCK)));

3)USBCON (USB Configuration)

7번비트-USB 이네이블이므로 1로 합니다
5번비트-USB클럭을 일시적으로 비활성화해서 소비전류를 줄이려는 옵션인데 사용안하므로 0으로합니다
4번비트-USB장치와 호스트간에 전원을 공급하는 설정인데 전원을 공급받을것이므로 1로 합니다
0번비트-VBUS 신호에따라서 인터럽트가 발생하는건데 사용안할것이므로 0으로합니다

4)UDCON(USB DEVICE CONTROL)

3번비트- ?
2번비트-FS로 사용할것이므로 0으로 합니다
1번비트-? (0으로 set합니다)
0번비트-호스트와 분리할때 사용하는데 0으로 합니다

5)UDIEN(USB Device interface Enable Register)

3번비트트, 2번비트를 1로 set합니다
3번비트-USB리셋이후에 인터럽트가 발생합니다.
2번비트-USB프레임의 시작을 감지할때마다 인터럽트가 발생합니다.

결론적으로 초기화하는 레지스터는 아래와 같습니다

// initialize USB serial
void usb_cdc_init(void)
{
    cli();
    UHWCON = (1<<UVREGE); // Enable USB Pads Regulator
    PLLCSR = (1<<PINDIV)|(1<<PLLE);	 // config PLL, 16 MHz xtal
    while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
    USBCON |= ((1<<USBE)|(1<<OTGPADE)); // start USB clock
    USBCON &= ~(1 << FRZCLK);          // Unfreeze the clock
    UDCON = 0;				// enable attach resistor
    UDIEN = (1<<EORSTE)|(1<<SOFE);
    sei();
}

해당 초기화하는 코드만 넣으면 아래와 같이 뜹니다. 장치관리자에서 USB 디바이스는 잡히긴하는데 알수없는 USB라고 뜹니다. 이후로는 어떤 디바이스인지 호스트에게 알려주는 코드가 들어가야 합니다 . 


이 외에도  알아야하는 내용이 많으므로 다음에 자세히 작성하겠습니다.

USB CDC 코드는 https://www.pjrc.com/teensy/usb_serial.html 사이트를 참고하여 작성하였습니다.
작성한코드에서 usb_cdc.h에있는 아래의 내용이 변하면 USB를 연결했을때 뜨는 디스크립터들이 변하게됩니다

#define VENDOR_ID	    	0x0000
#define PRODUCT_ID	    	0x0001
#define STR_INFO1           L"wowon"
#define STR_INFO2           L"tistory"
#define STR_INFO3           L"1203"


프로그램동작은 CH1 (UART), CH2(USB CDC)를 모두 출력하게 해놨습니다.

    while (1) 
    {
        if(uartAvailable(UART_CH1))
        {
            ledToggle(LED_CH1);
            uartPrintf(UART_CH1, "CH1 received : %c \n", uartRead(UART_CH1));
        }
                
        if(uartAvailable(UART_CH2))
        {
            ledToggle(LED_CH1);
            uartPrintf(UART_CH2, "CH2 received : %c \n", uartRead(UART_CH2));
        }
    }


소스코드(Commits: ADD USB CDC)
https://github.com/yhunterr/ATMEGA32u4/commits/main/