Skip to content

Commit 46cd6c7

Browse files
committed
Add Usb HOST Mass Storage Device library
Former-commit-id: abadef9
1 parent 9a98c3b commit 46cd6c7

File tree

3 files changed

+377
-0
lines changed

3 files changed

+377
-0
lines changed

libraries/UsbHostMsd/UsbHostMsd.cpp

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/* ########################################################################## */
2+
/* - File: UsbHostMsd.h
3+
- Copyright (c): 2023 Arduino srl. All right reserved.
4+
- Author: Daniele Aimo (d.aimo@arduino.cc)
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
This library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc.,51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
19+
/* ########################################################################## */
20+
#include "UsbHostMsd.h"
21+
22+
23+
24+
25+
#define CBW_SIGNATURE 0x43425355
26+
#define CSW_SIGNATURE 0x53425355
27+
28+
#define DEVICE_TO_HOST 0x80
29+
#define HOST_TO_DEVICE 0x00
30+
31+
#define GET_MAX_LUN (0xFE)
32+
#define BO_MASS_STORAGE_RESET (0xFF)
33+
34+
USBHostMSD::USBHostMSD()
35+
{
36+
37+
}
38+
39+
40+
41+
bool USBHostMSD::connected()
42+
{
43+
return false;
44+
}
45+
46+
bool USBHostMSD::connect()
47+
{
48+
49+
50+
return false;
51+
}
52+
53+
/*virtual*/ void USBHostMSD::setVidPid(uint16_t vid, uint16_t pid)
54+
{
55+
// we don't check VID/PID for MSD driver
56+
}
57+
58+
/*virtual*/ bool USBHostMSD::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
59+
{
60+
61+
return false;
62+
}
63+
64+
/*virtual*/ //bool USBHostMSD::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
65+
//{
66+
67+
//return false;
68+
//}
69+
70+
/*
71+
int USBHostMSD::testUnitReady()
72+
{
73+
return 0;
74+
}
75+
76+
77+
int USBHostMSD::readCapacity()
78+
{
79+
return 0;
80+
}
81+
82+
83+
int USBHostMSD::SCSIRequestSense()
84+
{
85+
return 0;
86+
}
87+
88+
89+
int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code)
90+
{
91+
92+
return 0;
93+
}
94+
95+
int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep)
96+
{
97+
98+
99+
return 0;
100+
}
101+
102+
103+
int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len)
104+
{
105+
106+
107+
108+
109+
return 0;
110+
}
111+
112+
113+
int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction)
114+
{
115+
return 0;
116+
}
117+
118+
int USBHostMSD::getMaxLun()
119+
{
120+
return 0;
121+
}
122+
*/
123+
int USBHostMSD::init()
124+
{
125+
return 0;
126+
}
127+
128+
int USBHostMSD::program(const void *buffer, bd_addr_t addr, bd_size_t size)
129+
{
130+
uint32_t block_number, count;
131+
uint8_t *buf = (uint8_t *)buffer;
132+
if (!disk_init) {
133+
init();
134+
}
135+
if (!disk_init) {
136+
return -1;
137+
}
138+
block_number = addr / block_size;
139+
count = size /block_size;
140+
141+
for (uint32_t b = block_number; b < block_number + count; b++) {
142+
/*
143+
if (dataTransfer(buf, b, 1, HOST_TO_DEVICE))
144+
return -1;
145+
*/
146+
buf += block_size;
147+
}
148+
return 0;
149+
}
150+
151+
int USBHostMSD::read(void *buffer, bd_addr_t addr, bd_size_t size)
152+
{
153+
uint32_t block_number, count;
154+
uint8_t *buf = (uint8_t *)buffer;
155+
if (!disk_init) {
156+
init();
157+
}
158+
if (!disk_init) {
159+
return -1;
160+
}
161+
block_number = addr / block_size;
162+
count = size / block_size;
163+
164+
for (uint32_t b = block_number; b < block_number + count; b++) {
165+
/*
166+
if (dataTransfer(buf, b, 1, DEVICE_TO_HOST))
167+
return -1;
168+
*/
169+
buf += block_size;
170+
}
171+
return 0;
172+
}
173+
174+
int USBHostMSD::erase(bd_addr_t addr, bd_size_t size)
175+
{
176+
return 0;
177+
}
178+
179+
bd_size_t USBHostMSD::get_read_size() const {
180+
return (disk_init ? (bd_size_t)block_size : -1);
181+
}
182+
183+
bd_size_t USBHostMSD::get_program_size() const
184+
{
185+
return (disk_init ? (bd_size_t)block_size : -1);
186+
}
187+
bd_size_t USBHostMSD::get_erase_size() const
188+
{
189+
return (disk_init ? (bd_size_t)block_size : -1);
190+
}
191+
192+
bd_size_t USBHostMSD::size() const
193+
{
194+
//USB_DBG("FILESYSTEM: size ");
195+
return (disk_init ? (bd_size_t)block_size : 0);
196+
}
197+
198+
const char *USBHostMSD::get_type() const
199+
{
200+
return "USBMSD";
201+
}
202+

libraries/UsbHostMsd/UsbHostMsd.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* ########################################################################## */
2+
/* - File: UsbHostMsd.h
3+
- Copyright (c): 2023 Arduino srl. All right reserved.
4+
- Author: Daniele Aimo (d.aimo@arduino.cc)
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
This library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc.,51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
19+
/* ########################################################################## */
20+
21+
#ifndef USB_HOST_MSD_H
22+
#define USB_HOST_MSD_H
23+
24+
#include "Arduino.h"
25+
26+
#include "FATFileSystem.h"
27+
#include "blockDevice.h"
28+
29+
/**
30+
* A class to communicate a USB flash disk
31+
*/
32+
class USBHostMSD : public BlockDevice {
33+
public:
34+
USBHostMSD();
35+
bool connected();
36+
bool connect();
37+
virtual int init();
38+
virtual int deinit();
39+
virtual int read(void *buffer, bd_addr_t addr, bd_size_t size);
40+
virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size);
41+
virtual int erase(bd_addr_t addr, bd_size_t size);
42+
virtual bd_size_t get_read_size() const;
43+
virtual bd_size_t get_program_size() const;
44+
virtual bd_size_t get_erase_size() const;
45+
virtual bd_size_t size() const;
46+
virtual const char *get_type() const;
47+
48+
49+
50+
51+
protected:
52+
//From IUSBEnumerator
53+
virtual void setVidPid(uint16_t vid, uint16_t pid);
54+
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
55+
//virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
56+
57+
58+
private:
59+
bool disk_init;
60+
61+
virtual int open();
62+
virtual int close();
63+
virtual int write(const void *buffer, bd_addr_t addr, bd_size_t size);
64+
65+
bd_size_t total_size;
66+
bd_size_t block_size;
67+
68+
};
69+
70+
71+
#endif

libraries/UsbHostMsd/tu_msc.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019 Ha Thach (tinyusb.org)
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*
24+
*/
25+
26+
#include "tusb.h"
27+
28+
#if CFG_TUH_MSC
29+
30+
//--------------------------------------------------------------------+
31+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
32+
//--------------------------------------------------------------------+
33+
static scsi_inquiry_resp_t inquiry_resp;
34+
35+
bool inquiry_complete_cb(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)
36+
{
37+
if (csw->status != 0)
38+
{
39+
printf("Inquiry failed\r\n");
40+
return false;
41+
}
42+
43+
// Print out Vendor ID, Product ID and Rev
44+
printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev);
45+
46+
// Get capacity of device
47+
uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun);
48+
uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun);
49+
50+
printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size));
51+
printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size);
52+
53+
return true;
54+
}
55+
56+
//------------- IMPLEMENTATION -------------//
57+
void tuh_msc_mount_cb(uint8_t dev_addr) {
58+
mylogadd("[CALL]: tuh_msc_mount_cb %i ++++++++ MOUNT", dev_addr);
59+
60+
//uint8_t const lun = 0;
61+
//tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb);
62+
//
63+
// //------------- file system (only 1 LUN support) -------------//
64+
// uint8_t phy_disk = dev_addr-1;
65+
// disk_initialize(phy_disk);
66+
//
67+
// if ( disk_is_ready(phy_disk) )
68+
// {
69+
// if ( f_mount(phy_disk, &fatfs[phy_disk]) != FR_OK )
70+
// {
71+
// puts("mount failed");
72+
// return;
73+
// }
74+
//
75+
// f_chdrive(phy_disk); // change to newly mounted drive
76+
// f_chdir("/"); // root as current dir
77+
//
78+
// cli_init();
79+
// }
80+
}
81+
82+
void tuh_msc_umount_cb(uint8_t dev_addr) {
83+
(void) dev_addr;
84+
mylogadd("[CALL]: tuh_msc_umount_cb %i --------- UMOUNT", dev_addr);
85+
86+
// uint8_t phy_disk = dev_addr-1;
87+
//
88+
// f_mount(phy_disk, NULL); // unmount disk
89+
// disk_deinitialize(phy_disk);
90+
//
91+
// if ( phy_disk == f_get_current_drive() )
92+
// { // active drive is unplugged --> change to other drive
93+
// for(uint8_t i=0; i<CFG_TUH_DEVICE_MAX; i++)
94+
// {
95+
// if ( disk_is_ready(i) )
96+
// {
97+
// f_chdrive(i);
98+
// cli_init(); // refractor, rename
99+
// }
100+
// }
101+
// }
102+
}
103+
104+
#endif

0 commit comments

Comments
 (0)