Страница 6 из 11
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 14:49:02
urry
Я ничего не понимаю в Бейсике, но хочу сказать, что vusb НЕ ЯВЛЯЕТСЯ стандатным HID .
Да, контроллер появляется в винде как хид - и на этом точка. И дело не в структуре репорта - без этой длл-ки libusb0.dll не инициализируется в принципе.
Это медленный и неправильный обмен. Советую сосредоточить усилия, раз так нравяться АВР, на тех, которые поддерживают USB.
К тому же внимательное чтение лицензии говорит, что с каждого изделия сколько-то центов должно идти автору программного обеспечения.
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 16:09:30
demson
vusb НЕ ЯВЛЯЕТСЯ стандатным HID .
а вот оно что...

тогда понятно почему оно не идет.
Значит будем мучать libusb0.dll
оттуда 4 функции надо взять.
- открыть устройство
чтение
запись
закрыть устройство
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 17:38:13
demson
позволю себе выделить эту ссылку отдельным постом
Итак есть проект бэйсик 6.0 на этой библиотеке
http://www.circuitsonline.net/forum/view/42808
там на 4 странице проект а на 1 все декларации всех функций
Ура с мертвой точки сдвинулись!
теперь задача найти наше устройство, там чета поменяли немного в отличае от си.
смотрим исходники.
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 19:40:35
PB_EXPERT
demson писал(а):
- открыть устройство
чтение
запись
закрыть устройство
Написал небольшую DLLку на
PureBasic 
для работы с HID устройствами. Может кому будет полезной.
Обозвал её
HID_Lib_PB.dll
Устройство открывается с помощью функции
Код: Выделить всё
Handle = HID_OpenDevice(PID, VID, VersionNumber, Index)
Чтение данных
Код: Выделить всё
CountReadBytes = HID_ReadDevice(Handle, *buffer, LenBuffer)
Запись данных
Код: Выделить всё
CountWriteBytes = HID_WriteDevice(Handle, *buffer, LenBuffer)
Закрытие устройства
Это далеко не все функции (их всего 14).
Полное описание функций есть в архиве.
DLLка имеет не большой размер, всего 10КБ и при этом вообще не использует никаких внешних файлов или библиотек, типа runtime или .NET
Используются только системные библиотеки с API функциями, типа "hid.dll", "setupapi.dll" и др.
Так что будет работать на любой винде, имеющей поддержку USB HID, т. е. начиная с Win 98.
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 21:23:39
demson
Однозначно будет полезной

