boart test board

Dependencies:   USBDevice mbed-dev lwip

Fork of USBSerial_HelloWorld by Compass Yap

Committer:
ua1arn
Date:
Mon Jul 30 13:11:13 2018 +0000
Revision:
21:85a0f94a84cd
prepare to generate new (multi-configuratiom USB)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ua1arn 21:85a0f94a84cd 1
ua1arn 21:85a0f94a84cd 2 #include <string.h>
ua1arn 21:85a0f94a84cd 3 #include <wchar.h>
ua1arn 21:85a0f94a84cd 4 #include <stdint.h>
ua1arn 21:85a0f94a84cd 5 #include <stdarg.h>
ua1arn 21:85a0f94a84cd 6
ua1arn 21:85a0f94a84cd 7 //#include "usb_conf.h"
ua1arn 21:85a0f94a84cd 8 //#include "usbd_core.h"
ua1arn 21:85a0f94a84cd 9 //#include "usbd_desc.h"
ua1arn 21:85a0f94a84cd 10 //#include "usbd_conf.h"
ua1arn 21:85a0f94a84cd 11
ua1arn 21:85a0f94a84cd 12 //#include "debug.h"
ua1arn 21:85a0f94a84cd 13
ua1arn 21:85a0f94a84cd 14 // TODO: move to right place
ua1arn 21:85a0f94a84cd 15 #include "usbd_desc2.h"
ua1arn 21:85a0f94a84cd 16
ua1arn 21:85a0f94a84cd 17
ua1arn 21:85a0f94a84cd 18 #define ALIGNX_BEGIN //__ALIGN_BEGIN
ua1arn 21:85a0f94a84cd 19 #define ALIGNX_END //__ALIGN_END
ua1arn 21:85a0f94a84cd 20
ua1arn 21:85a0f94a84cd 21 #define CPUSTYLE_STM32F 1
ua1arn 21:85a0f94a84cd 22
ua1arn 21:85a0f94a84cd 23 /* USB Descriptor Types */
ua1arn 21:85a0f94a84cd 24 #define USB_DEVICE_DESCRIPTOR_TYPE 1
ua1arn 21:85a0f94a84cd 25 #define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
ua1arn 21:85a0f94a84cd 26 #define USB_STRING_DESCRIPTOR_TYPE 3
ua1arn 21:85a0f94a84cd 27 #define USB_INTERFACE_DESCRIPTOR_TYPE 4
ua1arn 21:85a0f94a84cd 28 #define USB_ENDPOINT_DESCRIPTOR_TYPE 5
ua1arn 21:85a0f94a84cd 29 #define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6
ua1arn 21:85a0f94a84cd 30 #define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7
ua1arn 21:85a0f94a84cd 31 #define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8
ua1arn 21:85a0f94a84cd 32 #define USB_OTG_DESCRIPTOR_TYPE 9
ua1arn 21:85a0f94a84cd 33 #define USB_DEBUG_DESCRIPTOR_TYPE 10
ua1arn 21:85a0f94a84cd 34 #define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11
ua1arn 21:85a0f94a84cd 35 #define USB_DEVICE_CAPABITY_DESCRIPTOR_TYPE 0x10
ua1arn 21:85a0f94a84cd 36
ua1arn 21:85a0f94a84cd 37 /* Wireless USB extension Descriptor Type. */
ua1arn 21:85a0f94a84cd 38 #define USB_SECURITY_TYPE 12
ua1arn 21:85a0f94a84cd 39 #define USB_KEY_TYPE 13
ua1arn 21:85a0f94a84cd 40 #define USB_ENCRIPTION_TYPE 14
ua1arn 21:85a0f94a84cd 41 #define USB_BOS_TYPE 15
ua1arn 21:85a0f94a84cd 42 #define USB_DEVICE_CAPABILITY_TYPE 16
ua1arn 21:85a0f94a84cd 43 #define USB_WIRELESS_ENDPOINT_COMPANION_TYPE 17
ua1arn 21:85a0f94a84cd 44
ua1arn 21:85a0f94a84cd 45 /* USB Device Classes */
ua1arn 21:85a0f94a84cd 46 #define USB_DEVICE_CLASS_RESERVED 0x00
ua1arn 21:85a0f94a84cd 47 #define USB_DEVICE_CLASS_AUDIO 0x01
ua1arn 21:85a0f94a84cd 48 #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
ua1arn 21:85a0f94a84cd 49 #define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
ua1arn 21:85a0f94a84cd 50 #define USB_DEVICE_CLASS_MONITOR 0x04
ua1arn 21:85a0f94a84cd 51 #define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
ua1arn 21:85a0f94a84cd 52 #define USB_DEVICE_CLASS_POWER 0x06
ua1arn 21:85a0f94a84cd 53 #define USB_DEVICE_CLASS_PRINTER 0x07
ua1arn 21:85a0f94a84cd 54 #define USB_DEVICE_CLASS_STORAGE 0x08
ua1arn 21:85a0f94a84cd 55 #define USB_DEVICE_CLASS_HUB 0x09
ua1arn 21:85a0f94a84cd 56 #define USB_DEVICE_CLASS_WIRELESS_CONTROLLER 0xE0
ua1arn 21:85a0f94a84cd 57 #define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF
ua1arn 21:85a0f94a84cd 58 #define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
ua1arn 21:85a0f94a84cd 59
ua1arn 21:85a0f94a84cd 60 #define UNICODE_ENGLISH (0x0409) /* US_English (Ref: USB_LANGIDs.pdf) */
ua1arn 21:85a0f94a84cd 61
ua1arn 21:85a0f94a84cd 62 // --- адаптация к использованию
ua1arn 21:85a0f94a84cd 63
ua1arn 21:85a0f94a84cd 64
ua1arn 21:85a0f94a84cd 65
ua1arn 21:85a0f94a84cd 66 // +++ адаптация к использованию
ua1arn 21:85a0f94a84cd 67 #include "usb200.h"
ua1arn 21:85a0f94a84cd 68
ua1arn 21:85a0f94a84cd 69
ua1arn 21:85a0f94a84cd 70 #if WITHUSBHW
ua1arn 21:85a0f94a84cd 71
ua1arn 21:85a0f94a84cd 72 //#include "usb200.h"
ua1arn 21:85a0f94a84cd 73 //#include "usbch9.h"
ua1arn 21:85a0f94a84cd 74
ua1arn 21:85a0f94a84cd 75 // UAC audio device
ua1arn 21:85a0f94a84cd 76 // USB\VID_FFFF&PID_0736&REV_0100&MI_00
ua1arn 21:85a0f94a84cd 77 // USB\VID_FFFF&PID_0736&MI_00
ua1arn 21:85a0f94a84cd 78
ua1arn 21:85a0f94a84cd 79 // ACM serial device:
ua1arn 21:85a0f94a84cd 80 //
ua1arn 21:85a0f94a84cd 81 // USB\VID_FFFF&PID_0736&REV_0100&MI_03
ua1arn 21:85a0f94a84cd 82 // USB\VID_FFFF&PID_0736&MI_03
ua1arn 21:85a0f94a84cd 83
ua1arn 21:85a0f94a84cd 84 // CDC ECM
ua1arn 21:85a0f94a84cd 85 //
ua1arn 21:85a0f94a84cd 86 // USB\Class_02&SubClass_06
ua1arn 21:85a0f94a84cd 87
ua1arn 21:85a0f94a84cd 88 // CDC EEM
ua1arn 21:85a0f94a84cd 89 //
ua1arn 21:85a0f94a84cd 90 // USB\Class_02&SubClass_0c&Prot_07
ua1arn 21:85a0f94a84cd 91 // USB\Class_02&SubClass_0c
ua1arn 21:85a0f94a84cd 92 // USB\Class_02
ua1arn 21:85a0f94a84cd 93 //
ua1arn 21:85a0f94a84cd 94 // http://blog.metrotek.spb.ru/2011/07/07/usb-set-na-cortex-m3/
ua1arn 21:85a0f94a84cd 95
ua1arn 21:85a0f94a84cd 96 #define USB_FUNCTION_BCD_USB 0x0200 // 0x0201 in ST samples
ua1arn 21:85a0f94a84cd 97 #define USB_FUNCTION_VENDOR_ID 0xFFFF // Generic
ua1arn 21:85a0f94a84cd 98 //#define USB_FUNCTION_VENDOR_ID 0x041C // Altera Corp.
ua1arn 21:85a0f94a84cd 99 //#define USB_FUNCTION_VENDOR_ID 0x04d9 // Holtek Semiconductor, Inc.
ua1arn 21:85a0f94a84cd 100
ua1arn 21:85a0f94a84cd 101 #define USB_FUNCTION_PRODUCT_ID 0x0001
ua1arn 21:85a0f94a84cd 102
ua1arn 21:85a0f94a84cd 103 // From STMicroelectronics Comunication Device Class driver (CDC) INF FILE:
ua1arn 21:85a0f94a84cd 104 //#define USB_FUNCTION_VENDOR_ID 0x0483 // STM
ua1arn 21:85a0f94a84cd 105 //#define USB_FUNCTION_PRODUCT_ID 0x5740
ua1arn 21:85a0f94a84cd 106 //#define USB_FUNCTION_RELEASE_NO 0x0200
ua1arn 21:85a0f94a84cd 107
ua1arn 21:85a0f94a84cd 108 #if WITHUSBUAC && WITHUSBUAC3
ua1arn 21:85a0f94a84cd 109 #if WITHRTS96
ua1arn 21:85a0f94a84cd 110 #define BUILD_ID 6 // модификатор serial sumber
ua1arn 21:85a0f94a84cd 111 #define USB_FUNCTION_RELEASE_NO 0x0106
ua1arn 21:85a0f94a84cd 112 #elif WITHRTS192
ua1arn 21:85a0f94a84cd 113 #define BUILD_ID 5 // модификатор serial sumber
ua1arn 21:85a0f94a84cd 114 #define USB_FUNCTION_RELEASE_NO 0x0105
ua1arn 21:85a0f94a84cd 115 #else
ua1arn 21:85a0f94a84cd 116 #define BUILD_ID 4 // модификатор serial sumber
ua1arn 21:85a0f94a84cd 117 #define USB_FUNCTION_RELEASE_NO 0x0104
ua1arn 21:85a0f94a84cd 118 #endif
ua1arn 21:85a0f94a84cd 119 #else /* WITHUSBUAC && WITHUSBUAC3 */
ua1arn 21:85a0f94a84cd 120 #if WITHRTSNOAUDIO
ua1arn 21:85a0f94a84cd 121 #define BUILD_ID 3 // модификатор serial sumber
ua1arn 21:85a0f94a84cd 122 #define USB_FUNCTION_RELEASE_NO 0x0103
ua1arn 21:85a0f94a84cd 123 #elif WITHRTS96
ua1arn 21:85a0f94a84cd 124 #define BUILD_ID 2 // модификатор serial sumber
ua1arn 21:85a0f94a84cd 125 #define USB_FUNCTION_RELEASE_NO 0x0102
ua1arn 21:85a0f94a84cd 126 #elif WITHRTS192
ua1arn 21:85a0f94a84cd 127 #define BUILD_ID 1 // модификатор serial sumber
ua1arn 21:85a0f94a84cd 128 #define USB_FUNCTION_RELEASE_NO 0x0101
ua1arn 21:85a0f94a84cd 129 #else
ua1arn 21:85a0f94a84cd 130 #define BUILD_ID 0 // модификатор serial sumber
ua1arn 21:85a0f94a84cd 131 #define USB_FUNCTION_RELEASE_NO 0x0100
ua1arn 21:85a0f94a84cd 132 #endif
ua1arn 21:85a0f94a84cd 133 #endif /* WITHUSBUAC && WITHUSBUAC3 */
ua1arn 21:85a0f94a84cd 134
ua1arn 21:85a0f94a84cd 135 enum
ua1arn 21:85a0f94a84cd 136 {
ua1arn 21:85a0f94a84cd 137 STRING_ID_0 = 0, /* Language ID */
ua1arn 21:85a0f94a84cd 138
ua1arn 21:85a0f94a84cd 139 STRING_ID_1, /* Manufacturer */
ua1arn 21:85a0f94a84cd 140 STRING_ID_2, /* Product */
ua1arn 21:85a0f94a84cd 141 STRING_ID_3, /* SerialNumber */
ua1arn 21:85a0f94a84cd 142
ua1arn 21:85a0f94a84cd 143 // USB CDC strings
ua1arn 21:85a0f94a84cd 144 STRING_ID_4a, /* */
ua1arn 21:85a0f94a84cd 145 STRING_ID_4b, /* */
ua1arn 21:85a0f94a84cd 146
ua1arn 21:85a0f94a84cd 147 STRING_ID_5,
ua1arn 21:85a0f94a84cd 148 STRING_ID_5a,
ua1arn 21:85a0f94a84cd 149 STRING_ID_MACADDRESS, // iMacAddress
ua1arn 21:85a0f94a84cd 150
ua1arn 21:85a0f94a84cd 151 // USB UAC strings
ua1arn 21:85a0f94a84cd 152 STRING_ID_a0, /* tag for Interface Descriptor 0/0 Audio */
ua1arn 21:85a0f94a84cd 153 STRING_ID_a1, /* tag for Interface Descriptor 0/0 Spectrum */
ua1arn 21:85a0f94a84cd 154
ua1arn 21:85a0f94a84cd 155 STRING_ID_d0,
ua1arn 21:85a0f94a84cd 156 STRING_ID_d1,
ua1arn 21:85a0f94a84cd 157
ua1arn 21:85a0f94a84cd 158 STRING_ID_e0,
ua1arn 21:85a0f94a84cd 159 STRING_ID_e1,
ua1arn 21:85a0f94a84cd 160
ua1arn 21:85a0f94a84cd 161 STRING_ID_x0, /* */
ua1arn 21:85a0f94a84cd 162 STRING_ID_x1, /* */
ua1arn 21:85a0f94a84cd 163
ua1arn 21:85a0f94a84cd 164 STRING_ID_y0, /* */
ua1arn 21:85a0f94a84cd 165 STRING_ID_y1, /* */
ua1arn 21:85a0f94a84cd 166
ua1arn 21:85a0f94a84cd 167 STRING_ID_z0, /* */
ua1arn 21:85a0f94a84cd 168 STRING_ID_z1, /* */
ua1arn 21:85a0f94a84cd 169
ua1arn 21:85a0f94a84cd 170 //STRING_ID_b, // tag for USB Speaker Audio Feature Unit Descriptor
ua1arn 21:85a0f94a84cd 171
ua1arn 21:85a0f94a84cd 172 STRING_ID_Left, STRING_ID_Right, // Идут подряд
ua1arn 21:85a0f94a84cd 173
ua1arn 21:85a0f94a84cd 174 STRING_ID_RNDIS,
ua1arn 21:85a0f94a84cd 175 STRING_ID_HIDa,
ua1arn 21:85a0f94a84cd 176 STRING_ID_IQSPECTRUM,
ua1arn 21:85a0f94a84cd 177 //
ua1arn 21:85a0f94a84cd 178 STRING_ID_count
ua1arn 21:85a0f94a84cd 179 };
ua1arn 21:85a0f94a84cd 180
ua1arn 21:85a0f94a84cd 181 struct stringtempl
ua1arn 21:85a0f94a84cd 182 {
ua1arn 21:85a0f94a84cd 183 uint_fast8_t id;
ua1arn 21:85a0f94a84cd 184 const char * str;
ua1arn 21:85a0f94a84cd 185 };
ua1arn 21:85a0f94a84cd 186
ua1arn 21:85a0f94a84cd 187 static const struct stringtempl strtemplates [] =
ua1arn 21:85a0f94a84cd 188 {
ua1arn 21:85a0f94a84cd 189 { STRING_ID_1, "Smekalka.com", }, // Manufacturer
ua1arn 21:85a0f94a84cd 190 { STRING_ID_2, "HLAB reader", }, // Product
ua1arn 21:85a0f94a84cd 191 { STRING_ID_4a, "HLAB reader CAT", },
ua1arn 21:85a0f94a84cd 192 { STRING_ID_4b, "HLAB reader CTL", },
ua1arn 21:85a0f94a84cd 193 { STRING_ID_5, "HLAB reader CDC EEM", },
ua1arn 21:85a0f94a84cd 194 { STRING_ID_5a, "HLAB reader CDC ECM", },
ua1arn 21:85a0f94a84cd 195 { STRING_ID_RNDIS, "HLAB reader Remote NDIS", },
ua1arn 21:85a0f94a84cd 196
ua1arn 21:85a0f94a84cd 197 { STRING_ID_a0, "HLAB reader Voice", }, // tag for Interface Descriptor 0/0 Audio
ua1arn 21:85a0f94a84cd 198 { STRING_ID_a1, "HLAB reader Spectrum", }, // tag for Interface Descriptor 0/0 Audio
ua1arn 21:85a0f94a84cd 199
ua1arn 21:85a0f94a84cd 200 //{ STRING_ID_b, "xxx_id11", }, // tag for USB Speaker Audio Feature Unit Descriptor
ua1arn 21:85a0f94a84cd 201
ua1arn 21:85a0f94a84cd 202 { STRING_ID_d0, "Transmitter Input1", }, // Audio Control Input Terminal Descriptor
ua1arn 21:85a0f94a84cd 203 { STRING_ID_d1, "Transmitter Input2", }, // Audio Control Input Terminal Descriptor
ua1arn 21:85a0f94a84cd 204
ua1arn 21:85a0f94a84cd 205 { STRING_ID_e0, "Receiver Output 1", }, // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 206 { STRING_ID_e1, "Receiver Output 2", }, // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 207
ua1arn 21:85a0f94a84cd 208 { STRING_ID_x0, "xxxx In 1", }, // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 209 { STRING_ID_x1, "xxxx In 2", }, // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 210
ua1arn 21:85a0f94a84cd 211 { STRING_ID_y0, "yyyy In 1", }, // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 212 { STRING_ID_y1, "yyyy In 2", }, // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 213
ua1arn 21:85a0f94a84cd 214 { STRING_ID_z0, "zzzz In 1", }, // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 215 { STRING_ID_z1, "zzzz In 2", }, // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 216
ua1arn 21:85a0f94a84cd 217 { STRING_ID_Left, "USB", }, // tag for USB Speaker Audio Feature Unit Descriptor
ua1arn 21:85a0f94a84cd 218 { STRING_ID_Right, "LSB", }, // tag for USB Speaker Audio Feature Unit Descriptor
ua1arn 21:85a0f94a84cd 219 { STRING_ID_HIDa, "HID xxx", },
ua1arn 21:85a0f94a84cd 220 { STRING_ID_IQSPECTRUM, "RX IQ Output", },
ua1arn 21:85a0f94a84cd 221 };
ua1arn 21:85a0f94a84cd 222 #if 0
ua1arn 21:85a0f94a84cd 223
ua1arn 21:85a0f94a84cd 224 static int
ua1arn 21:85a0f94a84cd 225 toprintc(int c)
ua1arn 21:85a0f94a84cd 226 {
ua1arn 21:85a0f94a84cd 227 if (c < 0x20 || c >= 0x7f)
ua1arn 21:85a0f94a84cd 228 return '.';
ua1arn 21:85a0f94a84cd 229 return c;
ua1arn 21:85a0f94a84cd 230 }
ua1arn 21:85a0f94a84cd 231
ua1arn 21:85a0f94a84cd 232 void
ua1arn 21:85a0f94a84cd 233 static printhex(unsigned long voffs, const unsigned char * buff, unsigned length)
ua1arn 21:85a0f94a84cd 234 {
ua1arn 21:85a0f94a84cd 235 unsigned i, j;
ua1arn 21:85a0f94a84cd 236 unsigned rows = (length + 15) / 16;
ua1arn 21:85a0f94a84cd 237
ua1arn 21:85a0f94a84cd 238 for (i = 0; i < rows; ++ i)
ua1arn 21:85a0f94a84cd 239 {
ua1arn 21:85a0f94a84cd 240 int trl = 16;
ua1arn 21:85a0f94a84cd 241 //const int trl = ((length - 1) - i * 16) % 16 + 1; // количество символов в данной строке
ua1arn 21:85a0f94a84cd 242
ua1arn 21:85a0f94a84cd 243 PRINTF(PSTR("%08lX "), voffs + i * 16);
ua1arn 21:85a0f94a84cd 244 for (j = 0; j < trl; ++ j)
ua1arn 21:85a0f94a84cd 245 PRINTF(PSTR(" %02X"), buff [i * 16 + j]);
ua1arn 21:85a0f94a84cd 246
ua1arn 21:85a0f94a84cd 247 PRINTF(PSTR("%*s"), (16 - trl) * 3, "");
ua1arn 21:85a0f94a84cd 248
ua1arn 21:85a0f94a84cd 249 PRINTF(PSTR(" "));
ua1arn 21:85a0f94a84cd 250 for (j = 0; j < trl; ++ j)
ua1arn 21:85a0f94a84cd 251 PRINTF(PSTR("%c"), toprintc(buff [i * 16 + j]));
ua1arn 21:85a0f94a84cd 252
ua1arn 21:85a0f94a84cd 253 PRINTF(PSTR("\n"));
ua1arn 21:85a0f94a84cd 254 }
ua1arn 21:85a0f94a84cd 255 }
ua1arn 21:85a0f94a84cd 256 #endif
ua1arn 21:85a0f94a84cd 257
ua1arn 21:85a0f94a84cd 258
ua1arn 21:85a0f94a84cd 259 // Инициализация дескриптора произвольным массивом данных
ua1arn 21:85a0f94a84cd 260 static unsigned fill_pattern_descriptor(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, const void * pattern, unsigned length)
ua1arn 21:85a0f94a84cd 261 {
ua1arn 21:85a0f94a84cd 262 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 263 if (maxsize < length)
ua1arn 21:85a0f94a84cd 264 return 0;
ua1arn 21:85a0f94a84cd 265 if (fill && buff != NULL)
ua1arn 21:85a0f94a84cd 266 {
ua1arn 21:85a0f94a84cd 267 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 268 memcpy(buff, pattern, length);
ua1arn 21:85a0f94a84cd 269 }
ua1arn 21:85a0f94a84cd 270 return length;
ua1arn 21:85a0f94a84cd 271 }
ua1arn 21:85a0f94a84cd 272
ua1arn 21:85a0f94a84cd 273 // usb_20.pdf:
ua1arn 21:85a0f94a84cd 274 // 5.9 High-Speed, High Bandwidth Endpoints
ua1arn 21:85a0f94a84cd 275 // 9.6.6 Endpoint
ua1arn 21:85a0f94a84cd 276 // Table 9-14. Allowed wMaxPacketSize Values for Different Numbers of Transactions per Microframe
ua1arn 21:85a0f94a84cd 277 static uint_fast16_t encodeMaxPacketSize(uint_fast32_t size)
ua1arn 21:85a0f94a84cd 278 {
ua1arn 21:85a0f94a84cd 279 // For all endpoints, bits 10..0 specify the maximum
ua1arn 21:85a0f94a84cd 280 // packet size (in bytes).
ua1arn 21:85a0f94a84cd 281
ua1arn 21:85a0f94a84cd 282 // A high-speed endpoint can move up to 3072 bytes per microframe
ua1arn 21:85a0f94a84cd 283 // For high-speed isochronous and interrupt endpoints:
ua1arn 21:85a0f94a84cd 284 // Bits 12..11 specify the number of additional transaction
ua1arn 21:85a0f94a84cd 285 // opportunities per microframe:
ua1arn 21:85a0f94a84cd 286 // 00 = None (1 transaction per microframe)
ua1arn 21:85a0f94a84cd 287 // 01 = 1 additional (2 per microframe)
ua1arn 21:85a0f94a84cd 288 // 10 = 2 additional (3 per microframe)
ua1arn 21:85a0f94a84cd 289
ua1arn 21:85a0f94a84cd 290 if (size <= 1024)
ua1arn 21:85a0f94a84cd 291 return size; // 1..1024
ua1arn 21:85a0f94a84cd 292 if (size <= 2048)
ua1arn 21:85a0f94a84cd 293 return (0x01 << 11) | ((size + 1) / 2); // 513..1024
ua1arn 21:85a0f94a84cd 294 else
ua1arn 21:85a0f94a84cd 295 return (0x02 << 11) | ((size + 2) / 3); // 683..1024
ua1arn 21:85a0f94a84cd 296 }
ua1arn 21:85a0f94a84cd 297
ua1arn 21:85a0f94a84cd 298 #if WITHUSBUAC
ua1arn 21:85a0f94a84cd 299
ua1arn 21:85a0f94a84cd 300 #if 0
ua1arn 21:85a0f94a84cd 301 // Вариант Oleg UR3IQO
ua1arn 21:85a0f94a84cd 302 static const uint_fast8_t USBD_UACIN_EP_ATTRIBUTES =
ua1arn 21:85a0f94a84cd 303 USB_ENDPOINT_USAGE_DATA |
ua1arn 21:85a0f94a84cd 304 USB_ENDPOINT_SYNC_SYNCHRONOUS |
ua1arn 21:85a0f94a84cd 305 USB_ENDPOINT_TYPE_ISOCHRONOUS;
ua1arn 21:85a0f94a84cd 306
ua1arn 21:85a0f94a84cd 307 static const uint_fast8_t USBD_UACOUT_EP_ATTRIBUTES =
ua1arn 21:85a0f94a84cd 308 USB_ENDPOINT_USAGE_DATA |
ua1arn 21:85a0f94a84cd 309 USB_ENDPOINT_SYNC_SYNCHRONOUS |
ua1arn 21:85a0f94a84cd 310 USB_ENDPOINT_TYPE_ISOCHRONOUS;
ua1arn 21:85a0f94a84cd 311 #else
ua1arn 21:85a0f94a84cd 312 // Мой вариант
ua1arn 21:85a0f94a84cd 313 static const uint_fast8_t USBD_UACIN_EP_ATTRIBUTES =
ua1arn 21:85a0f94a84cd 314 USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK |
ua1arn 21:85a0f94a84cd 315 USB_ENDPOINT_SYNC_ASYNCHRONOUS |
ua1arn 21:85a0f94a84cd 316 USB_ENDPOINT_TYPE_ISOCHRONOUS;
ua1arn 21:85a0f94a84cd 317
ua1arn 21:85a0f94a84cd 318 static const uint_fast8_t USBD_UACOUT_EP_ATTRIBUTES =
ua1arn 21:85a0f94a84cd 319 USB_ENDPOINT_USAGE_DATA |
ua1arn 21:85a0f94a84cd 320 USB_ENDPOINT_SYNC_ASYNCHRONOUS |
ua1arn 21:85a0f94a84cd 321 USB_ENDPOINT_TYPE_ISOCHRONOUS;
ua1arn 21:85a0f94a84cd 322 #endif
ua1arn 21:85a0f94a84cd 323
ua1arn 21:85a0f94a84cd 324
ua1arn 21:85a0f94a84cd 325 #if 0
ua1arn 21:85a0f94a84cd 326
ua1arn 21:85a0f94a84cd 327 //In the following code bmAttributes field is 0x01;
ua1arn 21:85a0f94a84cd 328 //which means that clock type is internal fixed clock.
ua1arn 21:85a0f94a84cd 329 /* Clock Source Descriptor(4.7.2.1) */
ua1arn 21:85a0f94a84cd 330 static unsigned r9fill_clock_source(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 331 {
ua1arn 21:85a0f94a84cd 332 const uint_fast8_t length = 8;
ua1arn 21:85a0f94a84cd 333 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 334 if (maxsize < length)
ua1arn 21:85a0f94a84cd 335 return 0;
ua1arn 21:85a0f94a84cd 336 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 337 {
ua1arn 21:85a0f94a84cd 338 // Вызов для заполнения; а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 339 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 340 * buff ++ = CS_INTERFACE; /* bDescriptorType(0x24): CS_INTERFACE */
ua1arn 21:85a0f94a84cd 341 * buff ++ = 0x0A; /* bDescriptorSubType(0x0A): CLOCK_SOURCE */
ua1arn 21:85a0f94a84cd 342 * buff ++ = 0x10; /* bClockID(0x10): CLOCK_SOURCE_ID */
ua1arn 21:85a0f94a84cd 343 * buff ++ = 0x01; /* bmAttributes(0x01): internal fixed clock */
ua1arn 21:85a0f94a84cd 344 * buff ++ = 0x07; /* bmControls(0x07):
ua1arn 21:85a0f94a84cd 345 clock frequency control: 0b11 - host programmable;
ua1arn 21:85a0f94a84cd 346 clock validity control: 0b01 - host read only */
ua1arn 21:85a0f94a84cd 347 * buff ++ = TERMINAL_ID_UNDEFINED; /* bAssocTerminal(0x00) */
ua1arn 21:85a0f94a84cd 348 * buff ++ = 0x01; /* iClockSource(0x01): Not requested */
ua1arn 21:85a0f94a84cd 349 }
ua1arn 21:85a0f94a84cd 350 return length;
ua1arn 21:85a0f94a84cd 351 }
ua1arn 21:85a0f94a84cd 352
ua1arn 21:85a0f94a84cd 353 #endif
ua1arn 21:85a0f94a84cd 354
ua1arn 21:85a0f94a84cd 355 /* UAC IAD */
ua1arn 21:85a0f94a84cd 356 // Interface Association Descriptor Audio
ua1arn 21:85a0f94a84cd 357 // Audio10.pdf 4.3.2.8 Associated Interface Descriptor
ua1arn 21:85a0f94a84cd 358 // documented in USB ECN : Interface Association Descriptor - InterfaceAssociationDescriptor_ecn.pdf
ua1arn 21:85a0f94a84cd 359 static unsigned UAC_InterfaceAssociationDescriptor(uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 360 uint_fast8_t bFirstInterface,
ua1arn 21:85a0f94a84cd 361 uint_fast8_t bInterfaceCount,
ua1arn 21:85a0f94a84cd 362 uint_fast8_t offset
ua1arn 21:85a0f94a84cd 363 )
ua1arn 21:85a0f94a84cd 364 {
ua1arn 21:85a0f94a84cd 365 const uint_fast8_t length = 8;
ua1arn 21:85a0f94a84cd 366 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 367 if (maxsize < length)
ua1arn 21:85a0f94a84cd 368 return 0;
ua1arn 21:85a0f94a84cd 369 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 370 {
ua1arn 21:85a0f94a84cd 371 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 372 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 373 * buff ++ = USB_INTERFACE_ASSOC_DESCRIPTOR_TYPE; // bDescriptorType: IAD
ua1arn 21:85a0f94a84cd 374 * buff ++ = bFirstInterface; // bFirstInterface
ua1arn 21:85a0f94a84cd 375 * buff ++ = bInterfaceCount; // bInterfaceCount
ua1arn 21:85a0f94a84cd 376 * buff ++ = USB_DEVICE_CLASS_AUDIO; // bFunctionClass: Audio
ua1arn 21:85a0f94a84cd 377 * buff ++ = 0x00; // bFunctionSubClass
ua1arn 21:85a0f94a84cd 378 * buff ++ = 0x00; // bFunctionProtocol
ua1arn 21:85a0f94a84cd 379 * buff ++ = STRING_ID_a0 + offset; // Interface string index
ua1arn 21:85a0f94a84cd 380 }
ua1arn 21:85a0f94a84cd 381 return length;
ua1arn 21:85a0f94a84cd 382 }
ua1arn 21:85a0f94a84cd 383
ua1arn 21:85a0f94a84cd 384 /* USB Speaker Standard interface descriptor */
ua1arn 21:85a0f94a84cd 385 // Interface Descriptor 0/0 Audio, 0 Endpoints
ua1arn 21:85a0f94a84cd 386 static unsigned r9fill_3(uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 387 uint_fast8_t bInterfaceNumber,
ua1arn 21:85a0f94a84cd 388 uint_fast8_t bAlternateSetting,
ua1arn 21:85a0f94a84cd 389 uint_fast8_t offset
ua1arn 21:85a0f94a84cd 390 )
ua1arn 21:85a0f94a84cd 391 {
ua1arn 21:85a0f94a84cd 392 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 393 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 394 if (maxsize < length)
ua1arn 21:85a0f94a84cd 395 return 0;
ua1arn 21:85a0f94a84cd 396 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 397 {
ua1arn 21:85a0f94a84cd 398 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 399 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 400 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType */
ua1arn 21:85a0f94a84cd 401 * buff ++ = bInterfaceNumber; /* bInterfaceNumber */
ua1arn 21:85a0f94a84cd 402 * buff ++ = bAlternateSetting; /* bAlternateSetting */
ua1arn 21:85a0f94a84cd 403 * buff ++ = 0x00; /* bNumEndpoints */
ua1arn 21:85a0f94a84cd 404 * buff ++ = USB_DEVICE_CLASS_AUDIO; /* bInterfaceClass */
ua1arn 21:85a0f94a84cd 405 * buff ++ = AUDIO_SUBCLASS_AUDIOCONTROL; /* bInterfaceSubClass */
ua1arn 21:85a0f94a84cd 406 * buff ++ = AUDIO_PROTOCOL_UNDEFINED; /* bInterfaceProtocol */
ua1arn 21:85a0f94a84cd 407 * buff ++ = STRING_ID_a0 + offset; /* iInterface */
ua1arn 21:85a0f94a84cd 408 /* 09 byte*/
ua1arn 21:85a0f94a84cd 409 }
ua1arn 21:85a0f94a84cd 410 return length;
ua1arn 21:85a0f94a84cd 411 }
ua1arn 21:85a0f94a84cd 412
ua1arn 21:85a0f94a84cd 413 // Audio Control Input Terminal Descriptor
ua1arn 21:85a0f94a84cd 414 // audio10.pdf: Table 4-3: Input Terminal Descriptor
ua1arn 21:85a0f94a84cd 415 // Sereo signal source
ua1arn 21:85a0f94a84cd 416 // Audio или RTS
ua1arn 21:85a0f94a84cd 417 static unsigned UAC_AudioControlIT_IN(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bTerminalID, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 418 {
ua1arn 21:85a0f94a84cd 419 const uint_fast8_t length = 12;
ua1arn 21:85a0f94a84cd 420 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 421 if (maxsize < length)
ua1arn 21:85a0f94a84cd 422 return 0;
ua1arn 21:85a0f94a84cd 423 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 424 {
ua1arn 21:85a0f94a84cd 425 // 4.3.2.1 Input Terminal Descriptor
ua1arn 21:85a0f94a84cd 426 const uint_fast16_t wTerminalType = AUDIO_TERMINAL_RADIO_RECEIVER;
ua1arn 21:85a0f94a84cd 427 const uint_fast8_t bNrChannels = HARDWARE_USBD_AUDIO_IN_CHANNELS;
ua1arn 21:85a0f94a84cd 428 const uint_fast16_t wChannelConfig = bNrChannels == 1 ?
ua1arn 21:85a0f94a84cd 429 AUDIO_CHANNEL_M : // Mono
ua1arn 21:85a0f94a84cd 430 (AUDIO_CHANNEL_L | AUDIO_CHANNEL_R); // Left Front & Right Front
ua1arn 21:85a0f94a84cd 431 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 432 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 433 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE; // CS_INTERFACE Descriptor Type
ua1arn 21:85a0f94a84cd 434 * buff ++ = AUDIO_CONTROL_INPUT_TERMINAL; // INPUT_TERMINAL 0x02 descriptor subtype
ua1arn 21:85a0f94a84cd 435 * buff ++ = bTerminalID; // bTerminalID ID of this Terminal.
ua1arn 21:85a0f94a84cd 436 * buff ++ = LO_BYTE(wTerminalType); /* wTerminalType */
ua1arn 21:85a0f94a84cd 437 * buff ++ = HI_BYTE(wTerminalType);
ua1arn 21:85a0f94a84cd 438 * buff ++ = TERMINAL_ID_UNDEFINED; // bAssocTerminal No association
ua1arn 21:85a0f94a84cd 439 // The bNrChannels, wChannelConfig and iChannelNames fields together constitute the cluster descriptor
ua1arn 21:85a0f94a84cd 440 * buff ++ = bNrChannels; /* bNrChannels */
ua1arn 21:85a0f94a84cd 441 * buff ++ = LO_BYTE(wChannelConfig); /* bmChannelConfig size = 4 bytes Mono sets no position bits */
ua1arn 21:85a0f94a84cd 442 * buff ++ = HI_BYTE(wChannelConfig);
ua1arn 21:85a0f94a84cd 443 * buff ++ = STRING_ID_Left; /* iChannelNames */
ua1arn 21:85a0f94a84cd 444 * buff ++ = 0; // iTerminal - Index of a string descriptor, describing the Input Terminal. Receiver Output
ua1arn 21:85a0f94a84cd 445
ua1arn 21:85a0f94a84cd 446 }
ua1arn 21:85a0f94a84cd 447 return length;
ua1arn 21:85a0f94a84cd 448 }
ua1arn 21:85a0f94a84cd 449
ua1arn 21:85a0f94a84cd 450 static unsigned UAC_AudioControlIT_INRTS(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bTerminalID, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 451 {
ua1arn 21:85a0f94a84cd 452 const uint_fast8_t length = 12;
ua1arn 21:85a0f94a84cd 453 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 454 if (maxsize < length)
ua1arn 21:85a0f94a84cd 455 return 0;
ua1arn 21:85a0f94a84cd 456 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 457 {
ua1arn 21:85a0f94a84cd 458 // 4.3.2.1 Input Terminal Descriptor
ua1arn 21:85a0f94a84cd 459 const uint_fast16_t wTerminalType = AUDIO_TERMINAL_RADIO_RECEIVER;
ua1arn 21:85a0f94a84cd 460 const uint_fast8_t bNrChannels = HARDWARE_USBD_AUDIO_IN_CHANNELS_RTS; // для канала со спектром всегда стерео. но это не тут указано
ua1arn 21:85a0f94a84cd 461 const uint_fast16_t wChannelConfig = bNrChannels == 1 ?
ua1arn 21:85a0f94a84cd 462 AUDIO_CHANNEL_M : // Mono
ua1arn 21:85a0f94a84cd 463 (AUDIO_CHANNEL_L | AUDIO_CHANNEL_R); // Left Front & Right Front
ua1arn 21:85a0f94a84cd 464 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 465 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 466 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE; // CS_INTERFACE Descriptor Type
ua1arn 21:85a0f94a84cd 467 * buff ++ = AUDIO_CONTROL_INPUT_TERMINAL; // INPUT_TERMINAL 0x02 descriptor subtype
ua1arn 21:85a0f94a84cd 468 * buff ++ = bTerminalID; // bTerminalID ID of this Terminal.
ua1arn 21:85a0f94a84cd 469 * buff ++ = LO_BYTE(wTerminalType); /* wTerminalType */
ua1arn 21:85a0f94a84cd 470 * buff ++ = HI_BYTE(wTerminalType);
ua1arn 21:85a0f94a84cd 471 * buff ++ = TERMINAL_ID_UNDEFINED; // bAssocTerminal No association
ua1arn 21:85a0f94a84cd 472 // The bNrChannels, wChannelConfig and iChannelNames fields together constitute the cluster descriptor
ua1arn 21:85a0f94a84cd 473 * buff ++ = bNrChannels; /* bNrChannels */
ua1arn 21:85a0f94a84cd 474 * buff ++ = LO_BYTE(wChannelConfig); /* bmChannelConfig size = 4 bytes Mono sets no position bits */
ua1arn 21:85a0f94a84cd 475 * buff ++ = HI_BYTE(wChannelConfig);
ua1arn 21:85a0f94a84cd 476 * buff ++ = 0; /* iChannelNames */
ua1arn 21:85a0f94a84cd 477 * buff ++ = STRING_ID_IQSPECTRUM; // iTerminal - Index of a string descriptor, describing the Input Terminal. Receiver Output
ua1arn 21:85a0f94a84cd 478
ua1arn 21:85a0f94a84cd 479 }
ua1arn 21:85a0f94a84cd 480 return length;
ua1arn 21:85a0f94a84cd 481 }
ua1arn 21:85a0f94a84cd 482
ua1arn 21:85a0f94a84cd 483 /* !USB Speaker Input Terminal Descriptor */
ua1arn 21:85a0f94a84cd 484 // Audio Control Input Terminal Descriptor
ua1arn 21:85a0f94a84cd 485 // audio10.pdf: Table 4-3: Input Terminal Descriptor
ua1arn 21:85a0f94a84cd 486 // audio48 only
ua1arn 21:85a0f94a84cd 487 static unsigned UAC_AudioControlIT_OUT(
ua1arn 21:85a0f94a84cd 488 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 489 uint_fast8_t bTerminalID,
ua1arn 21:85a0f94a84cd 490 uint_fast8_t offset
ua1arn 21:85a0f94a84cd 491 )
ua1arn 21:85a0f94a84cd 492 {
ua1arn 21:85a0f94a84cd 493 const uint_fast8_t length = 12;
ua1arn 21:85a0f94a84cd 494 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 495 if (maxsize < length)
ua1arn 21:85a0f94a84cd 496 return 0;
ua1arn 21:85a0f94a84cd 497 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 498 {
ua1arn 21:85a0f94a84cd 499 // 4.3.2.1 Input Terminal Descriptor
ua1arn 21:85a0f94a84cd 500 const uint_fast16_t wTerminalType = AUDIO_TERMINAL_USB_STREAMING;
ua1arn 21:85a0f94a84cd 501 const uint_fast8_t bNrChannels = HARDWARE_USBD_AUDIO_OUT_CHANNELS;
ua1arn 21:85a0f94a84cd 502 const uint_fast16_t wChannelConfig = bNrChannels == 1 ?
ua1arn 21:85a0f94a84cd 503 AUDIO_CHANNEL_M : // Mono
ua1arn 21:85a0f94a84cd 504 (AUDIO_CHANNEL_L | AUDIO_CHANNEL_R); // Left Front & Right Front
ua1arn 21:85a0f94a84cd 505
ua1arn 21:85a0f94a84cd 506 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 507 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType */
ua1arn 21:85a0f94a84cd 508 * buff ++ = AUDIO_CONTROL_INPUT_TERMINAL; /* bDescriptorSubtype */
ua1arn 21:85a0f94a84cd 509 * buff ++ = bTerminalID; /* bTerminalID */
ua1arn 21:85a0f94a84cd 510 * buff ++ = LO_BYTE(wTerminalType); /* wTerminalType */
ua1arn 21:85a0f94a84cd 511 * buff ++ = HI_BYTE(wTerminalType);
ua1arn 21:85a0f94a84cd 512 * buff ++ = TERMINAL_ID_UNDEFINED; /* bAssocTerminal */
ua1arn 21:85a0f94a84cd 513 // The bNrChannels, wChannelConfig and iChannelNames fields together constitute the cluster descriptor
ua1arn 21:85a0f94a84cd 514 * buff ++ = bNrChannels; /* bNrChannels */
ua1arn 21:85a0f94a84cd 515 * buff ++ = LO_BYTE(wChannelConfig); /* wChannelConfig 0x0003 Front Left; Front Right */
ua1arn 21:85a0f94a84cd 516 * buff ++ = HI_BYTE(wChannelConfig);
ua1arn 21:85a0f94a84cd 517 * buff ++ = STRING_ID_Left; /* iChannelNames */
ua1arn 21:85a0f94a84cd 518 * buff ++ = STRING_ID_d0 + offset; /* iTerminal - появляется как pop-up в панели управления ASIO4ALL */
ua1arn 21:85a0f94a84cd 519 /* 12 bytes*/
ua1arn 21:85a0f94a84cd 520 }
ua1arn 21:85a0f94a84cd 521 return length;
ua1arn 21:85a0f94a84cd 522 }
ua1arn 21:85a0f94a84cd 523
ua1arn 21:85a0f94a84cd 524 /*! USB Microphone Output Terminal Descriptor bSourceID -> bTerminalID */
ua1arn 21:85a0f94a84cd 525 // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 526 // Audio или RTS
ua1arn 21:85a0f94a84cd 527 static unsigned UAC_AudioControlOT_IN(
ua1arn 21:85a0f94a84cd 528 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 529 uint_fast8_t bTerminalID,
ua1arn 21:85a0f94a84cd 530 uint_fast8_t bSourceID,
ua1arn 21:85a0f94a84cd 531 uint_fast8_t offset
ua1arn 21:85a0f94a84cd 532 )
ua1arn 21:85a0f94a84cd 533 {
ua1arn 21:85a0f94a84cd 534 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 535 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 536 if (maxsize < length)
ua1arn 21:85a0f94a84cd 537 return 0;
ua1arn 21:85a0f94a84cd 538 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 539 {
ua1arn 21:85a0f94a84cd 540 //
ua1arn 21:85a0f94a84cd 541 const uint_fast16_t wTerminalType = AUDIO_TERMINAL_USB_STREAMING;
ua1arn 21:85a0f94a84cd 542 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 543 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 544 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE; // CS_INTERFACE Descriptor Type (bDescriptorType)
ua1arn 21:85a0f94a84cd 545 * buff ++ = AUDIO_CONTROL_OUTPUT_TERMINAL; // OUTPUT_TERMINAL descriptor subtype (bDescriptorSubtype)
ua1arn 21:85a0f94a84cd 546 * buff ++ = bTerminalID; // ID of this Terminal. (bTerminalID)
ua1arn 21:85a0f94a84cd 547 * buff ++ = LO_BYTE(wTerminalType); /* wTerminalType */
ua1arn 21:85a0f94a84cd 548 * buff ++ = HI_BYTE(wTerminalType);
ua1arn 21:85a0f94a84cd 549 * buff ++ = TERMINAL_ID_UNDEFINED; // unused (bAssocTerminal)
ua1arn 21:85a0f94a84cd 550 * buff ++ = bSourceID; // From Input Terminal.(bSourceID)
ua1arn 21:85a0f94a84cd 551 * buff ++ = STRING_ID_e0 + offset; // unused (iTerminal)
ua1arn 21:85a0f94a84cd 552 }
ua1arn 21:85a0f94a84cd 553 return length;
ua1arn 21:85a0f94a84cd 554 }
ua1arn 21:85a0f94a84cd 555
ua1arn 21:85a0f94a84cd 556 #if 0
ua1arn 21:85a0f94a84cd 557 // Selector Unit Descriptor
ua1arn 21:85a0f94a84cd 558 static unsigned UAC_AudioSelectorUnit_IN(
ua1arn 21:85a0f94a84cd 559 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 560 uint_fast8_t bUnitID
ua1arn 21:85a0f94a84cd 561 )
ua1arn 21:85a0f94a84cd 562 {
ua1arn 21:85a0f94a84cd 563 //unsigned i;
ua1arn 21:85a0f94a84cd 564 const uint_fast8_t bNrInPins = TERMINAL_ID_SELECTOR_6_INPUTS; // количество входных потоков
ua1arn 21:85a0f94a84cd 565 const uint_fast8_t length = 6 + bNrInPins;
ua1arn 21:85a0f94a84cd 566 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 567 if (maxsize < length)
ua1arn 21:85a0f94a84cd 568 return 0;
ua1arn 21:85a0f94a84cd 569 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 570 {
ua1arn 21:85a0f94a84cd 571 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 572 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE;/* bDescriptorType */
ua1arn 21:85a0f94a84cd 573 * buff ++ = AUDIO_CONTROL_SELECTOR_UNIT; /* bDescriptorSubtype */
ua1arn 21:85a0f94a84cd 574 * buff ++ = bUnitID; /* bUnitID */
ua1arn 21:85a0f94a84cd 575 * buff ++ = bNrInPins; /* bNrInPins */
ua1arn 21:85a0f94a84cd 576 * buff ++ = TERMINAL_ID_IT_2; /* baSourceID(0) */
ua1arn 21:85a0f94a84cd 577 * buff ++ = TERMINAL_ID_FU_5c; /* baSourceID(1) */
ua1arn 21:85a0f94a84cd 578 * buff ++ = 0; /* iSelector (string ID) - unused */
ua1arn 21:85a0f94a84cd 579 }
ua1arn 21:85a0f94a84cd 580 return length;
ua1arn 21:85a0f94a84cd 581 }
ua1arn 21:85a0f94a84cd 582 #endif
ua1arn 21:85a0f94a84cd 583
ua1arn 21:85a0f94a84cd 584 // Audio Control Feature Unit Descriptor
ua1arn 21:85a0f94a84cd 585 // See 4.3.2.5 Feature Unit Descriptor for details
ua1arn 21:85a0f94a84cd 586 // В нашем случае используется для подавления отображения раздельных элементов регулировки уровня по каналам
ua1arn 21:85a0f94a84cd 587 static unsigned UAC_AudioFeatureUnit(
ua1arn 21:85a0f94a84cd 588 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 589 uint_fast8_t bUnitID,
ua1arn 21:85a0f94a84cd 590 uint_fast8_t bSourceID
ua1arn 21:85a0f94a84cd 591 )
ua1arn 21:85a0f94a84cd 592 {
ua1arn 21:85a0f94a84cd 593 // Параметр определяет, ккие управляющие элементы появляются на страничке управления "Custom"
ua1arn 21:85a0f94a84cd 594 // Причем, на этой страничке собраны все управляющие элементы со всех Feature Unit Descriptor
ua1arn 21:85a0f94a84cd 595 // в пути сигнала данного источника звука.
ua1arn 21:85a0f94a84cd 596 // Не может быть нулём.
ua1arn 21:85a0f94a84cd 597 const uint_fast32_t bmaControls =
ua1arn 21:85a0f94a84cd 598 AUDIO_CONTROL_MUTE |
ua1arn 21:85a0f94a84cd 599 AUDIO_CONTROL_VOLUME |
ua1arn 21:85a0f94a84cd 600 //AUDIO_CONTROL_AUTOMATIC_GAIN |
ua1arn 21:85a0f94a84cd 601 //AUDIO_CONTROL_GRAPHIC_EQUALIZER |
ua1arn 21:85a0f94a84cd 602 //AUDIO_CONTROL_LOUDNESS | // "Custom" property page added
ua1arn 21:85a0f94a84cd 603 0;
ua1arn 21:85a0f94a84cd 604
ua1arn 21:85a0f94a84cd 605 const uint_fast8_t n = 1; // 1: Only master channel controls, 3: master, left and right
ua1arn 21:85a0f94a84cd 606 const uint_fast8_t bControlSize = 2; /* Достаточно, чтобы вместить все определенные для bmaControls биты */
ua1arn 21:85a0f94a84cd 607 const uint_fast8_t length = 7 + bControlSize * n;
ua1arn 21:85a0f94a84cd 608 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 609 if (maxsize < length)
ua1arn 21:85a0f94a84cd 610 return 0;
ua1arn 21:85a0f94a84cd 611 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 612 {
ua1arn 21:85a0f94a84cd 613 uint_fast8_t i;
ua1arn 21:85a0f94a84cd 614 // See 4.3.2.5 Feature Unit Descriptor for details
ua1arn 21:85a0f94a84cd 615 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 616 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE;/* bDescriptorType */
ua1arn 21:85a0f94a84cd 617 * buff ++ = AUDIO_CONTROL_FEATURE_UNIT; /* bDescriptorSubtype */
ua1arn 21:85a0f94a84cd 618 * buff ++ = bUnitID; /* bUnitID */
ua1arn 21:85a0f94a84cd 619 * buff ++ = bSourceID; /* bSourceID */
ua1arn 21:85a0f94a84cd 620 * buff ++ = bControlSize; /* bControlSize - колтчество элементов в следующем элементе, повторяющемся для каждого канала */
ua1arn 21:85a0f94a84cd 621 for (i = 0; i < n; ++ i)
ua1arn 21:85a0f94a84cd 622 {
ua1arn 21:85a0f94a84cd 623 uint_fast32_t v = bmaControls;
ua1arn 21:85a0f94a84cd 624 uint_fast8_t cs = bControlSize;
ua1arn 21:85a0f94a84cd 625 while (cs --)
ua1arn 21:85a0f94a84cd 626 {
ua1arn 21:85a0f94a84cd 627 * buff ++ = (uint8_t) v;
ua1arn 21:85a0f94a84cd 628 v >>= 8;
ua1arn 21:85a0f94a84cd 629 }
ua1arn 21:85a0f94a84cd 630 }
ua1arn 21:85a0f94a84cd 631 * buff ++ = 0;//STRING_ID_b; /* iTerminal */
ua1arn 21:85a0f94a84cd 632 /* 10 byte*/
ua1arn 21:85a0f94a84cd 633 }
ua1arn 21:85a0f94a84cd 634 return length;
ua1arn 21:85a0f94a84cd 635 }
ua1arn 21:85a0f94a84cd 636
ua1arn 21:85a0f94a84cd 637 //
ua1arn 21:85a0f94a84cd 638 // Если выход AUDIO_TERMINAL_RADIO_TRANSMITTER, закладки enchancements нет
ua1arn 21:85a0f94a84cd 639 // Audio Control Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 640 // bSourceID -> bTerminalID
ua1arn 21:85a0f94a84cd 641 // audio48 only
ua1arn 21:85a0f94a84cd 642 static unsigned UAC_AudioControlOT_OUT(
ua1arn 21:85a0f94a84cd 643 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 644 uint_fast8_t bTerminalID,
ua1arn 21:85a0f94a84cd 645 uint_fast8_t bSourceID
ua1arn 21:85a0f94a84cd 646 )
ua1arn 21:85a0f94a84cd 647 {
ua1arn 21:85a0f94a84cd 648 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 649 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 650 if (maxsize < length)
ua1arn 21:85a0f94a84cd 651 return 0;
ua1arn 21:85a0f94a84cd 652 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 653 {
ua1arn 21:85a0f94a84cd 654 // 4.3.2.2 Output Terminal Descriptor
ua1arn 21:85a0f94a84cd 655 const uint_fast16_t wTerminalType = AUDIO_TERMINAL_RADIO_TRANSMITTER;
ua1arn 21:85a0f94a84cd 656
ua1arn 21:85a0f94a84cd 657 * buff ++ = length; /* 0 bLength */
ua1arn 21:85a0f94a84cd 658 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE;/* 1 bDescriptorType */
ua1arn 21:85a0f94a84cd 659 * buff ++ = AUDIO_CONTROL_OUTPUT_TERMINAL; /* 2 bDescriptorSubtype */
ua1arn 21:85a0f94a84cd 660 * buff ++ = bTerminalID; /* 3 bTerminalID */
ua1arn 21:85a0f94a84cd 661 * buff ++ = LO_BYTE(wTerminalType); /* 4 wTerminalType */
ua1arn 21:85a0f94a84cd 662 * buff ++ = HI_BYTE(wTerminalType);
ua1arn 21:85a0f94a84cd 663 * buff ++ = TERMINAL_ID_UNDEFINED; /* 6 bAssocTerminal */
ua1arn 21:85a0f94a84cd 664 * buff ++ = bSourceID; /* 7 bSourceID */
ua1arn 21:85a0f94a84cd 665 * buff ++ = 0; /* 8 iTerminal*/
ua1arn 21:85a0f94a84cd 666 /* 9 byte*/
ua1arn 21:85a0f94a84cd 667 }
ua1arn 21:85a0f94a84cd 668 return length;
ua1arn 21:85a0f94a84cd 669 }
ua1arn 21:85a0f94a84cd 670
ua1arn 21:85a0f94a84cd 671 #define WITHUSENOFU 0 // 1 - без использования Feature Unit, 0 - с использованием, игнорирование управления громкостью
ua1arn 21:85a0f94a84cd 672
ua1arn 21:85a0f94a84cd 673 // Заполнение схемы ввода звука
ua1arn 21:85a0f94a84cd 674 // IN data flow
ua1arn 21:85a0f94a84cd 675 static unsigned UAC_AudioControlIfCircuitIN(uint_fast8_t fill, uint8_t * p, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 676 {
ua1arn 21:85a0f94a84cd 677 unsigned n = 0;
ua1arn 21:85a0f94a84cd 678
ua1arn 21:85a0f94a84cd 679 if (WITHUSENOFU)
ua1arn 21:85a0f94a84cd 680 {
ua1arn 21:85a0f94a84cd 681 // Только один источник для компьютера
ua1arn 21:85a0f94a84cd 682 n += UAC_AudioControlIT_IN(fill, p + n, maxsize - n, TERMINAL_ID_IT_2 + offset, offset); /* AUDIO_TERMINAL_RADIO_RECEIVER */
ua1arn 21:85a0f94a84cd 683 n += UAC_AudioControlOT_IN(fill, p + n, maxsize - n, TERMINAL_ID_OT_4 + offset, TERMINAL_ID_IT_2 + offset, offset); /* AUDIO_TERMINAL_USB_STREAMING Terminal Descriptor TERMINAL_ID_IT_2 -> TERMINAL_ID_OT_4 */
ua1arn 21:85a0f94a84cd 684 }
ua1arn 21:85a0f94a84cd 685 else
ua1arn 21:85a0f94a84cd 686 {
ua1arn 21:85a0f94a84cd 687 // Только один источник для компьютера
ua1arn 21:85a0f94a84cd 688 n += UAC_AudioControlIT_IN(fill, p + n, maxsize - n, TERMINAL_ID_IT_2 + offset, offset); /* AUDIO_TERMINAL_RADIO_RECEIVER */
ua1arn 21:85a0f94a84cd 689 n += UAC_AudioFeatureUnit(fill, p + n, maxsize - n, TERMINAL_ID_FU_AUDIO + offset, TERMINAL_ID_IT_2 + offset); /* USB microphone Audio Feature Unit Descriptor TERMINAL_ID_IT_1 -> TERMINAL_ID_FU_AUDIO */
ua1arn 21:85a0f94a84cd 690 n += UAC_AudioControlOT_IN(fill, p + n, maxsize - n, TERMINAL_ID_OT_4 + offset, TERMINAL_ID_FU_AUDIO + offset, offset); /* AUDIO_TERMINAL_USB_STREAMING Terminal Descriptor TERMINAL_ID_FU_AUDIO -> TERMINAL_ID_OT_4 */
ua1arn 21:85a0f94a84cd 691 }
ua1arn 21:85a0f94a84cd 692
ua1arn 21:85a0f94a84cd 693 return n;
ua1arn 21:85a0f94a84cd 694 }
ua1arn 21:85a0f94a84cd 695
ua1arn 21:85a0f94a84cd 696 // Заполнение схемы вывода звука
ua1arn 21:85a0f94a84cd 697 // OUT data flow
ua1arn 21:85a0f94a84cd 698 // audio48 only
ua1arn 21:85a0f94a84cd 699 static unsigned UAC_AudioControlIfCircuitOUT(uint_fast8_t fill, uint8_t * p, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 700 {
ua1arn 21:85a0f94a84cd 701 unsigned n = 0;
ua1arn 21:85a0f94a84cd 702
ua1arn 21:85a0f94a84cd 703 if (WITHUSENOFU)
ua1arn 21:85a0f94a84cd 704 {
ua1arn 21:85a0f94a84cd 705 // без feature unit между IT и OT
ua1arn 21:85a0f94a84cd 706 n += UAC_AudioControlIT_OUT(fill, p + n, maxsize - n, TERMINAL_ID_IT_1 + offset, offset); /* AUDIO_TERMINAL_USB_STREAMING Input Terminal Descriptor TERMINAL_ID_IT_1 + offset */
ua1arn 21:85a0f94a84cd 707 n += UAC_AudioControlOT_OUT(fill, p + n, maxsize - n, TERMINAL_ID_OT_3 + offset, TERMINAL_ID_IT_1 + offset); /* AUDIO_TERMINAL_RADIO_TRANSMITTER Output Terminal Descriptor TERMINAL_ID_IT_1 + offset -> TERMINAL_ID_OT_3 + offset */
ua1arn 21:85a0f94a84cd 708 }
ua1arn 21:85a0f94a84cd 709 else
ua1arn 21:85a0f94a84cd 710 {
ua1arn 21:85a0f94a84cd 711 n += UAC_AudioControlIT_OUT(fill, p + n, maxsize - n, TERMINAL_ID_IT_1 + offset, offset); /* AUDIO_TERMINAL_USB_STREAMING Input Terminal Descriptor TERMINAL_ID_IT_1 */
ua1arn 21:85a0f94a84cd 712 n += UAC_AudioFeatureUnit(fill, p + n, maxsize - n, TERMINAL_ID_FU_5 + offset, TERMINAL_ID_IT_1 + offset); /* USB Speaker Audio Feature Unit Descriptor TERMINAL_ID_IT_1 -> TERMINAL_ID_FU_5 */
ua1arn 21:85a0f94a84cd 713 n += UAC_AudioControlOT_OUT(fill, p + n, maxsize - n, TERMINAL_ID_OT_3 + offset, TERMINAL_ID_FU_5 + offset); /* AUDIO_TERMINAL_RADIO_TRANSMITTER Output Terminal Descriptor TERMINAL_ID_FU_5 -> TERMINAL_ID_OT_3 */
ua1arn 21:85a0f94a84cd 714 }
ua1arn 21:85a0f94a84cd 715
ua1arn 21:85a0f94a84cd 716 return n;
ua1arn 21:85a0f94a84cd 717 }
ua1arn 21:85a0f94a84cd 718
ua1arn 21:85a0f94a84cd 719 static unsigned UAC_AudioControlIfCircuitINRTS(uint_fast8_t fill, uint8_t * p, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 720 {
ua1arn 21:85a0f94a84cd 721 unsigned n = 0;
ua1arn 21:85a0f94a84cd 722
ua1arn 21:85a0f94a84cd 723 if (WITHUSENOFU)
ua1arn 21:85a0f94a84cd 724 {
ua1arn 21:85a0f94a84cd 725 // Только один источник для компьютера
ua1arn 21:85a0f94a84cd 726 n += UAC_AudioControlIT_INRTS(fill, p + n, maxsize - n, TERMINAL_ID_ITRTS_2 + offset, offset); /* AUDIO_TERMINAL_RADIO_RECEIVER */
ua1arn 21:85a0f94a84cd 727 n += UAC_AudioControlOT_IN(fill, p + n, maxsize - n, TERMINAL_ID_OTRTS_4 + offset, TERMINAL_ID_ITRTS_2 + offset, offset); /* AUDIO_TERMINAL_USB_STREAMING Terminal Descriptor TERMINAL_ID_IT_2 -> TERMINAL_ID_OT_4 */
ua1arn 21:85a0f94a84cd 728 }
ua1arn 21:85a0f94a84cd 729 else
ua1arn 21:85a0f94a84cd 730 {
ua1arn 21:85a0f94a84cd 731 n += UAC_AudioControlIT_INRTS(fill, p + n, maxsize - n, TERMINAL_ID_ITRTS_2 + offset, offset); /* AUDIO_TERMINAL_RADIO_RECEIVER */
ua1arn 21:85a0f94a84cd 732 n += UAC_AudioFeatureUnit(fill, p + n, maxsize - n, TERMINAL_ID_FU_RTS + offset, TERMINAL_ID_ITRTS_2 + offset); /* USB microphone Audio Feature Unit Descriptor TERMINAL_ID_IT_1 -> TERMINAL_ID_FU_RTS */
ua1arn 21:85a0f94a84cd 733 n += UAC_AudioControlOT_IN(fill, p + n, maxsize - n, TERMINAL_ID_OTRTS_4 + offset, TERMINAL_ID_FU_RTS + offset, offset); /* AUDIO_TERMINAL_USB_STREAMING Terminal Descriptor TERMINAL_ID_IT_2 -> TERMINAL_ID_OT_4 */
ua1arn 21:85a0f94a84cd 734 }
ua1arn 21:85a0f94a84cd 735
ua1arn 21:85a0f94a84cd 736 return n;
ua1arn 21:85a0f94a84cd 737 }
ua1arn 21:85a0f94a84cd 738
ua1arn 21:85a0f94a84cd 739 static unsigned UAC_AudioControlIfCircuits(uint_fast8_t fill, uint8_t * p, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 740 {
ua1arn 21:85a0f94a84cd 741 unsigned n = 0;
ua1arn 21:85a0f94a84cd 742
ua1arn 21:85a0f94a84cd 743 n += UAC_AudioControlIfCircuitIN(fill, p + n, maxsize - n, offset); // Заполнение схемы ввода звука
ua1arn 21:85a0f94a84cd 744 n += UAC_AudioControlIfCircuitOUT(fill, p + n, maxsize - n, offset); // Заполнение схемы вывода звука
ua1arn 21:85a0f94a84cd 745
ua1arn 21:85a0f94a84cd 746 return n;
ua1arn 21:85a0f94a84cd 747 }
ua1arn 21:85a0f94a84cd 748
ua1arn 21:85a0f94a84cd 749
ua1arn 21:85a0f94a84cd 750 /* USB Speaker Class-specific AC Interface Descriptor */
ua1arn 21:85a0f94a84cd 751 // Audio Control Interface Header Descriptor
ua1arn 21:85a0f94a84cd 752 static unsigned UACINOUT_AudioControlIfHeader(
ua1arn 21:85a0f94a84cd 753 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 754 const uint_fast8_t * coll,
ua1arn 21:85a0f94a84cd 755 uint_fast8_t bInCollection,
ua1arn 21:85a0f94a84cd 756 unsigned (* audiocontrolifcircuits)(uint_fast8_t fill, uint8_t * p, unsigned maxsize, uint_fast8_t offset),
ua1arn 21:85a0f94a84cd 757 uint_fast8_t offset
ua1arn 21:85a0f94a84cd 758 )
ua1arn 21:85a0f94a84cd 759 {
ua1arn 21:85a0f94a84cd 760 const uint_fast8_t length = 8 + bInCollection;
ua1arn 21:85a0f94a84cd 761 const unsigned wTotalLength = length + audiocontrolifcircuits(0, buff + length, maxsize - length, offset);
ua1arn 21:85a0f94a84cd 762 uint_fast8_t i;
ua1arn 21:85a0f94a84cd 763 ASSERT(maxsize >= wTotalLength);
ua1arn 21:85a0f94a84cd 764 if (maxsize < wTotalLength)
ua1arn 21:85a0f94a84cd 765 return 0;
ua1arn 21:85a0f94a84cd 766 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 767 {
ua1arn 21:85a0f94a84cd 768 // 4.3.2 Class-Specific AC Interface Descriptor
ua1arn 21:85a0f94a84cd 769 const uint_fast16_t bcdADC = 0x0100; // Revision of class specification - 1.0
ua1arn 21:85a0f94a84cd 770 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 771 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 772 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE;/* bDescriptorType */
ua1arn 21:85a0f94a84cd 773 * buff ++ = AUDIO_CONTROL_HEADER; /* bDescriptorSubtype */
ua1arn 21:85a0f94a84cd 774 * buff ++ = LO_BYTE(bcdADC); /* bcdADC */
ua1arn 21:85a0f94a84cd 775 * buff ++ = HI_BYTE(bcdADC);
ua1arn 21:85a0f94a84cd 776 * buff ++ = LO_BYTE(wTotalLength); /* wTotalLength */
ua1arn 21:85a0f94a84cd 777 * buff ++ = HI_BYTE(wTotalLength);
ua1arn 21:85a0f94a84cd 778 * buff ++ = bInCollection; /* bInCollection=2: 1 - AudioStreaming Out; 2 - AudioStreaming In*/
ua1arn 21:85a0f94a84cd 779 for (i = 0; i < bInCollection; ++ i)
ua1arn 21:85a0f94a84cd 780 * buff ++ = coll [i]; /* baInterfaceNr(i) */
ua1arn 21:85a0f94a84cd 781 /* 10 bytes*/
ua1arn 21:85a0f94a84cd 782 audiocontrolifcircuits(fill, buff, maxsize - length, offset);
ua1arn 21:85a0f94a84cd 783 }
ua1arn 21:85a0f94a84cd 784 return wTotalLength;
ua1arn 21:85a0f94a84cd 785
ua1arn 21:85a0f94a84cd 786 }
ua1arn 21:85a0f94a84cd 787
ua1arn 21:85a0f94a84cd 788 /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */
ua1arn 21:85a0f94a84cd 789 /* Interface 1, Alternate Setting 0 */
ua1arn 21:85a0f94a84cd 790 // USBLyzer: Interface Descriptor 0/0 Audio, 0 Endpoints
ua1arn 21:85a0f94a84cd 791 static unsigned r9fill_10(
ua1arn 21:85a0f94a84cd 792 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 793 uint_fast8_t bInterfaceNumber,
ua1arn 21:85a0f94a84cd 794 uint_fast8_t bAlternateSetting,
ua1arn 21:85a0f94a84cd 795 uint_fast8_t offset
ua1arn 21:85a0f94a84cd 796 )
ua1arn 21:85a0f94a84cd 797 {
ua1arn 21:85a0f94a84cd 798 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 799 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 800 if (maxsize < length)
ua1arn 21:85a0f94a84cd 801 return 0;
ua1arn 21:85a0f94a84cd 802 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 803 {
ua1arn 21:85a0f94a84cd 804 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 805 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 806 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType */
ua1arn 21:85a0f94a84cd 807 * buff ++ = bInterfaceNumber; //; /* bInterfaceNumber */
ua1arn 21:85a0f94a84cd 808 * buff ++ = bAlternateSetting; /* bAlternateSetting - zero-based index */
ua1arn 21:85a0f94a84cd 809 * buff ++ = 0x00; /* bNumEndpoints */
ua1arn 21:85a0f94a84cd 810 * buff ++ = USB_DEVICE_CLASS_AUDIO; /* bInterfaceClass */
ua1arn 21:85a0f94a84cd 811 * buff ++ = AUDIO_SUBCLASS_AUDIOSTREAMING; /* bInterfaceSubClass */
ua1arn 21:85a0f94a84cd 812 * buff ++ = AUDIO_PROTOCOL_UNDEFINED; /* bInterfaceProtocol - unused */
ua1arn 21:85a0f94a84cd 813 * buff ++ = STRING_ID_y0 + offset; /* iInterface - unused */
ua1arn 21:85a0f94a84cd 814 /* 9 byte*/
ua1arn 21:85a0f94a84cd 815 }
ua1arn 21:85a0f94a84cd 816 return length;
ua1arn 21:85a0f94a84cd 817 }
ua1arn 21:85a0f94a84cd 818
ua1arn 21:85a0f94a84cd 819 /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */
ua1arn 21:85a0f94a84cd 820 /* 48000 Hz sample rate, 2 channel, stereo - for stereo signal */
ua1arn 21:85a0f94a84cd 821 /* Interface 1, Alternate Setting 1 */
ua1arn 21:85a0f94a84cd 822 // USBLyzer: Interface Descriptor 1/1 Audio
ua1arn 21:85a0f94a84cd 823 // USBLyzer: Interface Descriptor 1/2 Audio
ua1arn 21:85a0f94a84cd 824 static unsigned r9fill_11(
ua1arn 21:85a0f94a84cd 825 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 826 uint_fast8_t bInterfaceNumber,
ua1arn 21:85a0f94a84cd 827 uint_fast8_t bAlternateSetting,
ua1arn 21:85a0f94a84cd 828 uint_fast8_t offset
ua1arn 21:85a0f94a84cd 829 )
ua1arn 21:85a0f94a84cd 830 {
ua1arn 21:85a0f94a84cd 831 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 832 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 833 if (maxsize < length)
ua1arn 21:85a0f94a84cd 834 return 0;
ua1arn 21:85a0f94a84cd 835 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 836 {
ua1arn 21:85a0f94a84cd 837 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 838 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 839 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType */
ua1arn 21:85a0f94a84cd 840 * buff ++ = bInterfaceNumber; /* bInterfaceNumber */
ua1arn 21:85a0f94a84cd 841 * buff ++ = bAlternateSetting; /* bAlternateSetting - zero-based index */
ua1arn 21:85a0f94a84cd 842 * buff ++ = 0x01; /* bNumEndpoints */
ua1arn 21:85a0f94a84cd 843 * buff ++ = USB_DEVICE_CLASS_AUDIO; /* bInterfaceClass */
ua1arn 21:85a0f94a84cd 844 * buff ++ = AUDIO_SUBCLASS_AUDIOSTREAMING; /* bInterfaceSubClass */
ua1arn 21:85a0f94a84cd 845 * buff ++ = AUDIO_PROTOCOL_UNDEFINED; /* bInterfaceProtocol - unused */
ua1arn 21:85a0f94a84cd 846 * buff ++ = STRING_ID_z0 + offset; /* iInterface - unused */
ua1arn 21:85a0f94a84cd 847 /* 9 byte*/
ua1arn 21:85a0f94a84cd 848 }
ua1arn 21:85a0f94a84cd 849 return length;
ua1arn 21:85a0f94a84cd 850 }
ua1arn 21:85a0f94a84cd 851
ua1arn 21:85a0f94a84cd 852 /* USB Speaker Audio Type I Format Interface Descriptor */
ua1arn 21:85a0f94a84cd 853 // USBLyzer: Audio Streaming Format Type Descriptor
ua1arn 21:85a0f94a84cd 854 static unsigned r9fill_13(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 855 {
ua1arn 21:85a0f94a84cd 856 const uint_fast8_t length = 11;
ua1arn 21:85a0f94a84cd 857 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 858 if (maxsize < length)
ua1arn 21:85a0f94a84cd 859 return 0;
ua1arn 21:85a0f94a84cd 860 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 861 {
ua1arn 21:85a0f94a84cd 862 const uint_fast32_t samplefreq1 = dsp_get_samplerateuacout();
ua1arn 21:85a0f94a84cd 863 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 864 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 865 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType */
ua1arn 21:85a0f94a84cd 866 * buff ++ = AUDIO_STREAMING_FORMAT_TYPE; /* bDescriptorSubtype */
ua1arn 21:85a0f94a84cd 867 * buff ++ = AUDIO_FORMAT_TYPE_I; /* bFormatType */
ua1arn 21:85a0f94a84cd 868 * buff ++ = HARDWARE_USBD_AUDIO_OUT_CHANNELS; /* bNrChannels */
ua1arn 21:85a0f94a84cd 869 * buff ++ = (HARDWARE_USBD_AUDIO_OUT_SAMPLEBITS + 7) / 8; /* bSubFrameSize : 2 Bytes per frame (16bits) */
ua1arn 21:85a0f94a84cd 870 * buff ++ = HARDWARE_USBD_AUDIO_OUT_SAMPLEBITS; /* bBitResolution (16-bits per sample) */
ua1arn 21:85a0f94a84cd 871 * buff ++ = 1; /* bSamFreqType only one frequency supported */
ua1arn 21:85a0f94a84cd 872 * buff ++ = LO_BYTE(samplefreq1); /* Audio sampling frequency coded on 3 bytes */
ua1arn 21:85a0f94a84cd 873 * buff ++ = HI_BYTE(samplefreq1);
ua1arn 21:85a0f94a84cd 874 * buff ++ = HI_24BY(samplefreq1);
ua1arn 21:85a0f94a84cd 875 /* 11 byte*/
ua1arn 21:85a0f94a84cd 876 }
ua1arn 21:85a0f94a84cd 877 return length;
ua1arn 21:85a0f94a84cd 878 }
ua1arn 21:85a0f94a84cd 879
ua1arn 21:85a0f94a84cd 880 /* Endpoint 1 - Standard Descriptor */
ua1arn 21:85a0f94a84cd 881 // out: from computer to our device
ua1arn 21:85a0f94a84cd 882 static unsigned r9fill_14(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bEndpointAddress, int highspeed)
ua1arn 21:85a0f94a84cd 883 {
ua1arn 21:85a0f94a84cd 884 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 885 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 886 if (maxsize < length)
ua1arn 21:85a0f94a84cd 887 return 0;
ua1arn 21:85a0f94a84cd 888 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 889 {
ua1arn 21:85a0f94a84cd 890 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(VIRTUAL_AUDIO_PORT_DATA_SIZE_OUT);
ua1arn 21:85a0f94a84cd 891 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 892 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 893 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType */
ua1arn 21:85a0f94a84cd 894 * buff ++ = bEndpointAddress; /* bEndpointAddress 1 out endpoint*/
ua1arn 21:85a0f94a84cd 895 * buff ++ = USBD_UACOUT_EP_ATTRIBUTES; /* bmAttributes */
ua1arn 21:85a0f94a84cd 896 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 897 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 898 * buff ++ = highspeed ? HSINTERVAL_AUDIO48 : FSINTERVAL_AUDIO48; /* bInterval */
ua1arn 21:85a0f94a84cd 899 * buff ++ = 0x00; /* bRefresh */
ua1arn 21:85a0f94a84cd 900 * buff ++ = 0; /* bSynchAddress */
ua1arn 21:85a0f94a84cd 901 /* 9 byte*/
ua1arn 21:85a0f94a84cd 902 }
ua1arn 21:85a0f94a84cd 903 return length;
ua1arn 21:85a0f94a84cd 904 }
ua1arn 21:85a0f94a84cd 905
ua1arn 21:85a0f94a84cd 906 /* Endpoint - Audio Streaming Descriptor*/
ua1arn 21:85a0f94a84cd 907 static unsigned r9fill_15(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 908 {
ua1arn 21:85a0f94a84cd 909 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 910 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 911 if (maxsize < length)
ua1arn 21:85a0f94a84cd 912 return 0;
ua1arn 21:85a0f94a84cd 913 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 914 {
ua1arn 21:85a0f94a84cd 915 const uint_fast16_t wLockDelay = 0;
ua1arn 21:85a0f94a84cd 916 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 917 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 918 * buff ++ = AUDIO_ENDPOINT_DESCRIPTOR_TYPE; /* 0x25 bDescriptorType */
ua1arn 21:85a0f94a84cd 919 * buff ++ = AUDIO_ENDPOINT_GENERAL; /* 0x01 bDescriptor */
ua1arn 21:85a0f94a84cd 920 * buff ++ = 0x00; /* bmAttributes */
ua1arn 21:85a0f94a84cd 921 * buff ++ = 0x00; /* bLockDelayUnits */
ua1arn 21:85a0f94a84cd 922 * buff ++ = LO_BYTE(wLockDelay); /* wLockDelay */
ua1arn 21:85a0f94a84cd 923 * buff ++ = HI_BYTE(wLockDelay);
ua1arn 21:85a0f94a84cd 924 /* 07 byte*/
ua1arn 21:85a0f94a84cd 925 }
ua1arn 21:85a0f94a84cd 926 return length;
ua1arn 21:85a0f94a84cd 927 }
ua1arn 21:85a0f94a84cd 928
ua1arn 21:85a0f94a84cd 929 // Interface Descriptor 2/1 Audio, 1 Endpoint
ua1arn 21:85a0f94a84cd 930 static unsigned r9fill_24(
ua1arn 21:85a0f94a84cd 931 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 932 uint_fast8_t bInterfaceNumber,
ua1arn 21:85a0f94a84cd 933 uint_fast8_t bAlternateSetting,
ua1arn 21:85a0f94a84cd 934 uint_fast8_t bNumEndpoints, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 935 {
ua1arn 21:85a0f94a84cd 936 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 937 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 938 if (maxsize < length)
ua1arn 21:85a0f94a84cd 939 return 0;
ua1arn 21:85a0f94a84cd 940 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 941 {
ua1arn 21:85a0f94a84cd 942 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 943 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 944 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; // INTERFACE descriptor type (bDescriptorType)
ua1arn 21:85a0f94a84cd 945 * buff ++ = bInterfaceNumber; // Index of this interface. (bInterfaceNumber)
ua1arn 21:85a0f94a84cd 946 * buff ++ = bAlternateSetting; // Index of this alternate setting. (bAlternateSetting) - zero-based index
ua1arn 21:85a0f94a84cd 947 * buff ++ = bNumEndpoints; // bNumEndpoints
ua1arn 21:85a0f94a84cd 948 * buff ++ = USB_DEVICE_CLASS_AUDIO; // AUDIO (bInterfaceClass)
ua1arn 21:85a0f94a84cd 949 * buff ++ = AUDIO_SUBCLASS_AUDIOSTREAMING; // AUDIO_STREAMING (bInterfaceSubclass)
ua1arn 21:85a0f94a84cd 950 * buff ++ = AUDIO_PROTOCOL_UNDEFINED; /* bInterfaceProtocol */
ua1arn 21:85a0f94a84cd 951 * buff ++ = STRING_ID_x0 + offset; /* Unused iInterface */
ua1arn 21:85a0f94a84cd 952 /* 9 byte*/
ua1arn 21:85a0f94a84cd 953 }
ua1arn 21:85a0f94a84cd 954 return length;
ua1arn 21:85a0f94a84cd 955 }
ua1arn 21:85a0f94a84cd 956
ua1arn 21:85a0f94a84cd 957 #if ! WITHRTSNOAUDIO
ua1arn 21:85a0f94a84cd 958 /* USB Microphone Type I Format Type Descriptor (CODE == 6)*/
ua1arn 21:85a0f94a84cd 959 // Audio Streaming Format Type Descriptor
ua1arn 21:85a0f94a84cd 960 static unsigned UAC_r9fill_26_audio48(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 961 {
ua1arn 21:85a0f94a84cd 962 const uint_fast8_t length = 11;
ua1arn 21:85a0f94a84cd 963 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 964 if (maxsize < length)
ua1arn 21:85a0f94a84cd 965 return 0;
ua1arn 21:85a0f94a84cd 966 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 967 {
ua1arn 21:85a0f94a84cd 968 const uint_fast32_t samplefreq1 = dsp_get_samplerateuacin_audio48();
ua1arn 21:85a0f94a84cd 969 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 970 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 971 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE;// CS_INTERFACE Descriptor Type (bDescriptorType) 0x24
ua1arn 21:85a0f94a84cd 972 * buff ++ = AUDIO_STREAMING_FORMAT_TYPE; // FORMAT_TYPE subtype. (bDescriptorSubtype) 0x02
ua1arn 21:85a0f94a84cd 973 * buff ++ = AUDIO_FORMAT_TYPE_I; /* bFormatType */
ua1arn 21:85a0f94a84cd 974 * buff ++ = HARDWARE_USBD_AUDIO_IN_CHANNELS_AUDIO48; /* bNrChannels */
ua1arn 21:85a0f94a84cd 975 * buff ++ = (HARDWARE_USBD_AUDIO_IN_SAMPLEBITS_AUDIO48 + 7) / 8; /* bSubFrameSize : 2 Bytes per frame (16bits) */
ua1arn 21:85a0f94a84cd 976 * buff ++ = HARDWARE_USBD_AUDIO_IN_SAMPLEBITS_AUDIO48; /* bBitResolution (16-bits per sample) */
ua1arn 21:85a0f94a84cd 977 * buff ++ = 1; /* bSamFreqType only one frequency supported */
ua1arn 21:85a0f94a84cd 978 * buff ++ = LO_BYTE(samplefreq1); /* Audio sampling frequency coded on 3 bytes */
ua1arn 21:85a0f94a84cd 979 * buff ++ = HI_BYTE(samplefreq1);
ua1arn 21:85a0f94a84cd 980 * buff ++ = HI_24BY(samplefreq1);
ua1arn 21:85a0f94a84cd 981 }
ua1arn 21:85a0f94a84cd 982 return length;
ua1arn 21:85a0f94a84cd 983 }
ua1arn 21:85a0f94a84cd 984
ua1arn 21:85a0f94a84cd 985 /* USB Microphone Standard Endpoint Descriptor (CODE == 8)*/ //Standard AS Isochronous Audio Data Endpoint Descriptor
ua1arn 21:85a0f94a84cd 986 // Endpoint Descriptor 82 2 In, Isochronous, 125 us
ua1arn 21:85a0f94a84cd 987 static unsigned UAC_r9fill_27_audio48(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, int highspeed, uint_fast8_t bEndpointAddress, uint8_t offset)
ua1arn 21:85a0f94a84cd 988 {
ua1arn 21:85a0f94a84cd 989 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 990 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 991 if (maxsize < length)
ua1arn 21:85a0f94a84cd 992 return 0;
ua1arn 21:85a0f94a84cd 993 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 994 {
ua1arn 21:85a0f94a84cd 995 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(VIRTUAL_AUDIO_PORT_DATA_SIZE_IN_AUDIO48); // was: 0x300
ua1arn 21:85a0f94a84cd 996 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 997 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 998 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; // bDescriptorType
ua1arn 21:85a0f94a84cd 999 * buff ++ = bEndpointAddress; // bEndpointAddress
ua1arn 21:85a0f94a84cd 1000 * buff ++ = USBD_UACIN_EP_ATTRIBUTES; // bmAttributes
ua1arn 21:85a0f94a84cd 1001 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1002 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1003 * buff ++ = highspeed ? HSINTERVAL_AUDIO48 : FSINTERVAL_AUDIO48; /* bInterval */
ua1arn 21:85a0f94a84cd 1004 * buff ++ = 0x00; // Unused. (bRefresh)
ua1arn 21:85a0f94a84cd 1005 * buff ++ = 0x00; // Unused. (bSynchAddress)
ua1arn 21:85a0f94a84cd 1006 }
ua1arn 21:85a0f94a84cd 1007 return length;
ua1arn 21:85a0f94a84cd 1008 }
ua1arn 21:85a0f94a84cd 1009 #endif /* ! WITHRTSNOAUDIO */
ua1arn 21:85a0f94a84cd 1010
ua1arn 21:85a0f94a84cd 1011 #if WITHRTS96
ua1arn 21:85a0f94a84cd 1012
ua1arn 21:85a0f94a84cd 1013 /* USB Microphone Type I Format Type Descriptor (CODE == 6)*/
ua1arn 21:85a0f94a84cd 1014 // Audio Streaming Format Type Descriptor
ua1arn 21:85a0f94a84cd 1015 static unsigned UAC_r9fill_26_rts96(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1016 {
ua1arn 21:85a0f94a84cd 1017 const uint_fast8_t length = 11;
ua1arn 21:85a0f94a84cd 1018 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1019 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1020 return 0;
ua1arn 21:85a0f94a84cd 1021 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1022 {
ua1arn 21:85a0f94a84cd 1023 const uint_fast32_t samplefreq1 = dsp_get_samplerateuacin_rts96();
ua1arn 21:85a0f94a84cd 1024 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1025 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1026 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE;// CS_INTERFACE Descriptor Type (bDescriptorType) 0x24
ua1arn 21:85a0f94a84cd 1027 * buff ++ = AUDIO_STREAMING_FORMAT_TYPE; // FORMAT_TYPE subtype. (bDescriptorSubtype) 0x02
ua1arn 21:85a0f94a84cd 1028 * buff ++ = AUDIO_FORMAT_TYPE_I; /* bFormatType */
ua1arn 21:85a0f94a84cd 1029 * buff ++ = HARDWARE_USBD_AUDIO_IN_CHANNELS_RTS; /* bNrChannels */
ua1arn 21:85a0f94a84cd 1030 * buff ++ = (HARDWARE_USBD_AUDIO_IN_SAMPLEBITS_RTS96 + 7) / 8; /* bSubFrameSize : 2 Bytes per frame (16bits) */
ua1arn 21:85a0f94a84cd 1031 * buff ++ = HARDWARE_USBD_AUDIO_IN_SAMPLEBITS_RTS96; /* bBitResolution (16-bits per sample) */
ua1arn 21:85a0f94a84cd 1032 * buff ++ = 1; /* bSamFreqType only one frequency supported */
ua1arn 21:85a0f94a84cd 1033 * buff ++ = LO_BYTE(samplefreq1); /* Audio sampling frequency coded on 3 bytes */
ua1arn 21:85a0f94a84cd 1034 * buff ++ = HI_BYTE(samplefreq1);
ua1arn 21:85a0f94a84cd 1035 * buff ++ = HI_24BY(samplefreq1);
ua1arn 21:85a0f94a84cd 1036 }
ua1arn 21:85a0f94a84cd 1037 return length;
ua1arn 21:85a0f94a84cd 1038 }
ua1arn 21:85a0f94a84cd 1039
ua1arn 21:85a0f94a84cd 1040 /* USB Microphone Standard Endpoint Descriptor (CODE == 8)*/ //Standard AS Isochronous Audio Data Endpoint Descriptor
ua1arn 21:85a0f94a84cd 1041 // Endpoint Descriptor 82 2 In, Isochronous, 125 us
ua1arn 21:85a0f94a84cd 1042 static unsigned UAC_r9fill_27_rts96(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, int highspeed, uint_fast8_t bEndpointAddress, uint8_t offset)
ua1arn 21:85a0f94a84cd 1043 {
ua1arn 21:85a0f94a84cd 1044 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 1045 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1046 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1047 return 0;
ua1arn 21:85a0f94a84cd 1048 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1049 {
ua1arn 21:85a0f94a84cd 1050 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(VIRTUAL_AUDIO_PORT_DATA_SIZE_IN_RTS96); // was: 0x300
ua1arn 21:85a0f94a84cd 1051 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1052 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1053 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; // bDescriptorType
ua1arn 21:85a0f94a84cd 1054 * buff ++ = bEndpointAddress; // bEndpointAddress
ua1arn 21:85a0f94a84cd 1055 * buff ++ = USBD_UACIN_EP_ATTRIBUTES; // bmAttributes
ua1arn 21:85a0f94a84cd 1056 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1057 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1058 * buff ++ = highspeed ? HSINTERVAL_RTS96 : FSINTERVAL_RTS96; /* bInterval */
ua1arn 21:85a0f94a84cd 1059 * buff ++ = 0x00; // Unused. (bRefresh)
ua1arn 21:85a0f94a84cd 1060 * buff ++ = 0x00; // Unused. (bSynchAddress)
ua1arn 21:85a0f94a84cd 1061 }
ua1arn 21:85a0f94a84cd 1062 return length;
ua1arn 21:85a0f94a84cd 1063 }
ua1arn 21:85a0f94a84cd 1064
ua1arn 21:85a0f94a84cd 1065 #endif /* WITHRTS96 */
ua1arn 21:85a0f94a84cd 1066
ua1arn 21:85a0f94a84cd 1067 #if WITHRTS192
ua1arn 21:85a0f94a84cd 1068
ua1arn 21:85a0f94a84cd 1069 /* USB Microphone Type I Format Type Descriptor (CODE == 6)*/
ua1arn 21:85a0f94a84cd 1070 // Audio Streaming Format Type Descriptor
ua1arn 21:85a0f94a84cd 1071 static unsigned UAC_r9fill_26_rts192(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1072 {
ua1arn 21:85a0f94a84cd 1073 const uint_fast8_t length = 11;
ua1arn 21:85a0f94a84cd 1074 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1075 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1076 return 0;
ua1arn 21:85a0f94a84cd 1077 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1078 {
ua1arn 21:85a0f94a84cd 1079 const uint_fast32_t samplefreq1 = dsp_get_samplerateuacin_rts192();
ua1arn 21:85a0f94a84cd 1080 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1081 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1082 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE;// CS_INTERFACE Descriptor Type (bDescriptorType) 0x24
ua1arn 21:85a0f94a84cd 1083 * buff ++ = AUDIO_STREAMING_FORMAT_TYPE; // FORMAT_TYPE subtype. (bDescriptorSubtype) 0x02
ua1arn 21:85a0f94a84cd 1084 * buff ++ = AUDIO_FORMAT_TYPE_I; /* bFormatType */
ua1arn 21:85a0f94a84cd 1085 * buff ++ = HARDWARE_USBD_AUDIO_IN_CHANNELS_RTS; /* bNrChannels */
ua1arn 21:85a0f94a84cd 1086 * buff ++ = (HARDWARE_USBD_AUDIO_IN_SAMPLEBITS_RTS192 + 7) / 8; /* bSubFrameSize : 2 Bytes per frame (16bits) */
ua1arn 21:85a0f94a84cd 1087 * buff ++ = HARDWARE_USBD_AUDIO_IN_SAMPLEBITS_RTS192; /* bBitResolution (16-bits per sample) */
ua1arn 21:85a0f94a84cd 1088 * buff ++ = 1; /* bSamFreqType only one frequency supported */
ua1arn 21:85a0f94a84cd 1089 * buff ++ = LO_BYTE(samplefreq1); /* Audio sampling frequency coded on 3 bytes */
ua1arn 21:85a0f94a84cd 1090 * buff ++ = HI_BYTE(samplefreq1);
ua1arn 21:85a0f94a84cd 1091 * buff ++ = HI_24BY(samplefreq1);
ua1arn 21:85a0f94a84cd 1092 }
ua1arn 21:85a0f94a84cd 1093 return length;
ua1arn 21:85a0f94a84cd 1094 }
ua1arn 21:85a0f94a84cd 1095
ua1arn 21:85a0f94a84cd 1096 /* USB Microphone Standard Endpoint Descriptor (CODE == 8)*/ //Standard AS Isochronous Audio Data Endpoint Descriptor
ua1arn 21:85a0f94a84cd 1097 // Endpoint Descriptor 82 2 In, Isochronous, 125 us
ua1arn 21:85a0f94a84cd 1098 static unsigned UAC_r9fill_27_rts192(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, int highspeed, uint_fast8_t bEndpointAddress, uint8_t offset)
ua1arn 21:85a0f94a84cd 1099 {
ua1arn 21:85a0f94a84cd 1100 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 1101 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1102 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1103 return 0;
ua1arn 21:85a0f94a84cd 1104 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1105 {
ua1arn 21:85a0f94a84cd 1106 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(VIRTUAL_AUDIO_PORT_DATA_SIZE_IN_RTS192); // was: 0x300
ua1arn 21:85a0f94a84cd 1107 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1108 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1109 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; // bDescriptorType
ua1arn 21:85a0f94a84cd 1110 * buff ++ = bEndpointAddress; // bEndpointAddress
ua1arn 21:85a0f94a84cd 1111 * buff ++ = USBD_UACIN_EP_ATTRIBUTES; // bmAttributes
ua1arn 21:85a0f94a84cd 1112 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1113 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1114 * buff ++ = highspeed ? HSINTERVAL_RTS192 : FSINTERVAL_RTS192; /* bInterval */
ua1arn 21:85a0f94a84cd 1115 * buff ++ = 0x00; // Unused. (bRefresh)
ua1arn 21:85a0f94a84cd 1116 * buff ++ = 0x00; // Unused. (bSynchAddress)
ua1arn 21:85a0f94a84cd 1117 }
ua1arn 21:85a0f94a84cd 1118 return length;
ua1arn 21:85a0f94a84cd 1119 }
ua1arn 21:85a0f94a84cd 1120
ua1arn 21:85a0f94a84cd 1121 #endif /* WITHRTS192 */
ua1arn 21:85a0f94a84cd 1122
ua1arn 21:85a0f94a84cd 1123 /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - подтверждено документацией*/
ua1arn 21:85a0f94a84cd 1124 static unsigned r9fill_28(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1125 {
ua1arn 21:85a0f94a84cd 1126 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1127 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1128 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1129 return 0;
ua1arn 21:85a0f94a84cd 1130 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1131 {
ua1arn 21:85a0f94a84cd 1132 const uint_fast16_t wLockDelay = 0;
ua1arn 21:85a0f94a84cd 1133 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1134 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1135 * buff ++ = AUDIO_ENDPOINT_DESCRIPTOR_TYPE; // CS_ENDPOINT Descriptor Type (bDescriptorType) 0x25
ua1arn 21:85a0f94a84cd 1136 * buff ++ = AUDIO_ENDPOINT_GENERAL; // GENERAL subtype. (bDescriptorSubtype) 0x01
ua1arn 21:85a0f94a84cd 1137 * buff ++ = 0x00; // No sampling frequency control; no pitch control; no packet padding.(bmAttributes)
ua1arn 21:85a0f94a84cd 1138 * buff ++ = 0x02; // bLockDelayUnits
ua1arn 21:85a0f94a84cd 1139 * buff ++ = LO_BYTE(wLockDelay); /* wLockDelay */
ua1arn 21:85a0f94a84cd 1140 * buff ++ = HI_BYTE(wLockDelay);
ua1arn 21:85a0f94a84cd 1141 }
ua1arn 21:85a0f94a84cd 1142 return length;
ua1arn 21:85a0f94a84cd 1143 }
ua1arn 21:85a0f94a84cd 1144
ua1arn 21:85a0f94a84cd 1145
ua1arn 21:85a0f94a84cd 1146 /* USB Speaker Audio Streaming Interface Descriptor */
ua1arn 21:85a0f94a84cd 1147 // USBLyzer: Audio Streaming Interface Descriptor
ua1arn 21:85a0f94a84cd 1148 // audio10.pdf: Table 4-19: Class-Specific AS Interface Descriptor
ua1arn 21:85a0f94a84cd 1149 static unsigned UAC_AudioStreamingIf(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bTerminalLink)
ua1arn 21:85a0f94a84cd 1150 {
ua1arn 21:85a0f94a84cd 1151 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1152 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1153 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1154 return 0;
ua1arn 21:85a0f94a84cd 1155 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1156 {
ua1arn 21:85a0f94a84cd 1157 const uint_fast16_t wFormatTag = AUDIO_FORMAT_PCM; /* wFormatTag */
ua1arn 21:85a0f94a84cd 1158 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1159 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1160 * buff ++ = AUDIO_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType CS_INTERFACE */
ua1arn 21:85a0f94a84cd 1161 * buff ++ = AUDIO_STREAMING_GENERAL; /* bDescriptorSubtype AS_GENERAL */
ua1arn 21:85a0f94a84cd 1162 * buff ++ = bTerminalLink; /* bTerminalLink */
ua1arn 21:85a0f94a84cd 1163 * buff ++ = 0x01; /* bDelay */
ua1arn 21:85a0f94a84cd 1164 * buff ++ = LO_BYTE(wFormatTag); /* wFormatTag - Audio Data Format that */
ua1arn 21:85a0f94a84cd 1165 * buff ++ = HI_BYTE(wFormatTag);
ua1arn 21:85a0f94a84cd 1166 /* 07 byte*/
ua1arn 21:85a0f94a84cd 1167 }
ua1arn 21:85a0f94a84cd 1168 return length;
ua1arn 21:85a0f94a84cd 1169 }
ua1arn 21:85a0f94a84cd 1170
ua1arn 21:85a0f94a84cd 1171 #if WITHUSBUAC3
ua1arn 21:85a0f94a84cd 1172
ua1arn 21:85a0f94a84cd 1173 // UNUSED
ua1arn 21:85a0f94a84cd 1174 static unsigned UAC_AudioControlIfCircuitsAUDIOandRTS(uint_fast8_t fill, uint8_t * p, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1175 {
ua1arn 21:85a0f94a84cd 1176 unsigned n = 0;
ua1arn 21:85a0f94a84cd 1177
ua1arn 21:85a0f94a84cd 1178 n += UAC_AudioControlIfCircuits(fill, p + n, maxsize - n, offset); // Заполнение схемы ввода звука
ua1arn 21:85a0f94a84cd 1179 n += UAC_AudioControlIfCircuitINRTS(fill, p + n, maxsize - n, offset); // Заполнение схемы ввода звука
ua1arn 21:85a0f94a84cd 1180
ua1arn 21:85a0f94a84cd 1181 return n;
ua1arn 21:85a0f94a84cd 1182 }
ua1arn 21:85a0f94a84cd 1183
ua1arn 21:85a0f94a84cd 1184 // AUDIO48 and RTS output audio function
ua1arn 21:85a0f94a84cd 1185 // не используется - так как запуск HDSDR & ASIO4ALL сьивает акдиоканал
ua1arn 21:85a0f94a84cd 1186 static unsigned fill_UACINOUT48andRTS_function_UNUSED(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1187 {
ua1arn 21:85a0f94a84cd 1188 unsigned n = 0;
ua1arn 21:85a0f94a84cd 1189 const uint_fast8_t controlifv = INTERFACE_AUDIO_CONTROL_0;
ua1arn 21:85a0f94a84cd 1190 const uint_fast8_t mikeifv = INTERFACE_AUDIO_MIKE_2;
ua1arn 21:85a0f94a84cd 1191 const uint_fast8_t modulatorifv = INTERFACE_AUDIO_SPK_1;
ua1arn 21:85a0f94a84cd 1192 const uint_fast8_t rtsifv = INTERFACE_AUDIO_RTS_3;
ua1arn 21:85a0f94a84cd 1193 const uint_fast8_t coll [] =
ua1arn 21:85a0f94a84cd 1194 {
ua1arn 21:85a0f94a84cd 1195 modulatorifv,
ua1arn 21:85a0f94a84cd 1196 mikeifv,
ua1arn 21:85a0f94a84cd 1197 rtsifv,
ua1arn 21:85a0f94a84cd 1198 };
ua1arn 21:85a0f94a84cd 1199
ua1arn 21:85a0f94a84cd 1200 const uint_fast8_t epin = USB_ENDPOINT_IN(USBD_EP_AUDIO_IN);
ua1arn 21:85a0f94a84cd 1201 const uint_fast8_t epout = USB_ENDPOINT_OUT(USBD_EP_AUDIO_OUT);
ua1arn 21:85a0f94a84cd 1202 const uint_fast8_t epinrts = USB_ENDPOINT_IN(USBD_EP_RTS_IN);
ua1arn 21:85a0f94a84cd 1203
ua1arn 21:85a0f94a84cd 1204 n += UAC_InterfaceAssociationDescriptor(fill, p + n, maxsize - n, controlifv, 4, offset); /* INTERFACE_AUDIO_CONTROL_0 Interface Association Descriptor Audio */
ua1arn 21:85a0f94a84cd 1205 // INTERFACE_AUDIO_CONTROL_0 - audio conntrol interface
ua1arn 21:85a0f94a84cd 1206 n += r9fill_3(fill, p + n, maxsize - n, controlifv, 0x00, offset); /* INTERFACE_AUDIO_CONTROL_0 - Interface Descriptor 0/0 Audio, 0 Endpoints */
ua1arn 21:85a0f94a84cd 1207 n += UACINOUT_AudioControlIfHeader(fill, p + n, maxsize - n, coll, sizeof coll / sizeof coll [0], UAC_AudioControlIfCircuitsAUDIOandRTS, offset); /* bcdADC Audio Control Interface Header Descriptor */
ua1arn 21:85a0f94a84cd 1208
ua1arn 21:85a0f94a84cd 1209 // OUT data flow: USB Speaker
ua1arn 21:85a0f94a84cd 1210 // INTERFACE_AUDIO_SPK_1 - audio streaming interface
ua1arn 21:85a0f94a84cd 1211 n += r9fill_10(fill, p + n, maxsize - n, modulatorifv, 0x00, offset); /* INTERFACE_AUDIO_SPK_1 - Interface 1, Alternate Setting 0 */
ua1arn 21:85a0f94a84cd 1212
ua1arn 21:85a0f94a84cd 1213 n += r9fill_11(fill, p + n, maxsize - n, modulatorifv, 0x01, offset); /* INTERFACE_AUDIO_SPK_1 - Interface 1, Alternate Setting 1 */
ua1arn 21:85a0f94a84cd 1214 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_IT_1 + offset); /* USB Speaker Audio Streaming Interface Descriptor (for output TERMINAL_ID_IT_1 + offset) */
ua1arn 21:85a0f94a84cd 1215 n += r9fill_13(fill, p + n, maxsize - n); /* USB Speaker Audio Type I Format Interface Descriptor (one sample rate) 48000 */
ua1arn 21:85a0f94a84cd 1216 n += r9fill_14(fill, p + n, maxsize - n, epout, highspeed); /* Endpoint USBD_EP_AUDIO_OUT - Standard Descriptor */
ua1arn 21:85a0f94a84cd 1217 n += r9fill_15(fill, p + n, maxsize - n); /* Endpoint - Audio Streaming Descriptor */
ua1arn 21:85a0f94a84cd 1218 // IN data flow: USB Microphone
ua1arn 21:85a0f94a84cd 1219 // INTERFACE_AUDIO_MIKE_2 - audio streaming interface
ua1arn 21:85a0f94a84cd 1220 n += r9fill_24(fill, p + n, maxsize - n, mikeifv, UACINALT_NONE, 0, offset); /* USB Microphone Standard AS Interface Descriptor (Alt. Set. 0) (CODE == 3) */ //zero-bandwidth interface
ua1arn 21:85a0f94a84cd 1221
ua1arn 21:85a0f94a84cd 1222 // IN data flow: radio RX audio data
ua1arn 21:85a0f94a84cd 1223 n += r9fill_24(fill, p + n, maxsize - n, mikeifv, UACINALT_AUDIO48, 1, offset); /* INTERFACE_AUDIO_MIKE_2 Interface Descriptor 2/1 Audio, 1 Endpoint, bAlternateSetting=0x01 */
ua1arn 21:85a0f94a84cd 1224 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_OT_4 + offset); /* USB Microphone Class-specific AS General Interface Descriptor (for output TERMINAL_ID_OT_4) (CODE == 5) */
ua1arn 21:85a0f94a84cd 1225 n += UAC_r9fill_26_audio48(fill, p + n, maxsize - n); /* USB Microphone Type I Format Type Descriptor (CODE == 6) 48000 */
ua1arn 21:85a0f94a84cd 1226 n += UAC_r9fill_27_audio48(fill, p + n, maxsize - n, highspeed, epin, offset); /* Endpoint Descriptor USBD_EP_AUDIO_IN In, Isochronous, 125 us */
ua1arn 21:85a0f94a84cd 1227 n += r9fill_28(fill, p + n, maxsize - n); /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - подтверждено документацией*/
ua1arn 21:85a0f94a84cd 1228
ua1arn 21:85a0f94a84cd 1229 #if WITHRTS96 || WITHRTS192
ua1arn 21:85a0f94a84cd 1230 n += r9fill_24(fill, p + n, maxsize - n, rtsifv, UACINRTSALT_NONE, 0, offset); /* USB Microphone Standard AS Interface Descriptor (Alt. Set. 0) (CODE == 3) */ //zero-bandwidth interface
ua1arn 21:85a0f94a84cd 1231
ua1arn 21:85a0f94a84cd 1232 #if WITHRTS96
ua1arn 21:85a0f94a84cd 1233 // IN data flow: radio RX specrum data
ua1arn 21:85a0f94a84cd 1234 n += r9fill_24(fill, p + n, maxsize - n, rtsifv, UACINRTSALT_RTS96, 1, offset); /* INTERFACE_AUDIO_RTS_2 Interface Descriptor 2/1 Audio, 1 Endpoint, bAlternateSetting=0x01 */
ua1arn 21:85a0f94a84cd 1235 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_OTRTS_4 + offset); /* USB Microphone Class-specific AS General Interface Descriptor (for output TERMINAL_ID_OT_4) (CODE == 5) */
ua1arn 21:85a0f94a84cd 1236 n += UAC_r9fill_26_rts96(fill, p + n, maxsize - n); /* USB Microphone Type I Format Type Descriptor (CODE == 6) 48000 */
ua1arn 21:85a0f94a84cd 1237 n += UAC_r9fill_27_rts96(fill, p + n, maxsize - n, highspeed, epinrts, offset); /* Endpoint Descriptor USBD_EP_AUDIO_IN In, Isochronous, 125 us */
ua1arn 21:85a0f94a84cd 1238 n += r9fill_28(fill, p + n, maxsize - n); /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - подтверждено документацией*/
ua1arn 21:85a0f94a84cd 1239 #endif /* WITHRTS96 */
ua1arn 21:85a0f94a84cd 1240
ua1arn 21:85a0f94a84cd 1241 #if WITHRTS192
ua1arn 21:85a0f94a84cd 1242 // IN data flow: radio RX specrum data
ua1arn 21:85a0f94a84cd 1243 n += r9fill_24(fill, p + n, maxsize - n, rtsifv, UACINRTSALT_RTS192, 1, offset); /* INTERFACE_AUDIO_RTS_2 Interface Descriptor 2/1 Audio, 1 Endpoint, bAlternateSetting=0x01 */
ua1arn 21:85a0f94a84cd 1244 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_OTRTS_4 + offset); /* USB Microphone Class-specific AS General Interface Descriptor (for output TERMINAL_ID_OT_4) (CODE == 5) */
ua1arn 21:85a0f94a84cd 1245 n += UAC_r9fill_26_rts192(fill, p + n, maxsize - n); /* USB Microphone Type I Format Type Descriptor (CODE == 6) 48000 */
ua1arn 21:85a0f94a84cd 1246 n += UAC_r9fill_27_rts192(fill, p + n, maxsize - n, highspeed, epinrts, offset); /* Endpoint Descriptor USBD_EP_AUDIO_IN In, Isochronous, 125 us */
ua1arn 21:85a0f94a84cd 1247 n += r9fill_28(fill, p + n, maxsize - n); /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - подтверждено документацией*/
ua1arn 21:85a0f94a84cd 1248 #endif /* WITHRTS192 */
ua1arn 21:85a0f94a84cd 1249
ua1arn 21:85a0f94a84cd 1250 #endif /* WITHRTS96 || WITHRTS192 */
ua1arn 21:85a0f94a84cd 1251
ua1arn 21:85a0f94a84cd 1252 return n;
ua1arn 21:85a0f94a84cd 1253 }
ua1arn 21:85a0f94a84cd 1254
ua1arn 21:85a0f94a84cd 1255 // AUDIO48 only output audio function
ua1arn 21:85a0f94a84cd 1256 static unsigned fill_UACINOUT48_function(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1257 {
ua1arn 21:85a0f94a84cd 1258 unsigned n = 0;
ua1arn 21:85a0f94a84cd 1259 const uint_fast8_t controlifv = INTERFACE_AUDIO_CONTROL_0;
ua1arn 21:85a0f94a84cd 1260 const uint_fast8_t mikeifv = INTERFACE_AUDIO_MIKE_2;
ua1arn 21:85a0f94a84cd 1261 const uint_fast8_t modulatorifv = INTERFACE_AUDIO_SPK_1;
ua1arn 21:85a0f94a84cd 1262 const uint_fast8_t coll [] =
ua1arn 21:85a0f94a84cd 1263 {
ua1arn 21:85a0f94a84cd 1264 modulatorifv,
ua1arn 21:85a0f94a84cd 1265 mikeifv,
ua1arn 21:85a0f94a84cd 1266 };
ua1arn 21:85a0f94a84cd 1267
ua1arn 21:85a0f94a84cd 1268 const uint_fast8_t epin = USB_ENDPOINT_IN(USBD_EP_AUDIO_IN);
ua1arn 21:85a0f94a84cd 1269 const uint_fast8_t epout = USB_ENDPOINT_OUT(USBD_EP_AUDIO_OUT);
ua1arn 21:85a0f94a84cd 1270
ua1arn 21:85a0f94a84cd 1271 n += UAC_InterfaceAssociationDescriptor(fill, p + n, maxsize - n, controlifv, 3, offset); /* INTERFACE_AUDIO_CONTROL_0 Interface Association Descriptor Audio */
ua1arn 21:85a0f94a84cd 1272 // INTERFACE_AUDIO_CONTROL_0 - audio conntrol interface
ua1arn 21:85a0f94a84cd 1273 n += r9fill_3(fill, p + n, maxsize - n, controlifv, 0x00, offset); /* INTERFACE_AUDIO_CONTROL_0 - Interface Descriptor 0/0 Audio, 0 Endpoints */
ua1arn 21:85a0f94a84cd 1274 n += UACINOUT_AudioControlIfHeader(fill, p + n, maxsize - n, coll, sizeof coll / sizeof coll [0], UAC_AudioControlIfCircuits, offset); /* bcdADC Audio Control Interface Header Descriptor */
ua1arn 21:85a0f94a84cd 1275
ua1arn 21:85a0f94a84cd 1276 // OUT data flow: USB Speaker
ua1arn 21:85a0f94a84cd 1277 // INTERFACE_AUDIO_SPK_1 - audio streaming interface
ua1arn 21:85a0f94a84cd 1278 n += r9fill_10(fill, p + n, maxsize - n, modulatorifv, 0x00, offset); /* INTERFACE_AUDIO_SPK_1 - Interface 1, Alternate Setting 0 */
ua1arn 21:85a0f94a84cd 1279
ua1arn 21:85a0f94a84cd 1280 n += r9fill_11(fill, p + n, maxsize - n, modulatorifv, 0x01, offset); /* INTERFACE_AUDIO_SPK_1 - Interface 1, Alternate Setting 1 */
ua1arn 21:85a0f94a84cd 1281 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_IT_1 + offset); /* USB Speaker Audio Streaming Interface Descriptor (for output TERMINAL_ID_IT_1 + offset) */
ua1arn 21:85a0f94a84cd 1282 n += r9fill_13(fill, p + n, maxsize - n); /* USB Speaker Audio Type I Format Interface Descriptor (one sample rate) 48000 */
ua1arn 21:85a0f94a84cd 1283 n += r9fill_14(fill, p + n, maxsize - n, epout, highspeed); /* Endpoint USBD_EP_AUDIO_OUT - Standard Descriptor */
ua1arn 21:85a0f94a84cd 1284 n += r9fill_15(fill, p + n, maxsize - n); /* Endpoint - Audio Streaming Descriptor */
ua1arn 21:85a0f94a84cd 1285 // IN data flow: USB Microphone
ua1arn 21:85a0f94a84cd 1286 // INTERFACE_AUDIO_MIKE_2 - audio streaming interface
ua1arn 21:85a0f94a84cd 1287 n += r9fill_24(fill, p + n, maxsize - n, mikeifv, UACINALT_NONE, 0, offset); /* USB Microphone Standard AS Interface Descriptor (Alt. Set. 0) (CODE == 3) */ //zero-bandwidth interface
ua1arn 21:85a0f94a84cd 1288
ua1arn 21:85a0f94a84cd 1289 // IN data flow: radio RX audio data
ua1arn 21:85a0f94a84cd 1290 n += r9fill_24(fill, p + n, maxsize - n, mikeifv, UACINALT_AUDIO48, 1, offset); /* INTERFACE_AUDIO_MIKE_2 Interface Descriptor 2/1 Audio, 1 Endpoint, bAlternateSetting=0x01 */
ua1arn 21:85a0f94a84cd 1291 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_OT_4 + offset); /* USB Microphone Class-specific AS General Interface Descriptor (for output TERMINAL_ID_OT_4) (CODE == 5) */
ua1arn 21:85a0f94a84cd 1292 n += UAC_r9fill_26_audio48(fill, p + n, maxsize - n); /* USB Microphone Type I Format Type Descriptor (CODE == 6) 48000 */
ua1arn 21:85a0f94a84cd 1293 n += UAC_r9fill_27_audio48(fill, p + n, maxsize - n, highspeed, epin, offset); /* Endpoint Descriptor USBD_EP_AUDIO_IN In, Isochronous, 125 us */
ua1arn 21:85a0f94a84cd 1294 n += r9fill_28(fill, p + n, maxsize - n); /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - ???????????? ?????????????*/
ua1arn 21:85a0f94a84cd 1295
ua1arn 21:85a0f94a84cd 1296 return n;
ua1arn 21:85a0f94a84cd 1297 }
ua1arn 21:85a0f94a84cd 1298
ua1arn 21:85a0f94a84cd 1299 #if 1
ua1arn 21:85a0f94a84cd 1300
ua1arn 21:85a0f94a84cd 1301
ua1arn 21:85a0f94a84cd 1302 static unsigned UAC_AudioControlIfCircuitsRTS(uint_fast8_t fill, uint8_t * p, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1303 {
ua1arn 21:85a0f94a84cd 1304 unsigned n = 0;
ua1arn 21:85a0f94a84cd 1305
ua1arn 21:85a0f94a84cd 1306 n += UAC_AudioControlIfCircuitINRTS(fill, p + n, maxsize - n, offset); // Заполнение схемы ввода звука
ua1arn 21:85a0f94a84cd 1307
ua1arn 21:85a0f94a84cd 1308 return n;
ua1arn 21:85a0f94a84cd 1309 }
ua1arn 21:85a0f94a84cd 1310
ua1arn 21:85a0f94a84cd 1311 static unsigned fill_UACINRTS_function(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1312 {
ua1arn 21:85a0f94a84cd 1313 unsigned n = 0;
ua1arn 21:85a0f94a84cd 1314 const uint_fast8_t rtscontrolifv = INTERFACE_AUDIO_CONTROL_1;
ua1arn 21:85a0f94a84cd 1315 const uint_fast8_t rtsifv = INTERFACE_AUDIO_RTS_3;
ua1arn 21:85a0f94a84cd 1316
ua1arn 21:85a0f94a84cd 1317 const uint_fast8_t epinrts = USB_ENDPOINT_IN(USBD_EP_RTS_IN);
ua1arn 21:85a0f94a84cd 1318
ua1arn 21:85a0f94a84cd 1319 n += UAC_InterfaceAssociationDescriptor(fill, p + n, maxsize - n, rtscontrolifv, 2, offset); /* INTERFACE_AUDIO_CONTROL_0 Interface Association Descriptor Audio */
ua1arn 21:85a0f94a84cd 1320
ua1arn 21:85a0f94a84cd 1321 // IN data flow: USB Microphone
ua1arn 21:85a0f94a84cd 1322 // INTERFACE_AUDIO_MIKE_2 - audio streaming interface
ua1arn 21:85a0f94a84cd 1323 n += r9fill_3(fill, p + n, maxsize - n, rtscontrolifv, 0x00, offset); /* INTERFACE_AUDIO_CONTROL_2 - Interface Descriptor 0/0 Audio, 0 Endpoints */
ua1arn 21:85a0f94a84cd 1324 n += UACINOUT_AudioControlIfHeader(fill, p + n, maxsize - n, & rtsifv, 1, UAC_AudioControlIfCircuitsRTS, offset); /* bcdADC Audio Control Interface Header Descriptor */
ua1arn 21:85a0f94a84cd 1325 n += r9fill_24(fill, p + n, maxsize - n, rtsifv, UACINRTSALT_NONE, 0, offset); /* USB Microphone Standard AS Interface Descriptor (Alt. Set. 0) (CODE == 3) */ //zero-bandwidth interface
ua1arn 21:85a0f94a84cd 1326
ua1arn 21:85a0f94a84cd 1327 #if WITHRTS96
ua1arn 21:85a0f94a84cd 1328 // IN data flow: radio RX specrum data
ua1arn 21:85a0f94a84cd 1329 n += r9fill_24(fill, p + n, maxsize - n, rtsifv, UACINRTSALT_RTS96, 1, offset); /* INTERFACE_AUDIO_RTS_2 Interface Descriptor 2/1 Audio, 1 Endpoint, bAlternateSetting=0x01 */
ua1arn 21:85a0f94a84cd 1330 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_OTRTS_4 + offset); /* USB Microphone Class-specific AS General Interface Descriptor (for output TERMINAL_ID_OT_4) (CODE == 5) */
ua1arn 21:85a0f94a84cd 1331 n += UAC_r9fill_26_rts96(fill, p + n, maxsize - n); /* USB Microphone Type I Format Type Descriptor (CODE == 6) 48000 */
ua1arn 21:85a0f94a84cd 1332 n += UAC_r9fill_27_rts96(fill, p + n, maxsize - n, highspeed, epinrts, offset); /* Endpoint Descriptor USBD_EP_AUDIO_IN In, Isochronous, 125 us */
ua1arn 21:85a0f94a84cd 1333 n += r9fill_28(fill, p + n, maxsize - n); /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - подтверждено документацией*/
ua1arn 21:85a0f94a84cd 1334 #endif /* WITHRTS96 */
ua1arn 21:85a0f94a84cd 1335
ua1arn 21:85a0f94a84cd 1336 #if WITHRTS192
ua1arn 21:85a0f94a84cd 1337 // IN data flow: radio RX specrum data
ua1arn 21:85a0f94a84cd 1338 n += r9fill_24(fill, p + n, maxsize - n, rtsifv, UACINRTSALT_RTS192, 1, offset); /* INTERFACE_AUDIO_RTS_2 Interface Descriptor 2/1 Audio, 1 Endpoint, bAlternateSetting=0x01 */
ua1arn 21:85a0f94a84cd 1339 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_OTRTS_4 + offset); /* USB Microphone Class-specific AS General Interface Descriptor (for output TERMINAL_ID_OT_4) (CODE == 5) */
ua1arn 21:85a0f94a84cd 1340 n += UAC_r9fill_26_rts192(fill, p + n, maxsize - n); /* USB Microphone Type I Format Type Descriptor (CODE == 6) 48000 */
ua1arn 21:85a0f94a84cd 1341 n += UAC_r9fill_27_rts192(fill, p + n, maxsize - n, highspeed, epinrts, offset); /* Endpoint Descriptor USBD_EP_AUDIO_IN In, Isochronous, 125 us */
ua1arn 21:85a0f94a84cd 1342 n += r9fill_28(fill, p + n, maxsize - n); /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - подтверждено документацией*/
ua1arn 21:85a0f94a84cd 1343 #endif /* WITHRTS192 */
ua1arn 21:85a0f94a84cd 1344 return n;
ua1arn 21:85a0f94a84cd 1345 }
ua1arn 21:85a0f94a84cd 1346 #endif
ua1arn 21:85a0f94a84cd 1347
ua1arn 21:85a0f94a84cd 1348 #else /* WITHUSBUAC3 */
ua1arn 21:85a0f94a84cd 1349
ua1arn 21:85a0f94a84cd 1350 static unsigned fill_UACINOUT_function(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1351 {
ua1arn 21:85a0f94a84cd 1352 unsigned n = 0;
ua1arn 21:85a0f94a84cd 1353 const uint_fast8_t controlifv = INTERFACE_AUDIO_CONTROL_0 + offset * INTERFACE_UAC_count;
ua1arn 21:85a0f94a84cd 1354 const uint_fast8_t mikeifv = INTERFACE_AUDIO_MIKE_2 + offset * INTERFACE_UAC_count;
ua1arn 21:85a0f94a84cd 1355 const uint_fast8_t modulatorifv = INTERFACE_AUDIO_SPK_1 + offset * INTERFACE_UAC_count;
ua1arn 21:85a0f94a84cd 1356 const uint_fast8_t coll [] =
ua1arn 21:85a0f94a84cd 1357 {
ua1arn 21:85a0f94a84cd 1358 modulatorifv,
ua1arn 21:85a0f94a84cd 1359 mikeifv,
ua1arn 21:85a0f94a84cd 1360 };
ua1arn 21:85a0f94a84cd 1361 const uint_fast8_t epin = USB_ENDPOINT_IN(USBD_EP_AUDIO_IN + offset);
ua1arn 21:85a0f94a84cd 1362 const uint_fast8_t epout = USB_ENDPOINT_OUT(USBD_EP_AUDIO_OUT + offset);
ua1arn 21:85a0f94a84cd 1363
ua1arn 21:85a0f94a84cd 1364 n += UAC_InterfaceAssociationDescriptor(fill, p + n, maxsize - n, controlifv, 3, offset); /* INTERFACE_AUDIO_CONTROL_0 Interface Association Descriptor Audio */
ua1arn 21:85a0f94a84cd 1365 // INTERFACE_AUDIO_CONTROL_0 - audio conntrol interface
ua1arn 21:85a0f94a84cd 1366 n += r9fill_3(fill, p + n, maxsize - n, controlifv, 0x00, offset); /* INTERFACE_AUDIO_CONTROL_0 - Interface Descriptor 0/0 Audio, 0 Endpoints */
ua1arn 21:85a0f94a84cd 1367 n += UACINOUT_AudioControlIfHeader(fill, p + n, maxsize - n, coll, sizeof coll / sizeof coll [0], UAC_AudioControlIfCircuits, offset); /* bcdADC Audio Control Interface Header Descriptor */
ua1arn 21:85a0f94a84cd 1368
ua1arn 21:85a0f94a84cd 1369 // OUT data flow: USB Speaker
ua1arn 21:85a0f94a84cd 1370 // INTERFACE_AUDIO_SPK_1 - audio streaming interface
ua1arn 21:85a0f94a84cd 1371 n += r9fill_10(fill, p + n, maxsize - n, modulatorifv, 0x00, offset); /* INTERFACE_AUDIO_SPK_1 - Interface 1, Alternate Setting 0 */
ua1arn 21:85a0f94a84cd 1372
ua1arn 21:85a0f94a84cd 1373 n += r9fill_11(fill, p + n, maxsize - n, modulatorifv, 0x01, offset); /* INTERFACE_AUDIO_SPK_1 - Interface 1, Alternate Setting 1 */
ua1arn 21:85a0f94a84cd 1374 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_IT_1 + offset); /* USB Speaker Audio Streaming Interface Descriptor (for output TERMINAL_ID_IT_1 + offset) */
ua1arn 21:85a0f94a84cd 1375 n += r9fill_13(fill, p + n, maxsize - n); /* USB Speaker Audio Type I Format Interface Descriptor (one sample rate) 48000 */
ua1arn 21:85a0f94a84cd 1376 n += r9fill_14(fill, p + n, maxsize - n, epout, highspeed); /* Endpoint USBD_EP_AUDIO_OUT - Standard Descriptor */
ua1arn 21:85a0f94a84cd 1377 n += r9fill_15(fill, p + n, maxsize - n); /* Endpoint - Audio Streaming Descriptor */
ua1arn 21:85a0f94a84cd 1378 // IN data flow: USB Microphone
ua1arn 21:85a0f94a84cd 1379 // INTERFACE_AUDIO_MIKE_2 - audio streaming interface
ua1arn 21:85a0f94a84cd 1380 n += r9fill_24(fill, p + n, maxsize - n, mikeifv, UACINALT_NONE, 0, offset); /* USB Microphone Standard AS Interface Descriptor (Alt. Set. 0) (CODE == 3) */ //zero-bandwidth interface
ua1arn 21:85a0f94a84cd 1381
ua1arn 21:85a0f94a84cd 1382 #if ! WITHRTSNOAUDIO
ua1arn 21:85a0f94a84cd 1383 // IN data flow: radio RX audio data
ua1arn 21:85a0f94a84cd 1384 n += r9fill_24(fill, p + n, maxsize - n, mikeifv, UACINALT_AUDIO48, 1, offset); /* INTERFACE_AUDIO_MIKE_2 Interface Descriptor 2/1 Audio, 1 Endpoint, bAlternateSetting=0x01 */
ua1arn 21:85a0f94a84cd 1385 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_OT_4 + offset); /* USB Microphone Class-specific AS General Interface Descriptor (for output TERMINAL_ID_OT_4) (CODE == 5) */
ua1arn 21:85a0f94a84cd 1386 n += UAC_r9fill_26_audio48(fill, p + n, maxsize - n); /* USB Microphone Type I Format Type Descriptor (CODE == 6) 48000 */
ua1arn 21:85a0f94a84cd 1387 n += UAC_r9fill_27_audio48(fill, p + n, maxsize - n, highspeed, epin, offset); /* Endpoint Descriptor USBD_EP_AUDIO_IN In, Isochronous, 125 us */
ua1arn 21:85a0f94a84cd 1388 n += r9fill_28(fill, p + n, maxsize - n); /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - подтверждено документацией*/
ua1arn 21:85a0f94a84cd 1389 #endif /* ! WITHRTSNOAUDIO */
ua1arn 21:85a0f94a84cd 1390
ua1arn 21:85a0f94a84cd 1391 #if WITHRTS96
ua1arn 21:85a0f94a84cd 1392 // IN data flow: radio RX specrum data
ua1arn 21:85a0f94a84cd 1393 n += r9fill_24(fill, p + n, maxsize - n, mikeifv, UACINALT_RTS96, 1, offset); /* INTERFACE_AUDIO_MIKE_2 Interface Descriptor 2/1 Audio, 1 Endpoint, bAlternateSetting=0x01 */
ua1arn 21:85a0f94a84cd 1394 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_OT_4 + offset); /* USB Microphone Class-specific AS General Interface Descriptor (for output TERMINAL_ID_OT_4) (CODE == 5) */
ua1arn 21:85a0f94a84cd 1395 n += UAC_r9fill_26_rts96(fill, p + n, maxsize - n); /* USB Microphone Type I Format Type Descriptor (CODE == 6) 48000 */
ua1arn 21:85a0f94a84cd 1396 n += UAC_r9fill_27_rts96(fill, p + n, maxsize - n, highspeed, epin, offset); /* Endpoint Descriptor USBD_EP_AUDIO_IN In, Isochronous, 125 us */
ua1arn 21:85a0f94a84cd 1397 n += r9fill_28(fill, p + n, maxsize - n); /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - подтверждено документацией*/
ua1arn 21:85a0f94a84cd 1398 #endif /* WITHRTS96 */
ua1arn 21:85a0f94a84cd 1399
ua1arn 21:85a0f94a84cd 1400 #if WITHRTS192
ua1arn 21:85a0f94a84cd 1401 // IN data flow: radio RX specrum data
ua1arn 21:85a0f94a84cd 1402 n += r9fill_24(fill, p + n, maxsize - n, mikeifv, UACINALT_RTS192, 1, offset); /* INTERFACE_AUDIO_MIKE_2 Interface Descriptor 2/1 Audio, 1 Endpoint, bAlternateSetting=0x01 */
ua1arn 21:85a0f94a84cd 1403 n += UAC_AudioStreamingIf(fill, p + n, maxsize - n, TERMINAL_ID_OT_4 + offset); /* USB Microphone Class-specific AS General Interface Descriptor (for output TERMINAL_ID_OT_4) (CODE == 5) */
ua1arn 21:85a0f94a84cd 1404 n += UAC_r9fill_26_rts192(fill, p + n, maxsize - n); /* USB Microphone Type I Format Type Descriptor (CODE == 6) 48000 */
ua1arn 21:85a0f94a84cd 1405 n += UAC_r9fill_27_rts192(fill, p + n, maxsize - n, highspeed, epin, offset); /* Endpoint Descriptor USBD_EP_AUDIO_IN In, Isochronous, 125 us */
ua1arn 21:85a0f94a84cd 1406 n += r9fill_28(fill, p + n, maxsize - n); /* USB Microphone Class-specific Isoc. Audio Data Endpoint Descriptor (CODE == 7) OK - подтверждено документацией*/
ua1arn 21:85a0f94a84cd 1407 #endif /* WITHRTS192 */
ua1arn 21:85a0f94a84cd 1408 return n;
ua1arn 21:85a0f94a84cd 1409 }
ua1arn 21:85a0f94a84cd 1410 #endif /* WITHUSBUAC3 */
ua1arn 21:85a0f94a84cd 1411
ua1arn 21:85a0f94a84cd 1412 #endif /* WITHUSBUAC */
ua1arn 21:85a0f94a84cd 1413
ua1arn 21:85a0f94a84cd 1414 #if WITHUSBCDC
ua1arn 21:85a0f94a84cd 1415 /* CDC IAD */
ua1arn 21:85a0f94a84cd 1416
ua1arn 21:85a0f94a84cd 1417 // ISBLyzer: Interface Association Descriptor Abstract Control Model
ua1arn 21:85a0f94a84cd 1418 // documented in USB ECN : Interface Association Descriptor - InterfaceAssociationDescriptor_ecn.pdf
ua1arn 21:85a0f94a84cd 1419 static unsigned CDCACM_InterfaceAssociationDescriptor_a(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1420 {
ua1arn 21:85a0f94a84cd 1421 const uint_fast8_t length = 8;
ua1arn 21:85a0f94a84cd 1422 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1423 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1424 return 0;
ua1arn 21:85a0f94a84cd 1425 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1426 {
ua1arn 21:85a0f94a84cd 1427 // 0x02/0x02/0x01 - cdc
ua1arn 21:85a0f94a84cd 1428 // 0x02/0x0c/0x07 - CDC Ethernet Emulation Model
ua1arn 21:85a0f94a84cd 1429 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1430 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1431 * buff ++ = USB_INTERFACE_ASSOC_DESCRIPTOR_TYPE; // bDescriptorType: IAD
ua1arn 21:85a0f94a84cd 1432 * buff ++ = INTERFACE_CDC_CONTROL_3a + offset * INTERFACE_CDCACM_count; // bFirstInterface
ua1arn 21:85a0f94a84cd 1433 * buff ++ = INTERFACE_CDCACM_count; // bInterfaceCount
ua1arn 21:85a0f94a84cd 1434 * buff ++ = USB_DEVICE_CLASS_COMMUNICATIONS; // bFunctionClass: CDC
ua1arn 21:85a0f94a84cd 1435 * buff ++ = CDC_ABSTRACT_CONTROL_MODEL; // bFunctionSubClass
ua1arn 21:85a0f94a84cd 1436 * buff ++ = CDC_PROTOCOL_COMMON_AT_COMMANDS; // bFunctionProtocol
ua1arn 21:85a0f94a84cd 1437 * buff ++ = STRING_ID_4a + offset; // iFunction - Storch HF TRX CAT - появляется, если сделать не тот bFunctionSubClass
ua1arn 21:85a0f94a84cd 1438 }
ua1arn 21:85a0f94a84cd 1439 return length;
ua1arn 21:85a0f94a84cd 1440 }
ua1arn 21:85a0f94a84cd 1441
ua1arn 21:85a0f94a84cd 1442 /*Interface Descriptor*/
ua1arn 21:85a0f94a84cd 1443 // USBLyzer: Interface Descriptor 3/0 CDC Control, 1 Endpoint
ua1arn 21:85a0f94a84cd 1444 static unsigned CDCACM_InterfaceDescriptorControlIf_a(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1445 {
ua1arn 21:85a0f94a84cd 1446 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 1447 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1448 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1449 return 0;
ua1arn 21:85a0f94a84cd 1450 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1451 {
ua1arn 21:85a0f94a84cd 1452 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1453 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1454 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType: Interface */ /* Interface descriptor type */
ua1arn 21:85a0f94a84cd 1455 * buff ++ = INTERFACE_CDC_CONTROL_3a + offset * INTERFACE_CDCACM_count; /* bInterfaceNumber: Number of Interface */
ua1arn 21:85a0f94a84cd 1456 * buff ++ = 0; /* bAlternateSetting: Alternate setting - zero-based index */
ua1arn 21:85a0f94a84cd 1457 * buff ++ = 0x01; /* bNumEndpoints: One endpoints used (interrupt type) */
ua1arn 21:85a0f94a84cd 1458 * buff ++ = CDC_COMMUNICATION_INTERFACE_CLASS; /* bInterfaceClass: Communication Interface Class */
ua1arn 21:85a0f94a84cd 1459 * buff ++ = 0x02; /* bInterfaceSubClass: Abstract Control Model */
ua1arn 21:85a0f94a84cd 1460 * buff ++ = 0x01; /* bInterfaceProtocol: Common AT commands */
ua1arn 21:85a0f94a84cd 1461 * buff ++ = STRING_ID_0; /* iInterface */
ua1arn 21:85a0f94a84cd 1462 }
ua1arn 21:85a0f94a84cd 1463 return length;
ua1arn 21:85a0f94a84cd 1464 }
ua1arn 21:85a0f94a84cd 1465
ua1arn 21:85a0f94a84cd 1466 /* Call Managment Functional Descriptor */
ua1arn 21:85a0f94a84cd 1467 // Call Management Functional Descriptor
ua1arn 21:85a0f94a84cd 1468 static unsigned CDCACM_r9fill_32_a(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1469 {
ua1arn 21:85a0f94a84cd 1470 const uint_fast8_t length = 5;
ua1arn 21:85a0f94a84cd 1471 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1472 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1473 return 0;
ua1arn 21:85a0f94a84cd 1474 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1475 {
ua1arn 21:85a0f94a84cd 1476 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1477 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1478 * buff ++ = CS_INTERFACE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 1479 * buff ++ = 0x01; /* bDescriptorSubtype: Call Management Func Desc */
ua1arn 21:85a0f94a84cd 1480 * buff ++ = 0x00; /* bmCapabilities: D0+D1 */
ua1arn 21:85a0f94a84cd 1481 * buff ++ = INTERFACE_CDC_DATA_4a + offset * INTERFACE_CDCACM_count; /* bDataInterface: Zero based index of the interface in this configuration.(bInterfaceNum) */
ua1arn 21:85a0f94a84cd 1482 }
ua1arn 21:85a0f94a84cd 1483 return length;
ua1arn 21:85a0f94a84cd 1484 }
ua1arn 21:85a0f94a84cd 1485
ua1arn 21:85a0f94a84cd 1486 /* Union Functional Descriptor */
ua1arn 21:85a0f94a84cd 1487 // Union Functional Descriptor
ua1arn 21:85a0f94a84cd 1488 static unsigned CDC_UnionFunctionalDescriptor_a(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1489 {
ua1arn 21:85a0f94a84cd 1490 const uint_fast8_t length = 5;
ua1arn 21:85a0f94a84cd 1491 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1492 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1493 return 0;
ua1arn 21:85a0f94a84cd 1494 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1495 {
ua1arn 21:85a0f94a84cd 1496 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1497 * buff ++ = length; /* bFunctionLength */
ua1arn 21:85a0f94a84cd 1498 * buff ++ = CS_INTERFACE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 1499 * buff ++ = CDC_UNION; /* bDescriptorSubtype: Union func desc */
ua1arn 21:85a0f94a84cd 1500 * buff ++ = INTERFACE_CDC_CONTROL_3a + offset * INTERFACE_CDCACM_count; /* bMasterInterface: Communication class interface - Zero based index of the interface in this configuration (bInterfaceNum) */
ua1arn 21:85a0f94a84cd 1501 * buff ++ = INTERFACE_CDC_DATA_4a + offset * INTERFACE_CDCACM_count; /* bSlaveInterface0: Data Class Interface - Zero based index of the interface in this configuration (bInterfaceNum) */
ua1arn 21:85a0f94a84cd 1502 }
ua1arn 21:85a0f94a84cd 1503 return length;
ua1arn 21:85a0f94a84cd 1504 }
ua1arn 21:85a0f94a84cd 1505
ua1arn 21:85a0f94a84cd 1506 /* Data class interface descriptor*/
ua1arn 21:85a0f94a84cd 1507 // USBLyzer: Interface Descriptor 4/0 CDC Data, 2 Endpoints
ua1arn 21:85a0f94a84cd 1508 static unsigned CDC_InterfaceDescriptorDataIf_a(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1509 {
ua1arn 21:85a0f94a84cd 1510 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 1511 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1512 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1513 return 0;
ua1arn 21:85a0f94a84cd 1514 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1515 {
ua1arn 21:85a0f94a84cd 1516 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1517 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1518 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType: */
ua1arn 21:85a0f94a84cd 1519 * buff ++ = INTERFACE_CDC_DATA_4a + offset * INTERFACE_CDCACM_count; /* bInterfaceNumber: Number of Interface */
ua1arn 21:85a0f94a84cd 1520 * buff ++ = 0; /* bAlternateSetting: Alternate setting - zero-based index */
ua1arn 21:85a0f94a84cd 1521 * buff ++ = 0x02; /* bNumEndpoints: Two endpoints used: data in and data out */
ua1arn 21:85a0f94a84cd 1522 * buff ++ = CDC_DATA_INTERFACE_CLASS; /* bInterfaceClass: CDC */
ua1arn 21:85a0f94a84cd 1523 * buff ++ = 0x00; /* bInterfaceSubClass: */
ua1arn 21:85a0f94a84cd 1524 * buff ++ = 0x00; /* bInterfaceProtocol: */
ua1arn 21:85a0f94a84cd 1525 * buff ++ = STRING_ID_0; /* iInterface: */
ua1arn 21:85a0f94a84cd 1526 }
ua1arn 21:85a0f94a84cd 1527 return length;
ua1arn 21:85a0f94a84cd 1528 }
ua1arn 21:85a0f94a84cd 1529
ua1arn 21:85a0f94a84cd 1530 /* Header Functional Descriptor */
ua1arn 21:85a0f94a84cd 1531 static unsigned r9fill_31(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1532 {
ua1arn 21:85a0f94a84cd 1533 const uint_fast8_t length = 5;
ua1arn 21:85a0f94a84cd 1534 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1535 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1536 return 0;
ua1arn 21:85a0f94a84cd 1537 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1538 {
ua1arn 21:85a0f94a84cd 1539 const uint_fast16_t bcdCDC = CDC_V1_10; /* bcdCDC: spec release number */
ua1arn 21:85a0f94a84cd 1540 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1541 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1542 * buff ++ = CDC_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 1543 * buff ++ = 0x00; /* bDescriptorSubtype: Header Func Desc */
ua1arn 21:85a0f94a84cd 1544 * buff ++ = LO_BYTE(bcdCDC); /* bcdCDC: spec release number */
ua1arn 21:85a0f94a84cd 1545 * buff ++ = HI_BYTE(bcdCDC);
ua1arn 21:85a0f94a84cd 1546 }
ua1arn 21:85a0f94a84cd 1547 return length;
ua1arn 21:85a0f94a84cd 1548 }
ua1arn 21:85a0f94a84cd 1549
ua1arn 21:85a0f94a84cd 1550 /* ACM Functional Descriptor */
ua1arn 21:85a0f94a84cd 1551 // Abstract Control Management Functional Descriptor
ua1arn 21:85a0f94a84cd 1552 static unsigned r9fill_33(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1553 {
ua1arn 21:85a0f94a84cd 1554 const uint_fast8_t length = 4;
ua1arn 21:85a0f94a84cd 1555 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1556 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1557 return 0;
ua1arn 21:85a0f94a84cd 1558 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1559 {
ua1arn 21:85a0f94a84cd 1560 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1561 // defined in PSTN120.pdf 5.3.2 Abstract Control Management Functional Descriptor
ua1arn 21:85a0f94a84cd 1562 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1563 * buff ++ = CS_INTERFACE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 1564 * buff ++ = 0x02; /* bDescriptorSubtype: Abstract Control Management desc */
ua1arn 21:85a0f94a84cd 1565 * buff ++ = 0x02; /* bmCapabilities 0x02: Line Coding requests and Serial State notification supported */
ua1arn 21:85a0f94a84cd 1566 }
ua1arn 21:85a0f94a84cd 1567 return length;
ua1arn 21:85a0f94a84cd 1568 }
ua1arn 21:85a0f94a84cd 1569
ua1arn 21:85a0f94a84cd 1570 /* Endpoint 3 Descriptor */
ua1arn 21:85a0f94a84cd 1571 // Endpoint Descriptor 86 6 In, Interrupt
ua1arn 21:85a0f94a84cd 1572 static unsigned r9fill_35(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, int highspeed, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 1573 {
ua1arn 21:85a0f94a84cd 1574 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1575 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1576 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1577 return 0;
ua1arn 21:85a0f94a84cd 1578 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1579 {
ua1arn 21:85a0f94a84cd 1580 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(VIRTUAL_COM_PORT_INT_SIZE);
ua1arn 21:85a0f94a84cd 1581 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1582 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1583 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 1584 * buff ++ = bEndpointAddress; /* bEndpointAddress: (IN) */
ua1arn 21:85a0f94a84cd 1585 * buff ++ = USB_ENDPOINT_TYPE_INTERRUPT; /* bmAttributes: Interrupt */
ua1arn 21:85a0f94a84cd 1586 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1587 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1588 * buff ++ = highspeed ? 0x10 : 0xFF; /* bInterval: 255 mS */
ua1arn 21:85a0f94a84cd 1589 }
ua1arn 21:85a0f94a84cd 1590 return length;
ua1arn 21:85a0f94a84cd 1591 }
ua1arn 21:85a0f94a84cd 1592
ua1arn 21:85a0f94a84cd 1593 /*Endpoint 2 OUT Descriptor*/
ua1arn 21:85a0f94a84cd 1594 // Endpoint Descriptor 03 3 Out, Bulk, 64 bytes
ua1arn 21:85a0f94a84cd 1595 static unsigned r9fill_37(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 1596 {
ua1arn 21:85a0f94a84cd 1597 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1598 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1599 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1600 return 0;
ua1arn 21:85a0f94a84cd 1601 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1602 {
ua1arn 21:85a0f94a84cd 1603 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(VIRTUAL_COM_PORT_DATA_SIZE);
ua1arn 21:85a0f94a84cd 1604 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1605 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1606 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 1607 * buff ++ = bEndpointAddress; /* bEndpointAddress: (OUT2) */
ua1arn 21:85a0f94a84cd 1608 * buff ++ = USB_ENDPOINT_TYPE_BULK; /* bmAttributes: Bulk */
ua1arn 21:85a0f94a84cd 1609 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1610 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1611 * buff ++ = 0x00; /* bInterval: ignore for Bulk transfer */
ua1arn 21:85a0f94a84cd 1612 }
ua1arn 21:85a0f94a84cd 1613 return length;
ua1arn 21:85a0f94a84cd 1614 }
ua1arn 21:85a0f94a84cd 1615
ua1arn 21:85a0f94a84cd 1616 /*Endpoint 2 IN Descriptor*/
ua1arn 21:85a0f94a84cd 1617 // Endpoint Descriptor 84 4 In, Bulk, 64 bytes
ua1arn 21:85a0f94a84cd 1618 static unsigned r9fill_38(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 1619 {
ua1arn 21:85a0f94a84cd 1620 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1621 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1622 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1623 return 0;
ua1arn 21:85a0f94a84cd 1624 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1625 {
ua1arn 21:85a0f94a84cd 1626 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(VIRTUAL_COM_PORT_DATA_SIZE);
ua1arn 21:85a0f94a84cd 1627 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1628 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1629 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 1630 * buff ++ = bEndpointAddress; /* bEndpointAddress: (IN2) */
ua1arn 21:85a0f94a84cd 1631 * buff ++ = USB_ENDPOINT_TYPE_BULK; /* bmAttributes: Bulk */
ua1arn 21:85a0f94a84cd 1632 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1633 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1634 * buff ++ = 0x00; /* bInterval: ignore for Bulk transfer */
ua1arn 21:85a0f94a84cd 1635 }
ua1arn 21:85a0f94a84cd 1636 return length;
ua1arn 21:85a0f94a84cd 1637 }
ua1arn 21:85a0f94a84cd 1638
ua1arn 21:85a0f94a84cd 1639 static unsigned fill_CDCACM_function_a(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed, uint_fast8_t offset)
ua1arn 21:85a0f94a84cd 1640 {
ua1arn 21:85a0f94a84cd 1641 unsigned n = 0;
ua1arn 21:85a0f94a84cd 1642 const uint8_t inep = USBD_EP_CDC_IN + offset;
ua1arn 21:85a0f94a84cd 1643 const uint8_t outnep = USBD_EP_CDC_OUT + offset;
ua1arn 21:85a0f94a84cd 1644 const uint8_t intnep = USBD_EP_CDC_INT + offset;
ua1arn 21:85a0f94a84cd 1645
ua1arn 21:85a0f94a84cd 1646 // CDC
ua1arn 21:85a0f94a84cd 1647 n += CDCACM_InterfaceAssociationDescriptor_a(fill, p + n, maxsize - n, offset); /* CDC: Interface Association Descriptor Abstract Control Model */
ua1arn 21:85a0f94a84cd 1648 n += CDCACM_InterfaceDescriptorControlIf_a(fill, p + n, maxsize - n, offset); /* INTERFACE_CDC_CONTROL_3a Interface Descriptor 3/0 CDC Control, 1 Endpoint */
ua1arn 21:85a0f94a84cd 1649 n += r9fill_31(fill, p + n, maxsize - n); /* Header Functional Descriptor*/
ua1arn 21:85a0f94a84cd 1650 n += CDCACM_r9fill_32_a(fill, p + n, maxsize - n, offset); /* Call Managment Functional Descriptor*/
ua1arn 21:85a0f94a84cd 1651 n += r9fill_33(fill, p + n, maxsize - n); /* ACM Functional Descriptor */
ua1arn 21:85a0f94a84cd 1652 n += CDC_UnionFunctionalDescriptor_a(fill, p + n, maxsize - n, offset); /* Union Functional Descriptor INTERFACE_CDC_CONTROL_3a & INTERFACE_CDC_DATA_4a */
ua1arn 21:85a0f94a84cd 1653 n += r9fill_35(fill, p + n, maxsize - n, highspeed, USB_ENDPOINT_IN(intnep)); /* Endpoint Descriptor 86 6 In, Interrupt */
ua1arn 21:85a0f94a84cd 1654
ua1arn 21:85a0f94a84cd 1655 n += CDC_InterfaceDescriptorDataIf_a(fill, p + n, maxsize - n, offset); /* INTERFACE_CDC_DATA_4a Data class interface descriptor */
ua1arn 21:85a0f94a84cd 1656 n += r9fill_37(fill, p + n, maxsize - n, USB_ENDPOINT_OUT(outnep)); /* Endpoint Descriptor USBD_EP_CDC_OUT Out, Bulk, 64 bytes */
ua1arn 21:85a0f94a84cd 1657 n += r9fill_38(fill, p + n, maxsize - n, USB_ENDPOINT_IN(inep)); /* Endpoint Descriptor USBD_EP_CDC_IN In, Bulk, 64 bytes */
ua1arn 21:85a0f94a84cd 1658
ua1arn 21:85a0f94a84cd 1659 return n;
ua1arn 21:85a0f94a84cd 1660 }
ua1arn 21:85a0f94a84cd 1661
ua1arn 21:85a0f94a84cd 1662 #endif /* WITHUSBCDC */
ua1arn 21:85a0f94a84cd 1663
ua1arn 21:85a0f94a84cd 1664 #if WITHUSBCDCEEM
ua1arn 21:85a0f94a84cd 1665
ua1arn 21:85a0f94a84cd 1666 static unsigned CDCEEM_InterfaceAssociationDescriptor(
ua1arn 21:85a0f94a84cd 1667 uint_fast8_t fill,
ua1arn 21:85a0f94a84cd 1668 uint8_t * buff,
ua1arn 21:85a0f94a84cd 1669 unsigned maxsize
ua1arn 21:85a0f94a84cd 1670 )
ua1arn 21:85a0f94a84cd 1671 {
ua1arn 21:85a0f94a84cd 1672 const uint_fast8_t length = 8;
ua1arn 21:85a0f94a84cd 1673 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1674 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1675 return 0;
ua1arn 21:85a0f94a84cd 1676 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1677 {
ua1arn 21:85a0f94a84cd 1678 // 0x02/0x02/0x01 - cdc
ua1arn 21:85a0f94a84cd 1679 // 0x02/0x0c/0x07 - CDC Ethernet Emulation Model
ua1arn 21:85a0f94a84cd 1680 // http://blog.metrotek.spb.ru/2011/07/07/usb-set-na-cortex-m3/
ua1arn 21:85a0f94a84cd 1681
ua1arn 21:85a0f94a84cd 1682 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1683 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1684 * buff ++ = USB_INTERFACE_ASSOC_DESCRIPTOR_TYPE; // bDescriptorType: IAD
ua1arn 21:85a0f94a84cd 1685 * buff ++ = INTERFACE_CDCEEM_DATA_6; // bFirstInterface
ua1arn 21:85a0f94a84cd 1686 * buff ++ = INTERFACE_CDCEEM_count; // bInterfaceCount
ua1arn 21:85a0f94a84cd 1687 * buff ++ = USB_DEVICE_CLASS_COMMUNICATIONS; // bFunctionClass: CDC
ua1arn 21:85a0f94a84cd 1688 * buff ++ = CDC_ETHERNET_EMULATION_MODEL; // bFunctionSubClass - Ethernet Networking
ua1arn 21:85a0f94a84cd 1689 * buff ++ = 0x07; // bFunctionProtocol
ua1arn 21:85a0f94a84cd 1690 * buff ++ = STRING_ID_5; // iFunction - CDC Ethernet Control Model (EEM)
ua1arn 21:85a0f94a84cd 1691 }
ua1arn 21:85a0f94a84cd 1692 return length;
ua1arn 21:85a0f94a84cd 1693 }
ua1arn 21:85a0f94a84cd 1694
ua1arn 21:85a0f94a84cd 1695 // Информация о типе требуемого драйвера берется отсюда по кодам в bInterfaceClass, bInterfaceSubclass, bInterfaceProtocol
ua1arn 21:85a0f94a84cd 1696 static unsigned CDCEEM_r9fill_24(uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 1697 uint_fast8_t bInterfaceNumber,
ua1arn 21:85a0f94a84cd 1698 uint_fast8_t bAlternateSetting,
ua1arn 21:85a0f94a84cd 1699 uint_fast8_t bNumEndpoints
ua1arn 21:85a0f94a84cd 1700 )
ua1arn 21:85a0f94a84cd 1701 {
ua1arn 21:85a0f94a84cd 1702 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 1703 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1704 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1705 return 0;
ua1arn 21:85a0f94a84cd 1706 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1707 {
ua1arn 21:85a0f94a84cd 1708 // 0x02/0x0c/0x07 - CDC Ethernet Emulation Model
ua1arn 21:85a0f94a84cd 1709 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1710 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1711 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; // INTERFACE descriptor type (bDescriptorType) 0x04
ua1arn 21:85a0f94a84cd 1712 * buff ++ = bInterfaceNumber; // Index of this interface. (bInterfaceNumber) ?????????? (3<) (1<<) (1<M)
ua1arn 21:85a0f94a84cd 1713 * buff ++ = bAlternateSetting; // 0 Index of this alternate setting. (bAlternateSetting) - zero-based index
ua1arn 21:85a0f94a84cd 1714 * buff ++ = bNumEndpoints; // bNumEndpoints
ua1arn 21:85a0f94a84cd 1715 * buff ++ = 0x02; // bInterfaceClass
ua1arn 21:85a0f94a84cd 1716 * buff ++ = CDC_ETHERNET_EMULATION_MODEL; /* bInterfaceSubclass */
ua1arn 21:85a0f94a84cd 1717 * buff ++ = 0x07; /* bInterfaceProtocol */
ua1arn 21:85a0f94a84cd 1718 * buff ++ = STRING_ID_5; /* Unused iInterface */
ua1arn 21:85a0f94a84cd 1719 /* 9 byte*/
ua1arn 21:85a0f94a84cd 1720 }
ua1arn 21:85a0f94a84cd 1721 return length;
ua1arn 21:85a0f94a84cd 1722 }
ua1arn 21:85a0f94a84cd 1723
ua1arn 21:85a0f94a84cd 1724 // Endpoint Descriptor
ua1arn 21:85a0f94a84cd 1725 static unsigned CDCEEM_r9fill_37(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 1726 {
ua1arn 21:85a0f94a84cd 1727 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1728 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1729 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1730 return 0;
ua1arn 21:85a0f94a84cd 1731 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1732 {
ua1arn 21:85a0f94a84cd 1733 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(USBD_CDCEEM_BUFSIZE);
ua1arn 21:85a0f94a84cd 1734 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1735 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1736 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 1737 * buff ++ = bEndpointAddress; /* bEndpointAddress: (OUT2) */
ua1arn 21:85a0f94a84cd 1738 * buff ++ = USB_ENDPOINT_TYPE_BULK; /* bmAttributes: Bulk */
ua1arn 21:85a0f94a84cd 1739 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1740 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1741 * buff ++ = 0x01; /* bInterval: ignore for Bulk transfer */
ua1arn 21:85a0f94a84cd 1742 }
ua1arn 21:85a0f94a84cd 1743 return length;
ua1arn 21:85a0f94a84cd 1744 }
ua1arn 21:85a0f94a84cd 1745
ua1arn 21:85a0f94a84cd 1746 /*Endpoint 2 IN Descriptor*/
ua1arn 21:85a0f94a84cd 1747 // Endpoint Descriptor 84 4 In, Bulk, 64 bytes
ua1arn 21:85a0f94a84cd 1748 static unsigned CDCEEM_r9fill_38(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 1749 {
ua1arn 21:85a0f94a84cd 1750 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1751 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1752 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1753 return 0;
ua1arn 21:85a0f94a84cd 1754 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1755 {
ua1arn 21:85a0f94a84cd 1756 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(USBD_CDCEEM_BUFSIZE);
ua1arn 21:85a0f94a84cd 1757 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1758 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1759 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 1760 * buff ++ = bEndpointAddress; /* bEndpointAddress: (IN2) */
ua1arn 21:85a0f94a84cd 1761 * buff ++ = USB_ENDPOINT_TYPE_BULK; /* bmAttributes: Bulk */
ua1arn 21:85a0f94a84cd 1762 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1763 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1764 * buff ++ = 0x01; /* bInterval: ignore for full speed Bulk endpoints */
ua1arn 21:85a0f94a84cd 1765 }
ua1arn 21:85a0f94a84cd 1766 return length;
ua1arn 21:85a0f94a84cd 1767 }
ua1arn 21:85a0f94a84cd 1768
ua1arn 21:85a0f94a84cd 1769 /* CDC Ethernet Emulation Model */
ua1arn 21:85a0f94a84cd 1770 static unsigned fill_CDCEEM_function(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed)
ua1arn 21:85a0f94a84cd 1771 {
ua1arn 21:85a0f94a84cd 1772 unsigned n = 0;
ua1arn 21:85a0f94a84cd 1773
ua1arn 21:85a0f94a84cd 1774 // iadclasscode_r10.pdf
ua1arn 21:85a0f94a84cd 1775 // InterfaceAssociationDescriptor требуется только для многоинтерфейсных
ua1arn 21:85a0f94a84cd 1776 // Провда, там написано что iadclasscode_r10.pdf
ua1arn 21:85a0f94a84cd 1777 n += CDCEEM_InterfaceAssociationDescriptor(fill, p + n, maxsize - n); /* CDC EEM: Interface Association Descriptor Abstract Control Model */
ua1arn 21:85a0f94a84cd 1778 n += CDCEEM_r9fill_24(fill, p + n, maxsize - n, INTERFACE_CDCEEM_DATA_6, 0x00, 2); /* INTERFACE_CDCEEM_DATA_6 Data class interface descriptor */
ua1arn 21:85a0f94a84cd 1779 n += CDCEEM_r9fill_38(fill, p + n, maxsize - n, USB_ENDPOINT_IN(USBD_EP_CDCEEM_IN)); /* Endpoint Descriptor USBD_EP_CDCECM_IN In, Bulk, 64 bytes */
ua1arn 21:85a0f94a84cd 1780 n += CDCEEM_r9fill_37(fill, p + n, maxsize - n, USB_ENDPOINT_OUT(USBD_EP_CDCEEM_OUT)); /* Endpoint Descriptor USBD_EP_CDCECM_OUT Out, Bulk, 64 bytes */
ua1arn 21:85a0f94a84cd 1781
ua1arn 21:85a0f94a84cd 1782 return n;
ua1arn 21:85a0f94a84cd 1783 }
ua1arn 21:85a0f94a84cd 1784
ua1arn 21:85a0f94a84cd 1785 #endif /* WITHUSBCDCEEM */
ua1arn 21:85a0f94a84cd 1786
ua1arn 21:85a0f94a84cd 1787 #if WITHUSBCDCECM
ua1arn 21:85a0f94a84cd 1788
ua1arn 21:85a0f94a84cd 1789 // ISBLyzer: Interface Association Descriptor Abstract Control Model
ua1arn 21:85a0f94a84cd 1790 // documented in USB ECN : Interface Association Descriptor - InterfaceAssociationDescriptor_ecn.pdf
ua1arn 21:85a0f94a84cd 1791 static unsigned CDCECM_InterfaceAssociationDescriptor(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1792 {
ua1arn 21:85a0f94a84cd 1793 const uint_fast8_t length = 8;
ua1arn 21:85a0f94a84cd 1794 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1795 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1796 return 0;
ua1arn 21:85a0f94a84cd 1797 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1798 {
ua1arn 21:85a0f94a84cd 1799 // 0x02/0x02/0x01 - cdc
ua1arn 21:85a0f94a84cd 1800 // 0x02/0x0c/0x07 - CDC Ethernet Emulation Model
ua1arn 21:85a0f94a84cd 1801 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1802 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1803 * buff ++ = USB_INTERFACE_ASSOC_DESCRIPTOR_TYPE; // bDescriptorType: IAD
ua1arn 21:85a0f94a84cd 1804 * buff ++ = INTERFACE_CDCECM_CONTROL_5; // bFirstInterface
ua1arn 21:85a0f94a84cd 1805 * buff ++ = INTERFACE_CDCECM_count; // bInterfaceCount
ua1arn 21:85a0f94a84cd 1806 * buff ++ = USB_DEVICE_CLASS_COMMUNICATIONS; // bFunctionClass: CDC
ua1arn 21:85a0f94a84cd 1807 * buff ++ = CDC_ETHERNET_NETWORKING_CONTROL_MODEL; // bFunctionSubClass - Ethernet Networking
ua1arn 21:85a0f94a84cd 1808 * buff ++ = 0x00; // bFunctionProtocol
ua1arn 21:85a0f94a84cd 1809 * buff ++ = STRING_ID_5a; // iFunction - CDC Ethernet Control Model (ECM)
ua1arn 21:85a0f94a84cd 1810 }
ua1arn 21:85a0f94a84cd 1811 return length;
ua1arn 21:85a0f94a84cd 1812 }
ua1arn 21:85a0f94a84cd 1813
ua1arn 21:85a0f94a84cd 1814
ua1arn 21:85a0f94a84cd 1815 /*Interface Descriptor*/
ua1arn 21:85a0f94a84cd 1816 // USBLyzer: Interface Descriptor 3/0 CDC Control, 1 Endpoint
ua1arn 21:85a0f94a84cd 1817 static unsigned CDCECM_InterfaceDescriptorControlIf(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1818 {
ua1arn 21:85a0f94a84cd 1819 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 1820 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1821 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1822 return 0;
ua1arn 21:85a0f94a84cd 1823 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1824 {
ua1arn 21:85a0f94a84cd 1825 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1826 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1827 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType: Interface */ /* Interface descriptor type */
ua1arn 21:85a0f94a84cd 1828 * buff ++ = INTERFACE_CDCECM_CONTROL_5; /* bInterfaceNumber: Number of Interface */
ua1arn 21:85a0f94a84cd 1829 * buff ++ = 0; /* bAlternateSetting: Alternate setting - zero-based index */
ua1arn 21:85a0f94a84cd 1830 * buff ++ = 0x01; /* bNumEndpoints: One endpoints used (interrupt type) */
ua1arn 21:85a0f94a84cd 1831 * buff ++ = CDC_COMMUNICATION_INTERFACE_CLASS; /* bInterfaceClass: Communication Interface Class */
ua1arn 21:85a0f94a84cd 1832 * buff ++ = CDC_ETHERNET_NETWORKING_CONTROL_MODEL; /* bInterfaceSubClass: Ethernet Networking */
ua1arn 21:85a0f94a84cd 1833 * buff ++ = 0x00; /* bInterfaceProtocol */
ua1arn 21:85a0f94a84cd 1834 * buff ++ = STRING_ID_0; /* iInterface */
ua1arn 21:85a0f94a84cd 1835 }
ua1arn 21:85a0f94a84cd 1836 return length;
ua1arn 21:85a0f94a84cd 1837 }
ua1arn 21:85a0f94a84cd 1838
ua1arn 21:85a0f94a84cd 1839
ua1arn 21:85a0f94a84cd 1840 /* Union Functional Descriptor */
ua1arn 21:85a0f94a84cd 1841 // Union Functional Descriptor
ua1arn 21:85a0f94a84cd 1842 static unsigned CDCECM_UnionFunctionalDescriptor(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1843 {
ua1arn 21:85a0f94a84cd 1844 const uint_fast8_t length = 5;
ua1arn 21:85a0f94a84cd 1845 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1846 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1847 return 0;
ua1arn 21:85a0f94a84cd 1848 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1849 {
ua1arn 21:85a0f94a84cd 1850 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1851 * buff ++ = length; /* bFunctionLength */
ua1arn 21:85a0f94a84cd 1852 * buff ++ = CS_INTERFACE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 1853 * buff ++ = CDC_UNION; /* bDescriptorSubtype: Union func desc */
ua1arn 21:85a0f94a84cd 1854 * buff ++ = INTERFACE_CDCECM_CONTROL_5; /* bMasterInterface: Communication class interface - Zero based index of the interface in this configuration (bInterfaceNum) */
ua1arn 21:85a0f94a84cd 1855 * buff ++ = INTERFACE_CDCECM_DATA_6; /* bSlaveInterface0: Data Class Interface - Zero based index of the interface in this configuration (bInterfaceNum) */
ua1arn 21:85a0f94a84cd 1856 }
ua1arn 21:85a0f94a84cd 1857 return length;
ua1arn 21:85a0f94a84cd 1858 }
ua1arn 21:85a0f94a84cd 1859
ua1arn 21:85a0f94a84cd 1860 // Ethernet Networking Functional Descriptor
ua1arn 21:85a0f94a84cd 1861 static unsigned CDCECM_EthernetNetworkingFunctionalDescriptor(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1862 {
ua1arn 21:85a0f94a84cd 1863 const uint_fast8_t length = 13;
ua1arn 21:85a0f94a84cd 1864 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1865 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1866 return 0;
ua1arn 21:85a0f94a84cd 1867 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1868 {
ua1arn 21:85a0f94a84cd 1869 const uint_fast32_t bmEthernetStatistics = 0;
ua1arn 21:85a0f94a84cd 1870 const uint_fast16_t wMaxSegmentSize = 1514;
ua1arn 21:85a0f94a84cd 1871 const uint_fast16_t wNumberMCFilters = 0;
ua1arn 21:85a0f94a84cd 1872 const uint_fast8_t bNumberPowerFilters = 0;
ua1arn 21:85a0f94a84cd 1873
ua1arn 21:85a0f94a84cd 1874 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1875 * buff ++ = length; /* bFunctionLength */
ua1arn 21:85a0f94a84cd 1876 * buff ++ = CS_INTERFACE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 1877 * buff ++ = 0x0F; /* bDescriptorSubtype: Ethernet Networking Functional Descriptor */
ua1arn 21:85a0f94a84cd 1878 * buff ++ = STRING_ID_MACADDRESS; /* iMacAddress */
ua1arn 21:85a0f94a84cd 1879 * buff ++ = LO_BYTE(bmEthernetStatistics); /* bmEthernetStatistics */
ua1arn 21:85a0f94a84cd 1880 * buff ++ = HI_BYTE(bmEthernetStatistics);
ua1arn 21:85a0f94a84cd 1881 * buff ++ = HI_24BY(bmEthernetStatistics);
ua1arn 21:85a0f94a84cd 1882 * buff ++ = HI_32BY(bmEthernetStatistics);
ua1arn 21:85a0f94a84cd 1883 * buff ++ = LO_BYTE(wMaxSegmentSize); /* wMaxSegmentSize */
ua1arn 21:85a0f94a84cd 1884 * buff ++ = HI_BYTE(wMaxSegmentSize);
ua1arn 21:85a0f94a84cd 1885 * buff ++ = LO_BYTE(wNumberMCFilters); /* wNumberMCFilters */
ua1arn 21:85a0f94a84cd 1886 * buff ++ = HI_BYTE(wNumberMCFilters);
ua1arn 21:85a0f94a84cd 1887 * buff ++ = bNumberPowerFilters; /* bNumberPowerFilters */
ua1arn 21:85a0f94a84cd 1888 }
ua1arn 21:85a0f94a84cd 1889 return length;
ua1arn 21:85a0f94a84cd 1890 }
ua1arn 21:85a0f94a84cd 1891
ua1arn 21:85a0f94a84cd 1892
ua1arn 21:85a0f94a84cd 1893 /* Header Functional Descriptor */
ua1arn 21:85a0f94a84cd 1894 static unsigned CDCECM_r9fill_31(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 1895 {
ua1arn 21:85a0f94a84cd 1896 const uint_fast8_t length = 5;
ua1arn 21:85a0f94a84cd 1897 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1898 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1899 return 0;
ua1arn 21:85a0f94a84cd 1900 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1901 {
ua1arn 21:85a0f94a84cd 1902 const uint_fast16_t bcdCDC = CDC_V1_10; /* bcdCDC: spec release number */
ua1arn 21:85a0f94a84cd 1903 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1904 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1905 * buff ++ = CDC_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 1906 * buff ++ = 0x00; /* bDescriptorSubtype: Header Func Desc */
ua1arn 21:85a0f94a84cd 1907 * buff ++ = LO_BYTE(bcdCDC); /* bcdCDC: spec release number */
ua1arn 21:85a0f94a84cd 1908 * buff ++ = HI_BYTE(bcdCDC);
ua1arn 21:85a0f94a84cd 1909 }
ua1arn 21:85a0f94a84cd 1910 return length;
ua1arn 21:85a0f94a84cd 1911 }
ua1arn 21:85a0f94a84cd 1912
ua1arn 21:85a0f94a84cd 1913 /* Endpoint 3 Descriptor */
ua1arn 21:85a0f94a84cd 1914 // Endpoint Descriptor 86 6 In, Interrupt
ua1arn 21:85a0f94a84cd 1915
ua1arn 21:85a0f94a84cd 1916 static unsigned CDCECM_r9fill_35(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, int highspeed, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 1917 {
ua1arn 21:85a0f94a84cd 1918 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1919 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1920 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1921 return 0;
ua1arn 21:85a0f94a84cd 1922 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1923 {
ua1arn 21:85a0f94a84cd 1924 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(CDCECM_NOTIFICATION_IN_SZ);
ua1arn 21:85a0f94a84cd 1925 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1926 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1927 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 1928 * buff ++ = bEndpointAddress; /* bEndpointAddress: (IN) */
ua1arn 21:85a0f94a84cd 1929 * buff ++ = USB_ENDPOINT_TYPE_INTERRUPT; /* bmAttributes: Interrupt */
ua1arn 21:85a0f94a84cd 1930 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1931 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1932 * buff ++ = highspeed ? HSINTERVAL_32MS : FSINTERVAL_32MS; /* bInterval: 32 mS */
ua1arn 21:85a0f94a84cd 1933 }
ua1arn 21:85a0f94a84cd 1934 return length;
ua1arn 21:85a0f94a84cd 1935 }
ua1arn 21:85a0f94a84cd 1936
ua1arn 21:85a0f94a84cd 1937 // Endpoint Descriptor
ua1arn 21:85a0f94a84cd 1938 static unsigned CDCECM_r9fill_37(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 1939 {
ua1arn 21:85a0f94a84cd 1940 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1941 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1942 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1943 return 0;
ua1arn 21:85a0f94a84cd 1944 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1945 {
ua1arn 21:85a0f94a84cd 1946 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(CDCECM_DATA_OUT_SZ);
ua1arn 21:85a0f94a84cd 1947 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1948 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1949 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 1950 * buff ++ = bEndpointAddress; /* bEndpointAddress: (OUT2) */
ua1arn 21:85a0f94a84cd 1951 * buff ++ = USB_ENDPOINT_TYPE_BULK; /* bmAttributes: Bulk */
ua1arn 21:85a0f94a84cd 1952 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1953 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1954 * buff ++ = 0x00; /* bInterval: ignore for Bulk transfer */
ua1arn 21:85a0f94a84cd 1955 }
ua1arn 21:85a0f94a84cd 1956 return length;
ua1arn 21:85a0f94a84cd 1957 }
ua1arn 21:85a0f94a84cd 1958
ua1arn 21:85a0f94a84cd 1959 /*Endpoint 2 IN Descriptor*/
ua1arn 21:85a0f94a84cd 1960 // Endpoint Descriptor 84 4 In, Bulk, 64 bytes
ua1arn 21:85a0f94a84cd 1961 static unsigned CDCECM_r9fill_38(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 1962 {
ua1arn 21:85a0f94a84cd 1963 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 1964 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1965 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1966 return 0;
ua1arn 21:85a0f94a84cd 1967 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1968 {
ua1arn 21:85a0f94a84cd 1969 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(CDCECM_DATA_IN_SZ);
ua1arn 21:85a0f94a84cd 1970 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1971 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1972 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 1973 * buff ++ = bEndpointAddress; /* bEndpointAddress: (IN2) */
ua1arn 21:85a0f94a84cd 1974 * buff ++ = USB_ENDPOINT_TYPE_BULK; /* bmAttributes: Bulk */
ua1arn 21:85a0f94a84cd 1975 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 1976 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 1977 * buff ++ = 0x00; /* bInterval: ignore for Bulk transfer */
ua1arn 21:85a0f94a84cd 1978 }
ua1arn 21:85a0f94a84cd 1979 return length;
ua1arn 21:85a0f94a84cd 1980 }
ua1arn 21:85a0f94a84cd 1981
ua1arn 21:85a0f94a84cd 1982 static unsigned CDCECM_InterfaceDescriptorDataIf(
ua1arn 21:85a0f94a84cd 1983 uint_fast8_t fill, uint8_t * buff, unsigned maxsize,
ua1arn 21:85a0f94a84cd 1984 uint_fast8_t bInterfaceNumber,
ua1arn 21:85a0f94a84cd 1985 uint_fast8_t bAlternateSetting,
ua1arn 21:85a0f94a84cd 1986 uint_fast8_t bNumEndpoints
ua1arn 21:85a0f94a84cd 1987 )
ua1arn 21:85a0f94a84cd 1988 {
ua1arn 21:85a0f94a84cd 1989 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 1990 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 1991 if (maxsize < length)
ua1arn 21:85a0f94a84cd 1992 return 0;
ua1arn 21:85a0f94a84cd 1993 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 1994 {
ua1arn 21:85a0f94a84cd 1995 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 1996 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 1997 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; // INTERFACE descriptor type (bDescriptorType) 0x04
ua1arn 21:85a0f94a84cd 1998 * buff ++ = bInterfaceNumber; // Index of this interface. (bInterfaceNumber) ?????????? (3<) (1<<) (1<M)
ua1arn 21:85a0f94a84cd 1999 * buff ++ = bAlternateSetting; // 0 Index of this alternate setting. (bAlternateSetting) - zero-based index
ua1arn 21:85a0f94a84cd 2000 * buff ++ = bNumEndpoints; // 2 endpoints. (bNumEndpoints)
ua1arn 21:85a0f94a84cd 2001 * buff ++ = CDC_DATA_INTERFACE_CLASS; // 10 CDC Data (bInterfaceClass)
ua1arn 21:85a0f94a84cd 2002 * buff ++ = 0x00; // bInterfaceSubclass)
ua1arn 21:85a0f94a84cd 2003 * buff ++ = 0x00; /* 0 bInterfaceProtocol */
ua1arn 21:85a0f94a84cd 2004 * buff ++ = STRING_ID_0; /* 0 Unused iInterface */
ua1arn 21:85a0f94a84cd 2005 /* 9 byte*/
ua1arn 21:85a0f94a84cd 2006 }
ua1arn 21:85a0f94a84cd 2007 return length;
ua1arn 21:85a0f94a84cd 2008 }
ua1arn 21:85a0f94a84cd 2009
ua1arn 21:85a0f94a84cd 2010 /* CDC Ethernet Control Model */
ua1arn 21:85a0f94a84cd 2011 static unsigned fill_CDCECM_function(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed)
ua1arn 21:85a0f94a84cd 2012 {
ua1arn 21:85a0f94a84cd 2013 unsigned n = 0;
ua1arn 21:85a0f94a84cd 2014
ua1arn 21:85a0f94a84cd 2015 n += CDCECM_InterfaceAssociationDescriptor(fill, p + n, maxsize - n); /* CDC: Interface Association Descriptor Abstract Control Model */
ua1arn 21:85a0f94a84cd 2016 n += CDCECM_InterfaceDescriptorControlIf(fill, p + n, maxsize - n); /* INTERFACE_CDC_CONTROL_3a Interface Descriptor 3/0 CDC Control, 1 Endpoint */
ua1arn 21:85a0f94a84cd 2017 n += CDCECM_r9fill_31(fill, p + n, maxsize - n); /* Header Functional Descriptor*/
ua1arn 21:85a0f94a84cd 2018 n += CDCECM_UnionFunctionalDescriptor(fill, p + n, maxsize - n); /* Union Functional Descriptor INTERFACE_CDC_CONTROL_3a & INTERFACE_CDC_DATA_4a */
ua1arn 21:85a0f94a84cd 2019 n += CDCECM_EthernetNetworkingFunctionalDescriptor(fill, p + n, maxsize - n); /* Union Functional Descriptor INTERFACE_CDC_CONTROL_3a & INTERFACE_CDC_DATA_4a */
ua1arn 21:85a0f94a84cd 2020 n += CDCECM_r9fill_35(fill, p + n, maxsize - n, highspeed, USB_ENDPOINT_IN(USBD_EP_CDCECM_INT)); /* Endpoint Descriptor 86 6 In, Interrupt */
ua1arn 21:85a0f94a84cd 2021
ua1arn 21:85a0f94a84cd 2022 n += CDCECM_InterfaceDescriptorDataIf(fill, p + n, maxsize - n, INTERFACE_CDCECM_DATA_6, 0x00, 0); /* INTERFACE_CDCECM_DATA_6 Data class interface descriptor */
ua1arn 21:85a0f94a84cd 2023
ua1arn 21:85a0f94a84cd 2024 n += CDCECM_InterfaceDescriptorDataIf(fill, p + n, maxsize - n, INTERFACE_CDCECM_DATA_6, 0x01, 2); /* INTERFACE_CDCECM_DATA_6 Data class interface descriptor */
ua1arn 21:85a0f94a84cd 2025 n += CDCECM_r9fill_37(fill, p + n, maxsize - n, USB_ENDPOINT_OUT(USBD_EP_CDCECM_OUT)); /* Endpoint Descriptor USBD_EP_CDCECM_OUT Out, Bulk, 64 bytes */
ua1arn 21:85a0f94a84cd 2026 n += CDCECM_r9fill_38(fill, p + n, maxsize - n, USB_ENDPOINT_IN(USBD_EP_CDCECM_IN)); /* Endpoint Descriptor USBD_EP_CDCECM_IN In, Bulk, 64 bytes */
ua1arn 21:85a0f94a84cd 2027
ua1arn 21:85a0f94a84cd 2028 return n;
ua1arn 21:85a0f94a84cd 2029 }
ua1arn 21:85a0f94a84cd 2030
ua1arn 21:85a0f94a84cd 2031 #endif /* WITHUSBCDCECM */
ua1arn 21:85a0f94a84cd 2032
ua1arn 21:85a0f94a84cd 2033 #if WITHUSBRNDIS
ua1arn 21:85a0f94a84cd 2034
ua1arn 21:85a0f94a84cd 2035
ua1arn 21:85a0f94a84cd 2036 // Interface Association Descriptor RF Controller
ua1arn 21:85a0f94a84cd 2037 // documented in USB ECN : Interface Association Descriptor - InterfaceAssociationDescriptor_ecn.pdf
ua1arn 21:85a0f94a84cd 2038 static unsigned RNDIS_InterfaceAssociationDescriptor(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2039 {
ua1arn 21:85a0f94a84cd 2040 const uint_fast8_t length = 8;
ua1arn 21:85a0f94a84cd 2041 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2042 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2043 return 0;
ua1arn 21:85a0f94a84cd 2044 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2045 {
ua1arn 21:85a0f94a84cd 2046 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2047 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2048 * buff ++ = USB_INTERFACE_ASSOC_DESCRIPTOR_TYPE; // bDescriptorType: IAD
ua1arn 21:85a0f94a84cd 2049 * buff ++ = INTERFACE_RNDIS_CONTROL_5; // bFirstInterface
ua1arn 21:85a0f94a84cd 2050 * buff ++ = INTERFACE_RNDIS_count; // bInterfaceCount
ua1arn 21:85a0f94a84cd 2051 * buff ++ = USB_DEVICE_CLASS_WIRELESS_CONTROLLER; // bFunctionClass: CDC
ua1arn 21:85a0f94a84cd 2052 * buff ++ = 0x01; // bFunctionSubClass - RF Controller
ua1arn 21:85a0f94a84cd 2053 * buff ++ = 0x03; // bFunctionProtocol - Remote NDIS
ua1arn 21:85a0f94a84cd 2054 * buff ++ = STRING_ID_RNDIS; // iFunction - Remote NDIS
ua1arn 21:85a0f94a84cd 2055 }
ua1arn 21:85a0f94a84cd 2056 return length;
ua1arn 21:85a0f94a84cd 2057 }
ua1arn 21:85a0f94a84cd 2058
ua1arn 21:85a0f94a84cd 2059
ua1arn 21:85a0f94a84cd 2060 /*Interface Descriptor*/
ua1arn 21:85a0f94a84cd 2061 // Interface Descriptor 0/0 Wireless Controller, 1 Endpoint
ua1arn 21:85a0f94a84cd 2062 // Communication Class INTERFACE descriptor
ua1arn 21:85a0f94a84cd 2063 // https://msdn.microsoft.com/en-US/library/ee485851(v=winembedded.60).aspx
ua1arn 21:85a0f94a84cd 2064 static unsigned RNDIS_InterfaceDescriptorControlIf(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2065 {
ua1arn 21:85a0f94a84cd 2066 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 2067 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2068 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2069 return 0;
ua1arn 21:85a0f94a84cd 2070 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2071 {
ua1arn 21:85a0f94a84cd 2072 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2073 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2074 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType: Interface */ /* Interface descriptor type */
ua1arn 21:85a0f94a84cd 2075 * buff ++ = INTERFACE_RNDIS_CONTROL_5; /* bInterfaceNumber: Number of Interface */
ua1arn 21:85a0f94a84cd 2076 * buff ++ = 0; /* bAlternateSetting: Alternate setting - zero-based index */
ua1arn 21:85a0f94a84cd 2077 * buff ++ = 0x01; /* bNumEndpoints: One endpoints used (interrupt type) */
ua1arn 21:85a0f94a84cd 2078 * buff ++ = USB_DEVICE_CLASS_WIRELESS_CONTROLLER; /* bInterfaceClass: Wireless Controller */
ua1arn 21:85a0f94a84cd 2079 * buff ++ = 0x01; // bFunctionSubClass - RF Controller
ua1arn 21:85a0f94a84cd 2080 * buff ++ = 0x03; /* bInterfaceProtocol - Remote NDIS */
ua1arn 21:85a0f94a84cd 2081 * buff ++ = STRING_ID_0; /* iInterface */
ua1arn 21:85a0f94a84cd 2082 }
ua1arn 21:85a0f94a84cd 2083 return length;
ua1arn 21:85a0f94a84cd 2084 }
ua1arn 21:85a0f94a84cd 2085
ua1arn 21:85a0f94a84cd 2086 /* Header Functional Descriptor */
ua1arn 21:85a0f94a84cd 2087 static unsigned RNDIS_r9fill_31(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2088 {
ua1arn 21:85a0f94a84cd 2089 const uint_fast8_t length = 5;
ua1arn 21:85a0f94a84cd 2090 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2091 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2092 return 0;
ua1arn 21:85a0f94a84cd 2093 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2094 {
ua1arn 21:85a0f94a84cd 2095 const uint_fast16_t bcdCDC = CDC_V1_10; /* bcdCDC: spec release number */
ua1arn 21:85a0f94a84cd 2096 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2097 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2098 * buff ++ = CDC_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 2099 * buff ++ = 0x00; /* bDescriptorSubtype: Header Func Desc */
ua1arn 21:85a0f94a84cd 2100 * buff ++ = LO_BYTE(bcdCDC); /* bcdCDC: spec release number */
ua1arn 21:85a0f94a84cd 2101 * buff ++ = HI_BYTE(bcdCDC);
ua1arn 21:85a0f94a84cd 2102 }
ua1arn 21:85a0f94a84cd 2103 return length;
ua1arn 21:85a0f94a84cd 2104 }
ua1arn 21:85a0f94a84cd 2105
ua1arn 21:85a0f94a84cd 2106
ua1arn 21:85a0f94a84cd 2107 /* Call Managment Functional Descriptor */
ua1arn 21:85a0f94a84cd 2108 // Call Management Functional Descriptor
ua1arn 21:85a0f94a84cd 2109 static unsigned RNDIS_r9fill_32(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2110 {
ua1arn 21:85a0f94a84cd 2111 const uint_fast8_t length = 5;
ua1arn 21:85a0f94a84cd 2112 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2113 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2114 return 0;
ua1arn 21:85a0f94a84cd 2115 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2116 {
ua1arn 21:85a0f94a84cd 2117 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2118 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2119 * buff ++ = CS_INTERFACE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 2120 * buff ++ = 0x01; /* bDescriptorSubtype: Call Management Func Desc */
ua1arn 21:85a0f94a84cd 2121 * buff ++ = 0x00; /* bmCapabilities: D0+D1 */
ua1arn 21:85a0f94a84cd 2122 * buff ++ = INTERFACE_RNDIS_DATA_6; /* bDataInterface: Zero based index of the interface in this configuration.(bInterfaceNum) */
ua1arn 21:85a0f94a84cd 2123 }
ua1arn 21:85a0f94a84cd 2124 return length;
ua1arn 21:85a0f94a84cd 2125 }
ua1arn 21:85a0f94a84cd 2126
ua1arn 21:85a0f94a84cd 2127 // Abstract Control Management Functional Descriptor
ua1arn 21:85a0f94a84cd 2128 static unsigned RNDIS_r9fill_33(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2129 {
ua1arn 21:85a0f94a84cd 2130 const uint_fast8_t length = 4;
ua1arn 21:85a0f94a84cd 2131 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2132 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2133 return 0;
ua1arn 21:85a0f94a84cd 2134 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2135 {
ua1arn 21:85a0f94a84cd 2136 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2137 // defined in PSTN120.pdf 5.3.2 Abstract Control Management Functional Descriptor
ua1arn 21:85a0f94a84cd 2138 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2139 * buff ++ = CS_INTERFACE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 2140 * buff ++ = 0x02; /* bDescriptorSubtype: Abstract Control Management desc */
ua1arn 21:85a0f94a84cd 2141 * buff ++ = 0x00; /* bmCapabilities 0x00: Requests/notifications not supported */
ua1arn 21:85a0f94a84cd 2142 }
ua1arn 21:85a0f94a84cd 2143 return length;
ua1arn 21:85a0f94a84cd 2144 }
ua1arn 21:85a0f94a84cd 2145
ua1arn 21:85a0f94a84cd 2146
ua1arn 21:85a0f94a84cd 2147 /* Union Functional Descriptor */
ua1arn 21:85a0f94a84cd 2148 // Union Functional Descriptor
ua1arn 21:85a0f94a84cd 2149 static unsigned RNDIS_UnionFunctionalDescriptor(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2150 {
ua1arn 21:85a0f94a84cd 2151 const uint_fast8_t length = 5;
ua1arn 21:85a0f94a84cd 2152 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2153 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2154 return 0;
ua1arn 21:85a0f94a84cd 2155 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2156 {
ua1arn 21:85a0f94a84cd 2157 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2158 * buff ++ = length; /* bFunctionLength */
ua1arn 21:85a0f94a84cd 2159 * buff ++ = CS_INTERFACE; /* bDescriptorType: CS_INTERFACE */
ua1arn 21:85a0f94a84cd 2160 * buff ++ = CDC_UNION; /* bDescriptorSubtype: Union func desc */
ua1arn 21:85a0f94a84cd 2161 * buff ++ = INTERFACE_RNDIS_CONTROL_5; /* bMasterInterface: Communication class interface - Zero based index of the interface in this configuration (bInterfaceNum) */
ua1arn 21:85a0f94a84cd 2162 * buff ++ = INTERFACE_RNDIS_DATA_6; /* bSlaveInterface0: Data Class Interface - Zero based index of the interface in this configuration (bInterfaceNum) */
ua1arn 21:85a0f94a84cd 2163 }
ua1arn 21:85a0f94a84cd 2164 return length;
ua1arn 21:85a0f94a84cd 2165 }
ua1arn 21:85a0f94a84cd 2166
ua1arn 21:85a0f94a84cd 2167 /* Endpoint 3 Descriptor */
ua1arn 21:85a0f94a84cd 2168 // Endpoint Descriptor 86 6 In, Interrupt
ua1arn 21:85a0f94a84cd 2169
ua1arn 21:85a0f94a84cd 2170 static unsigned RNDIS_r9fill_35(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, int highspeed, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 2171 {
ua1arn 21:85a0f94a84cd 2172 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 2173 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2174 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2175 return 0;
ua1arn 21:85a0f94a84cd 2176 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2177 {
ua1arn 21:85a0f94a84cd 2178 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(RNDIS_NOTIFICATION_IN_SZ);
ua1arn 21:85a0f94a84cd 2179 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2180 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2181 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 2182 * buff ++ = bEndpointAddress; /* bEndpointAddress: (IN) */
ua1arn 21:85a0f94a84cd 2183 * buff ++ = USB_ENDPOINT_TYPE_INTERRUPT; /* bmAttributes: Interrupt */
ua1arn 21:85a0f94a84cd 2184 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 2185 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 2186 * buff ++ = highspeed ? HSINTERVAL_32MS : FSINTERVAL_32MS; /* bInterval: 32 mS */
ua1arn 21:85a0f94a84cd 2187 }
ua1arn 21:85a0f94a84cd 2188 return length;
ua1arn 21:85a0f94a84cd 2189 }
ua1arn 21:85a0f94a84cd 2190
ua1arn 21:85a0f94a84cd 2191 /* Data class interface descriptor*/
ua1arn 21:85a0f94a84cd 2192 // USBLyzer: Interface Descriptor 1/0 CDC Data, 2 Endpoints
ua1arn 21:85a0f94a84cd 2193 static unsigned RNDIS_InterfaceDescriptorDataIf(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2194 {
ua1arn 21:85a0f94a84cd 2195 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 2196 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2197 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2198 return 0;
ua1arn 21:85a0f94a84cd 2199 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2200 {
ua1arn 21:85a0f94a84cd 2201 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2202 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2203 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType: */
ua1arn 21:85a0f94a84cd 2204 * buff ++ = INTERFACE_RNDIS_DATA_6; /* bInterfaceNumber: Number of Interface */
ua1arn 21:85a0f94a84cd 2205 * buff ++ = 0; /* bAlternateSetting: Alternate setting - zero-based index */
ua1arn 21:85a0f94a84cd 2206 * buff ++ = 0x02; /* bNumEndpoints: Two endpoints used: data in and data out */
ua1arn 21:85a0f94a84cd 2207 * buff ++ = CDC_DATA_INTERFACE_CLASS; /* bInterfaceClass: CDC */
ua1arn 21:85a0f94a84cd 2208 * buff ++ = 0x00; /* bInterfaceSubClass: */
ua1arn 21:85a0f94a84cd 2209 * buff ++ = 0x00; /* bInterfaceProtocol: */
ua1arn 21:85a0f94a84cd 2210 * buff ++ = STRING_ID_0; /* iInterface: */
ua1arn 21:85a0f94a84cd 2211 }
ua1arn 21:85a0f94a84cd 2212 return length;
ua1arn 21:85a0f94a84cd 2213 }
ua1arn 21:85a0f94a84cd 2214
ua1arn 21:85a0f94a84cd 2215 /*Endpoint 2 IN Descriptor*/
ua1arn 21:85a0f94a84cd 2216 // Endpoint Descriptor 84 4 In, Bulk, 64 bytes
ua1arn 21:85a0f94a84cd 2217 static unsigned RNDIS_r9fill_38(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 2218 {
ua1arn 21:85a0f94a84cd 2219 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 2220 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2221 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2222 return 0;
ua1arn 21:85a0f94a84cd 2223 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2224 {
ua1arn 21:85a0f94a84cd 2225 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(RNDIS_DATA_IN_SZ);
ua1arn 21:85a0f94a84cd 2226 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2227 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2228 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 2229 * buff ++ = bEndpointAddress; /* bEndpointAddress: (IN2) */
ua1arn 21:85a0f94a84cd 2230 * buff ++ = USB_ENDPOINT_TYPE_BULK; /* bmAttributes: Bulk */
ua1arn 21:85a0f94a84cd 2231 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 2232 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 2233 * buff ++ = 0x00; /* bInterval: ignore for Bulk transfer */
ua1arn 21:85a0f94a84cd 2234 }
ua1arn 21:85a0f94a84cd 2235 return length;
ua1arn 21:85a0f94a84cd 2236 }
ua1arn 21:85a0f94a84cd 2237
ua1arn 21:85a0f94a84cd 2238 // Endpoint Descriptor
ua1arn 21:85a0f94a84cd 2239 static unsigned RNDIS_r9fill_37(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 2240 {
ua1arn 21:85a0f94a84cd 2241 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 2242 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2243 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2244 return 0;
ua1arn 21:85a0f94a84cd 2245 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2246 {
ua1arn 21:85a0f94a84cd 2247 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(RNDIS_DATA_OUT_SZ);
ua1arn 21:85a0f94a84cd 2248 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2249 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2250 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 2251 * buff ++ = bEndpointAddress; /* bEndpointAddress: (OUT2) */
ua1arn 21:85a0f94a84cd 2252 * buff ++ = USB_ENDPOINT_TYPE_BULK; /* bmAttributes: Bulk */
ua1arn 21:85a0f94a84cd 2253 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 2254 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 2255 * buff ++ = 0x00; /* bInterval: ignore for Bulk transfer */
ua1arn 21:85a0f94a84cd 2256 }
ua1arn 21:85a0f94a84cd 2257 return length;
ua1arn 21:85a0f94a84cd 2258 }
ua1arn 21:85a0f94a84cd 2259
ua1arn 21:85a0f94a84cd 2260
ua1arn 21:85a0f94a84cd 2261 /* CDC Ethernet Control Model */
ua1arn 21:85a0f94a84cd 2262 static unsigned fill_RNDIS_function(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed)
ua1arn 21:85a0f94a84cd 2263 {
ua1arn 21:85a0f94a84cd 2264 unsigned n = 0;
ua1arn 21:85a0f94a84cd 2265 // Interface Association Descriptor RF Controller
ua1arn 21:85a0f94a84cd 2266 // Configuration descriptor https://msdn.microsoft.com/en-US/library/ee482887(v=winembedded.60).aspx
ua1arn 21:85a0f94a84cd 2267 n += RNDIS_InterfaceAssociationDescriptor(fill, p + n, maxsize - n); /* CDC: Interface Association Descriptor Abstract Control Model */
ua1arn 21:85a0f94a84cd 2268 // Interface Descriptor 0/0 Wireless Controller, 1 Endpoint
ua1arn 21:85a0f94a84cd 2269 // Communication Class INTERFACE descriptor https://msdn.microsoft.com/en-US/library/ee485851(v=winembedded.60).aspx
ua1arn 21:85a0f94a84cd 2270 n += RNDIS_InterfaceDescriptorControlIf(fill, p + n, maxsize - n); /* INTERFACE_CDC_CONTROL_3a Interface Descriptor 3/0 CDC Control, 1 Endpoint */
ua1arn 21:85a0f94a84cd 2271 // Functional Descriptors for Communication Class Interface per RNDIS spec.
ua1arn 21:85a0f94a84cd 2272 // Header Functional Descriptor
ua1arn 21:85a0f94a84cd 2273 n += RNDIS_r9fill_31(fill, p + n, maxsize - n); // TODO: not need, not documented for this device class
ua1arn 21:85a0f94a84cd 2274 // Call Management Functional Descriptor
ua1arn 21:85a0f94a84cd 2275 n += RNDIS_r9fill_32(fill, p + n, maxsize - n);
ua1arn 21:85a0f94a84cd 2276 // Abstract Control Management Functional Descriptor
ua1arn 21:85a0f94a84cd 2277 n += RNDIS_r9fill_33(fill, p + n, maxsize - n);
ua1arn 21:85a0f94a84cd 2278 // Union Functional Descriptor
ua1arn 21:85a0f94a84cd 2279 n += RNDIS_UnionFunctionalDescriptor(fill, p + n, maxsize - n);
ua1arn 21:85a0f94a84cd 2280 // Endpoint descriptors for Communication Class Interface https://msdn.microsoft.com/en-US/library/ee482509(v=winembedded.60).aspx
ua1arn 21:85a0f94a84cd 2281 n += RNDIS_r9fill_35(fill, p + n, maxsize - n, highspeed, USB_ENDPOINT_IN(RNDIS_NOTIFICATION_IN_EP)); /* Endpoint Descriptor 86 6 In, Interrupt */
ua1arn 21:85a0f94a84cd 2282 // Data Class INTERFACE descriptor https://msdn.microsoft.com/en-US/library/ee481260(v=winembedded.60).aspx
ua1arn 21:85a0f94a84cd 2283 n += RNDIS_InterfaceDescriptorDataIf(fill, p + n, maxsize - n); /* INTERFACE_CDC_DATA_4a Data class interface descriptor */
ua1arn 21:85a0f94a84cd 2284 // IN Endpoint descriptor https://msdn.microsoft.com/en-US/library/ee484483(v=winembedded.60).aspx
ua1arn 21:85a0f94a84cd 2285 n += RNDIS_r9fill_38(fill, p + n, maxsize - n, USB_ENDPOINT_IN(RNDIS_DATA_IN_EP)); /* Endpoint Descriptor USBD_EP_CDCECM_IN In, Bulk, 64 bytes */
ua1arn 21:85a0f94a84cd 2286 // OUT Endpoint descriptor https://msdn.microsoft.com/en-US/library/ee482464(v=winembedded.60).aspx
ua1arn 21:85a0f94a84cd 2287 n += RNDIS_r9fill_37(fill, p + n, maxsize - n, USB_ENDPOINT_OUT(RNDIS_DATA_OUT_EP)); /* Endpoint Descriptor USBD_EP_CDCECM_OUT Out, Bulk, 64 bytes */
ua1arn 21:85a0f94a84cd 2288 return n;
ua1arn 21:85a0f94a84cd 2289 }
ua1arn 21:85a0f94a84cd 2290
ua1arn 21:85a0f94a84cd 2291 #endif /* WITHUSBRNDIS */
ua1arn 21:85a0f94a84cd 2292
ua1arn 21:85a0f94a84cd 2293 #if WITHUSBHID
ua1arn 21:85a0f94a84cd 2294
ua1arn 21:85a0f94a84cd 2295 static unsigned HID_InterfaceDescriptorXXXX(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2296 {
ua1arn 21:85a0f94a84cd 2297 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 2298 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2299 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2300 return 0;
ua1arn 21:85a0f94a84cd 2301 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2302 {
ua1arn 21:85a0f94a84cd 2303 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2304 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2305 * buff ++ = USB_INTERFACE_DESCRIPTOR_TYPE; /* bDescriptorType: */
ua1arn 21:85a0f94a84cd 2306 * buff ++ = INTERFACE_HID_CONTROL_7; // bInterfaceNumber
ua1arn 21:85a0f94a84cd 2307 * buff ++ = 0x00; /* bAlternateSetting */
ua1arn 21:85a0f94a84cd 2308 * buff ++ = 0;//0x01; /* bNumEndpoints */
ua1arn 21:85a0f94a84cd 2309 * buff ++ = USB_DEVICE_CLASS_HUMAN_INTERFACE; /* bInterfaceClass */
ua1arn 21:85a0f94a84cd 2310 * buff ++ = 0;//0x01; /* bInterfaceSubClass = boot interfsce */
ua1arn 21:85a0f94a84cd 2311 * buff ++ = 0;//0x02; /* bInterfaceProtocol: 1 = keyboard, 2 = mouse */
ua1arn 21:85a0f94a84cd 2312 * buff ++ = 0;//STRING_ID_HIDa; /* iInterface */
ua1arn 21:85a0f94a84cd 2313 }
ua1arn 21:85a0f94a84cd 2314 return length;
ua1arn 21:85a0f94a84cd 2315 }
ua1arn 21:85a0f94a84cd 2316
ua1arn 21:85a0f94a84cd 2317 static unsigned HID_Descriptor(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, unsigned wDescriptorLength)
ua1arn 21:85a0f94a84cd 2318 {
ua1arn 21:85a0f94a84cd 2319 const uint_fast8_t length = 9;
ua1arn 21:85a0f94a84cd 2320 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2321 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2322 return 0;
ua1arn 21:85a0f94a84cd 2323 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2324 {
ua1arn 21:85a0f94a84cd 2325 const uint_fast16_t bcdHID = 0x0111; // Revision of class specification - 1.11
ua1arn 21:85a0f94a84cd 2326 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2327 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2328 * buff ++ = HID_DESCRIPTOR_TYPE; /* bDescriptorType = HID */
ua1arn 21:85a0f94a84cd 2329 * buff ++ = LO_BYTE(bcdHID); /* bcdHID */
ua1arn 21:85a0f94a84cd 2330 * buff ++ = HI_BYTE(bcdHID);
ua1arn 21:85a0f94a84cd 2331 * buff ++ = 0x00; /* bCountryCode */
ua1arn 21:85a0f94a84cd 2332 * buff ++ = 1; /* bNumDescriptors=1 */
ua1arn 21:85a0f94a84cd 2333 * buff ++ = HID_REPORT_DESC; /* bDescriptorType: 0x22: report */
ua1arn 21:85a0f94a84cd 2334 * buff ++ = LO_BYTE(wDescriptorLength); /* wTotalLength */
ua1arn 21:85a0f94a84cd 2335 * buff ++ = HI_BYTE(wDescriptorLength);
ua1arn 21:85a0f94a84cd 2336 /* 9 bytes*/
ua1arn 21:85a0f94a84cd 2337 }
ua1arn 21:85a0f94a84cd 2338 return length;
ua1arn 21:85a0f94a84cd 2339
ua1arn 21:85a0f94a84cd 2340 }
ua1arn 21:85a0f94a84cd 2341
ua1arn 21:85a0f94a84cd 2342 #if 0
ua1arn 21:85a0f94a84cd 2343 // Endpoint Descriptor In, Interrupt
ua1arn 21:85a0f94a84cd 2344 static unsigned fill_HID_Mouse_IntEP(uint_fast8_t fill, uint8_t * buff, unsigned maxsize, int highspeed, uint_fast8_t bEndpointAddress)
ua1arn 21:85a0f94a84cd 2345 {
ua1arn 21:85a0f94a84cd 2346 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 2347 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2348 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2349 return 0;
ua1arn 21:85a0f94a84cd 2350 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2351 {
ua1arn 21:85a0f94a84cd 2352 const uint_fast16_t wMaxPacketSize = encodeMaxPacketSize(HIDMOUSE_INT_DATA_SIZE);
ua1arn 21:85a0f94a84cd 2353 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2354 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2355 * buff ++ = USB_ENDPOINT_DESCRIPTOR_TYPE; /* bDescriptorType: Endpoint */
ua1arn 21:85a0f94a84cd 2356 * buff ++ = bEndpointAddress; /* bEndpointAddress: (IN) */
ua1arn 21:85a0f94a84cd 2357 * buff ++ = USB_ENDPOINT_TYPE_INTERRUPT; /* bmAttributes: Interrupt */
ua1arn 21:85a0f94a84cd 2358 * buff ++ = LO_BYTE(wMaxPacketSize); /* wMaxPacketSize */
ua1arn 21:85a0f94a84cd 2359 * buff ++ = HI_BYTE(wMaxPacketSize);
ua1arn 21:85a0f94a84cd 2360 * buff ++ = highspeed ? 0x07 : 0x0A; /* bInterval: 10 mS */
ua1arn 21:85a0f94a84cd 2361 }
ua1arn 21:85a0f94a84cd 2362 return length;
ua1arn 21:85a0f94a84cd 2363 }
ua1arn 21:85a0f94a84cd 2364 #endif
ua1arn 21:85a0f94a84cd 2365
ua1arn 21:85a0f94a84cd 2366 // HID Report Descriptor
ua1arn 21:85a0f94a84cd 2367 // mouse
ua1arn 21:85a0f94a84cd 2368 static const uint8_t HID_report_desc_mouse []=
ua1arn 21:85a0f94a84cd 2369 {
ua1arn 21:85a0f94a84cd 2370 0x05, 0x01, // Usage Page (Generic Desktop)
ua1arn 21:85a0f94a84cd 2371 0x09, 0x02, // Usage (Mouse)
ua1arn 21:85a0f94a84cd 2372 0xA1, 0x01, // Collection (Application)
ua1arn 21:85a0f94a84cd 2373 0x09, 0x01, // Usage (Pointer)
ua1arn 21:85a0f94a84cd 2374 0xA1, 0x00, // Collection (Physical)
ua1arn 21:85a0f94a84cd 2375 0x05, 0x09, // Usage Page (Button)
ua1arn 21:85a0f94a84cd 2376 0x19, 0x01, // Usage Minimum (Button 1)
ua1arn 21:85a0f94a84cd 2377 0x29, 0x03, // Usage Maximum (Button 3)
ua1arn 21:85a0f94a84cd 2378 0x15, 0x00, // Logical Minimum (0)
ua1arn 21:85a0f94a84cd 2379 0x25, 0x01, // Logical Maximum (1)
ua1arn 21:85a0f94a84cd 2380 0x95, 0x08, // Report Count (8)
ua1arn 21:85a0f94a84cd 2381 0x75, 0x01, // Report Size (1)
ua1arn 21:85a0f94a84cd 2382 0x81, 0x02, // Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
ua1arn 21:85a0f94a84cd 2383 0x05, 0x01, // Usage Page (Generic Desktop)
ua1arn 21:85a0f94a84cd 2384 0x09, 0x30, // Usage (X)
ua1arn 21:85a0f94a84cd 2385 0x09, 0x31, // Usage (Y)
ua1arn 21:85a0f94a84cd 2386 0x09, 0x38, // Usage (Wheel)
ua1arn 21:85a0f94a84cd 2387 0x15, 0x81, // Logical Minimum (-127)
ua1arn 21:85a0f94a84cd 2388 0x25, 0x7F, // Logical Maximum (127)
ua1arn 21:85a0f94a84cd 2389 0x75, 0x08, // Report Size (8)
ua1arn 21:85a0f94a84cd 2390 0x95, 0x03, // Report Count (3)
ua1arn 21:85a0f94a84cd 2391 0x81, 0x06, // Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit)
ua1arn 21:85a0f94a84cd 2392 0xC0, // End Collection
ua1arn 21:85a0f94a84cd 2393 0xC0, // End Collection
ua1arn 21:85a0f94a84cd 2394 };
ua1arn 21:85a0f94a84cd 2395
ua1arn 21:85a0f94a84cd 2396 // HID Report Descriptor
ua1arn 21:85a0f94a84cd 2397 // keyboard
ua1arn 21:85a0f94a84cd 2398 static const uint8_t HID_report_desc_keyboard []=
ua1arn 21:85a0f94a84cd 2399 {
ua1arn 21:85a0f94a84cd 2400 0x05, 0x01, // Usage Page (Generic Desktop)
ua1arn 21:85a0f94a84cd 2401 0x09, 0x06, // Usage (Keyboard)
ua1arn 21:85a0f94a84cd 2402 0xA1, 0x01, // Collection (Application)
ua1arn 21:85a0f94a84cd 2403 0x05, 0x07, // Usage Page (Key Codes)
ua1arn 21:85a0f94a84cd 2404 0x19, 0xE0, // Usage Minimum (224)
ua1arn 21:85a0f94a84cd 2405 0x29, 0xE7, // Usage Maximum (231)
ua1arn 21:85a0f94a84cd 2406 0x15, 0x00, // Logical Minimum (0)
ua1arn 21:85a0f94a84cd 2407 0x25, 0x01, // Logical Maximum (1)
ua1arn 21:85a0f94a84cd 2408 0x75, 0x01, // Report Size (1)
ua1arn 21:85a0f94a84cd 2409 0x95, 0x08, // Report Count (8)
ua1arn 21:85a0f94a84cd 2410 0x81, 0x02, // Input (Data, Variable, Absolute) -- Modifier byte
ua1arn 21:85a0f94a84cd 2411 0x95, 0x01, // Report Count (1)
ua1arn 21:85a0f94a84cd 2412 0x75, 0x08, // Report Size (8)
ua1arn 21:85a0f94a84cd 2413 0x81, 0x03, // (81 01) Input (Constant) -- Reserved byte
ua1arn 21:85a0f94a84cd 2414 0x95, 0x05, // Report Count (5)
ua1arn 21:85a0f94a84cd 2415 0x75, 0x01, // Report Size (1)
ua1arn 21:85a0f94a84cd 2416 0x05, 0x08, // Usage Page (Page# for LEDs)
ua1arn 21:85a0f94a84cd 2417 0x19, 0x01, // Usage Minimum (1)
ua1arn 21:85a0f94a84cd 2418 0x29, 0x05, // Usage Maximum (5)
ua1arn 21:85a0f94a84cd 2419 0x91, 0x02, // Output (Data, Variable, Absolute) -- LED report
ua1arn 21:85a0f94a84cd 2420 0x95, 0x01, // Report Count (1)
ua1arn 21:85a0f94a84cd 2421 0x75, 0x03, // Report Size (3)
ua1arn 21:85a0f94a84cd 2422 0x91, 0x03, // (91 03) Output (Constant) -- LED report padding
ua1arn 21:85a0f94a84cd 2423 0x95, 0x06, // Report Count (6)
ua1arn 21:85a0f94a84cd 2424 0x75, 0x08, // Report Size (8)
ua1arn 21:85a0f94a84cd 2425 0x15, 0x00, // Logical Minimum (0)
ua1arn 21:85a0f94a84cd 2426 0x25, 0x66, // Logical Maximum(102) // was 0x65
ua1arn 21:85a0f94a84cd 2427 0x05, 0x07, // Usage Page (Key Codes)
ua1arn 21:85a0f94a84cd 2428 0x19, 0x00, // Usage Minimum (0)
ua1arn 21:85a0f94a84cd 2429 0x29, 0x66, // Usage Maximum (102) // was 0x65
ua1arn 21:85a0f94a84cd 2430 0x81, 0x00, // Input (Data, Array) -- Key arrays (6 bytes)
ua1arn 21:85a0f94a84cd 2431 0xC0, // End Collection
ua1arn 21:85a0f94a84cd 2432
ua1arn 21:85a0f94a84cd 2433 };
ua1arn 21:85a0f94a84cd 2434
ua1arn 21:85a0f94a84cd 2435
ua1arn 21:85a0f94a84cd 2436 // HID Report Descriptor
ua1arn 21:85a0f94a84cd 2437 // keyboard
ua1arn 21:85a0f94a84cd 2438 static const uint8_t HID_report_desc_display []=
ua1arn 21:85a0f94a84cd 2439 {
ua1arn 21:85a0f94a84cd 2440 0x05, 0x14, // USAGE_PAGE (Alphnumeric Display)
ua1arn 21:85a0f94a84cd 2441 0x09, 0x01, // USAGE (Alphanumeric Display)
ua1arn 21:85a0f94a84cd 2442 0x15, 0x00, // LOGICAL_MINIMUM (0)
ua1arn 21:85a0f94a84cd 2443 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2444 0x09, 0x20, // USAGE (Display Attributes Report)
ua1arn 21:85a0f94a84cd 2445 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2446 0x09, 0x35, // USAGE (Rows)
ua1arn 21:85a0f94a84cd 2447 0x09, 0x36, // USAGE (Columns)
ua1arn 21:85a0f94a84cd 2448 0x09, 0x3d, // USAGE (Character Width)
ua1arn 21:85a0f94a84cd 2449 0x09, 0x3e, // USAGE (Character Height)
ua1arn 21:85a0f94a84cd 2450 0x85, 0x01, // REPORT_ID (1)
ua1arn 21:85a0f94a84cd 2451 0x25, 0x1f, // LOGICAL_MAXIMUM (31)
ua1arn 21:85a0f94a84cd 2452 0x75, 0x05, // REPORT_SIZE (5)
ua1arn 21:85a0f94a84cd 2453 0x95, 0x04, // REPORT_COUNT (4)
ua1arn 21:85a0f94a84cd 2454 0xb1, 0x03, // FEATURE (Cnst,Var,Abs)
ua1arn 21:85a0f94a84cd 2455 0x75, 0x01, // REPORT_SIZE (1)
ua1arn 21:85a0f94a84cd 2456 0x95, 0x03, // REPORT_COUNT (3)
ua1arn 21:85a0f94a84cd 2457 0x25, 0x01, // LOGICAL_MAXIMUM (1)
ua1arn 21:85a0f94a84cd 2458 0x09, 0x21, // USAGE (ASCII Character Set)
ua1arn 21:85a0f94a84cd 2459 0x09, 0x22, // USAGE (Data Read Back)
ua1arn 21:85a0f94a84cd 2460 0x09, 0x29, // USAGE (Vertical Scroll)
ua1arn 21:85a0f94a84cd 2461 0xb1, 0x03, // FEATURE (Cnst,Var,Abs)
ua1arn 21:85a0f94a84cd 2462 0x95, 0x03, // REPORT_COUNT (3)
ua1arn 21:85a0f94a84cd 2463 0xb1, 0x03, // FEATURE (Cnst,Var,Abs)
ua1arn 21:85a0f94a84cd 2464 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2465 0x75, 0x08, // REPORT_SIZE (8)
ua1arn 21:85a0f94a84cd 2466 0x95, 0x01, // REPORT_COUNT (1)
ua1arn 21:85a0f94a84cd 2467 0x25, 0x02, // LOGICAL_MAXIMUM (2)
ua1arn 21:85a0f94a84cd 2468 0x09, 0x2d, // USAGE (Display Status)
ua1arn 21:85a0f94a84cd 2469 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2470 0x09, 0x2e, // USAGE (Stat Not Ready)
ua1arn 21:85a0f94a84cd 2471 0x09, 0x2f, // USAGE (Stat Ready)
ua1arn 21:85a0f94a84cd 2472 0x09, 0x30, // USAGE (Err Not a loadable character)
ua1arn 21:85a0f94a84cd 2473 0x81, 0x40, // INPUT (Data,Ary,Abs,Null)
ua1arn 21:85a0f94a84cd 2474 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2475 0x09, 0x32, // USAGE (Cursor Position Report)
ua1arn 21:85a0f94a84cd 2476 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2477 0x85, 0x02, // REPORT_ID (2)
ua1arn 21:85a0f94a84cd 2478 0x75, 0x04, // REPORT_SIZE (4)
ua1arn 21:85a0f94a84cd 2479 0x95, 0x01, // REPORT_COUNT (1)
ua1arn 21:85a0f94a84cd 2480 0x25, 0x0f, // LOGICAL_MAXIMUM (15)
ua1arn 21:85a0f94a84cd 2481 0x09, 0x34, // USAGE (Column)
ua1arn 21:85a0f94a84cd 2482 0xb1, 0x22, // FEATURE (Data,Var,Abs,NPrf)
ua1arn 21:85a0f94a84cd 2483 0x25, 0x01, // LOGICAL_MAXIMUM (1)
ua1arn 21:85a0f94a84cd 2484 0x09, 0x33, // USAGE (Row)
ua1arn 21:85a0f94a84cd 2485 0xb1, 0x22, // FEATURE (Data,Var,Abs,NPrf)
ua1arn 21:85a0f94a84cd 2486 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2487 0x09, 0x2b, // USAGE (Character Report)
ua1arn 21:85a0f94a84cd 2488 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2489 0x85, 0x03, // REPORT_ID (3)
ua1arn 21:85a0f94a84cd 2490 0x75, 0x08, // REPORT_SIZE (8)
ua1arn 21:85a0f94a84cd 2491 0x95, 0x04, // REPORT_COUNT (4)
ua1arn 21:85a0f94a84cd 2492 0x25, 0x7e, // LOGICAL_MAXIMUM (126)
ua1arn 21:85a0f94a84cd 2493 0x09, 0x2c, // USAGE (Display Data)
ua1arn 21:85a0f94a84cd 2494 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
ua1arn 21:85a0f94a84cd 2495 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2496 0x85, 0x04, // REPORT_ID (4)
ua1arn 21:85a0f94a84cd 2497 0x09, 0x3b, // USAGE (Font Report)
ua1arn 21:85a0f94a84cd 2498 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2499 0x15, 0x00, // LOGICAL_MINIMUM (0)
ua1arn 21:85a0f94a84cd 2500 0x25, 0x7e, // LOGICAL_MAXIMUM (126)
ua1arn 21:85a0f94a84cd 2501 0x75, 0x08, // REPORT_SIZE (8)
ua1arn 21:85a0f94a84cd 2502 0x95, 0x01, // REPORT_COUNT (1)
ua1arn 21:85a0f94a84cd 2503 0x09, 0x2c, // USAGE (Display Data)
ua1arn 21:85a0f94a84cd 2504 0x91, 0x02, // OUTPUT (Data,Var,Abs)
ua1arn 21:85a0f94a84cd 2505 0x95, 0x05, // REPORT_COUNT (5)
ua1arn 21:85a0f94a84cd 2506 0x09, 0x3c, // USAGE (Font Data)
ua1arn 21:85a0f94a84cd 2507 0x92, 0x02, 0x01, // OUTPUT (Data,Var,Abs,Buf)
ua1arn 21:85a0f94a84cd 2508 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2509 0xc0 // END_COLLECTION
ua1arn 21:85a0f94a84cd 2510 };
ua1arn 21:85a0f94a84cd 2511
ua1arn 21:85a0f94a84cd 2512
ua1arn 21:85a0f94a84cd 2513 // HID Report Descriptor
ua1arn 21:85a0f94a84cd 2514 // keyboard
ua1arn 21:85a0f94a84cd 2515 static const uint8_t hid_report_desc_telephony [] =
ua1arn 21:85a0f94a84cd 2516 {
ua1arn 21:85a0f94a84cd 2517 0x95, 0x01, // REPORT_COUNT (1)
ua1arn 21:85a0f94a84cd 2518 0x05, 0x0b, // USAGE_PAGE (Telephony Devices)
ua1arn 21:85a0f94a84cd 2519 0x09, 0x01, // USAGE (Phone)
ua1arn 21:85a0f94a84cd 2520 0xa1, 0x01, // COLLECTION (Application)
ua1arn 21:85a0f94a84cd 2521 0x09, 0x07, // USAGE (Programmable Button)
ua1arn 21:85a0f94a84cd 2522 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2523 0x05, 0x09, // USAGE_PAGE (Button)
ua1arn 21:85a0f94a84cd 2524 0x19, 0x01, // USAGE_MINIMUM (Button 1)
ua1arn 21:85a0f94a84cd 2525 0x29, 0x06, // USAGE_MAXIMUM (Button 6)
ua1arn 21:85a0f94a84cd 2526 0x75, 0x03, // REPORT_SIZE (3)
ua1arn 21:85a0f94a84cd 2527 0x15, 0x01, // LOGICAL_MINIMUM (1)
ua1arn 21:85a0f94a84cd 2528 0x25, 0x06, // LOGICAL_MAXIMUM (6)
ua1arn 21:85a0f94a84cd 2529 0x81, 0x00, // INPUT (Data,Ary,Abs)
ua1arn 21:85a0f94a84cd 2530 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2531 0x05, 0x0b, // USAGE_PAGE (Telephony Devices)
ua1arn 21:85a0f94a84cd 2532 0x09, 0x06, // USAGE (Telephony Key Pad)
ua1arn 21:85a0f94a84cd 2533 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2534 0x05, 0x09, // USAGE_PAGE (Button)
ua1arn 21:85a0f94a84cd 2535 0x19, 0x01, // USAGE_MINIMUM (Button 1)
ua1arn 21:85a0f94a84cd 2536 0x29, 0x0c, // USAGE_MAXIMUM (Button 12)
ua1arn 21:85a0f94a84cd 2537 0x25, 0x0c, // LOGICAL_MAXIMUM (12)
ua1arn 21:85a0f94a84cd 2538 0x75, 0x04, // REPORT_SIZE (4)
ua1arn 21:85a0f94a84cd 2539 0x81, 0x00, // INPUT (Data,Ary,Abs)
ua1arn 21:85a0f94a84cd 2540 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2541 0x05, 0x0b, // USAGE_PAGE (Telephony Devices)
ua1arn 21:85a0f94a84cd 2542 0x09, 0x20, // USAGE (Hook Switch)
ua1arn 21:85a0f94a84cd 2543 0x09, 0x29, // USAGE (Alternate Function)
ua1arn 21:85a0f94a84cd 2544 0x09, 0x2c, // USAGE (Conference)
ua1arn 21:85a0f94a84cd 2545 0x09, 0x25, // USAGE (Transfer)
ua1arn 21:85a0f94a84cd 2546 0x09, 0x26, // USAGE (Drop)
ua1arn 21:85a0f94a84cd 2547 0x09, 0x23, // USAGE (Hold)
ua1arn 21:85a0f94a84cd 2548 0x09, 0x2b, // USAGE (Speaker Phone)
ua1arn 21:85a0f94a84cd 2549 0x25, 0x07, // LOGICAL_MAXIMUM (7)
ua1arn 21:85a0f94a84cd 2550 0x75, 0x03, // REPORT_SIZE (3)
ua1arn 21:85a0f94a84cd 2551 0x81, 0x00, // INPUT (Data,Ary,Abs)
ua1arn 21:85a0f94a84cd 2552 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
ua1arn 21:85a0f94a84cd 2553 0x09, 0xe0, // USAGE (Volume)
ua1arn 21:85a0f94a84cd 2554 0x15, 0xff, // LOGICAL_MINIMUM (-1)
ua1arn 21:85a0f94a84cd 2555 0x25, 0x01, // LOGICAL_MAXIMUM (1)
ua1arn 21:85a0f94a84cd 2556 0x75, 0x02, // REPORT_SIZE (2)
ua1arn 21:85a0f94a84cd 2557 0x81, 0x02, // INPUT (Data,Var,Abs)
ua1arn 21:85a0f94a84cd 2558 0x75, 0x04, // REPORT_SIZE (4)
ua1arn 21:85a0f94a84cd 2559 0x81, 0x03, // INPUT (Cnst,Var,Abs)
ua1arn 21:85a0f94a84cd 2560 0x15, 0x00, // LOGICAL_MINIMUM (0)
ua1arn 21:85a0f94a84cd 2561 0x25, 0x01, // LOGICAL_MAXIMUM (1)
ua1arn 21:85a0f94a84cd 2562 0x05, 0x08, // USAGE_PAGE (LEDs)
ua1arn 21:85a0f94a84cd 2563 0x09, 0x3a, // USAGE (Usage Selected Indicator)
ua1arn 21:85a0f94a84cd 2564 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2565 0x05, 0x0b, // USAGE_PAGE (Telephony Devices)
ua1arn 21:85a0f94a84cd 2566 0x09, 0x07, // USAGE (Programmable Button)
ua1arn 21:85a0f94a84cd 2567 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2568 0x05, 0x09, // USAGE_PAGE (Button)
ua1arn 21:85a0f94a84cd 2569 0x19, 0x01, // USAGE_MINIMUM (Button 1)
ua1arn 21:85a0f94a84cd 2570 0x29, 0x02, // USAGE_MAXIMUM (Button 2)
ua1arn 21:85a0f94a84cd 2571 0x95, 0x02, // REPORT_COUNT (2)
ua1arn 21:85a0f94a84cd 2572 0x91, 0x02, // OUTPUT (Data,Var,Abs)
ua1arn 21:85a0f94a84cd 2573 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2574 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2575 0x05, 0x08, // USAGE_PAGE (LEDs)
ua1arn 21:85a0f94a84cd 2576 0x09, 0x3b, // USAGE (Usage In Use Indicator)
ua1arn 21:85a0f94a84cd 2577 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2578 0x05, 0x0b, // USAGE_PAGE (Telephony Devices)
ua1arn 21:85a0f94a84cd 2579 0x09, 0x07, // USAGE (Programmable Button)
ua1arn 21:85a0f94a84cd 2580 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2581 0x05, 0x09, // USAGE_PAGE (Button)
ua1arn 21:85a0f94a84cd 2582 0x19, 0x01, // USAGE_MINIMUM (Undefined)
ua1arn 21:85a0f94a84cd 2583 0x29, 0x06, // USAGE_MAXIMUM (Undefined)
ua1arn 21:85a0f94a84cd 2584 0x95, 0x06, // REPORT_COUNT (6)
ua1arn 21:85a0f94a84cd 2585 0x91, 0x02, // OUTPUT (Data,Var,Abs)
ua1arn 21:85a0f94a84cd 2586 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2587 0x05, 0x0b, // USAGE_PAGE (Telephony Devices)
ua1arn 21:85a0f94a84cd 2588 0x09, 0x29, // USAGE (Alternate Function)
ua1arn 21:85a0f94a84cd 2589 0x95, 0x01, // REPORT_COUNT (1)
ua1arn 21:85a0f94a84cd 2590 0x91, 0x02, // OUTPUT (Data,Var,Abs)
ua1arn 21:85a0f94a84cd 2591 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2592 0x05, 0x08, // USAGE_PAGE (LEDs)
ua1arn 21:85a0f94a84cd 2593 0x09, 0x3c, // USAGE (Usage Multi Mode Indicator)
ua1arn 21:85a0f94a84cd 2594 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2595 0x05, 0x0b, // USAGE_PAGE (Telephony Devices)
ua1arn 21:85a0f94a84cd 2596 0x09, 0x73, // USAGE (Message)
ua1arn 21:85a0f94a84cd 2597 0xa1, 0x02, // COLLECTION (Logical)
ua1arn 21:85a0f94a84cd 2598 0x05, 0x08, // USAGE_PAGE (LEDs)
ua1arn 21:85a0f94a84cd 2599 0x09, 0x3d, // USAGE (Indicator On)
ua1arn 21:85a0f94a84cd 2600 0x09, 0x40, // USAGE (Indicator Fast Blink)
ua1arn 21:85a0f94a84cd 2601 0x09, 0x41, // USAGE (Indicator Off)
ua1arn 21:85a0f94a84cd 2602 0x75, 0x02, // REPORT_SIZE (2)
ua1arn 21:85a0f94a84cd 2603 0x91, 0x00, // OUTPUT (Data,Ary,Abs)
ua1arn 21:85a0f94a84cd 2604 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2605 0xc0, // END_COLLECTION
ua1arn 21:85a0f94a84cd 2606 0x75, 0x05, // REPORT_SIZE (5)
ua1arn 21:85a0f94a84cd 2607 0x81, 0x03, // INPUT (Cnst,Var,Abs)
ua1arn 21:85a0f94a84cd 2608 0xc0 // END_COLLECTION
ua1arn 21:85a0f94a84cd 2609 };
ua1arn 21:85a0f94a84cd 2610
ua1arn 21:85a0f94a84cd 2611
ua1arn 21:85a0f94a84cd 2612 /* HID Human Interface Device */
ua1arn 21:85a0f94a84cd 2613 static unsigned fill_HID_XXXX_function(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed)
ua1arn 21:85a0f94a84cd 2614 {
ua1arn 21:85a0f94a84cd 2615 // HID Report Descriptor used for this function
ua1arn 21:85a0f94a84cd 2616 #define HIDREPORTDESC HID_report_desc_keyboard
ua1arn 21:85a0f94a84cd 2617 //#define HIDREPORTDESC HID_report_desc_mouse
ua1arn 21:85a0f94a84cd 2618 //#define HIDREPORTDESC HID_report_desc_display
ua1arn 21:85a0f94a84cd 2619 //#define HIDREPORTDESC hid_report_desc_telephony
ua1arn 21:85a0f94a84cd 2620
ua1arn 21:85a0f94a84cd 2621 const void * const pattern = HIDREPORTDESC;
ua1arn 21:85a0f94a84cd 2622 const unsigned patternlength = sizeof HIDREPORTDESC;
ua1arn 21:85a0f94a84cd 2623 //
ua1arn 21:85a0f94a84cd 2624 unsigned n = 0;
ua1arn 21:85a0f94a84cd 2625 //
ua1arn 21:85a0f94a84cd 2626 n += HID_InterfaceDescriptorXXXX(fill, p + n, maxsize - n); /* HID: HID Interface Descriptor */
ua1arn 21:85a0f94a84cd 2627 n += HID_Descriptor(fill, p + n, maxsize - n, patternlength); /* HID Descriptor */
ua1arn 21:85a0f94a84cd 2628 //n += fill_HID_Mouse_IntEP(fill, p + n, maxsize - n, highspeed, USB_ENDPOINT_IN(USBD_EP_HIDMOUSE_INT));
ua1arn 21:85a0f94a84cd 2629
ua1arn 21:85a0f94a84cd 2630 return n;
ua1arn 21:85a0f94a84cd 2631 }
ua1arn 21:85a0f94a84cd 2632
ua1arn 21:85a0f94a84cd 2633 #endif /* WITHUSBHID */
ua1arn 21:85a0f94a84cd 2634
ua1arn 21:85a0f94a84cd 2635 static unsigned fill_Configuration_main_group(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed)
ua1arn 21:85a0f94a84cd 2636 {
ua1arn 21:85a0f94a84cd 2637 unsigned n = 0;
ua1arn 21:85a0f94a84cd 2638 unsigned offset;
ua1arn 21:85a0f94a84cd 2639
ua1arn 21:85a0f94a84cd 2640 #if WITHUSBRNDIS
ua1arn 21:85a0f94a84cd 2641 n += fill_RNDIS_function(fill, p + n, maxsize - n, highspeed);
ua1arn 21:85a0f94a84cd 2642 #endif /* WITHUSBRNDIS */
ua1arn 21:85a0f94a84cd 2643
ua1arn 21:85a0f94a84cd 2644 #if WITHUSBUAC
ua1arn 21:85a0f94a84cd 2645 #if WITHUSBUAC3
ua1arn 21:85a0f94a84cd 2646 n += fill_UACINOUT48_function(fill, p + n, maxsize - n, highspeed, 0);
ua1arn 21:85a0f94a84cd 2647 //n += fill_UACINOUT48andRTS_function(fill, p + n, maxsize - n, highspeed, 0);
ua1arn 21:85a0f94a84cd 2648 #if WITHRTS96 || WITHRTS192
ua1arn 21:85a0f94a84cd 2649 n += fill_UACINRTS_function(fill, p + n, maxsize - n, highspeed, 1);
ua1arn 21:85a0f94a84cd 2650 #else /* WITHRTS96 || WITHRTS192 */
ua1arn 21:85a0f94a84cd 2651 #error WITHRTS96 or WITHRTS192 required for WITHUSBUAC3
ua1arn 21:85a0f94a84cd 2652 #endif /* WITHRTS96 || WITHRTS192 */
ua1arn 21:85a0f94a84cd 2653 #else /* WITHUSBUAC3 */
ua1arn 21:85a0f94a84cd 2654 n += fill_UACINOUT_function(fill, p + n, maxsize - n, highspeed, 0);
ua1arn 21:85a0f94a84cd 2655 #endif /* WITHUSBUAC3 */
ua1arn 21:85a0f94a84cd 2656 #endif /* WITHUSBUAC */
ua1arn 21:85a0f94a84cd 2657
ua1arn 21:85a0f94a84cd 2658 #if WITHUSBCDC
ua1arn 21:85a0f94a84cd 2659 for (offset = 0; offset < WITHUSBHWCDC_N; ++ offset)
ua1arn 21:85a0f94a84cd 2660 n += fill_CDCACM_function_a(fill, p + n, maxsize - n, highspeed, offset);
ua1arn 21:85a0f94a84cd 2661 #endif /* WITHUSBCDC */
ua1arn 21:85a0f94a84cd 2662
ua1arn 21:85a0f94a84cd 2663 #if WITHUSBCDCEEM
ua1arn 21:85a0f94a84cd 2664 n += fill_CDCEEM_function(fill, p + n, maxsize - n, highspeed);
ua1arn 21:85a0f94a84cd 2665 #endif /* WITHUSBCDCEEM */
ua1arn 21:85a0f94a84cd 2666
ua1arn 21:85a0f94a84cd 2667 #if WITHUSBCDCECM
ua1arn 21:85a0f94a84cd 2668 n += fill_CDCECM_function(fill, p + n, maxsize - n, highspeed);
ua1arn 21:85a0f94a84cd 2669 #endif /* WITHUSBCDCECM */
ua1arn 21:85a0f94a84cd 2670
ua1arn 21:85a0f94a84cd 2671 #if WITHUSBHID
ua1arn 21:85a0f94a84cd 2672 n += fill_HID_XXXX_function(fill, p + n, maxsize - n, highspeed);
ua1arn 21:85a0f94a84cd 2673 #endif /* WITHUSBHID */
ua1arn 21:85a0f94a84cd 2674 return n;
ua1arn 21:85a0f94a84cd 2675 }
ua1arn 21:85a0f94a84cd 2676
ua1arn 21:85a0f94a84cd 2677 typedef unsigned (* fill_func_t)(uint_fast8_t fill, uint8_t * p, unsigned maxsize, int highspeed);
ua1arn 21:85a0f94a84cd 2678
ua1arn 21:85a0f94a84cd 2679 // Only for high speed capable devices
ua1arn 21:85a0f94a84cd 2680 // Other Speed Configuration descriptor - pass highspeed=1
ua1arn 21:85a0f94a84cd 2681 // For all devices
ua1arn 21:85a0f94a84cd 2682 // Configuration descriptor - pass highspeed=0
ua1arn 21:85a0f94a84cd 2683 static unsigned fill_Configuration_descriptor(
ua1arn 21:85a0f94a84cd 2684 uint8_t * buff, unsigned maxsize, int highspeed,
ua1arn 21:85a0f94a84cd 2685 const uint_fast8_t bConfigurationValue, // = 0x01;
ua1arn 21:85a0f94a84cd 2686 const uint_fast8_t bNumInterfaces, // = INTERFACE_count;
ua1arn 21:85a0f94a84cd 2687 const fill_func_t fill_main_group // fill functional descriptor(s)
ua1arn 21:85a0f94a84cd 2688 )
ua1arn 21:85a0f94a84cd 2689 {
ua1arn 21:85a0f94a84cd 2690 #if WITHUSBHWHIGHSPEED && WITHUSBHWHIGHSPEEDDESC
ua1arn 21:85a0f94a84cd 2691 const int highspeedEPs = 1;
ua1arn 21:85a0f94a84cd 2692 #else /* WITHUSBHWHIGHSPEED && WITHUSBHWHIGHSPEEDDESC */
ua1arn 21:85a0f94a84cd 2693 const int highspeedEPs = 0;
ua1arn 21:85a0f94a84cd 2694 #endif /* WITHUSBHWHIGHSPEED && WITHUSBHWHIGHSPEEDDESC */
ua1arn 21:85a0f94a84cd 2695 unsigned length = 9;
ua1arn 21:85a0f94a84cd 2696 unsigned totalsize = length + fill_main_group(0, buff, maxsize - length, highspeedEPs);
ua1arn 21:85a0f94a84cd 2697 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2698 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2699 return 0;
ua1arn 21:85a0f94a84cd 2700 if (buff != NULL)
ua1arn 21:85a0f94a84cd 2701 {
ua1arn 21:85a0f94a84cd 2702 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2703 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2704 * buff ++ = highspeed ? USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE : USB_CONFIGURATION_DESCRIPTOR_TYPE; /* descriptor type */
ua1arn 21:85a0f94a84cd 2705 * buff ++ = LO_BYTE(totalsize); /* length of packed config descr. (16 bit) */
ua1arn 21:85a0f94a84cd 2706 * buff ++ = HI_BYTE(totalsize); /* length of packed config descr. (16 bit) */
ua1arn 21:85a0f94a84cd 2707 * buff ++ = bNumInterfaces; /* bNumInterfaces */
ua1arn 21:85a0f94a84cd 2708 * buff ++ = bConfigurationValue; /* bConfigurationValue - Value to use as an argument to the SetConfiguration() request to select this configuration */
ua1arn 21:85a0f94a84cd 2709 * buff ++ = STRING_ID_0; /* iConfiguration - Index of string descriptor describing this configuration */
ua1arn 21:85a0f94a84cd 2710 * buff ++ = 0xC0; /* bmAttributes BUS Powred, self powered */
ua1arn 21:85a0f94a84cd 2711 * buff ++ = USB_CONFIG_POWER_MA(250);/* bMaxPower = 250 mA. Сделано как попытка улучшить работу через активные USB изоляторы для обеспечения их питания. */
ua1arn 21:85a0f94a84cd 2712
ua1arn 21:85a0f94a84cd 2713 fill_main_group(1, buff, maxsize - length, highspeedEPs);
ua1arn 21:85a0f94a84cd 2714 }
ua1arn 21:85a0f94a84cd 2715 return totalsize;
ua1arn 21:85a0f94a84cd 2716 }
ua1arn 21:85a0f94a84cd 2717
ua1arn 21:85a0f94a84cd 2718 // Device Descriptor
ua1arn 21:85a0f94a84cd 2719 static unsigned fill_Device_descriptor(uint8_t * buff, unsigned maxsize, uint_fast8_t bNumConfigurations)
ua1arn 21:85a0f94a84cd 2720 {
ua1arn 21:85a0f94a84cd 2721 const unsigned length = 18;
ua1arn 21:85a0f94a84cd 2722 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2723 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2724 return 0;
ua1arn 21:85a0f94a84cd 2725 if (buff != NULL)
ua1arn 21:85a0f94a84cd 2726 {
ua1arn 21:85a0f94a84cd 2727 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2728 * buff ++ = length; /* 0:bLength */
ua1arn 21:85a0f94a84cd 2729 * buff ++ = USB_DEVICE_DESCRIPTOR_TYPE; /* 1:bDescriptorType */
ua1arn 21:85a0f94a84cd 2730 * buff ++ = LO_BYTE(USB_FUNCTION_BCD_USB); /* 2:bcdUSB_FUNCTION_lo */
ua1arn 21:85a0f94a84cd 2731 * buff ++ = HI_BYTE(USB_FUNCTION_BCD_USB); /* 3:bcdUSB_FUNCTION_hi */
ua1arn 21:85a0f94a84cd 2732 * buff ++ = USB_DEVICE_CLASS_MISCELLANEOUS; /* 4:bDeviceClass */
ua1arn 21:85a0f94a84cd 2733 * buff ++ = 2; /* 5:bDeviceSubClass - Common Class Sub Class */
ua1arn 21:85a0f94a84cd 2734 * buff ++ = 1; /* 6:bDeviceProtocol - Interface Association Descriptor protocol */
ua1arn 21:85a0f94a84cd 2735 * buff ++ = USB_OTG_MAX_EP0_SIZE; /* 7:bMaxPacketSize0 (for DCP) */
ua1arn 21:85a0f94a84cd 2736 * buff ++ = LO_BYTE(USB_FUNCTION_VENDOR_ID); /* 8:idVendor_lo */
ua1arn 21:85a0f94a84cd 2737 * buff ++ = HI_BYTE(USB_FUNCTION_VENDOR_ID); /* 9:idVendor_hi */
ua1arn 21:85a0f94a84cd 2738 * buff ++ = LO_BYTE(USB_FUNCTION_PRODUCT_ID); /* 10:idProduct_lo */
ua1arn 21:85a0f94a84cd 2739 * buff ++ = HI_BYTE(USB_FUNCTION_PRODUCT_ID); /* 11:idProduct_hi */
ua1arn 21:85a0f94a84cd 2740 * buff ++ = LO_BYTE(USB_FUNCTION_RELEASE_NO); /* 12:bcdDevice_lo */
ua1arn 21:85a0f94a84cd 2741 * buff ++ = HI_BYTE(USB_FUNCTION_RELEASE_NO); /* 13:bcdDevice_hi */
ua1arn 21:85a0f94a84cd 2742 * buff ++ = STRING_ID_1; /* 14:iManufacturer */
ua1arn 21:85a0f94a84cd 2743 * buff ++ = STRING_ID_2; /* 15:iProduct */
ua1arn 21:85a0f94a84cd 2744 * buff ++ = STRING_ID_3; /* 16:iSerialNumber */
ua1arn 21:85a0f94a84cd 2745 * buff ++ = bNumConfigurations; /* 17:bNumConfigurations */
ua1arn 21:85a0f94a84cd 2746 }
ua1arn 21:85a0f94a84cd 2747 return length;
ua1arn 21:85a0f94a84cd 2748 }
ua1arn 21:85a0f94a84cd 2749
ua1arn 21:85a0f94a84cd 2750 // Only for high speed capable devices
ua1arn 21:85a0f94a84cd 2751 // Device Qualifier Descriptor
ua1arn 21:85a0f94a84cd 2752 static unsigned fill_DeviceQualifier_descriptor(uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2753 {
ua1arn 21:85a0f94a84cd 2754 const unsigned length = 10;
ua1arn 21:85a0f94a84cd 2755 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2756 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2757 return 0;
ua1arn 21:85a0f94a84cd 2758 if (buff != NULL)
ua1arn 21:85a0f94a84cd 2759 {
ua1arn 21:85a0f94a84cd 2760 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2761 * buff ++ = length; /* 0:bLength */
ua1arn 21:85a0f94a84cd 2762 * buff ++ = USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE; /* 1:bDescriptorType */
ua1arn 21:85a0f94a84cd 2763 * buff ++ = LO_BYTE(USB_FUNCTION_BCD_USB); /* 2:bcdUSB_FUNCTION_lo */
ua1arn 21:85a0f94a84cd 2764 * buff ++ = HI_BYTE(USB_FUNCTION_BCD_USB); /* 3:bcdUSB_FUNCTION_hi */
ua1arn 21:85a0f94a84cd 2765 * buff ++ = USB_DEVICE_CLASS_MISCELLANEOUS; /* 4:bDeviceClass - Miscellaneous */
ua1arn 21:85a0f94a84cd 2766 * buff ++ = 2; /* 5:bDeviceSubClass - Common Class Sub Class */
ua1arn 21:85a0f94a84cd 2767 * buff ++ = 1; /* 6:bDeviceProtocol - Interface Association Descriptor protocol */
ua1arn 21:85a0f94a84cd 2768 * buff ++ = USB_OTG_MAX_EP0_SIZE; /* 7:bMaxPacketSize0 (for DCP) */
ua1arn 21:85a0f94a84cd 2769 * buff ++ = 1; /* 8:bNumConfigurations */
ua1arn 21:85a0f94a84cd 2770 * buff ++ = 0; /* 9:bReserved */
ua1arn 21:85a0f94a84cd 2771 }
ua1arn 21:85a0f94a84cd 2772 return length;
ua1arn 21:85a0f94a84cd 2773 }
ua1arn 21:85a0f94a84cd 2774
ua1arn 21:85a0f94a84cd 2775 // Device Capability Descriptor - USB 2.0 Extension
ua1arn 21:85a0f94a84cd 2776 static unsigned fill_devcaps_usb20ext(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2777 {
ua1arn 21:85a0f94a84cd 2778 const uint_fast8_t length = 7;
ua1arn 21:85a0f94a84cd 2779 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2780 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2781 return 0;
ua1arn 21:85a0f94a84cd 2782 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2783 {
ua1arn 21:85a0f94a84cd 2784 const uint_fast32_t bmAttributes =
ua1arn 21:85a0f94a84cd 2785 (1uL << 1) | /* Link Power Management capability bit set */
ua1arn 21:85a0f94a84cd 2786 0;
ua1arn 21:85a0f94a84cd 2787 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2788 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2789 * buff ++ = USB_DEVICE_CAPABITY_DESCRIPTOR_TYPE; /* bDescriptorType: Device Capability */
ua1arn 21:85a0f94a84cd 2790 * buff ++ = 0x02; /* bDevCapabilityType: 0x02: USB 2.0 Extension */
ua1arn 21:85a0f94a84cd 2791 * buff ++ = LO_BYTE(bmAttributes);
ua1arn 21:85a0f94a84cd 2792 * buff ++ = HI_BYTE(bmAttributes);
ua1arn 21:85a0f94a84cd 2793 * buff ++ = HI_24BY(bmAttributes);
ua1arn 21:85a0f94a84cd 2794 * buff ++ = HI_32BY(bmAttributes);
ua1arn 21:85a0f94a84cd 2795 }
ua1arn 21:85a0f94a84cd 2796 return length;
ua1arn 21:85a0f94a84cd 2797 }
ua1arn 21:85a0f94a84cd 2798
ua1arn 21:85a0f94a84cd 2799 // Device Capability Descriptor - Container ID
ua1arn 21:85a0f94a84cd 2800 static unsigned fill_devcaps_ContainerID(uint_fast8_t fill, uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2801 {
ua1arn 21:85a0f94a84cd 2802 typedef struct _GUID {
ua1arn 21:85a0f94a84cd 2803 uint32_t Data1;
ua1arn 21:85a0f94a84cd 2804 uint16_t Data2;
ua1arn 21:85a0f94a84cd 2805 uint16_t Data3;
ua1arn 21:85a0f94a84cd 2806 uint8_t Data4 [8];
ua1arn 21:85a0f94a84cd 2807 } GUID;
ua1arn 21:85a0f94a84cd 2808
ua1arn 21:85a0f94a84cd 2809 const uint_fast8_t length = 20;
ua1arn 21:85a0f94a84cd 2810 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2811 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2812 return 0;
ua1arn 21:85a0f94a84cd 2813 if (fill != 0 && buff != NULL)
ua1arn 21:85a0f94a84cd 2814 {
ua1arn 21:85a0f94a84cd 2815 // {1D614FE7-58C2-42d8-942E-CC2A696218DB}
ua1arn 21:85a0f94a84cd 2816 static const GUID ContainerID =
ua1arn 21:85a0f94a84cd 2817 { 0x1d614fe7, 0x58c2, 0x42d8, { 0x94, 0x2e, 0xcc, 0x2a, 0x69, 0x62, 0x18, 0xdb } };
ua1arn 21:85a0f94a84cd 2818
ua1arn 21:85a0f94a84cd 2819 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2820 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2821 * buff ++ = USB_DEVICE_CAPABITY_DESCRIPTOR_TYPE; /* bDescriptorType: Device Capability */
ua1arn 21:85a0f94a84cd 2822 * buff ++ = 0x04; /* bDevCapabilityType: 0x04: Container ID */
ua1arn 21:85a0f94a84cd 2823 * buff ++ = 0x00; /* bReserved */
ua1arn 21:85a0f94a84cd 2824 memcpy(buff, & ContainerID, 16); /* ContainerID */
ua1arn 21:85a0f94a84cd 2825 }
ua1arn 21:85a0f94a84cd 2826 return length;
ua1arn 21:85a0f94a84cd 2827 }
ua1arn 21:85a0f94a84cd 2828
ua1arn 21:85a0f94a84cd 2829 static unsigned fill_DevCaps_group(uint_fast8_t fill, uint8_t * p, unsigned maxsize, uint_fast8_t bNumDeviceCaps)
ua1arn 21:85a0f94a84cd 2830 {
ua1arn 21:85a0f94a84cd 2831 unsigned n = 0;
ua1arn 21:85a0f94a84cd 2832 // Device Capability Descriptor - USB 2.0 Extension
ua1arn 21:85a0f94a84cd 2833 n += fill_devcaps_usb20ext(fill, p + n, maxsize - n);
ua1arn 21:85a0f94a84cd 2834 // Device Capability Descriptor - SuperSpeed USB
ua1arn 21:85a0f94a84cd 2835 //n += fill_devcaps_ContainerID(fill, p + n, maxsize - n);
ua1arn 21:85a0f94a84cd 2836 // Device Capability Descriptor - Container ID
ua1arn 21:85a0f94a84cd 2837 n += fill_devcaps_ContainerID(fill, p + n, maxsize - n);
ua1arn 21:85a0f94a84cd 2838
ua1arn 21:85a0f94a84cd 2839 ASSERT(bNumDeviceCaps == 2);
ua1arn 21:85a0f94a84cd 2840 return n;
ua1arn 21:85a0f94a84cd 2841 }
ua1arn 21:85a0f94a84cd 2842
ua1arn 21:85a0f94a84cd 2843 static unsigned fill_BinaryDeviceObjectStore_descriptor(uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2844 {
ua1arn 21:85a0f94a84cd 2845 const uint_fast8_t bNumDeviceCaps = 2;
ua1arn 21:85a0f94a84cd 2846 unsigned length = 5;
ua1arn 21:85a0f94a84cd 2847 unsigned totalsize = length + fill_DevCaps_group(0, buff, maxsize - length, bNumDeviceCaps);
ua1arn 21:85a0f94a84cd 2848 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2849 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2850 return 0;
ua1arn 21:85a0f94a84cd 2851 if (buff != NULL)
ua1arn 21:85a0f94a84cd 2852 {
ua1arn 21:85a0f94a84cd 2853 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2854 * buff ++ = length; /* 0:bLength */
ua1arn 21:85a0f94a84cd 2855 * buff ++ = USB_BOS_TYPE; /* 1:bDescriptorType */
ua1arn 21:85a0f94a84cd 2856 * buff ++ = LO_BYTE(totalsize); /* wTotalLength length of packed config descr. (16 bit) */
ua1arn 21:85a0f94a84cd 2857 * buff ++ = HI_BYTE(totalsize); /* wTotalLength length of packed config descr. (16 bit) */
ua1arn 21:85a0f94a84cd 2858 * buff ++ = bNumDeviceCaps; /* 4:bNumDeviceCaps */
ua1arn 21:85a0f94a84cd 2859 fill_DevCaps_group(1, buff, maxsize - length, bNumDeviceCaps);
ua1arn 21:85a0f94a84cd 2860 }
ua1arn 21:85a0f94a84cd 2861 return totalsize;
ua1arn 21:85a0f94a84cd 2862 }
ua1arn 21:85a0f94a84cd 2863
ua1arn 21:85a0f94a84cd 2864 static unsigned fill_align4(uint8_t * buff, unsigned maxsize)
ua1arn 21:85a0f94a84cd 2865 {
ua1arn 21:85a0f94a84cd 2866 const uintptr_t granulation = 32;
ua1arn 21:85a0f94a84cd 2867 return (granulation - ((uintptr_t) buff & (granulation - 1))) & (granulation - 1);
ua1arn 21:85a0f94a84cd 2868 }
ua1arn 21:85a0f94a84cd 2869
ua1arn 21:85a0f94a84cd 2870 static unsigned fill_langid_descriptor(uint8_t * buff, unsigned maxsize, uint_fast16_t langid)
ua1arn 21:85a0f94a84cd 2871 {
ua1arn 21:85a0f94a84cd 2872 const unsigned length = 4;
ua1arn 21:85a0f94a84cd 2873 ASSERT(maxsize >= length);
ua1arn 21:85a0f94a84cd 2874 if (maxsize < length)
ua1arn 21:85a0f94a84cd 2875 return 0;
ua1arn 21:85a0f94a84cd 2876 if (buff != NULL)
ua1arn 21:85a0f94a84cd 2877 {
ua1arn 21:85a0f94a84cd 2878 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2879 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2880 * buff ++ = USB_STRING_DESCRIPTOR_TYPE; /* descriptor type */
ua1arn 21:85a0f94a84cd 2881 * buff ++ = LO_BYTE(langid);
ua1arn 21:85a0f94a84cd 2882 * buff ++ = HI_BYTE(langid);
ua1arn 21:85a0f94a84cd 2883 }
ua1arn 21:85a0f94a84cd 2884 return length;
ua1arn 21:85a0f94a84cd 2885 }
ua1arn 21:85a0f94a84cd 2886
ua1arn 21:85a0f94a84cd 2887 // todo: ограничить размер дескриптора значением 254
ua1arn 21:85a0f94a84cd 2888 static unsigned fill_string_descriptor(uint8_t * buff, unsigned maxsize, const char * s)
ua1arn 21:85a0f94a84cd 2889 {
ua1arn 21:85a0f94a84cd 2890 const unsigned length = 2 + 2 * strlen(s);
ua1arn 21:85a0f94a84cd 2891 ASSERT(length < 256 && maxsize >= length);
ua1arn 21:85a0f94a84cd 2892 if (maxsize < length || length >= 256)
ua1arn 21:85a0f94a84cd 2893 return 0;
ua1arn 21:85a0f94a84cd 2894 if (buff != NULL)
ua1arn 21:85a0f94a84cd 2895 {
ua1arn 21:85a0f94a84cd 2896 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2897 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2898 * buff ++ = USB_STRING_DESCRIPTOR_TYPE; /* descriptor type */
ua1arn 21:85a0f94a84cd 2899 for (;;)
ua1arn 21:85a0f94a84cd 2900 {
ua1arn 21:85a0f94a84cd 2901 const int c = (unsigned char) * s ++;
ua1arn 21:85a0f94a84cd 2902 if (c == '\0')
ua1arn 21:85a0f94a84cd 2903 break;
ua1arn 21:85a0f94a84cd 2904 const wchar_t wc = c; // todo: для не-english преобразовывать
ua1arn 21:85a0f94a84cd 2905 * buff ++ = LO_BYTE(wc);
ua1arn 21:85a0f94a84cd 2906 * buff ++ = HI_BYTE(wc);
ua1arn 21:85a0f94a84cd 2907 }
ua1arn 21:85a0f94a84cd 2908 }
ua1arn 21:85a0f94a84cd 2909 return length;
ua1arn 21:85a0f94a84cd 2910 }
ua1arn 21:85a0f94a84cd 2911
ua1arn 21:85a0f94a84cd 2912 // todo: ограничить размер дескриптора значением 254
ua1arn 21:85a0f94a84cd 2913 static unsigned fill_wstring_descriptor(uint8_t * buff, unsigned maxsize, const wchar_t * s)
ua1arn 21:85a0f94a84cd 2914 {
ua1arn 21:85a0f94a84cd 2915 const unsigned length = 2 + 2 * wcslen(s);
ua1arn 21:85a0f94a84cd 2916 ASSERT(length < 256 && maxsize >= length);
ua1arn 21:85a0f94a84cd 2917 if (maxsize < length || length >= 256)
ua1arn 21:85a0f94a84cd 2918 return 0;
ua1arn 21:85a0f94a84cd 2919 if (buff != NULL)
ua1arn 21:85a0f94a84cd 2920 {
ua1arn 21:85a0f94a84cd 2921 // Вызов для заполнения, а не только для проверки занимаемого места в буфере
ua1arn 21:85a0f94a84cd 2922 * buff ++ = length; /* bLength */
ua1arn 21:85a0f94a84cd 2923 * buff ++ = USB_STRING_DESCRIPTOR_TYPE; /* descriptor type */
ua1arn 21:85a0f94a84cd 2924 for (;;)
ua1arn 21:85a0f94a84cd 2925 {
ua1arn 21:85a0f94a84cd 2926 const int c = * s ++;
ua1arn 21:85a0f94a84cd 2927 if (c == L'\0')
ua1arn 21:85a0f94a84cd 2928 break;
ua1arn 21:85a0f94a84cd 2929 const wchar_t wc = c;
ua1arn 21:85a0f94a84cd 2930 * buff ++ = LO_BYTE(wc);
ua1arn 21:85a0f94a84cd 2931 * buff ++ = HI_BYTE(wc);
ua1arn 21:85a0f94a84cd 2932 }
ua1arn 21:85a0f94a84cd 2933 }
ua1arn 21:85a0f94a84cd 2934 return length;
ua1arn 21:85a0f94a84cd 2935 }
ua1arn 21:85a0f94a84cd 2936
ua1arn 21:85a0f94a84cd 2937
ua1arn 21:85a0f94a84cd 2938 static ALIGNX_BEGIN uint8_t alldescbuffer [1440] ALIGNX_END;
ua1arn 21:85a0f94a84cd 2939
ua1arn 21:85a0f94a84cd 2940 struct descholder StringDescrTbl [STRING_ID_count];
ua1arn 21:85a0f94a84cd 2941 struct descholder ConfigDescrTbl [USBD_NCONFIGS];
ua1arn 21:85a0f94a84cd 2942 struct descholder DeviceDescrTbl [USBD_NCONFIGS];
ua1arn 21:85a0f94a84cd 2943
ua1arn 21:85a0f94a84cd 2944 struct descholder OtherSpeedConfigurationTbl [USBD_NCONFIGS];
ua1arn 21:85a0f94a84cd 2945 struct descholder DeviceQualifierTbl [USBD_NCONFIGS];
ua1arn 21:85a0f94a84cd 2946 struct descholder BinaryDeviceObjectStoreTbl [1];
ua1arn 21:85a0f94a84cd 2947 struct descholder HIDReportDescrTbl [1];
ua1arn 21:85a0f94a84cd 2948
ua1arn 21:85a0f94a84cd 2949
ua1arn 21:85a0f94a84cd 2950 uint_fast8_t usbd_get_stringsdesc_count(void)
ua1arn 21:85a0f94a84cd 2951 {
ua1arn 21:85a0f94a84cd 2952 return ARRAY_SIZE(StringDescrTbl);
ua1arn 21:85a0f94a84cd 2953 }
ua1arn 21:85a0f94a84cd 2954
ua1arn 21:85a0f94a84cd 2955
ua1arn 21:85a0f94a84cd 2956 // Динамическое формирование дескрипторов
ua1arn 21:85a0f94a84cd 2957 /* вызывается при запрещённых прерываниях. */
ua1arn 21:85a0f94a84cd 2958 void usbd_descriptors_initialize(uint_fast8_t HSdesc)
ua1arn 21:85a0f94a84cd 2959 {
ua1arn 21:85a0f94a84cd 2960 unsigned score = 0;
ua1arn 21:85a0f94a84cd 2961
ua1arn 21:85a0f94a84cd 2962 static const struct
ua1arn 21:85a0f94a84cd 2963 {
ua1arn 21:85a0f94a84cd 2964 fill_func_t fp;
ua1arn 21:85a0f94a84cd 2965 uint_fast8_t count;
ua1arn 21:85a0f94a84cd 2966 uint_fast8_t confvalue;
ua1arn 21:85a0f94a84cd 2967 } funcs [] =
ua1arn 21:85a0f94a84cd 2968 {
ua1arn 21:85a0f94a84cd 2969 #if WITHPLAINDESCROPTOR
ua1arn 21:85a0f94a84cd 2970 { fill_Configuration_main_group, INTERFACE_COMPOSITE_count, 0x01, },
ua1arn 21:85a0f94a84cd 2971 #else /* WITHPLAINDESCROPTOR */
ua1arn 21:85a0f94a84cd 2972 #if WITHUSBRNDIS
ua1arn 21:85a0f94a84cd 2973 { fill_RNDIS_function, INTERFACE_RNDIS_count, RNDIS_cfgidx, },
ua1arn 21:85a0f94a84cd 2974 #endif /* WITHUSBRNDIS */
ua1arn 21:85a0f94a84cd 2975 #if WITHUSBCDCECM
ua1arn 21:85a0f94a84cd 2976 { fill_CDCECM_function, INTERFACE_CDCECM_count, CDCECM_cfgidx },
ua1arn 21:85a0f94a84cd 2977 #endif /* WITHUSBCDCECM */
ua1arn 21:85a0f94a84cd 2978 #endif /* WITHPLAINDESCROPTOR */
ua1arn 21:85a0f94a84cd 2979 };
ua1arn 21:85a0f94a84cd 2980 const uint_fast8_t bNumConfigurations = ARRAY_SIZE(funcs);
ua1arn 21:85a0f94a84cd 2981
ua1arn 21:85a0f94a84cd 2982 {
ua1arn 21:85a0f94a84cd 2983 // Device Descriptor
ua1arn 21:85a0f94a84cd 2984 unsigned partlen;
ua1arn 21:85a0f94a84cd 2985 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 2986 partlen = fill_Device_descriptor(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score, bNumConfigurations);
ua1arn 21:85a0f94a84cd 2987 //partlen = fill_pattern_descriptor(1, alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score, fullSpdDesc, sizeof fullSpdDesc);
ua1arn 21:85a0f94a84cd 2988 DeviceDescrTbl [0].size = partlen;
ua1arn 21:85a0f94a84cd 2989 DeviceDescrTbl [0].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 2990 score += partlen;
ua1arn 21:85a0f94a84cd 2991 }
ua1arn 21:85a0f94a84cd 2992
ua1arn 21:85a0f94a84cd 2993 {
ua1arn 21:85a0f94a84cd 2994 // Configuration Descriptors list
ua1arn 21:85a0f94a84cd 2995 unsigned partlen;
ua1arn 21:85a0f94a84cd 2996 uint_fast8_t index;
ua1arn 21:85a0f94a84cd 2997 for (index = 0; index < bNumConfigurations && index < ARRAY_SIZE(ConfigDescrTbl); ++ index)
ua1arn 21:85a0f94a84cd 2998 {
ua1arn 21:85a0f94a84cd 2999 // Configuration Descriptor
ua1arn 21:85a0f94a84cd 3000 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3001 partlen = fill_Configuration_descriptor(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score, 0, funcs [index].confvalue, funcs [index].count, funcs [index].fp);
ua1arn 21:85a0f94a84cd 3002 ConfigDescrTbl [index].size = partlen;
ua1arn 21:85a0f94a84cd 3003 ConfigDescrTbl [index].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 3004 score += partlen;
ua1arn 21:85a0f94a84cd 3005 }
ua1arn 21:85a0f94a84cd 3006 }
ua1arn 21:85a0f94a84cd 3007
ua1arn 21:85a0f94a84cd 3008 if (HSdesc != 0)
ua1arn 21:85a0f94a84cd 3009 {
ua1arn 21:85a0f94a84cd 3010 unsigned partlen;
ua1arn 21:85a0f94a84cd 3011 // Device Qualifier
ua1arn 21:85a0f94a84cd 3012 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3013 partlen = fill_DeviceQualifier_descriptor(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3014 DeviceQualifierTbl [0].size = partlen;
ua1arn 21:85a0f94a84cd 3015 DeviceQualifierTbl [0].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 3016 score += partlen;
ua1arn 21:85a0f94a84cd 3017
ua1arn 21:85a0f94a84cd 3018 #if 0
ua1arn 21:85a0f94a84cd 3019 /*
ua1arn 21:85a0f94a84cd 3020 The other_speed_configuration descriptor shown in Table 9-11 describes a
ua1arn 21:85a0f94a84cd 3021 configuration of a highspeed capable device if it were operating at its
ua1arn 21:85a0f94a84cd 3022 other possible speed.
ua1arn 21:85a0f94a84cd 3023 The structure of the other_speed_configuration is identical to a
ua1arn 21:85a0f94a84cd 3024 configuration descriptor.
ua1arn 21:85a0f94a84cd 3025 */
ua1arn 21:85a0f94a84cd 3026 {
ua1arn 21:85a0f94a84cd 3027 // Other Speed Configuration descriptors list
ua1arn 21:85a0f94a84cd 3028 unsigned partlen;
ua1arn 21:85a0f94a84cd 3029 uint_fast8_t index;
ua1arn 21:85a0f94a84cd 3030 for (index = 0; index < bNumConfigurations && index < ARRAY_SIZE(OtherSpeedConfigurationTbl); ++ index)
ua1arn 21:85a0f94a84cd 3031 {
ua1arn 21:85a0f94a84cd 3032 // Configuration Descriptor
ua1arn 21:85a0f94a84cd 3033 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3034 partlen = fill_Configuration_descriptor(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score, ! HSdesc, funcs [index].confvalue, funcs [index].count, funcs [index].fp);
ua1arn 21:85a0f94a84cd 3035 OtherSpeedConfigurationTbl [index].size = partlen;
ua1arn 21:85a0f94a84cd 3036 OtherSpeedConfigurationTbl [index].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 3037 score += partlen;
ua1arn 21:85a0f94a84cd 3038 }
ua1arn 21:85a0f94a84cd 3039 }
ua1arn 21:85a0f94a84cd 3040 #endif
ua1arn 21:85a0f94a84cd 3041 }
ua1arn 21:85a0f94a84cd 3042 else
ua1arn 21:85a0f94a84cd 3043 {
ua1arn 21:85a0f94a84cd 3044 // Device Qualifier
ua1arn 21:85a0f94a84cd 3045 DeviceQualifierTbl [0].size = 0;
ua1arn 21:85a0f94a84cd 3046 DeviceQualifierTbl [0].data = NULL;
ua1arn 21:85a0f94a84cd 3047
ua1arn 21:85a0f94a84cd 3048 // Other Speed Configuration
ua1arn 21:85a0f94a84cd 3049 OtherSpeedConfigurationTbl [0].size = 0;
ua1arn 21:85a0f94a84cd 3050 OtherSpeedConfigurationTbl [0].data = NULL;
ua1arn 21:85a0f94a84cd 3051 }
ua1arn 21:85a0f94a84cd 3052
ua1arn 21:85a0f94a84cd 3053 // Binary Device Object Store (BOS) Descriptor
ua1arn 21:85a0f94a84cd 3054 if (USB_FUNCTION_BCD_USB > 0x0200)
ua1arn 21:85a0f94a84cd 3055 {
ua1arn 21:85a0f94a84cd 3056 unsigned partlen;
ua1arn 21:85a0f94a84cd 3057 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3058 partlen = fill_BinaryDeviceObjectStore_descriptor(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3059 BinaryDeviceObjectStoreTbl [0].size = partlen;
ua1arn 21:85a0f94a84cd 3060 BinaryDeviceObjectStoreTbl [0].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 3061 score += partlen;
ua1arn 21:85a0f94a84cd 3062 }
ua1arn 21:85a0f94a84cd 3063 else
ua1arn 21:85a0f94a84cd 3064 {
ua1arn 21:85a0f94a84cd 3065 BinaryDeviceObjectStoreTbl [0].size = 0;
ua1arn 21:85a0f94a84cd 3066 BinaryDeviceObjectStoreTbl [0].data = NULL;
ua1arn 21:85a0f94a84cd 3067 }
ua1arn 21:85a0f94a84cd 3068
ua1arn 21:85a0f94a84cd 3069 // String descriptors
ua1arn 21:85a0f94a84cd 3070 {
ua1arn 21:85a0f94a84cd 3071 // Language ID (mandatory)
ua1arn 21:85a0f94a84cd 3072 unsigned partlen;
ua1arn 21:85a0f94a84cd 3073 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3074 partlen = fill_langid_descriptor(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score, UNICODE_ENGLISH);
ua1arn 21:85a0f94a84cd 3075 StringDescrTbl [STRING_ID_0].size = partlen;
ua1arn 21:85a0f94a84cd 3076 StringDescrTbl [STRING_ID_0].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 3077 score += partlen;
ua1arn 21:85a0f94a84cd 3078
ua1arn 21:85a0f94a84cd 3079 // All string IDs, except serial number
ua1arn 21:85a0f94a84cd 3080 unsigned i;
ua1arn 21:85a0f94a84cd 3081 for (i = 0; i < ARRAY_SIZE(strtemplates); ++ i)
ua1arn 21:85a0f94a84cd 3082 {
ua1arn 21:85a0f94a84cd 3083 const uint_fast8_t id = strtemplates [i].id;
ua1arn 21:85a0f94a84cd 3084 ASSERT(id < ARRAY_SIZE(StringDescrTbl));
ua1arn 21:85a0f94a84cd 3085
ua1arn 21:85a0f94a84cd 3086 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3087 partlen = fill_string_descriptor(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score, strtemplates [i].str);
ua1arn 21:85a0f94a84cd 3088 StringDescrTbl [id].size = partlen;
ua1arn 21:85a0f94a84cd 3089 StringDescrTbl [id].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 3090 score += partlen;
ua1arn 21:85a0f94a84cd 3091 }
ua1arn 21:85a0f94a84cd 3092 }
ua1arn 21:85a0f94a84cd 3093
ua1arn 21:85a0f94a84cd 3094 #if WITHUSBHID
ua1arn 21:85a0f94a84cd 3095 {
ua1arn 21:85a0f94a84cd 3096 unsigned partlen;
ua1arn 21:85a0f94a84cd 3097 const uint_fast8_t id = 0;
ua1arn 21:85a0f94a84cd 3098 ASSERT(id < ARRAY_SIZE(HIDReportDescrTbl));
ua1arn 21:85a0f94a84cd 3099
ua1arn 21:85a0f94a84cd 3100 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3101 partlen = fill_pattern_descriptor(1, alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score, HIDREPORTDESC, sizeof HIDREPORTDESC);
ua1arn 21:85a0f94a84cd 3102 HIDReportDescrTbl [id].size = partlen;
ua1arn 21:85a0f94a84cd 3103 HIDReportDescrTbl [id].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 3104 score += partlen;
ua1arn 21:85a0f94a84cd 3105 }
ua1arn 21:85a0f94a84cd 3106 #endif /* WITHUSBHID */
ua1arn 21:85a0f94a84cd 3107
ua1arn 21:85a0f94a84cd 3108 #if WITHUSBCDCECM
ua1arn 21:85a0f94a84cd 3109 {
ua1arn 21:85a0f94a84cd 3110 unsigned partlen;
ua1arn 21:85a0f94a84cd 3111 // Формирование MAC адреса данного устройства
ua1arn 21:85a0f94a84cd 3112 // TODO: При модификации не забыть про достоверность значений
ua1arn 21:85a0f94a84cd 3113 const uint_fast8_t id = STRING_ID_MACADDRESS;
ua1arn 21:85a0f94a84cd 3114 char b [64];
ua1arn 21:85a0f94a84cd 3115 local_snprintf_P(b, ARRAY_SIZE(b), PSTR("3089846A96AB"));
ua1arn 21:85a0f94a84cd 3116 // Unic serial number
ua1arn 21:85a0f94a84cd 3117 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3118 partlen = fill_string_descriptor(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score, b);
ua1arn 21:85a0f94a84cd 3119 StringDescrTbl [id].size = partlen;
ua1arn 21:85a0f94a84cd 3120 StringDescrTbl [id].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 3121 score += partlen;
ua1arn 21:85a0f94a84cd 3122 }
ua1arn 21:85a0f94a84cd 3123 #endif /* WITHUSBCDCECM */
ua1arn 21:85a0f94a84cd 3124
ua1arn 21:85a0f94a84cd 3125 {
ua1arn 21:85a0f94a84cd 3126 unsigned partlen;
ua1arn 21:85a0f94a84cd 3127 const uint_fast8_t id = STRING_ID_3;
ua1arn 21:85a0f94a84cd 3128 char b [64];
ua1arn 21:85a0f94a84cd 3129 local_snprintf_P(b, ARRAY_SIZE(b), PSTR("SN:19640302_%lu"), (unsigned long) BUILD_ID);
ua1arn 21:85a0f94a84cd 3130 // Unic serial number
ua1arn 21:85a0f94a84cd 3131 score += fill_align4(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score);
ua1arn 21:85a0f94a84cd 3132 partlen = fill_string_descriptor(alldescbuffer + score, ARRAY_SIZE(alldescbuffer) - score, b);
ua1arn 21:85a0f94a84cd 3133 StringDescrTbl [id].size = partlen;
ua1arn 21:85a0f94a84cd 3134 StringDescrTbl [id].data = alldescbuffer + score;
ua1arn 21:85a0f94a84cd 3135 score += partlen;
ua1arn 21:85a0f94a84cd 3136 }
ua1arn 21:85a0f94a84cd 3137
ua1arn 21:85a0f94a84cd 3138 arm_hardware_flush_invalidate((uintptr_t) alldescbuffer, score);
ua1arn 21:85a0f94a84cd 3139 PRINTF(PSTR("usbd_descriptors_initialize: total length=%u\r\n"), score);
ua1arn 21:85a0f94a84cd 3140 }
ua1arn 21:85a0f94a84cd 3141
ua1arn 21:85a0f94a84cd 3142
ua1arn 21:85a0f94a84cd 3143 #endif /* WITHUSBHW */
ua1arn 21:85a0f94a84cd 3144
ua1arn 21:85a0f94a84cd 3145 // +++ адаптация
ua1arn 21:85a0f94a84cd 3146 #if CPUSTYLE_ARM_CM7
ua1arn 21:85a0f94a84cd 3147
ua1arn 21:85a0f94a84cd 3148 // Сейчас в эту память будем читать по DMA
ua1arn 21:85a0f94a84cd 3149 // Убрать копию этой области из кэша
ua1arn 21:85a0f94a84cd 3150 // Используется только в startup
ua1arn 21:85a0f94a84cd 3151 void arm_hardware_invalidate(uintptr_t base, size_t size)
ua1arn 21:85a0f94a84cd 3152 {
ua1arn 21:85a0f94a84cd 3153 //ASSERT((base % 32) == 0); // при работе с BACKUP SRAM невыровненно
ua1arn 21:85a0f94a84cd 3154 SCB_InvalidateDCache_by_Addr((void *) base, size); // DCIMVAC register used.
ua1arn 21:85a0f94a84cd 3155 }
ua1arn 21:85a0f94a84cd 3156
ua1arn 21:85a0f94a84cd 3157 // Сейчас эта память будет записываться по DMA куда-то
ua1arn 21:85a0f94a84cd 3158 // Записать содержимое кэша данных в память
ua1arn 21:85a0f94a84cd 3159 void arm_hardware_flush(uintptr_t base, size_t size)
ua1arn 21:85a0f94a84cd 3160 {
ua1arn 21:85a0f94a84cd 3161 //ASSERT((base % 32) == 0); // при работе с BACKUP SRAM невыровненно
ua1arn 21:85a0f94a84cd 3162 SCB_CleanDCache_by_Addr((void *) base, size); // DCCMVAC register used.
ua1arn 21:85a0f94a84cd 3163 }
ua1arn 21:85a0f94a84cd 3164
ua1arn 21:85a0f94a84cd 3165 // Записать содержимое кэша данных в память
ua1arn 21:85a0f94a84cd 3166 // применяетмся после начальной инициализации среды выполнния
ua1arn 21:85a0f94a84cd 3167 void arm_hardware_flush_all(void)
ua1arn 21:85a0f94a84cd 3168 {
ua1arn 21:85a0f94a84cd 3169 SCB_CleanDCache(); // DCCMVAC register used.
ua1arn 21:85a0f94a84cd 3170 }
ua1arn 21:85a0f94a84cd 3171
ua1arn 21:85a0f94a84cd 3172 // Сейчас эта память будет записываться по DMA куда-то. Потом содержимое не требуется
ua1arn 21:85a0f94a84cd 3173 // Записать содержимое кэша данных в память
ua1arn 21:85a0f94a84cd 3174 // Убрать копию этой области из кэша
ua1arn 21:85a0f94a84cd 3175 void arm_hardware_flush_invalidate(uintptr_t base, size_t size)
ua1arn 21:85a0f94a84cd 3176 {
ua1arn 21:85a0f94a84cd 3177 //ASSERT((base % 32) == 0); // при работе с BACKUP SRAM невыровненно
ua1arn 21:85a0f94a84cd 3178 SCB_CleanInvalidateDCache_by_Addr((void *) base, size); // DCCIMVAC register used.
ua1arn 21:85a0f94a84cd 3179 }
ua1arn 21:85a0f94a84cd 3180
ua1arn 21:85a0f94a84cd 3181 #elif CPUSTYLE_ARM_CA9
ua1arn 21:85a0f94a84cd 3182
ua1arn 21:85a0f94a84cd 3183 static unsigned long DCACHEROWSIZE; // 32
ua1arn 21:85a0f94a84cd 3184 static unsigned long ICACHEROWSIZE; // 32
ua1arn 21:85a0f94a84cd 3185
ua1arn 21:85a0f94a84cd 3186 #define MK_MVA(addr) ((uintptr_t) (addr) & ~ (uintptr_t) (DCACHEROWSIZE - 1))
ua1arn 21:85a0f94a84cd 3187
ua1arn 21:85a0f94a84cd 3188 // Сейчас в эту память будем читать по DMA
ua1arn 21:85a0f94a84cd 3189 // Используется только в startup
ua1arn 21:85a0f94a84cd 3190 void arm_hardware_invalidate(uintptr_t base, size_t size)
ua1arn 21:85a0f94a84cd 3191 {
ua1arn 21:85a0f94a84cd 3192 unsigned long len = (size + (DCACHEROWSIZE - 1)) / DCACHEROWSIZE + (((unsigned long) base & (DCACHEROWSIZE - 1)) != 0);
ua1arn 21:85a0f94a84cd 3193 while (len --)
ua1arn 21:85a0f94a84cd 3194 {
ua1arn 21:85a0f94a84cd 3195 uintptr_t mva = MK_MVA(base);
ua1arn 21:85a0f94a84cd 3196 L1C_InvalidateDCacheMVA((void *) mva); // очистить кэш
ua1arn 21:85a0f94a84cd 3197 base += DCACHEROWSIZE;
ua1arn 21:85a0f94a84cd 3198 }
ua1arn 21:85a0f94a84cd 3199 }
ua1arn 21:85a0f94a84cd 3200
ua1arn 21:85a0f94a84cd 3201
ua1arn 21:85a0f94a84cd 3202 /* считать конфигурационные параметры data cache */
ua1arn 21:85a0f94a84cd 3203 static void ca9_cache_setup(void)
ua1arn 21:85a0f94a84cd 3204 {
ua1arn 21:85a0f94a84cd 3205 uint32_t ccsidr0 [8]; // data cache parameters
ua1arn 21:85a0f94a84cd 3206 uint32_t ccsidr1 [8]; // instruction cache parameters
ua1arn 21:85a0f94a84cd 3207
ua1arn 21:85a0f94a84cd 3208 uint_fast32_t leveli;
ua1arn 21:85a0f94a84cd 3209 for (leveli = 0; leveli <= ARM_CA9_CACHELEVELMAX; ++ leveli)
ua1arn 21:85a0f94a84cd 3210 {
ua1arn 21:85a0f94a84cd 3211 __set_CSSELR(leveli * 2 + 0); // data cache select
ua1arn 21:85a0f94a84cd 3212 ccsidr0 [leveli] = __get_CCSIDR();
ua1arn 21:85a0f94a84cd 3213
ua1arn 21:85a0f94a84cd 3214 //const uint32_t assoc0 = (ccsidr0 >> 3) & 0x3FF;
ua1arn 21:85a0f94a84cd 3215 //const int passoc0 = ilog2(assoc0);
ua1arn 21:85a0f94a84cd 3216 //const uint32_t maxsets0 = (ccsidr0 >> 13) & 0x7FFF;
ua1arn 21:85a0f94a84cd 3217
ua1arn 21:85a0f94a84cd 3218 __set_CSSELR(leveli * 2 + 1); // instruction cache select
ua1arn 21:85a0f94a84cd 3219 ccsidr1 [leveli] = __get_CCSIDR();
ua1arn 21:85a0f94a84cd 3220
ua1arn 21:85a0f94a84cd 3221 //const uint32_t assoc1 = (ccsidr1 >> 3) & 0x3FF;
ua1arn 21:85a0f94a84cd 3222 //const int passoc1 = ilog2(assoc1);
ua1arn 21:85a0f94a84cd 3223 //const uint32_t maxsets1 = (ccsidr1 >> 13) & 0x7FFF;
ua1arn 21:85a0f94a84cd 3224 }
ua1arn 21:85a0f94a84cd 3225
ua1arn 21:85a0f94a84cd 3226 // Установка размера строки кэша
ua1arn 21:85a0f94a84cd 3227 DCACHEROWSIZE = 4uL << (((ccsidr0 [0] >> 0) & 0x07) + 2);
ua1arn 21:85a0f94a84cd 3228 ICACHEROWSIZE = 4uL << (((ccsidr1 [0] >> 0) & 0x07) + 2);
ua1arn 21:85a0f94a84cd 3229 }
ua1arn 21:85a0f94a84cd 3230
ua1arn 21:85a0f94a84cd 3231 // используется в startup
ua1arn 21:85a0f94a84cd 3232 static void
ua1arn 21:85a0f94a84cd 3233 arm_hardware_invalidate_all(void)
ua1arn 21:85a0f94a84cd 3234 {
ua1arn 21:85a0f94a84cd 3235 L1C_InvalidateDCacheAll();
ua1arn 21:85a0f94a84cd 3236 L1C_InvalidateICacheAll();
ua1arn 21:85a0f94a84cd 3237 L1C_InvalidateBTAC();
ua1arn 21:85a0f94a84cd 3238 }
ua1arn 21:85a0f94a84cd 3239
ua1arn 21:85a0f94a84cd 3240 // Сейчас эта память будет записываться по DMA куда-то
ua1arn 21:85a0f94a84cd 3241 void arm_hardware_flush(uintptr_t base, size_t size)
ua1arn 21:85a0f94a84cd 3242 {
ua1arn 21:85a0f94a84cd 3243 unsigned long len = (size + (DCACHEROWSIZE - 1)) / DCACHEROWSIZE + (((unsigned long) base & (DCACHEROWSIZE - 1)) != 0);
ua1arn 21:85a0f94a84cd 3244 while (len --)
ua1arn 21:85a0f94a84cd 3245 {
ua1arn 21:85a0f94a84cd 3246 uintptr_t mva = MK_MVA(base);
ua1arn 21:85a0f94a84cd 3247 L1C_CleanDCacheMVA((void *) mva); // записать буфер, кэш продолжает хранить
ua1arn 21:85a0f94a84cd 3248 base += DCACHEROWSIZE;
ua1arn 21:85a0f94a84cd 3249 }
ua1arn 21:85a0f94a84cd 3250 }
ua1arn 21:85a0f94a84cd 3251
ua1arn 21:85a0f94a84cd 3252
ua1arn 21:85a0f94a84cd 3253 // Записать содержимое кэша данных в память
ua1arn 21:85a0f94a84cd 3254 // применяетмся после начальной инициализации среды выполнния
ua1arn 21:85a0f94a84cd 3255 void arm_hardware_flush_all(void)
ua1arn 21:85a0f94a84cd 3256 {
ua1arn 21:85a0f94a84cd 3257 L1C_CleanDCacheAll();
ua1arn 21:85a0f94a84cd 3258 }
ua1arn 21:85a0f94a84cd 3259
ua1arn 21:85a0f94a84cd 3260 // Сейчас эта память будет записываться по DMA куда-то. Потом содержимое не требуется
ua1arn 21:85a0f94a84cd 3261 void arm_hardware_flush_invalidate(uintptr_t base, size_t size)
ua1arn 21:85a0f94a84cd 3262 {
ua1arn 21:85a0f94a84cd 3263 unsigned long len = (size + (DCACHEROWSIZE - 1)) / DCACHEROWSIZE + (((unsigned long) base & (DCACHEROWSIZE - 1)) != 0);
ua1arn 21:85a0f94a84cd 3264 while (len --)
ua1arn 21:85a0f94a84cd 3265 {
ua1arn 21:85a0f94a84cd 3266 uintptr_t mva = MK_MVA(base);
ua1arn 21:85a0f94a84cd 3267 L1C_CleanInvalidateDCacheMVA((void *) mva); // записать буфер, очистить кэш
ua1arn 21:85a0f94a84cd 3268 base += DCACHEROWSIZE;
ua1arn 21:85a0f94a84cd 3269 }
ua1arn 21:85a0f94a84cd 3270 }
ua1arn 21:85a0f94a84cd 3271
ua1arn 21:85a0f94a84cd 3272 #else
ua1arn 21:85a0f94a84cd 3273
ua1arn 21:85a0f94a84cd 3274 // Заглушки
ua1arn 21:85a0f94a84cd 3275 // Сейчас в эту память будем читать по DMA
ua1arn 21:85a0f94a84cd 3276 // Используется только в startup
ua1arn 21:85a0f94a84cd 3277 void arm_hardware_invalidate(uintptr_t base, size_t size)
ua1arn 21:85a0f94a84cd 3278 {
ua1arn 21:85a0f94a84cd 3279 }
ua1arn 21:85a0f94a84cd 3280
ua1arn 21:85a0f94a84cd 3281 // Сейчас эта память будет записываться по DMA куда-то
ua1arn 21:85a0f94a84cd 3282 void arm_hardware_flush(uintptr_t base, size_t size)
ua1arn 21:85a0f94a84cd 3283 {
ua1arn 21:85a0f94a84cd 3284 }
ua1arn 21:85a0f94a84cd 3285
ua1arn 21:85a0f94a84cd 3286 // Записать содержимое кэша данных в память
ua1arn 21:85a0f94a84cd 3287 // применяетмся после начальной инициализации среды выполнния
ua1arn 21:85a0f94a84cd 3288 void arm_hardware_flush_all(void)
ua1arn 21:85a0f94a84cd 3289 {
ua1arn 21:85a0f94a84cd 3290 }
ua1arn 21:85a0f94a84cd 3291
ua1arn 21:85a0f94a84cd 3292 // Сейчас эта память будет записываться по DMA куда-то. Потом содержимое не требуется
ua1arn 21:85a0f94a84cd 3293 void arm_hardware_flush_invalidate(uintptr_t base, size_t size)
ua1arn 21:85a0f94a84cd 3294 {
ua1arn 21:85a0f94a84cd 3295 }
ua1arn 21:85a0f94a84cd 3296
ua1arn 21:85a0f94a84cd 3297 #endif /* CPUSTYLE_ARM_CM7 */
ua1arn 21:85a0f94a84cd 3298
ua1arn 21:85a0f94a84cd 3299 #define FORMATFROMLIBRARY 1
ua1arn 21:85a0f94a84cd 3300 // Для архитектуры ATMega определена только эта функция -
ua1arn 21:85a0f94a84cd 3301 // с расположением форматной строкии в памяти программ.
ua1arn 21:85a0f94a84cd 3302 uint_fast8_t local_snprintf_P( char *buffer, uint_fast8_t count, const FLASHMEM char *format, ... )
ua1arn 21:85a0f94a84cd 3303 {
ua1arn 21:85a0f94a84cd 3304 va_list ap;
ua1arn 21:85a0f94a84cd 3305 int n;
ua1arn 21:85a0f94a84cd 3306
ua1arn 21:85a0f94a84cd 3307 #if FORMATFROMLIBRARY
ua1arn 21:85a0f94a84cd 3308 va_start(ap, format);
ua1arn 21:85a0f94a84cd 3309 n = vsnprintf(buffer, count, format, ap);
ua1arn 21:85a0f94a84cd 3310 va_end(ap);
ua1arn 21:85a0f94a84cd 3311 #else /* FORMATFROMLIBRARY */
ua1arn 21:85a0f94a84cd 3312
ua1arn 21:85a0f94a84cd 3313 struct fmt_param pr;
ua1arn 21:85a0f94a84cd 3314
ua1arn 21:85a0f94a84cd 3315 pr.buffer = buffer;
ua1arn 21:85a0f94a84cd 3316 pr.pos = 0;
ua1arn 21:85a0f94a84cd 3317 pr.count = count;
ua1arn 21:85a0f94a84cd 3318
ua1arn 21:85a0f94a84cd 3319 va_start(ap, format);
ua1arn 21:85a0f94a84cd 3320 // использование самописной функции
ua1arn 21:85a0f94a84cd 3321 n = local_format(& pr, vsputchar, format, ap); // никогда не возвращается ошибка
ua1arn 21:85a0f94a84cd 3322 va_end(ap);
ua1arn 21:85a0f94a84cd 3323 vsputchar(& pr, '\0');
ua1arn 21:85a0f94a84cd 3324 #endif /* FORMATFROMLIBRARY */
ua1arn 21:85a0f94a84cd 3325 return n == -1 ? count - 1 : n; // изменено от стандартного поведения = всегда длинну возвращаем.
ua1arn 21:85a0f94a84cd 3326 }
ua1arn 21:85a0f94a84cd 3327
ua1arn 21:85a0f94a84cd 3328 // --- адаптация