MSC/HostDevice.h
Go to the documentation of this file.
1 /****
2  * MSC/HostDevice.h
3  *
4  * Copyright 2023 mikee47 <mike@sillyhouse.net>
5  *
6  * This file is part of the Sming USB Library
7  *
8  * This library is free software: you can redistribute it and/or modify it under the terms of the
9  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with this library.
16  * If not, see <https://www.gnu.org/licenses/>.
17  *
18  ****/
19 
20 #pragma once
21 
22 #include "../HostInterface.h"
24 
25 namespace USB::MSC
26 {
27 class HostDevice;
28 
32 class LogicalUnit : public Storage::Disk::BlockDevice
33 {
34 public:
35  LogicalUnit(HostDevice& device, uint8_t lun);
36 
37  Type getType() const override
38  {
39  return Type::disk;
40  }
41 
42  String getName() const override;
43  uint32_t getId() const override;
44 
45 protected:
46  bool raw_sector_read(storage_size_t address, void* dst, size_t size) override;
47  bool raw_sector_write(storage_size_t address, const void* src, size_t size) override;
48  bool raw_sector_erase_range(storage_size_t address, size_t size) override;
49  bool raw_sync() override;
50 
51 private:
53  uint8_t lun;
54 };
55 
59 struct Inquiry {
60  scsi_inquiry_resp_t resp;
61 
62  String vendorId() const
63  {
64  return String(reinterpret_cast<const char*>(resp.vendor_id), sizeof(resp.vendor_id));
65  }
66 
67  String productId() const
68  {
69  return String(reinterpret_cast<const char*>(resp.product_id), sizeof(resp.product_id));
70  }
71 
73  {
74  return String(reinterpret_cast<const char*>(resp.product_rev), sizeof(resp.product_rev));
75  }
76 };
77 
82 class HostDevice : public HostInterface
83 {
84 public:
91  using EnumCallback = Delegate<bool(LogicalUnit& unit, const Inquiry& inquiry)>;
92 
93  using HostInterface::HostInterface;
94 
95  bool begin(const Instance& inst);
96  void end();
97 
102  bool enumerate(EnumCallback callback);
103 
109  LogicalUnit* operator[](unsigned lun) const
110  {
111  return (lun < MAX_LUN) ? units[lun].get() : nullptr;
112  }
113 
119  size_t getSectorSize(uint8_t lun) const
120  {
121  return tuh_msc_get_block_size(inst.dev_addr, lun);
122  }
123 
129  storage_size_t getSectorCount(uint8_t lun) const
130  {
131  return tuh_msc_get_block_count(inst.dev_addr, lun);
132  }
133 
142  bool read_sectors(uint8_t lun, uint32_t lba, void* dst, size_t size);
143 
152  bool write_sectors(uint8_t lun, uint32_t lba, const void* src, size_t size);
153 
162  bool wait();
163 
164  static constexpr size_t MAX_LUN{CFG_TUH_MSC_MAXLUN};
165  std::unique_ptr<LogicalUnit> units[MAX_LUN]{};
166 
167 private:
168  enum class State {
169  idle,
170  ready,
171  busy,
172  };
173 
174  bool sendInquiry(uint8_t lun);
175  bool handleInquiry(const tuh_msc_complete_data_t* cb_data);
176 
177  std::unique_ptr<Inquiry> inquiry;
178  EnumCallback enumCallback;
179  State state{};
180 };
181 
188 
193 using UnmountCallback = Delegate<void(HostDevice& dev)>;
194 
199 void onMount(MountCallback callback);
200 
205 void onUnmount(UnmountCallback callback);
206 
207 } // namespace USB::MSC
uint32_t storage_size_t
Definition: Components/Storage/src/include/Storage/Types.h:19
Type
Storage type.
Definition: Components/Storage/src/include/Storage/Device.h:42
Base class for sector-addressable (block) devices.
Definition: BlockDevice.h:34
The String class.
Definition: WString.h:137
Common base class to support Host USB access.
Definition: HostInterface.h:30
Instance inst
Definition: HostInterface.h:84
A USB mass storage device supports one or more logical units, each of which is a physical storage dev...
Definition: MSC/HostDevice.h:83
static constexpr size_t MAX_LUN
Definition: MSC/HostDevice.h:164
storage_size_t getSectorCount(uint8_t lun) const
Get the number of blocks/sectors for a unit.
Definition: MSC/HostDevice.h:129
bool write_sectors(uint8_t lun, uint32_t lba, const void *src, size_t size)
Write data to a unit.
bool wait()
Wait for all outstanding operations to complete.
size_t getSectorSize(uint8_t lun) const
Get the declared block/sector size for a unit.
Definition: MSC/HostDevice.h:119
bool enumerate(EnumCallback callback)
Enumerate all logical units managed by this device.
Delegate< bool(LogicalUnit &unit, const Inquiry &inquiry)> EnumCallback
Callback passed to enumerate() method.
Definition: MSC/HostDevice.h:91
LogicalUnit * operator[](unsigned lun) const
Access a specific logical unit by number.
Definition: MSC/HostDevice.h:109
void end()
Called when device is disconnected. Override as required.
std::unique_ptr< LogicalUnit > units[MAX_LUN]
Definition: MSC/HostDevice.h:165
bool read_sectors(uint8_t lun, uint32_t lba, void *dst, size_t size)
Read data from a unit.
bool begin(const Instance &inst)
Definition: Libraries/USB/src/USB/MSC/Device.h:26
void onUnmount(UnmountCallback callback)
Application should call this method to receive device disconnection notifications.
void onMount(MountCallback callback)
Application should call this method to receive device connection notifications.
Identifies a TinyUSB host interface.
Definition: HostInterface.h:35
uint8_t dev_addr
Device address (from 1)
Definition: HostInterface.h:36
Information provided by SCSI inquiry operation.
Definition: MSC/HostDevice.h:59
scsi_inquiry_resp_t resp
Definition: MSC/HostDevice.h:60
String productRev() const
Definition: MSC/HostDevice.h:72
String vendorId() const
Definition: MSC/HostDevice.h:62
String productId() const
Definition: MSC/HostDevice.h:67
A physical device instance managed by an MSC interface.
Definition: Libraries/USB/src/USB/MSC/Device.h:27
bool raw_sector_write(storage_size_t address, const void *src, size_t size) override
bool raw_sync() override
bool raw_sector_erase_range(storage_size_t address, size_t size) override
LogicalUnit(HostDevice &device, uint8_t lun)
bool raw_sector_read(storage_size_t address, void *dst, size_t size) override
String getName() const override
Obtain unique device name.
uint32_t getId() const override
Obtain device ID.
Type getType() const override
Obtain device type.
Definition: MSC/HostDevice.h:37
Storage::Device * device
Definition: Libraries/USB/src/USB/MSC/Device.h:28