@@ -47,3 +47,108 @@ void Adafruit_USBDev_MSC::begin(void)
47
47
USBDevice.addInterface (*this );
48
48
}
49
49
50
+ extern " C"
51
+ {
52
+
53
+ #include " nrf_gpio.h"
54
+ #include " flash/flash_qspi.h"
55
+
56
+ // Callback invoked when received an SCSI command not in built-in list below
57
+ // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
58
+ // - READ10 and WRITE10 has their own callbacks
59
+ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16 ], void * buffer, uint16_t bufsize)
60
+ {
61
+ const void * response = NULL ;
62
+ uint16_t resplen = 0 ;
63
+
64
+ switch ( scsi_cmd[0 ] )
65
+ {
66
+ case SCSI_CMD_TEST_UNIT_READY:
67
+ // Command that host uses to check our readiness before sending other commands
68
+ resplen = 0 ;
69
+ break ;
70
+
71
+ case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
72
+ // Host is about to read/write etc ... better not to disconnect disk
73
+ resplen = 0 ;
74
+ break ;
75
+
76
+ case SCSI_CMD_START_STOP_UNIT:
77
+ // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
78
+ /* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
79
+ // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
80
+ // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
81
+ start_stop->start;
82
+ start_stop->load_eject;
83
+ */
84
+ resplen = 0 ;
85
+ break ;
86
+
87
+ default :
88
+ // Set Sense = Invalid Command Operation
89
+ tud_msc_set_sense (lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20 , 0x00 );
90
+
91
+ // negative means error -> tinyusb could stall and/or response with failed status
92
+ resplen = -1 ;
93
+ break ;
94
+ }
95
+
96
+ // return len must not larger than bufsize
97
+ if ( resplen > bufsize )
98
+ {
99
+ resplen = bufsize;
100
+ }
101
+
102
+ // copy response to stack's buffer if any
103
+ if ( response && resplen )
104
+ {
105
+ memcpy (buffer, response, resplen);
106
+ }
107
+
108
+ return resplen;
109
+ }
110
+
111
+ // Callback invoked when received READ10 command.
112
+ // Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
113
+ int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void * buffer, uint32_t bufsize)
114
+ {
115
+ (void ) lun;
116
+
117
+ return flash_qspi_read (buffer, lba * CFG_TUD_MSC_BLOCK_SZ + offset, bufsize);
118
+ }
119
+
120
+ // Callback invoked when received WRITE10 command.
121
+ // Process data in buffer to disk's storage and return number of written bytes
122
+ int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t * buffer, uint32_t bufsize)
123
+ {
124
+ (void ) lun;
125
+
126
+ uint32_t wrcount = flash_qspi_write (lba * CFG_TUD_MSC_BLOCK_SZ + offset, buffer, bufsize);
127
+
128
+ // update fatfs's cache if address matches
129
+ extern void ExternalFS_usbmsc_write (uint32_t lba, void const * buffer, uint32_t bufsize);
130
+ if ( ExternalFS_usbmsc_write ) ExternalFS_usbmsc_write (lba, buffer, bufsize);
131
+
132
+ return wrcount;
133
+ }
134
+
135
+ // Callback invoked when WRITE10 command is completed (status received and accepted by host).
136
+ // used to flush any pending cache.
137
+ void tud_msc_write10_complete_cb (uint8_t lun)
138
+ {
139
+ (void ) lun;
140
+
141
+ // flush pending cache when write10 is complete
142
+ flash_qspi_flush ();
143
+ }
144
+
145
+ void tud_msc_capacity_cb (uint8_t lun, uint32_t * block_count, uint16_t * block_size)
146
+ {
147
+ (void ) lun;
148
+
149
+ *block_count = flash_qspi_size () / CFG_TUD_MSC_BLOCK_SZ;
150
+ *block_size = CFG_TUD_MSC_BUFSIZE;
151
+ }
152
+
153
+ }
154
+
0 commit comments