ее и сделаем основе.
только не получается подключить.
код такой
Код: Выделить всё
Public Declare Function HID_OpenDevice Lib "HID_Lib_PB.dll" _
(ByVal PID As Integer, ByVal VID As Integer, ByVal VersionNumber As Integer, _
ByVal Index As Integer) As Integer
Код: Выделить всё
Dim vid As Integer = 5824
Dim pid As Integer = 1503
Dim ver As Integer = -1
Dim ind As Integer = 0
Dim Handle As Integer
Dim res
Handle = HID_OpenDevice(vid, pid, ver, ind)
Не удается загрузить DLL "HID_Lib_PB.dll": Не найден указанный модуль. (Исключение из HRESULT: 0x8007007E)
Лезет странная ошибка. Что бы это могло быть?
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 22:02:00
PB_EXPERT
demson писал(а):
Не удается загрузить DLL "HID_Lib_PB.dll": Не найден указанный модуль. (Исключение из HRESULT: 0x8007007E)
Лезет странная ошибка. Что бы это могло быть?
Сложно сказать.
Никогда с подобной ошибкой не сталкивался.
Может причина в том, что функции возвращают данные в переменных, типа Long.
Вот сделал небольшой пример использования этой DLLки.
Слеюущий код, работает с девайсом PicKit 2 (программатор для PICков).
После запуска проги, на секунду будет подано питание на программируемый PIC (загорится светодиод Target в PicKit 2, а затем погаснет).
После чего, прога завершает свою работу.
Код: Выделить всё
#USB_PID = $33 ; Идентификаторы PicKit 2
#USB_VID = $4D8
Lib=LoadLibrary_("HID_Lib_PB.dll")
If Lib=0
MessageRequester("PicKit 2 Test", "Нет HID_Lib_PB.dll!", 48)
End
EndIf
; Декларация функций HID_Lib_PB.dll
Prototype HID_OpenDevice(PID.w, VID.w, VersionNumber.w, Index.w)
Prototype HID_WriteDevice(Handle, *buffer, LenBuffer)
Prototype HID_CloseDevice(Handle)
HID_OpenDevice.HID_OpenDevice=GetProcAddress_(Lib, "HID_OpenDevice")
Global HID_WriteDevice.HID_WriteDevice=GetProcAddress_(Lib, "HID_WriteDevice")
HID_CloseDevice.HID_CloseDevice=GetProcAddress_(Lib, "HID_CloseDevice")
Procedure VddOn(Handle) ; Включить питание программируемого МК
Protected Dim OutBuffer.c(68)
OutBuffer(0)=0
OutBuffer(1)=$A6 ; EXECUTE_SCRIPT
OutBuffer(2)=2
OutBuffer(3)=$FC ; _VDD_GND_OFF
OutBuffer(4)=$FF ; _VDD_ON
ProcedureReturn HID_WriteDevice(Handle, @OutBuffer(), 65) ; Отсылаем данные девайсу PicKit 2
EndProcedure
Procedure VddOff(Handle) ; Выключить питание программируемого МК
Protected Dim OutBuffer.c(68)
OutBuffer(0)=0
OutBuffer(1)=$A6 ; EXECUTE_SCRIPT
OutBuffer(2)=2
OutBuffer(3)=$FE ; _VDD_OFF
OutBuffer(4)=$FD ; _VDD_GND_ON
ProcedureReturn HID_WriteDevice(Handle, @OutBuffer(), 65) ; Отсылаем данные девайсу PicKit 2
EndProcedure
Handle=HID_OpenDevice(#USB_PID, #USB_VID, -1, 0) ; Установка связи с PicKit 2
If Handle
VddOn(Handle) ; Включить питание
Delay(1000) ; Пауза 1 секунда
VddOff(Handle) ; Выключить питание
HID_CloseDevice(Handle) ; Разрыв связи с PicKit 2
Else
MessageRequester("PicKit 2 Test", "Нет связи с PicKit2!", 48)
EndIf
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 22:38:57
demson
Проверил на всякий случай с long. результат тот же.
Мне кажется несовместимость самой длл со студией 2008. Может попробовать пере собрать dll прямо на ней? Хотя там только просто вижуал бейсик. Не уверен что получится а если получится то поможет ли, но все таки возможно ли выложить исходники?
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 22:49:09
PB_EXPERT
Мне кажется несовместимость самой длл со студией 2008. Может попробовать пере собрать dll прямо на ней?
Студия PureBasic не поддерживает.
Это вообще продукт не майкрософт.
Может ошибка связанна с тем, что студия 2008 создаёт управляемый код под .NET, на эта DLLка - неуправляемый (native) код?
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 23:14:43
demson
Под .NET там просто все функции автоматом импортируются. Это не должно влиять, они прописаны вручную.
Сейчас еще на всякий на висте попробую, может винда(хп) косячит
Не удается загрузить DLL "HID_Lib_PB.dll": Не найден указанный модуль. (Исключение из HRESULT: 0x8007007E)
нет, систематический глюк какой то.
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Сб апр 17, 2010 23:26:54
demson
Проблема разрешилась. ура
в общем скопировал длл в систем32 и все. О как.
так, продолжаю с устройством.

Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 00:04:29
PB_EXPERT
demson писал(а):Проблема разрешилась. ура
в общем скопировал длл в систем32 и все. О как.
так, продолжаю с устройством.

У меня прекрасно работает когда DLLка находиться в одной папке с программой.
Правда я использую динамическую загрузку с помощью API
LoadLibrary либо встроенной функции
OpenLibrary.
Статическую линковку как правило не использую.
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 00:30:09
demson
В общем устройство отлично открывается. это радует
дальше пытаюсь считать данные и на HID_ReadDevice и на функции прога виснет.
проект hid-data считываю 128 символов с устройства.
пример кода хоста
Код: Выделить всё
usbDevice_t *dev;
char buffer[129]; /* room for dummy report ID */ 128 с нулем
int err;
if(argc < 2){
usage(argv[0]);
exit(1);
}
if((dev = openDevice()) == NULL)
exit(1);
if(strcasecmp(argv[1], "read") == 0){
int len = sizeof(buffer);
if((err = usbhidGetReport(dev, 0, buffer, &len)) != 0){
fprintf(stderr, "error reading data: %s\n", usbErrorMessage(err));
}else{
hexdump(buffer + 1, sizeof(buffer) - 1);
}
}else if(strcasecmp(argv[1], "write") == 0){
int i, pos;
bzero(buffer, sizeof(buffer));
for(pos = 1, i = 2; i < argc && pos < sizeof(buffer); i++){
pos += hexread(buffer + pos, argv[i], sizeof(buffer) - pos);
}
if((err = usbhidSetReport(dev, buffer, sizeof(buffer))) != 0) /* add a dummy report ID */
fprintf(stderr, "error writing data: %s\n", usbErrorMessage(err));
}else{
usage(argv[0]);
exit(1);
}
usbhidCloseDevice(dev);
код устройства
Код: Выделить всё
/* usbFunctionRead() is called when the host requests a chunk of data from
* the device. For more information see the documentation in usbdrv/usbdrv.h.
*/
uchar usbFunctionRead(uchar *data, uchar len)
{
if(len > bytesRemaining)
len = bytesRemaining;
eeprom_read_block(data, (uchar *)0 + currentAddress, len);
currentAddress += len;
bytesRemaining -= len;
return len;
}
/* usbFunctionWrite() is called when the host sends a chunk of data to the
* device. For more information see the documentation in usbdrv/usbdrv.h.
*/
uchar usbFunctionWrite(uchar *data, uchar len)
{
if(bytesRemaining == 0)
return 1; /* end of transfer */
if(len > bytesRemaining)
len = bytesRemaining;
eeprom_write_block(data, (uchar *)0 + currentAddress, len);
currentAddress += len;
bytesRemaining -= len;
return bytesRemaining == 0; /* return 1 if this was the last chunk */
}
/* ------------------------------------------------------------------------- */
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* HID class request */
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
/* since we have only one report type, we can ignore the report-ID */
bytesRemaining = 128;
currentAddress = 0;
return USB_NO_MSG; /* use usbFunctionRead() to obtain data */
}else if(rq->bRequest == USBRQ_HID_SET_REPORT){
/* since we have only one report type, we can ignore the report-ID */
bytesRemaining = 128;
currentAddress = 0;
return USB_NO_MSG; /* use usbFunctionWrite() to receive data from host */
}
}else{
/* ignore vendor type requests, we don't use any */
}
return 0;
}
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 08:27:25
urry
А разве Вы теоретически можете прочитать 128 байт ? По-моему, это максимальная длина, включая служебную инфу - там байт 20.
Покажите репорт дескриптор.
У меня, например, под обмен шло 8 байт.
Код: Выделить всё
PROGMEM char usbHidReportDescriptor[22] = { /* USB report descriptor */
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8) -------------- вот они ----------------------
0x95, 0x01, // REPORT_COUNT (1)
0x09, 0x00, // USAGE (Undefined)
0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
0xc0 // END_COLLECTION
};
А вот они в файле usbdrv.c
/* --------------------------- Device Descriptor --------------------------- */
#if USB_CFG_DESCR_PROPS_DEVICE == 0
#undef USB_CFG_DESCR_PROPS_DEVICE
#define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice)
PROGMEM char usbDescriptorDevice[] = { /* USB device descriptor */
18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
USBDESCR_DEVICE, /* descriptor type */
0x10, 0x01, /* USB version supported */
USB_CFG_DEVICE_CLASS,
USB_CFG_DEVICE_SUBCLASS,
0, /* protocol */
8, /* max packet size */ ------и здесь ---------------------------
и, собственно, сами байты в usbdrv.h
--------------------------------------------
typedef struct usbRequest{
uchar bmRequestType; //1
uchar bRequest; //2
usbWord_t wValue; //3,4
usbWord_t wIndex; //5,6
usbWord_t wLength; //7,8
}usbRequest_t;
---------------------------------------------
Все 8 штук, обращаюсь при чтении и записи
un.dataBuffer - это мой массив обмена
-------------------------------------------------------------
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_VENDOR){
DBG1(0x50, &rq->bRequest, 1); /* debug output: print our request */ // прием
if(rq->bRequest == CUSTOM_RQ_SET_STATUS)
{
un.dataBuffer[0] = rq->wValue.bytes[0];
un.dataBuffer[1] = rq->wValue.bytes[1];
un.dataBuffer[2] = rq->wIndex.bytes[0];
un.dataBuffer[3] = rq->wIndex.bytes[1];
flag=1;
usbMsgPtr = un.dataBuffer; /* tell the driver which data to return */
return 4;
}else if(rq->bRequest == CUSTOM_RQ_GET_STATUS){
/* buffer must stay valid when usbFunctionSetup returns */
//dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0); // передача
// данные в буфере должны быть готовы
un.dataBuffer[0]=0x12;
un.dataBuffer[1]=0x34;
usbMsgPtr = un.dataBuffer; /* tell the driver which data to return */
return 2; /* tell the driver to send 1 byte */
}
}else{
/* calss requests USBRQ_HID_GET_REPORT and USBRQ_HID_SET_REPORT are
* not implemented since we never call them. The operating system
* won't call them either because our descriptor defines no meaning.
*/
}
return 0; /* default for not implemented requests: return no data back to host */
}
Т.е. как бы теоретически большой массив бьется на маленькие пакеты и передается последовательно, но пока с этим не заморачивайтесь, добейтесь обмена полный пакет за 1 раз.
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 11:48:39
demson
нет, библиотека насколько я понял не отрабатывает типы запросов.
if(rq->bRequest == CUSTOM_RQ_SET_STATUS){
Зато есть возможность использовать функцию uchar usbFunctionRead(uchar *data, uchar len)
сейчас попробую написать под эту функцию код
-
нет все также виснет, и на 8 байтах и на одном (функция 1 байт изменяет)
странно.
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 12:51:08
urry
Что Гита. что Зита... Длл на все идет одна и та же. Думаю, это какое-то внутреннее соглашение, междусобойчик какой-то. Если интересно, я могу проверить в железе еще и этот вид обмена - по эхоотражению, например.
Но не сейчас - сейчас жена самостоятельно ремонтирует сд-плейер (первый ремонт) и работать точно не даст.

Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 12:57:06
PB_EXPERT
дальше пытаюсь считать данные и на HID_ReadDevice и на функции прога виснет.
проект hid-data считываю 128 символов с устройства
Я же писал об этом
ВНИМАНИЕ! Программа "повиснет" в этой функции до тех пор, пока не будет принято указанное число байт. Поэтому её желательно вызывать в отдельном потоке.
Вот что по этому поводу пишет Агуров в книге "Практика программирования USB"
128 байт это много. при программной реализации USB, число байт находится в пределах 1...8
Кроме того, вполне возможно что данные передаются через FEATURE-репорт как в примере
urry
В этом случае, для обмена информацией следует использовать функции
HID_GetFeature и
HID_SetFeature
Но это лишь предположение, нужно на HID-репорт устройства посмотреть.
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 13:00:48
demson
urry: было бы замечательно
тогда скажи vid pid
что передавать и какой длины. Я тебе скомпилирую прогу хоста и с исходниками выложу.
тогда уже увидим в чем проблема.

PB_EXPERT: кидаю 2 файла посмотри пожалуйста.
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 13:04:46
PB_EXPERT
urry писал(а):
У меня, например, под обмен шло 8 байт.
Код: Выделить всё
PROGMEM char usbHidReportDescriptor[22] = { /* USB report descriptor */
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8) -------------- вот они ----------------------
0x95, 0x01, // REPORT_COUNT (1)
0x09, 0x00, // USAGE (Undefined)
0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
0xc0 // END_COLLECTION
};
.......
......
......
......
В Вашем примере, передаются и принимаются не 8 байт, а всего лишь один!
REPORT_SIZE - число бит в слове
REPORT_COUNT - чило слов
Т. е. это один байт!
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 13:12:21
PB_EXPERT
demson писал(а):кидаю 2 файла посмотри пожалуйста.
Используется FEATURE, поэтому для обмена инфой, нужно использовать функции
HID_GetFeature и HID_SetFeature
Действительно 128 байт
----------
Функции
HID_ReadDevice и
HID_WriteDevice нужно использовать, если HID репорт имеет примерно такой вид.
Код: Выделить всё
// HID дескриптор репорта
PROGMEM const char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] =
{
0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined Page 1)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x02, // COLLECTION (Logical)
0x85, 0x77, // REPORT_ID (0x77)
0x09, 0x01, // USAGE (Pointer)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x01, // USAGE (Pointer)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x08, // REPORT_COUNT (8)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0xc0 // END_COLLECTION
};
Здесь есть описание конечных точек INPUT и OUTPUT
Re: Простейший код HID. Везде только слова, мыши и джойстики
Добавлено: Вс апр 18, 2010 13:18:12
urry
PB_EXPERT писал(а):urry писал(а):
В Вашем примере, передаются и принимаются не 8 байт, а всего лишь один!
REPORT_SIZE - число бит в слове
REPORT_COUNT - чило слов
Т. е. это один байт!
Вы правы. И с чего оно работает, ума не приложу ....
