⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d12_int.c

📁 sd卡usb读卡器的设计,仅供大家交流参考
💻 C
字号:
#include "D12_INT.h"
#include "USB_MassStorage.h"

#include "MMC_SD.h"


CBW cbw;
CSW csw;

unsigned char DISK_INF[36]=                   //Disk infomation                   //磁盘信息
{
 0x00,
 0x00,//最高位表示是否是可移动设备  //MSB of this byte indicate that this is removable disk
 0x00,
 0x01,
 0x1F,
 0x00,0x00,0x00,

 '*',0xd5,0xc2,0xc6,0xe4,0xb2,0xa8,'*',//这一段可以自己添加内容,但长度不可变,编码为ascii 也可是gbk
//You can add infomation here, a ASCII string needed, but the length must be 8 
 
 0xd6,0xc6,0xd7,0xf7,0xb5,0xc4,0xbf,0xc9,0xd2,0xc6,0xb6,0xaf,0xb4,0xc5,0xc5,0xcc,//这一段可以自己添加内容,但长度不可变,编码为ascii 也可是gbk
//You can add infomation here, a ASCII string needed, but the length must be 16
 
 
 
 0x31,0x2E,0x30,0x31
};

//Dis capacity. The first four bytes is the max LBA address
//It will be reinitialized when SD card is ready
unsigned char DISK_CAPACITY[8]=                                  //磁盘容量//在SD初始化后会修改
{
 0x00,0x0F,0x1C,0xF0,
 0x00,0x00,0x02,0x00
};

//the requied data of MODE SENSE
unsigned char SENSE[0x12]=                                      //模式探测返回数据
{
0x70, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00
};

//返回CSW包
void Send_CSW(U32 DataResidue,U8 status)
{
	csw.dCSWSignature = 0x53425355; //csw包标志
	csw.dCSWTag=cbw.dCBWTag;		//主机发过来的tag
 	csw.dCSWDataResidue=DataResidue;
 	csw.bCSWStatus=status;
 	while(D12_Select_Endpoint(5));
 	D12_Write_Endpoint(5, (U8 *)&csw, 13);//定长度 13字节
}

//SCSI读操作
void read_10()
{
	U32 Byte_Count;//总字节数
	U32 LBA;		//LBA地址
	U8 j=0;


//得到LBA地址	
	LBA = 0;
	LBA += cbw.CBWCB[2];
	LBA <<= 8;
	LBA += cbw.CBWCB[3];
	LBA <<= 8;
	LBA += cbw.CBWCB[4];
	LBA <<= 8;
	LBA += cbw.CBWCB[5];

//得到传输字节数	
	Byte_Count = 0;
	Byte_Count+=cbw.CBWCB[7];
	Byte_Count<<=8;
	Byte_Count+=cbw.CBWCB[8];
	Byte_Count<<=9;
 
//传输数据   //一个while循环为读一个扇区 
   while(1)	
   {
   		//以下为SD读一扇区的前导操作
		if(MMC_SD_SendCommand(17, LBA<<9)!=0x00){return;} 
		SPI_CS_Assert();
		while(SPI_WriteByte(0xff) != 0xfe);//等数据的开始	//wait to start recieve data
		LBA++;
		for(j=0;j<8;j++)
		{
			D12_Write_Endpoint_SD(5);//写端点,与SD卡同时操作//每次64字节
			Byte_Count-=64;
			if(Byte_Count==0)
			{
				//读一扇区结尾的伪crc
				SPI_WriteByte(0xff);//伪crc
				SPI_WriteByte(0xff);
	
				SPI_CS_Deassert();

				return;//结束返回
			}
		}
		//读一扇区结尾的伪crc
		SPI_WriteByte(0xff);//伪crc
		SPI_WriteByte(0xff);
	
		SPI_CS_Deassert();
	}
}

//SCSI写操作
void write_10()
{
	U32 Byte_Count;//写字节数
	U32 LBA;		//写LBA地址
	U8 j=0;

	U8 buffer[512];	//实践证明写SD卡操作不可像读操作那样操作,否则会出错 所以用缓冲区来做 等收到512字节再写

//LBA地址
	LBA = 0;
	LBA += cbw.CBWCB[2];
	LBA <<= 8;
	LBA += cbw.CBWCB[3];
	LBA <<= 8;
	LBA += cbw.CBWCB[4];
	LBA <<= 8;
	LBA += cbw.CBWCB[5];

//总字节数	
	Byte_Count = 0;
	Byte_Count+=cbw.CBWCB[7];
	Byte_Count<<=8;
	Byte_Count+=cbw.CBWCB[8];
	Byte_Count<<=9;

//写操作 1个while循环写1扇区   
	while(1)	
	{
		D12_Read_Endpoint(4, &buffer[j*64], 64);//正常端点读操作
		j++;
		Byte_Count-=64;
		if(j==8)//计满512字节后一起写到sd卡内
		{
			j=0;
			MMC_SD_WriteSingleBlock(LBA++, buffer);
		}
		if(Byte_Count==0)return;//结束返回
	}
}

