реклама на сайте
подробности

 
 
> STM4 USB CDC. Интересное поведение
drozel
сообщение Oct 19 2015, 10:35
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Использую libopencm3. За основу взят вот этот пример CDC.
Размер фрейма для нашего ендпойнта настроен 64.
Написал простеньку логику: МК принимает фрейм, смотрит первый элемент и высылает назад статик массив размером, указанным в принятом байте.
Таким образом, я в терминале посылаю число и в ответ получаю заказанное кол-во байт.
Код:
Код
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
{
    (void)ep;

    int len = usbd_ep_read_packet(usbd_dev, 0x01, USBio.buffer, 64);
    сdcacm_data_tx((uint8_t *)textBuf, USBio.buffer[0]);
}


Посылаю число 0х20 - получаю 32 байта данных.
Посылаю число 0х3F - gjkexf. 63 байта в ответ.
Посылаю 0x40 - тишина. Еще раз - тишина. Теперь внимание! Посылаю 0х01 - получаю 129 байт.
Т.е. пришли все запрошенные за прошлые 3 раза данные.
Выходит, что если МК посылает кол-во байт, совпадающее с размером фрейма - данные где-то зависают.

Начал копать: посылает ли МК? Поставил коллбек по окончанию передачи, виду, что передача проходит.
Принимает ли ПК? К сообщению прикреплен скриншот USB сниффера.
Данные действительно где-то зависают. Буфер драйвера? Буфер USB контроллера?

Кто сталкивался?

Прикрепленное изображение


UPD: нащел аналогичный вопрос на форуме СТ. Он там остался без ответа)
UPD2: Вот тут пояснили, что передача длиной равной размеру кадра должна дополняться передачей нулевой длины. Однако, такая логика не согласуется с логикой разрабов libopencm3, которые используют следующую логику для проверки занятости ендпойнта в функции отправки:
Код
while(usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0);

Функция возвращает 0, если идет передача, таким образом происходит ожидание освобождения ендпойнта. Посылка длиной 0 байт приведет к зависанию и вообще не похоже, что такая вещь предусмотрена разрабами

Сообщение отредактировал drozel - Oct 19 2015, 10:46
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
drozel
сообщение Oct 20 2015, 04:35
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Интересно, что в stdlib контроль трансфера уже прописан в низкоуровневых функциях:
Код
/* Program the transfer size and packet count
      * as follows: xfersize = N * maxpacket +
      * short_packet pktcnt = N + (short_packet
      * exist ? 1 : 0)
      */
      deptsiz.b.xfersize = ep->xfer_len;
      deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
      
      if (ep->type == EP_TYPE_ISOC)
      {
        deptsiz.b.mc = 1;
      }      
    }
    USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32);

Какого черта такое творится в libopencm3??
Я над, казалось бы, файлом верхнего уровня USB_cdc.c должен воротить логику протокола?

Сообщение отредактировал drozel - Oct 20 2015, 04:39
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 22:14
Рейтинг@Mail.ru


Страница сгенерированна за 0.01412 секунд с 7
ELECTRONIX ©2004-2016