?? msdc_dma.c
字號:
/*++
Copyright (c) 2001 Sunplus Technology Co., Ltd.
Module Name:
msdc_dma.c
Abstract:
Module related to Bulk-Only Transport of USB Mass Storage Device Class
Environment:
Keil C51 Compiler
Revision History:
08/28/2001 Richie li created
--*/
//=============================================================================
//Header file
//=============================================================================
#include "general.h"
//richie@si0417
#if ((USBMSDC_OPTION == 2) || (USBSIDC_OPTION == 1))
//richie@si0417 mark
//#include "usbmsdc2.h"
#include "msdc_dma.h"
//patch4.3@richie@res0530
extern xdata ULONG G_ulStorDataIndex;
//-----------------------------------------------------------------------------
//USBMSDC_L2_DoDMA
//-----------------------------------------------------------------------------
/*
routine description:
DMA data transfer, the source and the desitination cannot be the same
arguments:
Src: the source of DMA
0: DRAM
1: CPU 4K SRAM (0x1000 ~ 0x1FFF)
2: Storage Media
3: Audio
4: USB
5: DMA data port (0x2300)
Dst: the destination of DMA
0: DRAM
1: CPU 4K SRAM (0x1000 ~ 0x1FFF)
2: Storage Media
3: Audio
4: USB
5: DMA data port (0x2300)
nByte: the number of byte in the DMA data transfer (tha maximum size is 1024)
Mode:
0: the function return after the DMA is completed
1: the function return immediately after the DMA is trigger
FlashPageDMA
0: normal operation
1: if flash is one of the DMA source/destination, flash accessing is always in the unit of page
the insufficent data is stuffing by 0's
return value:
0x00 - success
others - error
*/
//richie@sd done
UCHAR USBMSDC_L2_DoDMA(UCHAR Src,UCHAR Dst, USHORT nByte, UCHAR Mode, UCHAR FlashPageDMA) USING_1
{
data UCHAR sramflag; // WWWW
data UCHAR dmamode; // WWWW
////PRINT_L2(" L2_DoDMA: Enter L2_DoDMA(Src=%x,Dst=%x,nByte=%x,Mode=%x,FlashPageDMA=%x)\n",(USHORT)Src,(USHORT)Dst,nByte,(USHORT)Mode,(USHORT)FlashPageDMA);
nByte = nByte - 1;
dmamode = Mode;
XBYTE[0x2301] = (Dst<<4)|Src;
XBYTE[0x2304] = 0x09; // reset DMA machine
XBYTE[0x2304] = 0x08;
XBYTE[0x23C0] = 0x00;
if(FlashPageDMA) XBYTE[0x2304] |= 0x02; // padding 0's to flash
else XBYTE[0x2304] &= 0xfd;
if((nByte>>10)!=0) return 0x01; // DMA size
XBYTE[0x2302] = (UCHAR)nByte&0xff;
XBYTE[0x2303] = (UCHAR)(nByte>>8)&0x03;
sramflag = 0;
if(Src==0x01 || Dst==0x01)
{
XBYTE[0x2C00] &= 0x1d;
XBYTE[0x2C11] = 0x02;
XBYTE[0x2C00] |= 0x02;
sramflag = 1;
}
XBYTE[0x23B0] = 0x01; // trigger DMA
if(dmamode) return L2K_SUCCESS;
else while(XBYTE[0x23C0]==0) ; // wait for DMA complete
XBYTE[0x23C0] = 0x00;
if(sramflag == 1)
{
XBYTE[0x2C00] &= 0x1d;
XBYTE[0x2C11] = 0x00;
XBYTE[0x2C00] |= 0x02;
}
////PRINT_L2(" L2_DoDMA: Exit L2_DoDMA\n");
return L2K_SUCCESS;
}
//-----------------------------------------------------------------------------
//USBMSDC_SDRAM_Dram2Usb
//-----------------------------------------------------------------------------
BYTE USBMSDC_Dram2Usb(ULONG DramAddr,USHORT size) USING_1
{
ULONG temp = DramAddr;
USBMSDC_L2_SetDRAMDMA(DramAddr);
USBMSDC_L2_SetUSBDMA(K_DMA_UsbDontCare,K_USB_CLASS_DMA_IN);//for class
USBMSDC_L2_DoDMA(K_DMA_DRAM,K_DMA_USB,size,1,0);
//DMA from CF to sdram for "size" bytes and wait till end and no nandf
return TRUE;
}
//-----------------------------------------------------------------------------
//USBMSDC_Usb2Dram
//-----------------------------------------------------------------------------
BYTE USBMSDC_Usb2Dram(ULONG DramAddr,USHORT size) USING_1
{
USBMSDC_L2_SetDRAMDMA(DramAddr);
USBMSDC_L2_SetUSBDMA(K_USB_CLASS_DMA_OUT,K_DMA_UsbDontCare);//for class
USBMSDC_L2_DoDMA(K_DMA_USB,K_DMA_DRAM,size,1,0); //DMA from CF to sdram for "size" bytes and wait till end and no nandf
return L2K_SUCCESS;
}
//-----------------------------------------------------------------------------
//USBMSDC_Sram2Usb
//-----------------------------------------------------------------------------
BYTE USBMSDC_Sram2Usb(USHORT size) USING_1
{
if (size <= 1024)
{
//USBMSDC_L2_SRAMLow2High(size,sramAddr);
//patch4.3@richie@res0530
USBMSDC_L2_SetSRAMDMA(0x0c00 + G_ulStorDataIndex);
USBMSDC_L2_SetUSBDMA(K_DMA_UsbDontCare,K_USB_CLASS_DMA_IN);//for class
USBMSDC_L2_DoDMA(K_DMA_SRAM,K_DMA_USB,size,0,0);
USBMSDC_L2_Set4KSRAMMode(0x00);
return TRUE;
}
else
{
return FALSE;
}
}
//-----------------------------------------------------------------------------
//USBMSDC_CF_LUsb2Sram
//-----------------------------------------------------------------------------
BYTE USBMSDC_Usb2Sram(UCHAR* sramAddr, USHORT size) USING_1
{
if (size <= 1024)
{
USBMSDC_L2_SetSRAMDMA(0x0c00);
USBMSDC_L2_SetUSBDMA(K_USB_CLASS_DMA_OUT,K_DMA_UsbDontCare);//for class
USBMSDC_L2_DoDMA(K_DMA_USB,K_DMA_SRAM,size,0,0);
USBMSDC_L2_SRAMHigh2Low(size,sramAddr);
//richie@0117
USBMSDC_L2_Set4KSRAMMode(0x00);
return TRUE;
}
else
{
return FALSE;
}
}
//-----------------------------------------------------------------------------
//USBMSDC_L2_Set4KSRAMMode
//-----------------------------------------------------------------------------
/*
routine description:
high bank 4k sram mode selection
arguments:
Mode: 0: addressible SRAM (0x1000 - 0x1FFF)
1: access data port (0x2C10) (0x0000 - 0x0FFF)
2: used for DMA buffer (0x0000 - 0x0FFF)
return value:
0x00 - success
others - error
*/
//richie@sd done
UCHAR USBMSDC_L2_Set4KSRAMMode(UCHAR Mode) USING_1
{
UCHAR tmp0;
tmp0 = XBYTE[0x2C00];
XBYTE[0x2C00] = tmp0 & 0x1d;
if(Mode == 0) XBYTE[0x2C11] = 0x00;
else if(Mode == 1) XBYTE[0x2C11] = 0x01;
else if(Mode == 2) XBYTE[0x2C11] = 0x02;
else {XBYTE[0x2C00] = tmp0 | 0x02; return 0x01;}
XBYTE[0x2C00] = tmp0 | 0x02;
return L2K_SUCCESS;
}
//-----------------------------------------------------------------------------
//USBMSDC_L2_SRAMHigh2Low
//-----------------------------------------------------------------------------
UCHAR USBMSDC_L2_SRAMHigh2Low(USHORT siz,UCHAR* buffer) USING_1
{
USHORT i;
XBYTE[0x2C11] &= 0xFC; //High bank sram can is addressed from 0x1000 to 0x1fff
for (i = 0; i < siz; i++)
{
buffer[i] = XBYTE[0x1c00 + i];
}
return L2K_SUCCESS;
}
//-----------------------------------------------------------------------------
//USBMSDC_L2_SRAMLow2High
//-----------------------------------------------------------------------------
UCHAR USBMSDC_L2_SRAMLow2High(USHORT siz,UCHAR* buffer) USING_1
{
USHORT i;
XBYTE[0x2C11] &= 0xFC; //High bank sram can is addressed from 0x1000 to 0x1fff
for (i = 0; i < siz; i++)
{
XBYTE[0x1c00 + i] = buffer[i];
}
return L2K_SUCCESS;
}
//-----------------------------------------------------------------------------
//USBMSDC_L2_SetSRAMDMA
//-----------------------------------------------------------------------------
/*
routine description:
SRAM DMA setting
arguments:
SRAMAddr: 4K SRAM buffer, starting address (0x0000 - 0x0FFF)
return value:
0x00 - success
others - error
*/
//richie@sd done
UCHAR USBMSDC_L2_SetSRAMDMA(USHORT SRAMAddr) USING_1
{
if((SRAMAddr & 0xF000)!=0) return 0x01 ;
XBYTE[0x2C12] = (UCHAR)SRAMAddr&0xFF;
XBYTE[0x2C13] = (UCHAR)(SRAMAddr>>8)&0x0F;
XBYTE[0x2C11] |= 0x04;
XBYTE[0x2C11] &= 0xFB;
return L2K_SUCCESS;
}
//-----------------------------------------------------------------------------
//USBMSDC_L2_SetUSBDMA
//-----------------------------------------------------------------------------
/*
routine description:
USB DMA setting
arguments:
USBDMASrc:
0: endpoint 3
1: endpoint 8
USBDMADst:
0: endpoint 2
1: endpoint 4
2: endpoint 7
3: endpoint 9
return value:
0x00 - success
others - error
*/
UCHAR USBMSDC_L2_SetUSBDMA(UCHAR USBDMASrc, UCHAR USBDMADst) USING_1
{
XBYTE[0x2510] = USBDMASrc;
XBYTE[0x2511] = USBDMADst;
return L2K_SUCCESS;
}
//-----------------------------------------------------------------------------
//USBMSDC_L2_SetDRAMDMA
//-----------------------------------------------------------------------------
/*
routine description:
DRAM DMA setting
arguments:
DRAMAddr: DRAM starting address
return value:
0x00 - success
others - error
*/
//richie@sd done
UCHAR USBMSDC_L2_SetDRAMDMA(ULONG DRAMAddr) USING_1
{
XBYTE[0x2750] = (UCHAR)(DRAMAddr&0x000000ff);
XBYTE[0x2751] = (UCHAR)((DRAMAddr>>8)&0x000000ff);
XBYTE[0x2752] = (UCHAR)((DRAMAddr>>16)&0x000000ff);
return L2K_SUCCESS;
}
//-----------------------------------------------------------------------------
//USBMSDC_L2_ReadDRAMDMAAdr
//-----------------------------------------------------------------------------
/*
routine description:
Read DRAM DMA address
arguments:
DRAMAddr: DRAM DMA starting address
return value:
None
*/
//richie@sd done
void USBMSDC_L2_ReadDRAMDMAAdr(ULONG* DRAMAddr) USING_1
{
*DRAMAddr = (ULONG)XBYTE[0x2750];
*DRAMAddr |= (ULONG)XBYTE[0x2751]<<8;
*DRAMAddr |= (ULONG)XBYTE[0x2752]<<16;
}
#endif
//end if USBMSDC_OPTION
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -