@@ -92,213 +92,22 @@ uint8_t const desc_hid_report[] =
9292
9393};
9494
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-
28795void setup () {
96+ USBDevice.setProductDescriptor (" CMSIS-DAP" );
97+
28898 usb_hid.enableOutEndpoint (true );
28999 usb_hid.setPollInterval (2 );
290100 usb_hid.setBootProtocol (0 );
291- USBDevice. setProductDescriptor (" CMSIS-DAP" );
101+ usb_hid. setStringDescriptor (" CMSIS-DAP" );
292102 usb_hid.setReportDescriptor (desc_hid_report, sizeof (desc_hid_report));
293103 usb_hid.setReportCallback (get_report_callback, set_report_callback);
294104
295105 usb_hid.begin ();
296106
297107 pinMode (LED_BUILTIN, OUTPUT);
298108
299- Serial.begin (115200 );
300- baud = Serial.getBaud ();
301- old_baud = baud;
109+ baud = old_baud = 115200 ;
110+ Serial.begin (baud);
302111 SerialTTL.begin (baud);
303112
304113 // wait until device mounted
@@ -311,15 +120,12 @@ void setup() {
311120 USB_ResponseIdle = 1 ;
312121 free_count = FREE_COUNT_INIT;
313122 send_count = SEND_COUNT_INIT;
314-
315- USBDevice.getSerialDescriptor (Serial_u16);
316-
317123}
318124
319125
320126void loop () {
321127 // put your main code here, to run repeatedly:
322- baud = Serial.getBaud ();
128+ baud = Serial.baud ();
323129 if (baud != old_baud) {
324130 SerialTTL.begin (baud);
325131 while (!SerialTTL);
@@ -337,6 +143,7 @@ void loop() {
337143 Serial.write (c);
338144 }
339145}
146+
340147void hid_send_packet ()
341148{
342149 if (send_count) {
0 commit comments