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