📄 atams_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: atams_processor.c REVISION 0.1
*
* DESCRIPTION: This module handles the ATA Mass Storage 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 2003.06.27 Derek Lau Initial version
* 0.1 2004.04.08 Derek Lau 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.
#include "usbms_includes.h" // Get USB Mass Storage
#include "usb_extern.h"
#include "usb_includes.h"
#include "ata_includes.h"
#include "ata_extern.h"
#include "app_extern.h"
#include "mk_extern.h"
#include "usbms_extern.h" // Get USB Mass Storage global prototypes
#define _ATA_SCSILIST_EXTERN_G_DECL_
#include "atams_scsilist.h"
// code is placed in the main code area.
#pragma CODE_SEG DEFAULT
// ==================================================================
// SCSILIST00() -
//
// Test Unit Ready
//
// ==================================================================
void ATAMS_SCSIList00(/*msSCSIMessage *myEventMsg*/)
{
if (!gUSBMSDeviceReady[HARDISK])
{
USBMS_SCSINotSupport();
return;
}
gUSBMSCSWResult = kCSWPass;
USBMS_SendCSW();
}
// ==================================================================
// SCSILIST03() -
//
// Request Sense
//
// ==================================================================
void ATAMS_SCSIList03()
{
muint16 zero;
zero = 0;
if (gUSBMSDeviceReady[HARDISK])
gUSBMSSenseKey[HARDISK] = (muint16) gATAError << 8;
mSetBit(QnPRST, QC3CR);
QC3DR = 0x7000; // error code / segment number
QC3DR = gUSBMSSenseKey[HARDISK];
QC3DR = zero; // information / information
QC3DR = 0x000a; // information / additional sense length
QC3DR = zero; // command specific information
QC3DR = zero; // command specific informaton
QC3DR = gUSBMSAddSenseKey[HARDISK];// Add sense key/ add sense code qualifier
QC3DR = zero;
QC3DR = zero;
gUSBMSCSWResult = kCSWPass;
USBMS_SetPhyEP5Int1(*(gpbCBWPacket+kCBWXferLength0),0x12);
}
// ==================================================================
// SCSILIST12() -
//
// Inquiry
//
// ==================================================================
void ATAMS_SCSIList12(void)
{
muint16 *pBuffer;
muint8 i;
const char S[] = "FSL_UF32 ATA Device"; // Vendor Identification 8 bytes
pBuffer = (muint16 *) 0x2400;
QC3DR = 0x0000; // fixed Hardisk
QC3DR = 0x0002; // SCSI 2 compatible
QC3DR = 0x1f00; // addition length = 31
QC3DR = 0x0000; // reserved
if (gUSBMSDeviceReady[HARDISK])
{
gUSBMSCSWResult = ATA_SCSIInquiry(pBuffer);
}
else
{
pBuffer = (muint16 *) &S[0];
for (i=0; i<14; i++)
{
QC3DR = *pBuffer++;
}
gUSBMSCSWResult = kCSWPass;
}
USBMS_SetPhyEP5Int1(*(gpbCBWPacket+kCBWXferLength0),0x24);
}
// ==================================================================
// SCSILIST25() -
//
// Read Capacity
//
// ==================================================================
void ATAMS_SCSIList25()
{
muint8 *pBuffer;
pBuffer = (muint8 *) 0x2400;
if (!gUSBMSDeviceReady[HARDISK])
{
USBMS_SCSINotSupport();
return;
}
mSetBit(QnPRST, QC3CR);
gUSBMSCSWResult = ATA_SCSIReadCapacity(pBuffer);
USB_Move2QUE3(pBuffer,8);
USBMS_SetPhyEP5Int(8);
}
// ==================================================================
// SCSILIST28() -
//
// Read
//
// ==================================================================
void ATAMS_SCSIList28()
{
muint32 i;
muint16 j,data,dummy;
muint8 Block;
muint32 *pLBA;
muint16 *pBlock16,Block16;
if (!gUSBMSDeviceReady[HARDISK])
{
USBMS_SCSINotSupport();
return;
}
mClearBit(kLED1Pin,kLED1Port);
pLBA = (muint32*) (gpbCBWPacket+kSCSI10LBAByte3);
gATALBA = *pLBA;
pBlock16 = (muint16*) (gpbCBWPacket+kSCSI10XferLength1);
Block16 = *pBlock16;
mSetBit(DBRST,QC34DCR); // reset QC34 double buffer
mSetBit(QnTHRU,QC3CR); // QC34 pass through mode
mClearBit(QnEN,QC1CR); // disable QC1
QC1REQ = kQCREQNone; // remap QC1 to mon-existing resources
QC4REQ = kQCREQATARx; // ATA receive
mClear2Bit(DRHE,DTHE,QC34DTR); // disable force handshake
mUSBClearBit(USBTCIE,UEPCSR5A); // disable PhyEP5 Xfer complete int
// block = *(gpbCBWPacket+kSCSI10XferLength0);
if (mCheckBit(bitATAUDMAMode,gATAStatus)) // UDMA mode
{
do
{
if (Block16 & 0xFF00) // Block > 0xff
{
Block = 0xff;
Block16 -= 0xff;
}
else
{
Block = (muint8) Block16;
Block16 = 0;
}
gUSBMSCSWResult = ATA_LBAATACommand(Block,kATACmdReadDMA);
QCDCT34 = Block;
if (!gUSBMSCSWResult) // no error found
{
USBMS_SetPhyEP5(gUSBPacketSize*2); // set USB buffer size
if (gUSBFullSpeed) // full speed
{
for (j=0; j<8; j++)
{
if (USBMS_WaitIQUEwithATAIRQ2(&QCDCT34))
{
gUSBMSCSWResult = kCSWPhaseError;
break;
}
QCDCT34 = Block;
}
if (!gUSBMSCSWResult) // no error found
QCDCT34 = 0; // indicate all data xfered
}
if (Block > 0x80)
asm nop
else // high speed
{
if (USBMS_WaitIQUEwithATAIRQ2(&QCDCT34))
gUSBMSCSWResult = kCSWPhaseError;
}
if (!QCDCT34) // if all data xfered
gUSBMSCSWResult = ATA_WaitATABusy();
}
gATALBA += Block;
}
while (Block16 && !gUSBMSCSWResult);
if (gUSBFullSpeed)
QC3CR = (1<<QnEN)+(1<<QnSML)+(1<<Qn16EN)+(1<<QnPRST); // 16 byte block mode
else
QC3CR = (1<<QnEN)+(1<<Qn16EN)+(1<<QnPRST); // 256 byte block mode
}
else // PIO mode
{
do
{
if (Block16 & 0xFF00) // Block > 0xff
{
Block = 0xff;
Block16 -= 0xff;
}
else
{
Block = (muint8) Block16;
Block16 = 0;
}
gUSBMSCSWResult = ATA_LBAATACommand(Block,kATACmdRead);
if (!gUSBMSCSWResult)
{
USBMS_SetPhyEP5(gUSBPacketSize*2); // set USB buffer size
for (i=0; i< (muint16) Block<<kOneByte;i) // get data
{
for (j=0; j<gUSBPacketSize; j++)
{
i++;
dummy = ATA_DDR;
(void) ATA_WaitRegBusy();
data = ATA_DDR;
QC3DR = data;
}
mSetBit(RXDA, QC34DTR); // Set Receive acknowledge
while ((QC34DSR & 0x03) == 2); // wait while both buffer are full
if ((i & 0x00ff) == 0)
{
gUSBMSCSWResult = ATA_WaitATABusy();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -