HomeMade

Pełna wersja: STM32 USB/CDC
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Stron: 1 2
Tak, szkielet robiłem z forbot. Od czegoś trzeba zacząć ;-)
A wracając do tematu to pętla ta zwraca cały czas:

3 0 4

bez względu na stan otwarcia portu.
Witam,

Z braku Discovery F4 zrobiłem test na discovery F429.
Ma on 2 porty USB - HS oraz FS. Port FS jest zajęty przez jakieś peryferium na PCB, ale dostępny jest port HS, który jest wyprowadzony na złącze mikroUSB - dla użytkownika.
W związku, że użyłem portu USB HS, a nie FS jak u Ciebie, nazwa struktury jest hUsbDeviceHS a nie hUsbDeviceFS oraz funkcja wysyłająca przez USB to CDC_Transmit_HS a nie CDC_Transmit_FS.


Konfiguracja wygenerowana najnowszym stm32CubeMX.

Nie zauważyłem żadnych problemów, na które Ty napotkałeś.

Kod testowy:
Kod:
char bufor[128];
uint8_t licznik, rozmiar;

  while (1)
  {

      sprintf(bufor, " id: %u \r\n dev_state:  %u \r\n ep0_state:  %lu \r\n dev_address: %u ",
        hUsbDeviceHS.id, hUsbDeviceHS.dev_state, hUsbDeviceHS.ep0_state, hUsbDeviceHS.dev_address);

      ILI9341_Print_String(0, 0,RED, bufor);


      if (hUsbDeviceHS.dev_state == USBD_STATE_CONFIGURED)
      {

          ILI9341_Print_String(0, 80, BLUE, " USB PODPIETE !!");

      } else
      {

         ILI9341_Print_String(0, 80, BLUE, " USB NIEAKTYWNE !!!");
      }
      

      rozmiar = sprintf(bufor, " Wiadomosc numer: %u   \r\n", licznik);

      CDC_Transmit_HS(bufor, rozmiar);
      ILI9341_Print_String(0, 100, GREEN, bufor);
      licznik++;

  }

A tu jest link do filmiku prezentujący prawidłową pracę, bez względu, czy USB jest podpięte czy odpięte.

Program nie zatrzymuje się na CDC_Transmit_HS(bufor, rozmiar) , gdy USB jest odpięte/nieaktywne. W takim wypadku sprawdzanie, czy port na komputerze jest otwarty/zamknięty nie jest potrzebne.

I widok konsoli terminala:
[attachment=12603]
Oczywiście, że u Ciebie program się nie zatrzymuje na CDC_Transmit_HS(bufor, rozmiar),
bo nie masz tego obudowanego pętlą while tak jak ja:
while (CDC_Transmit_FS(" ug/m3\n", 7) != USBD_OK);

A spróbuj jeszcze wobec tego dać kilka razy jeden pod drugim:

CDC_Transmit_HS(bufor, rozmiar);
CDC_Transmit_HS(bufor, rozmiar);
CDC_Transmit_HS(bufor, rozmiar);
CDC_Transmit_HS(bufor, rozmiar);

czy coś Ci nie ginie po drodze.
Witam,

Prawdę mówiąc zapomniałem o tym, że wysyłanie masz obudowane przez while....

Tak ginie, ale widzę że to normalne, bo poprzedni bufor nie został wysłany, a przy następnym jest status USBD_BUSY, więc zostaje porzucony.

Najprościej chyba będzie łączyć dane w jednym buforze i wysyłać całość lub dodać do tej pętli oczekującej mały licznik timeout.

Można również napisać małą funkcję z buforem cyklicznym, jak stosuje się przy normalnym UART

Nie wiem co chcesz docelowo osiągnąć, i dlaczego akurat takie rozwiązanie .
Dla mnie też jest to pierwsze starcie z obsługą USB w mikrokontrolerze...

Przeglądając czeluści internetu związane z stm32 usb i cdc doszedłem do wniosku, że można chyba odpytać sterownik w komputerze o stan portu z poziomu stm-a. Ale nie mam pomysłu jak tego dokonać.
No ja wiem, że są różne sposoby, aby wyjść z tego, ale głównym motywem było to, że po co
zabierać się za wysyłanie czegokolwiek na CDC skoro port jest zamknięty.
Czysta strata czasu.
Ale nawet zakładając, że port będzie cały czas otwarty to wystarczy ruszyć kablem od USB
co się często przytrafia, aby na chwilę połączenie zginęło i pojawia się nowy uchwyt do urządzenia
i całą transmisję wysyłamy w próżnię o ile nie mamy jakiejś zaawansowanej logiki do tego (ramki, ack itp...).

A inna sprawa, że Ty w swoim programie wykrywasz tylko fakt wpięcia kabla USB,
ale nie masz informacji, czy port jest otwarty po stronie PC. Tak to u mnie też działa.
Witam,

Przypomniało mi się, że interfejs cdc był opisany odrobinę w gazecie EP 3/2016 jako dodatkowa wkładka.
Tu jest artykuł z tej wkładki.

Wynikało by z tego, że trzeba w pliku usbd_cdc_if.c dopisać kod w funkcji CDC_Control_HS (uint8_t cmd, uint8_t* pbuf, uint16_t length). Funkcja ta jest wywoływana w przypadku zmiany ustawień portu VCOM. Jest tam tylko switch z obsługą pustych komend.

Ten link powinien być również pomocny. Jest przedstawiona obsługa bitrate przez w/w funkcję CDC_Control_HS (uint8_t cmd, uint8_t* pbuf, uint16_t length). Na podstawie takich danych, jest już chyba możliwość wykrywania otwarcia/zamknięcia portu. Tak mi się wydaje przynajmniej. Trzeba sprawdzić...

Po Testach

W funkcji CDC_Control_HS (uint8_t cmd, uint8_t* pbuf, uint16_t length)w poszczególnych segmentach obsługi komend podpiąłem wyświetlanie na LCD. Działa...

Ustawiany baudrate w programie terminalowym ładnie przekazywany jest przez w/w funkcję na LCD.
Zmiana stanu linii DTR/RTS, wysyłanie sygnału BREAK powoduje odpowiednią reakcję na LCD.

Można więc chyba zrobić detekcję stanu portu w komputerze...
No to ja podam gotowe rozwiązanie Rolleyes
Nie jest ono takie trywialne, bo trochę czasu na to zmarnowałem, ale działa tak, jak powinno. U mnie na STM32F103C8, ale proszę o potwierdzenie, czy u Was też.

Zmiany trzeba zrobić w dwóch plikach HAL dla USB - tych generowanych automatycznie przez CubeMX - oczywiście zmiany wprowadzamy tylko w sekcjach "USER...", a więc pozostaną nawet po zmianie konfiguracji sprzętu.

Zmienione pliki dostępne są TUTAJ (nie działa dodawanie pliku przy odpowiedzi na sp-hm), a poniżej lista numerów linii, które zostały dodane:

usbd_cdc_if.c:
107-108, 135-138, 166, 235, 239-246, 250

usbd_cdc_if.h:
118

Po takich zmianach wystarczy użyć funkcji "USBD_CDC_IsPortOpen()".
Zwróci ona 0 jeśli wystąpiło którekolwiek ze zdarzeń:
- nie włożono wtyczki USB do PC;
- włożono wtyczkę USB, ale nie otwarto portu;
- włożono wtyczkę USB, otwarto port, a następnie wyciągnięto wtyczkę (zerwane połączenie);
- zamknięto wcześniej otwarty port;
Funkcja zwróci 1 tylko jeśli mamy prawidłowe połączenie i port jest otwarty.

Całość rozpracowywałem mając włączony USB w przykładowym projekcie oraz jednocześnie robiąc "debug" na konsoli podpiętej po BT na USART2.
Próbowałem wszelkich (tak mi się wydaje) kombinacji z otwieraniem/zamykaniem portu i wkładaniem/wyciąganiem wtyczki USB, więc powinno być OK.
Jeśli ktoś zauważy problem, to proszę o raport Smile

Pozdrawiam,
Rafał SP3GO
Stron: 1 2
Przekierowanie