Jump to content

    

Обмен данными через USB

Собрал USB устройство, похожее на Automator (http://www.obdev.at/products/avrusb/).

Залил в него немного откорректированую прошивку Automator'а.

Все работает нормально. Устройство определяется как положено. Отвечает на обращение к нему.

Помогите осуществить обмен данными.

 

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

 

Со стороны ПК терминал я написал (в проекте есть программа, я ее перенес на C++Builder) и он даже считывает область памяти из контроллера.

Только вот куда обращаться из прошивки, чтобы передавать информацию для видения терминалом не пойму.

Share this post


Link to post
Share on other sites

Может стоит посмотреть как это сделано в проекте POWERSWITCH (http://www.obdev.at/products/avrusb/powerswitch.html) он передает в ПК данные о напряжении, а заодно в этом проекте находится последняя версия usb драйвера.

Share this post


Link to post
Share on other sites
Собрал USB устройство, похожее на Automator (http://www.obdev.at/products/avrusb/).

Залил в него немного откорректированую прошивку Automator'а.

Все работает нормально. Устройство определяется как положено. Отвечает на обращение к нему.

Помогите осуществить обмен данными.

 

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

 

Со стороны ПК терминал я написал (в проекте есть программа, я ее перенес на C++Builder) и он даже считывает область памяти из контроллера.

Только вот куда обращаться из прошивки, чтобы передавать информацию для видения терминалом не пойму.

К usbTxBuf лезть нельзя ни в коем случае - это системная переменная драйвера. В ней хранятся данные для отправляемого драйвером пакета.

 

 

 

Я не вникал в код Atomator-a но, обычно общение происходит посредством функции usbFunctionRead и usbFunctionWrite, хотя, возможно я и ошибаюсь. Тем не менее, попробуйте скачать другие проекты, проще будет разобраться. А еще лучше взять самый простой из них, и начать с него, чтобы понять хотя бы основные принципы. По крайней мере я начинал так...

Share this post


Link to post
Share on other sites

А какую максимальную скорость можно получить при передаче из компа в устройство?

Share this post


Link to post
Share on other sites
А какую максимальную скорость можно получить при передаче из компа в устройство?
теоретически 800 байт пер сек:)

Share this post


Link to post
Share on other sites

Да уж... А как тогда всякие FTDI работают нормально? Понятно, что там не HID, но нельзя ли на AVR сделать аналог USB1.0<->UART и чтобы это было быстрее чем 115200 б.п.с.?

Share this post


Link to post
Share on other sites
Да уж... А как тогда всякие FTDI работают нормально? Понятно, что там не HID, но нельзя ли на AVR сделать аналог USB1.0<->UART и чтобы это было быстрее чем 115200 б.п.с.?
Всякие ФТДИ работают на FullSpeed, а программный AVR USB работает на LowSpeed: максимальный размер пакета 8 байт, минимальный период между кадрами - 10 милисекунд, вот и считайте, сколько можно передать байт в любую сторону.

 

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

Share this post


Link to post
Share on other sites
про премудрости USB, фактически, можно забыть.

Может и можно, зато потом можно будет неоднократно испытать превеликое удивление :biggrin:

Share this post


Link to post
Share on other sites

to GDI:

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

 

to prottoss:

попробовал usbFunctionWrite(). Ни к чему хорошему это ни привело. Терминал отказался читать блоки. Выдал ошибку соединения с устройством. Однако девайс по-прежнему определяется нормально.

Share this post


Link to post
Share on other sites
Всякие ФТДИ работают на FullSpeed, а программный AVR USB работает на LowSpeed: максимальный размер пакета 8 байт, минимальный период между кадрами - 10 милисекунд, вот и считайте, сколько можно передать байт в любую сторону.

Для данного драйвера 10мс - минимальный период опроса interrupt-in endpoint, для control transfer, который тут в основном используется, он не применим. А пакеты по 8 байт могут идти хоть друг за дружкой, правда в драйвере есть ограничение в 254 байта на одну передачу.

Вот пример: программатор USBasp считывает мегу32 за 4.6с, получается ~7к/с. Хотя тут завязана еще и передача по SPI, которая теоретически занимает ~3c. Так что чистая скорость точно не меньше :)

Share this post


Link to post
Share on other sites
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 они тоже предполагают передачу данных в ПК.

Share this post


Link to post
Share on other sites
Посмотрел проект 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.

Share this post


Link to post
Share on other sites
Если надо передавать большие блоки, то посмотрите USBasp.

 

Спасибо ahulap. Теперь хоть чуточку стало понятнее. Значит usbFunctionWrite, и usbFunctionRead не нужны. Да и обращения к ним не происходит.

А передавать большие блоки мне пока не надо.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this