HomeMade
STM32 USB/CDC - Wersja do druku

+- HomeMade (http://sp-hm.pl)
+-- Dział: Oprogramowanie (/forum-84.html)
+--- Dział: Technika programowania mikroprocesorów (/forum-85.html)
+--- Wątek: STM32 USB/CDC (/thread-2995.html)

Strony: 1 2


STM32 USB/CDC - SP9RQA - 06-04-2017 21:14

Witam.

Może ktoś będzie wiedział jak rozwiązać pewien mały problem z obsługą USB.
Otóż na urządzenie szeregowe można wysłać string za pomocą funkcji:

Kod:
CDC_Transmit_FS(... , ...);
[/code]

i to działa, ale pod warunkiem, że takich operacji nie robię jedna za drugą,
czyli:

Kod:
CDC_Transmit_FS(... , ...);
CDC_Transmit_FS(... , ...);
CDC_Transmit_FS(... , ...);
wtedy wysyła mi się jedynie ta pierwsza. Nie jest to jakiś problem, bo można dać po każdej z nich:
HAL_Delay();

i już jest dobrze, choć mało elegancko.

Funkcja może zwracać 3 wartości OK, BUSY, FAIL które można wykorzystać
choćby w ten sposób:

Kod:
while (CDC_Transmit_FS(... , ...) != USBD_OK);

i to też działa, ale ... no właśnie, chodzi o to ale ;-)
Działa dopóki po stronie PC jest otwarty port. Z chwilą jego zamknięcia program stoi na tej linii programu. Oczywiście można zrobić jakiś timeout i po chwili zrezygnować z wysyłania, ale to też niepotrzebna strata czasu.
Jak wobec tego wykryć otwarcie/zamknięcie portu po stronie PC?

Jest to moje pierwsze starcie z STM32. Projekt jako taki wygenerowałem przy pomocy MXCube i tam jest inicjalizacja CDC zrobiona z automatu. Ona działa raczej poprawnie, bo przy otwartym porcie leci wszystko to co ma lecieć, kłopot pojawił się w momencie jak zamykam port wtedy program się zatrzymuje na najbliższym komunikacie, który ma lecieć po CDC.
Przeczesałem już sieć w poszukiwaniu rozwiązania i znalazłem coś takiego:

http://stackoverflow.com/questions/5338875/detecting-open-pc-com-port-from-usb-virtual-com-port-device

ale coś mi to nie chce zaskoczyć.
Wykopiowałem z tamtego przykładu fragment:

Kod:
if ((hUsbDevice_0->dev_state != USBD_STATE_CONFIGURED)

            || (hUsbDevice_0->ep0_state == USBD_EP0_STATUS_IN))

i włożyłem do swojego, gdzie stan portu staram się wyświetlić na LCD:

Kod:
if ((hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED)
                        || (hUsbDeviceFS.ep0_state == USBD_EP0_STATUS_IN))


                {
                  
                            LCD_SetLocation(&lcd, 0, 1);
                            LCD_WriteString(&lcd, "Blad USB");
                            LCD_SetLocation(&lcd, 6, 1);
                            LCD_WriteString(&lcd, buffer);

                }
            else
                {
                    LCD_SetLocation(&lcd, 0, 1);
                    LCD_WriteString(&lcd, "USB OK");
                    LCD_SetLocation(&lcd, 6, 1);
                    LCD_WriteString(&lcd, buffer);
                }

ale jak można się spodziewać, cały czas mam "Blad USB". Więc coś pewnie dalej źle robię.


Krzysiek


RE: STM32 USB/CDC - SQ8MVY - 06-04-2017 21:34

Witam

Zamień miejscami fragmenty przed i po else lub dodaj ! w warunku
Kod:
...
if (!(hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED)
...

Ten fragment kodu, ktory zapożyczyłeś nie jest czasami dla jakiegoś rtos-a?


RE: STM32 USB/CDC - SP9RQA - 06-04-2017 21:56

Nie, kod jest z tego linku który podałem wcześniej, tylko tam siedzi w tej funkcji CDC_Transmit_FS(), natomiast ten fragment przerzuciłem do swojego maina.
W każdym razie z negacją, czy bez cały czas mam Blad USB bez względu na to, czy port jest otwarty, czy nie.
Widać ten warunek nie sprawdza tego o co mi chodzi.


RE: STM32 USB/CDC - SQ8MVY - 06-04-2017 22:11

Ach, no tak, mój błąd...... Tak to jest jak się pisze z telefonu.....

Tak sprawdź
Kod:
...
if (!((hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED)
                        || (hUsbDeviceFS.ep0_state == USBD_EP0_STATUS_IN)))
...
Brakło nawiasów i negacja była tylko dla pierwszej części wyrażenia, a ma obejmować całość warunku.


RE: STM32 USB/CDC - SP9RQA - 06-04-2017 22:21

Jedyna różnica to taka, że teraz jest cały czas USB OK.


RE: STM32 USB/CDC - SQ8MVY - 06-04-2017 22:51

Wyświetl na lcd wartości hUsbDeviceFS.dev_state oraz hUsbDeviceFS.ep0_state w pętli otwierając/zamykając port.


RE: STM32 USB/CDC - SP9RQA - 07-04-2017 14:21

(06-04-2017 22:51)SQ8MVY napisał(a):  Wyświetl na lcd wartości hUsbDeviceFS.dev_state oraz hUsbDeviceFS.ep0_state w pętli otwierając/zamykając port.

Te wartości się nie zmieniają, jedna jest 3, a druga 4 zgodnie zresztą z ich definicją.


RE: STM32 USB/CDC - SQ8MVY - 07-04-2017 15:42

Witam,

A powinny, w zależności od stanu USB. Przelgądałem wiele przykładów z obsługą usb i w większości do detekcji połączenia USB jest sprawdzana zawartość dev_state w strukurze hUsbDeviceFS.

Na jakim procku to robisz i w jakim środowisku IDE piszesz? Na weekendzie popatrzę u siebie jak to się zachowuje. Z chęcią zgłębie obsługę USB......


RE: STM32 USB/CDC - SP9RQA - 07-04-2017 16:30

Płytka STM32F4Discovery


RE: STM32 USB/CDC - SQ8MVY - 07-04-2017 20:36

Witam,

Nie wiem jaki masz wyświetlacz, ale sobie poprawisz współrzędne.
W CubeMX nie zapomniałeś włączyć przerwań ?

Przetestuj takie coś.

Kod:
while (1)
  {
      sprintf(buffer, "%u", hUsbDeviceFS.dev_state);
      LCD_SetLocation(&lcd, 0, 1);
      LCD_WriteString(&lcd, buffer);

      sprintf(buffer, "%u", hUsbDeviceFS.dev_connection_status);
      LCD_SetLocation(&lcd, 1, 1);
      LCD_WriteString(&lcd, buffer);

      sprintf(buffer, "%lu", hUsbDeviceFS.ep0_state);
      LCD_SetLocation(&lcd, 3, 1);
      LCD_WriteString(&lcd, buffer);
      
    }

Podaj co będzie na wyświetlaczu jak będziesz wypinał podpinał kabelek oraz otwierał/zamykał port.


Pętla ma być oczywiście w main()

Swój szkielet programu robiłeś zgodnie z tym kursem na forbot ? widziałem Twój komentarz...