Publish code

Dependencies:   FatFileSystem RPG TextLCD mbed wave_player

Committer:
YongChingTee
Date:
Wed Mar 06 00:21:35 2013 +0000
Revision:
1:ebb980d204ae
Parent:
0:ad48675db853
publish

Who changed what in which revision?

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