MP3 Player without external hardware MP3 Player without external hardware. A software based MP3 player based on a modified version of libmad. Mono output (at the moment) via AnalogOut. Files are read from an USB drive. This is a demo program, it plays only one file at the moment. Documentation is in "main.cpp" and "config.h"

Dependencies:   mbed

Committer:
Gruenfrosch
Date:
Fri Nov 26 12:18:30 2010 +0000
Revision:
0:7627c79db971
First Version

Who changed what in which revision?

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