@@ -92,213 +92,22 @@ uint8_t const desc_hid_report[] =
92
92
93
93
};
94
94
95
- uint16_t Serial_u16[33 ];
96
-
97
- static inline bool isInvalidUtf8Octet (uint8_t t) {
98
- // see bullets in https://tools.ietf.org/html/rfc3629#section-1
99
- return (t == 0xc0 ) || (t == 0xC1 ) || ((t >= 0xF5 ) && (t <= 0xFF ));
100
- }
101
-
102
- // up to 32 unicode characters (header make it 33)
103
- static uint16_t _desc_str[33 ];
104
-
105
- //
106
- // This function has an UNWRITTEN CONTRACT that the buffer is either:
107
- // 1. Pre-validated as legal UTF-8, -OR-
108
- // 2. has a trailing zero-value octet/byte/uint8_t (aka null-terminated string)
109
- //
110
- // If the above are not true, this decoder may read past the end of the allocated
111
- // buffer, by up to three bytes.
112
- //
113
- // U+1F47F == 👿 ("IMP")
114
- // == 0001_1111_0100_0111_1111 ==> requires four-byte encoding in UTF-8
115
- // AABB BBBB CCCC CCDD DDDD ==> 0xF0 0x9F 0x91 0xBF
116
- //
117
- // Example sandwich and safety variables are there to cover the
118
- // two most-common stack layouts for declared variables, in unoptimized
119
- // code, so that the bytes surrounding those allocated for 'evilUTF8'
120
- // are guaranteed to be non-zero and valid UTF8 continuation octets.
121
- // uint8_t safety1 = 0;
122
- // uint8_t sandwich1[4] = { 0x81, 0x82, 0x83, 0x84 };
123
- // uint8_t evilUTF8[5] = { 0xF0, 0x9F, 0x91, 0xBF, 0xF9 };
124
- // uint8_t sandwich2[4] = { 0x85, 0x86, 0x87, 0x88 };
125
- // uint8_t safety2 = 0;
126
- //
127
- // NOTE: evilUTF8 could just contain a single byte 0xF9 ....
128
- //
129
- // Attempting to decode evilUTF8 will progress to whatever is next to it on the stack.
130
- // The above should work when optimizations are turned
131
- //
132
- static int8_t utf8Codepoint (const uint8_t *utf8, uint32_t *codepointp)
133
- {
134
- const uint32_t CODEPOINT_LOWEST_SURROGATE_HALF = 0xD800 ;
135
- const uint32_t CODEPOINT_HIGHEST_SURROGATE_HALF = 0xDFFF ;
136
-
137
- *codepointp = 0xFFFD ; // always initialize output to known value ... 0xFFFD (REPLACEMENT CHARACTER) seems the natural choice
138
- int codepoint;
139
- int len;
140
-
141
- // The upper bits define both the length of additional bytes for the multi-byte encoding,
142
- // as well as defining how many bits of the first byte are included in the codepoint.
143
- // Each additional byte starts with 0b10xxxxxx, encoding six additional bits for the codepoint.
144
- //
145
- // For key summary points, see:
146
- // * https://tools.ietf.org/html/rfc3629#section-3
147
- //
148
- if (isInvalidUtf8Octet (utf8[0 ])) { // do not allow illegal octet sequences (e.g., 0xC0 0x80 should NOT decode to NULL)
149
- return -1 ;
150
- }
151
-
152
- if (utf8[0 ] < 0x80 ) { // characters 0000 0000..0000 007F (up to 7 significant bits)
153
- len = 1 ;
154
- codepoint = utf8[0 ];
155
- } else if ((utf8[0 ] & 0xe0 ) == 0xc0 ) { // characters 0000 0080..0000 07FF (up to 11 significant bits, so first byte encodes five bits)
156
- len = 2 ;
157
- codepoint = utf8[0 ] & 0x1f ;
158
- } else if ((utf8[0 ] & 0xf0 ) == 0xe0 ) { // characters 0000 8000..0000 FFFF (up to 16 significant bits, so first byte encodes four bits)
159
- len = 3 ;
160
- codepoint = utf8[0 ] & 0x0f ;
161
- } else if ((utf8[0 ] & 0xf8 ) == 0xf0 ) { // characters 0001 0000..0010 FFFF (up to 21 significant bits, so first byte encodes three bits)
162
- len = 4 ;
163
- codepoint = utf8[0 ] & 0x07 ;
164
- } else { // UTF-8 is defined to only map to Unicode -- 0x00000000..0x0010FFFF
165
- // 5-byte and 6-byte sequences are not legal per RFC3629
166
- return -1 ;
167
- }
168
-
169
- for (int i = 1 ; i < len; i++) {
170
- if ((utf8[i] & 0xc0 ) != 0x80 ) {
171
- // the additional bytes in a valid UTF-8 multi-byte encoding cannot have either of the top two bits set
172
- // This is more restrictive than isInvalidUtf8Octet()
173
- return -1 ;
174
- }
175
- codepoint <<= 6 ; // each continuation byte adds six bits to the codepoint
176
- codepoint |= utf8[i] & 0x3f ; // mask off the top two continuation bits, and add the six relevant bits
177
- }
178
-
179
- // explicit validation to prevent overlong encodings
180
- if ( (len == 1 ) && ((codepoint < 0x000000 ) || (codepoint > 0x00007F ))) {
181
- return -1 ;
182
- } else if ((len == 2 ) && ((codepoint < 0x000080 ) || (codepoint > 0x0007FF ))) {
183
- return -1 ;
184
- } else if ((len == 3 ) && ((codepoint < 0x000800 ) || (codepoint > 0x00FFFF ))) {
185
- return -1 ;
186
- } else if ((len == 4 ) && ((codepoint < 0x010000 ) || (codepoint > 0x10FFFF ))) {
187
- // "You might expect larger code points than U+10FFFF
188
- // to be expressible, but Unicode is limited in Sections 12
189
- // of RFC3629 to match the limits of UTF-16." -- Wikipedia UTF-8 note
190
- // See https://tools.ietf.org/html/rfc3629#section-12
191
- return -1 ;
192
- }
193
-
194
- // high and low surrogate halves (U+D800 through U+DFFF) used by UTF-16 are
195
- // not legal Unicode values ... see RFC 3629.
196
- if ((codepoint >= CODEPOINT_LOWEST_SURROGATE_HALF) && (codepoint <= CODEPOINT_HIGHEST_SURROGATE_HALF)) {
197
- return -1 ;
198
- }
199
-
200
- *codepointp = codepoint;
201
- return len;
202
- }
203
-
204
-
205
- static int strcpy_utf16 (const char *s, uint16_t *buf, int bufsize)
206
- {
207
- int i = 0 ;
208
- int buflen = 0 ;
209
-
210
- while (s[i] != 0 ) {
211
- uint32_t codepoint;
212
- int8_t utf8len = utf8Codepoint ((const uint8_t *)s + i, &codepoint);
213
-
214
- if (utf8len < 0 ) {
215
- // Invalid utf8 sequence, skip it
216
- i++;
217
- continue ;
218
- }
219
-
220
- i += utf8len;
221
-
222
- if (codepoint <= 0xffff ) {
223
- if (buflen == bufsize)
224
- break ;
225
-
226
- buf[buflen++] = codepoint;
227
-
228
- } else {
229
- if (buflen + 1 >= bufsize)
230
- break ;
231
-
232
- // Surrogate pair
233
- codepoint -= 0x10000 ;
234
- buf[buflen++] = (codepoint >> 10 ) + 0xd800 ;
235
- buf[buflen++] = (codepoint & 0x3ff ) + 0xdc00 ;
236
- }
237
- }
238
-
239
- return buflen;
240
- }
241
-
242
-
243
- // Invoked when received GET STRING DESCRIPTOR request
244
- // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
245
- // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
246
- // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
247
- const uint16_t * tud_descriptor_string_cb (uint8_t index, uint16_t langid)
248
- {
249
- (void ) langid;
250
-
251
- uint8_t chr_count;
252
-
253
- switch (index )
254
- {
255
- case 0 :
256
- _desc_str[1 ] = USBDevice.getLanguageDescriptor ();
257
- chr_count = 1 ;
258
- break ;
259
- case 1 :
260
- chr_count = strcpy_utf16 (USBDevice.getManufacturerDescriptor (), _desc_str + 1 , 32 );
261
- break ;
262
-
263
- case 2 :
264
- chr_count = strcpy_utf16 (USBDevice.getProductDescriptor (), _desc_str + 1 , 32 );
265
- break ;
266
-
267
- case 3 :
268
- // serial Number
269
- chr_count = USBDevice.getSerialDescriptor (_desc_str+1 );
270
- break ;
271
- case 4 :
272
- // interface name
273
- chr_count = strcpy_utf16 (" CMSIS-DAP" , _desc_str + 1 , 32 );
274
- break ;
275
- default : return NULL ;
276
- }
277
-
278
- // first byte is length (including header), second byte is string type
279
- _desc_str[0 ] = (TUSB_DESC_STRING << 8 ) | (2 *chr_count + 2 );
280
-
281
- return _desc_str;
282
- }
283
-
284
-
285
-
286
-
287
95
void setup () {
96
+ USBDevice.setProductDescriptor (" CMSIS-DAP" );
97
+
288
98
usb_hid.enableOutEndpoint (true );
289
99
usb_hid.setPollInterval (2 );
290
100
usb_hid.setBootProtocol (0 );
291
- USBDevice. setProductDescriptor (" CMSIS-DAP" );
101
+ usb_hid. setStringDescriptor (" CMSIS-DAP" );
292
102
usb_hid.setReportDescriptor (desc_hid_report, sizeof (desc_hid_report));
293
103
usb_hid.setReportCallback (get_report_callback, set_report_callback);
294
104
295
105
usb_hid.begin ();
296
106
297
107
pinMode (LED_BUILTIN, OUTPUT);
298
108
299
- Serial.begin (115200 );
300
- baud = Serial.getBaud ();
301
- old_baud = baud;
109
+ baud = old_baud = 115200 ;
110
+ Serial.begin (baud);
302
111
SerialTTL.begin (baud);
303
112
304
113
// wait until device mounted
@@ -311,15 +120,12 @@ void setup() {
311
120
USB_ResponseIdle = 1 ;
312
121
free_count = FREE_COUNT_INIT;
313
122
send_count = SEND_COUNT_INIT;
314
-
315
- USBDevice.getSerialDescriptor (Serial_u16);
316
-
317
123
}
318
124
319
125
320
126
void loop () {
321
127
// put your main code here, to run repeatedly:
322
- baud = Serial.getBaud ();
128
+ baud = Serial.baud ();
323
129
if (baud != old_baud) {
324
130
SerialTTL.begin (baud);
325
131
while (!SerialTTL);
@@ -337,6 +143,7 @@ void loop() {
337
143
Serial.write (c);
338
144
}
339
145
}
146
+
340
147
void hid_send_packet ()
341
148
{
342
149
if (send_count) {
0 commit comments