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

📄 mx1_usb.c

📁 ucos usb
💻 C
📖 第 1 页 / 共 2 页
字号:
{
	U32 fifoWord;
	U8  i, j,tmp;
	
	/* read device request data from FIFO */
	j = 0;
	for (i=0; i<2; i++)
	{
		fifoWord = _reg_USBD_EP0_FDAT;
		tmp = (U8)(fifoWord >> 24);
//		 EUARTputHex(tmp);
		_gUsbDevReq[j++] = tmp;
		
		tmp = (U8)(fifoWord >> 16);
//		 EUARTputHex(tmp);
		_gUsbDevReq[j++] = tmp;
		
		tmp = (U8)(fifoWord >> 8);
//		 EUARTputHex(tmp);
		_gUsbDevReq[j++] = tmp;		
				
		tmp = (U8)(fifoWord);
//		 EUARTputHex(tmp);
		_gUsbDevReq[j++] = tmp;
		

	}



	/* decode device request */
	if ((_gUsbDevReq[0] = 0x80) && (_gUsbDevReq[1] = 0x06))
	{
		switch (_gUsbDevReq[3])
		{
			case 0x01:  // device descriptor
				handleGetDevDscptr();
				break;
			case 0x02:  // configuration descriptor
				handleGetConfDscptr();
				break;
		}
	}
	_reg_USBD_EP0_INTR_STAT = 0x1FF;   // clear all interrupt flags
}

void readSectors()
{
	U8	done, i;

	done = 0;
	while (!done)
	{
		while (!(_reg_USBD_EP1_INTR_STAT & EOF_MASK));		// wait for EOF flag
		--_gUsbPacketCount;
		if (_gUsbPacketCount > 0)
		{
			for (i=0; i<31; i++)
		   	*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = *(_gpUsbBufPtr++);
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = *(_gpUsbBufPtr++);
		}
		else
		{
			// now the CSW
			_reg_USBD_EP1_FDAT = 0x55534253;		// signature in BIG endian
			for (i=0; i<4; i++)
				*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i];	// CSWtag
			_reg_USBD_EP1_FDAT = 0;		// data residue
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0;	// status: passed
		
			done = 1;
		}
		_reg_USBD_EP1_INTR_STAT |= EOF_MASK;	// clear EOF flag
	}
}

void writeSectors()
{
	U8 i;

	while (_gUsbPacketCount > 0)
	{
		while (!(_reg_USBD_EP2_INTR_STAT & EOF_MASK));		// wait for EOF flag
		
		while (((_reg_USBD_EP2_STAT >> 16) & 0x7F) >= 0x20)
		{
			for (i=0; i<32; i++)
		   	*(_gpUsbBufPtr++) = *((volatile U8 *)((U32)&_reg_USBD_EP2_FDAT+3));
			--_gUsbPacketCount;
		}
	}

	// now the CSW
	_reg_USBD_EP1_FDAT = 0x55534253;		// signature in BIG endian
	for (i=0; i<4; i++)
		*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i];	// CSWtag
	_reg_USBD_EP1_FDAT = 0;		// data residue
	_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
	*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0;	// status: passed
}

void processCommand()
{
	U8	i;

	for (i=0; i<31; i++)
		_gCBW[i] = *((volatile U8 *)((U32)&_reg_USBD_EP2_FDAT+3));

	_reg_USBD_EP2_INTR_STAT |= EOT_MASK;		// clear EOT flag
	//printf( "\r\n" );
	//MX1_UART_OutputHex( MX1_UART1, _gCBW[15] );
	//printf( "\r\n" );
	switch(_gCBW[15])
	{
		case 0x12:	// inquiry
			_reg_USBD_EP1_FDAT = 0x00800001;
			_reg_USBD_EP1_FDAT = 0x5B000000;
			// vendor identification (8 bytes)
			_reg_USBD_EP1_FDAT = 0xc6d5ccec;		// "MOTO"
			_reg_USBD_EP1_FDAT = 0xbbdbd1b6;		// "ROLA"
			// product identification (16 bytes)
			_reg_USBD_EP1_FDAT = 0x454D2D41;		// "MX1 "
			_reg_USBD_EP1_FDAT = 0x524D3920;		// "ADS "
			_reg_USBD_EP1_FDAT = 0x332E3220;
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			_reg_USBD_EP1_FDAT = 0x20202020;		// "    "

			// product revision level (4 bytes)
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x30;
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x31;
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x30;
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x30;

			// now the CSW
			_reg_USBD_EP1_FDAT = 0x55534253;		// signature in BIG endian
			for (i=0; i<4; i++)
				*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i];	// CSWtag
			_reg_USBD_EP1_FDAT = 0;		// data residue
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0;	// status: passed
//			SerialOutputString("0x12\n\r");
			break;
		case 0x23://EUARTputString("0x23\n ");	// READ FORMAT CAPACITIES, not supported, return STALL
		case 0x1A://EUARTputString("0x1a\n ");	// MODE SENSE, not supported, return STALL
		case 0x5A:	// MODE SENSE, not supported, return STALL
			_reg_USBD_EP1_STAT |= FORCE_STALL_MASK;
			// now the CSW
			_reg_USBD_EP1_FDAT = 0x55534253;		// signature in BIG endian
			for (i=0; i<8; i++)
				*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i];	// CSWtag
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x01;	// status: failed
//			SerialOutputString("0x5a\n\r");
			break;
		case 0x03:	// REQUEST SENSE, return error
			_reg_USBD_EP1_FDAT = 0x70000500;
			_reg_USBD_EP1_FDAT = 0x0000000C;
			_reg_USBD_EP1_FDAT = 0x00000000;
			_reg_USBD_EP1_FDAT = 0x20000000;
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x00;
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x00;
	
			// now the CSW
			_reg_USBD_EP1_FDAT = 0x55534253;		// signature in BIG endian
			for (i=0; i<4; i++)
				*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i];	// CSWtag
			_reg_USBD_EP1_FDAT = 0;		// data residue
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0;	// status: passed
//			SerialOutputString("0x03\n\r");
			break;
		case 0x25:	// READ CAPACITY
			_reg_USBD_EP1_FDAT = DISK_LAST_SECTOR;		// last sector of disk
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			_reg_USBD_EP1_FDAT = 0x00000200;		// block size
	
			// now the CSW
			_reg_USBD_EP1_FDAT = 0x55534253;		// signature in BIG endian
			for (i=0; i<4; i++)
				*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i];	// CSWtag
			_reg_USBD_EP1_FDAT = 0;		// data residue
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0;	// status: passed
//			SerialOutputString("0x25\n\r");
			break;
		case 0x28:	// READ
			// extract start sector
			_gUsbCurSector = 0;
			for (i=0; i<4; i++)
				_gUsbCurSector = (_gUsbCurSector << 8) | (U32)_gCBW[17+i];
			// extract number of sectors
			_gUsbNumSector = (((U32)_gCBW[22]) << 8) | ((U32)_gCBW[23]);
			_gUsbPacketCount = _gUsbNumSector * 16;
			_gpUsbBufPtr = (unsigned char *)(USB_DISK_START + _gUsbCurSector * 512);
	
			// fill up the 1st packet
			for (i=0; i<31; i++)
		   	*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = *(_gpUsbBufPtr++);
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = *(_gpUsbBufPtr++);

			// read sectors
			readSectors();
//			SerialOutputString("0x28\n\r");
			break;
		case 0x00://EUARTputString("0x00\n ");	// NULL COMMAND, return CSW with pass
		case 0x1E://EUARTputString("0x1e\n ");	// PREVENT-ALLOW MEDIUM REMOVAL, return CSW with pass
		case 0x2F://EUARTputString("0x2f\n ");	// VERIFY
			// now the CSW
			_reg_USBD_EP1_FDAT = 0x55534253;		// signature in BIG endian
			for (i=0; i<4; i++)
				*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i];	// CSWtag
			_reg_USBD_EP1_FDAT = 0;		// data residue
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0;	// status: passed
			break;
		case 0x1B:	// START-STOP UNIT (when host EJECT)
