EmbDev.net

Forum: FPGA, VHDL & Verilog max3420e usb Controller


Author: Rockyy Sharma (rockyy)
Posted on:

Rate this post
0 useful
not useful
Hello,

Did any one used max3420e USB controller with the FPGA.
Actually i am developing a microblaze sdk for max3420e using SPI pin 
Configuration.
But I am not getting any success in my task.If any one have any idea 
please share.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Rockyy Sharma wrote:
> But I am not getting any success in my task.I
And WHAT is the problem? Which SPI interface do you use? Does the SPI 
interface run? Do you get any information back from the MAX?

Author: Rockyy Sharma (rockyy)
Posted on:

Rate this post
0 useful
not useful
No I am not getting any information back from max.And my Pc is not able 
to detect MAX.I have a code which contain three files the code is from 
mAX3420e but I have update according to our FPGA.

Actually I have a board where max3420e is connected with FPGA.I  have 
developed a(controller) in microblaze and configured the spi pin for 
FPGA and Max3420e.we flashed the code to our FPGA but  nothing is 
happing from max3420e towards PC side or vice versa.
/*
 * EnumApp_enum_data.h
 *
 *  Created on: Jul 16, 2014
 *      Author: rnv5kor
 */


// EnumApp_enum_data.h
// Enumeration tables & HID keyboard data
//
const unsigned char device_descriptor[]=  // DEVICE Descriptor
        {0x12,             // bLength = 18d
        0x01,      // bDescriptorType = Device (1)
        0x00,0x01,    // bcdUSB(L/H) USB spec rev (BCD)
  0x00,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
  0x34,0x12,    // bcdDevice--1234
  1,2,3,      // iManufacturer, iProduct, iSerialNumber
  1};      // bNumConfigurations

const unsigned char configuration_descriptor[]=  // CONFIGURATION Descriptor
  {0x09,      // bLength
  0x02,      // bDescriptorType = Config
  0x22,0x00,    // wTotalLength(L/H) = 34 bytes
  0x02,      // bNumInterfaces
  0x01,      // bConfigValue
  0x00,      // iConfiguration
  0xA0,      // bmAttributes. b7=1 b6= no self-powered b5=RWU supported
  0xFA,      // MaxPower is 2 ma
// INTERFACE Descriptor
  0x09, // length = 9
  0x04, // type = IF
  0x00, // InterFace Number = 0
  0x00, // bAlternate Setting
  0x01, // bNum Endpoints = 1 IN
  0x02, // bInterfaceClass = 2 Communication
  0x02, // bInterfaceSubClass = 2
  0x01, // bInterfaceProtocol =1 (SubClass ACM=Abstract Control Mode, InterfaceProtocol=V.25ter, common AT commands)
  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 (2->6)

  // 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)

  ///////////****************** Call Management Functional Descriptor*****************

  // Endpoint Descriptor EP3-IN
  0x07, // bLength
  0x05, // bDescriptorType (Endpoint)
  0x83, // bEndpointAddress (EP3 IN)
  0x03, // bmAttributes (interrupt = 3)
  0x40,0x00, // wMaxPacketSize (64[0x0040])
  0x02, // bInterval, Maximum latency (0x02)

  // 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 EP1-OUT
  0x07, // bLength
  0x05, // bDescriptorType (Endpoint)
  0x01, // bEndpointAddress (EP1-OUT)
  0x02, // bmAttributes (bulk = 2)
  0x40,0x00, // wMaxPacketSize (64[0x40])
  0x00, // bInterval (0x00)

  // Endpoint Descriptor EP2-IN
  0x07, // bLength
  0x05, // bDescriptorType (Endpoint)
  0x82, // bEndpointAddress (EP2-IN)
  0x02, // bmAttributes (bulk = 2)
  0x40,0x00, // wMaxPacketSize (64[0x40])
  0x00, // bInterval (0x00)
  };

