📄 iusbprocesscommand.c
字号:
// This routine is called by the interrupt handler (triggered by the IN endpoint).
// It handles commands from the USB host
#include "usb_pptt.h"
#include "usb_pdef.h"
#include "usb_pvar.h"
U8 _gUsbDrvNum; // drive number (either 0 or 1)
U16 _gUsbSectorBuf[256]; // buffer for sector data
P_U16 _gpUsbBufPtr; // pointer to buffer data
U8 _gUsbNumSector; // number of sector to read/write
U16 _gUsbCurSector; // current sector being read/write
U8 _gUsbPacketCount; // USB packet count
U8 _gUsbDataToHost; // flag indicating whether data is to be sent to host
// The following 512 bytes of data seems to be some kind of configuration data
// for the card reader (or of the card being read).
// It's just reverse-engineered from the USB traffic.
// No information of what it mean.
const U16 _gUsbDrvParam[256] = {
0x8000,0xF401,0x0000,0x0400,0x0000,0x0000,0x1000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0002,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x007D,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
};
void _iUsbProcessCommand()
{
U16 command[4];
U8 i;
EVENT wakeupEvent;
_gUsbDataToHost = FALSE;
/* get command from endpoint FIFO */
for (i=0; i<4; i++)
{
command[i] = _reg_USB_EP3_FDAT;
}
/* extract start sector and number of sectors */
_gUsbCurSector = ((command[1] & 0xFF) << 8) | ((command[1] >> 8) & 0xFF);
_gUsbNumSector = command[0] & 0xFF;
_gUsbDrvNum = (((U8) command[2]) >> 4) & 1;
command[2] &= 0xFFEF;
/* handle various commands */
if (command[2] == 0x00A0) // i.e. read drive parameters
{
if (_gUsbDrvStatus[_gUsbDrvNum] == USB_DRV_NOT_READY)
{
_reg_USB_EP4_FCTRL |= 0x20000000;
_reg_USB_EP4_FDAT = 0xFF04; // drive not ready
}
else // i.e. status == USB_DRV_READY
{
if ((*((_gUsbCallbacks->Drv[_gUsbDrvNum]).driveStatus))() ==
USB_DRV_NOT_READY)
{
_reg_USB_EP4_FCTRL |= 0x20000000;
_reg_USB_EP4_FDAT = 0xFF04; // drive not ready
}
else
{
// This command read the parameter of the disk.
// We'll map the buffer pointer to the parameter block.
// And then, we pretend that it is a ordinally file system read
// operation to return the data requested
_gUsbNumSector = 0; // no need to read from disk
// set buffer pointer to parameter block
_gpUsbBufPtr = (P_U16)&_gUsbDrvParam;
// change command to pretend that it's a read sector command
command[2] = 0x00E0;
command[3] = 0x2001;
}
}
}
if (command[2] == 0x00E0) // i.e. disk read/write
{
if (_gUsbMode == USB_USE_INTR_ONLY)
{
if (command[3] == 0x2001) // i.e. read operation */
{
if (_gUsbNumSector > 0)
{
_iUsbReadSector();
}
// write first 2 packets to FIFO
for (i=0; i<31; i++)
{
_reg_USB_EP4_FDAT = *(_gpUsbBufPtr++);
}
_reg_USB_EP4_FCTRL |= 0x20000000; // next write is last one in packet
_reg_USB_EP4_FDAT = *(_gpUsbBufPtr++);
for (i=0; i<31; i++)
{
_reg_USB_EP4_FDAT = *(_gpUsbBufPtr++);;
}
_reg_USB_EP4_FCTRL |= 0x20000000; // next write is last one in packet
_reg_USB_EP4_FDAT = *(_gpUsbBufPtr++);
_gUsbPacketCount = 2; // count #packets copied to FIFO
_gUsbDataToHost = TRUE;
}
else // write operation (i.e. 0x3001)
{
// initialize variable to get ready for data from host
// interrupt will then be generated to receive data
_gUsbPacketCount = 0;
_gpUsbBufPtr = (P_U16)&_gUsbSectorBuf;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -