KIT Solar Car Project / Mbed 2 deprecated BMS_6804_pb

Dependencies:   mbed INA226

Committer:
takuma1
Date:
Thu Apr 08 10:04:55 2021 +0000
Revision:
5:f07de56debf3
210408_BMS_v1;

Who changed what in which revision?

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