📄 usb_pdiusbd12.c
字号:
/*********************************************************************
** Module Name: USB_PDIUSBD12.c **
** Author: ZhangQuan **
** Version: 1.0 **
** CreateDate: 2001-05-18 **
** Description: Function Definitions about Controlling **
** PDISUBD12 Chip **
** Remark: **
** Revision History: **
**********************************************************************/
#define PD12_DEBUG 0
//#include <linux/interrupt.h>
#include "DataType.h"
#include "MC68VZ328.h"
// Function Declarations
void outportb(UCHAR cmdordata, UCHAR cmddata);
UCHAR inportb(UCHAR cmdordata);
void D12_SetAddressEnable(UCHAR bAddress, UCHAR bEnable);
void D12_SetEndpointEnable(UCHAR bEnable);
void D12_SetMode(UCHAR bConfig, UCHAR bClkDiv);
void D12_SetDMA(UCHAR bMode);
UWORD D12_ReadInterruptRegister(void);
UCHAR D12_SelectEndpoint(UCHAR bEndp);
UCHAR D12_ReadLastTransactionStatus(UCHAR bEndp);
UCHAR D12_ReadEndpointStatus(UCHAR bEndp);
void D12_SetEndpointStatus(UCHAR bEndp, UCHAR bStalled);
void D12_SendResume(void);
UWORD D12_ReadCurrentFrameNumber(void);
UCHAR D12_ReadEndpoint(UCHAR endp, UCHAR *buf, UCHAR len);
UCHAR D12_WriteEndpoint(UCHAR endp, UCHAR *buf, UCHAR welen);
void D12_AcknowledgeEndpoint(UCHAR endp);
UCHAR D12_ReadMainEndpoint(UCHAR * buf);
// Addition
void stall_ep0(void);
void Stall_EP2(void);
void single_transmit(UCHAR *buf, UCHAR len);
void code_transmit(UCHAR *pRomData, UWORD len);
void init_unconfig(void);
void init_config(void);
/************/
/************/
/************/
/************/
#define BUF2ADDR 0x1200030
#define BUF1ADDR 0x1200032
#define Read_buf1() (*((UCHAR*) BUF1ADDR))
#define Write_buf1(n) (*((UCHAR*) BUF1ADDR) = n)
#define Read_buf2() (*((UCHAR*) BUF2ADDR))
#define Write_buf2(n) (*((UCHAR*) BUF2ADDR) = n)
// Function Definitions
void outportb(UCHAR cmdordata, UCHAR cmddata)
{
UCHAR ch;
if(cmdordata == D12_COMMAND)
{
//Write_buf1(cmddata);
asm(move.b cmddata,0x1200032);
}
else if(cmdordata == D12_DATA)
{
// Write_buf2(cmddata);
asm(move.b cmddata,0x1200030);
}
}
UCHAR inportb(UCHAR cmdordata)
{
UCHAR ch;
if(cmdordata == D12_DATA)
{
// ch = Read_buf2();
asm(move.b 0x1200030,ch);
}
return ch;
}
/************/
/************/
/************/
/************/
// Function Definitions
/*void outportb(UCHAR cmdordata, UCHAR cmddata)
{
UCHAR ch;
if(cmdordata == D12_COMMAND)
{
PCDIR = 0xFF; //Set Port C Output
PKDATA &= (~USB_CS); //Chip Select
PKDATA |= USB_A0; //Select Command Instruction
PCDATA = cmddata; //Output the Command data
PKDATA &= (~USB_WRITE); //Write strobe(low)
ch = PCDATA;
PKDATA |= USB_WRITE; //Write strobe(high)
}
else if(cmdordata == D12_DATA)
{
PCDIR = 0xFF; //Set Port C Output
PKDATA &= (~USB_CS); //Chip Select
PKDATA &= (~USB_A0); //Select Data Phase
PCDATA = cmddata;
PKDATA &= (~USB_WRITE); //Write strobe(low)
PCDATA;
PKDATA |= USB_WRITE; //Write strobe(high)
}
PKDATA |= 0x01; //Chip Deselect
PKDATA |= 0x60; //Write and Read Disable
}
//This function is used to read data from endpoint 4
UCHAR inportb(UCHAR cmdordata)
{
UCHAR ch;
if(cmdordata == D12_DATA)
{
PCDIR = 0x00; //Select Port C Input
PKDATA &= (~USB_CS); //Chip Select
PKDATA &= (~USB_A0); //Data Phase
PKDATA &= (~USB_READ); //Read strobe(low)
ch = PCDATA;
PKDATA = (USB_WRITE|USB_READ); //Read strobe(high)
}
PKDATA |= 0x01; //Chip Deselect
PKDATA |= 0x60; //Write and Read Disable
return ch;
}
*/
void D12_SetAddressEnable(UCHAR bAddress, UCHAR bEnable)
{
UCHAR ch;
ch = bAddress;
outportb(D12_COMMAND, 0xD0);
if(bEnable) ch |= 0x80;
outportb(D12_DATA, ch); //Dis or Enable the address
}
void D12_SetEndpointEnable(UCHAR bEnable)
{
outportb(D12_COMMAND, 0xD8);
if(bEnable)
{
outportb(D12_DATA, 1);//Enable the endpoints
}
else
{
outportb(D12_DATA, 0);//Disable the endpoints
}
}
void D12_SetMode(UCHAR bConfig, UCHAR bClkDiv)
{
outportb(D12_COMMAND, 0xF3);
outportb(D12_DATA, bConfig);
outportb(D12_DATA, bClkDiv);
}
void D12_SetDMA(UCHAR bMode)
{
outportb(D12_COMMAND, 0xFB);
outportb(D12_DATA, bMode);
}
UWORD D12_ReadInterruptRegister(void)
{
UWORD wd;
UCHAR ch1,ch2;
outportb(D12_COMMAND, 0xF4);
ch1 = inportb(D12_DATA);
ch2 = inportb(D12_DATA);
wd = (ch2 << 0x08) | ch1;
return wd;
}
UCHAR D12_SelectEndpoint(UCHAR bEndp)
{
UCHAR c;
outportb(D12_COMMAND, bEndp);
c = inportb(D12_DATA);
return c;
}
UCHAR D12_ReadLastTransactionStatus(UCHAR bEndp)
{
UCHAR ch;
outportb(D12_COMMAND, 0x40 + bEndp);
ch = inportb(D12_DATA);
return ch;
}
UCHAR D12_ReadEndpointStatus(UCHAR bEndp)
{
UCHAR c;
outportb(D12_COMMAND, 0x80 + bEndp);
c = inportb(D12_DATA);
return c;
}
void D12_SetEndpointStatus(UCHAR bEndp, UCHAR bStalled)
{
outportb(D12_COMMAND, 0x40 + bEndp);
outportb(D12_DATA, bStalled);
}
void D12_SendResume(void)
{
outportb(D12_COMMAND, 0xF6);
}
UWORD D12_ReadCurrentFrameNumber(void)
{
UWORD i,j;
outportb(D12_COMMAND, 0xF5);
i= inportb(D12_DATA);
j = inportb(D12_DATA);
i += (j<<8);
return i;
}
UCHAR D12_ReadEndpoint(UCHAR endp, UCHAR *buf, UCHAR len)
{
UCHAR i, j;
i = D12_SelectEndpoint(endp); //Select Endpoint
if(i == 0)
{
return 0;
}
//OK the endpoint buffer has data;
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); //OK data are taken all, Clear the buffer
return j;
}
UCHAR asmD12_ReadMainEndpoint(UCHAR *buf)
{
UCHAR i, j, kk;
kk = D12_SelectEndpoint(4); //Select Endpoint
if(kk == 0)
{
return 0;
}
outportb(D12_COMMAND, 0xF0);
j = inportb(D12_DATA);
j = inportb(D12_DATA);
for(i=0; i<j; i++)
{
*(buf+i) = inportb(D12_DATA);
}
outportb(D12_COMMAND, 0xF2); //Clear the buffer
return j;
}
UCHAR D12_ReadMainEndpoint(UCHAR *buf)
{
UCHAR i, j, kk;
kk = D12_SelectEndpoint(4); //Select Endpoint
if(kk == 0)
{
return 0;
}
outportb(D12_COMMAND, 0xF0);
j = inportb(D12_DATA);
j = inportb(D12_DATA);
for(i=0; i<j; i++)
{
*(buf+i) = inportb(D12_DATA);
}
outportb(D12_COMMAND, 0xF2); //Clear the buffer
return j;
}
UCHAR D12_WriteEndpoint(UCHAR endp, UCHAR *buf, UCHAR welen)
{
UCHAR i,ch;
outportb(D12_COMMAND, endp); //Select Endpoint
ch = inportb(D12_DATA);
if((ch & D12_FULLEMPTY) == 0)
{
}
else
{
printk("This endpoint's buffer is full;\n");
}
outportb(D12_COMMAND, 0xF0); //Write buffer
outportb(D12_DATA, 0);
outportb(D12_DATA, welen); //Write the length
for(i=0; i<welen; i++)
{
ch = *(buf+i);
outportb(D12_DATA, ch);
#if PD12_DEBUG
printk(" %3x ",ch);
#endif
}
outportb(D12_COMMAND, 0xFA); //Validate the buffer
#if PD12_DEBUG
printk(" \n ");
#endif
return welen;
}
void D12_AcknowledgeEndpoint(UCHAR endp)
{
outportb(D12_COMMAND, endp);
outportb(D12_COMMAND, 0xF1);
if(endp == 0) outportb(D12_COMMAND, 0xF2);
#if PD12_DEBUG
printk("Acknowledge Endpoint %d;\n",endp);
#endif
}
// Addition
void stall_ep0(void)
{
D12_SetEndpointStatus(0, 1);
D12_SetEndpointStatus(1, 1);
}
void Stall_EP2(void)
{
D12_SetEndpointStatus(4, 1);
D12_SetEndpointStatus(5, 1);
}
void single_transmit(UCHAR *buf, UCHAR len)
{
if(len <= EP0_PACKET_SIZE)
D12_WriteEndpoint(1, buf, len);
}
void single_transmit_5(UCHAR *buf, UCHAR len)
{
if(len <= EP0_PACKET_SIZE)
D12_WriteEndpoint(5, buf, len);
}
void code_transmit(UCHAR *pRomData, UWORD len)
{
UCHAR length;
UCHAR *Datapt;
ControlData.wCount = 0;
if(ControlData.wLength > len)
ControlData.wLength = len;
length = len;
ControlData.pData = pRomData;
Datapt = pRomData;
//Transfer the first frame to PD12 EP0 in buffer;
if(length >= EP0_PACKET_SIZE)
{
//printk("code_transmit is over\n");
D12_WriteEndpoint(1, Datapt, EP0_PACKET_SIZE);
ControlData.wCount += EP0_PACKET_SIZE;
bEPPflags.bits.control_state = USB_TRANSMIT;
}
else
{
//printk("code_transmit is over\n");
D12_WriteEndpoint(1, Datapt, length);
ControlData.wCount += ControlData.wLength;
bEPPflags.bits.control_state = USB_IDLE;
}
}
void init_unconfig(void)
{
D12_SetEndpointEnable(0); // Disable all endpoints but EPP0.
}
void init_config(void)
{
D12_SetEndpointEnable(1); // Enable generic/iso endpoints.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -