Suspended plotter for the skaperfest

Dependencies:   mbed HTTPServer EthernetNetIf FatFileSystemCpp

Committer:
rengro01
Date:
Mon Aug 22 10:24:23 2022 +0000
Revision:
0:602ff2b2d41c
skaperfest

Who changed what in which revision?

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