CodeShare

Dependencies:   FatFileSystem mbed

Fork of 4180_Lab2_USB by Jeremy Cai

Committer:
jeremycai3721
Date:
Sun Sep 25 19:04:39 2016 +0000
Revision:
1:fca955be2a5b
Parent:
0:4e756c4c88a7
CodeShare

Who changed what in which revision?

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