Перейти к содержанию
    

Не заводится USB на STM32F302. Chibios

Собственно, вот и вся проблема. :(

Внешний кварц 16МГц. Осциллограф показывает 16МГц. Через mcuconf.h настроил тактирование. Вроде всё верно.

#define STM32_NO_INIT FALSE
#define STM32_PVD_ENABLE FALSE
#define STM32_PLS STM32_PLS_LEV0
#define STM32_HSI_ENABLED TRUE
#define STM32_LSI_ENABLED TRUE
#define STM32_HSE_ENABLED TRUE
#define STM32_LSE_ENABLED FALSE
#define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_PREDIV_VALUE 2 // 16MHZ HSE -> 72MHZ SYSCLK
#define STM32_PLLMUL_VALUE 9
#define STM32_HPRE STM32_HPRE_DIV1 // 72MHz AHB
#define STM32_PPRE1 STM32_PPRE1_DIV2 // 36MHz APB1
#define STM32_PPRE2 STM32_PPRE2_DIV2 // 72MHz APB2
#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
#define STM32_ADC12PRES STM32_ADC12PRES_DIV1

Программа стартует, отрабатывает следующий код:

  sduObjectInit(&SDU1);
  sduStart(&SDU1, &serusbcfg);

  usbDisconnectBus(serusbcfg.usbp);
  chThdSleepMilliseconds(1500);
  usbStart(serusbcfg.usbp, &usbcfg);
  usbConnectBus(serusbcfg.usbp);

И навечно остаётся в следующем коде, моргая светодиодом:

	while (SDU1.config->usbp->state != USB_ACTIVE) {
		led_toggle(STATUS_LED);
		chThdSleepMilliseconds(500);
	}

в обработчике:

static void usb_event(USBDriver *usbp, usbevent_t event) {
  extern SerialUSBDriver SDU1;

  switch (event) {
  case USB_EVENT_ADDRESS:
    return;
  case USB_EVENT_CONFIGURED:
    chSysLockFromISR();

    /* Enables the endpoints specified into the configuration.
       Note, this callback is invoked from an ISR so I-Class functions
       must be used.*/
    usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
    usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);

    /* Resetting the state of the CDC subsystem.*/
    sduConfigureHookI(&SDU1);

    chSysUnlockFromISR();
    return;
  case USB_EVENT_RESET:
    /* Falls into.*/
  case USB_EVENT_UNCONFIGURED:
    /* Falls into.*/
  case USB_EVENT_SUSPEND:
    chSysLockFromISR();

    /* Disconnection event on suspend.*/
    sduSuspendHookI(&SDU1);

    chSysUnlockFromISR();
    return;
  case USB_EVENT_WAKEUP:
    chSysLockFromISR();

    /* Connection event on wakeup.*/
    sduWakeupHookI(&SDU1);

    chSysUnlockFromISR();
    return;
  case USB_EVENT_STALLED:
    return;
  }
  return;
}

несколько раз дёргается USB_EVENT_RESET, после USB_EVENT_SUSPEND и всё. Событие USB_EVENT_CONFIGURED никогда не приходит.

Операционка говорит, что не может прочитать дескриптор устройства.

Резистор подтяжки есть. По шине что-то дёргается.

Уже не знаю куда копать. :(

Update:

В режиме DFU определяется системой нормально. Т.е. физический канал USB - рабочий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 часов назад, gab сказал:

Уже не знаю куда копать. :(

А Вы CubeMX используете?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 часов назад, gab сказал:

несколько раз дёргается USB_EVENT_RESET, после USB_EVENT_SUSPEND и всё

Надо ставить точку останова в обработчике и смотреть, есть ли запросы к EP0 и корректно ли они отрабатываются. Именно через нее читаются дескрипторы. Но надо быть готовым к тому, что на этапе конфигурации каждая остановка в обработчике вызовет ошибку на шине. То есть на момент остановки у вас в отладчике должны быть открыты нужные регистры, вы смотрите их содержимое и перезапукаете программу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так не доходит до конфигурации. Точка останова стоит на "usb_event".

Ещё один момент. на чипе написано STM32F302C8T6 или CBT6, трудно разглядеть. А пишет:

Info : device id = 0x10036422
Info : flash size = 128kbytes

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

58 минут назад, gab сказал:

Так не доходит до конфигурации. Точка останова стоит на "usb_event".

usb_event() - это не обрабтчик прерывания USB, а некая функция, которая вызывается при возникновнии в программе каких-то событий. Вас же должен интересовать обработчик прерывания, который занимается всей "грязной работой".

P.S. а на каком языке у вас название города в профиле написано? Просто любопытно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот определение:

/**
 * @name    Low level driver helper macros
 * @{
 */
/**
 * @brief   Common ISR code, usb event callback.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @param[in] evt       USB event code
 *
 * @notapi
 */
#define _usb_isr_invoke_event_cb(usbp, evt) {                               \
  if (((usbp)->config->event_cb) != NULL) {                                 \
    (usbp)->config->event_cb(usbp, evt);                                    \
  }                                                                         \
}

event_cb и есть этот usb_event. Ещё есть usb_serve_endpoints, но он не вызывается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 минут назад, gab сказал:

event_cb и есть этот usb_event.

Да хоть горшком назовите. При возникновении аппаратного события USB ядро вызывает обработчик прерывания, адрес которого записан в векторе 0x0000 0168 (USB High priority interrupt) или 0x0000 016C (USB Low priority interrupt). Вот ту функцию, которая называется USB_чего-то-там_Handler() и указатель на которую вы или ваша библиотека записали в соответствующий вектор, вам и надо смотреть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) {
  uint32_t istr;
  USBDriver *usbp = &USBD1;

  OSAL_IRQ_PROLOGUE();

  istr = STM32_USB->ISTR;

  /* USB bus reset condition handling.*/
  if (istr & ISTR_RESET) {
    STM32_USB->ISTR = ~ISTR_RESET;

    _usb_reset(usbp);
  }

  /* USB bus SUSPEND condition handling.*/
  if (istr & ISTR_SUSP) {
    STM32_USB->CNTR |= CNTR_FSUSP;
#if STM32_USB_LOW_POWER_ON_SUSPEND
    STM32_USB->CNTR |= CNTR_LP_MODE;
#endif
    STM32_USB->ISTR = ~ISTR_SUSP;

    _usb_suspend(usbp);
  }

  /* USB bus WAKEUP condition handling.*/
  if (istr & ISTR_WKUP) {
    uint32_t fnr = STM32_USB->FNR;
    if (!(fnr & FNR_RXDP)) {
      STM32_USB->CNTR &= ~CNTR_FSUSP;

      _usb_wakeup(usbp);
    }
#if STM32_USB_LOW_POWER_ON_SUSPEND
    else {
      /* Just noise, going back in SUSPEND mode, reference manual 22.4.5,
         table 169.*/
      STM32_USB->CNTR |= CNTR_LP_MODE;
    }
#endif
    STM32_USB->ISTR = ~ISTR_WKUP;
  }

  /* SOF handling.*/
  if (istr & ISTR_SOF) {
    _usb_isr_invoke_sof_cb(usbp);
    STM32_USB->ISTR = ~ISTR_SOF;
  }

  /* Endpoint events handling.*/
  while (istr & ISTR_CTR) {
    usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK);
    istr = STM32_USB->ISTR;
  }

  OSAL_IRQ_EPILOGUE();
}

