Pierre Provent / USBHost

Dependents:   TEST_USB_Nucleo_F429ZI Essais_USB_Nucleo_F429ZI SID_V3_Nucleo_F429ZI SID_V4_Nucleo_F429ZI_copy

Committer:
pierreprovent
Date:
Fri Sep 25 10:17:49 2020 +0000
Revision:
0:77ca32e8e04e
Programme acquisition en enregistrement sur clef USB carte Nucleo F429ZI cours ELE118 Cnam

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pierreprovent 0:77ca32e8e04e 1 /* mbed USBHost Library
pierreprovent 0:77ca32e8e04e 2 * Copyright (c) 2006-2013 ARM Limited
pierreprovent 0:77ca32e8e04e 3 *
pierreprovent 0:77ca32e8e04e 4 * Licensed under the Apache License, Version 2.0 (the "License");
pierreprovent 0:77ca32e8e04e 5 * you may not use this file except in compliance with the License.
pierreprovent 0:77ca32e8e04e 6 * You may obtain a copy of the License at
pierreprovent 0:77ca32e8e04e 7 *
pierreprovent 0:77ca32e8e04e 8 * http://www.apache.org/licenses/LICENSE-2.0
pierreprovent 0:77ca32e8e04e 9 *
pierreprovent 0:77ca32e8e04e 10 * Unless required by applicable law or agreed to in writing, software
pierreprovent 0:77ca32e8e04e 11 * distributed under the License is distributed on an "AS IS" BASIS,
pierreprovent 0:77ca32e8e04e 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
pierreprovent 0:77ca32e8e04e 13 * See the License for the specific language governing permissions and
pierreprovent 0:77ca32e8e04e 14 * limitations under the License.
pierreprovent 0:77ca32e8e04e 15 */
pierreprovent 0:77ca32e8e04e 16
pierreprovent 0:77ca32e8e04e 17 #include "USBHostMSD.h"
pierreprovent 0:77ca32e8e04e 18
pierreprovent 0:77ca32e8e04e 19 #if USBHOST_MSD
pierreprovent 0:77ca32e8e04e 20
pierreprovent 0:77ca32e8e04e 21 #include "dbg.h"
pierreprovent 0:77ca32e8e04e 22
pierreprovent 0:77ca32e8e04e 23 #define CBW_SIGNATURE 0x43425355
pierreprovent 0:77ca32e8e04e 24 #define CSW_SIGNATURE 0x53425355
pierreprovent 0:77ca32e8e04e 25
pierreprovent 0:77ca32e8e04e 26 #define DEVICE_TO_HOST 0x80
pierreprovent 0:77ca32e8e04e 27 #define HOST_TO_DEVICE 0x00
pierreprovent 0:77ca32e8e04e 28
pierreprovent 0:77ca32e8e04e 29 #define GET_MAX_LUN (0xFE)
pierreprovent 0:77ca32e8e04e 30 #define BO_MASS_STORAGE_RESET (0xFF)
pierreprovent 0:77ca32e8e04e 31
pierreprovent 0:77ca32e8e04e 32 USBHostMSD::USBHostMSD(const char * rootdir) : FATFileSystem(rootdir)
pierreprovent 0:77ca32e8e04e 33 {
pierreprovent 0:77ca32e8e04e 34 host = USBHost::getHostInst();
pierreprovent 0:77ca32e8e04e 35 init();
pierreprovent 0:77ca32e8e04e 36 }
pierreprovent 0:77ca32e8e04e 37
pierreprovent 0:77ca32e8e04e 38 void USBHostMSD::init() {
pierreprovent 0:77ca32e8e04e 39 dev_connected = false;
pierreprovent 0:77ca32e8e04e 40 dev = NULL;
pierreprovent 0:77ca32e8e04e 41 bulk_in = NULL;
pierreprovent 0:77ca32e8e04e 42 bulk_out = NULL;
pierreprovent 0:77ca32e8e04e 43 dev_connected = false;
pierreprovent 0:77ca32e8e04e 44 blockSize = 0;
pierreprovent 0:77ca32e8e04e 45 blockCount = 0;
pierreprovent 0:77ca32e8e04e 46 msd_intf = -1;
pierreprovent 0:77ca32e8e04e 47 msd_device_found = false;
pierreprovent 0:77ca32e8e04e 48 disk_init = false;
pierreprovent 0:77ca32e8e04e 49 dev_connected = false;
pierreprovent 0:77ca32e8e04e 50 nb_ep = 0;
pierreprovent 0:77ca32e8e04e 51 }
pierreprovent 0:77ca32e8e04e 52
pierreprovent 0:77ca32e8e04e 53
pierreprovent 0:77ca32e8e04e 54 bool USBHostMSD::connected()
pierreprovent 0:77ca32e8e04e 55 {
pierreprovent 0:77ca32e8e04e 56 return dev_connected;
pierreprovent 0:77ca32e8e04e 57 }
pierreprovent 0:77ca32e8e04e 58
pierreprovent 0:77ca32e8e04e 59 bool USBHostMSD::connect()
pierreprovent 0:77ca32e8e04e 60 {
pierreprovent 0:77ca32e8e04e 61
pierreprovent 0:77ca32e8e04e 62 if (dev_connected) {
pierreprovent 0:77ca32e8e04e 63 return true;
pierreprovent 0:77ca32e8e04e 64 }
pierreprovent 0:77ca32e8e04e 65
pierreprovent 0:77ca32e8e04e 66 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
pierreprovent 0:77ca32e8e04e 67 if ((dev = host->getDevice(i)) != NULL) {
pierreprovent 0:77ca32e8e04e 68
pierreprovent 0:77ca32e8e04e 69 USB_DBG("Trying to connect MSD device\r\n");
pierreprovent 0:77ca32e8e04e 70
pierreprovent 0:77ca32e8e04e 71 if(host->enumerate(dev, this))
pierreprovent 0:77ca32e8e04e 72 break;
pierreprovent 0:77ca32e8e04e 73
pierreprovent 0:77ca32e8e04e 74 if (msd_device_found) {
pierreprovent 0:77ca32e8e04e 75 /* As this is done in a specific thread
pierreprovent 0:77ca32e8e04e 76 * this lock is taken to avoid to process a disconnection in
pierreprovent 0:77ca32e8e04e 77 * usb process during the device registering */
pierreprovent 0:77ca32e8e04e 78 USBHost::Lock Lock(host);
pierreprovent 0:77ca32e8e04e 79
pierreprovent 0:77ca32e8e04e 80 bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN);
pierreprovent 0:77ca32e8e04e 81 bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT);
pierreprovent 0:77ca32e8e04e 82
pierreprovent 0:77ca32e8e04e 83 if (!bulk_in || !bulk_out)
pierreprovent 0:77ca32e8e04e 84 continue;
pierreprovent 0:77ca32e8e04e 85
pierreprovent 0:77ca32e8e04e 86 USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf);
pierreprovent 0:77ca32e8e04e 87 dev->setName("MSD", msd_intf);
pierreprovent 0:77ca32e8e04e 88 host->registerDriver(dev, msd_intf, this, &USBHostMSD::init);
pierreprovent 0:77ca32e8e04e 89
pierreprovent 0:77ca32e8e04e 90 dev_connected = true;
pierreprovent 0:77ca32e8e04e 91 return true;
pierreprovent 0:77ca32e8e04e 92 }
pierreprovent 0:77ca32e8e04e 93 } //if()
pierreprovent 0:77ca32e8e04e 94 } //for()
pierreprovent 0:77ca32e8e04e 95 init();
pierreprovent 0:77ca32e8e04e 96 return false;
pierreprovent 0:77ca32e8e04e 97 }
pierreprovent 0:77ca32e8e04e 98
pierreprovent 0:77ca32e8e04e 99 /*virtual*/ void USBHostMSD::setVidPid(uint16_t vid, uint16_t pid)
pierreprovent 0:77ca32e8e04e 100 {
pierreprovent 0:77ca32e8e04e 101 // we don't check VID/PID for MSD driver
pierreprovent 0:77ca32e8e04e 102 }
pierreprovent 0:77ca32e8e04e 103
pierreprovent 0:77ca32e8e04e 104 /*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
pierreprovent 0:77ca32e8e04e 105 {
pierreprovent 0:77ca32e8e04e 106 if ((msd_intf == -1) &&
pierreprovent 0:77ca32e8e04e 107 (intf_class == MSD_CLASS) &&
pierreprovent 0:77ca32e8e04e 108 (intf_subclass == 0x06) &&
pierreprovent 0:77ca32e8e04e 109 (intf_protocol == 0x50)) {
pierreprovent 0:77ca32e8e04e 110 msd_intf = intf_nb;
pierreprovent 0:77ca32e8e04e 111 return true;
pierreprovent 0:77ca32e8e04e 112 }
pierreprovent 0:77ca32e8e04e 113 return false;
pierreprovent 0:77ca32e8e04e 114 }
pierreprovent 0:77ca32e8e04e 115
pierreprovent 0:77ca32e8e04e 116 /*virtual*/ bool USBHostMSD::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
pierreprovent 0:77ca32e8e04e 117 {
pierreprovent 0:77ca32e8e04e 118 if (intf_nb == msd_intf) {
pierreprovent 0:77ca32e8e04e 119 if (type == BULK_ENDPOINT) {
pierreprovent 0:77ca32e8e04e 120 nb_ep++;
pierreprovent 0:77ca32e8e04e 121 if (nb_ep == 2)
pierreprovent 0:77ca32e8e04e 122 msd_device_found = true;
pierreprovent 0:77ca32e8e04e 123 return true;
pierreprovent 0:77ca32e8e04e 124 }
pierreprovent 0:77ca32e8e04e 125 }
pierreprovent 0:77ca32e8e04e 126 return false;
pierreprovent 0:77ca32e8e04e 127 }
pierreprovent 0:77ca32e8e04e 128
pierreprovent 0:77ca32e8e04e 129
pierreprovent 0:77ca32e8e04e 130 int USBHostMSD::testUnitReady()
pierreprovent 0:77ca32e8e04e 131 {
pierreprovent 0:77ca32e8e04e 132 USB_DBG("Test unit ready");
pierreprovent 0:77ca32e8e04e 133 return SCSITransfer(NULL, 6, DEVICE_TO_HOST, 0, 0);
pierreprovent 0:77ca32e8e04e 134 }
pierreprovent 0:77ca32e8e04e 135
pierreprovent 0:77ca32e8e04e 136
pierreprovent 0:77ca32e8e04e 137 int USBHostMSD::readCapacity()
pierreprovent 0:77ca32e8e04e 138 {
pierreprovent 0:77ca32e8e04e 139 USB_DBG("Read capacity");
pierreprovent 0:77ca32e8e04e 140 uint8_t cmd[10] = {0x25,0,0,0,0,0,0,0,0,0};
pierreprovent 0:77ca32e8e04e 141 uint8_t result[8];
pierreprovent 0:77ca32e8e04e 142 int status = SCSITransfer(cmd, 10, DEVICE_TO_HOST, result, 8);
pierreprovent 0:77ca32e8e04e 143 if (status == 0) {
pierreprovent 0:77ca32e8e04e 144 blockCount = (result[0] << 24) | (result[1] << 16) | (result[2] << 8) | result[3];
pierreprovent 0:77ca32e8e04e 145 blockSize = (result[4] << 24) | (result[5] << 16) | (result[6] << 8) | result[7];
pierreprovent 0:77ca32e8e04e 146 USB_INFO("MSD [dev: %p] - blockCount: %lld, blockSize: %d, Capacity: %lld\r\n", dev, blockCount, blockSize, blockCount*blockSize);
pierreprovent 0:77ca32e8e04e 147 }
pierreprovent 0:77ca32e8e04e 148 return status;
pierreprovent 0:77ca32e8e04e 149 }
pierreprovent 0:77ca32e8e04e 150
pierreprovent 0:77ca32e8e04e 151
pierreprovent 0:77ca32e8e04e 152 int USBHostMSD::SCSIRequestSense()
pierreprovent 0:77ca32e8e04e 153 {
pierreprovent 0:77ca32e8e04e 154 USB_DBG("Request sense");
pierreprovent 0:77ca32e8e04e 155 uint8_t cmd[6] = {0x03,0,0,0,18,0};
pierreprovent 0:77ca32e8e04e 156 uint8_t result[18];
pierreprovent 0:77ca32e8e04e 157 int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 18);
pierreprovent 0:77ca32e8e04e 158 return status;
pierreprovent 0:77ca32e8e04e 159 }
pierreprovent 0:77ca32e8e04e 160
pierreprovent 0:77ca32e8e04e 161
pierreprovent 0:77ca32e8e04e 162 int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code)
pierreprovent 0:77ca32e8e04e 163 {
pierreprovent 0:77ca32e8e04e 164 USB_DBG("Inquiry");
pierreprovent 0:77ca32e8e04e 165 uint8_t evpd = (page_code == 0) ? 0 : 1;
pierreprovent 0:77ca32e8e04e 166 uint8_t cmd[6] = {0x12, uint8_t((lun << 5) | evpd), page_code, 0, 36, 0};
pierreprovent 0:77ca32e8e04e 167 uint8_t result[36];
pierreprovent 0:77ca32e8e04e 168 int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 36);
pierreprovent 0:77ca32e8e04e 169 if (status == 0) {
pierreprovent 0:77ca32e8e04e 170 char vid_pid[17];
pierreprovent 0:77ca32e8e04e 171 memcpy(vid_pid, &result[8], 8);
pierreprovent 0:77ca32e8e04e 172 vid_pid[8] = 0;
pierreprovent 0:77ca32e8e04e 173 USB_INFO("MSD [dev: %p] - Vendor ID: %s", dev, vid_pid);
pierreprovent 0:77ca32e8e04e 174
pierreprovent 0:77ca32e8e04e 175 memcpy(vid_pid, &result[16], 16);
pierreprovent 0:77ca32e8e04e 176 vid_pid[16] = 0;
pierreprovent 0:77ca32e8e04e 177 USB_INFO("MSD [dev: %p] - Product ID: %s", dev, vid_pid);
pierreprovent 0:77ca32e8e04e 178
pierreprovent 0:77ca32e8e04e 179 memcpy(vid_pid, &result[32], 4);
pierreprovent 0:77ca32e8e04e 180 vid_pid[4] = 0;
pierreprovent 0:77ca32e8e04e 181 USB_INFO("MSD [dev: %p] - Product rev: %s", dev, vid_pid);
pierreprovent 0:77ca32e8e04e 182 }
pierreprovent 0:77ca32e8e04e 183 return status;
pierreprovent 0:77ca32e8e04e 184 }
pierreprovent 0:77ca32e8e04e 185
pierreprovent 0:77ca32e8e04e 186 int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep)
pierreprovent 0:77ca32e8e04e 187 {
pierreprovent 0:77ca32e8e04e 188 // if ep stalled: send clear feature
pierreprovent 0:77ca32e8e04e 189 if (res == USB_TYPE_STALL_ERROR) {
pierreprovent 0:77ca32e8e04e 190 res = host->controlWrite( dev,
pierreprovent 0:77ca32e8e04e 191 USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
pierreprovent 0:77ca32e8e04e 192 CLEAR_FEATURE,
pierreprovent 0:77ca32e8e04e 193 0, ep->getAddress(), NULL, 0);
pierreprovent 0:77ca32e8e04e 194 // set state to IDLE if clear feature successful
pierreprovent 0:77ca32e8e04e 195 if (res == USB_TYPE_OK) {
pierreprovent 0:77ca32e8e04e 196 ep->setState(USB_TYPE_IDLE);
pierreprovent 0:77ca32e8e04e 197 }
pierreprovent 0:77ca32e8e04e 198 }
pierreprovent 0:77ca32e8e04e 199
pierreprovent 0:77ca32e8e04e 200 if (res != USB_TYPE_OK)
pierreprovent 0:77ca32e8e04e 201 return -1;
pierreprovent 0:77ca32e8e04e 202
pierreprovent 0:77ca32e8e04e 203 return 0;
pierreprovent 0:77ca32e8e04e 204 }
pierreprovent 0:77ca32e8e04e 205
pierreprovent 0:77ca32e8e04e 206
pierreprovent 0:77ca32e8e04e 207 int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len)
pierreprovent 0:77ca32e8e04e 208 {
pierreprovent 0:77ca32e8e04e 209
pierreprovent 0:77ca32e8e04e 210 int res = 0;
pierreprovent 0:77ca32e8e04e 211
pierreprovent 0:77ca32e8e04e 212 cbw.Signature = CBW_SIGNATURE;
pierreprovent 0:77ca32e8e04e 213 cbw.Tag = 0;
pierreprovent 0:77ca32e8e04e 214 cbw.DataLength = transfer_len;
pierreprovent 0:77ca32e8e04e 215 cbw.Flags = flags;
pierreprovent 0:77ca32e8e04e 216 cbw.LUN = 0;
pierreprovent 0:77ca32e8e04e 217 cbw.CBLength = cmd_len;
pierreprovent 0:77ca32e8e04e 218 memset(cbw.CB,0,sizeof(cbw.CB));
pierreprovent 0:77ca32e8e04e 219 if (cmd) {
pierreprovent 0:77ca32e8e04e 220 memcpy(cbw.CB,cmd,cmd_len);
pierreprovent 0:77ca32e8e04e 221 }
pierreprovent 0:77ca32e8e04e 222
pierreprovent 0:77ca32e8e04e 223 // send the cbw
pierreprovent 0:77ca32e8e04e 224 USB_DBG("Send CBW");
pierreprovent 0:77ca32e8e04e 225 res = host->bulkWrite(dev, bulk_out,(uint8_t *)&cbw, 31);
pierreprovent 0:77ca32e8e04e 226 if (checkResult(res, bulk_out))
pierreprovent 0:77ca32e8e04e 227 return -1;
pierreprovent 0:77ca32e8e04e 228
pierreprovent 0:77ca32e8e04e 229 // data stage if needed
pierreprovent 0:77ca32e8e04e 230 if (data) {
pierreprovent 0:77ca32e8e04e 231 USB_DBG("data stage");
pierreprovent 0:77ca32e8e04e 232 if (flags == HOST_TO_DEVICE) {
pierreprovent 0:77ca32e8e04e 233
pierreprovent 0:77ca32e8e04e 234 res = host->bulkWrite(dev, bulk_out, data, transfer_len);
pierreprovent 0:77ca32e8e04e 235 if (checkResult(res, bulk_out))
pierreprovent 0:77ca32e8e04e 236 return -1;
pierreprovent 0:77ca32e8e04e 237
pierreprovent 0:77ca32e8e04e 238 } else if (flags == DEVICE_TO_HOST) {
pierreprovent 0:77ca32e8e04e 239
pierreprovent 0:77ca32e8e04e 240 res = host->bulkRead(dev, bulk_in, data, transfer_len);
pierreprovent 0:77ca32e8e04e 241 if (checkResult(res, bulk_in))
pierreprovent 0:77ca32e8e04e 242 return -1;
pierreprovent 0:77ca32e8e04e 243 }
pierreprovent 0:77ca32e8e04e 244 }
pierreprovent 0:77ca32e8e04e 245
pierreprovent 0:77ca32e8e04e 246 // status stage
pierreprovent 0:77ca32e8e04e 247 csw.Signature = 0;
pierreprovent 0:77ca32e8e04e 248 USB_DBG("Read CSW");
pierreprovent 0:77ca32e8e04e 249 res = host->bulkRead(dev, bulk_in,(uint8_t *)&csw, 13);
pierreprovent 0:77ca32e8e04e 250 if (checkResult(res, bulk_in))
pierreprovent 0:77ca32e8e04e 251 return -1;
pierreprovent 0:77ca32e8e04e 252
pierreprovent 0:77ca32e8e04e 253 if (csw.Signature != CSW_SIGNATURE) {
pierreprovent 0:77ca32e8e04e 254 return -1;
pierreprovent 0:77ca32e8e04e 255 }
pierreprovent 0:77ca32e8e04e 256
pierreprovent 0:77ca32e8e04e 257 USB_DBG("recv csw: status: %d", csw.Status);
pierreprovent 0:77ca32e8e04e 258
pierreprovent 0:77ca32e8e04e 259 // ModeSense?
pierreprovent 0:77ca32e8e04e 260 if ((csw.Status == 1) && (cmd[0] != 0x03)) {
pierreprovent 0:77ca32e8e04e 261 USB_DBG("request mode sense");
pierreprovent 0:77ca32e8e04e 262 return SCSIRequestSense();
pierreprovent 0:77ca32e8e04e 263 }
pierreprovent 0:77ca32e8e04e 264
pierreprovent 0:77ca32e8e04e 265 // perform reset recovery
pierreprovent 0:77ca32e8e04e 266 if ((csw.Status == 2) && (cmd[0] != 0x03)) {
pierreprovent 0:77ca32e8e04e 267
pierreprovent 0:77ca32e8e04e 268 // send Bulk-Only Mass Storage Reset request
pierreprovent 0:77ca32e8e04e 269 res = host->controlWrite( dev,
pierreprovent 0:77ca32e8e04e 270 USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
pierreprovent 0:77ca32e8e04e 271 BO_MASS_STORAGE_RESET,
pierreprovent 0:77ca32e8e04e 272 0, msd_intf, NULL, 0);
pierreprovent 0:77ca32e8e04e 273
pierreprovent 0:77ca32e8e04e 274 // unstall both endpoints
pierreprovent 0:77ca32e8e04e 275 res = host->controlWrite( dev,
pierreprovent 0:77ca32e8e04e 276 USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
pierreprovent 0:77ca32e8e04e 277 CLEAR_FEATURE,
pierreprovent 0:77ca32e8e04e 278 0, bulk_in->getAddress(), NULL, 0);
pierreprovent 0:77ca32e8e04e 279
pierreprovent 0:77ca32e8e04e 280 res = host->controlWrite( dev,
pierreprovent 0:77ca32e8e04e 281 USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
pierreprovent 0:77ca32e8e04e 282 CLEAR_FEATURE,
pierreprovent 0:77ca32e8e04e 283 0, bulk_out->getAddress(), NULL, 0);
pierreprovent 0:77ca32e8e04e 284
pierreprovent 0:77ca32e8e04e 285 }
pierreprovent 0:77ca32e8e04e 286
pierreprovent 0:77ca32e8e04e 287 return csw.Status;
pierreprovent 0:77ca32e8e04e 288 }
pierreprovent 0:77ca32e8e04e 289
pierreprovent 0:77ca32e8e04e 290
pierreprovent 0:77ca32e8e04e 291 int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction)
pierreprovent 0:77ca32e8e04e 292 {
pierreprovent 0:77ca32e8e04e 293 uint8_t cmd[10];
pierreprovent 0:77ca32e8e04e 294 memset(cmd,0,10);
pierreprovent 0:77ca32e8e04e 295 cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A;
pierreprovent 0:77ca32e8e04e 296
pierreprovent 0:77ca32e8e04e 297 cmd[2] = (block >> 24) & 0xff;
pierreprovent 0:77ca32e8e04e 298 cmd[3] = (block >> 16) & 0xff;
pierreprovent 0:77ca32e8e04e 299 cmd[4] = (block >> 8) & 0xff;
pierreprovent 0:77ca32e8e04e 300 cmd[5] = block & 0xff;
pierreprovent 0:77ca32e8e04e 301
pierreprovent 0:77ca32e8e04e 302 cmd[7] = (nbBlock >> 8) & 0xff;
pierreprovent 0:77ca32e8e04e 303 cmd[8] = nbBlock & 0xff;
pierreprovent 0:77ca32e8e04e 304
pierreprovent 0:77ca32e8e04e 305 return SCSITransfer(cmd, 10, direction, buf, blockSize*nbBlock);
pierreprovent 0:77ca32e8e04e 306 }
pierreprovent 0:77ca32e8e04e 307
pierreprovent 0:77ca32e8e04e 308 int USBHostMSD::getMaxLun()
pierreprovent 0:77ca32e8e04e 309 {
pierreprovent 0:77ca32e8e04e 310 uint8_t buf[1], res;
pierreprovent 0:77ca32e8e04e 311 res = host->controlRead( dev, USB_RECIPIENT_INTERFACE | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
pierreprovent 0:77ca32e8e04e 312 0xfe, 0, msd_intf, buf, 1);
pierreprovent 0:77ca32e8e04e 313 USB_DBG("max lun: %d", buf[0]);
pierreprovent 0:77ca32e8e04e 314 return res;
pierreprovent 0:77ca32e8e04e 315 }
pierreprovent 0:77ca32e8e04e 316
pierreprovent 0:77ca32e8e04e 317 int USBHostMSD::disk_initialize() {
pierreprovent 0:77ca32e8e04e 318 USB_DBG("FILESYSTEM: init");
pierreprovent 0:77ca32e8e04e 319 uint16_t i, timeout = 10;
pierreprovent 0:77ca32e8e04e 320
pierreprovent 0:77ca32e8e04e 321 getMaxLun();
pierreprovent 0:77ca32e8e04e 322
pierreprovent 0:77ca32e8e04e 323 for (i = 0; i < timeout; i++) {
pierreprovent 0:77ca32e8e04e 324 Thread::wait(100);
pierreprovent 0:77ca32e8e04e 325 if (!testUnitReady())
pierreprovent 0:77ca32e8e04e 326 break;
pierreprovent 0:77ca32e8e04e 327 }
pierreprovent 0:77ca32e8e04e 328
pierreprovent 0:77ca32e8e04e 329 if (i == timeout) {
pierreprovent 0:77ca32e8e04e 330 disk_init = false;
pierreprovent 0:77ca32e8e04e 331 return -1;
pierreprovent 0:77ca32e8e04e 332 }
pierreprovent 0:77ca32e8e04e 333
pierreprovent 0:77ca32e8e04e 334 inquiry(0, 0);
pierreprovent 0:77ca32e8e04e 335 disk_init = 1;
pierreprovent 0:77ca32e8e04e 336 return readCapacity();
pierreprovent 0:77ca32e8e04e 337 }
pierreprovent 0:77ca32e8e04e 338
pierreprovent 0:77ca32e8e04e 339 int USBHostMSD::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) {
pierreprovent 0:77ca32e8e04e 340 USB_DBG("FILESYSTEM: write block: %lld, count: %d", block_number, count);
pierreprovent 0:77ca32e8e04e 341 if (!disk_init) {
pierreprovent 0:77ca32e8e04e 342 disk_initialize();
pierreprovent 0:77ca32e8e04e 343 }
pierreprovent 0:77ca32e8e04e 344 if (!disk_init)
pierreprovent 0:77ca32e8e04e 345 return -1;
pierreprovent 0:77ca32e8e04e 346 for (uint32_t b = block_number; b < block_number + count; b++) {
pierreprovent 0:77ca32e8e04e 347 if (dataTransfer((uint8_t*)buffer, b, 1, HOST_TO_DEVICE))
pierreprovent 0:77ca32e8e04e 348 return -1;
pierreprovent 0:77ca32e8e04e 349 buffer += 512;
pierreprovent 0:77ca32e8e04e 350 }
pierreprovent 0:77ca32e8e04e 351 return 0;
pierreprovent 0:77ca32e8e04e 352 }
pierreprovent 0:77ca32e8e04e 353
pierreprovent 0:77ca32e8e04e 354 int USBHostMSD::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) {
pierreprovent 0:77ca32e8e04e 355 USB_DBG("FILESYSTEM: read block: %lld, count: %d", block_number, count);
pierreprovent 0:77ca32e8e04e 356 if (!disk_init) {
pierreprovent 0:77ca32e8e04e 357 disk_initialize();
pierreprovent 0:77ca32e8e04e 358 }
pierreprovent 0:77ca32e8e04e 359 if (!disk_init)
pierreprovent 0:77ca32e8e04e 360 return -1;
pierreprovent 0:77ca32e8e04e 361 for (uint32_t b = block_number; b < block_number + count; b++) {
pierreprovent 0:77ca32e8e04e 362 if (dataTransfer((uint8_t*)buffer, b, 1, DEVICE_TO_HOST))
pierreprovent 0:77ca32e8e04e 363 return -1;
pierreprovent 0:77ca32e8e04e 364 buffer += 512;
pierreprovent 0:77ca32e8e04e 365 }
pierreprovent 0:77ca32e8e04e 366 return 0;
pierreprovent 0:77ca32e8e04e 367 }
pierreprovent 0:77ca32e8e04e 368
pierreprovent 0:77ca32e8e04e 369 uint32_t USBHostMSD::disk_sectors() {
pierreprovent 0:77ca32e8e04e 370 USB_DBG("FILESYSTEM: sectors");
pierreprovent 0:77ca32e8e04e 371 if (!disk_init) {
pierreprovent 0:77ca32e8e04e 372 disk_initialize();
pierreprovent 0:77ca32e8e04e 373 }
pierreprovent 0:77ca32e8e04e 374 if (!disk_init)
pierreprovent 0:77ca32e8e04e 375 return 0;
pierreprovent 0:77ca32e8e04e 376 return blockCount;
pierreprovent 0:77ca32e8e04e 377 }
pierreprovent 0:77ca32e8e04e 378
pierreprovent 0:77ca32e8e04e 379 #endif