EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

USB-Communication Device Class-Virtual Com Port

Started by igelegin July 19, 2012
Hi all,
I wrote an enumeration and soruce codes as you can see below for making
communicated Max3420e USB with PC via terminals . When I plugged in the
USB, PC  said "USB Device not recognized".
I don't understand where my fault:(
I only want to make communicated Max USB with PC terminals(TeraTerm,Hyper
Terminal etc.)
Please help me,please...

Note:I attached one c file and two header file to my message.
Abraham.

//****************************************************************************
//max_usb_driver_enum.c
//****************************************************************************
#include <soc.h>
#include <csl_mcbsp.h>
#include <csl_tmr.h>
#include <csl_gpio.h>
#include <csl_pllc.h>
#include <stdio.h>
#include "max3420e_usb.h"       					
#include "max_usb_driver_enum_data.h"  				
#include "spi_usb_comm.h"


#define ENABLE_IRQS
usb_write_config(rEPIEN,(bmSUDAVIE+bmIN3BAVIE+bmIN0BAVIE+bmOUT0DAVIE));
usb_write_config(rUSBIEN,(bmURESIE+bmURESDNIE+bmBUSACTIE));
#define TWENTY_MSEC 14200           				// adjust this constant for 20 msec
button checks
#define BLINKTIME 25                				// blink every 500 msec


//Global variables
Uint8 SUD[8];	
Uint8 configval;									// Set/Get_Configuration value
Uint8 ep3stall;										// Flag for EP3 Stall, set by Set_Feature,
reported back in Get_Status
Uint8 interfacenum;  								// Set/Get interface value
Uint8 RWU_enabled;   							    // Set by Set/Clear_Feature RWU request,
sent back for Get_Status-RWU
Uint8 Suspended;     							    // Tells the main loop to look for host
resume and RWU pushbutton
Uint16 msec_timer;    							    // Count off time in the main loop
Uint16 blinktimer;    							    // Count milliseconds to blink the "loop
active" light
Uint8 test_1,test_2,test_3;
int i;
Uint8 msgidx,msglen;								// Text string in EnumApp_enum_data.h--index
and length
Uint8 inhibit_send;									// Flag for the keyboard character send
routine
Uint8 send3zeros;    							  	// EP3-IN function uses this to send HID
(key up) codes between keystrokes
Uint8 test_4[64];
int PC_DTR=0;


// USB functions
void std_request(void);
void class_request(void);
void vendor_request(void);
void send_descriptor(void);
void feature(Uint8);
void get_status(void);
void set_interface(void);
void get_interface(void);
void set_configuration(void);
void get_configuration(void);


// Application code
void do_SETUP(void); 
void do_IN3(void);      											// Handle a USB SETUP transfer
void check_for_resume(void);
void service_irqs(void);
void usb_main_exec(void);


//********main
void usb_main_exec(void)
{ 	
test_1 = usb_read_config(rFNADDR);
test_2 = usb_read_config(rEPIRQ);
test_3 = usb_read_config(rUSBIRQ);

	if(Suspended)
		{
		check_for_resume();
		}
	service_irqs();  											//burada if i&ccedil;inde "max_int_pending" diye bir
fonk vard&#305;
	msec_timer++;
	if(msec_timer==TWENTY_MSEC)
		{
		msec_timer=0;
		}					
	blinktimer++;                 								// blink the loop active light every
half second
	if(blinktimer==BLINKTIME)
		{
		blinktimer=0;
		}														// msec_timer==ONE_MSEC	
}


void check_for_resume(void)         
{
  if(usb_read_config(rUSBIRQ) & bmBUSACTIRQ)     				// THE HOST RESUMED
BUS TRAFFIC
      {				
      Suspended=0;                    							// no longer suspended
      }				
} 

void service_irqs(void)
{
Uint8 itest1,itest2;
itest1 = usb_read_config(rEPIRQ);            				// Check the EPIRQ bits
itest2 = usb_read_config(rUSBIRQ);           				// Check the USBIRQ bits
	if(itest1 & bmSUDAVIRQ) 					
	    {					
	     usb_write_config(rEPIRQ,bmSUDAVIRQ);     			// clear the SUDAV IRQ
	     do_SETUP();					
	    }
if(itest1 & bmIN3BAVIRQ)          					// Was an EP3-IN packet just
dispatched to the host?
{					
//do_IN3();
} 					
	if((configval != 0) && (itest2&bmSUSPIRQ))   			// HOST suspended bus for
3 msec
	    {
	    usb_write_config(rUSBIRQ,(bmSUSPIRQ+bmBUSACTIRQ));	// clear the IRQ
and bus activity IRQ
	    Suspended=1;                  						// signal the main loop
	    }					
	if(usb_read_config(rUSBIRQ)& bmURESIRQ)
	    {
	    usb_write_config(rUSBIRQ,bmURESIRQ);      			// clear the IRQ
	    }					
	if(usb_read_config(rUSBIRQ) & bmURESDNIRQ)					
	    {					
	    usb_write_config(rUSBIRQ,bmURESDNIRQ);    			// clear the IRQ bit
	    Suspended=0;                  						// in case we were suspended
	    ENABLE_IRQS                   						// ...because a bus reset clears
the IE bits
	    }
} 


void do_SETUP(void)
{
int i;
	for (i=0;i<8;i++)
		{
		SUD[i]=usb_read_config(rSUDFIFO); 					// got a SETUP packet. Read 8
SETUP bytes
		}							
	switch(SUD[bmRequestType]&0x60)     					// Parse the SETUP packet.For
request type,look only at b6&b5
	    {
	    case 0x00:	std_request();		break;
	    case 0x20:	class_request();	break;  			// just a stub in this program
	    case 0x40:	vendor_request();	break;  			// just a stub in this
program
	    default:	STALL_EP0                   			// unrecognized request type
	    }
}

/*void do_IN3(void)
{
    usb_write_config(rEP3INFIFO,Message[msgidx++]);			// load the keystroke
(3 bytes)
	usb_write_config(rEP3INFIFO,Message[msgidx++]);
	usb_write_config(rEP3INFIFO,Message[msgidx++]);
	if(msgidx >= msglen)                    				// check for message wrap
            {
            msgidx=0;
            }
usb_write_configAS(rEP3INBC,3);									// arm it
}*/


void std_request(void)
{
switch(SUD[bRequest])			
	{
	case	SR_GET_DESCRIPTOR:		send_descriptor();    		break;
	//case	SR_SET_FEATURE:			feature(1);           		break;
	//case	SR_CLEAR_FEATURE:		feature(0);          		break;
	//case	SR_GET_STATUS:			get_status();         		break;
	case	SR_SET_INTERFACE:		set_interface();     		break;
	case	SR_GET_INTERFACE:		get_interface();     	 	break;
	case	SR_GET_CONFIGURATION:   get_configuration(); 		break;
	case	SR_SET_CONFIGURATION:   set_configuration(); 		break;
	case	SR_SET_ADDRESS:         usb_read_configAS(rFNADDR); break;  //
discard return value
	default:STALL_EP0
	}
}


void set_configuration(void)
{
configval=wValueL;           						// Store the config value
	if(configval != 0)                				// If we are configured, 
		SETBIT(rUSBIEN,bmSUSPIE);       			// start looking for SUSPEND
interrupts
usb_read_configAS(rFNADDR);                  		// dummy read to set the
ACKSTAT bit
}

void get_configuration(void)
{
usb_write_config(rEP0FIFO,configval);         		// Send the config value
usb_write_configAS(rEP0BC,1);   
}


void set_interface(void)							// All we accept are Interface=0 and
AlternateSetting=0, otherwise send STALL
{						
Uint8 dumval;						
	if((SUD[wValueL]==0)							// wValueL=Alternate Setting index
	&&(SUD[wIndexL]==0))							// wIndexL=Interface index
	  	dumval=usb_read_configAS(rFNADDR);			// dummy read to set the ACKSTAT
bit
	else STALL_EP0
}


void get_interface(void)							// Check for Interface=0, always report
AlternateSetting=0
{							
	if(SUD[wIndexL]==0)								// wIndexL=Interface index
		{							
		usb_write_config(rEP0FIFO,0);				// AS=0
		usb_write_configAS(rEP0BC,1);				// send one byte, ACKSTAT
		}
	else STALL_EP0
}


void get_status(void)
{
Uint8 testbyte;
testbyte=SUD[bmRequestType];
	switch(testbyte)	
		{
		case 0x80: 										// directed to DEVICE
			usb_write_config(rEP0FIFO,(RWU_enabled+1));	// first byte is 000000rs
where r=enabled for RWU and s=self-powered.
			usb_write_config(rEP0FIFO,0x00);			// second byte is always 0
			usb_write_configAS(rEP0BC,2); 				// load byte count, arm the IN
transfer, ACK the status stage of the CTL transfer
			break; 				
		case 0x81: 										// directed to INTERFACE
			usb_write_config(rEP0FIFO,0x00);			// this one is easy--two zero bytes
			usb_write_config(rEP0FIFO,0x00);		
			usb_write_configAS(rEP0BC,2); 				// load byte count, arm the IN
transfer, ACK the status stage of the CTL transfer
			break; 				
		case 0x82: 										// directed to ENDPOINT
			if(SUD[wIndexL]==0x83)						// We only reported ep3, so it's the only
one the host can stall IN3=83
				{
				usb_write_config(rEP0FIFO,ep3stall);	// first byte is 0000000h where h
is the halt (stall) bit
				usb_write_config(rEP0FIFO,0x00);		// second byte is always 0
				usb_write_configAS(rEP0BC,2); 			// load byte count, arm the IN
transfer, ACK the status stage of the CTL transfer
				break;
				}
			else  STALL_EP0								// Host tried to stall an invalid endpoint (not
3)				
		default:      STALL_EP0							// don't recognize the request
		}
}


// FUNCTION: Set/Get_Feature. Call as feature(1) for Set_Feature or
feature(0) for Clear_Feature.
// There are two set/clear feature requests:
//	To a DEVICE: 	Remote Wakeup (RWU). 
//  	To an ENDPOINT:	Stall (EP3 only for this app)
// 

void feature(Uint8 sc)
{
Uint8 mask;
  if((SUD[bmRequestType]==0x02)						// dir=h->p, recipient = ENDPOINT
  &&  (SUD[wValueL]==0x00)							// wValueL is feature selector, 00 is EP
Halt
  &&  (SUD[wIndexL]==0x83))							// wIndexL is endpoint number IN3=83
      {
      mask=usb_read_config(rEPSTALLS);  			// read existing bits
      if(sc==1)              						// set_feature
        {
        mask += bmSTLEP3IN;       					// Halt EP3IN
        ep3stall=1;					
        }					
      else                        					// clear_feature
        {					
        mask &= ~bmSTLEP3IN;      					// UnHalt EP3IN
        ep3stall=0;
        usb_write_config(rCLRTOGS,bmCTGEP3IN);  	// clear the EP3 data
toggle
        }
      usb_write_config(rEPSTALLS,(mask|bmACKSTAT)); // Don't use
usb_write_configAS for this--directly writing the ACKSTAT bit
      }			
  else if ((SUD[bmRequestType]==0x00)				// dir=h->p, recipient = DEVICE
           &&  (SUD[wValueL]==0x01))				// wValueL is feature selector, 01
is Device_Remote_Wakeup
            {
            RWU_enabled = sc<<1;					// =2 for set, =0 for clear feature.
The shift puts it in the get_status bit position.			
            usb_read_configAS(rFNADDR);				// dummy read to set ACKSTAT
            }
  else STALL_EP0
}


