|
楼主 |
发表于 2006-3-29 14:37:33
|
显示全部楼层
low-level 驱动来了,测试顺利通过:
/*---------------------------------------------------------------
FileName : D12.c
Created by : ZhengYanbo
Crtated date : 2006.3.23
Last Modified:
Comments : d12 low-level drive
Contact : Datazyb_007@163.com
---------------------------------------------------------------*/
#include "type.h"
#ifndef __D12_H__
#define __D12_H__
// data pin define
#define USB_DATA_PORT PORTA
#define USB_DATA_PIN PINA
#define USB_DATA_DDDR DDRA
//pins
#define RD_PIN PD7
#define WR_PIN PD6
#define INT_PIN PD2
#define A0_PIN PC0
#define nCS_PIN PE2
#define RESET_PIN PB4
//RD pin
#define D12_RD_OUT() DDRD.7=1;
#define SET_D12_RD() PORTD.7=1;
#define CLR_D12_RD() PORTD.7=0;
//WR pin
#define D12_WR_OUT() DDRD.6=1;
#define SET_D12_WR() PORTD.6=1;
#define CLR_D12_WR() PORTD.6=0;
//INT pin
#define D12_INT_IN() DDRD.2=0;
#define D12_INT_PIN PIND.2
//A0 pin
#define D12_A0_OUT() DDRC.0=1;
#define SET_D12_A0() PORTC.0=1;
#define CLR_D12_A0() PORTC.0=0;
//CS pin
#define D12_CS_OUT() DDRE.2=1;
#define D12_Enable() PORTE.2=0;
#define D12_Disable() PORTE.2=1;
//RESET pin
#define D12_RESET_OUT() DDRB.4=1;
#define SET_D12_RESET() PORTB.4=1;
#define CLR_D12_RESET() PORTB.4=0;
// D12 data sheet
#define D12_FIFOEMPTY 0xff
#define EP0_TX_FIFO_SIZE 16
#define EP0_RX_FIFO_SIZE 16
#define EP0_PACKET_SIZE 16
#define EP1_TX_FIFO_SIZE 16
#define EP1_RX_FIFO_SIZE 16
#define EP1_PACKET_SIZE 16
#define EP2_TX_FIFO_SIZE 64
#define EP2_RX_FIFO_SIZE 64
#define EP2_PACKET_SIZE 64
#define D12CMD_SNDRESUME 0xF6
#define D12CMD_RDCURFRAME 0xF5
#define D12CMD_SETADDR 0xD0
#define D12CMD_SETENDP 0xD8
#define D12CMD_SETMODE 0xF3
#define D12CMD_SETDMA 0xFB
#define D12CMD_RDIR 0xF4
#define D12CMD_SELEP0OUT 0x00
#define D12CMD_SELEP0IN 0x01
#define D12CMD_SELEP1OUT 0x02
#define D12CMD_SELEP1IN 0x03
#define D12CMD_SELEP2OUT 0x04
#define D12CMD_SELEP2IN 0x05
#define D12CMD_RDBUFFER 0xF0
#define D12CMD_WRBUFFER 0xF0
#define D12CMD_ACKSETUP 0xF1
#define D12CMD_CLRBUFFER 0xF2
#define D12CMD_VALIDBUFFER 0xFA
#define D12CMD_RDLTSEP0OUT 0x40
#define D12CMD_RDLTSEP0IN 0x41
#define D12CMD_RDLTSEP1OUT 0x42
#define D12CMD_RDLTSEP1IN 0x43
#define D12CMD_RDLTSEP2OUT 0x44
#define D12CMD_RDLTSEP2IN 0x45
#define D12CMD_SETEP0OUTSTS 0x40
#define D12CMD_SETEP0INSTS 0x41
#define D12CMD_SETEP1OUTSTS 0x42
#define D12CMD_SETEP1INSTS 0x43
#define D12CMD_SETEP2OUTSTS 0x44
#define D12CMD_SETEP2INSTS 0x45
#define D12CMD_RDEP0OUTSTS 0x80
#define D12CMD_RDEP0INSTS 0x81
#define D12CMD_RDEP1OUTSTS 0x82
#define D12CMD_RDEP1INSTS 0x83
#define D12CMD_RDEP2OUTSTS 0x84
#define D12CMD_RDEP2INSTS 0x85
#define D12_NOLAZYCLOCK 0x02
#define D12_CLOCKRUNNING 0x04
#define D12_INTERRUPTMODE 0x08
#define D12_SOFTCONNECT 0x10
#define D12_ENDP_NONISO 0x00
#define D12_ENDP_ISOOUT 0x40
#define D12_ENDP_ISOIN 0x80
#define D12_ENDP_ISOIO 0xC0
#define D12_CLOCK_16M 0x02
#define D12_CLOCK_12M 0x03
#define D12_CLOCK_8M 0x05
#define D12_CLOCK_4M 0x0b
#define D12_SETTOONE 0x40
#define D12_SOFONLY 0x80
#define D12_DMASINGLE 0x00
#define D12_BURST_4 0x01
#define D12_BURST_8 0x02
#define D12_BURST_16 0x03
#define D12_DMAENABLE 0x04
#define D12_DMA_INTOKEN 0x08
#define D12_AUTOLOAD 0x10
#define D12_NORMALPLUSSOF 0x20
#define D12_ENDP4INTENABLE 0x40
#define D12_ENDP5INTENABLE 0x80 // bug fixed in V2.1
#define D12_INT_ENDP0OUT 0x01
#define D12_INT_ENDP0IN 0x02
#define D12_INT_ENDP1OUT 0x04
#define D12_INT_ENDP1IN 0x08
#define D12_INT_ENDP2OUT 0x10
#define D12_INT_ENDP2IN 0x20
#define D12_INT_BUSRESET 0x40
#define D12_INT_SUSPENDCHANGE 0x80
#define D12_INT_EOT 0x0100
#define D12_SETUPPACKET 0x20
#define D12_BUFFER0FULL 0x20
#define D12_BUFFER1FULL 0x40
#define D12_FULLEMPTY 0x01
#define D12_STALL 0x02
//-------------------------------------------------------
// prototypes
//-------------------------------------------------------
void D12_reset(void);
void D12_PortInit(void);
void D12_SetAddressEnable(byte bAddress, byte bEnable);
void D12_SetEndpointEnable(byte bEnable);
void D12_AcknowledgeEndpoint(byte endp);
void D12_SetMode(byte bConfig, byte bClkDiv);
void D12_SetDMA(byte bMode);
byte D12_ReadInterruptRegister(void);
byte D12_ReadLastTransactionStatus(byte bEndp);
byte D12_ReadEndpointStatus(byte bEndp);
void D12_SetEndpointStatus(byte bEndp, byte bStalled);
byte D12_SelectEndpoint(byte bEndp);
byte D12_ReadEndpoint(byte endp, byte len, byte *buffer);
byte D12_ReadEPAtCode(byte endp, byte len);
byte D12_WriteEndpoint(byte endp, byte len, byte *buffer);
byte D12_WriteEndpoint_PGM(byte endp, byte len, byte flash *buffer);
//byte D12_WriteEPAtCode(byte endp, byte len, byte *buffer);
//void D12_ValidateBuffer(byte endp);
//void D12_ClearBuffer(byte endp);
void D12_SingleTransmitEP0(byte *buffer, byte len);
void D12_AcknowledgeSETUP(void);
void D12_StallEP0(void);
//I/O functions
void D12CmdPortOutB(byte data);
void D12DataPortOutB(byte data);
byte D12DataPortInB(void);
//void ResetD12(void);
//void InitD12(void);
// Other
void ReconnectUSB(void);
void ConnectUSB(void);
void DisconnectUSB(void);
#endif
/*---------------------------------------------------------------
FileName : D12.c
Created by : ZhengYanbo
Crtated date : 2006.3.23
Last Modified:
Comments : d12 low-level drive
Contact : Datazyb_007@163.com
---------------------------------------------------------------*/
#include "type.h"
#include "D12.h"
//*************************************************************
//硬件reset d12
//注意:
//复位后等待至少3ms 再对PDIUSBD12 寄存器进行访问这将使晶振有足够的
//时间稳定下来
void D12_reset(void)
//*************************************************************
{
//d12 RESET output mode
D12_RESET_OUT();
CLR_D12_RESET();
//wait d12 process
delay_ms(10);
SET_D12_RESET();
//wait d12 ready
delay_ms(10);
}
//*************************************************************
//初始化与D12连接的AVR端口
void D12_PortInit(void)
//*************************************************************
{
//D0-D7 input mode
USB_DATA_DDDR = 0x00;
//pull-up enabled
USB_DATA_PORT = 0xFF;
//d12 RD output mode
D12_RD_OUT();
//d12 WR output mode
D12_WR_OUT();
//d12 A0 output mode
D12_A0_OUT();
//d12 CS output mode
D12_CS_OUT();
//d12 RESET output mode
D12_RESET_OUT();
//enable d12
D12_Enable();
}
//*************************************************************
//d12地址允许
void D12_SetAddressEnable(byte bAddress, byte bEnable)
//*************************************************************
{
D12CmdPortOutB(0xD0);
if(bEnable) bAddress |= 0x80;
D12DataPortOutB(bAddress);
}
//*************************************************************
//d12 端点允许
void D12_SetEndpointEnable(byte bEnable)
//*************************************************************
{
D12CmdPortOutB(0xD8);
if(bEnable)
D12DataPortOutB(1);
else
D12DataPortOutB(0);
}
//*************************************************************
//模式设置
void D12_SetMode(byte bConfig, byte bClkDiv)
//*************************************************************
{
D12CmdPortOutB(0xF3);
D12DataPortOutB(bConfig);
D12DataPortOutB(bClkDiv);
}
//*************************************************************
//DMA模式设置
void D12_SetDMA(byte bMode)
//*************************************************************
{
D12CmdPortOutB(0xFB);
D12DataPortOutB(bMode);
}
//*************************************************************
//读d12中断寄存器,返回数据
//注意:中断寄存器是16位的,这里只读了低8位!!!
byte D12_ReadInterruptRegister(void)
//*************************************************************
{
byte temp;
D12CmdPortOutB(0xF4);
temp = D12DataPortInB();
D12DataPortInB();
return(temp);
}
//*************************************************************
//读d12最后传输状态
byte D12_ReadLastTransactionStatus(byte bEndp)
//*************************************************************
{
byte temp;
D12CmdPortOutB(0x40|bEndp);
temp = D12DataPortInB();
return(temp);
}
//*************************************************************
//读d12的端口状态
byte D12_ReadEndpointStatus(byte bEndp)
//*************************************************************
{
byte temp;
D12CmdPortOutB(0x80|bEndp);
temp = D12DataPortInB();
return(temp);
}
//*************************************************************
//d12端口选择
byte D12_SelectEndpoint(byte bEndp)
//*************************************************************
{
byte temp;
D12CmdPortOutB(bEndp);
temp = D12DataPortInB();
return(temp);
}
//*************************************************************
//设置d12的端口状态
void D12_SetEndpointStatus(byte bEndp, byte bStalled)
//*************************************************************
{
D12CmdPortOutB(0x40|bEndp);
D12DataPortOutB(bStalled);
}
//*************************************************************
//读d12端口数据到缓冲区
byte D12_ReadEndpoint(byte endp, byte len, byte *buffer)
//*************************************************************
{
D12CmdPortOutB(endp);
//enable buffer
D12CmdPortOutB(0xF0);
D12DataPortInB();
endp = D12DataPortInB();
if( endp > len)
endp = len;
else
len = endp;
//read buffer now
for(; endp != 0 ; endp--, buffer++ )
{
*(buffer) = D12DataPortInB();
}
D12CmdPortOutB(0xF2);
return len ;
}
//*************************************************************
//写数据到d12端口缓冲区
byte D12_WriteEndpoint(byte endp, byte len, byte *buffer)
//*************************************************************
{
D12CmdPortOutB(endp);
D12DataPortInB();
D12CmdPortOutB(0xF0);
endp = len;
D12DataPortOutB(0);
D12DataPortOutB(endp);
for( ; endp != 0; endp-- , buffer++)
{
D12DataPortOutB(*buffer);
}
//validate buffer
D12CmdPortOutB(0xFA);
return len;
}
//*************************************************************
//从程序存储器中写数据到d12端口
//注释:这个函数和上面的函数功能一样.
//由于CVAVR的指针不能混淆使用,所以单独写此函数:)
byte D12_WriteEndpoint_PGM(byte endp, byte len, byte flash *buffer)
//*************************************************************
{
D12CmdPortOutB(endp);
D12DataPortInB();
//read buffer cmd
D12CmdPortOutB(0xF0);
endp = len;
D12DataPortOutB(0);
D12DataPortOutB(endp);
for( ; endp != 0; endp-- , buffer++)
{
D12DataPortOutB(*buffer);
}
//validate buffer
D12CmdPortOutB(0xFA);
return len;
}
//*************************************************************
//d12端口响应函数
void D12_AcknowledgeEndpoint(byte endp)
//*************************************************************
{
D12CmdPortOutB(endp);
D12CmdPortOutB(0xF1);
if(endp == 0)
D12CmdPortOutB(0xF2);
}
//*************************************************************
//默认端口传输
void D12_SingleTransmitEP0(byte *buffer, byte len)
//*************************************************************
{
//endpoint 1
D12_WriteEndpoint(1, len, buffer);
}
//*************************************************************
//d12 setup 响应
void D12_AcknowledgeSETUP(void)
//*************************************************************
{
D12_AcknowledgeEndpoint(0);
D12_AcknowledgeEndpoint(1);
}
//*************************************************************
//设置"STALL"状态,详细参看usb spec
void D12_StallEP0(void)
//*************************************************************
{
D12_SetEndpointStatus(0, 1);
D12_SetEndpointStatus(1, 1);
}
//*************************************************************
//d12 low-level IO function
//写一个数据到d12数据口
void D12DataPortOutB(byte data)
//*************************************************************
{
//set A0 to 0
CLR_D12_A0();
SET_D12_WR();
//set it as output
USB_DATA_DDDR = 0xFF;
USB_DATA_PORT = data;
//allow pin change
#asm("nop");
#asm("nop");
//set WR low
CLR_D12_WR();
#asm("nop"); //allow pin change
#asm("nop"); //allow pin change
//#asm("nop"); //allow pin change
//#asm("nop"); //allow pin change
//set WR low
SET_D12_WR();
}
//*************************************************************
//d12 low-level IO function
//写一个数据到d12的命令口
void D12CmdPortOutB(byte data)
//*************************************************************
{
//set A0 to 1
SET_D12_A0();
SET_D12_WR();
//set it as output
USB_DATA_DDDR = 0xFF;
USB_DATA_PORT = data;
//allow pin change
#asm("nop");
#asm("nop");
//set WR low
CLR_D12_WR();
#asm("nop"); //allow pin change
#asm("nop"); //allow pin change
//#asm("nop"); //allow pin change
//#asm("nop"); //allow pin change
//set WR low
SET_D12_WR();
//wait d12 ready
delay_us(1);
}
//*************************************************************
//d12 low-level IO function
//读d12数据口
byte D12DataPortInB(void)
//*************************************************************
{
byte temp;
//set A0 to 0
CLR_D12_A0();
SET_D12_RD();
//set it as input
USB_DATA_DDDR = 0x00;
//active pull up
USB_DATA_PORT = 0xFF;
#asm("nop"); //allow pin change
#asm("nop"); //allow pin change
//set WR low
CLR_D12_RD();
#asm("nop"); //allow pin change
#asm("nop"); //allow pin change
//#asm("nop"); //allow pin change
//#asm("nop"); //allow pin change
//read PINA
temp = USB_DATA_PIN;
//set WR high
SET_D12_RD();
//return its value
return(temp);
}
//*************************************************************
//d12 USB软断开
void DisconnectUSB(void)
//*************************************************************
{
byte config, clkDiv;
config = D12_NOLAZYCLOCK|D12_CLOCKRUNNING|D12_INTERRUPTMODE;
clkDiv = D12_SETTOONE|D12_CLOCK_12M;
//d12 mode select
D12_SetMode(config, clkDiv);
}
//*************************************************************
//d12 USB软连接
void ConnectUSB(void)
//*************************************************************
{
byte config, clkDiv;
D12_SetDMA(0);
config = D12_NOLAZYCLOCK|D12_SOFTCONNECT|D12_CLOCKRUNNING|D12_INTERRUPTMODE;
clkDiv = D12_SETTOONE | D12_CLOCK_12M;
// Initialize D12 configuration
D12_SetMode(config, clkDiv);
//--------------------------------
//address enabled
//D12_SetAddressEnable(0, 1);
//end point enabled
//D12_SetEndpointEnable(1);
}
//*************************************************************
//d12 USB重连
void ReconnectUSB(void)
//*************************************************************
{
DisconnectUSB();
//wait d12 ready
delay_ms(10);
ConnectUSB();
}
//------------------ end of D12.c ----------------------------//
-----此内容被elefan于2006-03-29,14:40:31编辑过 |
|