|
|
  |
USB CDC на PIC18F2550, Работа ping-pong buffer |
|
|
|
Feb 5 2009, 09:00
|
Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461

|
Доброго времени суток. Прошу помочь, ответом на такой вопрос: Собрал схему USB CDC устройства на PIC18F2550, скачал родные исходники с microchip.com, подправил кое, что в функциях пользователя. Работает так: на PC с помощью терминала отправляю в появившийся виртуальный порт строку из 5 байт, по идее они сохраняются в буфере до их прочтения. Читаю принятую инф. после нажатия на кнопку на плате устройства, а на терминале получаю ответ от устройства. Так вот, пытливости ради, отправил дважды одну и ту же последовательность, нажал на кнопку, устройство ответило один раз на первую посылку. Отправил последовательность трижды... две отобразились на терминале как отправленные, третья не отобразилась в строке отосланных, терминал повис, нажал на кнопку устройства, в строке отосланных появился третья отправленная последовательность, устройство ответило на первое и третье. То что ответ приходит на первую и третью последовательность проверил сделав последовательности разными. Тут возник вопрос: куда девалась вторая последовательность? Если устройство удержало посылку только третей последовательности, значит вторую он принял... ??? Буфер сконфигурирован: no ping-pong.
|
|
|
|
|
Feb 5 2009, 09:34
|
Частый гость
 
Группа: Свой
Сообщений: 95
Регистрация: 31-07-05
Из: Полоцк Беларусь
Пользователь №: 7 227

|
Цитата(J-t @ Feb 5 2009, 11:00)  Доброго времени суток. Прошу помочь, ответом на такой вопрос: Собрал схему USB CDC устройства на PIC18F2550, скачал родные исходники с microchip.com, подправил кое, что в функциях пользователя. Работает так: на PC с помощью терминала отправляю в появившийся виртуальный порт строку из 5 байт, по идее они сохраняются в буфере до их прочтения. Читаю принятую инф. после нажатия на кнопку на плате устройства, а на терминале получаю ответ от устройства. Так вот, пытливости ради, отправил дважды одну и ту же последовательность, нажал на кнопку, устройство ответило один раз на первую посылку. Отправил последовательность трижды... две отобразились на терминале как отправленные, третья не отобразилась в строке отосланных, терминал повис, нажал на кнопку устройства, в строке отосланных появился третья отправленная последовательность, устройство ответило на первое и третье. То что ответ приходит на первую и третью последовательность проверил сделав последовательности разными. Тут возник вопрос: куда девалась вторая последовательность? Если устройство удержало посылку только третей последовательности, значит вторую он принял... ??? Буфер сконфигурирован: no ping-pong. Посмотрите по ссылке
|
|
|
|
|
Feb 5 2009, 10:33
|
Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461

|
За ссылку спасибо, прочитал. Оч полезная. Но все же у меня CDC устройство. Вот что не могу в толк взять: в коде программы в конфигурации USB есть строка: #define USB_EP0_BUFF_SIZE 8 // Valid Options: 8, 16, 32, or 64 bytes. Как я понимаю это количество байт которые могут приняться модулем за один "сеанс передачи". Если буфер переполнен, то ПК останавливает передачу (не получен ответ от микроконтроллера). В модуле USB двойная буферизация, есть четный буфер и нечетный. Так вот если ping-pong включен то первый принятый байт принимается в четный буфер, второй в нечетный и пока принимается второй первый должен быть обработан. А если ping-pong отключен, оба буфера имеют один и тот же адрес 0. Вот тут и загвоздка, первый принимается и по логике вещей буфер заполнен. Или я не так понимаю принцип работы. Прошу помочь, кто сталкивался.
|
|
|
|
|
Feb 5 2009, 14:32
|
Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461

|
Наверное запутал и себя и всех присутствующих. Вообщем вот еще: строка #define USB_EP0_BUFF_SIZE 8 определяет количество байт зарезервированое под буфер конечной точки 0. Он используется и на прием и на передачу. Опыт с железом показал, что буфер заполняется за одну транзакцию (даже если буфер 8 байт, а принимаю 5 байт), если не прочитать его и не освободить, то следующая посылка просто игнорируется. Так почему если переданы первые 5 байт - заполнили буфер, вторый 5 байт проигнорированы, а на третьей посылке 5-ти байт зависает терминал?
|
|
|
|
|
Feb 5 2009, 19:54
|
Участник