void send_descriptor(void)
{
Uint16 reqlen,sendlen,desclen;
Uint8 *pDdata;										// pointer to ROM Descriptor data to send

// NOTE This function assumes all descriptors are 64 or fewer bytes and can
be sent in a single packet

desclen = 0;													// check for zero as error condition (no case
statements satisfied)
reqlen = SUD[wLengthL] + 256*SUD[wLengthH];						// 16-bit
	switch (SUD[wValueH])										// wValueH is descriptor type
		{
		case  GD_DEVICE:
		          desclen = device_descriptor[0];				// descriptor length
		          pDdata  = device_descriptor;
		          break;	
		case  GD_CONFIGURATION:
		          desclen = configuration_descriptor[2];		// Config descriptor
includes interface, HID, report and ep descriptors
		          pDdata  = configuration_descriptor;
		          break;
		case  GD_STRING:
		          desclen = string_descriptor[SUD[wValueL]][0];	// wValueL=string
index, array[0] is the length
		          pDdata  = string_descriptor[SUD[wValueL]];	// point to first
array element
		          break;
		case CS_INTERFACE:		  
				  if(SUD[wIndexL]==0)    // Interface Number=0. Del EndPoint 2
(interrupci&Atilde;&sup3;n), Communication
                         {
                               
//if(SUD[wLengthL]>configuration_descriptor[9])
                                desclen = configuration_descriptor[9];
                                //else desclen = SUD[wLengthL];
                                pDdata = (Uint8 *)
&configuration_descriptor[9];
                         }
                         else if (SUD[wIndexL]==1)      // Interface
Number=1. Del EndPoint 1 (bulk), Datos
                         {
                               
//if(SUD[wLengthL]>configuration_descriptor[44])
                                 desclen = configuration_descriptor[44];
                                //else desclen = SUD[wLengthL];
                                pDdata = (Uint8 *)
&configuration_descriptor[44];
                         }
                   break;
/*		case  GD_REPORT:
		          desclen = configuration_descriptor[25];
		          pDdata = report_descriptor;
		break;*/
		}														// end switch on descriptor type

	if (desclen!=0)
	{
		sendlen = (reqlen <= desclen) ? reqlen : desclen;
		if(sendlen<=64)											//if just one frame
		{
			usb_write_bytes(rEP0FIFO,sendlen,pDdata);
			usb_write_configAS(rEP0BC,sendlen);
		}
		else													//if sendlen >  64, like your configuration descriptor,
67 byte require 2 frame
		{
			do
			{
			
			sendlen = 64;										//first time i send 64 bytes, because 67 = 64+ 3
			usb_write_bytes(rEP0FIFO,sendlen,pDdata);
			usb_write_config(rEP0BC,sendlen);
			desclen=desclen-sendlen;
			pDdata=pDdata+sendlen;
	
			} while(desclen>64);
			
			sendlen = desclen;
			while(!usb_read_config(rEPIRQ& bmIN0BAVIRQ));
			if(sendlen>0)  usb_write_bytes(rEP0FIFO,sendlen,pDdata);		//3 bytes
more
			usb_write_configAS(rEP0BC,sendlen);
		}
	}
	
		else STALL_EP0  											// none of the descriptor types match
	}



void class_request(void) 
{
switch (SUD[bRequest])
        {
        case SEND_ENCAPSULATED_COMMAND: usb_write_configAS(rEP0BC, 0);     
break; // send_encapsulated_command();  break;
        case GET_ENCAPSULATED_RESPONSE: usb_write_configAS(rEP0BC, 0);     
break; // send_encapsulated_command();  break; //
get_encapsulated_response();  break;

        case SET_COMM_FEATURE:  break;
        case GET_COMM_FEATURE:  break;
        case CLEAR_COMM_FEATURE:break;
        case SET_LINE_CODING:
        {
                usb_write_configAS(rEP0BC, 0);                            

                if(SUD[wLengthL]>0)
                {
                        while(!(usb_read_config(rEPIRQ) & bmOUT0DAVIRQ) &&
SUD[7]<=5) SUD[7]++;
		for(i=0;i<=SUD[wLengthL];)
        usb_read_bytes(rEP0FIFO,SUD[wLengthL],(unsigned char *)&SUD[0]);   
          
                }
        } break;
        case GET_LINE_CODING:
        {
                usb_write_configAS(rEP0BC, 0);                             

        usb_write_bytes(rEP0FIFO,SUD[wLengthL],(unsigned char
*)&SerialConf[0]);
                usb_write_config(rEP0BC, SUD[wLengthL]);
        } break;
        case SET_CONTROL_LINE_STATE:
        {
                if(configval)
                {
                        spi_max3420_init();                                
    
                        if((SUD[wValueL]&0x01)==0x01)
                                PC_DTR=1;
                        if(SUD[wValueL]==0x00)         
                                PC_DTR=0;
                }
                usb_write_configAS(rEP3INBC, 0);
        } break;
        case SEND_BREAK:        break;
        default: STALL_EP0;                                    
        }
}                         

void vendor_request(void)
{
STALL_EP0
}
// ******************** END of ENUMERATION CODE ********************


//****************************************************************************
//max_usb_driver_enum_data.h
//****************************************************************************



// Enumeration tables

Uint8 device_descriptor[]=			// DEVICE Descriptor
						{	0x12,               // bLength = 18d
							0x01,               // bDescriptorType = Device (1)
							0x00,0x02,          // bcdUSB(L/H) USB spec rev (BCD)
							0x02,0x00,0x00,     // bDeviceClass, bDeviceSubClass,
bDeviceProtocol
							0x40,               // bMaxPacketSize0 EP0 is 64 bytes
							0x6A,0x0B,          // idVendor(L/H)--Maxim is 0B6A
							0x46,0x53,          // idProduct(L/H)--5346
							0x00,0x10,          // bcdDevice--1234
							1,2,0,              // iManufacturer, iProduct, iSerialNumber
							0x01				// bNumConfigurations
						};
					
Uint8 configuration_descriptor[]=	// CONFIGURATION Descriptor
						{	0x09,               // bLength
							0x02,               // bDescriptorType = Config
							0x43,0x00,          // wTotalLength(L/H) = 67 bytes
							0x02,               // bNumInterfaces
							0x01,               // bConfigValue
							0x00,               // iConfiguration
							0xE0,				// bmAttributes. b7=1 b6=self-powered b5=RWU supported
							0x01,				// MaxPower is 2 ma
									// INTERFACE Descriptor
							0x09,               // length = 9
							0x04,               // type = IF
							0x00,               // IF #0, Number of the interface -> default
first interface is 0
							0x00,               // bAlternate Setting
							0x01,               // bNum Endpoints
							0x02,               // bInterfaceClass = CDC
							0x02,0x01,          // bInterfaceSubClass, bInterfaceProtocol
							0x00,               // iInterface
									// Header Functional Descriptor (marks beginning of the
concatenated set of Functional Descriptors)
							0x05, 				// bFunctionLength, Descriptor size in bytes --[18]
--[48]
							0x24, 				// bDescriptorType, CS_INTERFACE
							0x00, 				// bDescriptorSubtype, Header Functional Descriptor
							0x10,0x01, 			// bcdCDC, CDC specification release number in BCD
format ([0x10, 0x01])
						
									// Call Management Functional Descriptor
							0x05, 				// bFunctionLength, Descriptor size in bytes
							0x24, 				// bDescriptorType, CS_INTERFACE
							0x01, 				// bDescriptorSubtype, Call Management Functional
