eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronikaAVR32 - problem z USB (bit detach)Re: AVR32 - problem z USB (bit detach)
  • Data: 2009-11-14 18:41:45
    Temat: Re: AVR32 - problem z USB (bit detach)
    Od: SM <b...@k...com.pl> szukaj wiadomości tego autora
    [ pokaż wszystkie nagłówki ]

    Wziąłem się za przeglądanie przykładów atmela dostarczanych z AVR32
    Przykład usb_cdc.
    Możliwa praca albo z FREERTOS albo z poolingiem.
    W obu przypadkach część funkcji jest realizowana na przerwaniach.
    Biorę pod uwagę tylko tę cześć programu, które odpowiada
    wyłącznie za tryb pracy DEVICE.

    Najpierw mamy wywołanie:
    pm_configure_usb_clock()
    Spoko. Uruchamia PLL1 dla USB na 48MHz.

    Potem:
    usb_task_init();
    Też w miarę OK.
    1. Instaluje handler przerwania.
    2. Wymusza tryb pracy DEVICE.
    3. Wywołuje usb_device_task_init();
    Ten też OK.
    1. Uruchamia pad OTG
    2. Uruchamia USBE
    3. Odmraża zegar dla USB
    4. I tu uwaga! Uruchamia przerwanie USB od VBUS (kontroli
    napięcia zasilania na lini VBUS).

    Inicjalizację mamy za sobą. Teraz w kółko wywoływana jest
    procedura usb_task() która w przypadku DEVICE wywołuje
    usb_device_task().

    Co widzimy na początku usb_device_task():

    if (!usb_connected && Is_usb_vbus_high())
    {
    usb_start_device();

    Czyli: usb_connected to flaga programu. Oczywiście wyzerowana.
    Is_usb_vbus_high() natomiast robi pooling USBSTA bitu VBUS.
    Czyli usb_start_device() zostanie wywołane w momencie
    podania napięcia na VBUS.

    I byłoby OK, ale zajrzyjmy do procedury obsługi przerwań
    od USB, czyli usb_general_interrupt(void):

    if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled())
    {
    Usb_ack_vbus_transition();
    if (Is_usb_vbus_high())
    {
    usb_start_device();

    Tutaj w przerwaniu mamy dokładnie to samo w pętli głównej, tyle
    że na przerwaniach. W momencie przyjścia napięcia na VBUS
    zostaje wywołana ta sama procedura co w programie głównym.
    Co będzie jeśli przerwanie przyjdzie wtedy, kiedy główna
    procedura będzie odczytywała stan bitu VBUS w USBSTA?
    Zostanie dwukrotnie wywołane usb_start_device().
    Mało prawdopodobna sytuacja, ale możlwia. I co wtedy?
    Będziemy mieć np. podwójne zaalokowanie pamięci dla
    endpoint 0. Bardzo wredny błąd, bo ciężki do wychwycenia.

    Dlatego chciałem napisać własną obsługę USB CDC niż korzystać
    z wątpliwych gotowców atmela, tyle że procek nie bardzo
    chce pracować wg tego co piszą w PDFie.

    Robię tak:

    // usbb base

    mov.w r12, USBB_BASE

    // disable usb, freeze clock, force device mode

    mov.w r0, (1 << USBCON_FRZCLK) | (1 << USBCON_OTGPADE) | (1 <<
    USBCON_UIMOD) | (1 << USBCON_VBUSHWC)
    st.w r12[USBB_USBCON], r0

    // enable usb, unfreeze clock, force device mode

    mov.w r0, (1 << USBCON_USBE) | (1 << USBCON_OTGPADE) | (1 <<
    USBCON_UIMOD) | (1 << USBCON_VBUSHWC)
    st.w r12[USBB_USBCON], r0

    // enable endpoint

    mov r0, (1 << UERST_EPEN0)
    st.w r12[USBB_UERST], r0

    // configure endpoint

    mov.w r0, (3 << UECFG_EPSIZE) | (1 << UECFG_ALLOC)
    st.w r12[USBB_UECFG0], r0

    // attach

    mov r0, 0
    st.w r12[USBB_UDCON], r0

    I lipa. Attach nie działa. Żadna z linii D+/D- nie zostaje podciągnięta.

    SM

Podziel się

Poleć ten post znajomemu poleć

Wydrukuj ten post drukuj


Następne wpisy z tego wątku

  • 15.11.09 05:52 SM
  • 16.11.09 17:46 Konop
  • 17.11.09 05:12 SM

Najnowsze wątki z tej grupy


Najnowsze wątki

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: