This program plays an internet radio audio stream like Shoutcast.

Dependencies:   EthernetNetIf mbed HTTPClient

Committer:
parik
Date:
Tue Mar 01 06:22:50 2011 +0000
Revision:
0:37da71b87d96

        

Who changed what in which revision?

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