📄 sdms_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: sdms_processor.c REVISION 0.1
*
* DESCRIPTION: This module handles the SD Mass Storage Processor
* applicaton tasks for the system
*
* NOTES: All modules remain at their reset addresses
*
* UPDATED HISTORY:
*
* REV YYYY.MM.DD AUTHOR DESCRIPTION OF CHANGE
* --- ---------- ------ ---------------------
* 0.0 2004.03.01 Taine Chang Initial version
* 0.1 2004.04.12 Derek Lau
* Kenny Lam Demo 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 "UF32reg.h" // Get the UF32 registers.
//#define _USBMS_G_DECL_
#include "usbms_extern.h" // Get USB Mass Storage global prototypes
#include "usb_extern.h"
#include "usb_includes.h"
#include "usbms_includes.h"
#define _SD_SCSILIST_EXTERN_G_DECL_
#include "sdms_scsilist.h"
#include "sd_extern.h"
#include "sd_includes.h"
#define kCBWDirection 0x80 // direction
#define kHost2Device 0 // 0-host to device, 1-device to host
#define QUE_FULL 2 // Que full
#define QUE_EMPTY 0 // Que empty
// code is placed in the main code area.
#pragma CODE_SEG DEFAULT
// ==================================================================
// SCSILIST00() -
//
// Test Unit Ready
//
// ==================================================================
void SDMS_SCSIList00(/*msSCSIMessage *myEventMsg*/)
{
if (gUSBMSDeviceReady[SECUREDIGIT] && !gUSBMSSenseKey[SECUREDIGIT])
{
gUSBMSCSWResult = kCSWPass;
USBMS_SendCSW();
}
else
USBMS_SCSINotSupport();
}
// ==================================================================
// SCSILIST03() -
//
// Request Sense
//
// ==================================================================
void SDMS_SCSIList03()
{
gUSBMSCSWResult = kCSWPass;
QC3DR = 0x7000; // error code / segment number
QC3DR = gUSBMSSenseKey[SECUREDIGIT]; // 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[SECUREDIGIT]; // Add sense key/ add sense code qualifier
QC3DR = 0x0000;
QC3DR = 0x0000;
USBMS_SetPhyEP5Int1(*(gpbCBWPacket+kCBWXferLength0),0x12);
if (gUSBMSSenseKey[SECUREDIGIT] == (kSCSISKUnitAttention<<8))
gUSBMSSenseKey[SECUREDIGIT] = 0;
}
// ==================================================================
// SCSILIST12() -
//
// Inquiry
//
// ==================================================================
void SDMS_SCSIList12(void)
{
muint16 i,*p;
const char S[] = "FSL_UF32 SD Card Reader R0.0";
p = (muint16 *) &S[0];
QC3DR = 0x0080; // removeable
QC3DR = 0x0002; // SCSI 2 compatible
QC3DR = 0x1f00; // addition length = 31
QC3DR = 0x0000; // reserved
// Vendor Identification 8 bytes
// Product Indentification 16 bytes
// Product Revision Level 4 bytes
for (i=0; i<14; i++)
{
QC3DR = (muint16) ((S[2*(i)] << 8) | S[2*(i)+1]);
}
gUSBMSCSWResult = kCSWPass;
USBMS_SetPhyEP5Int1(*(gpbCBWPacket+kCBWXferLength0),0x24);
}
/*
void SDMS_SCSIList1A()
{
gUSBMSCSWResult = kCSWPass;
QC3DR = 0x0000;
QC3DR = 0x0000;
USBMS_SetPhyEP5Int1(*(gpbCBWPacket+kCBWXferLength0),0x04);
}
void SDMS_SCSIList23()
{
muint16 i,*p;
const int R[] =
{
0x0000,0x0010,0x0003,0xD3FF,0x0200,0x0200,0x0003,0xD3FF,
0x0000,0x0200
};
p = (muint16 *) &R[0];
for (i=0; i<10; i++)
{
QC3DR = R[i];
}
gUSBMSCSWResult = kCSWPass;
USBMS_SetPhyEP5Int1(*(gpbCBWPacket+kCBWXferLength0),0x14);
}
*/
// ==================================================================
// SCSILIST25() -
//
// Read Capacity
//
// ==================================================================
void SDMS_SCSIList25()
{
muint16 *pBuffer;
pBuffer = (muint16 *) 0x2400;
if (gUSBMSDeviceReady[SECUREDIGIT])
{
gUSBMSCSWResult = (muint8)SD_SCSIReadCapacity();
USBMS_SetPhyEP5Int(8);
}
else
USBMS_SCSINotSupport();
}
// ==================================================================
// SDMS_SCSIList28() -
//
// Read
//
// ==================================================================
void SDMS_SCSIList28()
{
volatile muint32 SD_LBA;
muint16 status,i;
muint8 *pBuffer,k=0;
if (!gUSBMSDeviceReady[SECUREDIGIT])
{
USBMS_SCSINotSupport();
return;
}
mClearBit(kLED3Pin,kLED3Port); // SD LED OFF
mClearBit(QnEN,QC1CR); // disable QC1
QC1REQ = 0xff; // remap QC1 to mon-existing resources
QC2REQ = 0xff; // remap QC1 to mon-existing resources
mSetBit(DBRST,QC34DCR); // reset QC34
mUSBClearBit(USBTCIE,UEPCSR5A); // disable PhyEP5 Xfer complete int
mSetBit(QnPRST, QC3CR); // reset QC3
QC3REQ = 0x01; // USB Tx
USBMS_SetPhyEP5(gUSBPacketSize*2);
gUSBMSCSWResult = (muint8) SD_LBASDCommand(*(gpbCBWPacket+kSCSI10XferLength0));
SD_LBA=gSD_LBA;
pBuffer = (muint8 *) 0x2400;
if(gUSBFullSpeed==0)
{
IQUECR = (1<<CH34DBE)+(1<<IQUEEN); // Enable double buffer
QC34DTR = 0; // Enable force handshake
mClearBit(SBTE,QC34DCR); // clear single buffer mode
// mSetBit(DBTIE,QC34DCR); // Enable doubble buffer transfer int. mode
QC3CR=0x17; // Q1SML = 0, large buffer 16-bit transfer
QC3SZB=0x12; // 512 bytes block, starting from $0400
QC3REQ=0x01; // USB Tx
QC4REQ=0x08; // SD Rx channel
mClearBit(QnEN,QC1CR); // disable QC1
QC1REQ = 0xff; // remap QC1 to mon-existing resources
}
if(gUSBFullSpeed) //full speed operation
{
for(i=0;i<gSD_DSCR_B;i++)
{
// status = SM_readw_FS((segment>>1),phyblock);
status=SD_QUE_ReadSingleBlock_FS(SD_LBA++);
while((QC34DSR&3)!=QUE_EMPTY); //wait for Que empty
}
}
else
{
// while((QC34DSR&3)==QUE_FULL); //for high speed
// status=SD_QUE_ReadSingleBlock(SD_LBA++);
// QCDCT34 = gSD_DSCR_B;
status = SD_QUE_ReadMultipleBlock(SD_LBA, gSD_DSCR_B);
}
while((QC34DSR&3)!=QUE_EMPTY); //wait for Que empty
mUSBSetBit(SNAK,UEPCSR4A); // disable USB tx
/* IQUECR = (1<<CH34DBE)+(1<<IQUEEN); // Enable double buffer
QC1CR |= (1<<QnEN); // enable QC1
QC1REQ = 0x00; // USB Rx
QC4CR &= ~(1<<QnEN); // disable QC4
QC4REQ = 0xff; // map to non existing resource
QC34DTR |= 0x03; // force handshake
gUSBMSCSWResult = kCSWPass; //test
USBMS_SendCSW();
*/
IQUECR = (1<<CH34DBE)+(1<<IQUEEN); // Enable double buffer
QC34DTR = (1<<DTHE)+(1<<DRHE); // Enable force handshake
QC3CR = (1<<QnEN)+(1<<Qn16EN)+(1<<QnPRST);
QC3SZB = 0x12; // 2 block 0f 256 bytes (HS), base 0x2000
QC3REQ = 0x01; // Channel 3 set to USB TX
QC1CR = (1<<QnEN)+(1<<Qn16EN)+(1<<QnPRST);
QC1SZB = 0x10; // 2 block of 256 bytes (HS)
QC1REQ = 0x00; // Channel 1 set to USB RX
gUSBMSCSWResult = kCSWPass; //test
USBMS_SendCSW();
}
// ==================================================================
// SDMS_SCSIList2A() -
//
// Write
//
// ==================================================================
void SDMS_SCSIList2A()
{
muint32 SD_LBA;
muint16 i,k,status,error=0;//,usbPacketSize;
muint8 *scptr,block;
mClearBit(kLED3Pin,kLED3Port); // SD LED OFF
mSetBit(DBRST,QC12DCR);
mSetBit(QnPRST, QC1CR);
mSetBit(DBRST,QC34DCR);
mUSBClearBit(USBTCIE,UEPCSR4A); // disable Xfer complete int
mUSBWriteClearBit(TFRC,UEPCSR4A);
QC3REQ = 0xff; // remap to non-exisiting resources
QC4REQ = 0xff; // remap to non-exisiting resources
gUSBMSCSWResult = (muint8) SD_LBASDCommand(*(gpbCBWPacket+kSCSI10XferLength0));
SD_LBA = gSD_LBA;
block = gSD_DSCR_B;
if(gUSBFullSpeed)
{
IQUECR = (1<<CH12DBE)+(1<<IQUERST)+(1<<IQUEEN); // Enable double buffer
QC1CR=0x1D; // Q3SML = 1, small buffer 16-bit transfer not passthrough
QC1SZB=0x30; // 64 bytes block, starting from $2000
QC2SZB=0x34; // 64 bytes block, starting from $2000
QC1REQ=0x0; // USB Rx channel to QueRam
QC2REQ=0xff; // SM Tx channel
QC12DTR |= (1<<DRHE)+(1<<DTHE); // enable force handshake
}
else
{
mClearBit(CH34DBE,IQUECR); // disable QC34 double buffer
mClearBit(QnEN,QC3CR); // disable QC3
mClearBit(QnEN,QC4CR); // disable QC4
// IQUECR = (1<<CH12DBE)+(1<<IQUERST)+(1<<IQUEEN); // Enable double buffer
IQUECR = (1<<CH12DBE)+(1<<IQUEEN); // Enable double buffer
QC1CR=0x17; // Q3SML = 0, large buffer 16-bit transfer
QC1SZB=0x12; // 512 bytes block, starting from $0400
QC1REQ=0x0; // USB Rx channel to QueRam
QC2REQ=0x09; // SD Tx channel
QC12DTR &= ~((1<<DRHE)+(1<<DTHE)); // disable QC12 force handshake
}
mUSBClearBit(SNAK,UEPCSR4A); // enable receive
mUSBWriteClearBit(SPKT,UEPCSR4B);
if(gUSBFullSpeed)
{
for(i=0;i<gSD_DSCR_B;i++)
{
QC3CR=0x15; // Q3SML = 0, large buffer 16-bit transfer
QC3SZB=0x14; // 512 bytes block, starting from $0400
QC3REQ=0x09; // SD Tx channel
for(k=0;k<8;k++)
{
while((QC12DSR&3)==0); //wait for 1 of buffers full
if((k&1)==0)
scptr=(muint8*)0x2000;
else
scptr=(muint8*)0x2040;
USB_Move2QUE3( (muint8 *) scptr,64);
while((UMSR1&0xe000)!=0xe000);
mSetBit(TXDA,QC12DTR);
}
asm nop;
}
}
else
{
QCDCT12=gSD_DSCR_B;
/* for(i=0;i<gSD_DSCR_B;i++)
{
while((QC12DSR&3)==0); //wait for 1 of buffers full
status = SD_QUE_WriteMultipleBlock(SD_LBA++, 1);
}
*/
// while((mCheckBit(DBFIF, QC12DSR))==0); // wait for buffer not empty
// mClearBit(DBFIF, QC12DSR); // clear buffer full bit
status = SD_QUE_WriteMultipleBlock(SD_LBA, gSD_DSCR_B);
}
//update logtophyemptytbl
// if(new_logblk==ENABLE)
/* {
QCDCT12=block;
k=0;
while(((QC12DSR&3)==0)&&(error==0)) // wait for buffer not empty
{
if (k++ >= 500000)
error=1;
}
if(error!=1)
{
mlearBit(DBFIF, QC12DSR); // clear buffer full bit
error = SD_QUE_WriteMultipleBlock(SD_LBA, block);
}
}
if (error)
{
w_USBClearBit(SNAK,UEPCSR4A);
w_USBWriteClearBit(TFRC,UEPCSR4A);
mSetBit(STALL,UEPCSR4A);
}
*/
// IQUECR = (1<<CH34DBE)+(1<<IQUERST)+(1<<IQUEEN); // Enable double buffer
IQUECR = (1<<CH34DBE)+(1<<IQUEEN); // Enable double buffer
QC34DTR = (1<<DTHE)+(1<<DRHE); // Enable force handshake
QC3CR = (1<<QnEN)+(1<<Qn16EN)+(1<<QnPRST);
QC3SZB = 0x12; // 2 block 0f 256 bytes (HS), base 0x2000
QC3REQ = 0x01; // Channel 3 set to USB TX
QC1CR = (1<<QnEN)+(1<<Qn16EN)+(1<<QnPRST);
QC1SZB = 0x10; // 2 block of 256 bytes (HS)
QC1REQ = 0x00; // Channel 1 set to USB RX
USBMS_SendCSW();
mSetBit(kLED3Pin,kLED3Port); // SD LED OFF
}
void SDMS_SCSIList2F()
{
if (gUSBMSDeviceReady[SECUREDIGIT])
{
gUSBMSCSWResult = kCSWPass;
USBMS_SendCSW();
}
else
USBMS_SCSINotSupport();
}
//
// The end of file usbms_processor.c
// *********************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -