Racelogic / Mbed 2 deprecated VIPS_LTC_RAW_IMU

Dependencies:   BufferedSerial FatFileSystemCpp mbed

Committer:
AndyA
Date:
Thu Feb 18 18:15:48 2021 +0000
Revision:
9:7214e3c3e5f8
massive ripup and redesign; currently has file system build errors

Who changed what in which revision?

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