//标准请求的函数指针
U8 (*Stand_Device_Request[])(U8 *SetupPacket) = 
{
	Get_Status,
	Clear_Feature,
	Reserved,
	Set_Feature,
	Reserved,
	Set_Address,
	Get_Descriptor,
	Reserved,
	Get_Configuration,
	Set_Configuration,
	Get_Interface,
	Set_Interface,
	Reserved,
	Reserved,
	Reserved,
	Reserved
}; 


/**************************************/
void USB_Delay(U16 Time)
{
	while(Time--)asm("nop");
}



/*****************初始化USB********************/
U8 USB_Init()
{
//	D12_PORT_INI();
	USB_Delay(20000);

	if(D12_Read_Chip_ID()!=0x1210 )
		return 0;

	D12_Set_DMA(MyD12DmaCfg);
	if(D12_Get_DMA()!=MyD12DmaCfg)
		return 0;

	D12_Set_Mode(MyD12EpCfgOff, D12Pll24M);
	USB_Delay(20000);
	USB_Delay(20000);
	D12_Set_Mode(MyD12EpCfgOn, D12Pll24M);

	return 1;
}


/********************** D12 interrupt process ******************/
void D12Ep0IntProc()
{
	U8 SetupPacket[8];
	U8 i = 0;
	
	Clear_Remain_Descriptor_Flag();
	//printf("\nEndpoint0 Process!");
	if(D12_Read_Last_Transaction_Status(0)&0x20)
	{	

		if(D12_Read_Endpoint(0, SetupPacket, 8)==8)
		{
			D12_Ack_Endpoint(0);
			D12_Ack_Endpoint(1);
			
			//for(i=0; i<8; i++)
				//printf("%x,", SetupPacket[i]);
			if(SetupPacket[0] == 0xa1 && SetupPacket[1] == 0xfe)
			{
				D12_Write_Endpoint(1,&i,1);
			}
			if(!Stand_Device_Request[SetupPacket[1]&0xf](SetupPacket));//调用相应的标准请求响应函数
				return;
		}
	}
					
	D12_Set_Endpoint_Status(0, D12EpStall);
	D12_Set_Endpoint_Status(1, D12EpStall);		
}

void D12Ep1IntProc()
{
	U8 i;
	//printf("\nEndpoint1 Process!\n");
	i = D12_Read_Last_Transaction_Status(1);
	if(Remain_Descriptor_Flag())
		Send_Descriptor();
		
}

void D12Ep2IntProc()
{
//	printf("\nEndpoint2 Process!\n");
	D12_Set_Endpoint_Status(2, D12EpStall);
}

void D12Ep3IntProc()
{
//	printf("\nEndpoint3 Process!\n");
	D12_Set_Endpoint_Status(3, D12EpStall);
}

void D12Ep4IntProc()
{
	//printf("\nEndpoint4 Process!\n");
	D12_Read_Last_Transaction_Status(4);	
	D12_Read_Endpoint(4, (U8 *)&cbw, Endpoint2_Packet_Size);
	if(cbw.dCBWSignature != 0x43425355)return;			//cbw包标志

	if(cbw.bmCBWFlags&0x80)								//写操作
	{
		switch(cbw.CBWCB[0])
		{
			case              Read_10: read_10();Send_CSW(0x00,SUCCESS);break;
			case              Inquiry: D12_Write_Endpoint(5,DISK_INF,36);Send_CSW(0x00,SUCCESS); break;
  		  	case        Read_Capacity: D12_Write_Endpoint(5,DISK_CAPACITY,0x08);Send_CSW(0x00,SUCCESS);break;
  	 	 	case Read_Format_capacity: D12_Write_Endpoint(5,0x00,0x00);Send_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
   		 	case        Request_Sense: D12_Write_Endpoint(5,SENSE,0x12);Send_CSW(0x00,SUCCESS);break;
		 	case                 0x1a: D12_Write_Endpoint(5,0x00,0x00);Send_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
   		 	default                  : D12_Write_Endpoint(5,0x00,0x00);Send_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
		}
	}
	else												//读操作
	{
		switch(cbw.CBWCB[0])
		{
			case        Write_10: write_10();Send_CSW(0x00,SUCCESS);break;
			case Test_Unit_Ready: Send_CSW(0x00,SUCCESS);break; 
			case          Verify: Send_CSW(0x00,SUCCESS);break;
			default             : Send_CSW(cbw.dCBWDataTransgerLength,FAIL);break;
		}
	}
}

void D12Ep5IntProc()
{
	//printf("\nEndpoint5 Process!\n");
	D12_Read_Last_Transaction_Status(5);//所有的数据传输都已在ep4内完成,该程序没有采用中断机制
}

void D12BusRstProc()
{
	//printf("\nBus Reset!");
	D12_Clear_Buffer();
	D12_Enable_Buffer();
	D12_Set_Endpoint_Enable(1);
}

void D12SuspChgProc()
{
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -