Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 /**
Pawel Zarembski 0:01f31e923fe2 2 * @file usbd_msc.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief Mass Storage Class driver
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 8 *
Pawel Zarembski 0:01f31e923fe2 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 10 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 11 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 12 *
Pawel Zarembski 0:01f31e923fe2 13 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 14 *
Pawel Zarembski 0:01f31e923fe2 15 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 18 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 19 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 20 */
Pawel Zarembski 0:01f31e923fe2 21
Pawel Zarembski 0:01f31e923fe2 22 #include <string.h>
Pawel Zarembski 0:01f31e923fe2 23
Pawel Zarembski 0:01f31e923fe2 24 #include "rl_usb.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "usb_for_lib.h"
Pawel Zarembski 0:01f31e923fe2 26 #include "util.h"
Pawel Zarembski 0:01f31e923fe2 27
Pawel Zarembski 0:01f31e923fe2 28 BOOL USBD_MSC_MediaReady = __FALSE;
Pawel Zarembski 0:01f31e923fe2 29 BOOL USBD_MSC_ReadOnly = __FALSE;
Pawel Zarembski 0:01f31e923fe2 30 U32 USBD_MSC_MemorySize;
Pawel Zarembski 0:01f31e923fe2 31 U32 USBD_MSC_BlockSize;
Pawel Zarembski 0:01f31e923fe2 32 U32 USBD_MSC_BlockGroup;
Pawel Zarembski 0:01f31e923fe2 33 U32 USBD_MSC_BlockCount;
Pawel Zarembski 0:01f31e923fe2 34 U8 *USBD_MSC_BlockBuf;
Pawel Zarembski 0:01f31e923fe2 35
Pawel Zarembski 0:01f31e923fe2 36 MSC_CBW USBD_MSC_CBW; /* Command Block Wrapper */
Pawel Zarembski 0:01f31e923fe2 37 MSC_CSW USBD_MSC_CSW; /* Command Status Wrapper */
Pawel Zarembski 0:01f31e923fe2 38
Pawel Zarembski 0:01f31e923fe2 39 BOOL USBD_MSC_MediaReadyEx = __FALSE; /* Previous state of Media ready */
Pawel Zarembski 0:01f31e923fe2 40 BOOL MemOK; /* Memory OK */
Pawel Zarembski 0:01f31e923fe2 41
Pawel Zarembski 0:01f31e923fe2 42 U32 Block; /* R/W Block */
Pawel Zarembski 0:01f31e923fe2 43 U32 Offset; /* R/W Offset */
Pawel Zarembski 0:01f31e923fe2 44 U32 Length; /* R/W Length */
Pawel Zarembski 0:01f31e923fe2 45
Pawel Zarembski 0:01f31e923fe2 46 U8 BulkStage; /* Bulk Stage */
Pawel Zarembski 0:01f31e923fe2 47 U32 BulkLen; /* Bulk In/Out Length */
Pawel Zarembski 0:01f31e923fe2 48
Pawel Zarembski 0:01f31e923fe2 49
Pawel Zarembski 0:01f31e923fe2 50 /* Dummy Weak Functions that need to be provided by user */
Pawel Zarembski 0:01f31e923fe2 51 __weak void usbd_msc_init()
Pawel Zarembski 0:01f31e923fe2 52 {
Pawel Zarembski 0:01f31e923fe2 53
Pawel Zarembski 0:01f31e923fe2 54 }
Pawel Zarembski 0:01f31e923fe2 55 __weak void usbd_msc_read_sect(U32 block, U8 *buf, U32 num_of_blocks)
Pawel Zarembski 0:01f31e923fe2 56 {
Pawel Zarembski 0:01f31e923fe2 57
Pawel Zarembski 0:01f31e923fe2 58 }
Pawel Zarembski 0:01f31e923fe2 59 __weak void usbd_msc_write_sect(U32 block, U8 *buf, U32 num_of_blocks)
Pawel Zarembski 0:01f31e923fe2 60 {
Pawel Zarembski 0:01f31e923fe2 61
Pawel Zarembski 0:01f31e923fe2 62 }
Pawel Zarembski 0:01f31e923fe2 63 __weak void usbd_msc_start_stop(BOOL start)
Pawel Zarembski 0:01f31e923fe2 64 {
Pawel Zarembski 0:01f31e923fe2 65
Pawel Zarembski 0:01f31e923fe2 66 }
Pawel Zarembski 0:01f31e923fe2 67
Pawel Zarembski 0:01f31e923fe2 68
Pawel Zarembski 0:01f31e923fe2 69 /*
Pawel Zarembski 0:01f31e923fe2 70 * Set Stall for USB Device MSC Endpoint
Pawel Zarembski 0:01f31e923fe2 71 * Parameters: EPNum: USB Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 72 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 73 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 74 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 75 */
Pawel Zarembski 0:01f31e923fe2 76
Pawel Zarembski 0:01f31e923fe2 77 void USBD_MSC_SetStallEP(U32 EPNum) /* set EP halt status according stall status */
Pawel Zarembski 0:01f31e923fe2 78 {
Pawel Zarembski 0:01f31e923fe2 79 USBD_SetStallEP(EPNum);
Pawel Zarembski 0:01f31e923fe2 80 USBD_EndPointHalt |= (EPNum & 0x80) ? ((1 << 16) << (EPNum & 0x0F)) : (1 << EPNum);
Pawel Zarembski 0:01f31e923fe2 81 }
Pawel Zarembski 0:01f31e923fe2 82
Pawel Zarembski 0:01f31e923fe2 83
Pawel Zarembski 0:01f31e923fe2 84 /*
Pawel Zarembski 0:01f31e923fe2 85 * Clear Stall for USB Device MSC Endpoint
Pawel Zarembski 0:01f31e923fe2 86 * Parameters: EPNum: USB Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 87 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 88 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 89 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 90 */
Pawel Zarembski 0:01f31e923fe2 91
Pawel Zarembski 0:01f31e923fe2 92 void USBD_MSC_ClrStallEP(U32 EPNum) /* clear EP halt status according stall status */
Pawel Zarembski 0:01f31e923fe2 93 {
Pawel Zarembski 0:01f31e923fe2 94 U32 n, m;
Pawel Zarembski 0:01f31e923fe2 95 n = USBD_SetupPacket.wIndexL & 0x8F;
Pawel Zarembski 0:01f31e923fe2 96 m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
Pawel Zarembski 0:01f31e923fe2 97
Pawel Zarembski 0:01f31e923fe2 98 if ((n == (usbd_msc_ep_bulkin | 0x80)) && ((USBD_EndPointHalt & m) != 0)) {
Pawel Zarembski 0:01f31e923fe2 99 /* Compliance Test: rewrite CSW after unstall */
Pawel Zarembski 0:01f31e923fe2 100 if (USBD_MSC_CSW.dSignature == MSC_CSW_Signature) {
Pawel Zarembski 0:01f31e923fe2 101 USBD_WriteEP((usbd_msc_ep_bulkin | 0x80), (U8 *)&USBD_MSC_CSW, sizeof(USBD_MSC_CSW));
Pawel Zarembski 0:01f31e923fe2 102 }
Pawel Zarembski 0:01f31e923fe2 103 }
Pawel Zarembski 0:01f31e923fe2 104 }
Pawel Zarembski 0:01f31e923fe2 105
Pawel Zarembski 0:01f31e923fe2 106
Pawel Zarembski 0:01f31e923fe2 107 /*
Pawel Zarembski 0:01f31e923fe2 108 * USB Device MSC Mass Storage Reset Request Callback
Pawel Zarembski 0:01f31e923fe2 109 * Called automatically on USB Device Mass Storage Reset Request
Pawel Zarembski 0:01f31e923fe2 110 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 111 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 112 */
Pawel Zarembski 0:01f31e923fe2 113
Pawel Zarembski 0:01f31e923fe2 114 BOOL USBD_MSC_Reset(void)
Pawel Zarembski 0:01f31e923fe2 115 {
Pawel Zarembski 0:01f31e923fe2 116 USBD_EndPointStall = 0x00000000; /* EP must stay stalled */
Pawel Zarembski 0:01f31e923fe2 117 USBD_MSC_CSW.dSignature = 0; /* invalid signature */
Pawel Zarembski 0:01f31e923fe2 118 BulkStage = MSC_BS_RESET;
Pawel Zarembski 0:01f31e923fe2 119 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 120 }
Pawel Zarembski 0:01f31e923fe2 121
Pawel Zarembski 0:01f31e923fe2 122
Pawel Zarembski 0:01f31e923fe2 123 /*
Pawel Zarembski 0:01f31e923fe2 124 * USB Device MSC Get Max LUN Request Callback
Pawel Zarembski 0:01f31e923fe2 125 * Called automatically on USB Device Get Max LUN Request
Pawel Zarembski 0:01f31e923fe2 126 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 127 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 128 */
Pawel Zarembski 0:01f31e923fe2 129
Pawel Zarembski 0:01f31e923fe2 130 BOOL USBD_MSC_GetMaxLUN(void)
Pawel Zarembski 0:01f31e923fe2 131 {
Pawel Zarembski 0:01f31e923fe2 132 USBD_EP0Buf[0] = 0; /* one LUN associated with this device */
Pawel Zarembski 0:01f31e923fe2 133 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 134 }
Pawel Zarembski 0:01f31e923fe2 135
Pawel Zarembski 0:01f31e923fe2 136
Pawel Zarembski 0:01f31e923fe2 137 /*
Pawel Zarembski 0:01f31e923fe2 138 * USB Device Check Media Ready
Pawel Zarembski 0:01f31e923fe2 139 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 140 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 141 */
Pawel Zarembski 0:01f31e923fe2 142
Pawel Zarembski 0:01f31e923fe2 143 BOOL USBD_MSC_CheckMedia(void)
Pawel Zarembski 0:01f31e923fe2 144 {
Pawel Zarembski 0:01f31e923fe2 145 USBD_MSC_MediaReadyEx = USBD_MSC_MediaReady;
Pawel Zarembski 0:01f31e923fe2 146
Pawel Zarembski 0:01f31e923fe2 147 if (!USBD_MSC_MediaReady) {
Pawel Zarembski 0:01f31e923fe2 148 if (USBD_MSC_CBW.dDataLength) {
Pawel Zarembski 0:01f31e923fe2 149 if ((USBD_MSC_CBW.bmFlags & 0x80) != 0) {
Pawel Zarembski 0:01f31e923fe2 150 USBD_MSC_SetStallEP(usbd_msc_ep_bulkin | 0x80);
Pawel Zarembski 0:01f31e923fe2 151 } else {
Pawel Zarembski 0:01f31e923fe2 152 if (USBD_MSC_CSW.dDataResidue != BulkLen) {
Pawel Zarembski 0:01f31e923fe2 153 // Only stall if this isn't the last transfer
Pawel Zarembski 0:01f31e923fe2 154 USBD_MSC_SetStallEP(usbd_msc_ep_bulkout);
Pawel Zarembski 0:01f31e923fe2 155 }
Pawel Zarembski 0:01f31e923fe2 156 }
Pawel Zarembski 0:01f31e923fe2 157 }
Pawel Zarembski 0:01f31e923fe2 158
Pawel Zarembski 0:01f31e923fe2 159 USBD_MSC_CSW.bStatus = CSW_CMD_FAILED;
Pawel Zarembski 0:01f31e923fe2 160 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 161 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 162 }
Pawel Zarembski 0:01f31e923fe2 163
Pawel Zarembski 0:01f31e923fe2 164 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 165 }
Pawel Zarembski 0:01f31e923fe2 166
Pawel Zarembski 0:01f31e923fe2 167
Pawel Zarembski 0:01f31e923fe2 168 /*
Pawel Zarembski 0:01f31e923fe2 169 * USB Device MSC Memory Read Callback
Pawel Zarembski 0:01f31e923fe2 170 * Called automatically on USB Device Memory Read Event
Pawel Zarembski 0:01f31e923fe2 171 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 172 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 173 */
Pawel Zarembski 0:01f31e923fe2 174
Pawel Zarembski 0:01f31e923fe2 175 void USBD_MSC_MemoryRead(void)
Pawel Zarembski 0:01f31e923fe2 176 {
Pawel Zarembski 0:01f31e923fe2 177 U32 n, m;
Pawel Zarembski 0:01f31e923fe2 178
Pawel Zarembski 0:01f31e923fe2 179 if (Block >= USBD_MSC_BlockCount) {
Pawel Zarembski 0:01f31e923fe2 180 n = 0;
Pawel Zarembski 0:01f31e923fe2 181 USBD_MSC_SetStallEP(usbd_msc_ep_bulkin | 0x80);
Pawel Zarembski 0:01f31e923fe2 182 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED;
Pawel Zarembski 0:01f31e923fe2 183 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 184 } else {
Pawel Zarembski 0:01f31e923fe2 185 if (Length > usbd_msc_maxpacketsize[USBD_HighSpeed]) {
Pawel Zarembski 0:01f31e923fe2 186 n = usbd_msc_maxpacketsize[USBD_HighSpeed];
Pawel Zarembski 0:01f31e923fe2 187 } else {
Pawel Zarembski 0:01f31e923fe2 188 n = Length;
Pawel Zarembski 0:01f31e923fe2 189 }
Pawel Zarembski 0:01f31e923fe2 190 }
Pawel Zarembski 0:01f31e923fe2 191
Pawel Zarembski 0:01f31e923fe2 192 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 193 n = 0;
Pawel Zarembski 0:01f31e923fe2 194 }
Pawel Zarembski 0:01f31e923fe2 195
Pawel Zarembski 0:01f31e923fe2 196 if ((Offset == 0) && (n != 0)) {
Pawel Zarembski 0:01f31e923fe2 197 m = (Length + (USBD_MSC_BlockSize - 1)) / USBD_MSC_BlockSize;
Pawel Zarembski 0:01f31e923fe2 198
Pawel Zarembski 0:01f31e923fe2 199 if (m > USBD_MSC_BlockGroup) {
Pawel Zarembski 0:01f31e923fe2 200 m = USBD_MSC_BlockGroup;
Pawel Zarembski 0:01f31e923fe2 201 }
Pawel Zarembski 0:01f31e923fe2 202
Pawel Zarembski 0:01f31e923fe2 203 usbd_msc_read_sect(Block, USBD_MSC_BlockBuf, m);
Pawel Zarembski 0:01f31e923fe2 204 }
Pawel Zarembski 0:01f31e923fe2 205
Pawel Zarembski 0:01f31e923fe2 206 if (n) {
Pawel Zarembski 0:01f31e923fe2 207 USBD_WriteEP(usbd_msc_ep_bulkin | 0x80, &USBD_MSC_BlockBuf[Offset], n);
Pawel Zarembski 0:01f31e923fe2 208 Offset += n;
Pawel Zarembski 0:01f31e923fe2 209 Length -= n;
Pawel Zarembski 0:01f31e923fe2 210 }
Pawel Zarembski 0:01f31e923fe2 211
Pawel Zarembski 0:01f31e923fe2 212 if (Offset == USBD_MSC_BlockGroup * USBD_MSC_BlockSize) {
Pawel Zarembski 0:01f31e923fe2 213 Offset = 0;
Pawel Zarembski 0:01f31e923fe2 214 Block += USBD_MSC_BlockGroup;
Pawel Zarembski 0:01f31e923fe2 215 }
Pawel Zarembski 0:01f31e923fe2 216
Pawel Zarembski 0:01f31e923fe2 217 USBD_MSC_CSW.dDataResidue -= n;
Pawel Zarembski 0:01f31e923fe2 218
Pawel Zarembski 0:01f31e923fe2 219 if (!n) {
Pawel Zarembski 0:01f31e923fe2 220 return;
Pawel Zarembski 0:01f31e923fe2 221 }
Pawel Zarembski 0:01f31e923fe2 222
Pawel Zarembski 0:01f31e923fe2 223 if (Length == 0) {
Pawel Zarembski 0:01f31e923fe2 224 BulkStage = MSC_BS_DATA_IN_LAST;
Pawel Zarembski 0:01f31e923fe2 225 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED;
Pawel Zarembski 0:01f31e923fe2 226 }
Pawel Zarembski 0:01f31e923fe2 227 }
Pawel Zarembski 0:01f31e923fe2 228
Pawel Zarembski 0:01f31e923fe2 229
Pawel Zarembski 0:01f31e923fe2 230 /*
Pawel Zarembski 0:01f31e923fe2 231 * USB Device MSC Memory Write Callback
Pawel Zarembski 0:01f31e923fe2 232 * Called automatically on USB Device Memory Write Event
Pawel Zarembski 0:01f31e923fe2 233 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 234 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 235 */
Pawel Zarembski 0:01f31e923fe2 236
Pawel Zarembski 0:01f31e923fe2 237 void USBD_MSC_MemoryWrite(void)
Pawel Zarembski 0:01f31e923fe2 238 {
Pawel Zarembski 0:01f31e923fe2 239 U32 n;
Pawel Zarembski 0:01f31e923fe2 240
Pawel Zarembski 0:01f31e923fe2 241 if (Block >= USBD_MSC_BlockCount) {
Pawel Zarembski 0:01f31e923fe2 242 BulkLen = 0;
Pawel Zarembski 0:01f31e923fe2 243 USBD_MSC_SetStallEP(usbd_msc_ep_bulkout);
Pawel Zarembski 0:01f31e923fe2 244 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED;
Pawel Zarembski 0:01f31e923fe2 245 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 246 }
Pawel Zarembski 0:01f31e923fe2 247
Pawel Zarembski 0:01f31e923fe2 248 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 249 BulkLen = 0;
Pawel Zarembski 0:01f31e923fe2 250 }
Pawel Zarembski 0:01f31e923fe2 251
Pawel Zarembski 0:01f31e923fe2 252 if (Offset + BulkLen > USBD_MSC_BlockSize) {
Pawel Zarembski 0:01f31e923fe2 253 // This write would have overflowed USBD_MSC_BlockBuf
Pawel Zarembski 0:01f31e923fe2 254 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 255 return;
Pawel Zarembski 0:01f31e923fe2 256 }
Pawel Zarembski 0:01f31e923fe2 257
Pawel Zarembski 0:01f31e923fe2 258 for (n = 0; n < BulkLen; n++) {
Pawel Zarembski 0:01f31e923fe2 259 USBD_MSC_BlockBuf[Offset + n] = USBD_MSC_BulkBuf[n];
Pawel Zarembski 0:01f31e923fe2 260 }
Pawel Zarembski 0:01f31e923fe2 261
Pawel Zarembski 0:01f31e923fe2 262 Offset += BulkLen;
Pawel Zarembski 0:01f31e923fe2 263 Length -= BulkLen;
Pawel Zarembski 0:01f31e923fe2 264
Pawel Zarembski 0:01f31e923fe2 265 if (BulkLen) {
Pawel Zarembski 0:01f31e923fe2 266 if ((Length == 0) && (Offset != 0)) {
Pawel Zarembski 0:01f31e923fe2 267 n = (Offset + (USBD_MSC_BlockSize - 1)) / USBD_MSC_BlockSize;
Pawel Zarembski 0:01f31e923fe2 268
Pawel Zarembski 0:01f31e923fe2 269 if (n > USBD_MSC_BlockGroup) {
Pawel Zarembski 0:01f31e923fe2 270 n = USBD_MSC_BlockGroup;
Pawel Zarembski 0:01f31e923fe2 271 }
Pawel Zarembski 0:01f31e923fe2 272
Pawel Zarembski 0:01f31e923fe2 273 usbd_msc_write_sect(Block, USBD_MSC_BlockBuf, n);
Pawel Zarembski 0:01f31e923fe2 274 Offset = 0;
Pawel Zarembski 0:01f31e923fe2 275 Block += n;
Pawel Zarembski 0:01f31e923fe2 276 } else if (Offset == USBD_MSC_BlockGroup * USBD_MSC_BlockSize) {
Pawel Zarembski 0:01f31e923fe2 277 usbd_msc_write_sect(Block, USBD_MSC_BlockBuf, USBD_MSC_BlockGroup);
Pawel Zarembski 0:01f31e923fe2 278 Offset = 0;
Pawel Zarembski 0:01f31e923fe2 279 Block += USBD_MSC_BlockGroup;
Pawel Zarembski 0:01f31e923fe2 280 }
Pawel Zarembski 0:01f31e923fe2 281 }
Pawel Zarembski 0:01f31e923fe2 282
Pawel Zarembski 0:01f31e923fe2 283 USBD_MSC_CSW.dDataResidue -= BulkLen;
Pawel Zarembski 0:01f31e923fe2 284
Pawel Zarembski 0:01f31e923fe2 285 if (!BulkLen) {
Pawel Zarembski 0:01f31e923fe2 286 return;
Pawel Zarembski 0:01f31e923fe2 287 }
Pawel Zarembski 0:01f31e923fe2 288
Pawel Zarembski 0:01f31e923fe2 289 if ((Length == 0) || (BulkStage == MSC_BS_CSW)) {
Pawel Zarembski 0:01f31e923fe2 290 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED;
Pawel Zarembski 0:01f31e923fe2 291 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 292 }
Pawel Zarembski 0:01f31e923fe2 293 }
Pawel Zarembski 0:01f31e923fe2 294
Pawel Zarembski 0:01f31e923fe2 295
Pawel Zarembski 0:01f31e923fe2 296 /*
Pawel Zarembski 0:01f31e923fe2 297 * USB Device MSC Memory Verify Callback
Pawel Zarembski 0:01f31e923fe2 298 * Called automatically on USB Device Memory Verify Event
Pawel Zarembski 0:01f31e923fe2 299 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 300 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 301 */
Pawel Zarembski 0:01f31e923fe2 302
Pawel Zarembski 0:01f31e923fe2 303 void USBD_MSC_MemoryVerify(void)
Pawel Zarembski 0:01f31e923fe2 304 {
Pawel Zarembski 0:01f31e923fe2 305 U32 n;
Pawel Zarembski 0:01f31e923fe2 306
Pawel Zarembski 0:01f31e923fe2 307 if (Block >= USBD_MSC_BlockCount) {
Pawel Zarembski 0:01f31e923fe2 308 BulkLen = 0;
Pawel Zarembski 0:01f31e923fe2 309 USBD_MSC_SetStallEP(usbd_msc_ep_bulkout);
Pawel Zarembski 0:01f31e923fe2 310 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED;
Pawel Zarembski 0:01f31e923fe2 311 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 312 }
Pawel Zarembski 0:01f31e923fe2 313
Pawel Zarembski 0:01f31e923fe2 314 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 315 BulkLen = 0;
Pawel Zarembski 0:01f31e923fe2 316 }
Pawel Zarembski 0:01f31e923fe2 317
Pawel Zarembski 0:01f31e923fe2 318 if (BulkLen) {
Pawel Zarembski 0:01f31e923fe2 319 if ((Offset == 0) && (BulkLen != 0)) {
Pawel Zarembski 0:01f31e923fe2 320 n = (Length + (USBD_MSC_BlockSize - 1)) / USBD_MSC_BlockSize;
Pawel Zarembski 0:01f31e923fe2 321
Pawel Zarembski 0:01f31e923fe2 322 if (n > USBD_MSC_BlockGroup) {
Pawel Zarembski 0:01f31e923fe2 323 n = USBD_MSC_BlockGroup;
Pawel Zarembski 0:01f31e923fe2 324 }
Pawel Zarembski 0:01f31e923fe2 325
Pawel Zarembski 0:01f31e923fe2 326 usbd_msc_read_sect(Block, USBD_MSC_BlockBuf, n);
Pawel Zarembski 0:01f31e923fe2 327 }
Pawel Zarembski 0:01f31e923fe2 328
Pawel Zarembski 0:01f31e923fe2 329 for (n = 0; n < BulkLen; n++) {
Pawel Zarembski 0:01f31e923fe2 330 if (USBD_MSC_BlockBuf[Offset + n] != USBD_MSC_BulkBuf[n]) {
Pawel Zarembski 0:01f31e923fe2 331 MemOK = __FALSE;
Pawel Zarembski 0:01f31e923fe2 332 break;
Pawel Zarembski 0:01f31e923fe2 333 }
Pawel Zarembski 0:01f31e923fe2 334 }
Pawel Zarembski 0:01f31e923fe2 335 }
Pawel Zarembski 0:01f31e923fe2 336
Pawel Zarembski 0:01f31e923fe2 337 Offset += BulkLen;
Pawel Zarembski 0:01f31e923fe2 338 Length -= BulkLen;
Pawel Zarembski 0:01f31e923fe2 339
Pawel Zarembski 0:01f31e923fe2 340 if (Offset == USBD_MSC_BlockGroup * USBD_MSC_BlockSize) {
Pawel Zarembski 0:01f31e923fe2 341 Offset = 0;
Pawel Zarembski 0:01f31e923fe2 342 Block += USBD_MSC_BlockGroup;
Pawel Zarembski 0:01f31e923fe2 343 }
Pawel Zarembski 0:01f31e923fe2 344
Pawel Zarembski 0:01f31e923fe2 345 USBD_MSC_CSW.dDataResidue -= BulkLen;
Pawel Zarembski 0:01f31e923fe2 346
Pawel Zarembski 0:01f31e923fe2 347 if (!BulkLen) {
Pawel Zarembski 0:01f31e923fe2 348 return;
Pawel Zarembski 0:01f31e923fe2 349 }
Pawel Zarembski 0:01f31e923fe2 350
Pawel Zarembski 0:01f31e923fe2 351 if ((Length == 0) || (BulkStage == MSC_BS_CSW)) {
Pawel Zarembski 0:01f31e923fe2 352 USBD_MSC_CSW.bStatus = (MemOK) ? CSW_CMD_PASSED : CSW_CMD_FAILED;
Pawel Zarembski 0:01f31e923fe2 353 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 354 }
Pawel Zarembski 0:01f31e923fe2 355 }
Pawel Zarembski 0:01f31e923fe2 356
Pawel Zarembski 0:01f31e923fe2 357
Pawel Zarembski 0:01f31e923fe2 358 /*
Pawel Zarembski 0:01f31e923fe2 359 * USB Device MSC SCSI Read/Write Setup Callback
Pawel Zarembski 0:01f31e923fe2 360 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 361 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 362 */
Pawel Zarembski 0:01f31e923fe2 363
Pawel Zarembski 0:01f31e923fe2 364 BOOL USBD_MSC_RWSetup(void)
Pawel Zarembski 0:01f31e923fe2 365 {
Pawel Zarembski 0:01f31e923fe2 366 U32 n;
Pawel Zarembski 0:01f31e923fe2 367 /* Logical Block Address of First Block */
Pawel Zarembski 0:01f31e923fe2 368 n = (USBD_MSC_CBW.CB[2] << 24) |
Pawel Zarembski 0:01f31e923fe2 369 (USBD_MSC_CBW.CB[3] << 16) |
Pawel Zarembski 0:01f31e923fe2 370 (USBD_MSC_CBW.CB[4] << 8) |
Pawel Zarembski 0:01f31e923fe2 371 (USBD_MSC_CBW.CB[5] << 0);
Pawel Zarembski 0:01f31e923fe2 372 Block = n;
Pawel Zarembski 0:01f31e923fe2 373 Offset = 0;
Pawel Zarembski 0:01f31e923fe2 374
Pawel Zarembski 0:01f31e923fe2 375 /* Number of Blocks to transfer */
Pawel Zarembski 0:01f31e923fe2 376 switch (USBD_MSC_CBW.CB[0]) {
Pawel Zarembski 0:01f31e923fe2 377 case SCSI_WRITE10:
Pawel Zarembski 0:01f31e923fe2 378 case SCSI_VERIFY10:
Pawel Zarembski 0:01f31e923fe2 379 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 380 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 381 }
Pawel Zarembski 0:01f31e923fe2 382
Pawel Zarembski 0:01f31e923fe2 383 case SCSI_READ10:
Pawel Zarembski 0:01f31e923fe2 384 n = (USBD_MSC_CBW.CB[7] << 8) |
Pawel Zarembski 0:01f31e923fe2 385 (USBD_MSC_CBW.CB[8] << 0);
Pawel Zarembski 0:01f31e923fe2 386 break;
Pawel Zarembski 0:01f31e923fe2 387
Pawel Zarembski 0:01f31e923fe2 388 case SCSI_WRITE12:
Pawel Zarembski 0:01f31e923fe2 389 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 390 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 391 }
Pawel Zarembski 0:01f31e923fe2 392
Pawel Zarembski 0:01f31e923fe2 393 case SCSI_READ12:
Pawel Zarembski 0:01f31e923fe2 394 n = (USBD_MSC_CBW.CB[6] << 24) |
Pawel Zarembski 0:01f31e923fe2 395 (USBD_MSC_CBW.CB[7] << 16) |
Pawel Zarembski 0:01f31e923fe2 396 (USBD_MSC_CBW.CB[8] << 8) |
Pawel Zarembski 0:01f31e923fe2 397 (USBD_MSC_CBW.CB[9] << 0);
Pawel Zarembski 0:01f31e923fe2 398 break;
Pawel Zarembski 0:01f31e923fe2 399 }
Pawel Zarembski 0:01f31e923fe2 400
Pawel Zarembski 0:01f31e923fe2 401 Length = n * USBD_MSC_BlockSize;
Pawel Zarembski 0:01f31e923fe2 402
Pawel Zarembski 0:01f31e923fe2 403 if (USBD_MSC_CBW.dDataLength == 0) { /* host requests no data */
Pawel Zarembski 0:01f31e923fe2 404 USBD_MSC_CSW.bStatus = CSW_CMD_FAILED;
Pawel Zarembski 0:01f31e923fe2 405 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 406 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 407 }
Pawel Zarembski 0:01f31e923fe2 408
Pawel Zarembski 0:01f31e923fe2 409 if (USBD_MSC_CBW.dDataLength != Length) {
Pawel Zarembski 0:01f31e923fe2 410 if ((USBD_MSC_CBW.bmFlags & 0x80) != 0) { /* stall appropriate EP */
Pawel Zarembski 0:01f31e923fe2 411 USBD_MSC_SetStallEP(usbd_msc_ep_bulkin | 0x80);
Pawel Zarembski 0:01f31e923fe2 412 } else {
Pawel Zarembski 0:01f31e923fe2 413 USBD_MSC_SetStallEP(usbd_msc_ep_bulkout);
Pawel Zarembski 0:01f31e923fe2 414 }
Pawel Zarembski 0:01f31e923fe2 415
Pawel Zarembski 0:01f31e923fe2 416 USBD_MSC_CSW.bStatus = CSW_CMD_FAILED;
Pawel Zarembski 0:01f31e923fe2 417 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 418 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 419 }
Pawel Zarembski 0:01f31e923fe2 420
Pawel Zarembski 0:01f31e923fe2 421 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 422 }
Pawel Zarembski 0:01f31e923fe2 423
Pawel Zarembski 0:01f31e923fe2 424
Pawel Zarembski 0:01f31e923fe2 425 /*
Pawel Zarembski 0:01f31e923fe2 426 * USB Device Check Data IN Format
Pawel Zarembski 0:01f31e923fe2 427 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 428 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 429 */
Pawel Zarembski 0:01f31e923fe2 430
Pawel Zarembski 0:01f31e923fe2 431 BOOL USBD_MSC_DataInFormat(void)
Pawel Zarembski 0:01f31e923fe2 432 {
Pawel Zarembski 0:01f31e923fe2 433 if (USBD_MSC_CBW.dDataLength == 0) {
Pawel Zarembski 0:01f31e923fe2 434 USBD_MSC_CSW.bStatus = CSW_PHASE_ERROR;
Pawel Zarembski 0:01f31e923fe2 435 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 436 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 437 }
Pawel Zarembski 0:01f31e923fe2 438
Pawel Zarembski 0:01f31e923fe2 439 if ((USBD_MSC_CBW.bmFlags & 0x80) == 0) {
Pawel Zarembski 0:01f31e923fe2 440 USBD_MSC_SetStallEP(usbd_msc_ep_bulkout);
Pawel Zarembski 0:01f31e923fe2 441 USBD_MSC_CSW.bStatus = CSW_PHASE_ERROR;
Pawel Zarembski 0:01f31e923fe2 442 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 443 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 444 }
Pawel Zarembski 0:01f31e923fe2 445
Pawel Zarembski 0:01f31e923fe2 446 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 447 }
Pawel Zarembski 0:01f31e923fe2 448
Pawel Zarembski 0:01f31e923fe2 449
Pawel Zarembski 0:01f31e923fe2 450 /*
Pawel Zarembski 0:01f31e923fe2 451 * USB Device Perform Data IN Transfer
Pawel Zarembski 0:01f31e923fe2 452 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 453 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 454 */
Pawel Zarembski 0:01f31e923fe2 455
Pawel Zarembski 0:01f31e923fe2 456 void USBD_MSC_DataInTransfer(void)
Pawel Zarembski 0:01f31e923fe2 457 {
Pawel Zarembski 0:01f31e923fe2 458 if (BulkLen >= USBD_MSC_CBW.dDataLength) {
Pawel Zarembski 0:01f31e923fe2 459 BulkLen = USBD_MSC_CBW.dDataLength;
Pawel Zarembski 0:01f31e923fe2 460 BulkStage = MSC_BS_DATA_IN_LAST;
Pawel Zarembski 0:01f31e923fe2 461 } else {
Pawel Zarembski 0:01f31e923fe2 462 BulkStage = MSC_BS_DATA_IN_LAST_STALL; /* short or zero packet */
Pawel Zarembski 0:01f31e923fe2 463 }
Pawel Zarembski 0:01f31e923fe2 464
Pawel Zarembski 0:01f31e923fe2 465 USBD_WriteEP(usbd_msc_ep_bulkin | 0x80, USBD_MSC_BulkBuf, BulkLen);
Pawel Zarembski 0:01f31e923fe2 466 USBD_MSC_CSW.dDataResidue -= BulkLen;
Pawel Zarembski 0:01f31e923fe2 467 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED;
Pawel Zarembski 0:01f31e923fe2 468 }
Pawel Zarembski 0:01f31e923fe2 469
Pawel Zarembski 0:01f31e923fe2 470
Pawel Zarembski 0:01f31e923fe2 471 /*
Pawel Zarembski 0:01f31e923fe2 472 * USB Device MSC SCSI Test Unit Ready Callback
Pawel Zarembski 0:01f31e923fe2 473 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 474 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 475 */
Pawel Zarembski 0:01f31e923fe2 476
Pawel Zarembski 0:01f31e923fe2 477 void USBD_MSC_TestUnitReady(void)
Pawel Zarembski 0:01f31e923fe2 478 {
Pawel Zarembski 0:01f31e923fe2 479 if (USBD_MSC_CBW.dDataLength != 0) {
Pawel Zarembski 0:01f31e923fe2 480 if ((USBD_MSC_CBW.bmFlags & 0x80) != 0) {
Pawel Zarembski 0:01f31e923fe2 481 USBD_MSC_SetStallEP(usbd_msc_ep_bulkin | 0x80);
Pawel Zarembski 0:01f31e923fe2 482 } else {
Pawel Zarembski 0:01f31e923fe2 483 USBD_MSC_SetStallEP(usbd_msc_ep_bulkout);
Pawel Zarembski 0:01f31e923fe2 484 }
Pawel Zarembski 0:01f31e923fe2 485
Pawel Zarembski 0:01f31e923fe2 486 USBD_MSC_CSW.bStatus = CSW_CMD_FAILED;
Pawel Zarembski 0:01f31e923fe2 487 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 488 return;
Pawel Zarembski 0:01f31e923fe2 489 }
Pawel Zarembski 0:01f31e923fe2 490
Pawel Zarembski 0:01f31e923fe2 491 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 492 return;
Pawel Zarembski 0:01f31e923fe2 493 }
Pawel Zarembski 0:01f31e923fe2 494
Pawel Zarembski 0:01f31e923fe2 495 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED;
Pawel Zarembski 0:01f31e923fe2 496 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 497 }
Pawel Zarembski 0:01f31e923fe2 498
Pawel Zarembski 0:01f31e923fe2 499
Pawel Zarembski 0:01f31e923fe2 500 /*
Pawel Zarembski 0:01f31e923fe2 501 * USB Device MSC SCSI Request Sense Callback
Pawel Zarembski 0:01f31e923fe2 502 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 503 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 504 */
Pawel Zarembski 0:01f31e923fe2 505
Pawel Zarembski 0:01f31e923fe2 506 void USBD_MSC_RequestSense(void)
Pawel Zarembski 0:01f31e923fe2 507 {
Pawel Zarembski 0:01f31e923fe2 508 if (!USBD_MSC_DataInFormat()) {
Pawel Zarembski 0:01f31e923fe2 509 return;
Pawel Zarembski 0:01f31e923fe2 510 }
Pawel Zarembski 0:01f31e923fe2 511
Pawel Zarembski 0:01f31e923fe2 512 USBD_MSC_BulkBuf[ 0] = 0x70; /* Response Code */
Pawel Zarembski 0:01f31e923fe2 513 USBD_MSC_BulkBuf[ 1] = 0x00;
Pawel Zarembski 0:01f31e923fe2 514
Pawel Zarembski 0:01f31e923fe2 515 if ((USBD_MSC_MediaReadyEx ^ USBD_MSC_MediaReady) & USBD_MSC_MediaReady) { /* If media state changed to ready */
Pawel Zarembski 0:01f31e923fe2 516 USBD_MSC_BulkBuf[ 2] = 0x06; /* UNIT ATTENTION */
Pawel Zarembski 0:01f31e923fe2 517 USBD_MSC_BulkBuf[12] = 0x28; /* Additional Sense Code: Not ready to ready transition */
Pawel Zarembski 0:01f31e923fe2 518 USBD_MSC_BulkBuf[13] = 0x00; /* Additional Sense Code Qualifier */
Pawel Zarembski 0:01f31e923fe2 519 USBD_MSC_MediaReadyEx = USBD_MSC_MediaReady;
Pawel Zarembski 0:01f31e923fe2 520 } else if (!USBD_MSC_MediaReady) {
Pawel Zarembski 0:01f31e923fe2 521 USBD_MSC_BulkBuf[ 2] = 0x02; /* NOT READY */
Pawel Zarembski 0:01f31e923fe2 522 USBD_MSC_BulkBuf[12] = 0x3A; /* Additional Sense Code: Medium not present */
Pawel Zarembski 0:01f31e923fe2 523 USBD_MSC_BulkBuf[13] = 0x00; /* Additional Sense Code Qualifier */
Pawel Zarembski 0:01f31e923fe2 524 } else {
Pawel Zarembski 0:01f31e923fe2 525 if (USBD_MSC_CSW.bStatus == CSW_CMD_PASSED) {
Pawel Zarembski 0:01f31e923fe2 526 USBD_MSC_BulkBuf[ 2] = 0x00; /* NO SENSE */
Pawel Zarembski 0:01f31e923fe2 527 USBD_MSC_BulkBuf[12] = 0x00; /* Additional Sense Code: No additional code */
Pawel Zarembski 0:01f31e923fe2 528 USBD_MSC_BulkBuf[13] = 0x00; /* Additional Sense Code Qualifier */
Pawel Zarembski 0:01f31e923fe2 529 } else {
Pawel Zarembski 0:01f31e923fe2 530 USBD_MSC_BulkBuf[ 2] = 0x05; /* ILLEGAL REQUEST */
Pawel Zarembski 0:01f31e923fe2 531 USBD_MSC_BulkBuf[12] = 0x20; /* Additional Sense Code: Invalid command */
Pawel Zarembski 0:01f31e923fe2 532 USBD_MSC_BulkBuf[13] = 0x00; /* Additional Sense Code Qualifier */
Pawel Zarembski 0:01f31e923fe2 533 }
Pawel Zarembski 0:01f31e923fe2 534 }
Pawel Zarembski 0:01f31e923fe2 535
Pawel Zarembski 0:01f31e923fe2 536 USBD_MSC_BulkBuf[ 3] = 0x00;
Pawel Zarembski 0:01f31e923fe2 537 USBD_MSC_BulkBuf[ 4] = 0x00;
Pawel Zarembski 0:01f31e923fe2 538 USBD_MSC_BulkBuf[ 5] = 0x00;
Pawel Zarembski 0:01f31e923fe2 539 USBD_MSC_BulkBuf[ 6] = 0x00;
Pawel Zarembski 0:01f31e923fe2 540 USBD_MSC_BulkBuf[ 7] = 0x0A; /* Additional Length */
Pawel Zarembski 0:01f31e923fe2 541 USBD_MSC_BulkBuf[ 8] = 0x00;
Pawel Zarembski 0:01f31e923fe2 542 USBD_MSC_BulkBuf[ 9] = 0x00;
Pawel Zarembski 0:01f31e923fe2 543 USBD_MSC_BulkBuf[10] = 0x00;
Pawel Zarembski 0:01f31e923fe2 544 USBD_MSC_BulkBuf[11] = 0x00;
Pawel Zarembski 0:01f31e923fe2 545 USBD_MSC_BulkBuf[14] = 0x00;
Pawel Zarembski 0:01f31e923fe2 546 USBD_MSC_BulkBuf[15] = 0x00;
Pawel Zarembski 0:01f31e923fe2 547 USBD_MSC_BulkBuf[16] = 0x00;
Pawel Zarembski 0:01f31e923fe2 548 USBD_MSC_BulkBuf[17] = 0x00;
Pawel Zarembski 0:01f31e923fe2 549 BulkLen = 18;
Pawel Zarembski 0:01f31e923fe2 550 USBD_MSC_DataInTransfer();
Pawel Zarembski 0:01f31e923fe2 551 }
Pawel Zarembski 0:01f31e923fe2 552
Pawel Zarembski 0:01f31e923fe2 553
Pawel Zarembski 0:01f31e923fe2 554 /*
Pawel Zarembski 0:01f31e923fe2 555 * USB Device MSC SCSI Inquiry Callback
Pawel Zarembski 0:01f31e923fe2 556 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 557 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 558 */
Pawel Zarembski 0:01f31e923fe2 559
Pawel Zarembski 0:01f31e923fe2 560 void USBD_MSC_Inquiry(void)
Pawel Zarembski 0:01f31e923fe2 561 {
Pawel Zarembski 0:01f31e923fe2 562 U8 i;
Pawel Zarembski 0:01f31e923fe2 563 U8 *ptr_str;
Pawel Zarembski 0:01f31e923fe2 564
Pawel Zarembski 0:01f31e923fe2 565 if (!USBD_MSC_DataInFormat()) {
Pawel Zarembski 0:01f31e923fe2 566 return;
Pawel Zarembski 0:01f31e923fe2 567 }
Pawel Zarembski 0:01f31e923fe2 568
Pawel Zarembski 0:01f31e923fe2 569 USBD_MSC_BulkBuf[ 0] = 0x00; /* Direct Access Device */
Pawel Zarembski 0:01f31e923fe2 570 USBD_MSC_BulkBuf[ 1] = 0x80; /* RMB = 1: Removable Medium */
Pawel Zarembski 0:01f31e923fe2 571 USBD_MSC_BulkBuf[ 2] = 0x02; /* Version: ANSI X3.131: 1994 */
Pawel Zarembski 0:01f31e923fe2 572 USBD_MSC_BulkBuf[ 3] = 0x02;
Pawel Zarembski 0:01f31e923fe2 573 USBD_MSC_BulkBuf[ 4] = 36 - 4; /* Additional Length */
Pawel Zarembski 0:01f31e923fe2 574 USBD_MSC_BulkBuf[ 5] = 0x00; /* SCCS = 0: No Storage Controller Component */
Pawel Zarembski 0:01f31e923fe2 575 USBD_MSC_BulkBuf[ 6] = 0x00;
Pawel Zarembski 0:01f31e923fe2 576 USBD_MSC_BulkBuf[ 7] = 0x00;
Pawel Zarembski 0:01f31e923fe2 577 ptr_str = (U8 *)usbd_msc_inquiry_data;
Pawel Zarembski 0:01f31e923fe2 578
Pawel Zarembski 0:01f31e923fe2 579 for (i = 8; i < 36; i++) { /* Product Information + */
Pawel Zarembski 0:01f31e923fe2 580 if (*ptr_str) { /* Product Revision Level */
Pawel Zarembski 0:01f31e923fe2 581 USBD_MSC_BulkBuf[i] = *ptr_str++;
Pawel Zarembski 0:01f31e923fe2 582 } else {
Pawel Zarembski 0:01f31e923fe2 583 USBD_MSC_BulkBuf[i] = ' ';
Pawel Zarembski 0:01f31e923fe2 584 }
Pawel Zarembski 0:01f31e923fe2 585 }
Pawel Zarembski 0:01f31e923fe2 586
Pawel Zarembski 0:01f31e923fe2 587 BulkLen = 36;
Pawel Zarembski 0:01f31e923fe2 588 USBD_MSC_DataInTransfer();
Pawel Zarembski 0:01f31e923fe2 589 }
Pawel Zarembski 0:01f31e923fe2 590
Pawel Zarembski 0:01f31e923fe2 591
Pawel Zarembski 0:01f31e923fe2 592 /*
Pawel Zarembski 0:01f31e923fe2 593 * USB Device MSC SCSI Start Stop Unit Callback
Pawel Zarembski 0:01f31e923fe2 594 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 595 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 596 */
Pawel Zarembski 0:01f31e923fe2 597
Pawel Zarembski 0:01f31e923fe2 598 void USBD_MSC_StartStopUnit(void)
Pawel Zarembski 0:01f31e923fe2 599 {
Pawel Zarembski 0:01f31e923fe2 600 if (!USBD_MSC_CBW.CB[3]) { /* If power condition modifier is 0 */
Pawel Zarembski 0:01f31e923fe2 601 USBD_MSC_MediaReady = USBD_MSC_CBW.CB[4] & 0x01; /* Media ready = START bit value */
Pawel Zarembski 0:01f31e923fe2 602 usbd_msc_start_stop(USBD_MSC_MediaReady);
Pawel Zarembski 0:01f31e923fe2 603 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED; /* Start Stop Unit -> pass */
Pawel Zarembski 0:01f31e923fe2 604 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 605 return;
Pawel Zarembski 0:01f31e923fe2 606 }
Pawel Zarembski 0:01f31e923fe2 607
Pawel Zarembski 0:01f31e923fe2 608 USBD_MSC_CSW.bStatus = CSW_CMD_FAILED; /* Start Stop Unit -> fail */
Pawel Zarembski 0:01f31e923fe2 609 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 610 }
Pawel Zarembski 0:01f31e923fe2 611
Pawel Zarembski 0:01f31e923fe2 612
Pawel Zarembski 0:01f31e923fe2 613 /*
Pawel Zarembski 0:01f31e923fe2 614 * USB Device MSC SCSI Media Removal Callback
Pawel Zarembski 0:01f31e923fe2 615 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 616 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 617 */
Pawel Zarembski 0:01f31e923fe2 618
Pawel Zarembski 0:01f31e923fe2 619 void USBD_MSC_MediaRemoval(void)
Pawel Zarembski 0:01f31e923fe2 620 {
Pawel Zarembski 0:01f31e923fe2 621 if (USBD_MSC_CBW.CB[4] & 1) { /* If prevent */
Pawel Zarembski 0:01f31e923fe2 622 USBD_MSC_CSW.bStatus = CSW_CMD_FAILED; /* Prevent media removal -> fail */
Pawel Zarembski 0:01f31e923fe2 623 } else { /* If allow */
Pawel Zarembski 0:01f31e923fe2 624 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED; /* Allow media removal -> pass */
Pawel Zarembski 0:01f31e923fe2 625 }
Pawel Zarembski 0:01f31e923fe2 626
Pawel Zarembski 0:01f31e923fe2 627 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 628 }
Pawel Zarembski 0:01f31e923fe2 629
Pawel Zarembski 0:01f31e923fe2 630
Pawel Zarembski 0:01f31e923fe2 631 /*
Pawel Zarembski 0:01f31e923fe2 632 * USB Device MSC SCSI Mode Sense (6-Byte) Callback
Pawel Zarembski 0:01f31e923fe2 633 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 634 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 635 */
Pawel Zarembski 0:01f31e923fe2 636
Pawel Zarembski 0:01f31e923fe2 637 void USBD_MSC_ModeSense6(void)
Pawel Zarembski 0:01f31e923fe2 638 {
Pawel Zarembski 0:01f31e923fe2 639 if (!USBD_MSC_DataInFormat()) {
Pawel Zarembski 0:01f31e923fe2 640 return;
Pawel Zarembski 0:01f31e923fe2 641 }
Pawel Zarembski 0:01f31e923fe2 642
Pawel Zarembski 0:01f31e923fe2 643 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 644 return;
Pawel Zarembski 0:01f31e923fe2 645 }
Pawel Zarembski 0:01f31e923fe2 646
Pawel Zarembski 0:01f31e923fe2 647 USBD_MSC_BulkBuf[ 0] = 0x03;
Pawel Zarembski 0:01f31e923fe2 648 USBD_MSC_BulkBuf[ 1] = 0x00;
Pawel Zarembski 0:01f31e923fe2 649 USBD_MSC_BulkBuf[ 2] = (USBD_MSC_ReadOnly << 7);
Pawel Zarembski 0:01f31e923fe2 650 USBD_MSC_BulkBuf[ 3] = 0x00;
Pawel Zarembski 0:01f31e923fe2 651 BulkLen = 4;
Pawel Zarembski 0:01f31e923fe2 652
Pawel Zarembski 0:01f31e923fe2 653 /* Win host requests maximum number of bytes but as all we have is 4 bytes we have
Pawel Zarembski 0:01f31e923fe2 654 to tell host back that it is all we have, that's why we correct residue */
Pawel Zarembski 0:01f31e923fe2 655 if (USBD_MSC_CSW.dDataResidue > BulkLen) {
Pawel Zarembski 0:01f31e923fe2 656 USBD_MSC_CBW.dDataLength = BulkLen;
Pawel Zarembski 0:01f31e923fe2 657 USBD_MSC_CSW.dDataResidue = BulkLen;
Pawel Zarembski 0:01f31e923fe2 658 }
Pawel Zarembski 0:01f31e923fe2 659
Pawel Zarembski 0:01f31e923fe2 660 USBD_MSC_DataInTransfer();
Pawel Zarembski 0:01f31e923fe2 661 }
Pawel Zarembski 0:01f31e923fe2 662
Pawel Zarembski 0:01f31e923fe2 663
Pawel Zarembski 0:01f31e923fe2 664 /*
Pawel Zarembski 0:01f31e923fe2 665 * USB Device MSC SCSI Mode Sense (10-Byte) Callback
Pawel Zarembski 0:01f31e923fe2 666 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 667 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 668 */
Pawel Zarembski 0:01f31e923fe2 669
Pawel Zarembski 0:01f31e923fe2 670 void USBD_MSC_ModeSense10(void)
Pawel Zarembski 0:01f31e923fe2 671 {
Pawel Zarembski 0:01f31e923fe2 672 if (!USBD_MSC_DataInFormat()) {
Pawel Zarembski 0:01f31e923fe2 673 return;
Pawel Zarembski 0:01f31e923fe2 674 }
Pawel Zarembski 0:01f31e923fe2 675
Pawel Zarembski 0:01f31e923fe2 676 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 677 return;
Pawel Zarembski 0:01f31e923fe2 678 }
Pawel Zarembski 0:01f31e923fe2 679
Pawel Zarembski 0:01f31e923fe2 680 USBD_MSC_BulkBuf[ 0] = 0x00;
Pawel Zarembski 0:01f31e923fe2 681 USBD_MSC_BulkBuf[ 1] = 0x06;
Pawel Zarembski 0:01f31e923fe2 682 USBD_MSC_BulkBuf[ 2] = 0x00;
Pawel Zarembski 0:01f31e923fe2 683 USBD_MSC_BulkBuf[ 3] = (USBD_MSC_ReadOnly << 7);
Pawel Zarembski 0:01f31e923fe2 684 USBD_MSC_BulkBuf[ 4] = 0x00;
Pawel Zarembski 0:01f31e923fe2 685 USBD_MSC_BulkBuf[ 5] = 0x00;
Pawel Zarembski 0:01f31e923fe2 686 USBD_MSC_BulkBuf[ 6] = 0x00;
Pawel Zarembski 0:01f31e923fe2 687 USBD_MSC_BulkBuf[ 7] = 0x00;
Pawel Zarembski 0:01f31e923fe2 688 BulkLen = 8;
Pawel Zarembski 0:01f31e923fe2 689
Pawel Zarembski 0:01f31e923fe2 690 /* Win host requests maximum number of bytes but as all we have is 8 bytes we have
Pawel Zarembski 0:01f31e923fe2 691 to tell host back that it is all we have, that's why we correct residue */
Pawel Zarembski 0:01f31e923fe2 692 if (USBD_MSC_CSW.dDataResidue > BulkLen) {
Pawel Zarembski 0:01f31e923fe2 693 USBD_MSC_CBW.dDataLength = BulkLen;
Pawel Zarembski 0:01f31e923fe2 694 USBD_MSC_CSW.dDataResidue = BulkLen;
Pawel Zarembski 0:01f31e923fe2 695 }
Pawel Zarembski 0:01f31e923fe2 696
Pawel Zarembski 0:01f31e923fe2 697 USBD_MSC_DataInTransfer();
Pawel Zarembski 0:01f31e923fe2 698 }
Pawel Zarembski 0:01f31e923fe2 699
Pawel Zarembski 0:01f31e923fe2 700
Pawel Zarembski 0:01f31e923fe2 701 /*
Pawel Zarembski 0:01f31e923fe2 702 * USB Device MSC SCSI Read Capacity Callback
Pawel Zarembski 0:01f31e923fe2 703 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 704 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 705 */
Pawel Zarembski 0:01f31e923fe2 706
Pawel Zarembski 0:01f31e923fe2 707 void USBD_MSC_ReadCapacity(void)
Pawel Zarembski 0:01f31e923fe2 708 {
Pawel Zarembski 0:01f31e923fe2 709 if (!USBD_MSC_DataInFormat()) {
Pawel Zarembski 0:01f31e923fe2 710 return;
Pawel Zarembski 0:01f31e923fe2 711 }
Pawel Zarembski 0:01f31e923fe2 712
Pawel Zarembski 0:01f31e923fe2 713 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 714 return;
Pawel Zarembski 0:01f31e923fe2 715 }
Pawel Zarembski 0:01f31e923fe2 716
Pawel Zarembski 0:01f31e923fe2 717 /* Last Logical Block */
Pawel Zarembski 0:01f31e923fe2 718 USBD_MSC_BulkBuf[ 0] = ((USBD_MSC_BlockCount - 1) >> 24) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 719 USBD_MSC_BulkBuf[ 1] = ((USBD_MSC_BlockCount - 1) >> 16) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 720 USBD_MSC_BulkBuf[ 2] = ((USBD_MSC_BlockCount - 1) >> 8) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 721 USBD_MSC_BulkBuf[ 3] = ((USBD_MSC_BlockCount - 1) >> 0) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 722 /* Block Length */
Pawel Zarembski 0:01f31e923fe2 723 USBD_MSC_BulkBuf[ 4] = (USBD_MSC_BlockSize >> 24) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 724 USBD_MSC_BulkBuf[ 5] = (USBD_MSC_BlockSize >> 16) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 725 USBD_MSC_BulkBuf[ 6] = (USBD_MSC_BlockSize >> 8) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 726 USBD_MSC_BulkBuf[ 7] = (USBD_MSC_BlockSize >> 0) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 727 BulkLen = 8;
Pawel Zarembski 0:01f31e923fe2 728 USBD_MSC_DataInTransfer();
Pawel Zarembski 0:01f31e923fe2 729 }
Pawel Zarembski 0:01f31e923fe2 730
Pawel Zarembski 0:01f31e923fe2 731
Pawel Zarembski 0:01f31e923fe2 732 /*
Pawel Zarembski 0:01f31e923fe2 733 * USB Device MSC SCSI Read Format Capacity Callback
Pawel Zarembski 0:01f31e923fe2 734 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 735 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 736 */
Pawel Zarembski 0:01f31e923fe2 737
Pawel Zarembski 0:01f31e923fe2 738 void USBD_MSC_ReadFormatCapacity(void)
Pawel Zarembski 0:01f31e923fe2 739 {
Pawel Zarembski 0:01f31e923fe2 740 if (!USBD_MSC_DataInFormat()) {
Pawel Zarembski 0:01f31e923fe2 741 return;
Pawel Zarembski 0:01f31e923fe2 742 }
Pawel Zarembski 0:01f31e923fe2 743
Pawel Zarembski 0:01f31e923fe2 744 if (!USBD_MSC_CheckMedia()) {
Pawel Zarembski 0:01f31e923fe2 745 return;
Pawel Zarembski 0:01f31e923fe2 746 }
Pawel Zarembski 0:01f31e923fe2 747
Pawel Zarembski 0:01f31e923fe2 748 USBD_MSC_BulkBuf[ 0] = 0x00;
Pawel Zarembski 0:01f31e923fe2 749 USBD_MSC_BulkBuf[ 1] = 0x00;
Pawel Zarembski 0:01f31e923fe2 750 USBD_MSC_BulkBuf[ 2] = 0x00;
Pawel Zarembski 0:01f31e923fe2 751 USBD_MSC_BulkBuf[ 3] = 0x08; /* Capacity List Length */
Pawel Zarembski 0:01f31e923fe2 752 /* Block Count */
Pawel Zarembski 0:01f31e923fe2 753 USBD_MSC_BulkBuf[ 4] = (USBD_MSC_BlockCount >> 24) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 754 USBD_MSC_BulkBuf[ 5] = (USBD_MSC_BlockCount >> 16) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 755 USBD_MSC_BulkBuf[ 6] = (USBD_MSC_BlockCount >> 8) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 756 USBD_MSC_BulkBuf[ 7] = (USBD_MSC_BlockCount >> 0) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 757 /* Block Length */
Pawel Zarembski 0:01f31e923fe2 758 USBD_MSC_BulkBuf[ 8] = 0x02; /* Descriptor Code: Formatted Media */
Pawel Zarembski 0:01f31e923fe2 759 USBD_MSC_BulkBuf[ 9] = (USBD_MSC_BlockSize >> 16) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 760 USBD_MSC_BulkBuf[10] = (USBD_MSC_BlockSize >> 8) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 761 USBD_MSC_BulkBuf[11] = (USBD_MSC_BlockSize >> 0) & 0xFF;
Pawel Zarembski 0:01f31e923fe2 762 BulkLen = 12;
Pawel Zarembski 0:01f31e923fe2 763
Pawel Zarembski 0:01f31e923fe2 764 /* Win host requests maximum number of bytes but as all we have is 12 bytes we have
Pawel Zarembski 0:01f31e923fe2 765 to tell host back that it is all we have, that's why we correct residue */
Pawel Zarembski 0:01f31e923fe2 766 if (USBD_MSC_CSW.dDataResidue > BulkLen) {
Pawel Zarembski 0:01f31e923fe2 767 USBD_MSC_CBW.dDataLength = BulkLen;
Pawel Zarembski 0:01f31e923fe2 768 USBD_MSC_CSW.dDataResidue = BulkLen;
Pawel Zarembski 0:01f31e923fe2 769 }
Pawel Zarembski 0:01f31e923fe2 770
Pawel Zarembski 0:01f31e923fe2 771 USBD_MSC_DataInTransfer();
Pawel Zarembski 0:01f31e923fe2 772 }
Pawel Zarembski 0:01f31e923fe2 773
Pawel Zarembski 0:01f31e923fe2 774
Pawel Zarembski 0:01f31e923fe2 775 /*
Pawel Zarembski 0:01f31e923fe2 776 * USB Device MSC SCSI Synchronize Cache (10/16-Byte) Callback
Pawel Zarembski 0:01f31e923fe2 777 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 778 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 779 */
Pawel Zarembski 0:01f31e923fe2 780
Pawel Zarembski 0:01f31e923fe2 781 void USBD_MSC_SynchronizeCache(void)
Pawel Zarembski 0:01f31e923fe2 782 {
Pawel Zarembski 0:01f31e923fe2 783 /* Synchronize check always passes as we always write data dirrectly
Pawel Zarembski 0:01f31e923fe2 784 so cache is always synchronized */
Pawel Zarembski 0:01f31e923fe2 785 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED;
Pawel Zarembski 0:01f31e923fe2 786 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 787 }
Pawel Zarembski 0:01f31e923fe2 788
Pawel Zarembski 0:01f31e923fe2 789
Pawel Zarembski 0:01f31e923fe2 790 /*
Pawel Zarembski 0:01f31e923fe2 791 * USB Device MSC ATA Pass-Through Callback
Pawel Zarembski 0:01f31e923fe2 792 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 793 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 794 */
Pawel Zarembski 0:01f31e923fe2 795
Pawel Zarembski 0:01f31e923fe2 796 void USBD_MSC_ATAPassThrough(void)
Pawel Zarembski 0:01f31e923fe2 797 {
Pawel Zarembski 0:01f31e923fe2 798 if (!USBD_MSC_DataInFormat()) {
Pawel Zarembski 0:01f31e923fe2 799 return;
Pawel Zarembski 0:01f31e923fe2 800 }
Pawel Zarembski 0:01f31e923fe2 801
Pawel Zarembski 0:01f31e923fe2 802 USBD_MSC_BulkBuf[ 0] = 0x02;
Pawel Zarembski 0:01f31e923fe2 803 USBD_MSC_BulkBuf[ 1] = 0x02;
Pawel Zarembski 0:01f31e923fe2 804 BulkLen = 2;
Pawel Zarembski 0:01f31e923fe2 805 BulkStage = MSC_BS_DATA_IN_LAST;
Pawel Zarembski 0:01f31e923fe2 806
Pawel Zarembski 0:01f31e923fe2 807 /* Win host requests maximum number of bytes but as all we have is 2 bytes we have
Pawel Zarembski 0:01f31e923fe2 808 to tell host back that it is all we have, that's why we correct residue */
Pawel Zarembski 0:01f31e923fe2 809 if (USBD_MSC_CSW.dDataResidue > BulkLen) {
Pawel Zarembski 0:01f31e923fe2 810 USBD_MSC_CBW.dDataLength = BulkLen;
Pawel Zarembski 0:01f31e923fe2 811 USBD_MSC_CSW.dDataResidue = BulkLen;
Pawel Zarembski 0:01f31e923fe2 812 }
Pawel Zarembski 0:01f31e923fe2 813
Pawel Zarembski 0:01f31e923fe2 814 USBD_WriteEP(usbd_msc_ep_bulkin | 0x80, USBD_MSC_BulkBuf, BulkLen);
Pawel Zarembski 0:01f31e923fe2 815 USBD_MSC_CSW.dDataResidue -= BulkLen;
Pawel Zarembski 0:01f31e923fe2 816 USBD_MSC_CSW.bStatus = CSW_CMD_FAILED;
Pawel Zarembski 0:01f31e923fe2 817 }
Pawel Zarembski 0:01f31e923fe2 818
Pawel Zarembski 0:01f31e923fe2 819 /*
Pawel Zarembski 0:01f31e923fe2 820 * USB Device MSC Service Action (16-Byte) Callback
Pawel Zarembski 0:01f31e923fe2 821 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 822 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 823 */
Pawel Zarembski 0:01f31e923fe2 824
Pawel Zarembski 0:01f31e923fe2 825
Pawel Zarembski 0:01f31e923fe2 826 void USBD_MSC_ServiceActionIn16(void)
Pawel Zarembski 0:01f31e923fe2 827 {
Pawel Zarembski 0:01f31e923fe2 828 if (!USBD_MSC_DataInFormat()) {
Pawel Zarembski 0:01f31e923fe2 829 return;
Pawel Zarembski 0:01f31e923fe2 830 }
Pawel Zarembski 0:01f31e923fe2 831
Pawel Zarembski 0:01f31e923fe2 832 USBD_MSC_BulkBuf[ 0] = 0x20;
Pawel Zarembski 0:01f31e923fe2 833 USBD_MSC_BulkBuf[ 1] = 0x00;
Pawel Zarembski 0:01f31e923fe2 834 USBD_MSC_BulkBuf[31] = 0x00;
Pawel Zarembski 0:01f31e923fe2 835 BulkLen = 32;
Pawel Zarembski 0:01f31e923fe2 836 BulkStage = MSC_BS_DATA_IN_LAST;
Pawel Zarembski 0:01f31e923fe2 837 USBD_WriteEP(usbd_msc_ep_bulkin | 0x80, USBD_MSC_BulkBuf, BulkLen);
Pawel Zarembski 0:01f31e923fe2 838 USBD_MSC_CSW.dDataResidue -= BulkLen;
Pawel Zarembski 0:01f31e923fe2 839 USBD_MSC_CSW.bStatus = CSW_CMD_FAILED;
Pawel Zarembski 0:01f31e923fe2 840 }
Pawel Zarembski 0:01f31e923fe2 841
Pawel Zarembski 0:01f31e923fe2 842
Pawel Zarembski 0:01f31e923fe2 843 /*
Pawel Zarembski 0:01f31e923fe2 844 * USB Device MSC Get Command Block Wrapper Callback
Pawel Zarembski 0:01f31e923fe2 845 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 846 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 847 */
Pawel Zarembski 0:01f31e923fe2 848
Pawel Zarembski 0:01f31e923fe2 849 void USBD_MSC_GetCBW(void)
Pawel Zarembski 0:01f31e923fe2 850 {
Pawel Zarembski 0:01f31e923fe2 851 U32 n;
Pawel Zarembski 0:01f31e923fe2 852 U32 copy_size;
Pawel Zarembski 0:01f31e923fe2 853 copy_size = MIN(BulkLen, sizeof(USBD_MSC_CBW));
Pawel Zarembski 0:01f31e923fe2 854
Pawel Zarembski 0:01f31e923fe2 855 for (n = 0; n < copy_size; n++) {
Pawel Zarembski 0:01f31e923fe2 856 *((U8 *)&USBD_MSC_CBW + n) = USBD_MSC_BulkBuf[n];
Pawel Zarembski 0:01f31e923fe2 857 }
Pawel Zarembski 0:01f31e923fe2 858
Pawel Zarembski 0:01f31e923fe2 859 if ((BulkLen == sizeof(USBD_MSC_CBW)) && (USBD_MSC_CBW.dSignature == MSC_CBW_Signature)) {
Pawel Zarembski 0:01f31e923fe2 860 /* Valid USBD_MSC_CBW */
Pawel Zarembski 0:01f31e923fe2 861 USBD_MSC_CSW.dTag = USBD_MSC_CBW.dTag;
Pawel Zarembski 0:01f31e923fe2 862 USBD_MSC_CSW.dDataResidue = USBD_MSC_CBW.dDataLength;
Pawel Zarembski 0:01f31e923fe2 863
Pawel Zarembski 0:01f31e923fe2 864 if ((USBD_MSC_CBW.bLUN > 0) ||
Pawel Zarembski 0:01f31e923fe2 865 (USBD_MSC_CBW.bCBLength < 1) ||
Pawel Zarembski 0:01f31e923fe2 866 (USBD_MSC_CBW.bCBLength > 16)) {
Pawel Zarembski 0:01f31e923fe2 867 fail:
Pawel Zarembski 0:01f31e923fe2 868 USBD_MSC_CSW.bStatus = CSW_CMD_FAILED;
Pawel Zarembski 0:01f31e923fe2 869 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 870 } else {
Pawel Zarembski 0:01f31e923fe2 871 switch (USBD_MSC_CBW.CB[0]) {
Pawel Zarembski 0:01f31e923fe2 872 case SCSI_TEST_UNIT_READY:
Pawel Zarembski 0:01f31e923fe2 873 USBD_MSC_TestUnitReady();
Pawel Zarembski 0:01f31e923fe2 874 break;
Pawel Zarembski 0:01f31e923fe2 875
Pawel Zarembski 0:01f31e923fe2 876 case SCSI_REQUEST_SENSE:
Pawel Zarembski 0:01f31e923fe2 877 USBD_MSC_RequestSense();
Pawel Zarembski 0:01f31e923fe2 878 break;
Pawel Zarembski 0:01f31e923fe2 879
Pawel Zarembski 0:01f31e923fe2 880 case SCSI_FORMAT_UNIT:
Pawel Zarembski 0:01f31e923fe2 881 goto fail;
Pawel Zarembski 0:01f31e923fe2 882
Pawel Zarembski 0:01f31e923fe2 883 case SCSI_INQUIRY:
Pawel Zarembski 0:01f31e923fe2 884 USBD_MSC_Inquiry();
Pawel Zarembski 0:01f31e923fe2 885 break;
Pawel Zarembski 0:01f31e923fe2 886
Pawel Zarembski 0:01f31e923fe2 887 case SCSI_START_STOP_UNIT:
Pawel Zarembski 0:01f31e923fe2 888 USBD_MSC_StartStopUnit();
Pawel Zarembski 0:01f31e923fe2 889 break;
Pawel Zarembski 0:01f31e923fe2 890
Pawel Zarembski 0:01f31e923fe2 891 case SCSI_MEDIA_REMOVAL:
Pawel Zarembski 0:01f31e923fe2 892 USBD_MSC_MediaRemoval();
Pawel Zarembski 0:01f31e923fe2 893 break;
Pawel Zarembski 0:01f31e923fe2 894
Pawel Zarembski 0:01f31e923fe2 895 case SCSI_MODE_SELECT6:
Pawel Zarembski 0:01f31e923fe2 896 goto fail;
Pawel Zarembski 0:01f31e923fe2 897
Pawel Zarembski 0:01f31e923fe2 898 case SCSI_MODE_SENSE6:
Pawel Zarembski 0:01f31e923fe2 899 USBD_MSC_ModeSense6();
Pawel Zarembski 0:01f31e923fe2 900 break;
Pawel Zarembski 0:01f31e923fe2 901
Pawel Zarembski 0:01f31e923fe2 902 case SCSI_MODE_SELECT10:
Pawel Zarembski 0:01f31e923fe2 903 goto fail;
Pawel Zarembski 0:01f31e923fe2 904
Pawel Zarembski 0:01f31e923fe2 905 case SCSI_MODE_SENSE10:
Pawel Zarembski 0:01f31e923fe2 906 USBD_MSC_ModeSense10();
Pawel Zarembski 0:01f31e923fe2 907 break;
Pawel Zarembski 0:01f31e923fe2 908
Pawel Zarembski 0:01f31e923fe2 909 case SCSI_READ_FORMAT_CAPACITIES:
Pawel Zarembski 0:01f31e923fe2 910 USBD_MSC_ReadFormatCapacity();
Pawel Zarembski 0:01f31e923fe2 911 break;
Pawel Zarembski 0:01f31e923fe2 912
Pawel Zarembski 0:01f31e923fe2 913 case SCSI_READ_CAPACITY:
Pawel Zarembski 0:01f31e923fe2 914 USBD_MSC_ReadCapacity();
Pawel Zarembski 0:01f31e923fe2 915 break;
Pawel Zarembski 0:01f31e923fe2 916
Pawel Zarembski 0:01f31e923fe2 917 case SCSI_ATA_COMMAND_PASS_THROUGH12:
Pawel Zarembski 0:01f31e923fe2 918 USBD_MSC_ATAPassThrough();
Pawel Zarembski 0:01f31e923fe2 919 break;
Pawel Zarembski 0:01f31e923fe2 920
Pawel Zarembski 0:01f31e923fe2 921 case SCSI_SERVICE_ACTION_IN16:
Pawel Zarembski 0:01f31e923fe2 922 USBD_MSC_ServiceActionIn16();
Pawel Zarembski 0:01f31e923fe2 923 break;
Pawel Zarembski 0:01f31e923fe2 924
Pawel Zarembski 0:01f31e923fe2 925 case SCSI_READ10:
Pawel Zarembski 0:01f31e923fe2 926 case SCSI_READ12:
Pawel Zarembski 0:01f31e923fe2 927 if (USBD_MSC_RWSetup()) {
Pawel Zarembski 0:01f31e923fe2 928 if ((USBD_MSC_CBW.bmFlags & 0x80) != 0) {
Pawel Zarembski 0:01f31e923fe2 929 BulkStage = MSC_BS_DATA_IN;
Pawel Zarembski 0:01f31e923fe2 930 USBD_MSC_MemoryRead();
Pawel Zarembski 0:01f31e923fe2 931 } else { /* direction mismatch */
Pawel Zarembski 0:01f31e923fe2 932 USBD_MSC_SetStallEP(usbd_msc_ep_bulkout);
Pawel Zarembski 0:01f31e923fe2 933 USBD_MSC_CSW.bStatus = CSW_PHASE_ERROR;
Pawel Zarembski 0:01f31e923fe2 934 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 935 }
Pawel Zarembski 0:01f31e923fe2 936 }
Pawel Zarembski 0:01f31e923fe2 937
Pawel Zarembski 0:01f31e923fe2 938 break;
Pawel Zarembski 0:01f31e923fe2 939
Pawel Zarembski 0:01f31e923fe2 940 case SCSI_WRITE10:
Pawel Zarembski 0:01f31e923fe2 941 case SCSI_WRITE12:
Pawel Zarembski 0:01f31e923fe2 942 if (USBD_MSC_RWSetup()) {
Pawel Zarembski 0:01f31e923fe2 943 if ((USBD_MSC_CBW.bmFlags & 0x80) == 0) {
Pawel Zarembski 0:01f31e923fe2 944 BulkStage = MSC_BS_DATA_OUT;
Pawel Zarembski 0:01f31e923fe2 945 } else { /* direction mismatch */
Pawel Zarembski 0:01f31e923fe2 946 USBD_MSC_SetStallEP(usbd_msc_ep_bulkin | 0x80);
Pawel Zarembski 0:01f31e923fe2 947 USBD_MSC_CSW.bStatus = CSW_PHASE_ERROR;
Pawel Zarembski 0:01f31e923fe2 948 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 949 }
Pawel Zarembski 0:01f31e923fe2 950 }
Pawel Zarembski 0:01f31e923fe2 951
Pawel Zarembski 0:01f31e923fe2 952 break;
Pawel Zarembski 0:01f31e923fe2 953
Pawel Zarembski 0:01f31e923fe2 954 case SCSI_VERIFY10:
Pawel Zarembski 0:01f31e923fe2 955 if ((USBD_MSC_CBW.CB[1] & 0x02) == 0) {
Pawel Zarembski 0:01f31e923fe2 956 // BYTCHK = 0 -> CRC Check (not implemented)
Pawel Zarembski 0:01f31e923fe2 957 USBD_MSC_CSW.bStatus = CSW_CMD_PASSED;
Pawel Zarembski 0:01f31e923fe2 958 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 959 break;
Pawel Zarembski 0:01f31e923fe2 960 }
Pawel Zarembski 0:01f31e923fe2 961
Pawel Zarembski 0:01f31e923fe2 962 if (USBD_MSC_RWSetup()) {
Pawel Zarembski 0:01f31e923fe2 963 if ((USBD_MSC_CBW.bmFlags & 0x80) == 0) {
Pawel Zarembski 0:01f31e923fe2 964 BulkStage = MSC_BS_DATA_OUT;
Pawel Zarembski 0:01f31e923fe2 965 MemOK = __TRUE;
Pawel Zarembski 0:01f31e923fe2 966 } else {
Pawel Zarembski 0:01f31e923fe2 967 USBD_MSC_SetStallEP(usbd_msc_ep_bulkin | 0x80);
Pawel Zarembski 0:01f31e923fe2 968 USBD_MSC_CSW.bStatus = CSW_PHASE_ERROR;
Pawel Zarembski 0:01f31e923fe2 969 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 970 }
Pawel Zarembski 0:01f31e923fe2 971 }
Pawel Zarembski 0:01f31e923fe2 972
Pawel Zarembski 0:01f31e923fe2 973 break;
Pawel Zarembski 0:01f31e923fe2 974
Pawel Zarembski 0:01f31e923fe2 975 case SCSI_SYNC_CACHE10:
Pawel Zarembski 0:01f31e923fe2 976 case SCSI_SYNC_CACHE16:
Pawel Zarembski 0:01f31e923fe2 977 USBD_MSC_SynchronizeCache();
Pawel Zarembski 0:01f31e923fe2 978 break;
Pawel Zarembski 0:01f31e923fe2 979
Pawel Zarembski 0:01f31e923fe2 980 case SCSI_REPORT_ID_INFO:
Pawel Zarembski 0:01f31e923fe2 981 USBD_MSC_SetStallEP(usbd_msc_ep_bulkin | 0x80);
Pawel Zarembski 0:01f31e923fe2 982 goto fail;
Pawel Zarembski 0:01f31e923fe2 983
Pawel Zarembski 0:01f31e923fe2 984 default:
Pawel Zarembski 0:01f31e923fe2 985 goto fail;
Pawel Zarembski 0:01f31e923fe2 986 }
Pawel Zarembski 0:01f31e923fe2 987 }
Pawel Zarembski 0:01f31e923fe2 988 } else {
Pawel Zarembski 0:01f31e923fe2 989 /* Invalid USBD_MSC_CBW */
Pawel Zarembski 0:01f31e923fe2 990 USBD_MSC_SetStallEP(usbd_msc_ep_bulkin | 0x80);
Pawel Zarembski 0:01f31e923fe2 991 /* set EP to stay stalled */
Pawel Zarembski 0:01f31e923fe2 992 USBD_EndPointStall |= ((1 << 16) << (usbd_msc_ep_bulkin & 0x0F));
Pawel Zarembski 0:01f31e923fe2 993 USBD_MSC_SetStallEP(usbd_msc_ep_bulkout);
Pawel Zarembski 0:01f31e923fe2 994 /* set EP to stay stalled */
Pawel Zarembski 0:01f31e923fe2 995 USBD_EndPointStall |= 1 << usbd_msc_ep_bulkout;
Pawel Zarembski 0:01f31e923fe2 996 BulkStage = MSC_BS_ERROR;
Pawel Zarembski 0:01f31e923fe2 997 }
Pawel Zarembski 0:01f31e923fe2 998 }
Pawel Zarembski 0:01f31e923fe2 999
Pawel Zarembski 0:01f31e923fe2 1000
Pawel Zarembski 0:01f31e923fe2 1001 /*
Pawel Zarembski 0:01f31e923fe2 1002 * USB Device MSC Set Command Status Wrapper Callback
Pawel Zarembski 0:01f31e923fe2 1003 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 1004 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 1005 */
Pawel Zarembski 0:01f31e923fe2 1006
Pawel Zarembski 0:01f31e923fe2 1007 void USBD_MSC_SetCSW(void)
Pawel Zarembski 0:01f31e923fe2 1008 {
Pawel Zarembski 0:01f31e923fe2 1009 USBD_MSC_CSW.dSignature = MSC_CSW_Signature;
Pawel Zarembski 0:01f31e923fe2 1010 USBD_WriteEP(usbd_msc_ep_bulkin | 0x80, (U8 *)&USBD_MSC_CSW, sizeof(USBD_MSC_CSW));
Pawel Zarembski 0:01f31e923fe2 1011 BulkStage = MSC_BS_CSW;
Pawel Zarembski 0:01f31e923fe2 1012 }
Pawel Zarembski 0:01f31e923fe2 1013
Pawel Zarembski 0:01f31e923fe2 1014
Pawel Zarembski 0:01f31e923fe2 1015 /*
Pawel Zarembski 0:01f31e923fe2 1016 * USB Device MSC Bulk In Callback
Pawel Zarembski 0:01f31e923fe2 1017 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 1018 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 1019 */
Pawel Zarembski 0:01f31e923fe2 1020
Pawel Zarembski 0:01f31e923fe2 1021 void USBD_MSC_BulkIn(void)
Pawel Zarembski 0:01f31e923fe2 1022 {
Pawel Zarembski 0:01f31e923fe2 1023 switch (BulkStage) {
Pawel Zarembski 0:01f31e923fe2 1024 case MSC_BS_DATA_IN:
Pawel Zarembski 0:01f31e923fe2 1025 switch (USBD_MSC_CBW.CB[0]) {
Pawel Zarembski 0:01f31e923fe2 1026 case SCSI_READ10:
Pawel Zarembski 0:01f31e923fe2 1027 case SCSI_READ12:
Pawel Zarembski 0:01f31e923fe2 1028 USBD_MSC_MemoryRead();
Pawel Zarembski 0:01f31e923fe2 1029 break;
Pawel Zarembski 0:01f31e923fe2 1030 }
Pawel Zarembski 0:01f31e923fe2 1031
Pawel Zarembski 0:01f31e923fe2 1032 break;
Pawel Zarembski 0:01f31e923fe2 1033
Pawel Zarembski 0:01f31e923fe2 1034 case MSC_BS_DATA_IN_LAST:
Pawel Zarembski 0:01f31e923fe2 1035 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 1036 break;
Pawel Zarembski 0:01f31e923fe2 1037
Pawel Zarembski 0:01f31e923fe2 1038 case MSC_BS_DATA_IN_LAST_STALL:
Pawel Zarembski 0:01f31e923fe2 1039 USBD_MSC_SetStallEP(usbd_msc_ep_bulkin | 0x80);
Pawel Zarembski 0:01f31e923fe2 1040 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 1041 break;
Pawel Zarembski 0:01f31e923fe2 1042
Pawel Zarembski 0:01f31e923fe2 1043 case MSC_BS_CSW:
Pawel Zarembski 0:01f31e923fe2 1044 BulkStage = MSC_BS_CBW;
Pawel Zarembski 0:01f31e923fe2 1045 break;
Pawel Zarembski 0:01f31e923fe2 1046
Pawel Zarembski 0:01f31e923fe2 1047 default:
Pawel Zarembski 0:01f31e923fe2 1048 break;
Pawel Zarembski 0:01f31e923fe2 1049 }
Pawel Zarembski 0:01f31e923fe2 1050 }
Pawel Zarembski 0:01f31e923fe2 1051
Pawel Zarembski 0:01f31e923fe2 1052
Pawel Zarembski 0:01f31e923fe2 1053 /*
Pawel Zarembski 0:01f31e923fe2 1054 * USB Device MSC Bulk Out Callback
Pawel Zarembski 0:01f31e923fe2 1055 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 1056 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 1057 */
Pawel Zarembski 0:01f31e923fe2 1058
Pawel Zarembski 0:01f31e923fe2 1059 void USBD_MSC_BulkOut(void)
Pawel Zarembski 0:01f31e923fe2 1060 {
Pawel Zarembski 0:01f31e923fe2 1061 switch (BulkStage) {
Pawel Zarembski 0:01f31e923fe2 1062 case MSC_BS_CBW:
Pawel Zarembski 0:01f31e923fe2 1063 USBD_MSC_GetCBW();
Pawel Zarembski 0:01f31e923fe2 1064 break;
Pawel Zarembski 0:01f31e923fe2 1065
Pawel Zarembski 0:01f31e923fe2 1066 case MSC_BS_DATA_OUT:
Pawel Zarembski 0:01f31e923fe2 1067 switch (USBD_MSC_CBW.CB[0]) {
Pawel Zarembski 0:01f31e923fe2 1068 case SCSI_WRITE10:
Pawel Zarembski 0:01f31e923fe2 1069 case SCSI_WRITE12:
Pawel Zarembski 0:01f31e923fe2 1070 USBD_MSC_MemoryWrite();
Pawel Zarembski 0:01f31e923fe2 1071 break;
Pawel Zarembski 0:01f31e923fe2 1072
Pawel Zarembski 0:01f31e923fe2 1073 case SCSI_VERIFY10:
Pawel Zarembski 0:01f31e923fe2 1074 USBD_MSC_MemoryVerify();
Pawel Zarembski 0:01f31e923fe2 1075 break;
Pawel Zarembski 0:01f31e923fe2 1076 }
Pawel Zarembski 0:01f31e923fe2 1077 break;
Pawel Zarembski 0:01f31e923fe2 1078
Pawel Zarembski 0:01f31e923fe2 1079 case MSC_BS_CSW:
Pawel Zarembski 0:01f31e923fe2 1080 // Previous transfer must be complete
Pawel Zarembski 0:01f31e923fe2 1081 // before the next transfer begins.
Pawel Zarembski 0:01f31e923fe2 1082 //
Pawel Zarembski 0:01f31e923fe2 1083 // If bulk out is stalled then just
Pawel Zarembski 0:01f31e923fe2 1084 // drop this packet and don't assert.
Pawel Zarembski 0:01f31e923fe2 1085 // This packet was left over from before
Pawel Zarembski 0:01f31e923fe2 1086 // the transfer aborted with a stall.
Pawel Zarembski 0:01f31e923fe2 1087 util_assert(USBD_EndPointHalt & (1 << usbd_msc_ep_bulkout));
Pawel Zarembski 0:01f31e923fe2 1088 break;
Pawel Zarembski 0:01f31e923fe2 1089
Pawel Zarembski 0:01f31e923fe2 1090 case MSC_BS_RESET:
Pawel Zarembski 0:01f31e923fe2 1091 // If Bulk-Only Mass Storage Reset command was received on
Pawel Zarembski 0:01f31e923fe2 1092 // Control Endpoint ignore next Bulk OUT transfer if it was not
Pawel Zarembski 0:01f31e923fe2 1093 // a CBW (as it means it was a unprocessed leftover from
Pawel Zarembski 0:01f31e923fe2 1094 // transfer before reset happened)
Pawel Zarembski 0:01f31e923fe2 1095 BulkStage = MSC_BS_CBW;
Pawel Zarembski 0:01f31e923fe2 1096 if (BulkLen == sizeof(USBD_MSC_CBW)) {
Pawel Zarembski 0:01f31e923fe2 1097 // If it is a CBW size packet go process it as CBW
Pawel Zarembski 0:01f31e923fe2 1098 USBD_MSC_GetCBW();
Pawel Zarembski 0:01f31e923fe2 1099 }
Pawel Zarembski 0:01f31e923fe2 1100 break;
Pawel Zarembski 0:01f31e923fe2 1101
Pawel Zarembski 0:01f31e923fe2 1102 default:
Pawel Zarembski 0:01f31e923fe2 1103 USBD_MSC_SetStallEP(usbd_msc_ep_bulkout);
Pawel Zarembski 0:01f31e923fe2 1104 USBD_MSC_CSW.bStatus = CSW_PHASE_ERROR;
Pawel Zarembski 0:01f31e923fe2 1105 USBD_MSC_SetCSW();
Pawel Zarembski 0:01f31e923fe2 1106 break;
Pawel Zarembski 0:01f31e923fe2 1107 }
Pawel Zarembski 0:01f31e923fe2 1108 }
Pawel Zarembski 0:01f31e923fe2 1109
Pawel Zarembski 0:01f31e923fe2 1110 /** \brief Handle Reset Events
Pawel Zarembski 0:01f31e923fe2 1111
Pawel Zarembski 0:01f31e923fe2 1112 The function handles Reset events.
Pawel Zarembski 0:01f31e923fe2 1113 */
Pawel Zarembski 0:01f31e923fe2 1114
Pawel Zarembski 0:01f31e923fe2 1115 void USBD_MSC_Reset_Event(void)
Pawel Zarembski 0:01f31e923fe2 1116 {
Pawel Zarembski 0:01f31e923fe2 1117 USBD_MSC_Reset();
Pawel Zarembski 0:01f31e923fe2 1118 }
Pawel Zarembski 0:01f31e923fe2 1119
Pawel Zarembski 0:01f31e923fe2 1120 /*
Pawel Zarembski 0:01f31e923fe2 1121 * USB Device MSC Bulk In Endpoint Event Callback
Pawel Zarembski 0:01f31e923fe2 1122 * Parameters: event: not used (just for compatibility)
Pawel Zarembski 0:01f31e923fe2 1123 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 1124 */
Pawel Zarembski 0:01f31e923fe2 1125
Pawel Zarembski 0:01f31e923fe2 1126 void USBD_MSC_EP_BULKIN_Event(U32 event)
Pawel Zarembski 0:01f31e923fe2 1127 {
Pawel Zarembski 0:01f31e923fe2 1128 USBD_MSC_BulkIn();
Pawel Zarembski 0:01f31e923fe2 1129 }
Pawel Zarembski 0:01f31e923fe2 1130
Pawel Zarembski 0:01f31e923fe2 1131
Pawel Zarembski 0:01f31e923fe2 1132 /*
Pawel Zarembski 0:01f31e923fe2 1133 * USB Device MSC Bulk Out Endpoint Event Callback
Pawel Zarembski 0:01f31e923fe2 1134 * Parameters: event: not used (just for compatibility)
Pawel Zarembski 0:01f31e923fe2 1135 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 1136 */
Pawel Zarembski 0:01f31e923fe2 1137
Pawel Zarembski 0:01f31e923fe2 1138 void USBD_MSC_EP_BULKOUT_Event(U32 event)
Pawel Zarembski 0:01f31e923fe2 1139 {
Pawel Zarembski 0:01f31e923fe2 1140 BulkLen = USBD_ReadEP(usbd_msc_ep_bulkout, USBD_MSC_BulkBuf, USBD_MSC_BulkBufSize);
Pawel Zarembski 0:01f31e923fe2 1141 USBD_MSC_BulkOut();
Pawel Zarembski 0:01f31e923fe2 1142 }
Pawel Zarembski 0:01f31e923fe2 1143
Pawel Zarembski 0:01f31e923fe2 1144
Pawel Zarembski 0:01f31e923fe2 1145 /*
Pawel Zarembski 0:01f31e923fe2 1146 * USB Device MSC Bulk In/Out Endpoint Event Callback
Pawel Zarembski 0:01f31e923fe2 1147 * Parameters: event: USB Device Event
Pawel Zarembski 0:01f31e923fe2 1148 * USBD_EVT_OUT: Output Event
Pawel Zarembski 0:01f31e923fe2 1149 * USBD_EVT_IN: Input Event
Pawel Zarembski 0:01f31e923fe2 1150 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 1151 */
Pawel Zarembski 0:01f31e923fe2 1152
Pawel Zarembski 0:01f31e923fe2 1153 void USBD_MSC_EP_BULK_Event(U32 event)
Pawel Zarembski 0:01f31e923fe2 1154 {
Pawel Zarembski 0:01f31e923fe2 1155 if (event & USBD_EVT_OUT) {
Pawel Zarembski 0:01f31e923fe2 1156 USBD_MSC_EP_BULKOUT_Event(0);
Pawel Zarembski 0:01f31e923fe2 1157 }
Pawel Zarembski 0:01f31e923fe2 1158
Pawel Zarembski 0:01f31e923fe2 1159 if (event & USBD_EVT_IN) {
Pawel Zarembski 0:01f31e923fe2 1160 USBD_MSC_EP_BULKIN_Event(0);
Pawel Zarembski 0:01f31e923fe2 1161 }
Pawel Zarembski 0:01f31e923fe2 1162 }
Pawel Zarembski 0:01f31e923fe2 1163
Pawel Zarembski 0:01f31e923fe2 1164
Pawel Zarembski 0:01f31e923fe2 1165 #ifdef __RTX /* RTX tasks for handling events */
Pawel Zarembski 0:01f31e923fe2 1166
Pawel Zarembski 0:01f31e923fe2 1167 /*
Pawel Zarembski 0:01f31e923fe2 1168 * USB Device MSC Bulk In Endpoint Event Handler Task
Pawel Zarembski 0:01f31e923fe2 1169 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 1170 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 1171 */
Pawel Zarembski 0:01f31e923fe2 1172
Pawel Zarembski 0:01f31e923fe2 1173 __task void USBD_RTX_MSC_EP_BULKIN_Event(void)
Pawel Zarembski 0:01f31e923fe2 1174 {
Pawel Zarembski 0:01f31e923fe2 1175 for (;;) {
Pawel Zarembski 0:01f31e923fe2 1176 usbd_os_evt_wait_or(0xFFFF, 0xFFFF);
Pawel Zarembski 0:01f31e923fe2 1177
Pawel Zarembski 0:01f31e923fe2 1178 if (usbd_os_evt_get() & USBD_EVT_IN) {
Pawel Zarembski 0:01f31e923fe2 1179 USBD_MSC_EP_BULKIN_Event(0);
Pawel Zarembski 0:01f31e923fe2 1180 }
Pawel Zarembski 0:01f31e923fe2 1181 }
Pawel Zarembski 0:01f31e923fe2 1182 }
Pawel Zarembski 0:01f31e923fe2 1183
Pawel Zarembski 0:01f31e923fe2 1184
Pawel Zarembski 0:01f31e923fe2 1185 /*
Pawel Zarembski 0:01f31e923fe2 1186 * USB Device MSC Bulk Out Endpoint Event Handler Task
Pawel Zarembski 0:01f31e923fe2 1187 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 1188 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 1189 */
Pawel Zarembski 0:01f31e923fe2 1190
Pawel Zarembski 0:01f31e923fe2 1191 __task void USBD_RTX_MSC_EP_BULKOUT_Event(void)
Pawel Zarembski 0:01f31e923fe2 1192 {
Pawel Zarembski 0:01f31e923fe2 1193 for (;;) {
Pawel Zarembski 0:01f31e923fe2 1194 usbd_os_evt_wait_or(0xFFFF, 0xFFFF);
Pawel Zarembski 0:01f31e923fe2 1195
Pawel Zarembski 0:01f31e923fe2 1196 if (usbd_os_evt_get() & USBD_EVT_OUT) {
Pawel Zarembski 0:01f31e923fe2 1197 USBD_MSC_EP_BULKOUT_Event(0);
Pawel Zarembski 0:01f31e923fe2 1198 }
Pawel Zarembski 0:01f31e923fe2 1199 }
Pawel Zarembski 0:01f31e923fe2 1200 }
Pawel Zarembski 0:01f31e923fe2 1201
Pawel Zarembski 0:01f31e923fe2 1202
Pawel Zarembski 0:01f31e923fe2 1203 /*
Pawel Zarembski 0:01f31e923fe2 1204 * USB Device MSC Bulk In/Out Endpoint Event Handler Task
Pawel Zarembski 0:01f31e923fe2 1205 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 1206 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 1207 */
Pawel Zarembski 0:01f31e923fe2 1208
Pawel Zarembski 0:01f31e923fe2 1209 __task void USBD_RTX_MSC_EP_BULK_Event(void)
Pawel Zarembski 0:01f31e923fe2 1210 {
Pawel Zarembski 0:01f31e923fe2 1211 for (;;) {
Pawel Zarembski 0:01f31e923fe2 1212 usbd_os_evt_wait_or(0xFFFF, 0xFFFF);
Pawel Zarembski 0:01f31e923fe2 1213 USBD_MSC_EP_BULK_Event(usbd_os_evt_get());
Pawel Zarembski 0:01f31e923fe2 1214 }
Pawel Zarembski 0:01f31e923fe2 1215 }
Pawel Zarembski 0:01f31e923fe2 1216 #endif