These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!

Committer:
frank26080115
Date:
Sun Mar 20 05:38:56 2011 +0000
Revision:
0:bf7b9fba3924

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frank26080115 0:bf7b9fba3924 1 /*----------------------------------------------------------------------------
frank26080115 0:bf7b9fba3924 2 * U S B - K e r n e l
frank26080115 0:bf7b9fba3924 3 *----------------------------------------------------------------------------
frank26080115 0:bf7b9fba3924 4 * Name: MSCUSER.C
frank26080115 0:bf7b9fba3924 5 * Purpose: Mass Storage Class Custom User Module
frank26080115 0:bf7b9fba3924 6 * Version: V1.10
frank26080115 0:bf7b9fba3924 7 *----------------------------------------------------------------------------
frank26080115 0:bf7b9fba3924 8 * This software is supplied "AS IS" without any warranties, express,
frank26080115 0:bf7b9fba3924 9 * implied or statutory, including but not limited to the implied
frank26080115 0:bf7b9fba3924 10 * warranties of fitness for purpose, satisfactory quality and
frank26080115 0:bf7b9fba3924 11 * noninfringement. Keil extends you a royalty-free right to reproduce
frank26080115 0:bf7b9fba3924 12 * and distribute executable files created using this software for use
frank26080115 0:bf7b9fba3924 13 * on NXP Semiconductors LPC family microcontroller devices only. Nothing
frank26080115 0:bf7b9fba3924 14 * else gives you the right to use this software.
frank26080115 0:bf7b9fba3924 15 *
frank26080115 0:bf7b9fba3924 16 * Copyright (c) 2005-2009 Keil Software.
frank26080115 0:bf7b9fba3924 17 *---------------------------------------------------------------------------*/
frank26080115 0:bf7b9fba3924 18
frank26080115 0:bf7b9fba3924 19 #include "LPC17xx.h"
frank26080115 0:bf7b9fba3924 20
frank26080115 0:bf7b9fba3924 21 #include "lpc_types.h"
frank26080115 0:bf7b9fba3924 22
frank26080115 0:bf7b9fba3924 23 #include "usb.h"
frank26080115 0:bf7b9fba3924 24 #include "msc.h"
frank26080115 0:bf7b9fba3924 25 #include "usbcfg.h"
frank26080115 0:bf7b9fba3924 26 #include "usbhw.h"
frank26080115 0:bf7b9fba3924 27 #include "usbcore.h"
frank26080115 0:bf7b9fba3924 28 #include "mscuser.h"
frank26080115 0:bf7b9fba3924 29
frank26080115 0:bf7b9fba3924 30 #include "memory.h"
frank26080115 0:bf7b9fba3924 31
frank26080115 0:bf7b9fba3924 32
frank26080115 0:bf7b9fba3924 33 uint8_t Memory[MSC_MemorySize]; /* MSC RAM */
frank26080115 0:bf7b9fba3924 34
frank26080115 0:bf7b9fba3924 35 uint32_t MemOK; /* Memory OK */
frank26080115 0:bf7b9fba3924 36
frank26080115 0:bf7b9fba3924 37 uint32_t Offset; /* R/W Offset */
frank26080115 0:bf7b9fba3924 38 uint32_t Length; /* R/W Length */
frank26080115 0:bf7b9fba3924 39
frank26080115 0:bf7b9fba3924 40 uint8_t BulkStage; /* Bulk Stage */
frank26080115 0:bf7b9fba3924 41
frank26080115 0:bf7b9fba3924 42 uint8_t BulkBuf[MSC_MAX_PACKET]; /* Bulk In/Out Buffer */
frank26080115 0:bf7b9fba3924 43 uint8_t BulkLen; /* Bulk In/Out Length */
frank26080115 0:bf7b9fba3924 44
frank26080115 0:bf7b9fba3924 45 MSC_CBW CBW; /* Command Block Wrapper */
frank26080115 0:bf7b9fba3924 46 MSC_CSW CSW; /* Command Status Wrapper */
frank26080115 0:bf7b9fba3924 47
frank26080115 0:bf7b9fba3924 48
frank26080115 0:bf7b9fba3924 49 /*
frank26080115 0:bf7b9fba3924 50 * MSC Mass Storage Reset Request Callback
frank26080115 0:bf7b9fba3924 51 * Called automatically on Mass Storage Reset Request
frank26080115 0:bf7b9fba3924 52 * Parameters: None (global SetupPacket and EP0Buf)
frank26080115 0:bf7b9fba3924 53 * Return Value: TRUE - Success, FALSE - Error
frank26080115 0:bf7b9fba3924 54 */
frank26080115 0:bf7b9fba3924 55
frank26080115 0:bf7b9fba3924 56 uint32_t MSC_Reset (void) {
frank26080115 0:bf7b9fba3924 57
frank26080115 0:bf7b9fba3924 58 BulkStage = MSC_BS_CBW;
frank26080115 0:bf7b9fba3924 59 return (TRUE);
frank26080115 0:bf7b9fba3924 60 }
frank26080115 0:bf7b9fba3924 61
frank26080115 0:bf7b9fba3924 62
frank26080115 0:bf7b9fba3924 63 /*
frank26080115 0:bf7b9fba3924 64 * MSC Get Max LUN Request Callback
frank26080115 0:bf7b9fba3924 65 * Called automatically on Get Max LUN Request
frank26080115 0:bf7b9fba3924 66 * Parameters: None (global SetupPacket and EP0Buf)
frank26080115 0:bf7b9fba3924 67 * Return Value: TRUE - Success, FALSE - Error
frank26080115 0:bf7b9fba3924 68 */
frank26080115 0:bf7b9fba3924 69
frank26080115 0:bf7b9fba3924 70 uint32_t MSC_GetMaxLUN (void) {
frank26080115 0:bf7b9fba3924 71
frank26080115 0:bf7b9fba3924 72 EP0Buf[0] = 0; /* No LUN associated with this device */
frank26080115 0:bf7b9fba3924 73 return (TRUE);
frank26080115 0:bf7b9fba3924 74 }
frank26080115 0:bf7b9fba3924 75
frank26080115 0:bf7b9fba3924 76
frank26080115 0:bf7b9fba3924 77 /*
frank26080115 0:bf7b9fba3924 78 * MSC Memory Read Callback
frank26080115 0:bf7b9fba3924 79 * Called automatically on Memory Read Event
frank26080115 0:bf7b9fba3924 80 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 81 * Return Value: None
frank26080115 0:bf7b9fba3924 82 */
frank26080115 0:bf7b9fba3924 83
frank26080115 0:bf7b9fba3924 84 void MSC_MemoryRead (void) {
frank26080115 0:bf7b9fba3924 85 uint32_t n;
frank26080115 0:bf7b9fba3924 86
frank26080115 0:bf7b9fba3924 87 if (Length > MSC_MAX_PACKET) {
frank26080115 0:bf7b9fba3924 88 n = MSC_MAX_PACKET;
frank26080115 0:bf7b9fba3924 89 } else {
frank26080115 0:bf7b9fba3924 90 n = Length;
frank26080115 0:bf7b9fba3924 91 }
frank26080115 0:bf7b9fba3924 92
frank26080115 0:bf7b9fba3924 93 if ((Offset + n) > MSC_MemorySize) {
frank26080115 0:bf7b9fba3924 94 n = MSC_MemorySize - Offset;
frank26080115 0:bf7b9fba3924 95 BulkStage = MSC_BS_DATA_IN_LAST_STALL;
frank26080115 0:bf7b9fba3924 96 }
frank26080115 0:bf7b9fba3924 97
frank26080115 0:bf7b9fba3924 98 USB_WriteEP(MSC_EP_IN, &Memory[Offset], n);
frank26080115 0:bf7b9fba3924 99 Offset += n;
frank26080115 0:bf7b9fba3924 100 Length -= n;
frank26080115 0:bf7b9fba3924 101
frank26080115 0:bf7b9fba3924 102 CSW.dDataResidue -= n;
frank26080115 0:bf7b9fba3924 103
frank26080115 0:bf7b9fba3924 104 if (Length == 0) {
frank26080115 0:bf7b9fba3924 105 BulkStage = MSC_BS_DATA_IN_LAST;
frank26080115 0:bf7b9fba3924 106 }
frank26080115 0:bf7b9fba3924 107
frank26080115 0:bf7b9fba3924 108 if (BulkStage != MSC_BS_DATA_IN) {
frank26080115 0:bf7b9fba3924 109 CSW.bStatus = CSW_CMD_PASSED;
frank26080115 0:bf7b9fba3924 110 }
frank26080115 0:bf7b9fba3924 111 }
frank26080115 0:bf7b9fba3924 112
frank26080115 0:bf7b9fba3924 113
frank26080115 0:bf7b9fba3924 114 /*
frank26080115 0:bf7b9fba3924 115 * MSC Memory Write Callback
frank26080115 0:bf7b9fba3924 116 * Called automatically on Memory Write Event
frank26080115 0:bf7b9fba3924 117 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 118 * Return Value: None
frank26080115 0:bf7b9fba3924 119 */
frank26080115 0:bf7b9fba3924 120
frank26080115 0:bf7b9fba3924 121 void MSC_MemoryWrite (void) {
frank26080115 0:bf7b9fba3924 122 uint32_t n;
frank26080115 0:bf7b9fba3924 123
frank26080115 0:bf7b9fba3924 124 if ((Offset + BulkLen) > MSC_MemorySize) {
frank26080115 0:bf7b9fba3924 125 BulkLen = MSC_MemorySize - Offset;
frank26080115 0:bf7b9fba3924 126 BulkStage = MSC_BS_CSW;
frank26080115 0:bf7b9fba3924 127 USB_SetStallEP(MSC_EP_OUT);
frank26080115 0:bf7b9fba3924 128 }
frank26080115 0:bf7b9fba3924 129
frank26080115 0:bf7b9fba3924 130 for (n = 0; n < BulkLen; n++) {
frank26080115 0:bf7b9fba3924 131 Memory[Offset + n] = BulkBuf[n];
frank26080115 0:bf7b9fba3924 132 }
frank26080115 0:bf7b9fba3924 133
frank26080115 0:bf7b9fba3924 134 Offset += BulkLen;
frank26080115 0:bf7b9fba3924 135 Length -= BulkLen;
frank26080115 0:bf7b9fba3924 136
frank26080115 0:bf7b9fba3924 137 CSW.dDataResidue -= BulkLen;
frank26080115 0:bf7b9fba3924 138
frank26080115 0:bf7b9fba3924 139 if ((Length == 0) || (BulkStage == MSC_BS_CSW)) {
frank26080115 0:bf7b9fba3924 140 CSW.bStatus = CSW_CMD_PASSED;
frank26080115 0:bf7b9fba3924 141 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 142 }
frank26080115 0:bf7b9fba3924 143 }
frank26080115 0:bf7b9fba3924 144
frank26080115 0:bf7b9fba3924 145
frank26080115 0:bf7b9fba3924 146 /*
frank26080115 0:bf7b9fba3924 147 * MSC Memory Verify Callback
frank26080115 0:bf7b9fba3924 148 * Called automatically on Memory Verify Event
frank26080115 0:bf7b9fba3924 149 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 150 * Return Value: None
frank26080115 0:bf7b9fba3924 151 */
frank26080115 0:bf7b9fba3924 152
frank26080115 0:bf7b9fba3924 153 void MSC_MemoryVerify (void) {
frank26080115 0:bf7b9fba3924 154 uint32_t n;
frank26080115 0:bf7b9fba3924 155
frank26080115 0:bf7b9fba3924 156 if ((Offset + BulkLen) > MSC_MemorySize) {
frank26080115 0:bf7b9fba3924 157 BulkLen = MSC_MemorySize - Offset;
frank26080115 0:bf7b9fba3924 158 BulkStage = MSC_BS_CSW;
frank26080115 0:bf7b9fba3924 159 USB_SetStallEP(MSC_EP_OUT);
frank26080115 0:bf7b9fba3924 160 }
frank26080115 0:bf7b9fba3924 161
frank26080115 0:bf7b9fba3924 162 for (n = 0; n < BulkLen; n++) {
frank26080115 0:bf7b9fba3924 163 if (Memory[Offset + n] != BulkBuf[n]) {
frank26080115 0:bf7b9fba3924 164 MemOK = FALSE;
frank26080115 0:bf7b9fba3924 165 break;
frank26080115 0:bf7b9fba3924 166 }
frank26080115 0:bf7b9fba3924 167 }
frank26080115 0:bf7b9fba3924 168
frank26080115 0:bf7b9fba3924 169 Offset += BulkLen;
frank26080115 0:bf7b9fba3924 170 Length -= BulkLen;
frank26080115 0:bf7b9fba3924 171
frank26080115 0:bf7b9fba3924 172 CSW.dDataResidue -= BulkLen;
frank26080115 0:bf7b9fba3924 173
frank26080115 0:bf7b9fba3924 174 if ((Length == 0) || (BulkStage == MSC_BS_CSW)) {
frank26080115 0:bf7b9fba3924 175 CSW.bStatus = (MemOK) ? CSW_CMD_PASSED : CSW_CMD_FAILED;
frank26080115 0:bf7b9fba3924 176 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 177 }
frank26080115 0:bf7b9fba3924 178 }
frank26080115 0:bf7b9fba3924 179
frank26080115 0:bf7b9fba3924 180
frank26080115 0:bf7b9fba3924 181 /*
frank26080115 0:bf7b9fba3924 182 * MSC SCSI Read/Write Setup Callback
frank26080115 0:bf7b9fba3924 183 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 184 * Return Value: TRUE - Success, FALSE - Error
frank26080115 0:bf7b9fba3924 185 */
frank26080115 0:bf7b9fba3924 186
frank26080115 0:bf7b9fba3924 187 uint32_t MSC_RWSetup (void) {
frank26080115 0:bf7b9fba3924 188 uint32_t n;
frank26080115 0:bf7b9fba3924 189
frank26080115 0:bf7b9fba3924 190 /* Logical Block Address of First Block */
frank26080115 0:bf7b9fba3924 191 n = (CBW.CB[2] << 24) |
frank26080115 0:bf7b9fba3924 192 (CBW.CB[3] << 16) |
frank26080115 0:bf7b9fba3924 193 (CBW.CB[4] << 8) |
frank26080115 0:bf7b9fba3924 194 (CBW.CB[5] << 0);
frank26080115 0:bf7b9fba3924 195
frank26080115 0:bf7b9fba3924 196 Offset = n * MSC_BlockSize;
frank26080115 0:bf7b9fba3924 197
frank26080115 0:bf7b9fba3924 198 /* Number of Blocks to transfer */
frank26080115 0:bf7b9fba3924 199 n = (CBW.CB[7] << 8) |
frank26080115 0:bf7b9fba3924 200 (CBW.CB[8] << 0);
frank26080115 0:bf7b9fba3924 201
frank26080115 0:bf7b9fba3924 202 Length = n * MSC_BlockSize;
frank26080115 0:bf7b9fba3924 203
frank26080115 0:bf7b9fba3924 204 if (CBW.dDataLength != Length) {
frank26080115 0:bf7b9fba3924 205 USB_SetStallEP(MSC_EP_IN);
frank26080115 0:bf7b9fba3924 206 USB_SetStallEP(MSC_EP_OUT);
frank26080115 0:bf7b9fba3924 207 CSW.bStatus = CSW_PHASE_ERROR;
frank26080115 0:bf7b9fba3924 208 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 209 return (FALSE);
frank26080115 0:bf7b9fba3924 210 }
frank26080115 0:bf7b9fba3924 211
frank26080115 0:bf7b9fba3924 212 return (TRUE);
frank26080115 0:bf7b9fba3924 213 }
frank26080115 0:bf7b9fba3924 214
frank26080115 0:bf7b9fba3924 215
frank26080115 0:bf7b9fba3924 216 /*
frank26080115 0:bf7b9fba3924 217 * Check Data IN Format
frank26080115 0:bf7b9fba3924 218 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 219 * Return Value: TRUE - Success, FALSE - Error
frank26080115 0:bf7b9fba3924 220 */
frank26080115 0:bf7b9fba3924 221
frank26080115 0:bf7b9fba3924 222 uint32_t DataInFormat (void) {
frank26080115 0:bf7b9fba3924 223
frank26080115 0:bf7b9fba3924 224 if (CBW.dDataLength == 0) {
frank26080115 0:bf7b9fba3924 225 CSW.bStatus = CSW_PHASE_ERROR;
frank26080115 0:bf7b9fba3924 226 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 227 return (FALSE);
frank26080115 0:bf7b9fba3924 228 }
frank26080115 0:bf7b9fba3924 229 if ((CBW.bmFlags & 0x80) == 0) {
frank26080115 0:bf7b9fba3924 230 USB_SetStallEP(MSC_EP_OUT);
frank26080115 0:bf7b9fba3924 231 CSW.bStatus = CSW_PHASE_ERROR;
frank26080115 0:bf7b9fba3924 232 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 233 return (FALSE);
frank26080115 0:bf7b9fba3924 234 }
frank26080115 0:bf7b9fba3924 235 return (TRUE);
frank26080115 0:bf7b9fba3924 236 }
frank26080115 0:bf7b9fba3924 237
frank26080115 0:bf7b9fba3924 238
frank26080115 0:bf7b9fba3924 239 /*
frank26080115 0:bf7b9fba3924 240 * Perform Data IN Transfer
frank26080115 0:bf7b9fba3924 241 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 242 * Return Value: TRUE - Success, FALSE - Error
frank26080115 0:bf7b9fba3924 243 */
frank26080115 0:bf7b9fba3924 244
frank26080115 0:bf7b9fba3924 245 void DataInTransfer (void) {
frank26080115 0:bf7b9fba3924 246
frank26080115 0:bf7b9fba3924 247 if (BulkLen > CBW.dDataLength) {
frank26080115 0:bf7b9fba3924 248 BulkLen = CBW.dDataLength;
frank26080115 0:bf7b9fba3924 249 }
frank26080115 0:bf7b9fba3924 250
frank26080115 0:bf7b9fba3924 251 USB_WriteEP(MSC_EP_IN, BulkBuf, BulkLen);
frank26080115 0:bf7b9fba3924 252 BulkStage = MSC_BS_DATA_IN_LAST;
frank26080115 0:bf7b9fba3924 253
frank26080115 0:bf7b9fba3924 254 CSW.dDataResidue -= BulkLen;
frank26080115 0:bf7b9fba3924 255 CSW.bStatus = CSW_CMD_PASSED;
frank26080115 0:bf7b9fba3924 256 }
frank26080115 0:bf7b9fba3924 257
frank26080115 0:bf7b9fba3924 258
frank26080115 0:bf7b9fba3924 259 /*
frank26080115 0:bf7b9fba3924 260 * MSC SCSI Test Unit Ready Callback
frank26080115 0:bf7b9fba3924 261 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 262 * Return Value: None
frank26080115 0:bf7b9fba3924 263 */
frank26080115 0:bf7b9fba3924 264
frank26080115 0:bf7b9fba3924 265 void MSC_TestUnitReady (void) {
frank26080115 0:bf7b9fba3924 266
frank26080115 0:bf7b9fba3924 267 if (CBW.dDataLength != 0) {
frank26080115 0:bf7b9fba3924 268 if ((CBW.bmFlags & 0x80) != 0) {
frank26080115 0:bf7b9fba3924 269 USB_SetStallEP(MSC_EP_IN);
frank26080115 0:bf7b9fba3924 270 } else {
frank26080115 0:bf7b9fba3924 271 USB_SetStallEP(MSC_EP_OUT);
frank26080115 0:bf7b9fba3924 272 }
frank26080115 0:bf7b9fba3924 273 }
frank26080115 0:bf7b9fba3924 274
frank26080115 0:bf7b9fba3924 275 CSW.bStatus = CSW_CMD_PASSED;
frank26080115 0:bf7b9fba3924 276 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 277 }
frank26080115 0:bf7b9fba3924 278
frank26080115 0:bf7b9fba3924 279
frank26080115 0:bf7b9fba3924 280 /*
frank26080115 0:bf7b9fba3924 281 * MSC SCSI Request Sense Callback
frank26080115 0:bf7b9fba3924 282 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 283 * Return Value: None
frank26080115 0:bf7b9fba3924 284 */
frank26080115 0:bf7b9fba3924 285
frank26080115 0:bf7b9fba3924 286 void MSC_RequestSense (void) {
frank26080115 0:bf7b9fba3924 287
frank26080115 0:bf7b9fba3924 288 if (!DataInFormat()) return;
frank26080115 0:bf7b9fba3924 289
frank26080115 0:bf7b9fba3924 290 BulkBuf[ 0] = 0x70; /* Response Code */
frank26080115 0:bf7b9fba3924 291 BulkBuf[ 1] = 0x00;
frank26080115 0:bf7b9fba3924 292 BulkBuf[ 2] = 0x02; /* Sense Key */
frank26080115 0:bf7b9fba3924 293 BulkBuf[ 3] = 0x00;
frank26080115 0:bf7b9fba3924 294 BulkBuf[ 4] = 0x00;
frank26080115 0:bf7b9fba3924 295 BulkBuf[ 5] = 0x00;
frank26080115 0:bf7b9fba3924 296 BulkBuf[ 6] = 0x00;
frank26080115 0:bf7b9fba3924 297 BulkBuf[ 7] = 0x0A; /* Additional Length */
frank26080115 0:bf7b9fba3924 298 BulkBuf[ 8] = 0x00;
frank26080115 0:bf7b9fba3924 299 BulkBuf[ 9] = 0x00;
frank26080115 0:bf7b9fba3924 300 BulkBuf[10] = 0x00;
frank26080115 0:bf7b9fba3924 301 BulkBuf[11] = 0x00;
frank26080115 0:bf7b9fba3924 302 BulkBuf[12] = 0x30; /* ASC */
frank26080115 0:bf7b9fba3924 303 BulkBuf[13] = 0x01; /* ASCQ */
frank26080115 0:bf7b9fba3924 304 BulkBuf[14] = 0x00;
frank26080115 0:bf7b9fba3924 305 BulkBuf[15] = 0x00;
frank26080115 0:bf7b9fba3924 306 BulkBuf[16] = 0x00;
frank26080115 0:bf7b9fba3924 307 BulkBuf[17] = 0x00;
frank26080115 0:bf7b9fba3924 308
frank26080115 0:bf7b9fba3924 309 BulkLen = 18;
frank26080115 0:bf7b9fba3924 310 DataInTransfer();
frank26080115 0:bf7b9fba3924 311 }
frank26080115 0:bf7b9fba3924 312
frank26080115 0:bf7b9fba3924 313
frank26080115 0:bf7b9fba3924 314 /*
frank26080115 0:bf7b9fba3924 315 * MSC SCSI Inquiry Callback
frank26080115 0:bf7b9fba3924 316 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 317 * Return Value: None
frank26080115 0:bf7b9fba3924 318 */
frank26080115 0:bf7b9fba3924 319
frank26080115 0:bf7b9fba3924 320 void MSC_Inquiry (void) {
frank26080115 0:bf7b9fba3924 321
frank26080115 0:bf7b9fba3924 322 if (!DataInFormat()) return;
frank26080115 0:bf7b9fba3924 323
frank26080115 0:bf7b9fba3924 324 BulkBuf[ 0] = 0x00; /* Direct Access Device */
frank26080115 0:bf7b9fba3924 325 BulkBuf[ 1] = 0x80; /* RMB = 1: Removable Medium */
frank26080115 0:bf7b9fba3924 326 BulkBuf[ 2] = 0x00; /* Version: No conformance claim to standard */
frank26080115 0:bf7b9fba3924 327 BulkBuf[ 3] = 0x01;
frank26080115 0:bf7b9fba3924 328
frank26080115 0:bf7b9fba3924 329 BulkBuf[ 4] = 36-4; /* Additional Length */
frank26080115 0:bf7b9fba3924 330 BulkBuf[ 5] = 0x80; /* SCCS = 1: Storage Controller Component */
frank26080115 0:bf7b9fba3924 331 BulkBuf[ 6] = 0x00;
frank26080115 0:bf7b9fba3924 332 BulkBuf[ 7] = 0x00;
frank26080115 0:bf7b9fba3924 333
frank26080115 0:bf7b9fba3924 334 BulkBuf[ 8] = 'K'; /* Vendor Identification */
frank26080115 0:bf7b9fba3924 335 BulkBuf[ 9] = 'e';
frank26080115 0:bf7b9fba3924 336 BulkBuf[10] = 'i';
frank26080115 0:bf7b9fba3924 337 BulkBuf[11] = 'l';
frank26080115 0:bf7b9fba3924 338 BulkBuf[12] = ' ';
frank26080115 0:bf7b9fba3924 339 BulkBuf[13] = ' ';
frank26080115 0:bf7b9fba3924 340 BulkBuf[14] = ' ';
frank26080115 0:bf7b9fba3924 341 BulkBuf[15] = ' ';
frank26080115 0:bf7b9fba3924 342
frank26080115 0:bf7b9fba3924 343 BulkBuf[16] = 'L'; /* Product Identification */
frank26080115 0:bf7b9fba3924 344 BulkBuf[17] = 'P';
frank26080115 0:bf7b9fba3924 345 BulkBuf[18] = 'C';
frank26080115 0:bf7b9fba3924 346 BulkBuf[19] = '1';
frank26080115 0:bf7b9fba3924 347 BulkBuf[20] = '7';
frank26080115 0:bf7b9fba3924 348 BulkBuf[21] = 'x';
frank26080115 0:bf7b9fba3924 349 BulkBuf[22] = 'x';
frank26080115 0:bf7b9fba3924 350 BulkBuf[23] = ' ';
frank26080115 0:bf7b9fba3924 351 BulkBuf[24] = 'D';
frank26080115 0:bf7b9fba3924 352 BulkBuf[25] = 'i';
frank26080115 0:bf7b9fba3924 353 BulkBuf[26] = 's';
frank26080115 0:bf7b9fba3924 354 BulkBuf[27] = 'k';
frank26080115 0:bf7b9fba3924 355 BulkBuf[28] = ' ';
frank26080115 0:bf7b9fba3924 356 BulkBuf[29] = ' ';
frank26080115 0:bf7b9fba3924 357 BulkBuf[30] = ' ';
frank26080115 0:bf7b9fba3924 358 BulkBuf[31] = ' ';
frank26080115 0:bf7b9fba3924 359
frank26080115 0:bf7b9fba3924 360 BulkBuf[32] = '1'; /* Product Revision Level */
frank26080115 0:bf7b9fba3924 361 BulkBuf[33] = '.';
frank26080115 0:bf7b9fba3924 362 BulkBuf[34] = '0';
frank26080115 0:bf7b9fba3924 363 BulkBuf[35] = ' ';
frank26080115 0:bf7b9fba3924 364
frank26080115 0:bf7b9fba3924 365 BulkLen = 36;
frank26080115 0:bf7b9fba3924 366 DataInTransfer();
frank26080115 0:bf7b9fba3924 367 }
frank26080115 0:bf7b9fba3924 368
frank26080115 0:bf7b9fba3924 369
frank26080115 0:bf7b9fba3924 370 /*
frank26080115 0:bf7b9fba3924 371 * MSC SCSI Mode Sense (6-Byte) Callback
frank26080115 0:bf7b9fba3924 372 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 373 * Return Value: None
frank26080115 0:bf7b9fba3924 374 */
frank26080115 0:bf7b9fba3924 375
frank26080115 0:bf7b9fba3924 376 void MSC_ModeSense6 (void) {
frank26080115 0:bf7b9fba3924 377
frank26080115 0:bf7b9fba3924 378 if (!DataInFormat()) return;
frank26080115 0:bf7b9fba3924 379
frank26080115 0:bf7b9fba3924 380 BulkBuf[ 0] = 0x03;
frank26080115 0:bf7b9fba3924 381 BulkBuf[ 1] = 0x00;
frank26080115 0:bf7b9fba3924 382 BulkBuf[ 2] = 0x00;
frank26080115 0:bf7b9fba3924 383 BulkBuf[ 3] = 0x00;
frank26080115 0:bf7b9fba3924 384
frank26080115 0:bf7b9fba3924 385 BulkLen = 4;
frank26080115 0:bf7b9fba3924 386 DataInTransfer();
frank26080115 0:bf7b9fba3924 387 }
frank26080115 0:bf7b9fba3924 388
frank26080115 0:bf7b9fba3924 389
frank26080115 0:bf7b9fba3924 390 /*
frank26080115 0:bf7b9fba3924 391 * MSC SCSI Mode Sense (10-Byte) Callback
frank26080115 0:bf7b9fba3924 392 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 393 * Return Value: None
frank26080115 0:bf7b9fba3924 394 */
frank26080115 0:bf7b9fba3924 395
frank26080115 0:bf7b9fba3924 396 void MSC_ModeSense10 (void) {
frank26080115 0:bf7b9fba3924 397
frank26080115 0:bf7b9fba3924 398 if (!DataInFormat()) return;
frank26080115 0:bf7b9fba3924 399
frank26080115 0:bf7b9fba3924 400 BulkBuf[ 0] = 0x00;
frank26080115 0:bf7b9fba3924 401 BulkBuf[ 1] = 0x06;
frank26080115 0:bf7b9fba3924 402 BulkBuf[ 2] = 0x00;
frank26080115 0:bf7b9fba3924 403 BulkBuf[ 3] = 0x00;
frank26080115 0:bf7b9fba3924 404 BulkBuf[ 4] = 0x00;
frank26080115 0:bf7b9fba3924 405 BulkBuf[ 5] = 0x00;
frank26080115 0:bf7b9fba3924 406 BulkBuf[ 6] = 0x00;
frank26080115 0:bf7b9fba3924 407 BulkBuf[ 7] = 0x00;
frank26080115 0:bf7b9fba3924 408
frank26080115 0:bf7b9fba3924 409 BulkLen = 8;
frank26080115 0:bf7b9fba3924 410 DataInTransfer();
frank26080115 0:bf7b9fba3924 411 }
frank26080115 0:bf7b9fba3924 412
frank26080115 0:bf7b9fba3924 413
frank26080115 0:bf7b9fba3924 414 /*
frank26080115 0:bf7b9fba3924 415 * MSC SCSI Read Capacity Callback
frank26080115 0:bf7b9fba3924 416 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 417 * Return Value: None
frank26080115 0:bf7b9fba3924 418 */
frank26080115 0:bf7b9fba3924 419
frank26080115 0:bf7b9fba3924 420 void MSC_ReadCapacity (void) {
frank26080115 0:bf7b9fba3924 421
frank26080115 0:bf7b9fba3924 422 if (!DataInFormat()) return;
frank26080115 0:bf7b9fba3924 423
frank26080115 0:bf7b9fba3924 424 /* Last Logical Block */
frank26080115 0:bf7b9fba3924 425 BulkBuf[ 0] = ((MSC_BlockCount - 1) >> 24) & 0xFF;
frank26080115 0:bf7b9fba3924 426 BulkBuf[ 1] = ((MSC_BlockCount - 1) >> 16) & 0xFF;
frank26080115 0:bf7b9fba3924 427 BulkBuf[ 2] = ((MSC_BlockCount - 1) >> 8) & 0xFF;
frank26080115 0:bf7b9fba3924 428 BulkBuf[ 3] = ((MSC_BlockCount - 1) >> 0) & 0xFF;
frank26080115 0:bf7b9fba3924 429
frank26080115 0:bf7b9fba3924 430 /* Block Length */
frank26080115 0:bf7b9fba3924 431 BulkBuf[ 4] = (MSC_BlockSize >> 24) & 0xFF;
frank26080115 0:bf7b9fba3924 432 BulkBuf[ 5] = (MSC_BlockSize >> 16) & 0xFF;
frank26080115 0:bf7b9fba3924 433 BulkBuf[ 6] = (MSC_BlockSize >> 8) & 0xFF;
frank26080115 0:bf7b9fba3924 434 BulkBuf[ 7] = (MSC_BlockSize >> 0) & 0xFF;
frank26080115 0:bf7b9fba3924 435
frank26080115 0:bf7b9fba3924 436 BulkLen = 8;
frank26080115 0:bf7b9fba3924 437 DataInTransfer();
frank26080115 0:bf7b9fba3924 438 }
frank26080115 0:bf7b9fba3924 439
frank26080115 0:bf7b9fba3924 440
frank26080115 0:bf7b9fba3924 441 /*
frank26080115 0:bf7b9fba3924 442 * MSC SCSI Read Format Capacity Callback
frank26080115 0:bf7b9fba3924 443 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 444 * Return Value: None
frank26080115 0:bf7b9fba3924 445 */
frank26080115 0:bf7b9fba3924 446
frank26080115 0:bf7b9fba3924 447 void MSC_ReadFormatCapacity (void) {
frank26080115 0:bf7b9fba3924 448
frank26080115 0:bf7b9fba3924 449 if (!DataInFormat()) return;
frank26080115 0:bf7b9fba3924 450
frank26080115 0:bf7b9fba3924 451 BulkBuf[ 0] = 0x00;
frank26080115 0:bf7b9fba3924 452 BulkBuf[ 1] = 0x00;
frank26080115 0:bf7b9fba3924 453 BulkBuf[ 2] = 0x00;
frank26080115 0:bf7b9fba3924 454 BulkBuf[ 3] = 0x08; /* Capacity List Length */
frank26080115 0:bf7b9fba3924 455
frank26080115 0:bf7b9fba3924 456 /* Block Count */
frank26080115 0:bf7b9fba3924 457 BulkBuf[ 4] = (MSC_BlockCount >> 24) & 0xFF;
frank26080115 0:bf7b9fba3924 458 BulkBuf[ 5] = (MSC_BlockCount >> 16) & 0xFF;
frank26080115 0:bf7b9fba3924 459 BulkBuf[ 6] = (MSC_BlockCount >> 8) & 0xFF;
frank26080115 0:bf7b9fba3924 460 BulkBuf[ 7] = (MSC_BlockCount >> 0) & 0xFF;
frank26080115 0:bf7b9fba3924 461
frank26080115 0:bf7b9fba3924 462 /* Block Length */
frank26080115 0:bf7b9fba3924 463 BulkBuf[ 8] = 0x02; /* Descriptor Code: Formatted Media */
frank26080115 0:bf7b9fba3924 464 BulkBuf[ 9] = (MSC_BlockSize >> 16) & 0xFF;
frank26080115 0:bf7b9fba3924 465 BulkBuf[10] = (MSC_BlockSize >> 8) & 0xFF;
frank26080115 0:bf7b9fba3924 466 BulkBuf[11] = (MSC_BlockSize >> 0) & 0xFF;
frank26080115 0:bf7b9fba3924 467
frank26080115 0:bf7b9fba3924 468 BulkLen = 12;
frank26080115 0:bf7b9fba3924 469 DataInTransfer();
frank26080115 0:bf7b9fba3924 470 }
frank26080115 0:bf7b9fba3924 471
frank26080115 0:bf7b9fba3924 472
frank26080115 0:bf7b9fba3924 473 /*
frank26080115 0:bf7b9fba3924 474 * MSC Get Command Block Wrapper Callback
frank26080115 0:bf7b9fba3924 475 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 476 * Return Value: None
frank26080115 0:bf7b9fba3924 477 */
frank26080115 0:bf7b9fba3924 478
frank26080115 0:bf7b9fba3924 479 void MSC_GetCBW (void) {
frank26080115 0:bf7b9fba3924 480 uint32_t n;
frank26080115 0:bf7b9fba3924 481
frank26080115 0:bf7b9fba3924 482 for (n = 0; n < BulkLen; n++) {
frank26080115 0:bf7b9fba3924 483 *((uint8_t *)&CBW + n) = BulkBuf[n];
frank26080115 0:bf7b9fba3924 484 }
frank26080115 0:bf7b9fba3924 485 if ((BulkLen == sizeof(CBW)) && (CBW.dSignature == MSC_CBW_Signature)) {
frank26080115 0:bf7b9fba3924 486 /* Valid CBW */
frank26080115 0:bf7b9fba3924 487 CSW.dTag = CBW.dTag;
frank26080115 0:bf7b9fba3924 488 CSW.dDataResidue = CBW.dDataLength;
frank26080115 0:bf7b9fba3924 489 if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || CBW.bCBLength > 16) {
frank26080115 0:bf7b9fba3924 490 fail: CSW.bStatus = CSW_CMD_FAILED;
frank26080115 0:bf7b9fba3924 491 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 492 } else {
frank26080115 0:bf7b9fba3924 493 switch (CBW.CB[0]) {
frank26080115 0:bf7b9fba3924 494 case SCSI_TEST_UNIT_READY:
frank26080115 0:bf7b9fba3924 495 MSC_TestUnitReady();
frank26080115 0:bf7b9fba3924 496 break;
frank26080115 0:bf7b9fba3924 497 case SCSI_REQUEST_SENSE:
frank26080115 0:bf7b9fba3924 498 MSC_RequestSense();
frank26080115 0:bf7b9fba3924 499 break;
frank26080115 0:bf7b9fba3924 500 case SCSI_FORMAT_UNIT:
frank26080115 0:bf7b9fba3924 501 goto fail;
frank26080115 0:bf7b9fba3924 502 case SCSI_INQUIRY:
frank26080115 0:bf7b9fba3924 503 MSC_Inquiry();
frank26080115 0:bf7b9fba3924 504 break;
frank26080115 0:bf7b9fba3924 505 case SCSI_START_STOP_UNIT:
frank26080115 0:bf7b9fba3924 506 goto fail;
frank26080115 0:bf7b9fba3924 507 case SCSI_MEDIA_REMOVAL:
frank26080115 0:bf7b9fba3924 508 goto fail;
frank26080115 0:bf7b9fba3924 509 case SCSI_MODE_SELECT6:
frank26080115 0:bf7b9fba3924 510 goto fail;
frank26080115 0:bf7b9fba3924 511 case SCSI_MODE_SENSE6:
frank26080115 0:bf7b9fba3924 512 MSC_ModeSense6();
frank26080115 0:bf7b9fba3924 513 break;
frank26080115 0:bf7b9fba3924 514 case SCSI_MODE_SELECT10:
frank26080115 0:bf7b9fba3924 515 goto fail;
frank26080115 0:bf7b9fba3924 516 case SCSI_MODE_SENSE10:
frank26080115 0:bf7b9fba3924 517 MSC_ModeSense10();
frank26080115 0:bf7b9fba3924 518 break;
frank26080115 0:bf7b9fba3924 519 case SCSI_READ_FORMAT_CAPACITIES:
frank26080115 0:bf7b9fba3924 520 MSC_ReadFormatCapacity();
frank26080115 0:bf7b9fba3924 521 break;
frank26080115 0:bf7b9fba3924 522 case SCSI_READ_CAPACITY:
frank26080115 0:bf7b9fba3924 523 MSC_ReadCapacity();
frank26080115 0:bf7b9fba3924 524 break;
frank26080115 0:bf7b9fba3924 525 case SCSI_READ10:
frank26080115 0:bf7b9fba3924 526 if (MSC_RWSetup()) {
frank26080115 0:bf7b9fba3924 527 if ((CBW.bmFlags & 0x80) != 0) {
frank26080115 0:bf7b9fba3924 528 BulkStage = MSC_BS_DATA_IN;
frank26080115 0:bf7b9fba3924 529 MSC_MemoryRead();
frank26080115 0:bf7b9fba3924 530 } else {
frank26080115 0:bf7b9fba3924 531 USB_SetStallEP(MSC_EP_OUT);
frank26080115 0:bf7b9fba3924 532 CSW.bStatus = CSW_PHASE_ERROR;
frank26080115 0:bf7b9fba3924 533 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 534 }
frank26080115 0:bf7b9fba3924 535 }
frank26080115 0:bf7b9fba3924 536 break;
frank26080115 0:bf7b9fba3924 537 case SCSI_WRITE10:
frank26080115 0:bf7b9fba3924 538 if (MSC_RWSetup()) {
frank26080115 0:bf7b9fba3924 539 if ((CBW.bmFlags & 0x80) == 0) {
frank26080115 0:bf7b9fba3924 540 BulkStage = MSC_BS_DATA_OUT;
frank26080115 0:bf7b9fba3924 541 } else {
frank26080115 0:bf7b9fba3924 542 USB_SetStallEP(MSC_EP_IN);
frank26080115 0:bf7b9fba3924 543 CSW.bStatus = CSW_PHASE_ERROR;
frank26080115 0:bf7b9fba3924 544 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 545 }
frank26080115 0:bf7b9fba3924 546 }
frank26080115 0:bf7b9fba3924 547 break;
frank26080115 0:bf7b9fba3924 548 case SCSI_VERIFY10:
frank26080115 0:bf7b9fba3924 549 if (MSC_RWSetup()) {
frank26080115 0:bf7b9fba3924 550 if ((CBW.bmFlags & 0x80) == 0) {
frank26080115 0:bf7b9fba3924 551 BulkStage = MSC_BS_DATA_OUT;
frank26080115 0:bf7b9fba3924 552 MemOK = TRUE;
frank26080115 0:bf7b9fba3924 553 } else {
frank26080115 0:bf7b9fba3924 554 USB_SetStallEP(MSC_EP_IN);
frank26080115 0:bf7b9fba3924 555 CSW.bStatus = CSW_PHASE_ERROR;
frank26080115 0:bf7b9fba3924 556 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 557 }
frank26080115 0:bf7b9fba3924 558 }
frank26080115 0:bf7b9fba3924 559 break;
frank26080115 0:bf7b9fba3924 560 default:
frank26080115 0:bf7b9fba3924 561 goto fail;
frank26080115 0:bf7b9fba3924 562 }
frank26080115 0:bf7b9fba3924 563 }
frank26080115 0:bf7b9fba3924 564 } else {
frank26080115 0:bf7b9fba3924 565 /* Invalid CBW */
frank26080115 0:bf7b9fba3924 566 USB_SetStallEP(MSC_EP_IN);
frank26080115 0:bf7b9fba3924 567 USB_SetStallEP(MSC_EP_OUT);
frank26080115 0:bf7b9fba3924 568 BulkStage = MSC_BS_ERROR;
frank26080115 0:bf7b9fba3924 569 }
frank26080115 0:bf7b9fba3924 570 }
frank26080115 0:bf7b9fba3924 571
frank26080115 0:bf7b9fba3924 572
frank26080115 0:bf7b9fba3924 573 /*
frank26080115 0:bf7b9fba3924 574 * MSC Set Command Status Wrapper Callback
frank26080115 0:bf7b9fba3924 575 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 576 * Return Value: None
frank26080115 0:bf7b9fba3924 577 */
frank26080115 0:bf7b9fba3924 578
frank26080115 0:bf7b9fba3924 579 void MSC_SetCSW (void) {
frank26080115 0:bf7b9fba3924 580
frank26080115 0:bf7b9fba3924 581 CSW.dSignature = MSC_CSW_Signature;
frank26080115 0:bf7b9fba3924 582 USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW));
frank26080115 0:bf7b9fba3924 583 BulkStage = MSC_BS_CSW;
frank26080115 0:bf7b9fba3924 584 }
frank26080115 0:bf7b9fba3924 585
frank26080115 0:bf7b9fba3924 586
frank26080115 0:bf7b9fba3924 587 /*
frank26080115 0:bf7b9fba3924 588 * MSC Bulk In Callback
frank26080115 0:bf7b9fba3924 589 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 590 * Return Value: None
frank26080115 0:bf7b9fba3924 591 */
frank26080115 0:bf7b9fba3924 592
frank26080115 0:bf7b9fba3924 593 void MSC_BulkIn (void) {
frank26080115 0:bf7b9fba3924 594
frank26080115 0:bf7b9fba3924 595 switch (BulkStage) {
frank26080115 0:bf7b9fba3924 596 case MSC_BS_DATA_IN:
frank26080115 0:bf7b9fba3924 597 switch (CBW.CB[0]) {
frank26080115 0:bf7b9fba3924 598 case SCSI_READ10:
frank26080115 0:bf7b9fba3924 599 MSC_MemoryRead();
frank26080115 0:bf7b9fba3924 600 break;
frank26080115 0:bf7b9fba3924 601 }
frank26080115 0:bf7b9fba3924 602 break;
frank26080115 0:bf7b9fba3924 603 case MSC_BS_DATA_IN_LAST:
frank26080115 0:bf7b9fba3924 604 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 605 break;
frank26080115 0:bf7b9fba3924 606 case MSC_BS_DATA_IN_LAST_STALL:
frank26080115 0:bf7b9fba3924 607 USB_SetStallEP(MSC_EP_IN);
frank26080115 0:bf7b9fba3924 608 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 609 break;
frank26080115 0:bf7b9fba3924 610 case MSC_BS_CSW:
frank26080115 0:bf7b9fba3924 611 BulkStage = MSC_BS_CBW;
frank26080115 0:bf7b9fba3924 612 break;
frank26080115 0:bf7b9fba3924 613 }
frank26080115 0:bf7b9fba3924 614 }
frank26080115 0:bf7b9fba3924 615
frank26080115 0:bf7b9fba3924 616
frank26080115 0:bf7b9fba3924 617 /*
frank26080115 0:bf7b9fba3924 618 * MSC Bulk Out Callback
frank26080115 0:bf7b9fba3924 619 * Parameters: None (global variables)
frank26080115 0:bf7b9fba3924 620 * Return Value: None
frank26080115 0:bf7b9fba3924 621 */
frank26080115 0:bf7b9fba3924 622
frank26080115 0:bf7b9fba3924 623 void MSC_BulkOut (void) {
frank26080115 0:bf7b9fba3924 624
frank26080115 0:bf7b9fba3924 625 BulkLen = USB_ReadEP(MSC_EP_OUT, BulkBuf);
frank26080115 0:bf7b9fba3924 626 switch (BulkStage) {
frank26080115 0:bf7b9fba3924 627 case MSC_BS_CBW:
frank26080115 0:bf7b9fba3924 628 MSC_GetCBW();
frank26080115 0:bf7b9fba3924 629 break;
frank26080115 0:bf7b9fba3924 630 case MSC_BS_DATA_OUT:
frank26080115 0:bf7b9fba3924 631 switch (CBW.CB[0]) {
frank26080115 0:bf7b9fba3924 632 case SCSI_WRITE10:
frank26080115 0:bf7b9fba3924 633 MSC_MemoryWrite();
frank26080115 0:bf7b9fba3924 634 break;
frank26080115 0:bf7b9fba3924 635 case SCSI_VERIFY10:
frank26080115 0:bf7b9fba3924 636 MSC_MemoryVerify();
frank26080115 0:bf7b9fba3924 637 break;
frank26080115 0:bf7b9fba3924 638 }
frank26080115 0:bf7b9fba3924 639 break;
frank26080115 0:bf7b9fba3924 640 default:
frank26080115 0:bf7b9fba3924 641 USB_SetStallEP(MSC_EP_OUT);
frank26080115 0:bf7b9fba3924 642 CSW.bStatus = CSW_PHASE_ERROR;
frank26080115 0:bf7b9fba3924 643 MSC_SetCSW();
frank26080115 0:bf7b9fba3924 644 break;
frank26080115 0:bf7b9fba3924 645 }
frank26080115 0:bf7b9fba3924 646 }