/ usb_disk / usb_api.cpp
usb_api.cpp
  1  /* USB API for Teensy USB Development Board
  2   * http://www.pjrc.com/teensy/teensyduino.html
  3   * Copyright (c) 2008 PJRC.COM, LLC
  4   * 
  5   * Permission is hereby granted, free of charge, to any person obtaining a copy
  6   * of this software and associated documentation files (the "Software"), to deal
  7   * in the Software without restriction, including without limitation the rights
  8   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9   * copies of the Software, and to permit persons to whom the Software is
 10   * furnished to do so, subject to the following conditions:
 11   * 
 12   * The above copyright notice and this permission notice shall be included in
 13   * all copies or substantial portions of the Software.
 14   * 
 15   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 20   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 21   * THE SOFTWARE.
 22   */
 23  
 24  #include <avr/io.h>
 25  #include <avr/pgmspace.h>
 26  #include <stdint.h>
 27  #include "usb_common.h"
 28  #include "usb_private.h"
 29  #include "usb_api.h"
 30  #include "keylayouts.h"
 31  #include "wiring.h"
 32  
 33  
 34  
 35  
 36  // Step #1, decode UTF8 to Unicode code points
 37  //
 38  #if ARDUINO >= 100
 39  size_t usb_keyboard_class::write(uint8_t c)
 40  #else
 41  void usb_keyboard_class::write(uint8_t c)
 42  #endif
 43  {
 44  	if (c < 0x80) {
 45  		// single byte encoded, 0x00 to 0x7F
 46  		utf8_state = 0;
 47  		write_unicode(c);
 48  	} else if (c < 0xC0) {
 49  		// 2nd, 3rd or 4th byte, 0x80 to 0xBF
 50  		c &= 0x3F;
 51  		if (utf8_state == 1) {
 52  			utf8_state = 0;
 53  			write_unicode(unicode_wchar | c);
 54  		} else if (utf8_state == 2) {
 55  			unicode_wchar |= ((uint16_t)c << 6);
 56  			utf8_state = 1;
 57  		}
 58  	} else if (c < 0xE0) {
 59  		// begin 2 byte sequence, 0xC2 to 0xDF
 60  		// or illegal 2 byte sequence, 0xC0 to 0xC1
 61  		unicode_wchar = (uint16_t)(c & 0x1F) << 6;
 62  		utf8_state = 1;
 63  	} else if (c < 0xF0) {
 64  		// begin 3 byte sequence, 0xE0 to 0xEF
 65  		unicode_wchar = (uint16_t)(c & 0x0F) << 12;
 66  		utf8_state = 2;
 67  	} else {
 68  		// begin 4 byte sequence (not supported), 0xF0 to 0xF4
 69  		// or illegal, 0xF5 to 0xFF
 70  		utf8_state = 255;
 71  	}
 72  #if ARDUINO >= 100
 73  	return 1;
 74  #endif
 75  }
 76  
 77  
 78  // Step #2: translate Unicode code point to keystroke sequence
 79  //
 80  KEYCODE_TYPE usb_keyboard_class::unicode_to_keycode(uint16_t cpoint)
 81  {
 82  	// Unicode code points beyond U+FFFF are not supported
 83  	// technically this input should probably be called UCS-2
 84  	if (cpoint < 32) {
 85  		if (cpoint == 10) return KEY_ENTER & 0x3FFF;
 86  		return 0;
 87  	}
 88  	if (cpoint < 128) {
 89  		if (sizeof(KEYCODE_TYPE) == 1) {
 90  			return pgm_read_byte(keycodes_ascii + (cpoint - 0x20));
 91  		} else if (sizeof(KEYCODE_TYPE) == 2) {
 92  			return pgm_read_word(keycodes_ascii + (cpoint - 0x20));
 93  		}
 94  		return 0;
 95  	}
 96  	#ifdef ISO_8859_1_A0
 97  	if (cpoint <= 0xA0) return 0;
 98  	if (cpoint < 0x100) {
 99  		if (sizeof(KEYCODE_TYPE) == 1) {
100  			return pgm_read_byte(keycodes_iso_8859_1 + (cpoint - 0xA0));
101  		} else if (sizeof(KEYCODE_TYPE) == 2) {
102  			return pgm_read_word(keycodes_iso_8859_1 + (cpoint - 0xA0));
103  		}
104  		return 0;
105  	}
106  	#endif
107  	//#ifdef UNICODE_20AC
108  	//if (cpoint == 0x20AC) return UNICODE_20AC & 0x3FFF;
109  	//#endif
110  	#ifdef KEYCODE_EXTRA00
111  	if (cpoint == UNICODE_EXTRA00) return KEYCODE_EXTRA00 & 0x3FFF;
112  	#endif
113  	#ifdef KEYCODE_EXTRA01
114  	if (cpoint == UNICODE_EXTRA01) return KEYCODE_EXTRA01 & 0x3FFF;
115  	#endif
116  	#ifdef KEYCODE_EXTRA02
117  	if (cpoint == UNICODE_EXTRA02) return KEYCODE_EXTRA02 & 0x3FFF;
118  	#endif
119  	#ifdef KEYCODE_EXTRA03
120  	if (cpoint == UNICODE_EXTRA03) return KEYCODE_EXTRA03 & 0x3FFF;
121  	#endif
122  	#ifdef KEYCODE_EXTRA04
123  	if (cpoint == UNICODE_EXTRA04) return KEYCODE_EXTRA04 & 0x3FFF;
124  	#endif
125  	#ifdef KEYCODE_EXTRA05
126  	if (cpoint == UNICODE_EXTRA05) return KEYCODE_EXTRA05 & 0x3FFF;
127  	#endif
128  	#ifdef KEYCODE_EXTRA06
129  	if (cpoint == UNICODE_EXTRA06) return KEYCODE_EXTRA06 & 0x3FFF;
130  	#endif
131  	#ifdef KEYCODE_EXTRA07
132  	if (cpoint == UNICODE_EXTRA07) return KEYCODE_EXTRA07 & 0x3FFF;
133  	#endif
134  	#ifdef KEYCODE_EXTRA08
135  	if (cpoint == UNICODE_EXTRA08) return KEYCODE_EXTRA08 & 0x3FFF;
136  	#endif
137  	#ifdef KEYCODE_EXTRA09
138  	if (cpoint == UNICODE_EXTRA09) return KEYCODE_EXTRA09 & 0x3FFF;
139  	#endif
140  	return 0;
141  }
142  
143  // Step #3: execute keystroke sequence
144  //
145  void usb_keyboard_class::write_keycode(KEYCODE_TYPE keycode)
146  {
147  	if (!keycode) return;
148  	#ifdef DEADKEYS_MASK
149  	KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode);
150  	if (deadkeycode) write_key(deadkeycode);
151  	#endif
152  	write_key(keycode);
153  }
154  
155  KEYCODE_TYPE usb_keyboard_class::deadkey_to_keycode(KEYCODE_TYPE keycode)
156  {
157  	#ifdef DEADKEYS_MASK
158  	keycode &= DEADKEYS_MASK;
159  	if (keycode == 0) return 0;
160  	#ifdef ACUTE_ACCENT_BITS
161  	if (keycode == ACUTE_ACCENT_BITS) return DEADKEY_ACUTE_ACCENT;
162  	#endif
163  	#ifdef CEDILLA_BITS
164  	if (keycode == CEDILLA_BITS) return DEADKEY_CEDILLA;
165  	#endif
166  	#ifdef CIRCUMFLEX_BITS
167  	if (keycode == CIRCUMFLEX_BITS) return DEADKEY_CIRCUMFLEX;
168  	#endif
169  	#ifdef DIAERESIS_BITS
170  	if (keycode == DIAERESIS_BITS) return DEADKEY_DIAERESIS;
171  	#endif
172  	#ifdef GRAVE_ACCENT_BITS
173  	if (keycode == GRAVE_ACCENT_BITS) return DEADKEY_GRAVE_ACCENT;
174  	#endif
175  	#ifdef TILDE_BITS
176  	if (keycode == TILDE_BITS) return DEADKEY_TILDE;
177  	#endif
178  	#ifdef RING_ABOVE_BITS
179  	if (keycode == RING_ABOVE_BITS) return DEADKEY_RING_ABOVE;
180  	#endif
181  	#endif // DEADKEYS_MASK
182  	return 0;
183  }
184  
185  // Step #4: do each keystroke
186  //
187  void usb_keyboard_class::write_key(KEYCODE_TYPE keycode)
188  {
189  	keyboard_report_data[0] = keycode_to_modifier(keycode);
190  	keyboard_report_data[1] = 0;
191  	keyboard_report_data[2] = keycode_to_key(keycode);
192  	keyboard_report_data[3] = 0;
193  	keyboard_report_data[4] = 0;
194  	keyboard_report_data[5] = 0;
195  	keyboard_report_data[6] = 0;
196  	keyboard_report_data[7] = 0;
197  	send_now();
198  	keyboard_report_data[0] = 0;
199  	keyboard_report_data[2] = 0;
200  	send_now();
201  }
202  
203  uint8_t usb_keyboard_class::keycode_to_modifier(KEYCODE_TYPE keycode)
204  {
205  	uint8_t modifier=0;
206  
207  	#ifdef SHIFT_MASK
208  	if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT;
209  	#endif
210  	#ifdef ALTGR_MASK
211  	if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT;
212  	#endif
213  	#ifdef RCTRL_MASK
214  	if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL;
215  	#endif
216  	return modifier;
217  }
218  
219  uint8_t usb_keyboard_class::keycode_to_key(KEYCODE_TYPE keycode)
220  {
221  	uint8_t key = keycode & 0x3F;
222  	#ifdef KEY_NON_US_100
223  	if (key == KEY_NON_US_100) key = 100;
224  	#endif
225  	return key;
226  }
227  
228  
229  
230  void usb_keyboard_class::set_modifier(uint8_t c)
231  {
232  	keyboard_report_data[0] = c;
233  }
234  void usb_keyboard_class::set_key1(uint8_t c)
235  {
236  	keyboard_report_data[2] = c;
237  }
238  void usb_keyboard_class::set_key2(uint8_t c)
239  {
240  	keyboard_report_data[3] = c;
241  }
242  void usb_keyboard_class::set_key3(uint8_t c)
243  {
244  	keyboard_report_data[4] = c;
245  }
246  void usb_keyboard_class::set_key4(uint8_t c)
247  {
248  	keyboard_report_data[5] = c;
249  }
250  void usb_keyboard_class::set_key5(uint8_t c)
251  {
252  	keyboard_report_data[6] = c;
253  }
254  void usb_keyboard_class::set_key6(uint8_t c)
255  {
256  	keyboard_report_data[7] = c;
257  }
258  void usb_keyboard_class::set_media(uint8_t c)
259  {
260  	keyboard_report_data[1] = c;
261  }
262  
263  
264  void usb_keyboard_class::send_now(void)
265  {
266          uint8_t intr_state, timeout;
267  
268          if (!usb_configuration) return;
269          intr_state = SREG;
270          cli();
271          UENUM = KEYBOARD_ENDPOINT;
272          timeout = UDFNUML + 50;
273          while (1) {
274                  // are we ready to transmit?
275                  if (UEINTX & (1<<RWAL)) break;
276                  SREG = intr_state;
277                  // has the USB gone offline?
278                  if (!usb_configuration) return;
279                  // have we waited too long?
280                  if (UDFNUML == timeout) return;
281                  // get ready to try checking again
282                  intr_state = SREG;
283                  cli();
284                  UENUM = KEYBOARD_ENDPOINT;
285          }
286          UEDATX = keyboard_report_data[0];
287          UEDATX = keyboard_report_data[1];
288          UEDATX = keyboard_report_data[2];
289          UEDATX = keyboard_report_data[3];
290          UEDATX = keyboard_report_data[4];
291          UEDATX = keyboard_report_data[5];
292          UEDATX = keyboard_report_data[6];
293          UEDATX = keyboard_report_data[7];
294          UEINTX = 0x3A;
295          keyboard_idle_count = 0;
296          SREG = intr_state;
297  }
298  
299  
300  void usb_keyboard_class::press(uint16_t n)
301  {
302  	uint8_t key, mod, msb, modrestore=0;
303  
304  	msb = n >> 8;
305  	if (msb >= 0xC2 && msb <= 0xDF) {
306  		n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
307  	} else
308  	if (msb == 0x80) {
309  		presskey(0, n);
310  		return;
311  	} else
312  	if (msb == 0x40) {
313  		presskey(n, 0);
314  		return;
315  	}
316  	KEYCODE_TYPE keycode = unicode_to_keycode(n);
317  	if (!keycode) return;
318  	#ifdef DEADKEYS_MASK
319  	KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode);
320  	if (deadkeycode) {
321  		modrestore = keyboard_report_data[0];
322  		if (modrestore) {
323  			keyboard_report_data[0] = 0;
324  			send_now();
325  		}
326  		// TODO: test if operating systems recognize
327  		// deadkey sequences when other keys are held
328  		mod = keycode_to_modifier(deadkeycode);
329  		key = keycode_to_key(deadkeycode);
330  		presskey(key, mod);
331  		releasekey(key, mod);
332  	}
333  	#endif
334  	mod = keycode_to_modifier(keycode);
335  	key = keycode_to_key(keycode);
336  	presskey(key, mod | modrestore);
337  }
338  
339  void usb_keyboard_class::release(uint16_t n)
340  {
341  	uint8_t key, mod, msb;
342  
343  	msb = n >> 8;
344  	if (msb >= 0xC2 && msb <= 0xDF) {
345  		n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
346  	} else
347  	if (msb == 0x80) {
348  		releasekey(0, n);
349  		return;
350  	} else
351  	if (msb == 0x40) {
352  		releasekey(n, 0);
353  		return;
354  	}
355  	KEYCODE_TYPE keycode = unicode_to_keycode(n);
356  	if (!keycode) return;
357  	mod = keycode_to_modifier(keycode);
358  	key = keycode_to_key(keycode);
359  	releasekey(key, mod);
360  }
361  
362  void usb_keyboard_class::presskey(uint8_t key, uint8_t modifier)
363  {
364  	bool send_required = false;
365  	uint8_t i;
366  
367  	if (modifier) {
368  		if ((keyboard_report_data[0] & modifier) != modifier) {
369  			keyboard_report_data[0] |= modifier;
370  			send_required = true;
371  		}
372  	}
373  	if (key) {
374  		for (i=2; i < 8; i++) {
375  			if (keyboard_report_data[i] == key) goto end;
376  		}
377  		for (i=2; i < 8; i++) {
378  			if (keyboard_report_data[i] == 0) {
379  				keyboard_report_data[i] = key;
380  				send_required = true;
381  				goto end;
382  			}
383  		}
384  	}
385  	end:
386  	if (send_required) send_now();
387  }
388  
389  void usb_keyboard_class::releasekey(uint8_t key, uint8_t modifier)
390  {
391  	bool send_required = false;
392  	uint8_t i;
393  
394  	if (modifier) {
395  		if ((keyboard_report_data[0] & modifier) != 0) {
396  			keyboard_report_data[0] &= ~modifier;
397  			send_required = true;
398  		}
399  	}
400  	if (key) {
401  		for (i=2; i < 8; i++) {
402  			if (keyboard_report_data[i] == key) {
403  				keyboard_report_data[i] = 0;
404  				send_required = true;
405  			}
406  		}
407  	}
408  	if (send_required) send_now();
409  }
410  
411  void usb_keyboard_class::releaseAll(void)
412  {
413  	uint8_t i, anybits;
414  
415  	anybits = keyboard_report_data[0];
416  	for (i=2; i < 8; i++) {
417  		anybits |= keyboard_report_data[i];
418  		keyboard_report_data[i] = 0;
419  	}
420  	if (!anybits) return;
421  	keyboard_report_data[0] = 0;
422  	send_now();
423  }
424  
425  
426  
427  
428  
429  
430  
431  static volatile uint8_t prev_byte=0;
432  
433  void usb_serial_class::begin(long speed)
434  {
435  	// make sure USB is initialized
436  	usb_init();
437  	uint16_t begin_wait = (uint16_t)millis();
438  	while (1) {
439  		// wait for the host to finish enumeration
440  		if (usb_configuration) {
441  			delay(250);  // a little time for host to load a driver
442  			return;
443  		}
444  		// or for suspend mode (powered without USB)
445  		if (usb_suspended) {
446  			uint16_t begin_suspend = (uint16_t)millis();
447  			while (usb_suspended) {
448  				// must remain suspended for a while, because
449  				// normal USB enumeration causes brief suspend
450  				// states, typically under 0.1 second
451  				if ((uint16_t)millis() - begin_suspend > 250) {
452  					return;
453  				}
454  			}
455  		}
456  		// ... or a timout (powered by a USB power adaptor that
457  		// wiggles the data lines to keep a USB device charging)
458  		if ((uint16_t)millis() - begin_wait > 2500) return;
459  	}
460  	prev_byte = 0;
461  }
462  
463  void usb_serial_class::end()
464  {
465  	usb_shutdown();
466  	delay(25);
467  }
468  
469  
470  // number of bytes available in the receive buffer
471  int usb_serial_class::available()
472  {
473  	uint8_t c;
474  
475  	c = prev_byte;	// assume 1 byte static volatile access is atomic
476  	if (c) return 1;
477  	c = readnext();
478  	if (c) {
479  		prev_byte = c;
480  		return 1;
481  	}
482  	return 0;
483  }
484  
485  // get the next character, or -1 if nothing received
486  int usb_serial_class::read()
487  {
488  	uint8_t c;
489  
490  	c = prev_byte;
491  	if (c) {
492  		prev_byte = 0;
493  		return c;
494  	}
495  	c = readnext();
496  	if (c) return c;
497  	return -1;
498  }
499  
500  int usb_serial_class::peek()
501  {
502  	uint8_t c;
503  
504  	c = prev_byte;
505  	if (c) return c;
506  	c = readnext();
507  	if (c) {
508  		prev_byte = c;
509  		return c;
510  	}
511  	return -1;
512  }
513  
514  // get the next character, or 0 if nothing
515  uint8_t usb_serial_class::readnext(void)
516  {
517  	uint8_t c, intr_state;
518  
519  	// interrupts are disabled so these functions can be
520  	// used from the main program or interrupt context,
521  	// even both in the same program!
522  	intr_state = SREG;
523  	cli();
524  	if (!usb_configuration) {
525  		SREG = intr_state;
526  		return 0;
527  	}
528  	UENUM = DEBUG_RX_ENDPOINT;
529  try_again:
530  	if (!(UEINTX & (1<<RWAL))) {
531  		// no packet in buffer
532  		SREG = intr_state;
533  		return 0;
534  	}
535  	// take one byte out of the buffer
536  	c = UEDATX;
537  	if (c == 0) {
538  		// if we see a zero, discard it and
539  		// discard the rest of this packet
540  		UEINTX = 0x6B;
541  		goto try_again;
542  	}
543  	// if this drained the buffer, release it
544  	if (!(UEINTX & (1<<RWAL))) UEINTX = 0x6B;
545  	SREG = intr_state;
546  	return c;
547  }
548  
549  // discard any buffered input
550  void usb_serial_class::flush()
551  {
552  	uint8_t intr_state;
553  
554  	if (usb_configuration) {
555  		intr_state = SREG;
556  		cli();
557  		UENUM = DEBUG_RX_ENDPOINT;
558  		while ((UEINTX & (1<<RWAL))) {
559  			UEINTX = 0x6B;
560  		}
561  		SREG = intr_state;
562  	}
563  	prev_byte = 0;
564  }
565  
566  // transmit a character.
567  #if ARDUINO >= 100
568  size_t usb_serial_class::write(uint8_t c)
569  #else
570  void usb_serial_class::write(uint8_t c)
571  #endif
572  {
573  	//static uint8_t previous_timeout=0;
574  	uint8_t timeout, intr_state;
575  
576  	// if we're not online (enumerated and configured), error
577  	if (!usb_configuration) goto error;
578  	// interrupts are disabled so these functions can be
579  	// used from the main program or interrupt context,
580  	// even both in the same program!
581  	intr_state = SREG;
582  	cli();
583  	UENUM = DEBUG_TX_ENDPOINT;
584  	// if we gave up due to timeout before, don't wait again
585  #if 0
586  	if (previous_timeout) {
587  		if (!(UEINTX & (1<<RWAL))) {
588  			SREG = intr_state;
589  			return;
590  		}
591  		previous_timeout = 0;
592  	}
593  #endif
594  	// wait for the FIFO to be ready to accept data
595  	timeout = UDFNUML + TRANSMIT_TIMEOUT;
596  	while (1) {
597  		// are we ready to transmit?
598  		if (UEINTX & (1<<RWAL)) break;
599  		SREG = intr_state;
600  		// have we waited too long?  This happens if the user
601  		// is not running an application that is listening
602  		if (UDFNUML == timeout) {
603  			//previous_timeout = 1;
604  			goto error;
605  		}
606  		// has the USB gone offline?
607  		if (!usb_configuration) goto error;
608  		// get ready to try checking again
609  		intr_state = SREG;
610  		cli();
611  		UENUM = DEBUG_TX_ENDPOINT;
612  	}
613  	// actually write the byte into the FIFO
614  	UEDATX = c;
615  	// if this completed a packet, transmit it now!
616  	if (!(UEINTX & (1<<RWAL))) {
617  		UEINTX = 0x3A;
618  		debug_flush_timer = 0;
619  	} else {
620  		debug_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
621  	}
622  	SREG = intr_state;
623  #if ARDUINO >= 100
624          return 1;
625  #endif
626  error:
627  #if ARDUINO >= 100
628          setWriteError();
629          return 0;
630  #else
631  	return;
632  #endif
633  }
634  
635  
636  // These are Teensy-specific extensions to the Serial object
637  
638  // immediately transmit any buffered output.
639  // This doesn't actually transmit the data - that is impossible!
640  // USB devices only transmit when the host allows, so the best
641  // we can do is release the FIFO buffer for when the host wants it
642  void usb_serial_class::send_now(void)
643  {
644  	uint8_t intr_state;
645  
646  	intr_state = SREG;
647  	cli();
648  	if (debug_flush_timer) {
649  		UENUM = DEBUG_TX_ENDPOINT;
650  		while ((UEINTX & (1<<RWAL))) {
651  			UEDATX = 0;
652  		}
653  		UEINTX = 0x3A;
654  		debug_flush_timer = 0;
655  	}
656  	SREG = intr_state;
657  }
658  
659  uint32_t usb_serial_class::baud(void)
660  {
661  	return ((uint32_t)DEBUG_TX_SIZE * 10000 / DEBUG_TX_INTERVAL);
662  }
663  
664  uint8_t usb_serial_class::stopbits(void)
665  {
666  	return 1;
667  }
668  
669  uint8_t usb_serial_class::paritytype(void)
670  {
671  	return 0;
672  }
673  
674  uint8_t usb_serial_class::numbits(void)
675  {
676  	return 8;
677  }
678  
679  uint8_t usb_serial_class::dtr(void)
680  {
681  	return 1;
682  }
683  
684  uint8_t usb_serial_class::rts(void)
685  {
686  	return 1;
687  }
688  
689  usb_serial_class::operator bool()
690  {
691  	if (usb_configuration) return true;
692  	return false;
693  }
694  
695  
696  // Preinstantiate Objects //////////////////////////////////////////////////////
697  
698  usb_serial_class	Serial = usb_serial_class();
699  usb_keyboard_class	Keyboard = usb_keyboard_class();
700  usb_disk_class		Disk = usb_disk_class();
701  
702