Вот весь обработчик. За время связи вызывается 3 раза.

Флаги ISTR:

1. RESET

2. ESOF | RESET | SUSP

3. ESOF

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вывод dmesg в линуксе:

[117379.864359] usb 1-1: new full-speed USB device number 18 using xhci_hcd
[117379.992115] usb 1-1: device descriptor read/64, error -71
[117380.227595] usb 1-1: device descriptor read/64, error -71
[117380.335552] usb usb1-port1: attempt power cycle
[117380.985577] usb 1-1: new full-speed USB device number 19 using xhci_hcd
[117380.985719] usb 1-1: Device not responding to setup address.
[117381.193652] usb 1-1: Device not responding to setup address.
[117381.401082] usb 1-1: device not accepting address 19, error -71
[117381.528772] usb 1-1: new full-speed USB device number 20 using xhci_hcd
[117381.528990] usb 1-1: Device not responding to setup address.
[117381.736693] usb 1-1: Device not responding to setup address.
[117381.736778] debugfs: Directory '05' with parent 'devices' already present!
[117381.943880] usb 1-1: device not accepting address 20, error -71
[117381.944062] usb usb1-port1: unable to enumerate USB device
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не работает. Почти.

Если поставить ld-скрипт от 303, то загружается, моргает светодиодом и не определяется.

ld-скрипт от 302 - не влезает. 

На чипе написано STM32F302C8T6 или CBT6, трудно разглядеть. OpenOCD пишет:

Info : device id = 0x10036422
Info : flash size = 128kbytes

Отрубил тесты. Влезло. Моргает и не определяется.

 

8 hours ago, Сергей Борщ said:

Давайте смотреть, что делает _usb_reset(usbp)

/**
 * @brief   USB reset routine.
 * @details This function must be invoked when an USB bus reset condition is
 *          detected.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 *
 * @notapi
 */
void _usb_reset(USBDriver *usbp) {
  unsigned i;
  /* State transition.*/
  usbp->state         = USB_READY;
  /* Resetting internal state.*/
  usbp->status        = 0;
  usbp->address       = 0;
  usbp->configuration = 0;
  usbp->transmitting  = 0;
  usbp->receiving     = 0;
  /* Invalidates all endpoints into the USBDriver structure.*/
  for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) {
#if USB_USE_WAIT == TRUE
    /* Signaling the event to threads waiting on endpoints.*/
    if (usbp->epc[i] != NULL) {
      osalSysLockFromISR();
      if (usbp->epc[i]->in_state != NULL) {
        osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET);
      }
      if (usbp->epc[i]->out_state != NULL) {
        osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET);
      }
      osalSysUnlockFromISR();
    }
#endif
    usbp->epc[i] = NULL;
  }
  /* EP0 state machine initialization.*/
  usbp->ep0state = USB_EP0_STP_WAITING;
  /* Low level reset.*/
  usb_lld_reset(usbp);
  /* Notification of reset event.*/
  _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET);
}
/**
 * @brief   USB low level reset routine.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 *
 * @notapi
 */
void usb_lld_reset(USBDriver *usbp) {
  uint32_t cntr;
  /* Post reset initialization.*/
  STM32_USB->BTABLE = BTABLE_ADDR;
  STM32_USB->ISTR   = 0;
  STM32_USB->DADDR  = DADDR_EF;
  cntr              = /*CNTR_ESOFM | */ CNTR_RESETM  | CNTR_SUSPM |
                      CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
  /* The SOF interrupt is only enabled if a callback is defined for
     this service because it is an high rate source.*/
  if (usbp->config->sof_cb != NULL)
    cntr |= CNTR_SOFM;
  STM32_USB->CNTR = cntr;
  /* Resets the packet memory allocator.*/
  usb_pm_reset(usbp);
  /* EP0 initialization.*/
  usbp->epc[0] = &ep0config;
  usb_lld_init_endpoint(usbp, 0);
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...