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

Доброго времени суток.
Прошу помочь, ответом на такой вопрос:
Собрал схему USB CDC устройства на PIC18F2550, скачал родные исходники с microchip.com, подправил кое, что в функциях пользователя.
Работает так: на PC с помощью терминала отправляю в появившийся виртуальный порт строку из 5 байт, по идее они сохраняются в буфере до их прочтения. Читаю принятую инф. после нажатия на кнопку на плате устройства, а на терминале получаю ответ от устройства. Так вот, пытливости ради, отправил дважды одну и ту же последовательность, нажал на кнопку, устройство ответило один раз на первую посылку. Отправил последовательность трижды... две отобразились на терминале как отправленные, третья не отобразилась в строке отосланных, терминал повис, нажал на кнопку устройства, в строке отосланных появился третья отправленная последовательность, устройство ответило на первое и третье. То что ответ приходит на первую и третью последовательность проверил сделав последовательности разными.
Тут возник вопрос: куда девалась вторая последовательность? Если устройство удержало посылку только третей последовательности, значит вторую он принял... ???
Буфер сконфигурирован: no ping-pong.
Посмотрите по
ссылке
За ссылку спасибо, прочитал. Оч полезная.
Но все же у меня CDC устройство.
Вот что не могу в толк взять:
в коде программы в конфигурации USB есть строка: #define USB_EP0_BUFF_SIZE 8 // Valid Options: 8, 16, 32, or 64 bytes.
Как я понимаю это количество байт которые могут приняться модулем за один "сеанс передачи". Если буфер переполнен, то ПК останавливает передачу (не получен ответ от микроконтроллера). В модуле USB двойная буферизация, есть четный буфер и нечетный. Так вот если ping-pong включен то первый принятый байт принимается в четный буфер, второй в нечетный и пока принимается второй первый должен быть обработан. А если ping-pong отключен, оба буфера имеют один и тот же адрес 0. Вот тут и загвоздка, первый принимается и по логике вещей буфер заполнен. Или я не так понимаю принцип работы. Прошу помочь, кто сталкивался.
Наверное запутал и себя и всех присутствующих.
Вообщем вот еще: строка #define USB_EP0_BUFF_SIZE 8
определяет количество байт зарезервированое под буфер конечной точки 0. Он используется и на прием и на передачу. Опыт с железом показал, что буфер заполняется за одну транзакцию (даже если буфер 8 байт, а принимаю 5 байт), если не прочитать его и не освободить, то следующая посылка просто игнорируется.
Так почему если переданы первые 5 байт - заполнили буфер, вторый 5 байт проигнорированы, а на третьей посылке 5-ти байт зависает терминал?
Цитата(J-t @ Feb 5 2009, 13:33)

Но все же у меня CDC устройство.
Посмотрите сдесь
http://files.mail.ru/UCHZCEБрал на
http://www.microchip.su/showthread.php?t=4970 но сейчас ее почему-то закрыли.
Дело скорее всего в том, что за 1 милисекунду принимается 1 пакет, там нужно чуть код подкорректировать, покажите Ваш.
Вот то что писал сам (в целях обучения):
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(). Тогда ее нужно включить в цикл подпрограммы пользователя?
Дело скорее всего в том, что Вы неточно представляете себе работу юсб. Инициатором обмена всегда будет хост, а он бросает запросы через миллисекунду. Если Вам нужны микросекунды - примените другое решение. Это первое.
Во-вторых, говоря - я хотел бы увидеть код - я не рассчитывал на этот бред (простите мой француский). Я хотел сказать то. что если Вы в ответ на запрос хотите выдать что-то, превышающее размер буфера, то Вам нужно это счастье выдавать всю миллисекунду, пока есть готовность.
Т.е. вместо if (ready
do{
}while(ready
понимаете ???

Замечание уместное. Бред эксперементальный, выложил только то, что претерпело изменение в микрочиповском примере. Все остальное не изменилось.
Далее, с Вами соглашусь, на момент написания прошлого комментария не понимал процесса обмена, выходные потрачены не зря

Я вот только прошу ответить на вопрос: если у USB устройства занят буфер и оно не готово принять данные от host, то на посыл токен OUT устройство отвечает NAK и данные теряются. Я правильно понял? А то что терминал повис, при получении NAK это уже особенности терминала?
данные не теряются. Хост переносит обмен на следующую милисекунду. Ничего зависать не должно.
Ну есть же таймаут, по которому хост перестает откладывать перенос данных?
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.