Descriptor
							0x03, 				// bmCapabilities, Device doesn't call management itself
(0->3)
							0x01, 				// bDataInterface, Interface used for call management
									// Abstract Control Management Functional Descriptor
							0x04, 				// bDescriptorLength, Descriptor size in bytes
							0x24, 				// bDescriptorType, CS_INTERFACE
							0x02, 				// bDescriptorSubtype, Abstract Control Management
Functional Descriptor
							0x06, 				// bmCapabilities, Support for the GET/SET_LINE_CODING,
BREAK & SET_CONTROL_LINE_STATE
							
									// Union Functional Descriptor
							0x05, 				// bFunctionLength, Descriptor size in bytes
							0x24, 				// bDescriptorType, CS_INTERFACE
							0x06, 				// bDescriptorSubtype, Union Functional Descriptor
							0x00, 				// bMasterInterface, The controlling interface for the
union (bInterfaceNumber of a Communication or Data Class interface in this
configuration)
							0x01, 				// bSlaveInterface0, The controlled interace in the union
(bInterfaceNumber of an interface in this configuration)
									// Endpoint Descriptor 3 --> Data from USB-Maxim-Chip to the
Host-PC
							0x07, 				// bLength
							0x05, 				// bDescriptorType (Endpoint)
							0x83, 				// bEndpointAddress (EP2-IN)
							0x03, 				// bmAttributes (bulk = 2)
							0x40,0x00, 			// wMaxPacketSize (64[0x40])
							0x00, 				// bInterval (0x00)
									// INTERFACE Descriptor
							0x09,            	// length = 9 --[44]
							0x04,            	// type = IF
							0x01,            	// InterFace Number = 1
							0x00,            	// bAlternate Setting
							0x02,            	// bNum Endpoints = 2 (IN&OUT)
							0x0A,            	// bInterfaceClass = A (Data)
							0x00,0x00,       	// bInterfaceSubClass, bInterfaceProtocol
(SubClass ACM=Abstract Control Mode, InterfaceProtocol=V.25ter, common AT
commands)
							0x00,            	// iInterface

									// Endpoint Descriptor 1-OUT --> Data from the Host-PC to
USB-Maxim-Chip
							0x07,          		// bLength
							0x05,          		// bDescriptorType (Endpoint)
							0x01,          		// bEndpointAddress (EP1-OUT) (Adress ranges -->
out: 0x01..0x0F in: 0x81..0x8F
							0x02,          		// bNum Endpoints = 2 (IN&OUT)
							0x40,0x00,     		// wMaxPacketSize (64)
							00,            		// bInterval

									// Endpoint Descriptor EP2-IN
							0x07,          		 // bLength
							0x05,          		 // bDescriptorType (Endpoint)
							0x82,          		 // bEndpointAddress (EP2-IN) (Adress ranges -->
out: 0x01..0x0F in: 0x81..0x8F
							0x02,          		 // bmAttributes (interrupt)
							0x40,0x00,     		 // wMaxPacketSize (64)
							0x02,          		 // bInterval (poll every 2 msec)
						};				



// STRING descriptors. An array of string arrays

Uint8 string_descriptor[][64]= 
						{
								// STRING descriptor 0--Language string
							{
								0x04,							// bLength
								0x03,							// bDescriptorType = string
								0x09,0x04						// wLANGID(L/H) = English-United Sates
							},
								// STRING descriptor 1--Manufacturer ID
							{
								12,								// bLength
								0x03,							// bDescriptorType = string
								'M',0,'a',0,'x',0,'i',0,'m',0 	// text in Unicode
							}, 
								// STRING descriptor 2 - Product ID
							{	
								24,								// bLength
								0x03,							// bDescriptorType = string
								'M',0,'A',0,'X',0,'3',0,'4',0,'2',0,'0',0,'E',0,' ',0,
								'E',0,'n',0,'u',0,'m',0,' ',0,'C',0,'o',0,'d',0,'e',0
							},
		
								// STRING descriptor 3 - Serial Number ID
							{  
								20,								// bLength
								0x03,							// bDescriptorType = string
								'S',0,				
								'/',0,
								'N',0,
								' ',0,
								'3',0,
								'4',0,
								'2',0,
								'0',0,
								'E',0,
							}
						};	
						
const unsigned char SerialConf[]=
						{ 		0x80,0x25,0x00,0x00, // dwDTFRate. Baudrate (2580ex->9600 baud)
								0, // bCharFormat. 1 Stop bit
								0, // bParityType: none
								8, // Number of data bits: 8
						};
						
//****************************************************************************
//max3420e_usb.h
//****************************************************************************


#ifndef MAX3420E_H_
#define MAX3420E_H_

#define SETBIT(reg,val) usb_write_config(reg,(usb_read_config(reg)|val));
#define CLRBIT(reg,val) usb_write_config(reg,(usb_read_config(reg)&~val));

// ************ BUG FIX ************
//#define STALL_EP0 usb_write_config(9,0x23); // Set all three EP0 stall
bits--data stage IN/OUT and status stage
// BUG FIX 2-9-06. The above statement hard-codes the register number to 9,
ignoring the fact that
// the usb_write_config function expects the register numbers to be
pre-shifted 3 bits to put them into the 5 MSB's of
// the SPI command byte. Here is the correction:

#define STALL_EP0 usb_write_config(rEPSTALLS,0x23);	// Set all three EP0
stall bits--data stage IN/OUT and status stage

// ******** END OF BUG FIX**********

#define MSB(word) (BYTE)(((WORD)(word) >> 8) & 0xff)
#define LSB(word) (BYTE)((WORD)(word) & 0xff)

// MAX3420E Registers
#define rEP0FIFO    			0x00
#define rEP1OUTFIFO 			0x08
#define rEP2INFIFO  			0x10
#define rEP3INFIFO  			0x18
#define rSUDFIFO    			0x20
#define rEP0BC      			0x28
#define rEP1OUTBC   			0x30
#define rEP2INBC    			0x38
#define rEP3INBC    			0x40
#define rEPSTALLS   			0x48
#define rCLRTOGS    			0x50
#define rEPIRQ      			0x58
#define rEPIEN      			0x60
#define rUSBIRQ     			0x68
#define rUSBIEN     			0x70
#define rUSBCTL     			0x78
#define rCPUCTL     			0x80
#define rPINCTL     			0x88
#define rRevision   			0x90
#define rFNADDR     			0x98
#define rGPIO       			0xA0

// MAX3420E bit masks for register bits
// R9 EPSTALLS Register
#define bmACKSTAT   			0x40
#define bmSTLSTAT   			0x20
#define bmSTLEP3IN  			0x10
#define bmSTLEP2IN  			0x08
#define bmSTLEP1OUT 			0x04
#define bmSTLEP0OUT 			0x02
#define bmSTLEP0IN  			0x01

// R10 CLRTOGS Register
#define bmEP3DISAB  			0x80
#define bmEP2DISAB  			0x40
#define bmEP1DISAB  			0x20
#define bmCTGEP3IN  			0x10
#define bmCTGEP2IN  			0x08
#define bmCTGEP1OUT 			0x04

// R11 EPIRQ register bits
#define bmSUDAVIRQ  			0x20
#define bmIN3BAVIRQ 			0x10
#define bmIN2BAVIRQ 			0x08
#define bmOUT1DAVIRQ 			0x04
#define bmOUT0DAVIRQ 			0x02
#define bmIN0BAVIRQ 			0x01

// R12 EPIEN register bits
#define bmSUDAVIE   			0x20
#define bmIN3BAVIE  			0x10
#define bmIN2BAVIE  			0x08
#define bmOUT1DAVIE 			0x04
#define bmOUT0DAVIE 			0x02
#define bmIN0BAVIE  			0x01

