📄 pdiusbd12biancheng.txt
字号:
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
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
1
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
硬件提取层
EPPHAL.C
硬件提取层
EPPHAL.C
这是固件中的最低层代码它执行对
PDIUSBD12和评估板硬件与
I/O相关的访问当与其它
CPU平
台接口时这部分代码需要修改或增加
/*
//*************************************************************************
// File Name: EPPHAL.C
//*************************************************************************
*/
#include <stdio.h>
#ifdef __C51__
#include <reg51.h> /* 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;
2
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
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;
3
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
EPP_WRITE = 0; // OUT_TOKEN_DMA;
}
MCU_HOSTDACK = 0;
}
void dma_start(PIO_REQUEST pio)
{
eppAwrite( (pio->uAddressL >> 13) + (pio->bAddressH << 3) );
program_cpld(pio->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 <reg51.h> /* special function register declarations */
#else
#include <dos.h>
#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);
4
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
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;
}
5
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
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;
6
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
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;
}
7
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
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<<8);
if(bEPPflags.bits.in_isr == 0)
ENABLE;
return i;
}
unsigned char D12_ReadEndpoint(unsigned char endp, unsigned char * buf, unsigned char len)
{
unsigned char i, j;
if(bEPPflags.bits.in_isr == 0)
DISABLE;
outportb(D12_COMMAND, endp);
if((inportb(D12_DATA) & D12_FULLEMPTY) == 0) {
if(bEPPflags.bits.in_isr == 0)
ENABLE;
return 0;
}
outportb(D12_COMMAND, 0xF0);
j = inportb(D12_DATA);
j = inportb(D12_DATA);
if(j > len)
j = len;
for(i=0; i<j; i++)
*(buf+i) = inportb(D12_DATA);
outportb(D12_COMMAND, 0xF2);
8
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
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;
}
9
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
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));
10
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 http://www.zlgmcu.com
outportb(D12_EVAL_PORT_O, val);
last_val = val;
}
#endif
中断服务程序
ISR.C
这部分代码处理由
PDIUSBD12产生的中断它将数据从
PDIUSBD12的内部
FIFO取回到
CPU存储
器并建立正确的事件标志以通知主循环程序进行处理
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -