./../
  I D :    암호 :    ID저장      회원가입    네게(쥔장) 쪽지보내기    메모장    각종계산기    컬러빠렛    이모티콘(프레임, 새창)    보유장비
목록으로 가기..
STM32H747I-DISCO CP2102 USB Host 트러블슈팅 종합 보고서 김종호 | 삭제하기

# STM32H747I-DISCO CP2102 USB Host 트러블슈팅 종합 보고서 본 문서는 STM32H747I-DISCO 보드의 USB OTG HS 포트(CN1)에서 CP2102 (USB to UART) 모듈이 정상적으로 인식되고 통신하기까지 발생했던 문제 원인들과 해결 과정, **그리고 실제로 수정된 핵심 코드**를 종합적으로 정리한 보고서입니다. --- ## 1. 하드웨어 핀 맵핑 문제 (ULPI 통신 오류) ### 🚨 문제 상황 및 원인 가장 처음 발생했던 문제는 USB 케이블을 꽂아도 아무런 반응이 없는 현상이었습니다. STM32H747I-DISCO 보드는 외장 PHY 칩(USB3320C)을 사용하며, MCU와 PHY 간에는 고속 통신을 위해 12가닥의 ULPI 핀이 연결되어야 합니다. 하지만 코드 상에서 핵심 제어 핀인 `ULPI_DIR`과 `ULPI_NXT`가 잘못된 아날로그 핀으로 할당되어 통신이 단절된 상태였습니다. ### 💻 변경된 코드 (`CM7/USB_HOST/Target/usbh_conf.c`) 잘못 할당되었던 `PC2_C`, `PC3_C` 관련 코드를 완전히 제거하고, 회로도에 맞는 정확한 핀(`PI11`, `PH4`)을 설정하도록 수정했습니다. ```c // [수정 후: 올바른 ULPI 제어 핀 초기화 코드] void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hhcd->Instance==USB_OTG_HS) { /* 외장 PHY를 위한 클럭 활성화 */ __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); __HAL_RCC_GPIOI_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); // (데이터 핀 PB0, PB1 등 설정 생략...) /* PI11: ULPI_DIR 핀 설정 */ GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); /* PH4: ULPI_NXT 핀 설정 */ GPIO_InitStruct.Pin = GPIO_PIN_4; HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); } } ``` --- ## 2. VBUS 전원 공급 문제 (장치 활성화 불가) ### 🚨 문제 상황 및 원인 핀을 고친 후에도 장치가 깨어나지 않았습니다. CP2102는 Host가 5V(VBUS)를 제공해야만 동작하는 버스 파워 기기입니다. 외장 PHY 칩(USB3320C)이 전원 스위치(STMPS2151)를 열어 5V를 공급하게 하려면, STM32가 PHY 칩에게 명시적으로 "VBUS 전원 인가" 명령을 내려야 합니다. ### 💻 변경된 코드 (`CM7/USB_HOST/Target/usbh_conf.c`) `USB_DriveVbus` 함수가 정상적으로 VBUS를 인가하도록 로직을 복구했습니다. ```c // [수정 후: VBUS 구동 코드 복구] void USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, uint8_t state) { /* state 값이 1이면 PHY 칩을 통해 VBUS 전원을 인가함 */ if (phost->id == HOST_HS) { if (state == 0) { USB_DriveVbus(USB_OTG_HS, 0); // VBUS Off } else { USB_DriveVbus(USB_OTG_HS, 1); // VBUS On (이 명령이 누락되어 있었음) } } HAL_Delay(200); // 전원 안정화 대기 } ``` --- ## 3. 소프트웨어 클래스 불일치 (Enumeration 중단) ### 🚨 문제 상황 및 원인 하드웨어가 정상적으로 VBUS를 공급하여 장치를 감지(`Device Attached`)했음에도 불구하고 상태가 멈췄습니다. 이유는 STM32 USB Host 라이브러리에 **표준 CDC 드라이버**가 등록되어 있었기 때문입니다. CP2102는 표준 장치가 아닌 **벤더 전용(Vendor Specific, Class `0xFF`)** 장치이므로 기존 드라이버로는 인식되지 않습니다. ### 💻 변경된 코드 (`CM7/USB_HOST/App/usb_host.c`) 기존의 `USBH_CDC_CLASS`를 지우고, 사용자가 만든 커스텀 드라이버인 `CP210x_Class`를 등록하도록 헤더와 함수를 수정했습니다. ```c // [수정 후: 커스텀 클래스 등록] /* USER CODE BEGIN Includes */ #include "usbh_cp210x.h" // 커스텀 드라이버 헤더 추가 /* USER CODE END Includes */ void MX_USB_HOST_Init(void) { if (USBH_Init(&hUsbHostHS, USBH_UserProcess, HOST_HS) != USBH_OK) { Error_Handler(); } // 기존: if (USBH_RegisterClass(&hUsbHostHS, USBH_CDC_CLASS) != USBH_OK) // 수정: CP2102 전용 커스텀 클래스를 등록하여 벤더 특정 장치를 인식하게 함 if (USBH_RegisterClass(&hUsbHostHS, &CP210x_Class) != USBH_OK) { Error_Handler(); } } ``` --- ## 4. 커스텀 드라이버 기능 구현 (Baudrate / 통신) ### 🚨 문제 상황 및 원인 드라이버가 매칭되긴 했으나 기존 `usbh_cp210x.c`는 내부 구현이 없는 빈 껍데기(Template)였습니다. CP2102는 단순 데이터 입출력 외에도, 초기 연결 시 **전용 제어 명령(Control Request)**을 보내 Baudrate 등을 설정해주지 않으면 통신할 수 없습니다. ### 💻 변경된 코드 (`CM7/Core/Src/usbh_cp210x.c`) CP2102의 초기화, 파이프 할당, 통신 속도 설정(115200 bps), 8N1 라인 세팅을 처리하는 상태 머신과 데이터를 보내는 함수를 새롭게 구현했습니다. ```c // [수정 후: 실제 CP2102 제어 로직 구현 발췌] static USBH_StatusTypeDef Requests(USBH_HandleTypeDef *phost) { CP210x_HandleTypeDef *CP210x = (CP210x_HandleTypeDef *)phost->pActiveClass->pData; USBH_StatusTypeDef status = USBH_BUSY; switch (CP210x->state) { case CP210X_INIT_IFC_ENABLE: // CP2102 통신 인터페이스 활성화 명령 if (CP210x_CtlReq(phost, 0x00, 0x01, 0, NULL, 0) == USBH_OK) { CP210x->state = CP210X_INIT_SET_BAUD; } break; case CP210X_INIT_SET_BAUD: // Baudrate 설정: 115200 bps (분주비: 3686400 / 115200 = 32) if (CP210x_CtlReq(phost, 0x01, 32, 0, NULL, 0) == USBH_OK) { CP210x->state = CP210X_INIT_SET_LINE; } break; case CP210X_INIT_SET_LINE: // Line Control 설정: 8 데이터 비트, 1 스톱 비트, 패리티 없음 (0x0800) if (CP210x_CtlReq(phost, 0x03, 0x0800, 0, NULL, 0) == USBH_OK) { CP210x->state = CP210X_INIT_DONE; } break; case CP210X_INIT_DONE: status = USBH_OK; // 초기화 완료, 이제 데이터 송수신 가능 상태로 진입 break; } return status; } // 사용자 호출용 송신 함수 USBH_StatusTypeDef USBH_CP210x_Transmit(USBH_HandleTypeDef *phost, uint8_t *pbuff, uint16_t length) { CP210x_HandleTypeDef *CP210x = (CP210x_HandleTypeDef *)phost->pActiveClass->pData; if (phost->gState != HOST_CLASS || phost->device.is_disconnected) return USBH_FAIL; // 파이프(채널)가 비어있을 때만 Bulk Out 엔드포인트로 데이터 전송 if (USBH_LL_GetURBState(phost, CP210x->OutPipe) == USBH_URB_IDLE || USBH_LL_GetURBState(phost, CP210x->OutPipe) == USBH_URB_DONE) { USBH_BulkSendData(phost, pbuff, length, CP210x->OutPipe, 1); return USBH_OK; } return USBH_BUSY; } ``` --- ## 5. FreeRTOS 유저 태스크 송신 적용 ### 🚨 문제 상황 및 원인 드라이버가 완성된 후, 사용자께서는 TouchGFX 등 다른 시스템을 멈추지 않으면서 FreeRTOS 태스크 안에서 1초마다 `HAL_GetTick()`의 값을 CP2102를 통해 송신하기를 원하셨습니다. ### 💻 변경된 코드 (`CM7/Core/Src/main.c`) 메인 루프의 `myTaskFunc01` 태스크를 수정하여, 새로 만든 `USBH_CP210x_Transmit` 함수를 통해 `cnt` 값을 포맷팅하여 비동기로 전송하도록 구현했습니다. ```c // [수정 후: 1초마다 카운트 송신] void myTaskFunc01(void *argument) { uint32_t cnt = 0; Axis_t rxBuffer; osStatus_t status; char txBuffer[64]; // 송신 데이터를 담을 버퍼 /* Infinite loop */ for (;;) { cnt = HAL_GetTick(); // 현재 시스템 틱(ms) 가져오기 // USB 호스트 핸들러를 외부 참조하여 전송 함수 호출 extern USBH_HandleTypeDef hUsbHostHS; int len = snprintf(txBuffer, sizeof(txBuffer), "Tick: %lu\r\n", cnt); // 1초마다 CP2102로 데이터 쏘기 USBH_CP210x_Transmit(&hUsbHostHS, (uint8_t *)txBuffer, len); // osWaitForever 대신 1000ms 타임아웃을 주어, 메시지가 없더라도 1초마다 루프가 순환되도록 변경 status = osMessageQueueGet(myQueueAxisHandle, &rxBuffer, NULL, 1000); if (status == osOK) { printf("axis=%ld,%ld,%ld,%ld,%ld,%ld\r\n", rxBuffer.axis1,rxBuffer.axis2,rxBuffer.axis3, rxBuffer.axis4,rxBuffer.axis5,rxBuffer.axis6); } } } ``` --- ## 6. UI 스레드 기아 상태 (터치스크린 먹통 해결) ### 🚨 문제 상황 및 원인 마지막으로 통신 성공 직후, 화면의 GUI 터치가 먹통이 되는 현상이 발생했습니다. 이는 디버깅을 위해 설정한 `USBH_DEBUG_LEVEL 3` 옵션 때문이었습니다. USB 상태 로그가 느린 UART `printf`를 통해 동기적(Blocking)으로 쏟아지면서 USB 백그라운드 태스크가 자원을 독점, 결국 **TouchGFX 태스크가 CPU를 받지 못하는 기아 현상(Starvation)**이 발생했습니다. ### 💻 변경된 코드 (`CM7/USB_HOST/Target/usbh_conf.h`) 디버그 레벨을 0으로 되돌려 로그 출력을 차단함으로써 TouchGFX 프로세스가 제 속도를 낼 수 있도록 복원했습니다. ```c // [수정 후: 디버깅 로그 비활성화] /*---------- -----------*/ #define USBH_DEBUG_LEVEL 0U // 기존 3U에서 0U로 복구하여 시스템 멈춤 해결 /*---------- -----------*/ ``` --- ## 요약 이번 이슈는 하드웨어 핀 맵핑(ULPI) 오류, VBUS 전원 인가 명령 누락, Vendor-Specific 디바이스용 클래스 등록 부재, 전용 Control Request 프로토콜 부재, OS 태스크 Starvation이라는 여러 층위의 문제가 복합적으로 얽혀 있었습니다. 이들을 물리계층부터 애플리케이션 계층까지 하나씩 차근차근 해결해 나감으로써 완벽한 CP2102 USB Host 제어 시스템을 구축할 수 있었습니다.