// R13 USBIRQ register bits
#define bmURESDNIRQ 			0x80
#define bmVBUSIRQ   			0x40
#define bmNOVBUSIRQ 			0x20
#define bmSUSPIRQ   			0x10
#define bmURESIRQ   			0x08
#define bmBUSACTIRQ 			0x04
#define bmRWUDNIRQ  			0x02
#define bmOSCOKIRQ  			0x01

// R14 USBIEN register bits
#define bmURESDNIE  			0x80
#define bmVBUSIE    			0x40
#define bmNOVBUSIE  			0x20
#define bmSUSPIE    			0x10
#define bmURESIE    			0x08
#define bmBUSACTIE  			0x04
#define bmRWUDNIE   			0x02
#define bmOSCOKIE   			0x01

// R15 USBCTL Register
#define bmHOSCSTEN  			0x80
#define bmVBGATE    			0x40
#define bmCHIPRES   			0x20
#define bmPWRDOWN   			0x10
#define bmCONNECT   			0x08
#define bmSIGRWU    			0x04

// R16 CPUCTL Register
#define bmIE        			0x01

// R17 PINCTL Register
#define bmFDUPSPI  				0x10
#define bmINTLEVEL  			0x08
#define bmPOSINT    			0x04
#define bmGPOB      			0x02
#define	bmGPOA      			0x01

//
// GPX[B:A] settings (PINCTL register)
#define gpxOPERATE  			0x00
#define gpxVBDETECT 			0x01
#define gpxBUSACT   			0x02
#define gpxSOF     				0x03

// ************************
// Standard USB Requests
#define SR_GET_STATUS			0x00	// Get Status
#define SR_CLEAR_FEATURE		0x01	// Clear Feature
#define SR_RESERVED				0x02	// Reserved
#define SR_SET_FEATURE			0x03	// Set Feature
#define SR_SET_ADDRESS			0x05	// Set Address
#define SR_GET_DESCRIPTOR		0x06	// Get Descriptor
#define SR_SET_DESCRIPTOR		0x07	// Set Descriptor
#define SR_GET_CONFIGURATION	0x08	// Get Configuration
#define SR_SET_CONFIGURATION	0x09	// Set Configuration
#define SR_GET_INTERFACE		0x0a	// Get Interface
#define SR_SET_INTERFACE		0x0b	// Set Interface

// Get Descriptor codes	
#define GD_DEVICE				0x01	// Get device descriptor: Device
#define GD_CONFIGURATION		0x02	// Get device descriptor: Configuration
#define GD_STRING				0x03	// Get device descriptor: String
#define GD_REPORT	        	0x22	// Get descriptor: Report
#define CS_INTERFACE	        0x24	// Get descriptor: Interface
#define CS_ENDPOINT	        	0x25	// Get descriptor: Endpoint

// SETUP packet offsets
#define bmRequestType   		0
#define	bRequest				1	
#define wValueL					2
#define wValueH					3
#define wIndexL					4
#define wIndexH					5
#define wLengthL				6
#define wLengthH				7	

// CDC bRequest values
#define SEND_ENCAPSULATED_COMMAND   0x00
#define GET_ENCAPSULATED_RESPONSE   0x01
#define SET_COMM_FEATURE   			0x02
#define GET_COMM_FEATURE   			0x03
#define CLEAR_COMM_FEATURE  		0x04
#define SET_LINE_CODING   			0x20
#define GET_LINE_CODING   			0x21
#define SET_CONTROL_LINE_STATE  	0x22
#define SEND_BREAK   				0x23

#endif /* MAX3420E_H_ */

//***************************************************************************
//***************************************************************************

	   
					
---------------------------------------		
Posted through http://www.EmbeddedRelated.com

The 2024 Embedded Online Conference