These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!
USBDEV/USBMassStorage/mscuser.c@0:bf7b9fba3924, 2011-03-20 (annotated)
- Committer:
- frank26080115
- Date:
- Sun Mar 20 05:38:56 2011 +0000
- Revision:
- 0:bf7b9fba3924
Who changed what in which revision?
User | Revision | Line number | New 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 | } |