📄 cfms_processor.c
字号:
/******************************************************************************
*
* (c) copyright Freescale Semiconductor Hong Kong Ltd. 2004
* ALL RIGHTS RESERVED
*
*******************************************************************************
** THIS CODE IS ONLY INTENDED AS AN EXAMPLE FOR DEMONSTRATING THE FREESCALE **
** MICROCONTROLLERS. IT HAS ONLY BEEN GIVEN A MIMIMUM LEVEL OF TEST. IT IS **
** PROVIDED 'AS SEEN' WITH NO GUARANTEES AND NO PROMISE OF SUPPORT. **
*******************************************************************************
*
* FILE: CFMS_Processor.c
*
* DESCRIPTION: CompactFlash processor for USB Mass Storage
*
* UPDATED HISTORY:
*
* REV YYYY.MM.DD AUTHOR DESCRIPTION OF CHANGE
* --- ---------- ------ ---------------------
* 0.0 2003.09.01 Derek Lau Initial version
*
******************************************************************************/
/* Freescale is not obligated to provide any support, upgrades or new */
/* releases of the Software. Freescale may make changes to the Software at */
/* any time, without any obligation to notify or provide updated versions of */
/* the Software to you. Freescale expressly disclaims any warranty for the */
/* Software. The Software is provided as is, without warranty of any kind, */
/* either express or implied, including, without limitation, the implied */
/* warranties of merchantability, fitness for a particular purpose, or */
/* non-infringement. You assume the entire risk arising out of the use or */
/* performance of the Software, or any systems you design using the software */
/* (if any). Nothing may be construed as a warranty or representation by */
/* Freescale that the Software or any derivative work developed with or */
/* incorporating the Software will be free from infringement of the */
/* intellectual property rights of third parties. In no event will Freescale */
/* be liable, whether in contract, tort, or otherwise, for any incidental, */
/* special, indirect, consequential or punitive damages, including, but not */
/* limited to, damages for any loss of use, loss of time, inconvenience, */
/* commercial loss, or lost profits, savings, or revenues to the full extent */
/* such may be disclaimed by law. The Software is not fault tolerant and is */
/* not designed, manufactured or intended by Freescale for incorporation */
/* into products intended for use or resale in on-line control equipment in */
/* hazardous, dangerous to life or potentially life-threatening environments */
/* requiring fail-safe performance, such as in the operation of nuclear */
/* facilities, aircraft navigation or communication systems, air traffic */
/* control, direct life support machines or weapons systems, in which the */
/* failure of products could lead directly to death, personal injury or */
/* severe physical or environmental damage (High Risk Activities). You */
/* specifically represent and warrant that you will not use the Software or */
/* any derivative work of the Software for High Risk Activities. */
/* Freescale and the Freescale logos are registered trademarks of Freescale */
/* Semiconductor Inc. */
/*****************************************************************************/
#include "FreescaleDef.h" // Get my definitions (Constants & Macros)
#include "UF32reg.h" // Get the UF32 registers.
#include "mk_extern.h"
#include "usbms_includes.h" // Get USB Mass Storage
#include "usbms_extern.h" // Get USB Mass Storage global prototypes
#include "usb_extern.h"
#include "usb_includes.h"
#include "cf_includes.h"
#include "cf_extern.h"
#define _CF_SCSILIST_EXTERN_G_DECL_
#include "cfms_SCSIList.h"
// code is placed in the main code area.
//#pragma CODE_SEG DEFAULT
#pragma CODE_SEG DEFAULT
// ==================================================================
// CFMS_SCSIList00() -
//
// Test Unit Ready
//
// ==================================================================
void CFMS_SCSIList00(/*msSCSIMessage *myEventMsg*/)
{
if (gUSBMSDeviceReady[COMPACTFLASH]&& !gUSBMSSenseKey[COMPACTFLASH])
{
gUSBMSCSWResult = kCSWPass;
USBMS_SendCSW();
}
else
USBMS_SCSINotSupport();
}
// ==================================================================
// CFMS_SCSIList03() -
//
// Request Sense
//
// ==================================================================
void CFMS_SCSIList03()
{
if (gUSBMSDeviceReady[COMPACTFLASH]) // device ready
{
gUSBMSCSWResult = CF_WaitCardBusy();
if (!gUSBMSCSWResult)
gUSBMSCSWResult = CF_WriteMem(CF_M_HEAD_COMMAND,0xE000 | kCFCmdRequestSense);
gUSBMSSenseKey[COMPACTFLASH] = ((muint16) CF_Read8Mem(CF_M_DATA_ERROR) << 8);
}
else
gUSBMSCSWResult = 0;
if (!gUSBMSCSWResult)
{
QC3DR = 0x7000; // error code / segment number
QC3DR = gUSBMSSenseKey[COMPACTFLASH]; // sense key /information
QC3DR = 0x0000; // information / information
QC3DR = 0x000A; // information / additional sense length
QC3DR = 0x0000; // command specific information
QC3DR = 0x0000; // command specific informaton
QC3DR = gUSBMSAddSenseKey[COMPACTFLASH]; // Add sense key/ add sense code qualifier
QC3DR = 0x0000;
QC3DR = 0x0000;
// USB_Move2QUE3( (muint8 *) pBuffer,0x12);
USBMS_SetPhyEP5Int1(*(gpbCBWPacket+kCBWXferLength0),0x12);
}
else
USBMS_SetPhyEP5Int(0); // short packet
if (gUSBMSSenseKey[COMPACTFLASH] == (kSCSISKUnitAttention<<8))
gUSBMSSenseKey[COMPACTFLASH] = 0;
}
// ==================================================================
// CFMS_SCSIList12() -
//
// Inquiry
//
// ==================================================================
void CFMS_SCSIList12(void)
{
muint16 *pBuffer;
muint16 i;
const char S[] = "Freescale CF Card Reader R0.1"; // Vendor Identification 8 bytes
// Product Indentification 16 bytes
// Product Revision Level 4 bytes
pBuffer = (muint16 *) 0x2400;
mSetBit(QnPRST, QC3CR);
if (gUSBMSDeviceReady[COMPACTFLASH])
{
gUSBMSCSWResult = CF_SCSIInquiry(pBuffer,36);
}
else
{
i=36;
QC3DR = 0x0080; // removeable
QC3DR = 0x0002; // SCSI 2 compatible
QC3DR = 0x1f00; // addition length = 31
QC3DR = 0x0000; // reserved
for (i=0; i<14; i++)
{
QC3DR = (muint16) ((S[2*(i)] << 8) | S[2*(i)+1]);
}
}
USBMS_SetPhyEP5Int1(*(gpbCBWPacket+kCBWXferLength0),0x24);
}
// ==================================================================
// CFMS_SCSIList25() -
//
// Read Capacity
//
// ==================================================================
void CFMS_SCSIList25()
{
muint8 *pBuffer;
pBuffer = (muint8 *) 0x2400;
if (gUSBMSDeviceReady[COMPACTFLASH])
{
mSetBit(QnPRST, QC3CR);
gUSBMSCSWResult = CF_SCSIReadCapacity(pBuffer);
USB_Move2QUE3( (muint8 *) pBuffer,8);
USBMS_SetPhyEP5Int1(*(gpbCBWPacket+kCBWXferLength0),0x08);
}
else
USBMS_SCSINotSupport();
}
// ==================================================================
// CFMS_SCSIList28() -
//
// Read
//
// ==================================================================
void CFMS_SCSIList28()
{
muint8 i,j,block;
if (!gUSBMSDeviceReady[COMPACTFLASH])
{
USBMS_SCSINotSupport();
return;
}
mClearBit(kLED1Pin,kLED1Port);
mSetBit(DBRST,QC34DCR); // reset QC34
mSetBit(QnTHRU,QC3CR); // QC34 pass through mode
mClearBit(QnEN,QC1CR); // disable QC1
QC1REQ = kQCREQNone; // remap QC1 to mon-existing resources
QC4REQ = kQCREQCFRx; // CF receive
mUSBClearBit(USBTCIE,UEPCSR5A); // disable PhyEP5 Xfer complete int
// gpUSBMSLBA = ((muint16) *(gpbCBWPacket+kSCSI10LBAByte3) << 8) | *(gpbCBWPacket+kSCSI10LBAByte2);
// gpUSBMSLBA = (gpUSBMSLBA << 16) | ((muint16) *(gpbCBWPacket+kSCSI10LBAByte1) << 8) | *(gpbCBWPacket+kSCSI10LBAByte0);
block = *(gpbCBWPacket+kSCSI10XferLength0);
QCDCT34 = block;
gUSBMSCSWResult = CF_LBACFCommand( *(gpbCBWPacket+kSCSI10XferLength0),kCFCmdRead);
if (!gUSBMSCSWResult) // no error found
{
USBMS_SetPhyEP5(gUSBPacketSize*2); // set USB buffer size
if (gUSBFullSpeed)
{
for (i=0; i<block; i++) // full speed
{
for (j=0; j<8; j++) // full speed
{
while (CF_CR_L & (1<<BSY)); // loop while busy
CF_BSR = 0x3F;
while (mCheckBit(DBSF1,QC34DSR) && (!mCheckBit(DBSF0,QC34DSR)));
(void) CF_IQReadMem();
mSetBit(RXDA, QC34DTR); // Set Receive acknowledge
(void) CF_WaitCardBusy();
}
}
}
else // high speed
{
for (i=0; i<block; i++)
{
while (CF_CR_L & (1<<BSY)); // loop while busy
CF_BSR = 0x1FE;
while (mCheckBit(DBSF1,QC34DSR) && (!mCheckBit(DBSF0,QC34DSR)));
(void) CF_IQReadMem();
mSetBit(RXDA, QC34DTR); // Set Receive acknowledge
(void) CF_WaitCardBusy();
}
}
}
// CF_WaitCardBusy();
while (mCheck2Bit(DBSF1,DBSF0,QC34DSR));// wait for last data to send out
mSetBit(QnEN,QC1CR); // enable QC1
QC1REQ = kQCREQUSBRx; // USB Rx
mClearBit(QnEN,QC4CR); // disable QC4
QC4REQ = kQCREQNone; // map to non existing resource
mSetBit(QnPRST,QC3CR); // reset QC3
mSet2Bit(DRHE,DTHE,QC34DTR); // enable force handshake
mClearBit(QnTHRU,QC3CR); // disable QC34 passthrough mode
if (!gUSBMSCSWResult) // if all data tx out
USBMS_SendCSW();
else
USBMS_SetPhyEP5Int(0); // short packet
}
// ==================================================================
// CFMS_SCSIList2A() -
//
// Write
//
// ==================================================================
void CFMS_SCSIList2A()
{
muint8 i,j,block;
mClearBit(kLED1Pin,kLED1Port);
mUSBClearBit(USBTCIE,UEPCSR4A); // disable Xfer complete int
mSetBit(CH12DBE,IQUECR); // QC12 double buffer
mSetBit(DBRST,QC12DCR); // reset QC12 double buffer
mClearBit(QnEN,QC3CR); // disable QC3
QC3REQ = kQCREQNone; // remap to non-exisiting resources
QC2REQ = kQCREQCFTx; // QC2 = CF Tx
mClear2Bit(DRHE,DTHE,QC12DTR); // disable QC12 force handshake
mSetBit(QnTHRU,QC1CR); // QC12 passthrough mode
block = *(gpbCBWPacket+kSCSI10XferLength0);
gUSBMSCSWResult = CF_LBACFCommand(block,kCFCmdWrite);
if (!gUSBMSCSWResult) // no error
{
mUSBClearBit(SNAK,UEPCSR4A); // enable USB receive
QCDCT12 = *(gpbCBWPacket+kSCSI10XferLength0);
if (gUSBFullSpeed)
{
for (i=block; i>0; i--)
{
for(j=0; j<8; j++)
{
while (!mCheck2Bit(DBSF1,DBSF0,QC12DSR));
while (mCheckBit(BSY,CF_CR_L)); // loop while busy
gUSBMSCSWResult = CF_WaitCardDRQ();
if (gUSBMSCSWResult)
break;
CF_BSR = 0x3F;
(void) CF_IQWriteMem();
}
}
}
else // high speed
{
for (i=block; i>0; i--)
{
while (!mCheck2Bit(DBSF1,DBSF0,QC12DSR));
while (mCheckBit(BSY,CF_CR_L)); // loop while busy
gUSBMSCSWResult = CF_WaitCardDRQ();
if (gUSBMSCSWResult)
break;
CF_BSR = 0x1FE;
(void) CF_IQWriteMem();
}
}
}
if (!gUSBMSCSWResult)
gUSBMSCSWResult = CF_WaitCardBusy();
mUSBSetBit(SNAK,UEPCSR4A);
mSetBit(DBRST,QC12DCR); // reset QC12 double buffer
mClearBit(CH12DBE,IQUECR); // set QC12 single buffer
mSet2Bit(QnEN,QnPRST,QC1CR); // enable QC1 USB Rx
mClearBit(QnEN,QC2CR); // disable QC2
QC2REQ = kQCREQNone; // remap QC2 to unused area
mSetBit(QnPRST,QC1CR); // reset QC1
mClearBit(QnTHRU,QC1CR); // not passthrough
if (gUSBMSCSWResult) // error found
mUSBSetBit(STALL,UEPCSR4A);
USBMS_SendCSW();
mUSBSetBit(USBTCIE,UEPCSR4A); // enable Xfer complete int
mSetBit(kLED1Pin,kLED1Port);
}
void CFMS_SCSIList2F()
{
if (gUSBMSDeviceReady[COMPACTFLASH])
{
gUSBMSCSWResult = kCSWPass;
USBMS_SendCSW();
}
else
USBMS_SCSINotSupport();
}
muint8 CFMB_WaitIQUE(volatile muint8* QCxxDCR)
{
muint16 BegTime, CurTime;
BegTime = MK_GetCurrentTime(); // begin time
do
{
if (!*QCxxDCR)
return(kCSWPass); // exit
CurTime = MK_GetCurrentTime(); // current time
}
while ( ((CurTime-BegTime) < kCFTimeout) || ((BegTime - CurTime) < kCFTimeout));
gCFError = kSCSISKHardwareError;
return(kCSWPhaseError); // timeout => phase error
}
//
// The end of file USBMS_processor.c
// *********************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -