博文
IC设计过程 (2006-12-24 16:13:00)
| IC设计过程 | ||
| □ | ||
| ||
阅读全文(1071) | 评论:0 | 复制链接
EDA流程和软件(2006-12-24 16:09:00)

集成的PLD/FPGA开发环境
这类软件都是由PLD/FPGA芯片厂家提供,基本都可以完成所有的设计输入(原理图或HDL),仿真,综合,布线,下载等工作。
![]() |
Altera公司上一代的PLD开发软件,使用者众多。目前Altera已经停止开发MaxplusII,而转向QuartusII软件平台 | MaxplusII学习资料下载 |
| Altera公司的免费PLD开发软件,界面与标准版的MaxplusII完全一样,但需要通过使用MAX+PLUSII Advanced Synthsis插件才能支持VHDL/Verilog。 该支持MAX7000/3000和部分FLEX/ACEX芯片(如1K30,6016等),共47.1M | 用网卡号申请license 如没有网卡,可以用硬盘号申请,license会发到你的电子信箱,有效期为6个月,到期后可再申请 | |
| Altera公司的免费PLD开发软件,界面与标准版的MaxplusII完全一样,只支持MAX7000和MAX3000系列器件,本身支持不复杂的VHDL和Verilog综合,软件较小,共26.8M | 用网卡号申请license ,如没有网卡,可以用硬盘号申请,其他同上 | |
![]() |
Altera公司新一代PLD开发软件,适合大规模FPGA的开发 | QuartusII学习资料下载 |
| Altera公司的meifeui PLD开发软件QuartusII的免费版本,推荐使用256M以上内存,安装有NT或win2000的机器 | 用网卡号申请license license有效期为150天,到期后可再申请 | |
![]() |
Xilinx公司上一代的PLD开发软件,目前Xilinx已经停止开发Foundation,而转向ISE软件平台 | Foundation学习资料下载 |
![]() |
Xilinx公司目前的FPGA/PLD开发软件 | ISE4.1中文学习资料 |
| Xilinx公司的免费PLD开发软件,不需下载,可在线编译,结果用e-mail发送到信箱。使用简单,但要求较快的联网速度。支持XC9500 和 CoolRunner系列 | 不需要安装license,但必须注册,申请用户和password | |
| Xilinx公司的免费PLD开发软件,支持XC9500,coolrunner,Spartan/II,部分Virtex/E/II器件 | ||
|
ispDesignEXPERT |
Lattice公司的PLD开发软件,目前最新软件改名为:ispLEVER | |
| Lattice公司的免费PLD开发软件,支持600个宏单元以下的Lattice芯片的设计 | 需要注册 license有效期为6个月,到期后可再申请 | |
|
Wrap |
Cypress公司开发软件 | |
| ACTEL公司开发软件 | ||
| Quicklogic公司开发软件 | ||
| 开发GAL/PAL的软件,DOS界面 | 免费 | |
| 开发GAL/PAL的软件,DOS界面 | 免费 |
为了提高设计效率,优化设计结果,很多厂家提供了各种专业软件,用以配合PLD/FPGA芯片厂家提供工具进行更高效率的设计,最常见的组合是:同时使用专业HDL逻辑综合软件和PLD/FPGA芯片厂家提供的软件。
HDL前端输入与系统管理软件
这类软件主要是帮助用户完成HDL文本的编辑和输入工作,提高输入效率,并不是必须的,更多人更习惯使用集成开发软件或者综合/仿真工具中自带的文本编辑器,甚至可以直接使用普通文本编辑器。
|
UltraEdit |
一个使用广泛的编辑器,低版本并不直接支持HDL,但可以将下面的文件中的文字添加到WORDFILE.txt中(该文件在UltraEdit安装目录下),即可支持相应的语言编辑,关键字将用不同色彩标出。VHDL87 VHDL93 Verilog HDL |
|
HDL Turbo Writer |
VHDL/verilog专用编辑器,可大小写自动转换,缩进,折叠,格式编排很方便。可直接使用FPGAadvantage做后端处理,此套软件也可以编辑C/C++,Java等多重语言,www.saros.com |
|
HDL Designer Series |
Mentor公司的前端设计软件,包括5个部分,涉及设计管理,分析,输入等,原Renoir软件也已转到HDL Designer Series www.mentor.com/hdldesigner |
|
Visial VHDL/ Visal Verilog |
可视化的HDL/Verilog编辑工具,可以通过画流程图等可视化方法生成一部分VHDL/Verilog代码innoveda公司出品 |
|
Visual Elite |
Visial HDL的下一代产品,能够辅助系统级到电路级的设计 www.innoveda.com/products/datasheets_HTML/visualelite.asp |
HDL逻辑综合软件
这类软件将把HDL语言翻译成最基本的与或非门的连接关系(网表),输出edf文件,导给PLD/FPGA厂家的软件进行试配和布线。 为了优化结果,在进行复杂HDL设计时,基本上都会使用这些专业的逻辑综合软件,而不使用PLD/FPGA厂家的集成开发软件中自带的逻辑综合功能。
![]() |
Synplify / Synplify Pro, VHDL/Verilog综合软件,口碑相当不错。Synplicity公司出品。下载试用版 |
Synplify学习资料 |
|
|
LeonardoSpectrum,VHDL/VerilogHDL综合软件。(Mentor公司)下载试用版 |
|
| Mentor公司最新的VHDL/VerilogHDL综合软件 | ||
![]() |
FPGA ComplierII,VHDL/Verilog综合软件,Synopsys公司已停止发展FPGAexpress软件,而转到FPGA ComplierII平台。 | FPGAexpress学习资料 |
| MAX+PLUS II Advanced Synthsis | ALtera的一个免费HDL综合工具,安装后可以直接使用,是MaxplusII的一个插件,用这个插件进行语言综合,比直接使用MaxplusII综合的效果好。 下载(15M) |
HDL仿真软件
对设计进行校验仿真,包括布线以前的功能仿真(前仿真)和布线以后包含延时的时序仿真(后仿真),对于一些复杂的HDL设计可能需要这些软件专业的仿真功能。
|
ModleSim |
VHDL/VerilogHDL仿真软件,功能比ActiveHDL强大,使用比ActiveHDL复杂。Mentor的子公司Model Tech出品。更多信息可浏览:http://www.model.com ,下载试用板 |
Modelsim学习资料(中文) |
|
Active HDL |
Active HDL 6.1 使用简介 | |
|
|
Cadence公司出品,很好的Verilog/VHDL仿真工具,其中NC-Verilog 的前身是著名的Verilog仿真软件:Verilog-XL,用于Verilog仿真;NC-VHDL,用于VHDL仿真;NC-Sim,是Verilog/VHDL混合语言仿真工具 |
|
|
NC-Verlog/NC-VHDL/NC-SIM | ||
![]() |
||
|
VCS / Scirocco |
其他相关软件
| Mentor公司出品,VHDL/Verilog完整开发系统,可以完成除了布线以外所有的工作,包括三套软件:HDL Designer Series(输入及项目管理),Leonardo.Spectrum(综合)和Modelsim(仿真)下载试用版 | ||
| VHDL/Verilog专用调试和代码优化软件,多用于复杂设计的调试,如CPU设计 www.novas.com | Debussy学习资料(5.27M) | |
|
Visual IP |
可以为IP core供源代码保护和用户仿真模型 | |
| 可实现VHDL和Verilog语言的相互自动转化 | ||
| 静态时序分析软件,Synopsys公司出品,多用于ASIC设计,也可以用于FPGA/PLD设计 | ||
| ISE与与Mathlab的接口,利用IP核在Mathlab中快速完成数字信号处理的仿真和最终FPGA实现 | ||
| QuartusII与Mathlab的接口,利用IP核在Mathlab中快速完成数字信号处理的仿真和最终FPGA实现 | ||
| 配合QuartusII,可以完成NiosII软CPU的开发工作 | NiosII快速入门 | |
| Synplicity公司出品,物理级综合工具 | ||
| Synplicity公司最新推出的一种验证工具,可以在FPGA工作时查看实际的节点信号,甚至可以像调试单片机一样,在HDL代码中设断点 | ||
|
Synplify DSP |
和DSP Builder ,System Generator 类似,用于数字信号处理的开发 | |
| 一个很好用的HDL设计工具,能够自动将子模块聚合成一个顶层文件。 免费共享软件 |
||
阅读全文(1725) | 评论:4 | 复制链接
北京大学微电子系的课程安排表 (2006-12-24 16:05:00)
| 北京大学微电子系的课程安排表 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
阅读全文(1270) | 评论:0 | 复制链接
25位最具影响力的IC人物 (2006-12-24 16:00:00)
| 25位最具影响力的IC人物 | ||
| ||
阅读全文(1247) | 评论:0 | 复制链接
关于四金计算和工资对照表(2006-12-24 15:58:00)
| 关于四金计算和工资对照表 | ||
| ||
国家集成电路设计企业一览表 (2006-12-24 15:49:00)
| 国家集成电路设计企业一览表 | |||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||
全国IC设计企业名单(2006-12-24 15:48:00)
| 全国IC设计企业名单(转) | ||
| ||
阅读全文(1039) | 评论:0 | 复制链接
硬件工程师面试试题(2006-12-24 15:47:00)
|
模拟电路 |
阅读全文(1034) | 评论:0 | 复制链接
usbhw.c(2006-11-24 23:04:00)
/*---------------------------------------------------------------------------- * U S B - K e r n e l *---------------------------------------------------------------------------- * Name: usbhw.c * Purpose: USB Hardware layer module file for Philips LPC214x Family * Microprocessors * Version: V1.04 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce and * distribute executable files created using this software for use on * Philips LPC2xxx microcontroller devices only. Nothing else gives you the * right to use this software. * * Copyright (c) 2005 Keil Software. * Modified by Philips Semiconductor *---------------------------------------------------------------------------*/ #include <LPC214x.h> /* LPC214x definitions */ #include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbreg.h" #include "usbhw.h" #include "usbcore.h" #include "vcomuser.h" /* * Get Endpoint Address * Parameters: EPNum: Endpoint Number * EPNum.0..3: Address * EPNum.7: Dir * Return Value: Endpoint Physical Address */ DWORD EPAdr (DWORD EPNum) { DWORD val; val = (EPNum & 0x0F) << 1; if (EPNum & 0x80) { val += 1; } return (val); } /* * Write Command * Parameters: cmd: Command * Return Value: None */ void WrCmd (DWORD cmd) { CMD_CODE = cmd; while ((DEV_INT_STAT & CCEMTY_INT) == 0); DEV_INT_CLR = CCEMTY_INT; } /* * Write Command Data * Parameters: cmd: Command * val: Data * Return Value: None */ void WrCmdDat (DWORD cmd, DWORD val) { CMD_CODE = cmd; while ((DEV_INT_STAT & CCEMTY_INT) == 0); DEV_INT_CLR = CCEMTY_INT; CMD_CODE = val; while ((DEV_INT_STAT & CCEMTY_INT) == 0); DEV_INT_CLR = CCEMTY_INT; } /* * Read Command Data * Parameters: cmd: Command * Return Value: Data Value */ DWORD RdCmdDat (DWORD cmd) { DWORD val; DEV_INT_CLR = CDFULL_INT; CMD_CODE = cmd; while ((DEV_INT_STAT & CCEMTY_INT) == 0); DEV_INT_CLR = CCEMTY_INT; while ((DEV_INT_STAT & CDFULL_INT) == 0); val = CMD_DATA; DEV_INT_CLR = CDFULL_INT; return (val); } /* * USB Initialize Function * Return Value: None */ void USB_Init (void) { PCONP |= 0x80000000; /* Turn On USB PCLK */ // Configure 48MHz USB Clock; FOsc = 12MHz, M = 4, P = 2 PLL48CFG = 0x23; /* M = 4, P = 2 */ PLL48CON = PLLCON_PLLE; /* PLL Enable */ PLL48FEED = 0xAA; /* Feed Sequence 1 */ PLL48FEED = 0x55; /* Feed Sequence 2 */ while ((PLL48STAT & PLLSTAT_PLOCK) == 0); /* Wait for PLL Lock */ PLL48CON = PLLCON_PLLE | PLLCON_PLLC; /* PLL Enable & Connect */ PLL48FEED = 0xAA; /* Feed Sequence 1 */ PLL48FEED = 0x55; /* Feed Sequence 2 */ VICVectAddr0 = (unsigned long)USB_ISR; /* USB Interrupt -> Vector 0 */ VICVectCntl0 = 0x20 | 22; /* USB Interrupt -> IRQ Slot 0 */ VICIntEnable = 1 << 22; /* Enable USB Interrupt */ DEV_INT_EN = DEV_STAT_INT; /* Enable Device Status Interrupt */ #if 1 /* Partial Manual Reset */ USB_Reset(); USB_SetAddress(0); #endif } /* * USB Connect Function * Parameters: con: Connect/Disconnect * Return Value: None */ void USB_Connect (BOOL con) { WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con ? DEV_CON : 0)); } /* * USB Reset Function * Return Value: None */ void USB_Reset (void) { EP_INDEX = 0; MAXPACKET_SIZE = USB_MAX_PACKET0; EP_INDEX = 1; MAXPACKET_SIZE = USB_MAX_PACKET0; while ((DEV_INT_STAT & EP_RLZED_INT) == 0); EP_INT_CLR = 0xFFFFFFFF; EP_INT_EN = 0xFFFFFFFF; DEV_INT_CLR = 0xFFFFFFFF; DEV_INT_EN = DEV_STAT_INT | EP_SLOW_INT | (USB_SOF_EVENT ? FRAME_INT : 0) | (USB_ERROR_EVENT ? ERR_INT : 0); } /* * USB Suspend Function * Return Value: None */ void USB_Suspend (void) { // Performed by Hardware } /* * USB Resume Function * Return Value: None */ void USB_Resume (void) { // Performed by Hardware } /* * USB Remote Wakeup Function * Return Value: None */ void USB_WakeUp (void) { if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) { WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON)); } } /* * USB Remote Wakeup Configuration Function * Parameters: cfg: Enable/Disable * Return Value: None */ void USB_WakeUpCfg (BOOL cfg) { cfg; // Not needed } /* * USB Set Address Function * Parameters: adr: USB Address * Return Value: None */ void USB_SetAddress (BYTE adr) { WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Don't wait for next */ WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Setup Status Phase */ } /* * USB Configure Function * Parameters: cfg: Configure/Deconfigure * Return Value: None */ void USB_Configure (BOOL cfg) { WrCmdDat(CMD_CFG_DEV, DAT_WR_BYTE(cfg ? CONF_DVICE : 0)); REALIZE_EP = 0x00000003; while ((DEV_INT_STAT & EP_RLZED_INT) == 0); DEV_INT_CLR = EP_RLZED_INT; } /* * Configure USB Endpoint * Parameters: pEPD: Pointer to Endpoint Descriptor * Return Value: None */ void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD) { DWORD num; num = EPAdr(pEPD->bEndpointAddress); REALIZE_EP |= (1 << num); EP_INDEX = num; MAXPACKET_SIZE = pEPD->wMaxPacketSize; while ((DEV_INT_STAT & EP_RLZED_INT) == 0); DEV_INT_CLR = EP_RLZED_INT; } /* * Set Direction for USB Control Endpoint * Parameters: dir: Out (dir == 0), In (dir <> 0) * Return Value: None */ void USB_DirCtrlEP (BYTE dir) { dir; // Not needed } /* * Enable USB Endpoint * Parameters: EPNum: Endpoint Number * EPNum.0..3: Address * EPNum.7: Dir * Return Value: None */ void USB_EnableEP (BYTE EPNum) { WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); } /* * Disable USB Endpoint * Parameters: EPNum: Endpoint Number * EPNum.0..3: Address * EPNum.7: Dir * Return Value: None */ void USB_DisableEP (BYTE EPNum) { WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_DA)); } /* * Reset USB Endpoint * Parameters: EPNum: Endpoint Number * EPNum.0..3: Address * EPNum.7: Dir * Return Value: None */ void USB_ResetEP (BYTE EPNum) { WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); } /* * Set Stall for USB Endpoint * Parameters: EPNum: Endpoint Number * EPNum.0..3: Address * EPNum.7: Dir * Return Value: None */ void USB_SetStallEP (BYTE EPNum) { WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_ST)); } /* * Clear Stall for USB Endpoint * Parameters: EPNum: Endpoint Number * EPNum.0..3: Address * EPNum.7: Dir * Return Value: None */ void USB_ClrStallEP (BYTE EPNum) { WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); } /* * Read USB Endpoint Data * Parameters: EPNum: Endpoint Number * EPNum.0..3: Address * EPNum.7: Dir * pData: Pointer to Data Buffer * Return Value: Number of bytes read */ DWORD USB_ReadEP (BYTE EPNum, BYTE *pData) { DWORD cnt, n; USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_RD_EN; do { cnt = RX_PLENGTH; } while ((cnt & PKT_RDY) == 0); cnt &= PKT_LNGTH_MASK; for (n = 0; n < (cnt + 3) / 4; n++) { *((__packed DWORD *)pData) = RX_DATA; pData += 4; } USB_CTRL = 0; WrCmd(CMD_SEL_EP(EPAdr(EPNum))); WrCmd(CMD_CLR_BUF); return (cnt); } /* * Write USB Endpoint Data * Parameters: EPNum: Endpoint Number * EPNum.0..3: Address * EPNum.7: Dir * pData: Pointer to Data Buffer * cnt: Number of bytes to write * Return Value: Number of bytes written */ DWORD USB_WriteEP (BYTE EPNum, BYTE *pData, DWORD cnt) { DWORD n; USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_WR_EN; TX_PLENGTH = cnt; for (n = 0; n < (cnt + 3) / 4; n++) { TX_DATA = *((__packed DWORD *)pData); pData += 4; } USB_CTRL = 0; WrCmd(CMD_SEL_EP(EPAdr(EPNum))); WrCmd(CMD_VALID_BUF); return (cnt); } /* * USB Interrupt Service Routine */ void USB_ISR (void) __irq { DWORD disr, eisr, val, n, m; disr = DEV_INT_STAT; /* Device Interrupt Status */ // Device Status Interrupt (Reset, Suspend/Resume, Connect change) if (disr & DEV_STAT_INT) { WrCmd(CMD_GET_DEV_STAT); val = RdCmdDat(DAT_GET_DEV_STAT); /* Device Status */ if (val & DEV_RST) { /* Reset */ USB_Reset(); #if USB_RESET_EVENT USB_Reset_Event(); #endif goto isr_end; } if (val & DEV_SUS_CH) { /* Suspend/Resume */ if (val & DEV_SUS) { /* Suspend */ USB_Suspend(); #if USB_SUSPEND_EVENT USB_Suspend_Event(); #endif } else { /* Resume */ USB_Resume(); #if USB_RESUME_EVENT USB_Resume_Event(); #endif } goto isr_end; } if (val & DEV_CON_CH) { /* Connect change */ #if USB_POWER_EVENT USB_Power_Event(val & DEV_CON); #endif goto isr_end; } } #if USB_SOF_EVENT // Start of Frame Interrupt if (disr & FRAME_INT) { WrCmd(CMD_RD_FRAME); val = RdCmdDat(DAT_RD_FRAME); val = val | (RdCmdDat(DAT_RD_FRAME) << 8); USB_SOF_Event(val); } #endif #if USB_ERROR_EVENT // Error Interrupt if (disr & ERR_INT) { WrCmd(CMD_RD_ERR_STAT); val = RdCmdDat(DAT_RD_ERR_STAT); if (val & 0x01) { val = USB_ERR_PID; } else if (val & 0x02) { val = 0x100; // Unexpected Error } else if (val & 0x04) { val = USB_ERR_CRC; } else if (val & 0x08) { val = USB_ERR_TIMEOUT; } else if (val & 0x10) { val = USB_ERR_EOP; } else if (val & 0x20) { val = 0x101; // Buffer Overrun } else if (val & 0x40) { val = USB_ERR_BIT_STUFF; } else if (val & 0x80) { val = USB_ERR_DATA_TOGGLE; } USB_Error_Event(val); } #endif // Ednpoint's Slow Interrupt if (disr & EP_SLOW_INT) { while ( eisr = EP_INT_STAT ) { /* Endpoint Interrupt Status */ // Check All Endpoints for (n = 0; n < USB_EP_NUM; n++) { if (eisr & (1 << n)) { m = n >> 1; EP_INT_CLR = 1 << n; while ((DEV_INT_STAT & CDFULL_INT) == 0); val = CMD_DATA; DEV_INT_CLR = CDFULL_INT; if ((n & 1) == 0) { // OUT Endpoint if (n == 0) { /* Control OUT Endpoint */ if (val & EP_SEL_STP) { /* Setup Packet */ if (USB_P_EP[0]) { USB_P_EP[0](USB_EVT_SETUP); continue; } } } if (USB_P_EP[m]) { USB_P_EP[m](USB_EVT_OUT); } } else { // IN Endpoint if (USB_P_EP[m]) { USB_P_EP[m](USB_EVT_IN); } } } } } } isr_end: DEV_INT_CLR = disr; VICVectAddr = 0; /* Acknowledge Interrupt */ }
阅读全文(1234) | 评论:0 | 复制链接
usbcore.c(2006-11-24 23:00:00)
/*---------------------------------------------------------------------------- * U S B - K e r n e l *---------------------------------------------------------------------------- * Name: usbcore.c * Purpose: USB Core Module file for Philips LPC214x Family * Microprocessors * Version: V1.04 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce and * distribute executable files created using this software for use on * Philips LPC2xxx microcontroller devices only. Nothing else gives you the * right to use this software. * * Copyright (c) 2005 Keil Software. * Modified by Philips Semiconductor *---------------------------------------------------------------------------*/ #include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbhw.h" #include "usbcore.h" #include "usbdesc.h" #include "vcomuser.h" WORD USB_DeviceStatus; BYTE USB_DeviceAddress; BYTE USB_Configuration; DWORD USB_EndPointMask; DWORD USB_EndPointHalt; BYTE USB_NumInterfaces; BYTE USB_AltSetting[USB_IF_NUM]; BYTE EP0Buf[USB_MAX_PACKET0]; USB_EP_DATA EP0Data; USB_SETUP_PACKET SetupPacket; /* * Reset USB Core * Parameters: None * Return Value: None */ void USB_ResetCore (void) { USB_DeviceStatus = USB_POWER; USB_DeviceAddress = 0; USB_Configuration = 0; USB_EndPointMask = 0x00010001; USB_EndPointHalt = 0x00000000; } /* * USB Request - Setup Stage * (global SetupPacket) * Parameters: None * Return Value: None */ void USB_SetupStage (void) { USB_ReadEP(0x00, (BYTE *)&SetupPacket); } /* * USB Request - Data In Stage * Parameters: None (global EP0Data) * Return Value: None */ void USB_DataInStage (void) { DWORD cnt; if (EP0Data.Count > USB_MAX_PACKET0) { cnt = USB_MAX_PACKET0; } else { cnt = EP0Data.Count; } cnt = USB_WriteEP(0x80, EP0Data.pData, cnt); EP0Data.pData += cnt; EP0Data.Count -= cnt; } /* * USB Request - Data Out Stage * Parameters: None (global EP0Data) * Return Value: None */ void USB_DataOutStage (void) { DWORD cnt; cnt = USB_ReadEP(0x00, EP0Data.pData); EP0Data.pData += cnt; EP0Data.Count -= cnt; } /* * USB Request - Status In Stage * Parameters: None * Return Value: None */ void USB_StatusInStage (void) { USB_WriteEP(0x80, NULL, 0); } /* * USB Request - Status Out Stage * Parameters: None * Return Value: None */ void USB_StatusOutStage (void) { USB_ReadEP(0x00, EP0Buf); } /* * Get Status USB Request * Parameters: None (global SetupPacket) * Return Value: TRUE - Success, FALSE - Error */ __inline BOOL USB_GetStatus (void) { DWORD n, m; switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_DEVICE: EP0Data.pData = (BYTE *)&USB_DeviceStatus; USB_DataInStage(); break; case REQUEST_TO_INTERFACE: if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) { *((WORD *)EP0Buf) = 0; EP0Data.pData = EP0Buf; USB_DataInStage(); } else { return (FALSE); } break; case REQUEST_TO_ENDPOINT: n = SetupPacket.wIndex.WB.L & 0x8F; m = (n & 0x80) ? ((1 << 16) << n) : (1 << n); if (((USB_Configuration != 0) || ((n & 0x0F) == 0)) && (USB_EndPointMask & m)) { *((WORD *)EP0Buf) = (USB_EndPointHalt & m) ? 1 : 0; EP0Data.pData = EP0Buf; USB_DataInStage(); } else { return (FALSE); } break; default: return (FALSE); } return (TRUE); } /* * Set/Clear Feature USB Request * Parameters: sc: 0 - Clear, 1 - Set * None (global SetupPacket) * Return Value: TRUE - Success, FALSE - Error */ __inline BOOL USB_SetClrFeature (DWORD sc) { DWORD n, m; switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_DEVICE: if (SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP) { if (sc) { USB_WakeUpCfg(1); USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP; } else { USB_WakeUpCfg(0); USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP; } } else { return (FALSE); } break; case REQUEST_TO_INTERFACE: return (FALSE); case REQUEST_TO_ENDPOINT: n = SetupPacket.wIndex.WB.L & 0x8F; m = (n & 0x80) ? ((1 << 16) << n) : (1 << n); if ((USB_Configuration != 0) && ((n & 0x0F) != 0) && (USB_EndPointMask & m)) { if (SetupPacket.wValue.W == USB_FEATURE_ENDPOINT_STALL) { if (sc) { USB_SetStallEP(n); USB_EndPointHalt |= m; } else { USB_ClrStallEP(n); USB_EndPointHalt &= ~m; } } else { return (FALSE); } } else { return (FALSE); } break; default: return (FALSE); } return (TRUE); } /* * Get Descriptor USB Request * Parameters: None (global SetupPacket) * Return Value: TRUE - Success, FALSE - Error */ __inline BOOL USB_GetDescriptor (void) { BYTE *pD; DWORD len, n; switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_DEVICE: switch (SetupPacket.wValue.WB.H) { case USB_DEVICE_DESCRIPTOR_TYPE: // EP0Data.pData = (BYTE *)USB_DeviceDescriptor; len = USB_DEVICE_DESC_SIZE; break; case USB_CONFIGURATION_DESCRIPTOR_TYPE: // pD = (BYTE *)USB_ConfigDescriptor; for (n = 0; n != SetupPacket.wValue.WB.L; n++) { if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength != 0) { pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; } } if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength == 0) { return (FALSE); } EP0Data.pData = pD; len = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; break; case USB_STRING_DESCRIPTOR_TYPE: EP0Data.pData = (BYTE *)USB_StringDescriptor + SetupPacket.wValue.WB.L; len = ((USB_STRING_DESCRIPTOR *)EP0Data.pData)->bLength; break; default: return (FALSE); } break; case REQUEST_TO_INTERFACE: switch (SetupPacket.wValue.WB.H) { default: return (FALSE); } break; default: return (FALSE); } if (EP0Data.Count > len) { EP0Data.Count = len; } USB_DataInStage(); return (TRUE); } /* * Set Configuration USB Request * Parameters: None (global SetupPacket) * Return Value: TRUE - Success, FALSE - Error */ __inline BOOL USB_SetConfiguration (void) { USB_COMMON_DESCRIPTOR *pD; DWORD alt, n, m; if (SetupPacket.wValue.WB.L) { pD = (USB_COMMON_DESCRIPTOR *)USB_ConfigDescriptor; while (pD->bLength) { switch (pD->bDescriptorType) { case USB_CONFIGURATION_DESCRIPTOR_TYPE: if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue == SetupPacket.wValue.WB.L) { USB_Configuration = SetupPacket.wValue.WB.L; USB_NumInterfaces = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bNumInterfaces; for (n = 0; n < USB_IF_NUM; n++) { USB_AltSetting[n] = 0; } for (n = 1; n < 16; n++) { if (USB_EndPointMask & (1 << n)) { USB_DisableEP(n); } if (USB_EndPointMask & ((1 << 16) << n)) { USB_DisableEP(n | 0x80); } } USB_EndPointMask = 0x00010001; USB_EndPointHalt = 0x00000000; USB_Configure(TRUE); if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bmAttributes & USB_CONFIG_SELF_POWERED) { USB_DeviceStatus |= USB_GETSTATUS_SELF_POWERED; } else { USB_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED; } } else { (BYTE *)pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; continue; } break; case USB_INTERFACE_DESCRIPTOR_TYPE: alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting; break; case USB_ENDPOINT_DESCRIPTOR_TYPE: if (alt == 0) { n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F; m = (n & 0x80) ? ((1 << 16) << n) : (1 << n); USB_EndPointMask |= m; USB_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD); USB_EnableEP(n); USB_ResetEP(n); } break; } (BYTE *)pD += pD->bLength; } } else { USB_Configuration = 0; for (n = 1; n < 16; n++) { if (USB_EndPointMask & (1 << n)) { USB_DisableEP(n); } if (USB_EndPointMask & ((1 << 16) << n)) { USB_DisableEP(n | 0x80); } } USB_EndPointMask = 0x00010001; USB_EndPointHalt = 0x00000000; USB_Configure(FALSE); //??>-->usbhw.c } if (USB_Configuration == SetupPacket.wValue.WB.L) { return (TRUE); } else { return (FALSE); } } /* * Set Interface USB Request * Parameters: None (global SetupPacket) * Return Value: TRUE - Success, FALSE - Error */ __inline BOOL USB_SetInterface (void) { USB_COMMON_DESCRIPTOR *pD; DWORD ifn, alt, old, msk, n, m; BOOL set; if (USB_Configuration == 0) return (FALSE); set = FALSE; pD = (USB_COMMON_DESCRIPTOR *)USB_ConfigDescriptor; while (pD->bLength) { switch (pD->bDescriptorType) { case USB_CONFIGURATION_DESCRIPTOR_TYPE: if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue != USB_Configuration) { (BYTE *)pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; continue; } break; case USB_INTERFACE_DESCRIPTOR_TYPE: ifn = ((USB_INTERFACE_DESCRIPTOR *)pD)->bInterfaceNumber; alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting; msk = 0; if ((ifn == SetupPacket.wIndex.WB.L) && (alt == SetupPacket.wValue.WB.L)) { set = TRUE; old = USB_AltSetting[ifn]; USB_AltSetting[ifn] = (BYTE)alt; } break; case USB_ENDPOINT_DESCRIPTOR_TYPE: if (ifn == SetupPacket.wIndex.WB.L) { n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F; m = (n & 0x80) ? ((1 << 16) << n) : (1 << n); if (alt == SetupPacket.wValue.WB.L) { USB_EndPointMask |= m; USB_EndPointHalt &= ~m; USB_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD); USB_EnableEP(n); USB_ResetEP(n); msk |= m; } else if ((alt == old) && ((msk & m) == 0)) { USB_EndPointMask &= ~m; USB_EndPointHalt &= ~m; USB_DisableEP(n); } } break; } (BYTE *)pD += pD->bLength; } return (set); } /* * USB Endpoint 0 Event Callback * Parameter: event */ void USB_EndPoint0 (DWORD event) { BYTE UARTSettingCmd, UARTSettingData; switch (event) { case USB_EVT_SETUP: USB_SetupStage(); USB_DirCtrlEP(SetupPacket.bmRequestType.BM.Dir); EP0Data.Count = SetupPacket.wLength; switch (SetupPacket.bmRequestType.BM.Type) { case REQUEST_STANDARD: switch (SetupPacket.bRequest) { case USB_REQUEST_GET_STATUS: if (!USB_GetStatus()) { goto stall_i; } break; case USB_REQUEST_CLEAR_FEATURE: if (!USB_SetClrFeature(0)) { goto stall_i; } USB_StatusInStage(); #if USB_FEATURE_EVENT USB_Feature_Event(); #endif break; case USB_REQUEST_SET_FEATURE: if (!USB_SetClrFeature(1)) { goto stall_i; } USB_StatusInStage(); #if USB_FEATURE_EVENT USB_Feature_Event(); #endif break; case USB_REQUEST_SET_ADDRESS: switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_DEVICE: USB_DeviceAddress = 0x80 | SetupPacket.wValue.WB.L; USB_StatusInStage(); break; default: goto stall_i; } break; case USB_REQUEST_GET_DESCRIPTOR: if (!USB_GetDescriptor()) { goto stall_i; } break; case USB_REQUEST_SET_DESCRIPTOR: /*stall_o:*/ USB_SetStallEP(0x00); EP0Data.Count = 0; break; case USB_REQUEST_GET_CONFIGURATION: switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_DEVICE: EP0Data.pData = &USB_Configuration; USB_DataInStage(); break; default: goto stall_i; } break; case USB_REQUEST_SET_CONFIGURATION: switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_DEVICE: if (!USB_SetConfiguration()) { goto stall_i; } USB_StatusInStage(); #if USB_CONFIGURE_EVENT USB_Configure_Event(); #endif break; default: goto stall_i; } break; case USB_REQUEST_GET_INTERFACE: switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_INTERFACE: if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) { EP0Data.pData = USB_AltSetting + SetupPacket.wIndex.WB.L; USB_DataInStage(); } else { goto stall_i; } break; default: goto stall_i; } break; case USB_REQUEST_SET_INTERFACE: switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_INTERFACE: if (!USB_SetInterface()) { goto stall_i; } USB_StatusInStage(); #if USB_INTERFACE_EVENT USB_Interface_Event(); #endif break; default: goto stall_i; } break; default: goto stall_i; } break; case REQUEST_CLASS: #if USB_CLASS switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_INTERFACE: // break; default: goto stall_i; } #else goto stall_i; #endif /* USB_CLASS */ case REQUEST_VENDOR: #if USB_VCOM UARTSettingCmd = SetupPacket.bRequest & 0xFF; UARTSettingData = SetupPacket.wValue.WB.L; if (!VCOM_SetSIOSetup( UARTSettingCmd, UARTSettingData )) { goto stall_i; } USB_DataInStage(); #endif break; default: stall_i: USB_SetStallEP(0x80); EP0Data.Count = 0; break; } break; case USB_EVT_OUT: if (SetupPacket.bmRequestType.BM.Dir == 0) { if (EP0Data.Count) { USB_DataOutStage(); if (EP0Data.Count == 0) { switch (*((WORD *)&SetupPacket)) { default: goto stall_i; } USB_StatusInStage(); } } } else { USB_StatusOutStage(); } break; case USB_EVT_IN: if (SetupPacket.bmRequestType.BM.Dir == 1) { if (EP0Data.Count) { USB_DataInStage(); } } else { if (USB_DeviceAddress & 0x80) { USB_DeviceAddress &= 0x7F; USB_SetAddress(USB_DeviceAddress); } } break; case USB_EVT_IN_STALL: USB_ClrStallEP(0x80); break; case USB_EVT_OUT_STALL: USB_ClrStallEP(0x00); break; } }
阅读全文(1507) | 评论:0 | 复制链接













最新评论