This program displays heart rate and time between heart beats on LCD, prints it to a USB serial port, print it to a bluetooth serial port and store it on a USB mass storage device. The program has two interrupt routines: 1.Every 1ms a counter is increased with one, 2. On every heart beat the counter is value copied. In the main loop the beats per minute are calculated. Ext.Modules:- Polar RMCM-01 heart rate module connected to pin8. - 2x16 LCD - a RF-BT0417CB bluetooth serial device connected to p27 and p28 - an USB mass storage device

Dependencies:   TextLCD mbed

Committer:
jrsikken
Date:
Tue Jan 04 21:33:59 2011 +0000
Revision:
2:e660e68a91fa
Parent:
1:8b001f936bb0
Now the heart rate is also send over a serial port to a bluetooth device.

Who changed what in which revision?

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