//			printk("\nEJECT from host detected.\n");
			//printf("\n\rEJECT from host detected.\n\r");
			// now the CSW
			_reg_USBD_EP1_FDAT = 0x55534253;		// signature in BIG endian
			for (i=0; i<4; i++)
				*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i];	// CSWtag
			_reg_USBD_EP1_FDAT = 0;		// data residue
			_reg_USBD_EP1_FCTRL |= 0x20000000;	// next is last word in packet
			*((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0;	// status: passed
			quit = 1;
//			SerialOutputString("File transfer completed.\n\r");
			//printf("File transfer completed.\n\r");
			break;
		case 0x2A:	// WRITE
			// extract start sector
			_gUsbCurSector = 0;
			for (i=0; i<4; i++)
				_gUsbCurSector = (_gUsbCurSector << 8) | (U32)_gCBW[17+i];
			// extract number of sectors
			_gUsbNumSector = (((U32)_gCBW[22]) << 8) | ((U32)_gCBW[23]);
/*
			EUARTputData('(');
			EUARTputHex((U8)(_gUsbCurSector>>8));
			EUARTputHex((U8)_gUsbCurSector);
			EUARTputData('/');
			EUARTputHex((U8)_gUsbNumSector);
			EUARTputData(')');
*/
			_gUsbPacketCount = _gUsbNumSector * 16;
			_gpUsbBufPtr = (unsigned char *)(USB_DISK_START + _gUsbCurSector * 512);
			// check last sector
			{
				U32 lastSector = _gUsbCurSector + _gUsbNumSector - 1;
				if (lastSector == DISK_LAST_SECTOR)		// host is formatting disk
					gLastSector = 54;
				else if (lastSector > gLastSector)
					gLastSector = lastSector;
			}
			// write sectors
			writeSectors();
//			SerialOutputString("0x2a\n\r");
			break;
//		default:
//			SerialOutputString("Unknown command : 0x");
//			EUARTputHex(_gCBW[15]);
//			EUARTputString(" !\n");
	}
//	_reg_USBD_EP2_INTR_STAT |= EOT_MASK;		// clear EOT flag

}

// This poll-only driver make use of the last 16M of the SDRAM (i.e. 0x0B000000 - 0x0BFFFFFF) to
// simulate a removable disk. The File Explorer on the Windows 2000 will see this 16M drive and copy
// a single file to it.
// The file will be stored starting from sector 55 and following consecutive sectors.
// The file size is estimated by the number of sectors written.
// There is one trip here: if the Windows 2000 File Explorer format this disk, their will be 2 cases:
// 1. a true format - write every sector of disk
// 2. a quick format - only FAT is written
// For case 1, we reset the variable gLastSector to 54 if sector 0x7FFF is written
// For case 2, we don't have to do anything since FAT is at sectors < 55.

#define	SerialOutputString( str )		printf( (str) )
U32 usbrx( void )
{

   	USB_DISK_START=USBDISK_RAM_BASE;
	DISK_LAST_SECTOR=USBDISK_RAM_LEN/512;


	gLastSector = 54;		// to make the return value 0, if no file is downloaded
	formatDrive();
//	SerialOutputString("USB drive end format disk.\n\r");
	initUSB();
	SerialOutputString("USB drive ready for transfer.\n\r");
	SerialOutputString("step1: Connect usb line to your PC side, and in PC explore,\r\n       you will see a removable disk,\r\n       and then Copy file image under it.\n\rstep2. Eject the removable disk in PC explore\r\n");
	quit = 0;
	while (!quit)
	{
		// we need to clear USBD CFG_CHG interrupt flag, or else the module won't work after a
		// CFG_CHG setup packet is received
		_reg_USBD_INTR_STAT = 1;

		// handle DEVREQ to EP0
		if (_reg_USBD_EP0_INTR_STAT & DEVREQ_MASK)
		{
//			SerialOutputString("DEVREQ detected.\n\r");
			handleDevReq();
		}

		// handle COMMAND send to EP2
		if (_reg_USBD_EP2_INTR_STAT & EOT_MASK)
		{
//			SerialOutputString("EP2 EOT detected.\n\r");
			processCommand();
		}

		// since there is a bug in the current silicon that the CMD_OVER is mistakenly cleared
		// by control transfer of other addresses, so we'll set CMD_OVER bit repeatedly as
		// a work-around
		_reg_USBD_CTRL |= CMD_OVER_MASK;    // signal CMD_OVER

	}

	return ((gLastSector - 54) * 512);
}

⌨️ 快捷键说明

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