СПЕЦАМ по HID (USB)

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Открыл глаза
Аватара пользователя
Сообщения: 46
Зарегистрирован: Пт дек 25, 2009 12:29:51
Откуда: Н.Новгород

Сообщение RadioLab »

Всем МЯУ!!!

хотелось бы при помощи HID передать хосту данные размером 3200 байт!

как сконфигурировать дескриптор, и вообще возможно ли такое?

Код: Выделить всё

 PROGMEM char usbHidReportDescriptor[22] = {   
    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)   --- максимум 2 байта ?
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0xff,                    //   REPORT_COUNT (255)   --- это максимум
    0x09, 0x00,                    //   USAGE (Undefined)
    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)
    0xc0                           // END_COLLECTION
};
если REPORT_COUNT = 255 то передаю 255 байт а хотелось бы намного больше.

и что значит 0x75, 0x08, // REPORT_SIZE (8) ?
Контактная информация:
Реклама
Потрогал лапой паяльник
Сообщения: 331
Зарегистрирован: Вс мар 30, 2008 14:31:51

Сообщение PB_EXPERT »

RadioLab писал(а):хотелось бы при помощи HID передать хосту данные размером 3200 байт
В контроллере есть 7 КБ оперативки?
Почему бы не разбить данные на отдельные посылки, скажем, по 128 байт?
RadioLab писал(а):и что значит 0x75, 0x08, // REPORT_SIZE (8) ?
Размер пакета в битах, а REPORT_COUNT - число пакетов.
Размер пакета можно сделать большим, и таки добится этих 3200 байт.

Кстати, какой контроллер используете?
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 46
Зарегистрирован: Пт дек 25, 2009 12:29:51
Откуда: Н.Новгород

Сообщение RadioLab »

Почему бы не разбить данные на отдельные посылки, скажем, по 128 байт?
одним массивом проще обрабатывать. на 128 байт всё работает.
хорошо бы сконфигурировать дескриптор и больше ничего не трогать.
Размер пакета в битах, а REPORT_COUNT - число пакетов.
Размер пакета можно сделать большим, и таки добится этих 3200 байт.
размер пакета больше 8 байт не удаётся сделать, число пакетов больше 128 не удаётся сделать
как работать с болшим буфером?


процессор - мега8


для того чтобы отправлять кусками по 128 байт необходимо сконфигурировать дескриптор.
может кто подскажет каким образом и как готовить буфер обмена ...
Контактная информация:
Прорезались зубы
Сообщения: 231
Зарегистрирован: Пт ноя 16, 2007 13:52:44
Откуда: Рига, Латвия

Сообщение Pe3ucTop »

Должен вас огорчить :
HID использует Interrupt endpoint , а его размеры (пакета, данных) ограничиваются стандартом:

# The maximum data payload size for low-speed devices is 8 bytes.
# Maximum data payload size for full-speed devices is 64 bytes.
# Maximum data payload size for high-speed devices is 1024 bytes.

По поводу ограничения по числу пакетов ничего не скажу, надо смотреть..
По идее размер пакета не должен влиять на HID , но могу и ошибатся... Я бы посоветовал использовать железный USB нежели програмный..
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

А эти 3200 байт откуда берутся? Считывается "миллион" АЦП? Или температур? Или всё во внешнем EEPROM лежит? Ограничений нет. Иначе как бы у вас мышь или клавиатура работали бы...

Изображение

ftp://83.99.200.234/USB/HID_Development.pdf
Нельзя всё знать, достаточно понимать.
Реклама
Прорезались зубы
Сообщения: 231
Зарегистрирован: Пт ноя 16, 2007 13:52:44
Откуда: Рига, Латвия

Сообщение Pe3ucTop »

Интересную заметку нашел в Appl.manual:
Please note that the report length should be equal or less than the endpoint size. If the report is
bigger than the endpoint size you must send the report in several times.
А собственно размеры EP уже определяет стандарт USB...
Копать в сторону посылки Reporta несколькими пакетами.
Ну или если устройство позволяет - увеличивать размер EP под размер репорта.

И добавка - вырезка из тандарта HID:
5.6 Reports
Using USB terminology, a device may send or receive a transaction every USB
frame (1 millisecond). A transaction may be made up of multiple packets (token,
data, handshake) but is limited in size to 8 bytes for low-speed devices and 64
bytes for high-speed devices. A transfer is one or more transactions creating a set
of data that is meaningful to the device—for example, Input, Output, and
Feature reports. In this document, a transfer is synonymous with a report.
Хотя в подведении итогов по протоколу пишут:
8.4 Report Constraints
The following constraints apply to reports and to the report handler:
- An item field cannot span more than 4 bytes in a report. For example, a 32-bit
item must start on a byte boundary to satisfy this condition.
- Only one report is allowed in a single USB transfer.
- A report might span one or more USB transactions. For example, an
application that has 10-byte reports will span at least two USB transactions in
a low-speed device.
- All reports except the longest which exceed wMaxPacketSize for the endpoint
must terminate with a short packet. The longest report does not require a short
packet terminator.
- Each top level collection must be an application collection and reports may not
span more than one top level collection.
- If there are multiple reports in a top level collection then all reports, except the
longest, must terminate with a short packet.
- A report is always byte-aligned. If required, reports are padded with bits (0)
until the next byte boundary is reached.
Отчет может быть послан за одну или более USB transaction, но нигде не написано как разделять по транзакциям.
Хотя я предпологаю что имеется в виду глобальный "Report" который в свою очередь разбивается на "report count / report size / ..."
Реклама
Потрогал лапой паяльник
Сообщения: 331
Зарегистрирован: Вс мар 30, 2008 14:31:51

Сообщение PB_EXPERT »

mr_smit, это касается только дополнительных конечных точек, с которыми хост работает по прерываниям.
Но это не касается управляющей нулевой конечной точки, через которую проходят FEATURE посылки.
Вымогатель припоя
Аватара пользователя
Сообщения: 534
Зарегистрирован: Пн янв 16, 2006 08:00:17
Откуда: Иркутск

Сообщение Mamonth »

Разбивайте пакет на несколько и так их передавайте. В AVR USB потребляется достаточно много ресурсов и хоть и позволяет система еще вкручивать Ваш код - делать это надо осторожно.
Today fine night...
Открыл глаза
Аватара пользователя
Сообщения: 46
Зарегистрирован: Пт дек 25, 2009 12:29:51
Откуда: Н.Новгород

Сообщение RadioLab »

Ну что же, всем спасибо за ответы, но вопрос пока остаётся открыт.

мне удалось пока передать за одну трансакцию буфер размером в 254 байта, но этого мало.

итак, существует 2 варианта решения (передача массива большого объёма):

1. передать весь массив за одну трансакцию, установив в дескрипторе

а.

Код: Выделить всё

0x96, 0x80, 0х0С                  //   REPORT_COUNT (3200)   
б. изменив размер репорта
в. установив значение bytesRemaining

Код: Выделить всё

usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t    *rq = (void *)data;

    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    // запрос HID class 
        if(rq->bRequest == USBRQ_HID_GET_REPORT){  // wValue: ReportType (highbyte), ReportID (lowbyte) 
            // поскольку мы имеем только один тип репорта, мы можем игнорировать репорт-ID 
            bytesRemaining = 3200;
            currentAddress = 0;
            return USB_NO_MSG;  // использование usbFunctionRead() для получения данных хостом от устройства 
        }else if(rq->bRequest == USBRQ_HID_SET_REPORT){
            // поскольку мы имеем только один тип репорта, мы можем игнорировать репорт-ID 
            bytesRemaining = 3200;
            currentAddress = 0;
            return USB_NO_MSG;  // use usbFunctionWrite() для получения данных устройством от хоста 
        }
    }else{
        // игнорируем запросы типа вендора, мы их все равно не используем 
    }
    return 0;
}

г. установить в usbconfig

Код: Выделить всё

#define USB_CFG_LONG_TRANSFERS          1


но что-то ещё не хватает... быть может ещё какая переменная типа char?????!

____________________________________

2. разбить передаваемый массив на N частей по 254 байт.

для этого необходимо задать Report_ID ?

а как это сделать?

как правильно добавить в репорт строчку?
куда её вставить?

Код: Выделить всё

 0х85, 0х19    // Report_ID (25) 


как обрабатывать Report_ID в firmware и в Delphi? может у кого нибудь есть пример?

за ранее благодарен.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3385
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

RadioLab писал(а):2. разбить передаваемый массив на N частей по 254 байт.

для этого необходимо задать Report_ID ?
Зачем?
RadioLab писал(а):как правильно добавить в репорт строчку?
куда её вставить?
Эту строку нужно добавить в HID дескриптор репорта - в код из первого поста этой темы, не забыв прибавить 2 к размеру массива.
RadioLab писал(а):но что-то ещё не хватает
Оперативной памяти скорее всего.
У использованого контроллера есть больше 4 КБ памяти? А иначе куда будут записыватся данные?
RadioLab писал(а):как обрабатывать Report_ID в firmware и в Delphi? может у кого нибудь есть пример?
Незнаю как в дельфи, но в PureBasic, Report_ID задается так:

Код: Выделить всё

Out(0) = 25      ; Report_ID 
Out(1) = Command ; Передаваемые данные
HID_Lib_WriteDevice(HID_Handle, @Out(), 2) ; Передача 2 байт в USB устройство
В дельфи наверное аналогично.
Открыл глаза
Аватара пользователя
Сообщения: 46
Зарегистрирован: Пт дек 25, 2009 12:29:51
Откуда: Н.Новгород

Сообщение RadioLab »

2. разбить передаваемый массив на N частей по 254 байт.

для этого необходимо задать Report_ID ?
Зачем?
Мурик, я рассуждаю так:

мне нужно передать массив данных более 254 байт. Раз не могу его передать за 1 трансакцию, то разбиваю на N частей по 254 байт и передаю N раз. N задаётся в Report_ID. Или я ошибаюсь?

Оперативной памяти скорее всего.
У использованого контроллера есть больше 4 КБ памяти? А иначе куда будут записыватся данные?
:) конечно нет. Данные хранятся во внешней eepromке

Out(0) = 25 ; Report_ID
ну хорошо, в delphi data[0] являетcя Report_ID, а как на стороне микропроцессора?
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3385
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

RadioLab писал(а):конечно нет. Данные хранятся во внешней eepromке
Причем тут eeprom?
Для приема 3200 байт за одну посылку, нужен такой же размер буфера в оперативной памяти, куда будут записыватся данные, принятые через USB.
Для передачи нужето такой же буфер!
Это значит что только для USB буферов понадобится 3200*2 = 6400 байт оперативной памяти контроллера!
Я сомневаюсь что используемый контроллер обладает таким размером ОЗУ.
Открыл глаза
Аватара пользователя
Сообщения: 46
Зарегистрирован: Пт дек 25, 2009 12:29:51
Откуда: Н.Новгород

Сообщение RadioLab »

нет Мурик, вы ошибаетесь.. передача ведётся побайтно!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3385
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

RadioLab писал(а):передача ведётся побайтно!
нет Мурик, вы ошибаетесь.. передача ведётся побайтно!
То есть вы хотите сказать что HID дескриптор имеет вид

Код: Выделить всё

PROGMEM char usbHidReportDescriptor[22] = {   
    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)   --- максимум 2 байта ?
    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
};
Открыл глаза
Аватара пользователя
Сообщения: 46
Зарегистрирован: Пт дек 25, 2009 12:29:51
Откуда: Н.Новгород

Сообщение RadioLab »

REPORT_COUNT (xx) , xx - кол. байт для передачи.

информация передаётся пакетами по 8 байт. Получив эти 8 байт делаешь с ними что душе угодно.
потом принимаешь следующие 8 байт, и т.д.
Контактная информация:
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»