📄 usb.c
字号:
/*********************************************************************************
Module description:
This file is used to finish USB-related functions,
Implement all necessary USB event response
Send/Read data buffer for GP2021 to correspondent endpoints
Author : Yu Lu ,
luyu1974@gmail.com
*********************************************************************************/
#include "reg420.h"
#include "usbn9603.h"
#include "global.h"
#include "gp2021.h"
#include "gbl_macro.h"
#include "usb.h"
extern unsigned char write_buf_leng, write_buf_idx, frm_count,frm_count1;
extern unsigned int data usb_snd_idx,buf_idx;
extern void puthex_char(char ch);
extern void puthex_int(unsigned int a);
extern void put_char(char ch);
/*************************************
sbit GPS_ALE = P2^0;
sbit GPS_WR = P2^1;
sbit GPS_CS = P2^2;
sbit GPS_RD = P2^3;
sbit GPS_OE = P2^4;
**************************************/
extern void DELAY_8US();
extern void DELAY_50US();
extern void DELAY_1MS();
extern void read_gps(char add, unsigned int* datadd);
extern void write_gps(char add, char lo, char hi);
extern void write_gps_noint(char add, char lo, char hi);
extern char read_usb(unsigned int usbadr);
extern void write_usb(unsigned int usbadr, char dta);
extern void bunch_write_usb( unsigned int usbadr, unsigned int datadd, unsigned char count);
extern void bunch_read_usb( unsigned int usbadr, unsigned int datadd, unsigned char count);
/*
*
* the buffer is :
rsnc = read_usb(RXD1);
rcmd = read_usb(RXD1);
rdta = read_usb(RXD1);
radh = read_usb(RXD1);
radl = read_usb(RXD1);
rcks = read_usb(RXD1);
*/
void do_cmd()
{
unsigned char tmpch; // gps_part indicates which part of GP2021 regs is get this time
unsigned char *radr;
unsigned char idata tmp_buf[64];
radr = (unsigned char *)radl;
switch (rcmd)
{
case 'g': // read the vale of USBN9603's registers
tmpch = read_usb((unsigned int)(0x7E00+radl));
FLUSHTX1;
write_usb(TXD1,tmpch);
//TXEN1_PID_NO_TGL;
TXEN1_PID_NO_TGL;
break;
case 'r':
#if DEBG == 1
puthex_char(radr);
puthex_char(radl);
#endif
FLUSHTX1;
write_usb(TXD1,*radr); // read the value of C51's registers
TXEN1_PID_NO_TGL;
break;
case 'w': // write the value of C51's registers
*radr = rdta;
FLUSHTX1;
write_usb(TXD1,*radr);
TXEN1_PID_NO_TGL;
break;
case 'q': // read the value of GP2021's registers
read_gps(rdta, (unsigned int*)gps_data);
FLUSHTX1;
write_usb(TXD1,gps_data[0]);
write_usb(TXD1,gps_data[1]);
TXEN1_PID_NO_TGL;
break;
case 't': // write the value of GP2021's registers
/* just for debugging
puthex_char(rdta);
puthex_char(radh);
puthex_char(radl);
*/
write_gps(rdta,radl,radh );
break;
case 'a': // send all the GP2021's regs
sts_send_gp2021_all = 1; // set flag to indicate we need to transfer gp2021's reg
break;
case 'b':
get_usbn9603(tmp_buf);
send_all_usbn9603_TXD1(tmp_buf);
break;
case 'c': // control perfomance of gp2021
process_gp2021(rdta);
default:
// write_usb(TXD1,'?');
;
}
}
/*********************************************************************
delay to reset usbn9603
NOTE:
P2 = 0x7E, chip select usbn9603
P2 = 0xBE, reset usbn9603
P2 = 0xFE, idle state
*********************************************************************/
void rst_usb(void)
{
P2 = 0xBE; // reset usbn9603
DELAY_50US();
DELAY_1MS();
DELAY_1MS();
DELAY_1MS();
P2 = 0xFE;
DELAY_1MS();
DELAY_1MS();
}
/**********************************************************************/
/* This subroutine initializes the 9602. */
/**********************************************************************/
void init_usb(void)
{
/*toss out any previous state ***********************************/
status = 0;
sts_getdesc = 0;
usb_cfg = 0;
write_buf_leng = 0;
write_buf_idx = 0;
/*give a software reset, then set ints to active low push pull */
write_usb(MCNTRL,SRST);
while( read_usb(MCNTRL) & SRST);
write_usb(MCNTRL,INT_L_P + VGE );
write_usb(MAMSK, 0); // disable all ints
/*initialize the clock generator ********************************/
/* prior to this point, the clock output will be 4 Mhz. After, */
/* it will be (48 MHz/CLKDIV) */
write_usb(CCONF,CLKDIV-1);
/*set up interrupt masks ****************************************/
write_usb(NAKMSK,NAK_O0); /*NAK evnts*/
write_usb(TXMSK,TXFIFO0+TXFIFO1+TXFIFO2+TXFIFO3); /*TX events*/
write_usb(RXMSK,RXFIFO0+RXFIFO1+RXFIFO2+RXFIFO3); /*RX events*/
write_usb(ALTMSK,SD3+RESET_A); /*ALT evnts*/
/*this is modified in the */
/*suspend-resume routines */
/*so if any change is made*/
/*here it needs to be ref-*/
/*lected there too. */
write_usb(MAMSK,(INTR_E+RX_EV+NAK+TX_EV+ALT));
write_usb(DMAMASK, 0);
write_usb(0x7E1f, 0x40);
/*set default address, enable EP0 only **************************/
write_usb(FAR,AD_EN+0);
write_usb(EPC0, 0x00);
/*enable the receiver and go operational ************************/
FLUSHTX0; /*flush TX0 and disable */
write_usb(RXC0,RX_EN); /*enable the receiver */
write_usb(NFSR,OPR_ST); /*go operational */
write_usb(MCNTRL,INT_L_P+NAT+VGE); /*set NODE ATTACH */
}
/**********************************************************************/
/* This subroutine handles USB 'alternate' events. */
/**********************************************************************/
void usb_alt(void)
{
evnt = read_usb(ALTEV); /*check the events */
if(evnt & RESET_A) /*reset event */
{
write_usb(NFSR,RST_ST); /*enter reset state */
write_usb(FAR,AD_EN+0); /*set default address */
write_usb(EPC0,0x00); /*enable EP0 only */
FLUSHTX0; /*flush TX0 and disable */
write_usb(RXC0,RX_EN); /*enable the receiver */
write_usb(ALTMSK,SD3+RESET_A);
write_usb(NFSR,OPR_ST); /*go operational */
}
else if(evnt & (SD3 | SD5) ) /*suspend event */
{
write_usb(ALTMSK,RESUME_A + RESET_A); /*adjust interrupts */
write_usb(NFSR,SUS_ST); /*enter suspend state */
}
else if(evnt & RESUME_A) /*resume event */
{
write_usb(ALTMSK,SD3+RESET_A); /*adjust interrupts */
write_usb(NFSR,OPR_ST); /*go operational */
// write_usb(RXC0,RX_EN);
}
else /*spurious alt. event! */
{
}
}
/**********************************************************************/
/* The CLEAR_FEATURE request is done here */
/**********************************************************************/
void clrfeature(void)
{
switch(usb_buf[0]&0x03) /*find request target */
{
case 0: /*DEVICE */
break;
case 1: /*INTERFACE */
break;
case 2: /*ENDPOINT */
switch (usb_buf[3]) /*find specific endpoint */
{
case 0:
stall_ep0 = 0;
break;
case 1:
stall_ep1 = 0;
break;
case 2:
stall_ep2 = 0;
break;
case 3:
stall_ep3 = 0;
break;
case 4:
stall_ep4 = 0;
break;
case 5:
stall_ep5 = 0;
break;
case 6:
stall_ep6 = 0;
break;
default:
break;
}
break;
default: /*UNDEFINED */
break;
}
}
/**********************************************************************/
/* The GET_DESCRIPTOR request is done here */
/**********************************************************************/
void getdescriptor(void)
{
sts_getdesc=1; /*enter get_descr mode */
desc_typ = usb_buf[3]; /*store the type requested*/
string_idx = usb_buf[2]; /*store the index */
if(desc_typ==DEVICE)
desc_sze = DEV_DESC_SIZE;
else if(desc_typ==CONFIGURATION)
desc_sze = CFG_DESC_SIZE;
else if(desc_typ==XSTRING )
desc_sze = string_sze[ string_idx ];
/*adjust size, if the host has asked for less than we */
/*want to send. Note that we only check the low order */
/*byte of the wlength field. If we ever need to send */
/*back descriptors longer than 256 bytes, we'll need to */
/*revisit this. */
if (desc_sze > usb_buf[6])
desc_sze = usb_buf[6];
/*send the first data chunk back */
for(desc_t_idx=0; ((desc_t_idx<8)&&(desc_t_idx<desc_sze)); desc_t_idx++) get_desc();
}
/**********************************************************************/
/* This subroutine loads a byte from a descriptor into endpoint 0 */
/* Fifo. */
/**********************************************************************/
void get_desc(void)
{
char desc_dta;
/*select the appropriate descriptor. compiler limits forced*/
/*the code to be written in this (admittedly) akward way. */
if(desc_typ==DEVICE)
{
desc_dta=DEV_DESC[desc_t_idx];
}
else if(desc_typ==CONFIGURATION)
desc_dta=CFG_DESC[desc_t_idx];
else if(desc_typ==XSTRING)
desc_dta=((char*)(string_descs[string_idx]))[desc_t_idx];
write_usb(TXD0,desc_dta); /*send data to the FIFO */
#if DEBG == 1
puthex_char(desc_t_idx);
puthex_char(desc_dta);
#endif
}
/**********************************************************************/
/* The GET_STATUS request is done here */
/**********************************************************************/
void getstatus(void)
{
switch (usb_buf[0]&0x03) /*find request target */
{
case 0: /*DEVICE */
write_usb(TXD0,0); /*first byte is reserved */
break;
case 1: /*INTERFACE */
write_usb(TXD0,0); /*first byte is reserved */
break;
case 2: /*ENDPOINT */
switch (usb_buf[3]) /*find specific endpoint */
{
EPSTATUS(0); EPSTATUS(1); EPSTATUS(2); EPSTATUS(3);
EPSTATUS(4); EPSTATUS(5); EPSTATUS(6);
default:
break;
}
break;
default: /*UNDEFINED */
break;
}
write_usb(TXD0,0); /*second byte is reserved */
}
/**********************************************************************/
/* The SET_CONFIGURATION request is done here */
/**********************************************************************/
void setconfiguration(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -