州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w PDIUSBD12固件编程指南 介绍 PDIUSBDI2是一款带有并行总线和局部DMA传输能力的高速USB接口器件。固件设计的目标就是 使 PDIUSBD12在USB上达到最大的传输速率。外围设备例如打印机、扫描仪、外部的海量存储器和数码 相机都可使用 PDIUSBD2在USB上传输数据。这些设备的CPU要忙于处理许多设备控制和数据以及图像 处理等任务。 PDIUSBD12的固件设计成完全的中断驱动。当CPU处理前台任务时,USB的传输可在后台 进行。这就确保了最佳的传输速率和更好的软件结枃,同时简化了编程和调试 后台ISR(中断服务程序)和前台主程序循环之间的数据交换通过事件标志和数据缓冲区来实现。例 如, PDIUSBDI2的批量输出端点可使用循环的数据缓冲区。当 PDIUSBD12从USB收到一个数据包,那 么就对CPU产生一个中断请求,CPU立即响应中断。在ISR中,固件将数据包从 PDIUSBD12内部缓冲区 移到循环数据缓冲区并在随后清零 PDIUSBD12的内部缓冲区以使能接收新的数据包。CPU可以继续它当 前的前台任务直到完成,例如打印当前页。然后返回到主循环检查循环缓冲区内是否有新的数据并开始其 它的前台任务。 RXRP,主循环保持的读指针 前台主循环程序 后台中断服务程序(SR) 循环数据缓冲区 RXWP,ISR保持的写指针 由于这种结构,主循环不关心数据是来自USB、串口还是并口。它只检查循环缓冲区内需要处理的新 数据。这个概念很重要。这样主循环程序专注于数据的处理而ISR能够以最大可能的速度进行数据的传输。 相似的,控制端点在数据包处理时采用了同样的概念。ⅠSR接收和保存数据缓冲区中的控制传输并设 置相应的标志寄存器。主循环向协议处理程序发出请求。由于所有的标准器件,级别和厂商请求都是在协 议处理程序中进行处理,ISR得以保持它的效率。而且一旦增加新的请求,只需要在协议层进行修改。 结构 固件结构 评估板的固件有着如下的积木式结构: 主循环:发送USB请求、读测试Key、控制LED和处理USB 总线事件等等 MAINLOOP. C 标准请求 厂商请求 chAP 9.C PROTODMA. C 中断服务程序 ISR. C PDIUSBD2命令接口 DI2CLC
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 1 PDIUSBD12 固件编程指南 介绍 PDIUSBD12 是一款带有并行总线和局部 DMA 传输能力的高速 USB 接口器件 固件设计的目标就是 使 PDIUSBD12 在 USB 上达到最大的传输速率 外围设备例如打印机 扫描仪 外部的海量存储器和数码 相机都可使用 PDIUSBD12 在 USB 上传输数据 这些设备的 CPU 要忙于处理许多设备控制和数据以及图像 处理等任务 PDIUSBD12 的固件设计成完全的中断驱动 当 CPU 处理前台任务时 USB 的传输可在后台 进行 这就确保了最佳的传输速率和更好的软件结构 同时简化了编程和调试 后台 ISR 中断服务程序 和前台主程序循环之间的数据交换通过事件标志和数据缓冲区来实现 例 如 PDIUSBD12 的批量输出端点可使用循环的数据缓冲区 当 PDIUSBD12 从 USB 收到一个数据包 那 么就对 CPU 产生一个中断请求 CPU 立即响应中断 在 ISR 中 固件将数据包从 PDIUSBD12 内部缓冲区 移到循环数据缓冲区并在随后清零 PDIUSBD12 的内部缓冲区以使能接收新的数据包 CPU 可以继续它当 前的前台任务直到完成 例如打印当前页 然后返回到主循环检查循环缓冲区内是否有新的数据并开始其 它的前台任务 由于这种结构 主循环不关心数据是来自 USB 串口还是并口 它只检查循环缓冲区内需要处理的新 数据 这个概念很重要 这样主循环程序专注于数据的处理而 ISR 能够以最大可能的速度进行数据的传输 相似的 控制端点在数据包处理时采用了同样的概念 ISR 接收和保存数据缓冲区中的控制传输并设 置相应的标志寄存器 主循环向协议处理程序发出请求 由于所有的标准器件 级别和厂商请求都是在协 议处理程序中进行处理 ISR 得以保持它的效率 而且一旦增加新的请求 只需要在协议层进行修改 结构 固件结构 评估板的固件有着如下的积木式结构 主循环 发送 USB 请求 读测试 Key 控制 LED 和处理 USB 总线事件等等 MAINLOOP.C 标准请求 CHAP_9.C 厂商请求 PROTODMA.C 中断服务程序 ISR.C PDIUSBD12 命令接口 D12CI.C
州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w 硬件提取层 EPPHAL C 硬件提取层一 EPPHAL.C 这是固件中的最低层代码,它执行对 PDIUSBD2和评估板硬件与O相关的访问。当与其它CPU平 接口时,这部分代码需要修改或增加 /率*事事率布事布*帝布市水事亭春率布市摩摩率亭市率事布事布事布水序事布事布率*市事摩布市率事帝布布水事布率摩事 ∥ File name EPPHAL. C #ifdef C51 #include / special function register declarations * #include"epphalh #include d12ci h" extern EPPFLAGS bEPPflags unsigned char xdata ext address MCU HOSTDACK=I ext_address=Oxfi00+ port MCU HOSTDACK =O unsigned char inport(unsigned char port) unsigned char xdata ext address MCU HOSTDACK=I ext_ address=0xff00+ port MCU HOSTDACK =0
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 2 硬件提取层 EPPHAL.C 这是固件中的最低层代码 它执行对 PDIUSBD12 和评估板硬件与 I/O 相关的访问 当与其它 CPU 平 台接口时 这部分代码需要修改或增加 /* //************************************************************************* // File Name: EPPHAL.C //************************************************************************* */ #include #ifdef __C51__ #include /* special function register declarations */ #include "epphal.h" #include "d12ci.h" #include "mainloop.h" extern EPPFLAGS bEPPflags; void outportb(unsigned char port, unsigned char val) { unsigned char xdata *ext_address; MCU_HOSTDACK =1; ext_address=0xff00 + port; *ext_address = val; MCU_HOSTDACK =0; } unsigned char inportb(unsigned char port) { unsigned char c; unsigned char xdata *ext_address; MCU_HOSTDACK =1; ext_address=0xff00 + port; c = *ext_address ; MCU_HOSTDACK =0; 硬件提取层 EPPHAL.C
州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w void eppAwrite(unsigned char A data) MCU HOSTDACK =1 printf("eppAwrite=Ox%bx.n",A data); PO=(A data 0x80); EPP WRITE=0 EPP DSTROBE=I EPP ASTROBE= I EPP ASTROBE=O EPP ASTROBE= 1 PO=(A data& 0x7F) EPP ASTROBE=I MCU HOSTDACK=0 void program cpld(unsigned short uSize, unsigned char bCommand) MCU HOSTDACK =1 outport( CPLD CNTO, LSB(uSize)); /set CPLD counter portb(CPLD CNTl, MSB(sIze)); printf("CPLD counter read back=Ox%bx, Ox%bx. In", inport(CPLD_CNTO), inport( CPLD CNTI)) EPP WRITE=I ∥ IN TOKEN DMA MCU DMARD WR=1;
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 3 return c; } void eppAwrite(unsigned char A_data) { MCU_HOSTDACK =1; if(bEPPflags.bits.verbose) printf("eppAwrite = 0x%bx.\n", A_data); P0 = (A_data | 0x80); EPP_WRITE = 0; EPP_DSTROBE = 1; EPP_ASTROBE = 1; EPP_ASTROBE = 0; EPP_ASTROBE = 1; P0 = (A_data & 0x7F); EPP_ASTROBE = 0; EPP_ASTROBE = 1; MCU_HOSTDACK =0; } void program_cpld(unsigned short uSize, unsigned char bCommand) { MCU_HOSTDACK = 1; outportb(CPLD_CNT0, LSB(uSize)); // set CPLD counter outportb(CPLD_CNT1, MSB(uSize)); if(bEPPflags.bits.verbose) printf("CPLD counter read back = 0x%bx, 0x%bx.\n", inportb(CPLD_CNT0), inportb(CPLD_CNT1)); if(bCommand & 0x1) { MCU_DMARD_WR = 0; EPP_WRITE = 1; // IN_TOKEN_DMA; } else { MCU_DMARD_WR = 1;
州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w EPP WRITE=0: /OUT TOKEN DMA MCU HOSTDACK=0 void dma start(PIO REQUEST pio) eppAwrite((pio->uAddressL >> 13)+(pio->bAddressH <<3)); PDIUSBD12命令接口一D12c1.C 为了进一步简化 PDIUSBD12的编程,固件定义了一套压缩了所有访问 PDIUSBD2功能的命令接口。 /率事事布本亭率率摩春布布春布*事布冰布率布事事率事布本亭春布率事亭布市*率事冰摩布市*布布布事布率亭事 ∥ File name:ISRC ∥98/11/2 O mode Main endpoints read/write update(WK) ∥98/12 Added D12 ReadMain Endpoint (WK) extern EPPFLAGS bEPPflags: void D12 SetAddress Enable(unsigned char bAddress, unsigned char bEnable) if(bEPPflags bits i BLEs
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 4 EPP_WRITE = 0; // OUT_TOKEN_DMA; } MCU_HOSTDACK = 0; } void dma_start(PIO_REQUEST pio) { eppAwrite( (pio->uAddressL >> 13) + (pio->bAddressH uSize, pio->bCommand); } #endif PDIUSBD12 命令接口 D12CI.C 为了进一步简化 PDIUSBD12 的编程 固件定义了一套压缩了所有访问 PDIUSBD12 功能的命令接口 /* //************************************************************************* //File Name: ISR.C // 98/11/27 I/O mode Main endpoints read/write update (WK) // 98/12/2 Added D12_ReadMainEndpoint (WK) //************************************************************************* */ #ifdef __C51__ #include /* special function register declarations */ #else #include #endif #include "epphal.h" #include "mainloop.h" #include "d12ci.h" extern EPPFLAGS bEPPflags; void D12_SetAddressEnable(unsigned char bAddress, unsigned char bEnable) { if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(D12_COMMAND, 0xD0); if(bEnable) bAddress |= 0x80; outportb(D12_DATA, bAddress);
州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w if(bEPPflags bits in isr=0) ENABLE void D12 SetEndpointenable( e(unsigned char bEnable) DISABLE outport(DI2 COMMAND, OxD8); if(eNable) outport(D12 DATA, 1) se outport(D12 DATA, 0) if(bEPPflags bits in isr=0) ENABLE void D12 SetMode(unsigned char bConfig, unsigned char bClkDiv) f(bEPPflags bits in isr==0) DISABLE: outport(D12 COMMAND, OxF3) outport(D12 DATA, cOnfig) outport(DI2 DATA, bClkDiv if(bEPPflags bits in isr=0) ENAB void D12 SetDMA(unsigned char bMode) LER DISABLI outport(D12 COMMAND, OxFB): outport(DI2 DATA, bOde); if(bEPPflags bits in isr=0) ENABLE
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 5 if(bEPPflags.bits.in_isr == 0) ENABLE; } void D12_SetEndpointEnable(unsigned char bEnable) { if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(D12_COMMAND, 0xD8); if(bEnable) outportb(D12_DATA, 1); else outportb(D12_DATA, 0); if(bEPPflags.bits.in_isr == 0) ENABLE; } void D12_SetMode(unsigned char bConfig, unsigned char bClkDiv) { if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(D12_COMMAND, 0xF3); outportb(D12_DATA, bConfig); outportb(D12_DATA, bClkDiv); if(bEPPflags.bits.in_isr == 0) ENABLE; } void D12_SetDMA(unsigned char bMode) { if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(D12_COMMAND, 0xFB); outportb(D12_DATA, bMode); if(bEPPflags.bits.in_isr == 0) ENABLE; }
州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w unsigned short D12 ReadInterruptRegister( void) outport(DI2 COMMAND, OxF4); bl= inport(D 12 DATA), inport(DI2 DATA); 8 j+=bl; return ]; unsigned char Di2 SelectEndpoint( unsigned char bEndp if(bEPPflags bits in isr==0) DISABLE: outport(D12 COMMAND, bEndp): b(DI2 DAtA f(bEPPflags bits in isr==0) ENABLE eturn c unsigned char D12 Read TransactionStatus(unsigned char bEndp outport(D12 COMMAND, 0x40+ bEndp) return inport(DI2 DATA) unsigned char D12_ ReadEndpointStatus(unsigned char bEndp) unsigned char c: DISABLE 6
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 6 unsigned short D12_ReadInterruptRegister(void) { unsigned char b1; unsigned int j; outportb(D12_COMMAND, 0xF4); b1 = inportb(D12_DATA); j = inportb(D12_DATA); j <<= 8; j += b1; return j; } unsigned char D12_SelectEndpoint(unsigned char bEndp) { unsigned char c; if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(D12_COMMAND, bEndp); c = inportb(D12_DATA); if(bEPPflags.bits.in_isr == 0) ENABLE; return c; } unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp) { outportb(D12_COMMAND, 0x40 + bEndp); return inportb(D12_DATA); } unsigned char D12_ReadEndpointStatus(unsigned char bEndp) { unsigned char c; if(bEPPflags.bits.in_isr == 0) DISABLE;
州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w outport(DI2 COMMAND, 0x80 bEnd) C=inport(DI2 DATA); if(bEPPflags bits in isr=0) ENABLE return c void D12 Set EndpointStatus( unsigned char bEndp, unsigned char bStalled) if(bEPPflags bits in isr==0) DISABLE: outport (DI2 COMMAND, 0x40+ bEnd); portb(D12 DATA, stalled) f(bEPPflags bits ENABLE void D12 SendResume( void) orb(DI2 COMMAND, OxF6) unsigned short D12 Read Current FrameNumbe f(bEPPflags bits in isr==0) DISABLE: outport(D12 COMMAND, OxF5); F= inport(D12 DATA); inport(DI2 DATA i+=(<<8) f(bEPPflags bits in isr==0 ENABLE 7
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 7 outportb(D12_COMMAND, 0x80 + bEndp); c = inportb(D12_DATA); if(bEPPflags.bits.in_isr == 0) ENABLE; return c; } void D12_SetEndpointStatus(unsigned char bEndp, unsigned char bStalled) { if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(D12_COMMAND, 0x40 + bEndp); outportb(D12_DATA, bStalled); if(bEPPflags.bits.in_isr == 0) ENABLE; } void D12_SendResume(void) { outportb(D12_COMMAND, 0xF6); } unsigned short D12_ReadCurrentFrameNumber(void) { unsigned short i,j; if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(D12_COMMAND, 0xF5); i= inportb(D12_DATA); j = inportb(D12_DATA); i += (j<<8); if(bEPPflags.bits.in_isr == 0) ENABLE; return i; }
州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w unsigned short D12 Read ChiplD(void) ansI if(bEPPflags bits in isr=0) DISABLE: outport(portbase+ D12 COMMAND, OxFD); rebase+D12 DATA) inport(portbase+DI2 DATA), (len) j=len *(buf+i)=inport (D12 DATA); outport(D12 COMMAND, OxF2) 8
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 8 unsigned short D12_ReadChipID(void) { unsigned short i,j; if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(portbase+D12_COMMAND, 0xFD); i=inportb(portbase+D12_DATA); j=inportb(portbase+D12_DATA); i += (j len) j = len; for(i=0; i<j; i++) *(buf+i) = inportb(D12_DATA); outportb(D12_COMMAND, 0xF2);
州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w if(bEPPflags bi ENABLE: return ]; //D12_ ReadMain EndpointO added by V2.2 to support double-buffering // Caller should assume maxium 128 bytes of returned data. unsigned char DI2 ReadMain Endpoint(unsigned char* buf) unsigned char i,j,k=0, bDblBuf= 1 if(bEPPflags bits in isr=0) DISABLE: outport(D12 COMMAND, 0x84); if(( inport(D12 DATA)& 0x60)=0x60 bDblBuf= 2. while(bDblBuf)i outport(DI2 COMMAND, 4); if(inport(D12 DATA)& D12 FULLEMPTY==0) outport(D12 COMMAND, OxFO); j=inport(D12 DATA); for(=0,ij,++) *(buf+i+k)=inport(D12 DATA), k+=j, utportb(D12_ COMMAND, OxF2); bDblBuf f(bEPPflags bits in isr ENABLE return k
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 9 if(bEPPflags.bits.in_isr == 0) ENABLE; return j; } // D12_ReadMainEndpoint() added by V2.2 to support double-buffering. // Caller should assume maxium 128 bytes of returned data. unsigned char D12_ReadMainEndpoint(unsigned char * buf) { unsigned char i, j, k = 0, bDblBuf = 1; if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(D12_COMMAND, 0x84); if( (inportb(D12_DATA) & 0x60) == 0x60) bDblBuf = 2; while(bDblBuf) { outportb(D12_COMMAND, 4); if((inportb(D12_DATA) & D12_FULLEMPTY) == 0) break; outportb(D12_COMMAND, 0xF0); j = inportb(D12_DATA); j = inportb(D12_DATA); for(i=0; i<j; i++) *(buf+i+k) = inportb(D12_DATA); k += j; outportb(D12_COMMAND, 0xF2); bDblBuf --; } if(bEPPflags.bits.in_isr == 0) ENABLE; return k; }
州周立功单片机发展有限公司Te:(020)3873097638730977Fax:38730925htpr/w unsigned char D12 Write Endpoint(unsigned char endp, unsigned char*buf, unsigned char len) unsigned char 1; if(bEPPflags bits in isr=0) DISABLE: outport(D12 COMMAND, endp); inport(DI2 DATA); outport(D12 COMMAND, OxFO); outport(D12 DATA, 0); 12 DAT r(i=0,i<len;++) outport(D2DATA’bu+i) outport(D12 COMMAND, OxFA); if(bEPPflags bits in isr=0) ENAB void DI2 Acknowledge Endpoint(unsigned char endp outport(D12COMMAND, endp); outport(DI2 COMMAND, OxFI); outport(D12 COMMAND, OxF2) unsigned char D12Eval inport( void) eturn inport(D12 EVAL PORT D); void DI2Eval outport(unsigned char val, unsigned char mask) static unsigned char last val=0; al=(val mask)I (last val &(-mask));
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com 10 unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char * buf, unsigned char len) { unsigned char i; if(bEPPflags.bits.in_isr == 0) DISABLE; outportb(D12_COMMAND, endp); inportb(D12_DATA); outportb(D12_COMMAND, 0xF0); outportb(D12_DATA, 0); outportb(D12_DATA, len); for(i=0; i<len; i++) outportb(D12_DATA, *(buf+i)); outportb(D12_COMMAND, 0xFA); if(bEPPflags.bits.in_isr == 0) ENABLE; return len; } void D12_AcknowledgeEndpoint(unsigned char endp) { outportb(D12_COMMAND, endp); outportb(D12_COMMAND, 0xF1); if(endp == 0) outportb(D12_COMMAND, 0xF2); } #ifndef __C51__ unsigned char D12Eval_inportb(void) { return inportb(D12_EVAL_PORT_I); } void D12Eval_outportb(unsigned char val, unsigned char mask) { static unsigned char last_val = 0; val = (val & mask) | (last_val & (~mask));