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

 
 
 
Reply to this topicStart new topic
> USB CDC на PIC18F2550, Работа ping-pong buffer
J-t
сообщение Feb 5 2009, 09:00
Сообщение #1





Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461



Доброго времени суток.
Прошу помочь, ответом на такой вопрос:
Собрал схему USB CDC устройства на PIC18F2550, скачал родные исходники с microchip.com, подправил кое, что в функциях пользователя.
Работает так: на PC с помощью терминала отправляю в появившийся виртуальный порт строку из 5 байт, по идее они сохраняются в буфере до их прочтения. Читаю принятую инф. после нажатия на кнопку на плате устройства, а на терминале получаю ответ от устройства. Так вот, пытливости ради, отправил дважды одну и ту же последовательность, нажал на кнопку, устройство ответило один раз на первую посылку. Отправил последовательность трижды... две отобразились на терминале как отправленные, третья не отобразилась в строке отосланных, терминал повис, нажал на кнопку устройства, в строке отосланных появился третья отправленная последовательность, устройство ответило на первое и третье. То что ответ приходит на первую и третью последовательность проверил сделав последовательности разными.
Тут возник вопрос: куда девалась вторая последовательность? Если устройство удержало посылку только третей последовательности, значит вторую он принял... ???
Буфер сконфигурирован: no ping-pong.
Go to the top of the page
 
+Quote Post
Vlad27
сообщение Feb 5 2009, 09:34
Сообщение #2


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

Группа: Свой
Сообщений: 95
Регистрация: 31-07-05
Из: Полоцк Беларусь
Пользователь №: 7 227



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

Посмотрите по ссылке
Go to the top of the page
 
+Quote Post
J-t
сообщение Feb 5 2009, 10:33
Сообщение #3





Группа: Новичок
Сообщений: 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. Вот тут и загвоздка, первый принимается и по логике вещей буфер заполнен. Или я не так понимаю принцип работы. Прошу помочь, кто сталкивался.
Go to the top of the page
 
+Quote Post
J-t
сообщение Feb 5 2009, 14:32
Сообщение #4





Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461



Наверное запутал и себя и всех присутствующих.
Вообщем вот еще: строка #define USB_EP0_BUFF_SIZE 8
определяет количество байт зарезервированое под буфер конечной точки 0. Он используется и на прием и на передачу. Опыт с железом показал, что буфер заполняется за одну транзакцию (даже если буфер 8 байт, а принимаю 5 байт), если не прочитать его и не освободить, то следующая посылка просто игнорируется.
Так почему если переданы первые 5 байт - заполнили буфер, вторый 5 байт проигнорированы, а на третьей посылке 5-ти байт зависает терминал?
Go to the top of the page
 
+Quote Post
GAS
сообщение Feb 5 2009, 18:57
Сообщение #5





Группа: Участник
Сообщений: 8
Регистрация: 8-02-05
Пользователь №: 2 495



Цитата(J-t @ Feb 5 2009, 13:33) *
Но все же у меня CDC устройство.

Посмотрите сдесь http://files.mail.ru/UCHZCE
Брал на http://www.microchip.su/showthread.php?t=4970 но сейчас ее почему-то закрыли.
Go to the top of the page
 
+Quote Post
urry1
сообщение Feb 5 2009, 19:54
Сообщение #6


Участник
*

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



Дело скорее всего в том, что за 1 милисекунду принимается 1 пакет, там нужно чуть код подкорректировать, покажите Ваш.
Go to the top of the page
 
+Quote Post
J-t
сообщение Feb 6 2009, 06:50
Сообщение #7





Группа: Новичок
Сообщений: 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
Go to the top of the page
 
+Quote Post
urry1
сообщение Feb 7 2009, 15:34
Сообщение #8


Участник
*

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



Дело скорее всего в том, что Вы неточно представляете себе работу юсб. Инициатором обмена всегда будет хост, а он бросает запросы через миллисекунду. Если Вам нужны микросекунды - примените другое решение. Это первое.
Во-вторых, говоря - я хотел бы увидеть код - я не рассчитывал на этот бред (простите мой француский). Я хотел сказать то. что если Вы в ответ на запрос хотите выдать что-то, превышающее размер буфера, то Вам нужно это счастье выдавать всю миллисекунду, пока есть готовность.
Т.е. вместо if (ready
do{
}while(ready
понимаете ???
laughing.gif
Go to the top of the page
 
+Quote Post
J-t
сообщение Feb 9 2009, 11:32
Сообщение #9





Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461



smile.gif Замечание уместное. Бред эксперементальный, выложил только то, что претерпело изменение в микрочиповском примере. Все остальное не изменилось.
Далее, с Вами соглашусь, на момент написания прошлого комментария не понимал процесса обмена, выходные потрачены не зря smile.gif
Я вот только прошу ответить на вопрос: если у USB устройства занят буфер и оно не готово принять данные от host, то на посыл токен OUT устройство отвечает NAK и данные теряются. Я правильно понял? А то что терминал повис, при получении NAK это уже особенности терминала?
Go to the top of the page
 
+Quote Post
urry1
сообщение Feb 10 2009, 17:46
Сообщение #10


Участник
*

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



данные не теряются. Хост переносит обмен на следующую милисекунду. Ничего зависать не должно.
Go to the top of the page
 
+Quote Post
J-t
сообщение Feb 11 2009, 10:11
Сообщение #11





Группа: Новичок
Сообщений: 10
Регистрация: 18-10-07
Пользователь №: 31 461



Ну есть же таймаут, по которому хост перестает откладывать перенос данных?
Go to the top of the page
 
+Quote Post

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

 


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


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