esemi00

Dependencies:   mbed mbed-rtos EthernetInterface FatFileSystemCpp

Committer:
esemi00
Date:
Wed Jan 20 05:23:38 2021 +0000
Revision:
0:86b964b67dae
esemi00

Who changed what in which revision?

UserRevisionLine numberNew contents of line
esemi00 0:86b964b67dae 1 /*
esemi00 0:86b964b67dae 2 **************************************************************************************************************
esemi00 0:86b964b67dae 3 * NXP USB Host Stack
esemi00 0:86b964b67dae 4 *
esemi00 0:86b964b67dae 5 * (c) Copyright 2008, NXP SemiConductors
esemi00 0:86b964b67dae 6 * (c) Copyright 2008, OnChip Technologies LLC
esemi00 0:86b964b67dae 7 * All Rights Reserved
esemi00 0:86b964b67dae 8 *
esemi00 0:86b964b67dae 9 * www.nxp.com
esemi00 0:86b964b67dae 10 * www.onchiptech.com
esemi00 0:86b964b67dae 11 *
esemi00 0:86b964b67dae 12 * File : usbhost_ms.c
esemi00 0:86b964b67dae 13 * Programmer(s) : Ravikanth.P
esemi00 0:86b964b67dae 14 * Version :
esemi00 0:86b964b67dae 15 *
esemi00 0:86b964b67dae 16 **************************************************************************************************************
esemi00 0:86b964b67dae 17 */
esemi00 0:86b964b67dae 18
esemi00 0:86b964b67dae 19 /*
esemi00 0:86b964b67dae 20 **************************************************************************************************************
esemi00 0:86b964b67dae 21 * INCLUDE HEADER FILES
esemi00 0:86b964b67dae 22 **************************************************************************************************************
esemi00 0:86b964b67dae 23 */
esemi00 0:86b964b67dae 24
esemi00 0:86b964b67dae 25 #include "usbhost_ms.h"
esemi00 0:86b964b67dae 26
esemi00 0:86b964b67dae 27 /*
esemi00 0:86b964b67dae 28 **************************************************************************************************************
esemi00 0:86b964b67dae 29 * GLOBAL VARIABLES
esemi00 0:86b964b67dae 30 **************************************************************************************************************
esemi00 0:86b964b67dae 31 */
esemi00 0:86b964b67dae 32
esemi00 0:86b964b67dae 33 USB_INT32U MS_BlkSize;
esemi00 0:86b964b67dae 34
esemi00 0:86b964b67dae 35 /*
esemi00 0:86b964b67dae 36 **************************************************************************************************************
esemi00 0:86b964b67dae 37 * INITIALIZE MASS STORAGE INTERFACE
esemi00 0:86b964b67dae 38 *
esemi00 0:86b964b67dae 39 * Description: This function initializes the mass storage interface
esemi00 0:86b964b67dae 40 *
esemi00 0:86b964b67dae 41 * Arguments : None
esemi00 0:86b964b67dae 42 *
esemi00 0:86b964b67dae 43 * Returns : OK if Success
esemi00 0:86b964b67dae 44 * ERR_INVALID_BOOTSIG if Failed
esemi00 0:86b964b67dae 45 *
esemi00 0:86b964b67dae 46 **************************************************************************************************************
esemi00 0:86b964b67dae 47 */
esemi00 0:86b964b67dae 48
esemi00 0:86b964b67dae 49 USB_INT32S MS_Init (USB_INT32U *blkSize, USB_INT32U *numBlks, USB_INT08U *inquiryResult)
esemi00 0:86b964b67dae 50 {
esemi00 0:86b964b67dae 51 USB_INT08U retry;
esemi00 0:86b964b67dae 52 USB_INT32S rc;
esemi00 0:86b964b67dae 53
esemi00 0:86b964b67dae 54 MS_GetMaxLUN(); /* Get maximum logical unit number */
esemi00 0:86b964b67dae 55 retry = 80;
esemi00 0:86b964b67dae 56 while(retry) {
esemi00 0:86b964b67dae 57 rc = MS_TestUnitReady(); /* Test whether the unit is ready */
esemi00 0:86b964b67dae 58 if (rc == OK) {
esemi00 0:86b964b67dae 59 break;
esemi00 0:86b964b67dae 60 }
esemi00 0:86b964b67dae 61 MS_GetSenseInfo(); /* Get sense information */
esemi00 0:86b964b67dae 62 retry--;
esemi00 0:86b964b67dae 63 }
esemi00 0:86b964b67dae 64 if (rc != OK) {
esemi00 0:86b964b67dae 65 PRINT_Err(rc);
esemi00 0:86b964b67dae 66 return (rc);
esemi00 0:86b964b67dae 67 }
esemi00 0:86b964b67dae 68 rc = MS_ReadCapacity(numBlks, blkSize); /* Read capacity of the disk */
esemi00 0:86b964b67dae 69 MS_BlkSize = *blkSize; // Set global
esemi00 0:86b964b67dae 70 rc = MS_Inquire (inquiryResult);
esemi00 0:86b964b67dae 71 return (rc);
esemi00 0:86b964b67dae 72 }
esemi00 0:86b964b67dae 73 /*
esemi00 0:86b964b67dae 74 **************************************************************************************************************
esemi00 0:86b964b67dae 75 * PARSE THE CONFIGURATION
esemi00 0:86b964b67dae 76 *
esemi00 0:86b964b67dae 77 * Description: This function is used to parse the configuration
esemi00 0:86b964b67dae 78 *
esemi00 0:86b964b67dae 79 * Arguments : None
esemi00 0:86b964b67dae 80 *
esemi00 0:86b964b67dae 81 * Returns : OK if Success
esemi00 0:86b964b67dae 82 * ERR_INVALID_BOOTSIG if Failed
esemi00 0:86b964b67dae 83 *
esemi00 0:86b964b67dae 84 **************************************************************************************************************
esemi00 0:86b964b67dae 85 */
esemi00 0:86b964b67dae 86
esemi00 0:86b964b67dae 87 USB_INT32S MS_ParseConfiguration (void)
esemi00 0:86b964b67dae 88 {
esemi00 0:86b964b67dae 89 volatile USB_INT08U *desc_ptr;
esemi00 0:86b964b67dae 90 USB_INT08U ms_int_found;
esemi00 0:86b964b67dae 91
esemi00 0:86b964b67dae 92
esemi00 0:86b964b67dae 93 desc_ptr = TDBuffer;
esemi00 0:86b964b67dae 94 ms_int_found = 0;
esemi00 0:86b964b67dae 95
esemi00 0:86b964b67dae 96 if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) {
esemi00 0:86b964b67dae 97 return (ERR_BAD_CONFIGURATION);
esemi00 0:86b964b67dae 98 }
esemi00 0:86b964b67dae 99 desc_ptr += desc_ptr[0];
esemi00 0:86b964b67dae 100
esemi00 0:86b964b67dae 101 while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) {
esemi00 0:86b964b67dae 102
esemi00 0:86b964b67dae 103 switch (desc_ptr[1]) {
esemi00 0:86b964b67dae 104
esemi00 0:86b964b67dae 105 case USB_DESCRIPTOR_TYPE_INTERFACE: /* If it is an interface descriptor */
esemi00 0:86b964b67dae 106 if (desc_ptr[5] == MASS_STORAGE_CLASS && /* check if the class is mass storage */
esemi00 0:86b964b67dae 107 desc_ptr[6] == MASS_STORAGE_SUBCLASS_SCSI && /* check if the subclass is SCSI */
esemi00 0:86b964b67dae 108 desc_ptr[7] == MASS_STORAGE_PROTOCOL_BO) { /* check if the protocol is Bulk only */
esemi00 0:86b964b67dae 109 ms_int_found = 1;
esemi00 0:86b964b67dae 110 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
esemi00 0:86b964b67dae 111 }
esemi00 0:86b964b67dae 112 break;
esemi00 0:86b964b67dae 113
esemi00 0:86b964b67dae 114 case USB_DESCRIPTOR_TYPE_ENDPOINT: /* If it is an endpoint descriptor */
esemi00 0:86b964b67dae 115 if ((desc_ptr[3] & 0x03) == 0x02) { /* If it is Bulk endpoint */
esemi00 0:86b964b67dae 116 if (desc_ptr[2] & 0x80) { /* If it is In endpoint */
esemi00 0:86b964b67dae 117 EDBulkIn->Control = 1 | /* USB address */
esemi00 0:86b964b67dae 118 ((desc_ptr[2] & 0x7F) << 7) | /* Endpoint address */
esemi00 0:86b964b67dae 119 (2 << 11) | /* direction */
esemi00 0:86b964b67dae 120 (ReadLE16U(&desc_ptr[4]) << 16); /* MaxPkt Size */
esemi00 0:86b964b67dae 121 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
esemi00 0:86b964b67dae 122 } else { /* If it is Out endpoint */
esemi00 0:86b964b67dae 123 EDBulkOut->Control = 1 | /* USB address */
esemi00 0:86b964b67dae 124 ((desc_ptr[2] & 0x7F) << 7) | /* Endpoint address */
esemi00 0:86b964b67dae 125 (1 << 11) | /* direction */
esemi00 0:86b964b67dae 126 (ReadLE16U(&desc_ptr[4]) << 16); /* MaxPkt Size */
esemi00 0:86b964b67dae 127 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
esemi00 0:86b964b67dae 128 }
esemi00 0:86b964b67dae 129 } else { /* If it is not bulk end point */
esemi00 0:86b964b67dae 130 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
esemi00 0:86b964b67dae 131 }
esemi00 0:86b964b67dae 132 break;
esemi00 0:86b964b67dae 133
esemi00 0:86b964b67dae 134 default: /* If the descriptor is neither interface nor endpoint */
esemi00 0:86b964b67dae 135 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
esemi00 0:86b964b67dae 136 break;
esemi00 0:86b964b67dae 137 }
esemi00 0:86b964b67dae 138 }
esemi00 0:86b964b67dae 139 if (ms_int_found) {
esemi00 0:86b964b67dae 140 PRINT_Log("Mass Storage device connected\n");
esemi00 0:86b964b67dae 141 return (OK);
esemi00 0:86b964b67dae 142 } else {
esemi00 0:86b964b67dae 143 PRINT_Log("Not a Mass Storage device\n");
esemi00 0:86b964b67dae 144 return (ERR_NO_MS_INTERFACE);
esemi00 0:86b964b67dae 145 }
esemi00 0:86b964b67dae 146 }
esemi00 0:86b964b67dae 147
esemi00 0:86b964b67dae 148 /*
esemi00 0:86b964b67dae 149 **************************************************************************************************************
esemi00 0:86b964b67dae 150 * GET MAXIMUM LOGICAL UNIT
esemi00 0:86b964b67dae 151 *
esemi00 0:86b964b67dae 152 * Description: This function returns the maximum logical unit from the device
esemi00 0:86b964b67dae 153 *
esemi00 0:86b964b67dae 154 * Arguments : None
esemi00 0:86b964b67dae 155 *
esemi00 0:86b964b67dae 156 * Returns : OK if Success
esemi00 0:86b964b67dae 157 * ERR_INVALID_BOOTSIG if Failed
esemi00 0:86b964b67dae 158 *
esemi00 0:86b964b67dae 159 **************************************************************************************************************
esemi00 0:86b964b67dae 160 */
esemi00 0:86b964b67dae 161
esemi00 0:86b964b67dae 162 USB_INT32S MS_GetMaxLUN (void)
esemi00 0:86b964b67dae 163 {
esemi00 0:86b964b67dae 164 USB_INT32S rc;
esemi00 0:86b964b67dae 165
esemi00 0:86b964b67dae 166
esemi00 0:86b964b67dae 167 rc = Host_CtrlRecv(USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE,
esemi00 0:86b964b67dae 168 MS_GET_MAX_LUN_REQ,
esemi00 0:86b964b67dae 169 0,
esemi00 0:86b964b67dae 170 0,
esemi00 0:86b964b67dae 171 1,
esemi00 0:86b964b67dae 172 TDBuffer);
esemi00 0:86b964b67dae 173 return (rc);
esemi00 0:86b964b67dae 174 }
esemi00 0:86b964b67dae 175
esemi00 0:86b964b67dae 176 /*
esemi00 0:86b964b67dae 177 **************************************************************************************************************
esemi00 0:86b964b67dae 178 * GET SENSE INFORMATION
esemi00 0:86b964b67dae 179 *
esemi00 0:86b964b67dae 180 * Description: This function is used to get sense information from the device
esemi00 0:86b964b67dae 181 *
esemi00 0:86b964b67dae 182 * Arguments : None
esemi00 0:86b964b67dae 183 *
esemi00 0:86b964b67dae 184 * Returns : OK if Success
esemi00 0:86b964b67dae 185 * ERROR if Failed
esemi00 0:86b964b67dae 186 *
esemi00 0:86b964b67dae 187 **************************************************************************************************************
esemi00 0:86b964b67dae 188 */
esemi00 0:86b964b67dae 189
esemi00 0:86b964b67dae 190 USB_INT32S MS_GetSenseInfo (void)
esemi00 0:86b964b67dae 191 {
esemi00 0:86b964b67dae 192 USB_INT32S rc;
esemi00 0:86b964b67dae 193
esemi00 0:86b964b67dae 194
esemi00 0:86b964b67dae 195 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_REQUEST_SENSE, 6);
esemi00 0:86b964b67dae 196 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
esemi00 0:86b964b67dae 197 if (rc == OK) {
esemi00 0:86b964b67dae 198 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 18);
esemi00 0:86b964b67dae 199 if (rc == OK) {
esemi00 0:86b964b67dae 200 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
esemi00 0:86b964b67dae 201 if (rc == OK) {
esemi00 0:86b964b67dae 202 if (TDBuffer[12] != 0) {
esemi00 0:86b964b67dae 203 rc = ERR_MS_CMD_FAILED;
esemi00 0:86b964b67dae 204 }
esemi00 0:86b964b67dae 205 }
esemi00 0:86b964b67dae 206 }
esemi00 0:86b964b67dae 207 }
esemi00 0:86b964b67dae 208 return (rc);
esemi00 0:86b964b67dae 209 }
esemi00 0:86b964b67dae 210
esemi00 0:86b964b67dae 211 /*
esemi00 0:86b964b67dae 212 **************************************************************************************************************
esemi00 0:86b964b67dae 213 * TEST UNIT READY
esemi00 0:86b964b67dae 214 *
esemi00 0:86b964b67dae 215 * Description: This function is used to test whether the unit is ready or not
esemi00 0:86b964b67dae 216 *
esemi00 0:86b964b67dae 217 * Arguments : None
esemi00 0:86b964b67dae 218 *
esemi00 0:86b964b67dae 219 * Returns : OK if Success
esemi00 0:86b964b67dae 220 * ERROR if Failed
esemi00 0:86b964b67dae 221 *
esemi00 0:86b964b67dae 222 **************************************************************************************************************
esemi00 0:86b964b67dae 223 */
esemi00 0:86b964b67dae 224
esemi00 0:86b964b67dae 225 USB_INT32S MS_TestUnitReady (void)
esemi00 0:86b964b67dae 226 {
esemi00 0:86b964b67dae 227 USB_INT32S rc;
esemi00 0:86b964b67dae 228
esemi00 0:86b964b67dae 229
esemi00 0:86b964b67dae 230 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_NONE, SCSI_CMD_TEST_UNIT_READY, 6);
esemi00 0:86b964b67dae 231 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
esemi00 0:86b964b67dae 232 if (rc == OK) {
esemi00 0:86b964b67dae 233 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
esemi00 0:86b964b67dae 234 if (rc == OK) {
esemi00 0:86b964b67dae 235 if (TDBuffer[12] != 0) {
esemi00 0:86b964b67dae 236 rc = ERR_MS_CMD_FAILED;
esemi00 0:86b964b67dae 237 }
esemi00 0:86b964b67dae 238 }
esemi00 0:86b964b67dae 239 }
esemi00 0:86b964b67dae 240 return (rc);
esemi00 0:86b964b67dae 241 }
esemi00 0:86b964b67dae 242
esemi00 0:86b964b67dae 243 /*
esemi00 0:86b964b67dae 244 **************************************************************************************************************
esemi00 0:86b964b67dae 245 * READ CAPACITY
esemi00 0:86b964b67dae 246 *
esemi00 0:86b964b67dae 247 * Description: This function is used to read the capacity of the mass storage device
esemi00 0:86b964b67dae 248 *
esemi00 0:86b964b67dae 249 * Arguments : None
esemi00 0:86b964b67dae 250 *
esemi00 0:86b964b67dae 251 * Returns : OK if Success
esemi00 0:86b964b67dae 252 * ERROR if Failed
esemi00 0:86b964b67dae 253 *
esemi00 0:86b964b67dae 254 **************************************************************************************************************
esemi00 0:86b964b67dae 255 */
esemi00 0:86b964b67dae 256
esemi00 0:86b964b67dae 257 USB_INT32S MS_ReadCapacity (USB_INT32U *numBlks, USB_INT32U *blkSize)
esemi00 0:86b964b67dae 258 {
esemi00 0:86b964b67dae 259 USB_INT32S rc;
esemi00 0:86b964b67dae 260
esemi00 0:86b964b67dae 261
esemi00 0:86b964b67dae 262 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_READ_CAPACITY, 10);
esemi00 0:86b964b67dae 263 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
esemi00 0:86b964b67dae 264 if (rc == OK) {
esemi00 0:86b964b67dae 265 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 8);
esemi00 0:86b964b67dae 266 if (rc == OK) {
esemi00 0:86b964b67dae 267 if (numBlks)
esemi00 0:86b964b67dae 268 *numBlks = ReadBE32U(&TDBuffer[0]);
esemi00 0:86b964b67dae 269 if (blkSize)
esemi00 0:86b964b67dae 270 *blkSize = ReadBE32U(&TDBuffer[4]);
esemi00 0:86b964b67dae 271 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
esemi00 0:86b964b67dae 272 if (rc == OK) {
esemi00 0:86b964b67dae 273 if (TDBuffer[12] != 0) {
esemi00 0:86b964b67dae 274 rc = ERR_MS_CMD_FAILED;
esemi00 0:86b964b67dae 275 }
esemi00 0:86b964b67dae 276 }
esemi00 0:86b964b67dae 277 }
esemi00 0:86b964b67dae 278 }
esemi00 0:86b964b67dae 279 return (rc);
esemi00 0:86b964b67dae 280 }
esemi00 0:86b964b67dae 281
esemi00 0:86b964b67dae 282
esemi00 0:86b964b67dae 283
esemi00 0:86b964b67dae 284 USB_INT32S MS_Inquire (USB_INT08U *response)
esemi00 0:86b964b67dae 285 {
esemi00 0:86b964b67dae 286 USB_INT32S rc;
esemi00 0:86b964b67dae 287 USB_INT32U i;
esemi00 0:86b964b67dae 288
esemi00 0:86b964b67dae 289 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_INQUIRY, 6);
esemi00 0:86b964b67dae 290 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
esemi00 0:86b964b67dae 291 if (rc == OK) {
esemi00 0:86b964b67dae 292 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, INQUIRY_LENGTH);
esemi00 0:86b964b67dae 293 if (rc == OK) {
esemi00 0:86b964b67dae 294 if (response) {
esemi00 0:86b964b67dae 295 for ( i = 0; i < INQUIRY_LENGTH; i++ )
esemi00 0:86b964b67dae 296 *response++ = *TDBuffer++;
esemi00 0:86b964b67dae 297 #if 0
esemi00 0:86b964b67dae 298 MemCpy (response, TDBuffer, INQUIRY_LENGTH);
esemi00 0:86b964b67dae 299 StrNullTrailingSpace (response->vendorID, SCSI_INQUIRY_VENDORCHARS);
esemi00 0:86b964b67dae 300 StrNullTrailingSpace (response->productID, SCSI_INQUIRY_PRODUCTCHARS);
esemi00 0:86b964b67dae 301 StrNullTrailingSpace (response->productRev, SCSI_INQUIRY_REVCHARS);
esemi00 0:86b964b67dae 302 #endif
esemi00 0:86b964b67dae 303 }
esemi00 0:86b964b67dae 304 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
esemi00 0:86b964b67dae 305 if (rc == OK) {
esemi00 0:86b964b67dae 306 if (TDBuffer[12] != 0) { // bCSWStatus byte
esemi00 0:86b964b67dae 307 rc = ERR_MS_CMD_FAILED;
esemi00 0:86b964b67dae 308 }
esemi00 0:86b964b67dae 309 }
esemi00 0:86b964b67dae 310 }
esemi00 0:86b964b67dae 311 }
esemi00 0:86b964b67dae 312 return (rc);
esemi00 0:86b964b67dae 313 }
esemi00 0:86b964b67dae 314
esemi00 0:86b964b67dae 315 /*
esemi00 0:86b964b67dae 316 **************************************************************************************************************
esemi00 0:86b964b67dae 317 * RECEIVE THE BULK DATA
esemi00 0:86b964b67dae 318 *
esemi00 0:86b964b67dae 319 * Description: This function is used to receive the bulk data
esemi00 0:86b964b67dae 320 *
esemi00 0:86b964b67dae 321 * Arguments : None
esemi00 0:86b964b67dae 322 *
esemi00 0:86b964b67dae 323 * Returns : OK if Success
esemi00 0:86b964b67dae 324 * ERR_INVALID_BOOTSIG if Failed
esemi00 0:86b964b67dae 325 *
esemi00 0:86b964b67dae 326 **************************************************************************************************************
esemi00 0:86b964b67dae 327 */
esemi00 0:86b964b67dae 328
esemi00 0:86b964b67dae 329 USB_INT32S MS_BulkRecv ( USB_INT32U block_number,
esemi00 0:86b964b67dae 330 USB_INT16U num_blocks,
esemi00 0:86b964b67dae 331 volatile USB_INT08U *user_buffer)
esemi00 0:86b964b67dae 332 {
esemi00 0:86b964b67dae 333 USB_INT32S rc;
esemi00 0:86b964b67dae 334 int i;
esemi00 0:86b964b67dae 335 volatile USB_INT08U *c = user_buffer;
esemi00 0:86b964b67dae 336 for (i=0;i<MS_BlkSize*num_blocks;i++)
esemi00 0:86b964b67dae 337 *c++ = 0;
esemi00 0:86b964b67dae 338
esemi00 0:86b964b67dae 339
esemi00 0:86b964b67dae 340 Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_IN, SCSI_CMD_READ_10, 10);
esemi00 0:86b964b67dae 341
esemi00 0:86b964b67dae 342 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
esemi00 0:86b964b67dae 343 if (rc == OK) {
esemi00 0:86b964b67dae 344 rc = Host_ProcessTD(EDBulkIn, TD_IN, user_buffer, MS_BlkSize * num_blocks);
esemi00 0:86b964b67dae 345 if (rc == OK) {
esemi00 0:86b964b67dae 346 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
esemi00 0:86b964b67dae 347 if (rc == OK) {
esemi00 0:86b964b67dae 348 if (TDBuffer[12] != 0) {
esemi00 0:86b964b67dae 349 rc = ERR_MS_CMD_FAILED;
esemi00 0:86b964b67dae 350 }
esemi00 0:86b964b67dae 351 }
esemi00 0:86b964b67dae 352 }
esemi00 0:86b964b67dae 353 }
esemi00 0:86b964b67dae 354 return (rc);
esemi00 0:86b964b67dae 355 }
esemi00 0:86b964b67dae 356
esemi00 0:86b964b67dae 357 /*
esemi00 0:86b964b67dae 358 **************************************************************************************************************
esemi00 0:86b964b67dae 359 * SEND BULK DATA
esemi00 0:86b964b67dae 360 *
esemi00 0:86b964b67dae 361 * Description: This function is used to send the bulk data
esemi00 0:86b964b67dae 362 *
esemi00 0:86b964b67dae 363 * Arguments : None
esemi00 0:86b964b67dae 364 *
esemi00 0:86b964b67dae 365 * Returns : OK if Success
esemi00 0:86b964b67dae 366 * ERR_INVALID_BOOTSIG if Failed
esemi00 0:86b964b67dae 367 *
esemi00 0:86b964b67dae 368 **************************************************************************************************************
esemi00 0:86b964b67dae 369 */
esemi00 0:86b964b67dae 370
esemi00 0:86b964b67dae 371 USB_INT32S MS_BulkSend ( USB_INT32U block_number,
esemi00 0:86b964b67dae 372 USB_INT16U num_blocks,
esemi00 0:86b964b67dae 373 volatile USB_INT08U *user_buffer)
esemi00 0:86b964b67dae 374 {
esemi00 0:86b964b67dae 375 USB_INT32S rc;
esemi00 0:86b964b67dae 376
esemi00 0:86b964b67dae 377
esemi00 0:86b964b67dae 378 Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_OUT, SCSI_CMD_WRITE_10, 10);
esemi00 0:86b964b67dae 379
esemi00 0:86b964b67dae 380 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
esemi00 0:86b964b67dae 381 if (rc == OK) {
esemi00 0:86b964b67dae 382 rc = Host_ProcessTD(EDBulkOut, TD_OUT, user_buffer, MS_BlkSize * num_blocks);
esemi00 0:86b964b67dae 383 if (rc == OK) {
esemi00 0:86b964b67dae 384 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
esemi00 0:86b964b67dae 385 if (rc == OK) {
esemi00 0:86b964b67dae 386 if (TDBuffer[12] != 0) {
esemi00 0:86b964b67dae 387 rc = ERR_MS_CMD_FAILED;
esemi00 0:86b964b67dae 388 }
esemi00 0:86b964b67dae 389 }
esemi00 0:86b964b67dae 390 }
esemi00 0:86b964b67dae 391 }
esemi00 0:86b964b67dae 392 return (rc);
esemi00 0:86b964b67dae 393 }
esemi00 0:86b964b67dae 394
esemi00 0:86b964b67dae 395 /*
esemi00 0:86b964b67dae 396 **************************************************************************************************************
esemi00 0:86b964b67dae 397 * FILL MASS STORAGE COMMAND
esemi00 0:86b964b67dae 398 *
esemi00 0:86b964b67dae 399 * Description: This function is used to fill the mass storage command
esemi00 0:86b964b67dae 400 *
esemi00 0:86b964b67dae 401 * Arguments : None
esemi00 0:86b964b67dae 402 *
esemi00 0:86b964b67dae 403 * Returns : OK if Success
esemi00 0:86b964b67dae 404 * ERR_INVALID_BOOTSIG if Failed
esemi00 0:86b964b67dae 405 *
esemi00 0:86b964b67dae 406 **************************************************************************************************************
esemi00 0:86b964b67dae 407 */
esemi00 0:86b964b67dae 408
esemi00 0:86b964b67dae 409 void Fill_MSCommand (USB_INT32U block_number,
esemi00 0:86b964b67dae 410 USB_INT32U block_size,
esemi00 0:86b964b67dae 411 USB_INT16U num_blocks,
esemi00 0:86b964b67dae 412 MS_DATA_DIR direction,
esemi00 0:86b964b67dae 413 USB_INT08U scsi_cmd,
esemi00 0:86b964b67dae 414 USB_INT08U scsi_cmd_len)
esemi00 0:86b964b67dae 415 {
esemi00 0:86b964b67dae 416 USB_INT32U data_len;
esemi00 0:86b964b67dae 417 static USB_INT32U tag_cnt = 0;
esemi00 0:86b964b67dae 418 USB_INT32U cnt;
esemi00 0:86b964b67dae 419
esemi00 0:86b964b67dae 420
esemi00 0:86b964b67dae 421 for (cnt = 0; cnt < CBW_SIZE; cnt++) {
esemi00 0:86b964b67dae 422 TDBuffer[cnt] = 0;
esemi00 0:86b964b67dae 423 }
esemi00 0:86b964b67dae 424 switch(scsi_cmd) {
esemi00 0:86b964b67dae 425
esemi00 0:86b964b67dae 426 case SCSI_CMD_TEST_UNIT_READY:
esemi00 0:86b964b67dae 427 data_len = 0;
esemi00 0:86b964b67dae 428 break;
esemi00 0:86b964b67dae 429 case SCSI_CMD_READ_CAPACITY:
esemi00 0:86b964b67dae 430 data_len = 8;
esemi00 0:86b964b67dae 431 break;
esemi00 0:86b964b67dae 432 case SCSI_CMD_REQUEST_SENSE:
esemi00 0:86b964b67dae 433 data_len = 18;
esemi00 0:86b964b67dae 434 break;
esemi00 0:86b964b67dae 435 case SCSI_CMD_INQUIRY:
esemi00 0:86b964b67dae 436 data_len = 36;
esemi00 0:86b964b67dae 437 break;
esemi00 0:86b964b67dae 438 default:
esemi00 0:86b964b67dae 439 data_len = block_size * num_blocks;
esemi00 0:86b964b67dae 440 break;
esemi00 0:86b964b67dae 441 }
esemi00 0:86b964b67dae 442 WriteLE32U(TDBuffer, CBW_SIGNATURE);
esemi00 0:86b964b67dae 443 WriteLE32U(&TDBuffer[4], tag_cnt);
esemi00 0:86b964b67dae 444 WriteLE32U(&TDBuffer[8], data_len);
esemi00 0:86b964b67dae 445 TDBuffer[12] = (direction == MS_DATA_DIR_NONE) ? 0 : direction;
esemi00 0:86b964b67dae 446 TDBuffer[14] = scsi_cmd_len; /* Length of the CBW */
esemi00 0:86b964b67dae 447 TDBuffer[15] = scsi_cmd;
esemi00 0:86b964b67dae 448 if ((scsi_cmd == SCSI_CMD_REQUEST_SENSE)
esemi00 0:86b964b67dae 449 || (scsi_cmd == SCSI_CMD_INQUIRY)) {
esemi00 0:86b964b67dae 450 TDBuffer[19] = (USB_INT08U)data_len;
esemi00 0:86b964b67dae 451 } else {
esemi00 0:86b964b67dae 452 WriteBE32U(&TDBuffer[17], block_number);
esemi00 0:86b964b67dae 453 }
esemi00 0:86b964b67dae 454 WriteBE16U(&TDBuffer[22], num_blocks);
esemi00 0:86b964b67dae 455 }