Господа, помогите организовать обмен данными между USB устройством и программой хостом.
За основу взят пример от ST - "Custom HID" для IAR. Контроллер STM32F103RBT6
К нему прилагается программа для компа - "HID Demonstrator", в программе жмешь кнопки, на устройстве загораются светодиоды.
Хочу ее модифицировать, дабы передавать данные. НАшел в интернете пример для C++ Builder который позволяет принимать и отправлять пакеты, тоже его модифицировал
С программой HID Demonstrator управлять светодиодами получается. А вот с собственной не получается передать и двух байт.
Подскажите, чего не хвататет в программе.
ЛИчно мне непонятно, где в программе-хосте указание писать в конкретный ендпоинт...
Итак ближе к делу. ПРограмма для STM32F103:
CODE
#include "stm32f10x.h"
#include "usb_lib.h"
#include "hw_config.h"
#include "common.h"
#include "stdio.h"
#define nReportCnt 22
unsigned char str[10];
extern unsigned char Receive_Buffer[2];
extern unsigned char Transi_Buffer[2];
extern u8 USB_ReceiveFlg;
extern u8 TimeCount;
//*******************************************************************************/
int main(void)
{
Set_System();
USB_Interrupts_Config();
// Включаем подтяжку для USB
RCC->APB2ENR |= (1 << 5); // enable clock for GPIOD
GPIOD->CRL &= ~0x00000F00; // clear port PD2
GPIOD->CRL |= 0x00000700; // PD2 General purpose output open-drain, max speed 50 MHz
GPIOD->BRR = 0x0004; // reset PD2 (set to low)
// Настраиваем светодиоды
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;//Затактировали порт
GPIOA->CRL &= ~GPIO_CRL_CNF2;//определили режим работы.
GPIOA->CRL |= GPIO_CRL_MODE2_0;//определили направление.
GPIOA->CRL &= ~GPIO_CRL_CNF3;//определили режим работы.
GPIOA->CRL |= GPIO_CRL_MODE3_0;//определили направление.
Set_USBClock();
USB_Init();
LCD_Init();
LCD_Clear(RED);
while (1)
{
if (USB_ReceiveFlg == TRUE) // Проверяем, не поймала ли чего void EP1_OUT_Callback(void) (прописана в USB_ENDP.C)
{
// Если поймала - рисуем на экране
sprintf(str,"Recieved byte: %X ", Receive_Buffer[0]);
WriteString(0,240,str,BLUE);
USB_ReceiveFlg=0;//СБРАСЫВАЕМ ФЛАЖОК
Delay(5000000);
LCD_Clear(RED); //
}
}
}
Вот как устроен обработчик обращений к Endpoint
CODE
void EP1_OUT_Callback(void)
{
BitAction Led_State;
/* Read recieved data (2 bytes) */
USB_SIL_Read(EP1_OUT, Receive_Buffer);
USB_ReceiveFlg=1; //установка этого флажка призвана обеспечить реакцию дисплея если с хоста прийдет хоть что-нибудь.
// при дрыганьи светодиодами через HID Demonstrator флажок устанавливается, сообщения идут
// При использовании моей программы под C++ Builder - ноль реакции
//Ниже - это работа со светодиодами. Пока не удалял, помогает хоть как-то сориентироваться.
if (Receive_Buffer[1] == 0)
{
Led_State = Bit_RESET;
GPIOA->BSRR =GPIO_BSRR_BR3;
}
else
{
Led_State = Bit_SET;
GPIOA->BSRR =GPIO_BSRR_BS3;
}
switch (Receive_Buffer[0])
{
case 1:
if (Led_State != Bit_RESET)
{
STM_EVAL_LEDOn(LED1);
GPIOA->BSRR =GPIO_BSRR_BS2;
}
else
{
STM_EVAL_LEDOff(LED1);
GPIOA->BSRR =GPIO_BSRR_BR2;
}
break;
case 2:
if (Led_State != Bit_RESET)
{
STM_EVAL_LEDOn(LED2);
GPIOA->BSRR =GPIO_BSRR_BS2;
}
else
{
STM_EVAL_LEDOff(LED2);
GPIOA->BSRR =GPIO_BSRR_BR2;
}
break;
case 3:
if (Led_State != Bit_RESET)
{
STM_EVAL_LEDOn(LED3);
GPIOA->BSRR =GPIO_BSRR_BS2;
}
else
{
STM_EVAL_LEDOff(LED3);
GPIOA->BSRR =GPIO_BSRR_BR2;
}
break;
case 4:
if (Led_State != Bit_RESET)
{
STM_EVAL_LEDOn(LED4);
GPIOA->BSRR =GPIO_BSRR_BS2;
}
else
{
STM_EVAL_LEDOff(LED4);
GPIOA->BSRR =GPIO_BSRR_BR2;
}
break;
case 5:
if (Led_State != Bit_RESET)
{
STM_EVAL_LEDOn(LED4);
GPIOA->BSRR =GPIO_BSRR_BS2;
}
else
{
STM_EVAL_LEDOff(LED4);
GPIOA->BSRR =GPIO_BSRR_BR2;
}
break;
default:
STM_EVAL_LEDOff(LED1);
STM_EVAL_LEDOff(LED2);
STM_EVAL_LEDOff(LED3);
STM_EVAL_LEDOff(LED4);
break;
}
#ifndef STM32F10X_CL
SetEPRxStatus(ENDP1, EP_RX_VALID);
#endif /* STM32F10X_CL */
}
Вот дескрипторы программы для STM32
CODE
/* USB Standard Device Descriptor */
const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] =
{
0x12, /*bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
0x00, /*bcdUSB */
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
0x40, /*bMaxPacketSize40*/
0x83, /*idVendor (0x0483)*/
0x04,
0x50, /*idProduct = 0x5750*/
0x57,
0x00, /*bcdDevice rel. 2.00*/
0x02,
1, /*Index of string descriptor describing
manufacturer */
2, /*Index of string descriptor describing
product*/
3, /*Index of string descriptor describing the
device serial number */
0x01 /*bNumConfigurations*/
}
; /* CustomHID_DeviceDescriptor */
/* USB Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
{
0x09, /* bLength: Configuation Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
CUSTOMHID_SIZ_CONFIG_DESC,
/* wTotalLength: Bytes returned */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing
the configuration*/
0xC0, /* bmAttributes: Bus powered */
0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */
/************** Descriptor of Custom HID interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Custom HID HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
0x10, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Custom HID endpoints ******************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
0x81, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
0x08, /* wMaxPacketSize: 8 Bytes max */
0x00,
0x20, /* bInterval: Polling Interval (32 ms) */
/* 34 */
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
/* Endpoint descriptor type */
0x01, /* bEndpointAddress: */
/* Endpoint Address (OUT) */
0x03, /* bmAttributes: Interrupt endpoint */
0x08, /* wMaxPacketSize: 8 Bytes max */
0x00,
0x20, /* bInterval: Polling Interval (20 ms) */
/* 41 */
}
; /* CustomHID_ConfigDescriptor */
const uint8_t CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{
0x05, 0x8c, /* USAGE_PAGE (ST Page) */
0x09, 0x01, /* USAGE (Demo Kit) */
0xa1, 0x01, /* COLLECTION (Application) */
/* 6 */
/* Led 1 */
0x85, 0x01, /* REPORT_ID (1) */
0x09, 0x01, /* USAGE (LED 1) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x95, 0x01, /* REPORT_COUNT (1) */
0xB1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
0x85, 0x01, /* REPORT_ID (1) */
0x09, 0x01, /* USAGE (LED 1) */
0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */
/* 26 */
/* Led 2 */
0x85, 0x02, /* REPORT_ID 2 */
0x09, 0x02, /* USAGE (LED 2) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x95, 0x01, /* REPORT_COUNT (1) */
0xB1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
0x85, 0x02, /* REPORT_ID (2) */
0x09, 0x02, /* USAGE (LED 2) */
0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */
/* 46 */
/* Led 3 */
0x85, 0x03, /* REPORT_ID (3) */
0x09, 0x03, /* USAGE (LED 3) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x95, 0x01, /* REPORT_COUNT (1) */
0xB1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
0x85, 0x03, /* REPORT_ID (3) */
0x09, 0x03, /* USAGE (LED 3) */
0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */
/* 66 */
/* Led 4 */
0x85, 0x09, /* REPORT_ID 4) */
0x09, 0x09, /* USAGE (LED 4) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x95, 0x01, /* REPORT_COUNT (1) */
0xB1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
0x85, 0x09, /* REPORT_ID (4) */
0x09, 0x09, /* USAGE (LED 4) */
0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */
/* 86 */
/* key Push Button */
0x85, 0x05, /* REPORT_ID (5) */
0x09, 0x05, /* USAGE (Push Button) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x81, 0x82, /* INPUT (Data,Var,Abs,Vol) */
0x09, 0x05, /* USAGE (Push Button) */
0x75, 0x01, /* REPORT_SIZE (1) */
0xb1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
0x75, 0x07, /* REPORT_SIZE (7) */
0x81, 0x83, /* INPUT (Cnst,Var,Abs,Vol) */
0x85, 0x05, /* REPORT_ID (2) */
0x75, 0x07, /* REPORT_SIZE (7) */
0xb1, 0x83, /* FEATURE (Cnst,Var,Abs,Vol) */
/* 114 */
/* Tamper Push Button */
0x85, 0x06, /* REPORT_ID (6) */
0x09, 0x06, /* USAGE (Tamper Push Button) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x81, 0x82, /* INPUT (Data,Var,Abs,Vol) */
0x09, 0x06, /* USAGE (Tamper Push Button) */
0x75, 0x01, /* REPORT_SIZE (1) */
0xb1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
0x75, 0x07, /* REPORT_SIZE (7) */
0x81, 0x83, /* INPUT (Cnst,Var,Abs,Vol) */
0x85, 0x06, /* REPORT_ID (6) */
0x75, 0x07, /* REPORT_SIZE (7) */
0xb1, 0x83, /* FEATURE (Cnst,Var,Abs,Vol) */
/* 142 */
/* ADC IN */
0x85, 0x07, /* REPORT_ID (7) */
0x09, 0x07, /* USAGE (ADC IN) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x26, 0xff, 0x00, /* LOGICAL_MAXIMUM (255) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x81, 0x82, /* INPUT (Data,Var,Abs,Vol) */
0x85, 0x07, /* REPORT_ID (7) */
0x09, 0x07, /* USAGE (ADC in) */
0xb1, 0x82, /* FEATURE (Data,Var,Abs,Vol) */
/* 161 */
0xc0 /* END_COLLECTION */
}; /* CustomHID_ReportDescriptor */
/* USB String Descriptors (optional) */
const uint8_t CustomHID_StringLangID[CUSTOMHID_SIZ_STRING_LANGID] =
{
CUSTOMHID_SIZ_STRING_LANGID,
USB_STRING_DESCRIPTOR_TYPE,
0x09,
0x04
}
; /* LangID = 0x0409: U.S. English */
const uint8_t CustomHID_StringVendor[CUSTOMHID_SIZ_STRING_VENDOR] =
{
CUSTOMHID_SIZ_STRING_VENDOR, /* Size of Vendor string */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/
/* Manufacturer: "STMicroelectronics" */
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
'c', 0, 's', 0
};
const uint8_t CustomHID_StringProduct[CUSTOMHID_SIZ_STRING_PRODUCT] =
{
CUSTOMHID_SIZ_STRING_PRODUCT, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'C', 0,
'u', 0, 's', 0, 't', 0, 'm', 0, ' ', 0, 'H', 0, 'I', 0,
'D', 0
};
uint8_t CustomHID_StringSerial[CUSTOMHID_SIZ_STRING_SERIAL] =
{
CUSTOMHID_SIZ_STRING_SERIAL, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'S', 0, 'T', 0, 'M', 0,'3', 0,'2', 0, '1', 0, '0', 0
};
ТЕПЕРЬ К ХОСТУ. ВЫДЕРЖКИ ИЗ ПРОГРАММЫ ДЛЯ C++ Builder
Подключение. Сразу скажу - все работает, дескриптор читается, ошибок нет
CODE
int connect() // этой функцией будем подключаться к устройству
{
int i, n, res=0;
string exampleDeviceName = "";
string temp;
// exampleDeviceName += vendorName;
// exampleDeviceName += " ";
// exampleDeviceName += productName;
exampleDeviceName = "STMicroelectronics STM32 Custm HID";
n = hid.EnumerateHIDDevices(); // узнаем все Hid устройства
// vid и pid указаны в hidlibrary.h константой idstring
for (i=0; i<n; i++) // ищем среди них наше
{
hid.Connect(i);
temp=+"Подключено "+hid.GetConnectedDeviceName();
Form1->Memo1->Lines->Add(temp.c_str());
// GetConnectedDeviceName() возвращает string,
// где через пробел указаны vendor и product Name.
// Сравниваем, если совпало - значить устройство наше
if (hid.GetConnectedDeviceName() == exampleDeviceName )
{
res = 1;
break;
}
}
return res;
}
ОБработчик кнопки "Отправить данные" - на STM32 - никакой реакции
CODE
// Кнопка "Отправить данные"
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if ( 1 == connect() )
{
pdata.b0 = 0x00;
pdata.b1 = 0x00;
ShowMessage("OK");
hid.SendData(&pdata);
}
else
{
AnsiString s = "";
s += vendorName;
s += " ";
s += productName;
s += " не подключено.";
ShowMessage(s);
}
}
//---------------------------------------------------------------------------
Файл дескриптора. Я не знаю, странный он какой-то, писался для общения с AVR, тем не менее привожу как есть, он был в проекте для Builder C++
CODE
#ifndef __usbconfig_h_included__
#define __usbconfig_h_included__
/* Основное описание:
* Этот файл является примером конфигурации (со встроенной документацией) для
* драйвера USB. Он кофигурирует V-USB для сигнала USB D+, подсоединенного к
* порту D бит 2 (который также является входом аппаратного прерывания 0 [INT0]
* на многих чипах) и сигнала USB D- к порту D бит 4. Вы можете подсоединить
* эти сигналы на любой другой порт, однако D+ должен быть также подключен на
* вход аппаратного прерывания INT0, которое имеет наивысший приоритет,
* см. секцию в конце файла).
*/
/* ------------------------- Аппаратные настройки -------------------------- */
#define USB_CFG_IOPORTNAME D
/* Указан порт, к которому подключена шина USB. Если Вы сконфигурируете "B",
* будут использоваться регистры PORTB, PINB и DDRB.
*/
#define USB_CFG_DMINUS_BIT 4
/* Это номер бита в USB_CFG_IOPORT, куда подключен сигнал D-, может
* использоваться любой бит в порте.
*/
#define USB_CFG_DPLUS_BIT 2
/* Это номер бита в USB_CFG_IOPORTNAME, куда подключен сигнал D+, может
* использоваться любой бит в порте. Пожалуйста, примите во внимание, что D+
* должен быть также подсоединен к ножке прерывания INT0! [Вы можете также
* использовать другие прерывания, см. секцию "Optional MCU Description" далее,
* или Вы можете подсоединить D- к прерыванию, как это необходимо если Вы
* используете опцию USB_COUNT_SOF. Если Вы используете D- для прерывания,
* оно будет срабатывать также от маркеров Start-Of-Frame каждую
* милисекунду.]
*/
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
/* Тактовая частота чипа AVR в килогерцах. Допустимые величины 12000, 15000,
* 16000, 16500 и 20000. Версия кода на 16.5 МГц не требует кварца, она
* допускает уход частоты +/- 1% от номинальной. Все другие частоты требуют
* точности 2000 ppm, и в этом случае обязательно нужен кварц!
* Константа F_CPU должна быть определена в проекте, не нужно нигде писать
* вручную.
*/
#define USB_CFG_CHECK_CRC 0
/* Установите 1 если хотите чтобы драйвер V-USB проверял целостность входящих
* пакетов данных (CRC сумы). Проверка CRC требует достаточно много места для
* кода и на данный момент поддерживается только для частоты 18 MHz. Так что
* обязательно используйте частоту 18 MHz для включения этой опции.
*/
/* ----------------- Дополнительные Аппаратные настройки ------------------- */
/* #define USB_CFG_PULLUP_IOPORTNAME D */
/* Если Вы подсоединили 1.5k pullup резистор от D- к ножке порта вместо V+,
* Вы можете подсоединять и отсоединять устройство програмным путем вызовая
* макрос usbDeviceConnect() и usbDeviceDisconnect() (см. usbdrv.h).
* Эта константы задают порт, к которому подключен pullup резистор.
*/
/* #define USB_CFG_PULLUP_BIT 4 */
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
* above) where the 1.5k pullup resistor is connected. See description
* above for details.
* Эта константа определяет номер бита порта в USB_CFG_PULLUP_IOPORTNAME (задан
* више) куда подключен 1.5k pullup резистор. См. описание, указанное ранее.
*/
/* ----------------------- Функциональный диапазон ------------------------- */
#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
/* Задайте здесь 1, если Вы хотите скомпилировать версию с двумя конечными
* точками (endpoints): default control endpoint 0 и interrupt-in endpoint
* (любой другой endpoint номер).
*/
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
/* Задайте здесь 1, если Вы хотите скомпилировать версию с тремя конечными
* точками (endpoints): default control endpoint 0, interrupt-in endpoint 3
* (или номер, сконфигурированный далее) и catch-all default interrupt-in
* endpoint как указано ранее.
* Вы должны также задать USB_CFG_HAVE_INTRIN_ENDPOINT в 1 для этой опции.
*/
#define USB_CFG_EP3_NUMBER 3
/* Если так называемая конечная точка (endpoint) 3 используется, можно теперь
* ее сконфигурировать на любой другой номер конечной точки (за исключением 0).
* Если не задано, то по умолчанию 3.
*/
/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
/* Этот define определяет условие старта (startup condition) для переключения
* данных (data toggling) в момент конечных точек interrupt/bulk 1 и 3.
* По умолчанию USBPID_DATA1. Поскольку токен переключается ПЕРЕД отправкой
* любых данных, первый пакет отправляется c противоположной величиной
* от этой конфигурации!
*/
#define USB_CFG_IMPLEMENT_HALT 0
/* Задайте здесь 1, если Вы хотите также реализовать возможность ENDPOINT_HALT
* для endpoint 1 (interrupt endpoint). Несмотря на то, что Вам эта возможность
* может не понадобиться, она требуется по стандарту. Мы ввели эту опцию в
* конфигурацию потому что эта функция значительно раздувает код.
*/
#define USB_CFG_SUPPRESS_INTR_CODE 0
/* Задайте здесь 1, если Вы хотите определить interrupt-in endpoints, но не
* хотите отправлять любые данные с их помощью. Если эта опция включена, то
* функции usbSetInterrupt() и usbSetInterrupt3() будут пропущены. Полезно
* при необходимости interrupt-in endpoints для соответсвия интерфейсу
* (например HID), но без отправки даных с их помощью. Прилично экономит
* флеш память для кода и оперативную память буффера передачи данных.
*/
#define USB_CFG_INTR_POLL_INTERVAL 100
/* Если Вы скомпилировали версию с endpoint 1 (interrupt-in), то здесь задается
* интервал опроса (poll interval). Величина указана в милисекундах и не должна
* быть меньше 10 ms для низкоскоростных устройств.
*/
#define USB_CFG_IS_SELF_POWERED 0
/* Задайте здесь 1 если устройство имеет собственный источник питания.
* Установка в 0 соответствует устройству, запитанному от шины USB.
*/
#define USB_CFG_MAX_BUS_POWER 100
/* Установите эту переменную на max величину потребления мощности Вашего
* устройства от шины USB. Величина указана в милиамперах.
*/
#define USB_CFG_IMPLEMENT_FN_WRITE 1
/* Задайте здесь 1, если Вы хотите, чтобы функция usbFunctionWrite()
* вызывалась для передач control-out. Задайте 0 если Вам это не нужно,
* что позволит сэкономить несколько байт.
*/
#define USB_CFG_IMPLEMENT_FN_READ 1
/* Задайте 1 если Вам нужно отправлять управляющие запросы ответы, которые
* генерируются "на лету" при вызове usbFunctionRead(). Если Вам нужно только
* отправить данные из статического буфера, задайте 0 и возвращайте данные из
* usbFunctionSetup(). Это сэкономит некоторое количество байт.
*/
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
/* Задайте 1 если Вы хотите использовать interrupt-out (или bulk out)
* endpoints. Вы должны реализовать функцию usbFunctionWriteOut(), которая
* принимает все interrupt/bulk данные, отправленные в любую endpoint,
* отличную от 0. Номер endpoint можно найти в 'usbRxToken'.
*/
#define USB_CFG_HAVE_FLOWCONTROL 0
/* Задайте 1, если Вы хотите реализовать управление потоком (flowcontrol)
* через данные USB. Смотрим описание макроса usbDisableAllRequests() и
* usbEnableAllRequests() в usbdrv.h.
*/
#define USB_CFG_DRIVER_FLASH_PAGE 0
/* Если устройство имеет больше чем 64 kBytes флеш памяти, определите это
* в 64 k страницу где находятся константы (дескрипторы) драйвера. Другими
* словами: установить в 1 для загрузчиков (boot loaders) на ATMega128.
*/
#define USB_CFG_LONG_TRANSFERS 0
/* Задайте 1, если Вы хотите отправлять/принимать блоки оазмером более 254 байт
* в одиночной control-in или control-out передаче. Обратите внимание, что эта
* возможность увеличивает размер драйвера.
*/
/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
/* Этот macro является крюком (hook), если Вы хотите сделать нечто
* нетрадиционное. Если макрос задан, он вставляется в начало обработки
* принимаемого сообщения. Если Вы "съели" (обработали) сообщение и не хотите
* включать дальнейшую обработку по умолчанию, сделайте обычный возврат после
* Ваших действий. Одно из возможных применений (кроме отладки) - мигание
* статусным светодиодом при каждом пакете.
*/
/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
/* Этот macro является хуком для обработки события USB RESET. Он имеет один
* параметр, позволяющий отличать старт состояния RESET от окончания
* состояния RESET.
*/
/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
/* Этот macro (если задан) выполняется когда принят запрос USB SET_ADDRESS.
*/
#define USB_COUNT_SOF 0
/* Задайте здесь 1, если Вам нужна глобальная переменная "usbSofCount",
* в которой подсчитываются пакеты SOF. Эта возможность требует подключения
* аппаратного прерывания к D- вместо D+.
*/
/* #ifdef __ASSEMBLER__
* macro myAssemblerMacro
* in YL, TCNT0
* sts timer0Snapshot, YL
* endm
* #endif
* #define USB_SOF_HOOK myAssemblerMacro
* This macro (if defined) is executed in the assembler module when a
* Start Of Frame condition is detected. It is recommended to define it to
* the name of an assembler macro which is defined here as well so that more
* than one assembler instruction can be used. The macro may use the register
* YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
* immediately after an SOF pulse may be lost and must be retried by the host.
* What can you do with this hook? Since the SOF signal occurs exactly every
* 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
* designs running on the internal RC oscillator.
* Please note that Start Of Frame detection works only if D- is wired to the
* interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
*/
#define USB_CFG_CHECK_DATA_TOGGLING 0
/* Установите в 1 если хотите фильтровать повторяющиеся (duplicate) пакеты
* данных отправленные хостом. Повторения возникают лишь в результате ошибок
* связи, когда хост не получил ACK. Помните, фильтровать придется самим у
* usbFunctionWriteOut() и usbFunctionWrite(). Используйте глобальную
* usbCurrentDataToken и статическую переменную для каждого
* control- и out-endpoint для проверки на повторяющиеся пакеты.
*/
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
/* Задайте здесь 1, если Вам нужна функция usbMeasureFrameLength() - тогда она
* скомпилируется. Эта функция может использоваться для подстройки генератора
* RC микроконтроллера AVR.
*/
#define USB_USE_FAST_CRC 0
/* Ассемблерная часть имеет две реализации для алгоритма CRC. Одна быстрее,
* вторая меньшая по объему. Используйте меньшую лишь в передачах сообщений
* не критичных к таймингам. Быстрая реализация требует 31 цикл на байт, а
* меньшая требует 61 - 69 циклов. Быстрая реализация может быть на 32 байта
* кода большей при передачах данных и выводит AVR на состояние близкое к
* пределу возможностей.
*/
/* ---------------- Параметры, описывающие USB-устройство ------------------ */
#define USB_CFG_VENDOR_ID 0x83, 0x04 /* 0483 = voti.nl */
/* USB вендор ID для устройства, младший байт идет первым. Если Вы
* зарегистрировали свой собственный Vendor ID, укажите его здесь. В
* противном случае используйте одну из свободно предоставляемых пар
* VID/PID obdev. Прочитайте правила USB-IDs-for-free.txt!
*/
#define USB_CFG_DEVICE_ID 0x50, 0x57 /* obdev's shared PID for HIDs */
/* Это ID продукта, младший байт идет первым. Он интерпретируется в контексте
* vendor ID. Если Вы зарегистрировали свой собственный VID на usb.org, или
* если пользуетесь лицензией на PID от кого-нибудь еще, укажите его здесь.
* Иначе используйте предоставленную obdev свободно распространяемую
* пару VID/PID. Прочитайте правила USB-IDs-for-free.txt!
*/
#define USB_CFG_DEVICE_VERSION 0x00, 0x02
/* Номер версии устройства: сначала младший номер, затем старший номер.
*/
#define USB_CFG_VENDOR_NAME 'V', 'd', 'd', 'd', 'd', ' ', 'V', 'd', 'd', 'd', 'd', 'd', 'd', 'd'
#define USB_CFG_VENDOR_NAME_LEN 14
/* Здесь указывают имя вендора (vendor name), возвращаемое устройством.
* Имя должно предоставляться как список символов в одиночных
* кавычках, а USB_CFG_VENDOR_NAME_LEN задает их количество. Символы
* интерпретируются как Unicode (UTF-16). Если Вам не нужно имя вендора,
* закомментируйте этот макрос. ВСЕГДА указывайте имя вендора, содержащее Ваше
* доменное имя Internet, если Вы используете свободно распространяемую пару
* obdev VID/PID. За деталями обращайтесь к файлу USB-IDs-for-free.txt.
*/
#define USB_CFG_DEVICE_NAME 'V', 'd', 'd', 'd', 'd', ' ', 'V', 'd', 'd', 'd', 'd', 'd', 'd', 'd'
#define USB_CFG_DEVICE_NAME_LEN 14
/* Здесь указывается имя устройства (device name) таким же способом, как и в
* предыдущем параметре указывается имя вендора. Если Вам не нужно имя
* устройства, закомментируйте этот макрос. См. файл USB-IDs-for-free.txt
* перед назначением имени, если Вы используете свободно распространяемую
* пару obdev VID/PID.
*/
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
/* Серийный номер (serial number). Если серийный номер Вам не нужен,
* закомментируйте макрос. Может оказаться полезным предоставить serial number
* по другим соображениям, отличающимся от времени компиляции. См. секцию,
* описывающую свойства дескриптора далее, где указано как сделать точное
* управление дескрипторами USB (USB descriptors), такими как string
* descriptor для серийного номера.
*/
#define USB_CFG_DEVICE_CLASS 0
#define USB_CFG_DEVICE_SUBCLASS 0
/* См. спецификацию USB, если Вы хотите приспособить устройство к
* существующему классу устройств (device class). Класс 0xff является
* "специфическим для вендора" ("vendor specific").
*/
#define USB_CFG_INTERFACE_CLASS 3
#define USB_CFG_INTERFACE_SUBCLASS 0
#define USB_CFG_INTERFACE_PROTOCOL 0
/* См. спецификацию USB, если Вы хотите, чтобы устройство отвечало требованиям
* существующего класса или протокола. Следующие классы должны быть установлены
* на уровне интерфейса:
* HID class 3, нетребуется подклассов и протоколов (может оказаться полезным!)
* CDC class 2, используйте подкласс 2 и протокол 1 для ACM
*/
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 22
/* Задайте здесь длину HID report descriptor, если Вы реализовали HID
* устройство. Иначе не задавайте этот параметр или установите его в 0.
* Если используете этот параметр, то Вы должны добавить символьный массив
* PROGMEM, названный "usbHidReportDescriptor", в код, который содержит
* report descriptor. Не забудьте держать массив и этот параметр в
* соответствии!
*/
/* #define USB_PUBLIC static */
/* Используйте этот define, если Вы используете директиву #include usbdrv.c
* вместо линкования. Эта техника экономит несколько байт flash-памяти.
*/
/* --------------- Тонкое управление через дескрипторы USB ----------------- */
/* Если Вы не хотите использовать дескрипторы по умолчанию драйвера USB,
* Вы можете предоставить Ваши собственные. Это может быть сделано
* как (1) статические данные фиксированной длины в памяти flash,
* (2) статические данные фиксированной длины в RAM, или (3) динамические во
* время выполнения в функции usbFunctionDescriptor(). Смотрим usbdrv.h для
* большей информации по таким дескрипторам. Поддержка дескрипторов
* конфигурируется через свойства дескриптора. Если не заданы свойства или
* если они равны 0, используется дескриптор по умолчанию.
* Возможны свойства:
* + USB_PROP_IS_DYNAMIC: данные для дескриптора должны быть захвачены (fetched)
* во время выполнения через usbFunctionDescriptor(). Если используется
* механизм usbMsgPtr, данные по умолчанию у FLASH.
* Добавьте свойство USB_PROP_IS_RAM если хотите RAM указатели.
* + USB_PROP_IS_RAM: данные, возвращенные usbFunctionDescriptor() или
* найденные в статической памяти RAM, не в памяти flash.
* + USB_PROP_LENGTH(len): если данные в статической памяти (RAM или flash),
* драйвер должен знать длину дескриптора. Дескриптор сам по себе найден по адресу,
* известному как идентификатор (см. далее).
* Список статических имен дескрипторов (должен быть задекларирован PROGMEM в flash):
* char usbDescriptorDevice[];
* char usbDescriptorConfiguration[];
* char usbDescriptorHidReport[];
* char usbDescriptorString0[];
* int usbDescriptorStringVendor[];
* int usbDescriptorStringDevice[];
* int usbDescriptorStringSerialNumber[];
* Другие дескрипторы не могут быть предоставлены статически, они должны
* предоставляться динамически во время выполнения.
*
* Свойства дескрипторов объединяются по ИЛИ либо складываются вместе, например:
* #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
*
* Следующие дескрипторы заданы:
* USB_CFG_DESCR_PROPS_DEVICE
* USB_CFG_DESCR_PROPS_CONFIGURATION
* USB_CFG_DESCR_PROPS_STRINGS
* USB_CFG_DESCR_PROPS_STRING_0
* USB_CFG_DESCR_PROPS_STRING_VENDOR
* USB_CFG_DESCR_PROPS_STRING_PRODUCT
* USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
* USB_CFG_DESCR_PROPS_HID
* USB_CFG_DESCR_PROPS_HID_REPORT
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
*
* Помните что string дескрипторы не просто строки, они являются
* Unicode strings prefixed with a 2 byte header. Пример:
* int serialNumberDescriptor[] = {
* USB_STRING_DESCRIPTOR_HEADER(6),
* 'S', 'e', 'r', 'i', 'a', 'l'
* };
*/
#define USB_CFG_DESCR_PROPS_DEVICE 0
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
#define USB_CFG_DESCR_PROPS_STRINGS 0
#define USB_CFG_DESCR_PROPS_STRING_0 0
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
#define USB_CFG_DESCR_PROPS_HID 0
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
/* --------------------- Дополнительные настройки MCU ---------------------- */
/* Следующие конфигурации работают по умолчанию в usbdrv.h. Вам обычно не нужно
* устанавливать их. Только если Вам нужно запустить драйвер на устройстве,
* которое пока не обрабатывается компилятором, который не полностью
* поддерживается (как, например, IAR C) или если используете прерывание,
* отличное от INT0, Вы можете задать кое-что из этого.
*/
/* #define USB_INTR_CFG MCUCR */
/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
/* #define USB_INTR_CFG_CLR 0 */
/* #define USB_INTR_ENABLE GIMSK */
/* #define USB_INTR_ENABLE_BIT INT0 */
/* #define USB_INTR_PENDING GIFR */
/* #define USB_INTR_PENDING_BIT INTF0 */
/* #define USB_INTR_VECTOR INT0_vect */
Сообщение отредактировал IgorKossak - Nov 20 2012, 20:59
Причина редактирования: [codebox] для длинного кода!!!