|
32 | 32 | #ifndef NO_QSTR |
33 | 33 | #include "device/dcd.h" |
34 | 34 | #endif |
| 35 | +#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_HID * TUD_HID_DESC_LEN) |
| 36 | +// Some MCU doesn't have enough 8KB SRAM to store the whole disk |
| 37 | +// We will use Flash as read-only disk with board that has |
| 38 | +// CFG_EXAMPLE_MSC_READONLY defined |
35 | 39 |
|
36 | | -#if !MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE |
| 40 | +// whether host does safe-eject |
| 41 | +static bool ejected = false; |
| 42 | +#define README_CONTENTS \ |
| 43 | +"This is tinyusb's MassStorage Class demo.\r\n\r\n\ |
| 44 | +If you find any bugs or get any questions, feel free to file an\r\n\ |
| 45 | +issue at github.com/hathach/tinyusb" |
| 46 | + |
| 47 | +enum { |
| 48 | + DISK_BLOCK_NUM = 8192,// 8KB is the smallest size that windows allow to mount |
| 49 | + DISK_BLOCK_SIZE = 512 |
| 50 | +}; |
| 51 | + |
| 52 | +#ifdef CFG_EXAMPLE_MSC_READONLY |
| 53 | +const |
| 54 | +#endif |
| 55 | +uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = { |
| 56 | + //------------- Block0: Boot Sector -------------// |
| 57 | + // byte_per_sector = DISK_BLOCK_SIZE; fat12_sector_num_16 = DISK_BLOCK_NUM; |
| 58 | + // sector_per_cluster = 1; reserved_sectors = 1; |
| 59 | + // fat_num = 1; fat12_root_entry_num = 16; |
| 60 | + // sector_per_fat = 1; sector_per_track = 1; head_num = 1; hidden_sectors = 0; |
| 61 | + // drive_number = 0x80; media_type = 0xf8; extended_boot_signature = 0x29; |
| 62 | + // filesystem_type = "FAT12 "; volume_serial_number = 0x1234; volume_label = "TinyUSB MSC"; |
| 63 | + // FAT magic code at offset 510-511 |
| 64 | +{ |
| 65 | + 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00, |
| 66 | + 0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 67 | + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x34, 0x12, 0x00, 0x00, 'T', 'i', 'n', 'y', 'U', |
| 68 | + 'S', 'B', ' ', 'M', 'S', 'C', 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, |
| 69 | + |
| 70 | + // Zero up to 2 last bytes of FAT magic code |
| 71 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 72 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 73 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 74 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 75 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 76 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 77 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 78 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 79 | + |
| 80 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 81 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 82 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 83 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 84 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 85 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 86 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 87 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
37 | 88 |
|
| 89 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 90 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 91 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 92 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 93 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 94 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 95 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 96 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 97 | + |
| 98 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 99 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 100 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 101 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA}, |
| 102 | + |
| 103 | + //------------- Block1: FAT12 Table -------------// |
| 104 | +{ |
| 105 | + 0xF8, 0xFF, 0xFF, 0xFF, 0x0F// // first 2 entries must be F8FF, third entry is cluster end of readme file |
| 106 | + }, |
| 107 | + |
| 108 | + //------------- Block2: Root Directory -------------// |
| 109 | +{ |
| 110 | + // first entry is volume label |
| 111 | + 'T', 'i', 'n', 'y', 'U', 'S', 'B', ' ', 'M', 'S', 'C', 0x08, 0x00, 0x00, 0x00, 0x00, |
| 112 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6D, 0x65, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 113 | + // second entry is readme file |
| 114 | + 'R', 'E', 'A', 'D', 'M', 'E', ' ', ' ', 'T', 'X', 'T', 0x20, 0x00, 0xC6, 0x52, 0x6D, |
| 115 | + 0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00, |
| 116 | + sizeof(README_CONTENTS) - 1, 0x00, 0x00, 0x00// readme's files size (4 Bytes) |
| 117 | + }, |
| 118 | + |
| 119 | + //------------- Block3: Readme Content -------------// |
| 120 | + README_CONTENTS |
| 121 | +}; |
| 122 | +#if !MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE |
38 | 123 | void mp_usbd_task(void) { |
39 | 124 | tud_task_ext(0, false); |
40 | 125 | } |
@@ -71,5 +156,51 @@ void mp_usbd_hex_str(char *out_str, const uint8_t *bytes, size_t bytes_len) { |
71 | 156 | } |
72 | 157 | out_str[hex_len] = 0; |
73 | 158 | } |
| 159 | +const uint8_t hid_report_descriptor[] = { |
| 160 | + TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(HID_ITF_PROTOCOL_KEYBOARD)), |
| 161 | + TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(HID_ITF_PROTOCOL_MOUSE)) |
| 162 | +}; |
| 163 | + |
| 164 | +/** |
| 165 | + * @brief String descriptor |
| 166 | + */ |
| 167 | +const char* hid_string_descriptor[5] = { |
| 168 | + // array of pointer to string descriptors |
| 169 | + (char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) |
| 170 | + "TinyUSB", // 1: Manufacturer |
| 171 | + "TinyUSB Device", // 2: Product |
| 172 | + "123456", // 3: Serials, should use chip ID |
| 173 | + "Example HID interface", // 4: HID |
| 174 | +}; |
| 175 | + |
| 176 | +/********* TinyUSB HID callbacks ***************/ |
| 177 | + |
| 178 | +// Invoked when received GET HID REPORT DESCRIPTOR request |
| 179 | +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete |
| 180 | +uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance) |
| 181 | +{ |
| 182 | + // We use only one interface and one HID report descriptor, so we can ignore parameter 'instance' |
| 183 | + return hid_report_descriptor; |
| 184 | +} |
| 185 | + |
| 186 | +// Invoked when received GET_REPORT control request |
| 187 | +// Application must fill buffer report's content and return its length. |
| 188 | +// Return zero will cause the stack to STALL request |
| 189 | +uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) |
| 190 | +{ |
| 191 | + (void) instance; |
| 192 | + (void) report_id; |
| 193 | + (void) report_type; |
| 194 | + (void) buffer; |
| 195 | + (void) reqlen; |
| 196 | + |
| 197 | + return 0; |
| 198 | +} |
| 199 | + |
| 200 | +// Invoked when received SET_REPORT control request or |
| 201 | +// received data on OUT endpoint ( Report ID = 0, Type = 0 ) |
| 202 | +void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) |
| 203 | +{ |
| 204 | +} |
74 | 205 |
|
75 | 206 | #endif // MICROPY_HW_ENABLE_USBDEV |
0 commit comments