-
Notifications
You must be signed in to change notification settings - Fork 2
/
usb_msc_driver.c
127 lines (102 loc) · 3.21 KB
/
usb_msc_driver.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
* USB mass storage class driver that mimics littlefs to FAT12 file system.
*
* Copyright 2024, Hiroyuki OYAMA. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <tusb.h>
#include "mimic_fat.h"
extern const struct lfs_config lfs_pico_flash_config;
static bool ejected = false;
static bool is_initialized = false;
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
(void)lun;
const char vid[] = "littlefs";
const char pid[] = "Mass Storage";
const char rev[] = "1.0";
memcpy(vendor_id , vid, strlen(vid));
memcpy(product_id , pid, strlen(pid));
memcpy(product_rev, rev, strlen(rev));
}
bool tud_msc_test_unit_ready_cb(uint8_t lun) {
(void)lun;
return true;
}
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
(void)lun;
*block_count = mimic_fat_total_sector_size();
*block_size = DISK_SECTOR_SIZE;
}
bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) {
(void)lun;
(void)power_condition;
if (load_eject) {
if (start) {
// load disk storage
} else {
// unload disk storage
ejected = true;
}
}
return true;
}
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) {
(void)lun;
(void)offset;
if (!is_initialized) {
mimic_fat_init(&lfs_pico_flash_config);
mimic_fat_update_usb_device_is_enabled(true);
mimic_fat_create_cache();
is_initialized = true;
}
mimic_fat_read(lun, lba, buffer, bufsize);
return (int32_t)bufsize;
}
bool tud_msc_is_writable_cb (uint8_t lun) {
(void) lun;
return true;
}
int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) {
(void)offset;
mimic_fat_write(lun, lba, buffer, bufsize);
return bufsize;
}
int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) {
void const *response = NULL;
int32_t resplen = 0;
// most scsi handled is input
bool in_xfer = true;
switch (scsi_cmd[0]) {
default:
// Set Sense = Invalid Command Operation
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
// negative means error -> tinyusb could stall and/or response with failed status
resplen = -1;
break;
}
// return resplen must not larger than bufsize
if (resplen > bufsize) resplen = bufsize;
if (response && (resplen > 0)) {
if(in_xfer) {
memcpy(buffer, response, (size_t) resplen);
} else {
; // SCSI output
}
}
return (int32_t)resplen;
}
void tud_mount_cb(void) {
printf("\e[45mmount\e[0m\n");
/*
* NOTE:
* This callback must be returned immediately. Time-consuming processing
* here will cause TinyUSB to PANIC `ep 0 in was already available`.
*/
is_initialized = false;
}
void tud_suspend_cb(bool remote_wakeup_en) {
(void)remote_wakeup_en;
printf("\e[45msuspend\e[0m\n");
mimic_fat_cleanup_cache();
mimic_fat_update_usb_device_is_enabled(false);
}