Группа: Новичок
Сообщений: 54
Регистрация: 14-12-06
Пользователь №: 23 498

|
Дело скорее всего в том, что за 1 милисекунду принимается 1 пакет, там нужно чуть код подкорректировать, покажите Ваш.
|
|
|
|
|
Feb 6 2009, 06:50
|
Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461

|
Вот то что писал сам (в целях обучения): void ProcessIO(void) { //Blink the LEDs according to the USB device status // BlinkUSBStatus(); // User Application USB tasks mInitSwitch3(); if(sw3 == 0) { if(getsUSBUSART(USB_Out_Buffer, 8) == 5) { if (USB_Out_Buffer[0] == 'a') { if(USB_Out_Buffer[1] == 'a') { if(USB_Out_Buffer[2] == 'a') { if(USB_Out_Buffer[3] == 'a') { if(USB_Out_Buffer[4] == 'a') { if(mUSBUSARTIsTxTrfReady()) { putrsUSBUSART("A"); } } } } } } if (USB_Out_Buffer[0] == 'b') { if(USB_Out_Buffer[1] == 'b') { if(USB_Out_Buffer[2] == 'b') { if(USB_Out_Buffer[3] == 'b') { if(USB_Out_Buffer[4] == 'b') { if(mUSBUSARTIsTxTrfReady()) { putrsUSBUSART("B"); } } } } } } if (USB_Out_Buffer[0] == 'c') { if(USB_Out_Buffer[1] == 'c') { if(USB_Out_Buffer[2] == 'c') { if(USB_Out_Buffer[3] == 'c') { if(USB_Out_Buffer[4] == 'c') { if(mUSBUSARTIsTxTrfReady()) { putrsUSBUSART("C"); } } } } } } } }
Мой код ничего не делает полезного, пока. кнопка нужна, что бы давать отмашку на чтение из буфера данных; три последовательности: ааааа, bbbbb, ccccc на каждую из них PIC отвечает A или B или C.
Конечная цель всего этого - понять по какому алгоритму стоит действовать если пользовательская программа работает в цикле с другим контроллером или подключенным устройством (например: мерит температуру и показывает ее на дисплее) и в любой момент времени могут прийти данных от ПК по USB? Что будет если я не смогу их прочитать (нажать на кнопку, в программе выше) в виду выполнения более важных операций?
Сделал бесконечный цикл в подпрограмме пользователя, ПК вовсе не увидел устройство, я так понял, что из за того, что не вызывается функция USBDeviceTasks(). Тогда ее нужно включить в цикл подпрограммы пользователя?
Сообщение отредактировал J-t - Feb 6 2009, 07:43
|
|
|
|
|
Feb 7 2009, 15:34
|
Участник

Группа: Новичок
Сообщений: 54
Регистрация: 14-12-06
Пользователь №: 23 498

|
Дело скорее всего в том, что Вы неточно представляете себе работу юсб. Инициатором обмена всегда будет хост, а он бросает запросы через миллисекунду. Если Вам нужны микросекунды - примените другое решение. Это первое. Во-вторых, говоря - я хотел бы увидеть код - я не рассчитывал на этот бред (простите мой француский). Я хотел сказать то. что если Вы в ответ на запрос хотите выдать что-то, превышающее размер буфера, то Вам нужно это счастье выдавать всю миллисекунду, пока есть готовность. Т.е. вместо if (ready do{ }while(ready понимаете ???
|
|
|
|
|
Feb 9 2009, 11:32
|
Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461

|
 Замечание уместное. Бред эксперементальный, выложил только то, что претерпело изменение в микрочиповском примере. Все остальное не изменилось. Далее, с Вами соглашусь, на момент написания прошлого комментария не понимал процесса обмена, выходные потрачены не зря  Я вот только прошу ответить на вопрос: если у USB устройства занят буфер и оно не готово принять данные от host, то на посыл токен OUT устройство отвечает NAK и данные теряются. Я правильно понял? А то что терминал повис, при получении NAK это уже особенности терминала?
|
|
|
|
|
Feb 10 2009, 17:46
|
Участник

Группа: Новичок
Сообщений: 54
Регистрация: 14-12-06
Пользователь №: 23 498

|
данные не теряются. Хост переносит обмен на следующую милисекунду. Ничего зависать не должно.
|
|
|
|
|
Feb 11 2009, 10:11
|
Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461

|
Ну есть же таймаут, по которому хост перестает откладывать перенос данных?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|