첨언 달기
이름 : 암호 :
번호    제목...(첨언) 작성일 접속
xxx [공지]자유겔러리 등록 오류 수정 완료 2017-12-22 685432
xxx [공지]자료실 다운로드 오류 처리 2017-12-01 31350
xxx [공지]비난, 광고 게시물을 신고, 차단, 삭제됩니다. 2005-06-26 27037
261 [M D]  Windows 10 Home을 Windows 10 Pro로 업그레이드하는 방법 2026-10-22(목) 20
260 [C#]  시뮬레이터용 동역학 패킷 C# 2026-10-21(수) 22
259 [CPP]  시뮬레이터용 동역학 패킷 C/C++ 2026-10-21(수) 22
258 [M D]  VS Code 4대 AI 바이브코딩 명령어(`/`) & 맥락 호출(`@`) 완벽 통합 가이드 2026-10-20(화) 20
257 [일반]  VS Code에서 Google AI 사용할때 자동 agree 2026-10-02(금) 86
256 [C#]  asp.net .net core connectionString Encryption 표준 암호화 방법 2026-09-24(목) 82
255 [CPP]  MS Windows 64bit Time Converter 2026-09-23(수) 109
254 [M D]  STM32H747I-DISCO 이더넷(RMII) 및 LwIP 완벽 구현 및 트러블슈팅 가이드 2026-09-17(목) 131
253 [일반]  .net core Web 생성하면 나오는 구조 2026-09-12(토) 100
252 [M D]  STM32 개발 때 다양한 USB CDCs 사용CDC, CP210x, FTDI, CH34x, PL2303) 2026-09-11(금) 114
251 [M D] > STM32H747I-DISCO CP2102 USB Host 트러블슈팅 종합 보고서 < 2026-09-11(금) 89
250 [일반]  STM32H747I-DISCO에서 STM32CubeMX 템플릿때문에 USB OTG 문제 발생할때 2026-09-10(목) 135
249 [M D]  TouchGFX에서 버튼같은거 삭제 했을때 make: *** No rule to make target.. 오류 2026-08-20(목) 159
248 [M D]  STM TouchGFX설계할때 main에서 View에 접근하는 순서 2026-08-16(일) 133
247 [M D]  STM TouchGFX설계할때 View가 main에 접근하는 순서 2026-08-16(일) 181
246 [M D]  MCU Task관리할때 필요한 세마포어(Semaphore)와 뮤텍스(Mutex) 2026-08-09(일) 174
245 [M D]  STM32F 마이컴 공부할때 RAM에 올려서 시험하기.(속도 빠름) 2026-08-08(토) 181
244 [일반]  STM32F767과 FreeRTOS를 이용해 설계할때 Time base Source는? 2026-08-08(토) 170
243 [일반]  VSCode로 STM32 개발할때 printf에서 실수 출력 안되면 2026-07-16(목) 1030
242 [일반]  VisualStudio으로 만든 프로그램 .net 버전 올리기 위해 2026-07-02(목) 1261
검색 :
Page : 이전 1  2  3  4  5  6  7  8  9  10  11  12  13  다음




Copyright 2003-2026 ⓒ 김종호. All rights reserved. kimjongho.co.kr kimjongho.kr kimjongho.net kimjongho.com