Pendrive to sd card data transfer coding

Dependencies:   FatFileSystem TextLCD mbed

Fork of MSCUsbHost by gavin beardall

Committer:
sathguru
Date:
Thu Apr 16 05:12:20 2015 +0000
Revision:
1:77e50c06ea01
Parent:
0:e6a539e59b52
Pendrive to sd card data transfer coding

Who changed what in which revision?

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