?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /*********************************************************************
2 File Information:
3 FileName: usb_function_msd.c
4 Dependencies: See INCLUDES section below
5 Processor: PIC18, PIC24, or PIC32
6 Compiler: C18, C30, or C32
7 Company: Microchip Technology, Inc.
8  
9 Software License Agreement
10  
11 The software supplied herewith by Microchip Technology Incorporated
12 (the “Company”) for its PICmicro® Microcontroller is intended and
13 supplied to you, the Company’s customer, for use solely and
14 exclusively on Microchip PICmicro Microcontroller products. The
15 software is owned by the Company and/or its supplier, and is
16 protected under applicable copyright laws. All rights are reserved.
17 Any use in violation of the foregoing restrictions may subject the
18 user to criminal sanctions under applicable laws, as well as to
19 civil liability for the breach of the terms and conditions of this
20 license.
21  
22 THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
23 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
24 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
26 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
27 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
28  
29 Summary:
30 This file contains functions, macros, definitions, variables,
31 datatypes, etc. that are required for use of the MSD function
32 driver. This file should be included in projects that use the MSD
33 \function driver.
34  
35  
36  
37 This file is located in the "\<Install Directory\>\\Microchip\\USB\\MSD
38 Device Driver" directory.
39  
40 Description:
41 USB MSD Function Driver File
42  
43 This file contains functions, macros, definitions, variables,
44 datatypes, etc. that are required for use of the MSD function
45 driver. This file should be included in projects that use the MSD
46 \function driver.
47  
48 This file is located in the "\<Install Directory\>\\Microchip\\USB\\MSD
49 Device Driver" directory.
50  
51 When including this file in a new project, this file can either be
52 referenced from the directory in which it was installed or copied
53 directly into the user application folder. If the first method is
54 chosen to keep the file located in the folder in which it is installed
55 then include paths need to be added so that the library and the
56 application both know where to reference each others files. If the
57 application folder is located in the same folder as the Microchip
58 folder (like the current demo folders), then the following include
59 paths need to be added to the application's project:
60  
61 ..\\..\\Microchip\\Include
62 .
63  
64 If a different directory structure is used, modify the paths as
65 required. An example using absolute paths instead of relative paths
66 would be the following:
67  
68 C:\\Microchip Solutions\\Microchip\\Include
69  
70 C:\\Microchip Solutions\\My Demo Application
71  
72 Change History:
73 Rev Description
74 ---------- ----------------------------------------------------------
75 2.6 - 2.7a No change
76  
77 ********************************************************************/
78  
79 /** I N C L U D E S **************************************************/
80 #include "USB/USB.h"
81 #include "HardwareProfile.h"
82 #include "FSConfig.h"
83  
84 #include "./USB/usb_function_msd.h"
85  
86 #ifdef USB_USE_MSD
87  
88 #if MAX_LUN == 0
89 #define LUN_INDEX 0
90 #else
91 #define LUN_INDEX gblCBW.bCBWLUN
92 #endif
93  
94 #if defined(__C30__) || defined(__C32__)
95 #if defined(USE_INTERNAL_FLASH)
96 #include "MDD File System\Internal Flash.h"
97 #endif
98  
99 #if defined(USE_SD_INTERFACE_WITH_SPI)
100 #include "MDD File System\SD-SPI.h"
101 #endif
102  
103 extern LUN_FUNCTIONS LUN[MAX_LUN + 1];
104 #define LUNMediaInitialize() LUN[LUN_INDEX].MediaInitialize()
105 #define LUNReadCapacity() LUN[LUN_INDEX].ReadCapacity()
106 #define LUNReadSectorSize() LUN[LUN_INDEX].ReadSectorSize()
107 #define LUNMediaDetect() LUN[LUN_INDEX].MediaDetect()
108 #define LUNSectorWrite(bLBA,pDest,Write0) LUN[LUN_INDEX].SectorWrite(bLBA, pDest, Write0)
109 #define LUNWriteProtectState() LUN[LUN_INDEX].WriteProtectState()
110 #define LUNSectorRead(bLBA,pSrc) LUN[LUN_INDEX].SectorRead(bLBA, pSrc)
111 #else
112 #if defined(USE_INTERNAL_FLASH)
113 #include "MDD File System\Internal Flash.h"
114 #endif
115  
116 #if defined(USE_SD_INTERFACE_WITH_SPI)
117 #include "MDD File System\SD-SPI.h"
118 #endif
119  
120 #define LUNMediaInitialize() MDD_MediaInitialize()
121 #define LUNReadCapacity() MDD_ReadCapacity()
122 #define LUNReadSectorSize() MDD_ReadSectorSize()
123 #define LUNMediaDetect() MDD_MediaDetect()
124 #define LUNSectorWrite(bLBA,pDest,Write0) MDD_SectorWrite(bLBA, pDest, Write0)
125 #define LUNWriteProtectState() MDD_WriteProtectState()
126 #define LUNSectorRead(bLBA,pSrc) MDD_SectorRead(bLBA, pSrc)
127 #endif
128  
129 /** V A R I A B L E S ************************************************/
130 #pragma udata
131 BYTE MSD_State; // Takes values MSD_WAIT, MSD_DATA_IN or MSD_DATA_OUT
132 USB_MSD_CBW gblCBW;
133 BYTE gblCBWLength;
134 RequestSenseResponse gblSenseData[MAX_LUN + 1];
135 BYTE *ptrNextData;
136 USB_HANDLE USBMSDOutHandle;
137 USB_HANDLE USBMSDInHandle;
138 WORD MSBBufferIndex;
139 WORD gblMediaPresent;
140 BOOL SoftDetach[MAX_LUN + 1];
141 static BYTE MSDCommandState = MSD_COMMAND_WAIT;
142  
143 static WORD_VAL TransferLength;
144 static DWORD_VAL LBA;
145  
146 /*
147 * Number of Blocks and Block Length are global because
148 * for every READ_10 and WRITE_10 command need to verify if the last LBA
149 * is less than gblNumBLKS
150 */
151 DWORD_VAL gblNumBLKS,gblBLKLen;
152 extern const ROM InquiryResponse inq_resp;
153  
154 /** P R I V A T E P R O T O T Y P E S ***************************************/
155 BYTE MSDProcessCommand(void);
156 BYTE MSDReadHandler(void);
157 BYTE MSDWriteHandler(void);
158 void ResetSenseData(void);
159  
160 /** D E C L A R A T I O N S **************************************************/
161 #pragma code
162  
163 /** C L A S S S P E C I F I C R E Q ****************************************/
164  
165 /******************************************************************************
166 Function:
167 void USBMSDInit(void)
168  
169 Summary:
170 This routine initializes the MSD class packet handles, prepares to
171 receive a MSD packet, and initializes the MSD state machine. This
172 \function should be called once after the device is enumerated.
173  
174 Description:
175 This routine initializes the MSD class packet handles, prepares to
176 receive a MSD packet, and initializes the MSD state machine. This
177 \function should be called once after the device is enumerated.
178  
179 Typical Usage:
180 <code>
181 void USBCBInitEP(void)
182 {
183 USBEnableEndpoint(MSD_DATA_IN_EP,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
184 USBMSDInit();
185 }
186 </code>
187 Conditions:
188 The device should already be enumerated with a configuration that
189 supports MSD before calling this function.
190  
191 Paramters: None
192  
193 Remarks:
194 None
195 ****************************************************************************/
196 void USBMSDInit(void)
197 {
198 USBMSDInHandle = 0;
199 USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,(BYTE*)&msd_cbw,MSD_OUT_EP_SIZE);
200 MSD_State=MSD_WAIT;
201 gblNumBLKS.Val = 0;
202 gblBLKLen.Val = 0;
203  
204 gblMediaPresent = 0;
205  
206 //For each of the possible logical units
207 for(gblCBW.bCBWLUN=0;gblCBW.bCBWLUN<(MAX_LUN + 1);gblCBW.bCBWLUN++)
208 {
209 //clear all of the soft detach variables
210 SoftDetach[gblCBW.bCBWLUN] = FALSE;
211  
212 //see if the media is attached
213 if(LUNMediaDetect())
214 {
215 //initialize the media
216 if(LUNMediaInitialize())
217 {
218 //if the media was present and successfully initialized
219 // then mark and indicator that the media is ready
220 gblMediaPresent |= (1<<gblCBW.bCBWLUN);
221 }
222 }
223 ResetSenseData();
224 }
225 }
226  
227 /******************************************************************************
228 Function:
229 void USBCheckMSDRequest(void)
230  
231 Summary:
232 This routine handles MSD specific request that happen on EP0.
233 This function should be called from the USBCBCheckOtherReq() call back
234 function whenever implementing an MSD device.
235  
236 Description:
237 This routine handles MSD specific request that happen on EP0. These
238 include, but are not limited to, the standard RESET and GET_MAX_LUN
239 command requests. This function should be called from the
240 USBCBCheckOtherReq() call back function whenever using an MSD device.
241  
242 Typical Usage:
243 <code>
244 void USBCBCheckOtherReq(void)
245 {
246 //Since the stack didn't handle the request I need to check
247 // my class drivers to see if it is for them
248 USBCheckMSDRequest();
249 }
250 </code>
251  
252 PreCondition:
253 None
254  
255 Parameters:
256 None
257  
258 Return Values:
259 None
260  
261 Remarks:
262 None
263  
264 *****************************************************************************/
265 void USBCheckMSDRequest(void)
266 {
267 if(SetupPkt.Recipient != USB_SETUP_RECIPIENT_INTERFACE_BITFIELD) return;
268 if(SetupPkt.bIntfID != MSD_INTF_ID) return;
269  
270 switch(SetupPkt.bRequest)
271 {
272 case MSD_RESET:
273 break;
274 case GET_MAX_LUN:
275 //If the host asks for the maximum number of logical units
276 // then send out a packet with that information
277 CtrlTrfData[0] = MAX_LUN;
278 USBEP0SendRAMPtr((BYTE*)&CtrlTrfData[0],1,USB_EP0_INCLUDE_ZERO);
279 break;
280 } //end switch(SetupPkt.bRequest)
281 }
282  
283 /*********************************************************************************
284 Function:
285 BYTE MSDTasks(void)
286  
287 Summary:
288 This function runs the MSD class state machines and all of its
289 sub-systems. This function should be called periodically once the
290 device is in the configured state in order to keep the MSD state
291 machine going.
292 Description:
293 This function runs the MSD class state machines and all of its
294 sub-systems. This function should be called periodically once the
295 device is in the configured state in order to keep the MSD state
296 machine going.
297  
298 Typical Usage:
299 <code>
300 void main(void)
301 {
302 USBDeviceInit();
303 while(1)
304 {
305 USBDeviceTasks();
306 if((USBGetDeviceState() \< CONFIGURED_STATE) ||
307 (USBIsDeviceSuspended() == TRUE))
308 {
309 //Either the device is not configured or we are suspended
310 // so we don't want to do execute any application code
311 continue; //go back to the top of the while loop
312 }
313 else
314 {
315 //Keep the MSD state machine going
316 MSDTasks();
317  
318 //Run application code.
319 UserApplication();
320 }
321 }
322 }
323 </code>
324 Conditions:
325 None
326 Return Values:
327 BYTE - the current state of the MSD state machine the valid values are
328 defined in MSD.h under the MSDTasks state machine declaration section.
329 The possible values are the following\:
330 * MSD_WAIT
331 * MSD_DATA_IN
332 * MSD_DATA_OUT
333 * MSD_SEND_CSW
334 Remarks:
335 None
336 *********************************************************************************/
337 BYTE MSDTasks(void)
338 {
339 BYTE i;
340  
341 switch(MSD_State)
342 {
343 case MSD_WAIT:
344 {
345 //If the MSD state machine is waiting for something to happen
346 if(!USBHandleBusy(USBMSDOutHandle))
347 {
348 //If we received an OUT packet from the host
349 // then copy the data from the buffer to a global
350 // buffer so that we can keep the information but
351 // reuse the buffer
352 gblCBW.dCBWSignature=msd_cbw.dCBWSignature;
353 gblCBW.dCBWTag=msd_cbw.dCBWTag;
354 gblCBW.dCBWDataTransferLength=msd_cbw.dCBWDataTransferLength;
355 gblCBW.bCBWFlags=msd_cbw.bCBWFlags;
356 gblCBW.bCBWLUN=msd_cbw.bCBWLUN;
357 gblCBW.bCBWCBLength=msd_cbw.bCBWCBLength; // 3 MSB are zero
358  
359 for (i=0;i<msd_cbw.bCBWCBLength;i++)
360 {
361 gblCBW.CBWCB[i]=msd_cbw.CBWCB[i];
362 }
363  
364 gblCBWLength=USBHandleGetLength(USBMSDOutHandle);
365  
366 //If this CBW is valid?
367 if ((gblCBWLength==MSD_CBW_SIZE)&&(gblCBW.dCBWSignature==0x43425355))
368 {
369 //Is this CBW meaningful?
370 if((gblCBW.bCBWLUN<=0x0f)
371 &&(gblCBW.bCBWCBLength<=0x10)
372 &&(gblCBW.bCBWCBLength>=0x01)
373 &&(gblCBW.bCBWFlags==0x00||gblCBW.bCBWFlags==0x80))
374 {
375 //Prepare the CSW to be sent
376 msd_csw.dCSWTag=gblCBW.dCBWTag;
377 msd_csw.dCSWSignature=0x53425355;
378  
379 /* If direction is device to host*/
380 if (gblCBW.bCBWFlags==0x80)
381 {
382 MSD_State=MSD_DATA_IN;
383 }
384 else if (gblCBW.bCBWFlags==0x00)
385 {
386 /* If direction is host to device*/
387 /* prepare to read data in msd_buffer */
388 MSD_State=MSD_DATA_OUT;
389 }
390 }
391 }
392 }
393 break;
394 }
395 case MSD_DATA_IN:
396 if(MSDProcessCommand() == MSD_COMMAND_WAIT)
397 {
398 // Done processing the command, send the status
399 MSD_State = MSD_SEND_CSW;
400 }
401 break;
402 case MSD_DATA_OUT:
403 if(MSDProcessCommand() == MSD_COMMAND_WAIT)
404 {
405 /* Finished receiving the data prepare and send the status */
406 if ((msd_csw.bCSWStatus==0x00)&&(msd_csw.dCSWDataResidue!=0))
407 {
408 msd_csw.bCSWStatus=0x02;
409 }
410 MSD_State = MSD_SEND_CSW;
411 }
412 break;
413 case MSD_SEND_CSW:
414 if(USBHandleBusy(USBMSDInHandle))
415 {
416 //The TX buffer is not ready to send the status yet.
417 break;
418 }
419  
420 USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_csw,MSD_CSW_SIZE);
421  
422 //Get ready for next command to come in
423 if(!USBHandleBusy(USBMSDOutHandle))
424 {
425 USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,(BYTE*)&msd_cbw,sizeof(msd_cbw));
426 }
427  
428 MSD_State=MSD_WAIT;
429 break;
430 }
431  
432 return MSD_State;
433 }
434  
435 /******************************************************************************
436 Function:
437 void MSDProcessCommandMediaPresent(void)
438  
439 Description:
440 This funtion processes a command received through the MSD
441 class driver
442  
443 PreCondition:
444 None
445  
446 Paramters:
447 None
448  
449 Return Values:
450 BYTE - the current state of the MSDProcessCommand state
451 machine. The valid values are defined in MSD.h under the
452 MSDProcessCommand state machine declaration section
453  
454 Remarks:
455 None
456  
457 *****************************************************************************/
458 void MSDProcessCommandMediaPresent(void)
459 {
460 BYTE i;
461  
462 switch(MSDCommandState)
463 {
464 case MSD_COMMAND_WAIT:
465 //copy the received command to the command state machine
466 MSDCommandState = gblCBW.CBWCB[0];
467 break;
468 case MSD_INQUIRY:
469 {
470 //copy the inquiry results from the defined ROM buffer
471 // into the USB buffer so that it can be transmitted
472 memcpypgm2ram(
473 (void *)&msd_buffer[0],
474 (ROM void*)&inq_resp,
475 sizeof(InquiryResponse)
476 );
477 msd_csw.dCSWDataResidue=sizeof(InquiryResponse);
478 msd_csw.bCSWStatus=0x00; // success
479 MSDCommandState = MSD_COMMAND_RESPONSE;
480 break;
481 }
482 case MSD_READ_CAPACITY:
483 {
484 //If the host asked for the capacity of the device
485 DWORD_VAL sectorSize;
486 DWORD_VAL capacity;
487  
488 msd_csw.bCSWStatus=0x00; // success
489  
490 //get the information from the physical media
491 capacity.Val = LUNReadCapacity();
492 sectorSize.Val = LUNReadSectorSize();
493  
494 //copy the data to the buffer
495 msd_buffer[0]=capacity.v[3];
496 msd_buffer[1]=capacity.v[2];
497 msd_buffer[2]=capacity.v[1];
498 msd_buffer[3]=capacity.v[0];
499  
500 msd_buffer[4]=sectorSize.v[3];
501 msd_buffer[5]=sectorSize.v[2];
502 msd_buffer[6]=sectorSize.v[1];
503 msd_buffer[7]=sectorSize.v[0];
504  
505 msd_csw.dCSWDataResidue=0x08; // size of response
506 MSDCommandState = MSD_COMMAND_RESPONSE;
507 break;
508 }
509 case MSD_READ_10:
510 if(MSDReadHandler() == MSD_READ10_WAIT)
511 {
512 MSDCommandState = MSD_COMMAND_WAIT;
513 }
514 break;
515 case MSD_WRITE_10:
516 if(MSDWriteHandler() == MSD_WRITE10_WAIT)
517 {
518 MSDCommandState = MSD_COMMAND_WAIT;
519 }
520 break;
521 case MSD_REQUEST_SENSE:
522 for(i=0;i<sizeof(RequestSenseResponse);i++)
523 {
524 msd_buffer[i]=gblSenseData[LUN_INDEX]._byte[i];
525 }
526  
527 msd_csw.dCSWDataResidue=sizeof(RequestSenseResponse);
528 msd_csw.bCSWStatus=0x0; // success
529 MSDCommandState = MSD_COMMAND_RESPONSE;
530 break;
531 case MSD_MODE_SENSE:
532 msd_buffer[0]=0x02;
533 msd_buffer[1]=0x00;
534 msd_buffer[2]=0x00;
535 msd_buffer[3]=0x00;
536  
537 msd_csw.bCSWStatus=0x0;
538 msd_csw.dCSWDataResidue=0x04;
539 MSDCommandState = MSD_COMMAND_RESPONSE;
540 break;
541 case MSD_PREVENT_ALLOW_MEDIUM_REMOVAL:
542 if(LUNMediaDetect())
543 {
544 msd_csw.bCSWStatus=0x00;
545 msd_csw.dCSWDataResidue=0x00;
546 }
547 else
548 {
549 gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY;
550 gblSenseData[LUN_INDEX].ASC=ASC_MEDIUM_NOT_PRESENT;
551 gblSenseData[LUN_INDEX].ASCQ=ASCQ_MEDIUM_NOT_PRESENT;
552 msd_csw.bCSWStatus=0x01;
553 }
554 MSDCommandState = MSD_COMMAND_WAIT;
555 break;
556 case MSD_TEST_UNIT_READY:
557 if((gblSenseData[LUN_INDEX].SenseKey==S_UNIT_ATTENTION) && (msd_csw.bCSWStatus==1))
558 {
559 MSDCommandState = MSD_COMMAND_WAIT;
560 }
561 else
562 {
563 ResetSenseData();
564 msd_csw.dCSWDataResidue=0x00;
565 MSDCommandState = MSD_COMMAND_WAIT;
566 }
567 break;
568 case MSD_VERIFY:
569 //Fall through to STOP_START
570 case MSD_STOP_START:
571 msd_csw.bCSWStatus=0x0;
572 msd_csw.dCSWDataResidue=0x00;
573 MSDCommandState = MSD_COMMAND_WAIT;
574 break;
575 case MSD_COMMAND_RESPONSE:
576 if(USBHandleBusy(USBMSDInHandle) == FALSE)
577 {
578 USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_buffer[0],msd_csw.dCSWDataResidue);
579 MSDCommandState = MSD_COMMAND_WAIT;
580  
581 msd_csw.dCSWDataResidue=0;
582 }
583 break;
584 case MSD_COMMAND_ERROR:
585 default:
586 ResetSenseData();
587 gblSenseData[LUN_INDEX].SenseKey=S_ILLEGAL_REQUEST;
588 gblSenseData[LUN_INDEX].ASC=ASC_INVALID_COMMAND_OPCODE;
589 gblSenseData[LUN_INDEX].ASCQ=ASCQ_INVALID_COMMAND_OPCODE;
590 msd_csw.bCSWStatus=0x01;
591 msd_csw.dCSWDataResidue=0x00;
592 MSDCommandState = MSD_COMMAND_RESPONSE;
593 break;
594 } // end switch
595 }
596  
597 /******************************************************************************
598 Function:
599 void MSDProcessCommandMediaAbsent(void)
600  
601 Description:
602 This funtion processes a command received through the MSD
603 class driver
604  
605 PreCondition:
606 None
607  
608 Parameters:
609 None
610  
611 Return Values:
612 BYTE - the current state of the MSDProcessCommand state
613 machine. The valid values are defined in MSD.h under the
614 MSDProcessCommand state machine declaration section
615  
616 Remarks:
617 None
618  
619 *****************************************************************************/
620 void MSDProcessCommandMediaAbsent(void)
621 {
622 BYTE i;
623  
624 switch(MSDCommandState)
625 {
626 case MSD_REQUEST_SENSE:
627 {
628 ResetSenseData();
629 gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY;
630 gblSenseData[LUN_INDEX].ASC=ASC_MEDIUM_NOT_PRESENT;
631 gblSenseData[LUN_INDEX].ASCQ=ASCQ_MEDIUM_NOT_PRESENT;
632  
633 for(i=0;i<sizeof(RequestSenseResponse);i++)
634 {
635 msd_buffer[i]=gblSenseData[LUN_INDEX]._byte[i];
636 }
637  
638 msd_csw.dCSWDataResidue=sizeof(RequestSenseResponse);
639 msd_csw.bCSWStatus=0x0; // success
640 MSDCommandState = MSD_COMMAND_RESPONSE;
641 break;
642 }
643 case MSD_PREVENT_ALLOW_MEDIUM_REMOVAL:
644 case MSD_TEST_UNIT_READY:
645 {
646 msd_csw.bCSWStatus=0x01;
647 MSDCommandState = MSD_COMMAND_WAIT;
648 break;
649 }
650 case MSD_INQUIRY:
651 {
652 memcpypgm2ram(
653 (void *)&msd_buffer[0],
654 (ROM void*)&inq_resp,
655 sizeof(InquiryResponse)
656 );
657 msd_csw.dCSWDataResidue=sizeof(InquiryResponse);
658 msd_csw.bCSWStatus=0x00; // success
659 MSDCommandState = MSD_COMMAND_RESPONSE;
660 break;
661 }
662 case MSD_COMMAND_WAIT:
663 {
664 MSDCommandState = gblCBW.CBWCB[0];
665 break;
666 }
667 case MSD_COMMAND_RESPONSE:
668 if(USBHandleBusy(USBMSDInHandle) == FALSE)
669 {
670 USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_buffer[0],msd_csw.dCSWDataResidue);
671 MSDCommandState = MSD_COMMAND_WAIT;
672  
673 msd_csw.dCSWDataResidue=0;
674 }
675 break;
676 default:
677 {
678 //Stall MSD endpoint IN
679 USBStallEndpoint(MSD_DATA_IN_EP,1);
680 msd_csw.bCSWStatus=0x01;
681 MSDCommandState = MSD_COMMAND_WAIT;
682 break;
683 }
684 }
685 }
686  
687 /******************************************************************************
688 Function:
689 BYTE MSDProcessCommand(void)
690  
691 Description:
692 This funtion processes a command received through the MSD
693 class driver
694  
695 PreCondition:
696 None
697  
698 Paramters:
699 None
700  
701 Return Values:
702 BYTE - the current state of the MSDProcessCommand state
703 machine. The valid values are defined in MSD.h under the
704 MSDProcessCommand state machine declaration section
705  
706 Remarks:
707 None
708  
709 *****************************************************************************/
710 BYTE MSDProcessCommand(void)
711 {
712 if(LUNMediaDetect() == FALSE || SoftDetach[gblCBW.bCBWLUN] == TRUE)
713 {
714 gblMediaPresent &= ~(1<<gblCBW.bCBWLUN);
715  
716 MSDProcessCommandMediaAbsent();
717 }
718 else
719 {
720 if((gblMediaPresent & (1<<gblCBW.bCBWLUN)) == 0)
721 {
722 if(LUNMediaInitialize())
723 {
724 gblMediaPresent |= (1<<gblCBW.bCBWLUN);
725  
726 gblSenseData[LUN_INDEX].SenseKey=S_UNIT_ATTENTION;
727 gblSenseData[LUN_INDEX].ASC=0x28;
728 gblSenseData[LUN_INDEX].ASCQ=0x00;
729 msd_csw.bCSWStatus=0x01;
730  
731 MSDProcessCommandMediaPresent();
732 }
733 else
734 {
735 MSDProcessCommandMediaAbsent();
736 }
737 }
738 else
739 {
740 MSDProcessCommandMediaPresent();
741 }
742 }
743  
744 return MSDCommandState;
745 }
746  
747 /******************************************************************************
748 Function:
749 BYTE MSDReadHandler(void)
750  
751 Description:
752 This funtion processes a read command received through
753 the MSD class driver
754  
755 PreCondition:
756 None
757  
758 Parameters:
759 None
760  
761 Return Values:
762 BYTE - the current state of the MSDReadHandler state
763 machine. The valid values are defined in MSD.h under the
764 MSDReadHandler state machine declaration section
765  
766 Remarks:
767 None
768  
769 *****************************************************************************/
770  
771 BYTE MSDReadHandler(void)
772 {
773 static BYTE MSDReadState = MSD_READ10_WAIT;
774  
775 switch(MSDReadState)
776 {
777 case MSD_READ10_WAIT:
778 LBA.v[3]=gblCBW.CBWCB[2];
779 LBA.v[2]=gblCBW.CBWCB[3];
780 LBA.v[1]=gblCBW.CBWCB[4];
781 LBA.v[0]=gblCBW.CBWCB[5];
782  
783 TransferLength.v[1]=gblCBW.CBWCB[7];
784 TransferLength.v[0]=gblCBW.CBWCB[8];
785  
786 msd_csw.bCSWStatus=0x0;
787 msd_csw.dCSWDataResidue=0x0;
788  
789 MSDReadState = MSD_READ10_BLOCK;
790 //Fall through to MSD_READ_BLOCK
791 case MSD_READ10_BLOCK:
792 if(TransferLength.Val == 0)
793 {
794 MSDReadState = MSD_READ10_WAIT;
795 break;
796 }
797  
798 TransferLength.Val--; // we have read 1 LBA
799 MSDReadState = MSD_READ10_SECTOR;
800 //Fall through to MSD_READ10_SECTOR
801 case MSD_READ10_SECTOR:
802 //if the old data isn't completely sent yet
803 if(USBHandleBusy(USBMSDInHandle) != 0)
804 {
805 break;
806 }
807  
808 if(LUNSectorRead(LBA.Val, (BYTE*)&msd_buffer[0]) != TRUE)
809 {
810 msd_csw.bCSWStatus=0x01; // Error 0x01 Refer page#18
811 // of BOT specifications
812 /* Don't read any more data*/
813 msd_csw.dCSWDataResidue=0x0;
814  
815 MSD_State = MSD_DATA_IN;
816 break;
817 }
818  
819 LBA.Val++;
820  
821 msd_csw.bCSWStatus=0x00; // success
822 msd_csw.dCSWDataResidue=BLOCKLEN_512;//in order to send the
823 //512 bytes of data read
824  
825 ptrNextData=(BYTE *)&msd_buffer[0];
826  
827 MSDReadState = MSD_READ10_TX_SECTOR;
828  
829 //Fall through to MSD_READ10_TX_SECTOR
830 case MSD_READ10_TX_SECTOR:
831 if(msd_csw.dCSWDataResidue == 0)
832 {
833 MSDReadState = MSD_READ10_BLOCK;
834 break;
835 }
836  
837 MSDReadState = MSD_READ10_TX_PACKET;
838 //Fall through to MSD_READ10_TX_PACKET
839  
840 case MSD_READ10_TX_PACKET:
841 if ((msd_csw.bCSWStatus==0x00)&&(msd_csw.dCSWDataResidue>=MSD_IN_EP_SIZE))
842 {
843 /* Write next chunk of data to EP Buffer and send */
844 if(USBHandleBusy(USBMSDInHandle))
845 {
846 break;
847 }
848  
849 USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,ptrNextData,MSD_IN_EP_SIZE);
850  
851 MSDReadState = MSD_READ10_TX_SECTOR;
852  
853 gblCBW.dCBWDataTransferLength-= MSD_IN_EP_SIZE;
854 msd_csw.dCSWDataResidue-=MSD_IN_EP_SIZE;
855 ptrNextData+=MSD_IN_EP_SIZE;
856 }
857 break;
858 }
859  
860 return MSDReadState;
861 }
862  
863  
864 /******************************************************************************
865 Function:
866 BYTE MSDWriteHandler(void)
867  
868 Description:
869 This funtion processes a write command received through
870 the MSD class driver
871  
872 PreCondition:
873 None
874  
875 Parameters:
876 None
877  
878 Return Values:
879 BYTE - the current state of the MSDWriteHandler state
880 machine. The valid values are defined in MSD.h under the
881 MSDWriteHandler state machine declaration section
882  
883 Remarks:
884 None
885  
886 *****************************************************************************/
887 BYTE MSDWriteHandler(void)
888 {
889 static BYTE MSDWriteState = MSD_WRITE10_WAIT;
890  
891 switch(MSDWriteState)
892 {
893 case MSD_WRITE10_WAIT:
894 /* Read the LBA, TransferLength fields from Command Block
895 NOTE: CB is Big-Endian */
896  
897 LBA.v[3]=gblCBW.CBWCB[2];
898 LBA.v[2]=gblCBW.CBWCB[3];
899 LBA.v[1]=gblCBW.CBWCB[4];
900 LBA.v[0]=gblCBW.CBWCB[5];
901 TransferLength.v[1]=gblCBW.CBWCB[7];
902 TransferLength.v[0]=gblCBW.CBWCB[8];
903  
904 msd_csw.bCSWStatus=0x0;
905  
906 MSD_State = MSD_WRITE10_BLOCK;
907 //Fall through to MSD_WRITE10_BLOCK
908 case MSD_WRITE10_BLOCK:
909 if(TransferLength.Val == 0)
910 {
911 MSDWriteState = MSD_WRITE10_WAIT;
912 break;
913 }
914  
915 MSDWriteState = MSD_WRITE10_RX_SECTOR;
916 ptrNextData=(BYTE *)&msd_buffer[0];
917  
918 msd_csw.dCSWDataResidue=BLOCKLEN_512;
919  
920 //Fall through to MSD_WRITE10_RX_SECTOR
921 case MSD_WRITE10_RX_SECTOR:
922 {
923 /* Read 512B into msd_buffer*/
924 if(msd_csw.dCSWDataResidue>0)
925 {
926 if(USBHandleBusy(USBMSDOutHandle) == TRUE)
927 {
928 break;
929 }
930  
931 USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,ptrNextData,MSD_OUT_EP_SIZE);
932 MSDWriteState = MSD_WRITE10_RX_PACKET;
933 //Fall through to MSD_WRITE10_RX_PACKET
934 }
935 else
936 {
937 if(LUNWriteProtectState())
938 {
939 gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY;
940 gblSenseData[LUN_INDEX].ASC=ASC_WRITE_PROTECTED;
941 gblSenseData[LUN_INDEX].ASCQ=ASCQ_WRITE_PROTECTED;
942 msd_csw.bCSWStatus=0x01;
943 //TODO: (DF) - what state should I return to?
944 }
945 else
946 {
947 MSDWriteState = MSD_WRITE10_SECTOR;
948 }
949 break;
950 }
951 }
952 //Fall through to MSD_WRITE10_RX_PACKET
953 case MSD_WRITE10_RX_PACKET:
954 if(USBHandleBusy(USBMSDOutHandle) == TRUE)
955 {
956 break;
957 }
958  
959 gblCBW.dCBWDataTransferLength-=USBHandleGetLength(USBMSDOutHandle); // 64B read
960 msd_csw.dCSWDataResidue-=USBHandleGetLength(USBMSDOutHandle);
961 ptrNextData += MSD_OUT_EP_SIZE;
962  
963 MSDWriteState = MSD_WRITE10_RX_SECTOR;
964 break;
965 case MSD_WRITE10_SECTOR:
966 {
967 if(LUNSectorWrite(LBA.Val, (BYTE*)&msd_buffer[0], (LBA.Val==0)?TRUE:FALSE) != TRUE)
968 {
969 break;
970 }
971  
972 // if (status) {
973 // msd_csw.bCSWStatus=0x01;
974 // /* add some sense keys here*/
975 // }
976  
977 LBA.Val++; // One LBA is written. Write the next LBA
978 TransferLength.Val--;
979  
980 MSDWriteState = MSD_WRITE10_BLOCK;
981 break;
982 }
983 }
984  
985 return MSDWriteState;
986 }
987  
988 /******************************************************************************
989 Function:
990 void ResetSenseData(void)
991  
992 Description:
993 This routine resets the Sense Data, initializing the
994 structure RequestSenseResponse gblSenseData.
995  
996 PreCondition:
997 None
998  
999 Parameters:
1000 None
1001  
1002 Return Values:
1003 None
1004  
1005 Remarks:
1006 None
1007  
1008 *****************************************************************************/
1009 void ResetSenseData(void)
1010 {
1011 gblSenseData[LUN_INDEX].ResponseCode=S_CURRENT;
1012 gblSenseData[LUN_INDEX].VALID=0; // no data in the information field
1013 gblSenseData[LUN_INDEX].Obsolete=0x0;
1014 gblSenseData[LUN_INDEX].SenseKey=S_NO_SENSE;
1015 //gblSenseData.Resv;
1016 gblSenseData[LUN_INDEX].ILI=0;
1017 gblSenseData[LUN_INDEX].EOM=0;
1018 gblSenseData[LUN_INDEX].FILEMARK=0;
1019 gblSenseData[LUN_INDEX].InformationB0=0x00;
1020 gblSenseData[LUN_INDEX].InformationB1=0x00;
1021 gblSenseData[LUN_INDEX].InformationB2=0x00;
1022 gblSenseData[LUN_INDEX].InformationB3=0x00;
1023 gblSenseData[LUN_INDEX].AddSenseLen=0x0a; // n-7 (n=17 (0..17))
1024 gblSenseData[LUN_INDEX].CmdSpecificInfo.Val=0x0;
1025 gblSenseData[LUN_INDEX].ASC=0x0;
1026 gblSenseData[LUN_INDEX].ASCQ=0x0;
1027 gblSenseData[LUN_INDEX].FRUC=0x0;
1028 gblSenseData[LUN_INDEX].SenseKeySpecific[0]=0x0;
1029 gblSenseData[LUN_INDEX].SenseKeySpecific[1]=0x0;
1030 gblSenseData[LUN_INDEX].SenseKeySpecific[2]=0x0;
1031 }
1032  
1033 #endif
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3