// STRING descriptors. An array of string arrays

const unsigned char 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
{
34, // bLength (0x2C para 23 (incluyendo tamaño y tipo??)
0x03, // bDescriptorType = string
'x',0,
'x',0,
'x',0,
'x',0,
' ',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,// text in Unicode
},
// STRING descriptor 2 - Product ID
{ 8, // bLength
0x03, // bDescriptorType = string
'X',0,
'X',0,
'X',0,
},

// STRING descriptor 3 - Serial Number ID
{ 8, // bLength
0x03, // bDescriptorType = string
'X',0,
'X',0,
'X',0,
}};


const unsigned char SerialConf[]=
{
0x00,0xE8,0x03,0x00, // dwDTFRate. Baudrate (9600hex->38400 baud)
0, // bCharFormat. 1 Stop bit
0, // bParityType: none
8, // Number of data bits: 8
};
// MAX3420E_BF1.h
// Macros
// See the single bug fix below.
//
// For active-high lights attached to MAX3420E GP-Output pins.



#define L0_OFF wreg(rGPIO,(rreg(rGPIO) & 0xFE));
#define L0_ON wreg(rGPIO,(rreg(rGPIO) | 0x01));
#define L1_OFF wreg(rGPIO,(rreg(rGPIO) & 0xFD));
#define L1_ON wreg(rGPIO,(rreg(rGPIO) | 0x02));
#define L2_OFF wreg(rGPIO,(rreg(rGPIO) & 0xFB));
#define L2_ON wreg(rGPIO,(rreg(rGPIO) | 0x04));
#define L3_OFF wreg(rGPIO,(rreg(rGPIO) & 0xF7));
#define L3_ON wreg(rGPIO,(rreg(rGPIO) | 0x08));
#define L0_BLINK wreg(rGPIO,(rreg(rGPIO) ^ 0x01));
#define L1_BLINK wreg(rGPIO,(rreg(rGPIO) ^ 0x02));
#define L2_BLINK wreg(rGPIO,(rreg(rGPIO) ^ 0x04));
#define L3_BLINK wreg(rGPIO,(rreg(rGPIO) ^ 0x08));

#define SETBIT(reg,val) Max_wreg(reg,(Max_rreg(reg)|val));
#define CLRBIT(reg,val) Max_wreg(reg,(Max_rreg(reg)&~val));

// ************ BUG FIX ************
//#define STALL_EP0 wreg(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 wreg 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 Max_wreg(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    0<<3
#define rEP1OUTFIFO 1<<3
#define rEP2INFIFO  2<<3
#define rEP3INFIFO  3<<3
#define rSUDFIFO    4<<3
#define rEP0BC      5<<3
#define rEP1OUTBC   6<<3
#define rEP2INBC    7<<3
#define rEP3INBC    8<<3
#define rEPSTALLS   9<<3
#define rCLRTOGS    10<<3
#define rEPIRQ      11<<3
#define rEPIEN      12<<3
#define rUSBIRQ     13<<3
#define rUSBIEN     14<<3
#define rUSBCTL     15<<3
#define rCPUCTL     16<<3
#define rPINCTL     17<<3
#define rRevision   18<<3
#define rFNADDR     19<<3
#define rGPIO       20<<3




// 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


/*
 * MAX3420E_BF1.c
 *
 *  Created on: Jul 10, 2014
 *      Author: rnv5kor
 */



#include "xspi.h"
#include "xspi_l.h"
#include "xparameters.h"
#include "MAX3420E_BF1.h"
#include <stdio.h>
#include "platform.h"
#include "xbasic_types.h"
#include "time.h"
#include "EnumApp_enum_data.h"


typedef unsigned char BYTE;     // these save typing
typedef unsigned long uint32;
typedef unsigned long uint16;
typedef unsigned long uint8;
typedef unsigned short WORD;

#define TWENTY_MSEC 14200           // adjust this constant for 20 msec button checks
#define BLINKTIME 25                // blink every 500 msec

//Global variables
BYTE SUD[8];    // Local copy of the 8 setup data read from the MAX3420E SUDFIFO
BYTE msgidx,msglen;  // Text string in EnumApp_enum_data.h--index and length
BYTE configval;    // Set/Get_Configuration value
BYTE ep3stall;    // Flag for EP3 Stall, set by Set_Feature, reported back in Get_Status
BYTE interfacenum;      // Set/Get interface value
BYTE inhibit_send;  // Flag for the keyboard character send routine
BYTE RWU_enabled;       // Set by Set/Clear_Feature RWU request, sent back for Get_Status-RWU
BYTE Suspended;         // Tells the main loop to look for host resume and RWU pushbutton
WORD msec_timer;        // Count off time in the main loop
WORD blinktimer;        // Count milliseconds to blink the "loop active" light
BYTE send3zeros;        // EP3-IN function uses this to send HID (key up) codes between keystrokes

uint8 test_1,test_2,test_3,data;




static XSpi  mySPI;   /* The instance of the SPI device */
static XSpi SPI_SCK;
uint32  NumBytesSent = 0;
uint32  NumBytesRcvd = 0;
int PC_DTR=0;
#define ENABLE_IRQS Max_wreg(rEPIEN,(bmSUDAVIE+bmIN3BAVIE)); Max_wreg(rUSBIEN,(bmURESIE+bmURESDNIE));
// Note: the SUSPEND IRQ will be enabled later, when the device is configured.
// This prevents repeated SUSPEND IRQ's


extern void Max_wreg(BYTE r,BYTE v) ;
extern void Xps_SpiInit(void);
extern void Xps_Spi_Max_Transmit(void);
extern void IntialiseMax3420E(void);
extern void MAX_Reset(void);
extern BYTE Max_rreg(BYTE reg);
extern void Max_wregAS(BYTE reg, BYTE val);
extern BYTE Max_rregAS(BYTE reg);
extern void Max_readbytes(BYTE reg, BYTE N, BYTE *p);
extern void Max_writebytes(BYTE reg, BYTE N, BYTE *p);
BYTE MAX_Int_Pending(void);     // Poll the MAX3420E INT pin (set for active low level)

// USB functions
void std_request(void);
void class_request(void);
void vendor_request(void);
void send_descriptor(void);
void send_keystroke(BYTE);
void feature(BYTE);
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);      // Handle a USB SETUP transfer
void do_IN3(void);        // Send keyboard characters over Endpoint 3-IN
void check_for_resume(void);
void service_irqs(void);
void initialize_MAX(void);


void check_for_resume(void)
{

  if(Max_rreg(rUSBIRQ) & bmBUSACTIRQ) // THE HOST RESUMEDBUS TRAFFIC
  {
    Suspended=0; // no longer suspended
  }
}
//

void service_irqs(void)
{
  BYTE itest1,itest2;
  itest1 = Max_rreg(rEPIRQ);            // Check the EPIRQ bits
  itest2 = Max_rreg(rUSBIRQ);           // Check the USBIRQ bits


  if(itest1 & bmSUDAVIRQ)
  {
    Max_wreg(rEPIRQ,bmSUDAVIRQ);     // clear the SUDAV IRQ
    do_SETUP();
  }
  if(itest1 & bmIN3BAVIRQ)          // Was an EP3-IN packet just dispatched to the host?
  {
    //do_IN3();                     // Yes--load another keystroke and arm the endpoint
  }                             // NOTE: don't clear the IN3BAVIRQ bit here--loading the EP3-IN byte
  // count register in the do_IN3() function does it.
  if((configval != 0) && (itest2&bmSUSPIRQ))   // HOST suspended bus for 3 msec
  {
    Max_wreg(rUSBIRQ,(bmSUSPIRQ+bmBUSACTIRQ));  // clear the IRQ and bus activity IRQ
    Suspended=1;                  // signal the main loop
  }
  if(Max_rreg(rUSBIRQ)& bmURESIRQ)
  {
    Max_wreg(rUSBIRQ,bmURESIRQ);      // clear the IRQ
  }
  if(Max_rreg(rUSBIRQ) & bmURESDNIRQ)
  {
    Max_wreg(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]= Max_rreg(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 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:         Max_rregAS(rFNADDR);      break;  // discard return value
  default:  STALL_EP0
  }
}

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

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

//**********************
void set_interface(void)  // All we accept are Interface=0 and AlternateSetting=0, otherwise send STALL
{
  BYTE dumval;
  if((SUD[wValueL]==0)    // wValueL=Alternate Setting index
      &&(SUD[wIndexL]==0))    // wIndexL=Interface index
    dumval = Max_rregAS(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
  {
    Max_wreg(rEP0FIFO,0);    // AS=0
    Max_wregAS(rEP0BC,1);    // send one byte, ACKSTAT
  }
  else STALL_EP0
}

//*******************
void get_status(void)
{
  BYTE testbyte;
  testbyte=SUD[bmRequestType];
  switch(testbyte)
  {
  case 0x80:       // directed to DEVICE
    Max_wreg(rEP0FIFO,(RWU_enabled+1));  // first byte is 000000rs where r=enabled for RWU and s=self-powered.
    Max_wreg(rEP0FIFO,0x00);    // second byte is always 0
    Max_wregAS(rEP0BC,2);     // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer
    break;
  case 0x81:       // directed to INTERFACE
    Max_wreg(rEP0FIFO,0x00);    // this one is easy--two zero bytes
    Max_wreg(rEP0FIFO,0x00);
    Max_wregAS(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
    {
      Max_wreg(rEP0FIFO,ep3stall);  // first byte is 0000000h where h is the halt (stall) bit
      Max_wreg(rEP0FIFO,0x00);    // second byte is always 0
      Max_wregAS(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(BYTE sc)
{
  BYTE 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= Max_rreg(rEPSTALLS);   // read existing bits
    if(sc==1)               // set_feature
    {
      mask += bmSTLEP3IN;       // Halt EP3IN
      ep3stall=1;
    }
    else                        // clear_feature
    {
      mask &= ~bmSTLEP3IN;      // UnHalt EP3IN
      ep3stall=0;
      Max_wreg(rCLRTOGS,bmCTGEP3IN);  // clear the EP3 data toggle
    }
    Max_wreg(rEPSTALLS,(mask|bmACKSTAT)); // Don't use wregAS 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.
    Max_rregAS(rFNADDR);    // dummy read to set ACKSTAT
  }
  else STALL_EP0
}

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

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

  desclen = 0; // check for zero as error condition (no casestatements 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 descriptorincludes interface, HID, report and ep descriptors
    pDdata = configuration_descriptor;
    break;
  case GD_STRING:
    desclen = string_descriptor[SUD[wValueL]][0]; // wValueL=stringindex, array[0] is the length
    pDdata = string_descriptor[SUD[wValueL]]; // point to firstarray element
    break;
  case CS_INTERFACE:
    if(SUD[wIndexL]==0) // Interface Number=0. Del EndPoint 2(interrupción), Communication
    {
      //if(SUD[wLengthL]>configuration_descriptor[9])
      desclen = configuration_descriptor[9];
      //else desclen = SUD[wLengthL];
      pDdata = (BYTE *)&configuration_descriptor[9];
    }
    else if (SUD[wIndexL]==1) // InterfaceNumber=1. Del EndPoint 1 (bulk), Datos
    {
      //if(SUD[wLengthL]>configuration_descriptor[44])
      desclen = configuration_descriptor[44];
      //else desclen = SUD[wLengthL];
      pDdata = (BYTE *)&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
    {
      Max_writebytes(rEP0FIFO,sendlen,pDdata);
      Max_wregAS(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
        Max_writebytes(rEP0FIFO,sendlen,pDdata);
        Max_wreg(rEP0BC,sendlen);
        desclen=desclen-sendlen;
        pDdata=pDdata+sendlen;

      } while(desclen>64);

      sendlen = desclen;
      while(!Max_rreg(rEPIRQ& bmIN0BAVIRQ));
      if(sendlen>0) Max_writebytes(rEP0FIFO,sendlen,pDdata); //3 bytesmore
      Max_wregAS(rEP0BC,sendlen);
    }
  }

  else STALL_EP0 // none of the descriptor types match
}

void class_request(void)
{
  int i;
  switch (SUD[bRequest])
  {
  case SEND_ENCAPSULATED_COMMAND: Max_wregAS(rEP0BC, 0); break; // send_encapsulated_command(); break;
  case GET_ENCAPSULATED_RESPONSE: Max_wregAS(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:
  {
    Max_wregAS(rEP0BC, 0);
    if(SUD[wLengthL]>0)
    {
      while(!(Max_rreg(rEPIRQ) & bmOUT0DAVIRQ) &&SUD[7]<=5) SUD[7]++;
      for(i=0;i<=SUD[wLengthL];)
        Max_readbytes(rEP0FIFO,SUD[wLengthL],(unsigned char *)&SUD[0]);
    }
  } break;
  case GET_LINE_CODING:
  {
    Max_wregAS(rEP0BC, 0);
    Max_writebytes(rEP0FIFO,SUD[wLengthL],(unsigned char*)&SerialConf[0]);
    Max_wreg(rEP0BC, SUD[wLengthL]);
  } break;
  case SET_CONTROL_LINE_STATE:
  {
    if(configval)
    {
      //Xps_SpiInit();
      if((SUD[wValueL]&0x01)==0x01)
        PC_DTR=1;
      if(SUD[wValueL]==0x00)
        PC_DTR=0;
    }
    Max_wregAS(rEP3INBC, 0);
  } break;
  case SEND_BREAK: break;
  default: STALL_EP0;
  }
}

void vendor_request(void)
{
  STALL_EP0
}



extern void Xps_SpiInit()   // Parmeters need to be Intialized
{

  XStatus status = XST_SUCCESS;

  status =      XSpi_Initialize(&mySPI, XPAR_SPI_0_DEVICE_ID );//XPAR_SPI_0_DEVICE_ID);

  switch(status)
  {
  case XST_SUCCESS: print("Status: Erfolgreich initialisiert\n\r");
  break;
  case XST_DEVICE_IS_STARTED: print("Status: Device is started\n\r");
  break;
  case XST_DEVICE_NOT_FOUND: print("Status: Device not found\n\r");
  break;

  }

  status =   XSpi_SetOptions(&mySPI, XSP_MASTER_OPTION );//XSP_MANUAL_SSELECT_OPTION


  //status   =  XSpi_SetSlaveSelect(&mySPI, 1);

  //status =   XSpi_SetOptions(&mySPI, XSP_CLK_ACTIVE_LOW_OPTION);


  status =    XSpi_Start(&mySPI);


}

extern void Xps_Spi_Max_Transmit(void)
{

}

extern void IntialiseMax3420E(void)
{

  ep3stall=0;      // EP3 inintially un-halted (no stall) (CH9 testing)
  msgidx = 0;      // start of KB Message[]
  inhibit_send = 0x01;    // 0 means send, 1 means inhibit sending
  send3zeros=1;
  msec_timer=0;
  blinktimer=0;
  // software flags
  configval=0;                    // at pwr on OR bus reset we're unconfigured
  Suspended=0;
  RWU_enabled=0;                  // Set by host Set_Feature(enable RWU) request
  //
     BYTE dum;
  //Xps_SpiInit();

  Max_wreg(rPINCTL,(bmFDUPSPI+bmINTLEVEL+gpxSOF)); // MX3420: SPI=full-duplex, INT=neg level, GPX=SOF

  data = Max_rreg(rPINCTL);

  //Max_wreg(rPINCTL,bmFDUPSPI);    // MAX3420: SPI=full-duplex
  Max_wreg(rUSBCTL,bmCHIPRES);    // reset the MAX3420E
  Max_wreg(rUSBCTL,0);// remove the reset

  //MAX_Reset();
  //Max_wreg(rGPIO,0x01);                   // lites off (Active HIGH)
  // This is a self-powered design, so the host could turn off Vbus while we are powered.
  // Therefore set the VBGATE bit to have the MAX3420E automatically disconnect the D+
  // pullup resistor in the absense of Vbus. Note: the VBCOMP pin must be connected to Vbus
  // or pulled high for this code to work--a low on VBCOMP will prevent USB connection.
  Max_wreg(rUSBCTL, (bmCONNECT));

  //ENABLE_IRQS;

  //Max_wreg(rCPUCTL,bmIE);                 // Enable the INT pin
}

extern void MAX_Reset(void)
{

  BYTE dum;
  Max_wreg(rUSBCTL,0x20);  // chip reset
  Max_wreg(rUSBCTL,0x00);  // remove the reset
  do                  // Chip reset stops the oscillator. Wait for it to stabilize.
  {
    dum = Max_rreg(rUSBIRQ);
    dum &= bmOSCOKIRQ;
  }
  while (dum==0);

}

extern void  Max_wreg(BYTE reg,BYTE val)              // write a MAX3420E register byte
{
  u8 spiWCmd = 0;



  XStatus status = XST_SUCCESS;

  status   =    XSpi_IntrGlobalDisable(&mySPI);

  status   =    XSpi_SetSlaveSelect(&mySPI, 0);

  spiWCmd  =    reg + 2;

  status   =    XSpi_Transfer(&mySPI,&spiWCmd,NULL,1);

  spiWCmd  =    val;

  status   =    XSpi_Transfer(&mySPI,&spiWCmd,NULL,1);


  switch(status)
  {
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
  break;

  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
  break;

  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
  break;

  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
  break;
  };

  status =    XSpi_SetSlaveSelect(&mySPI, 1);

  //status =    XSpi_IntrGlobalEnable(&mySPI);
}

extern BYTE Max_rreg(BYTE reg)
{
  BYTE dum;
  u8 spiRCmd = 0;

  XStatus status = XST_SUCCESS;

  status =    XSpi_IntrGlobalDisable(&mySPI);

  status = XSpi_SetSlaveSelect(&mySPI, 0);

  spiRCmd  = reg;

  status = XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,1);

  dum =  spiRCmd;

  spiRCmd = 0x00;

  status = XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,1);

  switch(status)
  {
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
  break;

  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
  break;

  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
  break;

  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
  break;
  };

  status = XSpi_SetSlaveSelect(&mySPI,1);

//  status =    XSpi_IntrGlobalEnable(&mySPI);

  return dum;
}

// Write a MAX3410E register with the "ACK STATUS" bit set in the command byte
extern void Max_wregAS(BYTE reg, BYTE val)
{
  u8 spiWCmd = 0;

  XStatus Status = XST_SUCCESS;

  Status = XSpi_SetSlaveSelect(&mySPI, 0);                   // Set SS# low

  spiWCmd = reg+3;             // reg number with DIR=1 (write) and ACKSTAT=1

  Status = XSpi_Transfer(&mySPI,&spiWCmd,NULL,1);

  spiWCmd = val;               // send the data

  Status = XSpi_Transfer(&mySPI,&spiWCmd,NULL,1);


  switch(Status)
  {
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
  break;

  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
  break;

  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
  break;

  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
  break;
  };

  Status = XSpi_SetSlaveSelect(&mySPI, 1);
}

// Read a byte (as rreg), but also set the AckStat bit in the command byte.
extern BYTE Max_rregAS(BYTE reg)
{
  BYTE dum;
  u8 spiRCmd = 0;

  XStatus Status = XST_SUCCESS;

  XSpi_SetSlaveSelect(&mySPI, 0);

  spiRCmd  = reg +1;

  XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,2);

  dum =  spiRCmd;
  spiRCmd = 0xFF;

  XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,2);

  switch(Status)
  {
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
  break;

  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
  break;

  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
  break;

  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
  break;
  };

  XSpi_SetSlaveSelect(&mySPI,1);

  return dum;
}

extern void Max_readbytes(BYTE reg, BYTE N, BYTE *p)
{
  BYTE j;
  u8 spiRCmd = 0;

  XStatus Status = XST_SUCCESS;

  Status = XSpi_SetSlaveSelect(&mySPI, 0);

  spiRCmd  = reg +1;                            // write bit b1=0 to command a read operation

  Status = XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,N);

  j = spiRCmd;                 // NECESSARY TO RE-ENABLE THE INPUT BUFFER in BYTE MODE

  for(j=0; j<N; j++)
  {
    spiRCmd = 0x00;            // dummy value to get the next read byte
    Status = XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,N);   // loop if data still being sent
    *p = spiRCmd;              // store it in the data array
    p++;                    // bump the pointer
  }

  switch(Status)
  {
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
  break;

  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
  break;

  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
  break;

  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
  break;
  };

  Status = XSpi_SetSlaveSelect(&mySPI, 1);
}
void Max_writebytes(BYTE reg, BYTE N, BYTE *p)
{
  BYTE j,spiWCmd;
  // uint32 spiWCmd = 0;

  XStatus Status = XST_SUCCESS;

  Status = XSpi_SetSlaveSelect(&mySPI, 0);

  spiWCmd = reg+2;             // write bit b1=1 to command a write operation

  Status = XSpi_Transfer(&mySPI,&spiWCmd,NULL,N);

  for(j=0; j<N; j++)
  {
    spiWCmd = *p;                // write the array value
    Status = XSpi_Transfer(&mySPI,&spiWCmd,NULL,N);
    p++;                    // bump the pointer
  }

  switch(Status)
  {
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
  break;

  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
  break;

  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
  break;

  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
  break;
  };

  Status = XSpi_SetSlaveSelect(&mySPI, 1);
}

BYTE MAX_Int_Pending(void)
{
  return (BYTE)((0xA1&0x01)==0);
}

int main()
{
  init_platform();

  Xps_SpiInit();

  IntialiseMax3420E();

  test_1 = Max_rreg(rFNADDR);
  test_2 = Max_rreg(rEPIRQ);
  test_3 = Max_rreg(rUSBIRQ);

  while(1)    // endless loop
  {
    if(Suspended)
      check_for_resume();

    service_irqs();

    msec_timer++;

    if(msec_timer==TWENTY_MSEC)
    {
      msec_timer=0;
      if((Max_rreg(rGPIO) & 0x10) == 0) // Check the pushbutton on GPI-0
      {
        inhibit_send = 0x00;      // Tell the "do_IN3" function to send the text string
        //L0_ON                     // Turn on the SEND light
      }
      blinktimer++;                 // blink the loop active light every half second
      if(blinktimer==BLINKTIME)
      {
        blinktimer=0;
        //L3_BLINK
      }
    }// msec_timer==ONE_MSEC
  } // while(1)

  return 0;
}


Author: Daniel (Guest)
Posted on:

Rate this post
0 useful
not useful
Rockyy Sharma wrote:
> we flashed the code to our FPGA but  nothing is
> happing from max3420e towards PC side or vice versa.
How did you check this?
Do you have a scope to check the USB signals?
Do you have a logic analyzer (external or internal) to debug you FPGA 
design?

Daniel

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.