Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обмен данными через USB
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
ZoonMan
Собрал USB устройство, похожее на Automator (http://www.obdev.at/products/avrusb/).
Залил в него немного откорректированую прошивку Automator'а.
Все работает нормально. Устройство определяется как положено. Отвечает на обращение к нему.
Помогите осуществить обмен данными.

В драйвере USB есть буфер usbTxBuf. По логике вещей, записывать информацию нужно в него, однако он недоступен из программы, т.к. объявлен в usbdrv.c. Этот файл в проект входит. Все нормально. Но переменная usbTxBuf является внутренней. Может ее объявление перенести в usbdrv.h?

Со стороны ПК терминал я написал (в проекте есть программа, я ее перенес на C++Builder) и он даже считывает область памяти из контроллера.
Только вот куда обращаться из прошивки, чтобы передавать информацию для видения терминалом не пойму.
GDI
Может стоит посмотреть как это сделано в проекте POWERSWITCH (http://www.obdev.at/products/avrusb/powerswitch.html) он передает в ПК данные о напряжении, а заодно в этом проекте находится последняя версия usb драйвера.
prottoss
Цитата(ZoonMan @ Jun 14 2007, 15:55) *
Собрал USB устройство, похожее на Automator (http://www.obdev.at/products/avrusb/).
Залил в него немного откорректированую прошивку Automator'а.
Все работает нормально. Устройство определяется как положено. Отвечает на обращение к нему.
Помогите осуществить обмен данными.

В драйвере USB есть буфер usbTxBuf. По логике вещей, записывать информацию нужно в него, однако он недоступен из программы, т.к. объявлен в usbdrv.c. Этот файл в проект входит. Все нормально. Но переменная usbTxBuf является внутренней. Может ее объявление перенести в usbdrv.h?

Со стороны ПК терминал я написал (в проекте есть программа, я ее перенес на C++Builder) и он даже считывает область памяти из контроллера.
Только вот куда обращаться из прошивки, чтобы передавать информацию для видения терминалом не пойму.
К usbTxBuf лезть нельзя ни в коем случае - это системная переменная драйвера. В ней хранятся данные для отправляемого драйвером пакета.



Я не вникал в код Atomator-a но, обычно общение происходит посредством функции usbFunctionRead и usbFunctionWrite, хотя, возможно я и ошибаюсь. Тем не менее, попробуйте скачать другие проекты, проще будет разобраться. А еще лучше взять самый простой из них, и начать с него, чтобы понять хотя бы основные принципы. По крайней мере я начинал так...
Itch
А какую максимальную скорость можно получить при передаче из компа в устройство?
prottoss
Цитата(Itch @ Jun 14 2007, 20:14) *
А какую максимальную скорость можно получить при передаче из компа в устройство?
теоретически 800 байт пер секsmile.gif
Itch
Да уж... А как тогда всякие FTDI работают нормально? Понятно, что там не HID, но нельзя ли на AVR сделать аналог USB1.0<->UART и чтобы это было быстрее чем 115200 б.п.с.?
prottoss
Цитата(Itch @ Jun 14 2007, 20:36) *
Да уж... А как тогда всякие FTDI работают нормально? Понятно, что там не HID, но нельзя ли на AVR сделать аналог USB1.0<->UART и чтобы это было быстрее чем 115200 б.п.с.?
Всякие ФТДИ работают на FullSpeed, а программный AVR USB работает на LowSpeed: максимальный размер пакета 8 байт, минимальный период между кадрами - 10 милисекунд, вот и считайте, сколько можно передать байт в любую сторону.

А сделать на AVR относительно быстрое, то бишь FullSpeed устройство можно, если к нему прикрутить внешний USB FullSpeed контроллер, например PDIUSBD12D или USBN9604. Будет, ИМХО, немного быстрее чем с FTDI. НО, для этого надо немного разбираться в USB протоколах, в отличии от использования чипов от FTDI , где про премудрости USB, фактически, можно забыть.
oran-be
Цитата
про премудрости USB, фактически, можно забыть.

Может и можно, зато потом можно будет неоднократно испытать превеликое удивление biggrin.gif
ZoonMan
to GDI:
Посмотрел проект Power Switch. Ничего в нем нового не увидел. Только запись в EEPROM. Адрес они сами определили. Откуда они его взяли. Непонятно. И зачем писать в EEPROM - это же медленно. Да и циклы перезаписи не бесконечны.

to prottoss:
попробовал usbFunctionWrite(). Ни к чему хорошему это ни привело. Терминал отказался читать блоки. Выдал ошибку соединения с устройством. Однако девайс по-прежнему определяется нормально.
ahulap
Цитата(prottoss @ Jun 14 2007, 15:56) *
Всякие ФТДИ работают на FullSpeed, а программный AVR USB работает на LowSpeed: максимальный размер пакета 8 байт, минимальный период между кадрами - 10 милисекунд, вот и считайте, сколько можно передать байт в любую сторону.

Для данного драйвера 10мс - минимальный период опроса interrupt-in endpoint, для control transfer, который тут в основном используется, он не применим. А пакеты по 8 байт могут идти хоть друг за дружкой, правда в драйвере есть ограничение в 254 байта на одну передачу.
Вот пример: программатор USBasp считывает мегу32 за 4.6с, получается ~7к/с. Хотя тут завязана еще и передача по SPI, которая теоретически занимает ~3c. Так что чистая скорость точно не меньше smile.gif
GDI
Цитата
to GDI:
Посмотрел проект Power Switch. Ничего в нем нового не увидел. Только запись в EEPROM. Адрес они сами определили. Откуда они его взяли. Непонятно. И зачем писать в EEPROM - это же медленно. Да и циклы перезаписи не бесконечны.
В проекте PowerSwitch в файле
Код
main.c
есть функция
Код
usbFunctionSetup(uchar data[8])
в ней есть строки
Код
    if(data[1] == 4){       /* my function */
        //replyBuf[0] = 0xAA; //low
        //replyBuf[1] = 0x55; //high
          replyBuf[0]=vl[data[2]];
          replyBuf[1]=vh[data[2]];
        return 2;
, где vl, vh - это данные АЦП которые передаются в ПК.
Вот только PowerSwitch сделан НЕ НА HID, поэтому не знаю, заработает ли прямое копирование этого куска кода. Есть там еще проекты сделанные как HID - это HIDKeys и CDC они тоже предполагают передачу данных в ПК.
ahulap
Цитата(ZoonMan @ Jun 15 2007, 08:55) *
Посмотрел проект Power Switch. Ничего в нем нового не увидел. Только запись в EEPROM. Адрес они сами определили. Откуда они его взяли. Непонятно. И зачем писать в EEPROM - это же медленно. Да и циклы перезаписи не бесконечны.

Если брать самый простой вариант (без usbFunctionWrite и usbFunctionRead), то, например, в uchar usbFunctionSetup(uchar data[8]):
data[1] - код команды.
data[2]...data[5] - ее данные.
Так же есть какой-то static uchar replyBuffer[8]; , который заполняете необходимым ответом, ставите usbMsgPtr = replyBuffer; и возвращаете длину ответа.
Со стороны компьютера:
int usb_transmit(unsigned char functionid, unsigned char send[4], unsigned char * buffer, int buffersize)
{
int nbytes;
nbytes = usb_control_msg(usbhandle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
functionid,
(send[1] << 8) | send[0],
(send[3] << 8) | send[2],
buffer, buffersize,
5000);
if(nbytes < 0){
// Error
}

return nbytes;
}

Если надо передавать большие блоки, то посмотрите USBasp.
ZoonMan
Цитата(ahulap @ Jun 15 2007, 10:41) *
Если надо передавать большие блоки, то посмотрите USBasp.


Спасибо ahulap. Теперь хоть чуточку стало понятнее. Значит usbFunctionWrite, и usbFunctionRead не нужны. Да и обращения к ним не происходит.
А передавать большие блоки мне пока не надо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.