📄 usbrx.c
字号:
void handleDevReq(){ 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 switch(_gCBW[15]) { case 0x12: // inquiry _reg_USBD_EP1_FDAT = 0x00800001; _reg_USBD_EP1_FDAT = 0x5B000000; // vendor identification (8 bytes) _reg_USBD_EP1_FDAT = 0x4D4F544F; // "MOTO" _reg_USBD_EP1_FDAT = 0x524F4C41; // "ROLA" // product identification (16 bytes) _reg_USBD_EP1_FDAT = 0x4D583120; // "MX1 " _reg_USBD_EP1_FDAT = 0x41445320; // "ADS " _reg_USBD_EP1_FDAT = 0x302E3120; // "0.1 " _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// EUARTputString("0x12\n "); 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 //EUARTputString("0x5a\n "); 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 //EUARTputString("0x03\n "); 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 //EUARTputString("0x25\n "); 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(); //EUARTputString("0x28\n "); 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"); // 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; //EUARTputString("\nFile transfer completed.\n"); 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(); //EUARTputString("0x2a\n "); break; default: EUARTputString("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.U32 usbrx(){ gLastSector = 54; // to make the return value 0, if no file is downloaded formatDrive(); initUSB(); EUARTputString("USB drive ready for transfer.\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) { //EUARTputString("DEVREQ detected.\n"); handleDevReq(); } // handle COMMAND send to EP2 if (_reg_USBD_EP2_INTR_STAT & EOT_MASK) { //EUARTputString("EP2 EOT detected.\n"); 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 + -