EmbDev.net

Forum: FPGA, VHDL & Verilog max3420e usb Controller


von Rockyy S. (rockyy)


Rate this post
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.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
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?

von Rockyy S. (rockyy)


Rate this post
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.
1
/*
2
 * EnumApp_enum_data.h
3
 *
4
 *  Created on: Jul 16, 2014
5
 *      Author: rnv5kor
6
 */
7
8
9
// EnumApp_enum_data.h
10
// Enumeration tables & HID keyboard data
11
//
12
const unsigned char device_descriptor[]=  // DEVICE Descriptor
13
        {0x12,             // bLength = 18d
14
        0x01,      // bDescriptorType = Device (1)
15
        0x00,0x01,    // bcdUSB(L/H) USB spec rev (BCD)
16
  0x00,0x00,0x00,   // bDeviceClass, bDeviceSubClass, bDeviceProtocol
17
  0x40,      // bMaxPacketSize0 EP0 is 64 bytes
18
  0x6A,0x0B,    // idVendor(L/H)--Maxim is 0B6A
19
  0x46,0x53,    // idProduct(L/H)--5346
20
  0x34,0x12,    // bcdDevice--1234
21
  1,2,3,      // iManufacturer, iProduct, iSerialNumber
22
  1};      // bNumConfigurations
23
24
const unsigned char configuration_descriptor[]=  // CONFIGURATION Descriptor
25
  {0x09,      // bLength
26
  0x02,      // bDescriptorType = Config
27
  0x22,0x00,    // wTotalLength(L/H) = 34 bytes
28
  0x02,      // bNumInterfaces
29
  0x01,      // bConfigValue
30
  0x00,      // iConfiguration
31
  0xA0,      // bmAttributes. b7=1 b6= no self-powered b5=RWU supported
32
  0xFA,      // MaxPower is 2 ma
33
// INTERFACE Descriptor
34
  0x09, // length = 9
35
  0x04, // type = IF
36
  0x00, // InterFace Number = 0
37
  0x00, // bAlternate Setting
38
  0x01, // bNum Endpoints = 1 IN
39
  0x02, // bInterfaceClass = 2 Communication
40
  0x02, // bInterfaceSubClass = 2
41
  0x01, // bInterfaceProtocol =1 (SubClass ACM=Abstract Control Mode, InterfaceProtocol=V.25ter, common AT commands)
42
  0x00, // iInterface
43
44
  // Header Functional Descriptor (marks beginning of the concatenated set of Functional Descriptors)
45
  0x05, // bFunctionLength, Descriptor size in bytes --[18] --[48]
46
  0x24, // bDescriptorType, CS_INTERFACE
47
  0x00, // bDescriptorSubtype, Header Functional Descriptor
48
  0x10,0x01, // bcdCDC, CDC specification release number in BCD format ([0x10, 0x01])
49
50
  // Call Management Functional Descriptor
51
  0x05, // bFunctionLength, Descriptor size in bytes
52
  0x24, // bDescriptorType, CS_INTERFACE
53
  0x01, // bDescriptorSubtype, Call Management Functional Descriptor
54
  0x03, // bmCapabilities, Device doesn't call management itself (0->3)
55
  0x01, // bDataInterface, Interface used for call management
56
57
  // Abstract Control Management Functional Descriptor
58
  0x04, // bDescriptorLength, Descriptor size in bytes
59
  0x24, // bDescriptorType, CS_INTERFACE
60
  0x02, // bDescriptorSubtype, Abstract Control Management Functional Descriptor
61
  0x06, // bmCapabilities, Support for the GET/SET_LINE_CODING, BREAK & SET_CONTROL_LINE_STATE (2->6)
62
63
  // Union Functional Descriptor
64
  0x05, // bFunctionLength, Descriptor size in bytes
65
  0x24, // bDescriptorType, CS_INTERFACE
66
  0x06, // bDescriptorSubtype, Union Functional Descriptor
67
  0x00, // bMasterInterface, The controlling interface for the union (bInterfaceNumber of a Communication or Data Class interface in this configuration)
68
  0x01, // bSlaveInterface0, The controlled interace in the union (bInterfaceNumber of an interface in this configuration)
69
70
  ///////////****************** Call Management Functional Descriptor*****************
71
72
  // Endpoint Descriptor EP3-IN
73
  0x07, // bLength
74
  0x05, // bDescriptorType (Endpoint)
75
  0x83, // bEndpointAddress (EP3 IN)
76
  0x03, // bmAttributes (interrupt = 3)
77
  0x40,0x00, // wMaxPacketSize (64[0x0040])
78
  0x02, // bInterval, Maximum latency (0x02)
79
80
  // INTERFACE Descriptor
81
  0x09, // length = 9 --[44]
82
  0x04, // type = IF
83
  0x01, // InterFace Number = 1
84
  0x00, // bAlternate Setting
85
  0x02, // bNum Endpoints = 2 (IN&OUT)
86
  0x0A, // bInterfaceClass = A (Data)
87
  0x00,0x00, // bInterfaceSubClass, bInterfaceProtocol (SubClass ACM=Abstract Control Mode, InterfaceProtocol=V.25ter, common AT commands)
88
  0x00, // iInterface
89
90
  // Endpoint Descriptor EP1-OUT
91
  0x07, // bLength
92
  0x05, // bDescriptorType (Endpoint)
93
  0x01, // bEndpointAddress (EP1-OUT)
94
  0x02, // bmAttributes (bulk = 2)
95
  0x40,0x00, // wMaxPacketSize (64[0x40])
96
  0x00, // bInterval (0x00)
97
98
  // Endpoint Descriptor EP2-IN
99
  0x07, // bLength
100
  0x05, // bDescriptorType (Endpoint)
101
  0x82, // bEndpointAddress (EP2-IN)
102
  0x02, // bmAttributes (bulk = 2)
103
  0x40,0x00, // wMaxPacketSize (64[0x40])
104
  0x00, // bInterval (0x00)
105
  };
106
107
// STRING descriptors. An array of string arrays
108
109
const unsigned char string_descriptor[][64]= {
110
// STRING descriptor 0--Language string
111
{
112
0x04, // bLength
113
0x03, // bDescriptorType = string
114
0x09,0x04 // wLANGID(L/H) = English-United Sates
115
},
116
// STRING descriptor 1--Manufacturer ID
117
{
118
34, // bLength (0x2C para 23 (incluyendo tamaño y tipo??)
119
0x03, // bDescriptorType = string
120
'x',0,
121
'x',0,
122
'x',0,
123
'x',0,
124
' ',0,
125
'x',0,
126
'x',0,
127
'x',0,
128
'x',0,
129
'x',0,
130
'x',0,
131
'x',0,
132
'x',0,
133
'x',0,
134
'x',0,
135
'x',0,// text in Unicode
136
},
137
// STRING descriptor 2 - Product ID
138
{ 8, // bLength
139
0x03, // bDescriptorType = string
140
'X',0,
141
'X',0,
142
'X',0,
143
},
144
145
// STRING descriptor 3 - Serial Number ID
146
{ 8, // bLength
147
0x03, // bDescriptorType = string
148
'X',0,
149
'X',0,
150
'X',0,
151
}};
152
153
154
const unsigned char SerialConf[]=
155
{
156
0x00,0xE8,0x03,0x00, // dwDTFRate. Baudrate (9600hex->38400 baud)
157
0, // bCharFormat. 1 Stop bit
158
0, // bParityType: none
159
8, // Number of data bits: 8
160
};
1
// MAX3420E_BF1.h
2
// Macros
3
// See the single bug fix below.
4
//
5
// For active-high lights attached to MAX3420E GP-Output pins.
6
7
8
9
#define L0_OFF wreg(rGPIO,(rreg(rGPIO) & 0xFE));
10
#define L0_ON wreg(rGPIO,(rreg(rGPIO) | 0x01));
11
#define L1_OFF wreg(rGPIO,(rreg(rGPIO) & 0xFD));
12
#define L1_ON wreg(rGPIO,(rreg(rGPIO) | 0x02));
13
#define L2_OFF wreg(rGPIO,(rreg(rGPIO) & 0xFB));
14
#define L2_ON wreg(rGPIO,(rreg(rGPIO) | 0x04));
15
#define L3_OFF wreg(rGPIO,(rreg(rGPIO) & 0xF7));
16
#define L3_ON wreg(rGPIO,(rreg(rGPIO) | 0x08));
17
#define L0_BLINK wreg(rGPIO,(rreg(rGPIO) ^ 0x01));
18
#define L1_BLINK wreg(rGPIO,(rreg(rGPIO) ^ 0x02));
19
#define L2_BLINK wreg(rGPIO,(rreg(rGPIO) ^ 0x04));
20
#define L3_BLINK wreg(rGPIO,(rreg(rGPIO) ^ 0x08));
21
22
#define SETBIT(reg,val) Max_wreg(reg,(Max_rreg(reg)|val));
23
#define CLRBIT(reg,val) Max_wreg(reg,(Max_rreg(reg)&~val));
24
25
// ************ BUG FIX ************
26
//#define STALL_EP0 wreg(9,0x23); // Set all three EP0 stall bits--data stage IN/OUT and status stage
27
// BUG FIX 2-9-06. The above statement hard-codes the register number to 9, ignoring the fact that
28
// the wreg function expects the register numbers to be pre-shifted 3 bits to put them into the 5 MSB's of
29
// the SPI command byte. Here is the correction:
30
31
#define STALL_EP0 Max_wreg(rEPSTALLS,0x23);  // Set all three EP0 stall bits--data stage IN/OUT and status stage
32
33
// ******** END OF BUG FIX**********
34
35
#define MSB(word) (BYTE)(((WORD)(word) >> 8) & 0xff)
36
#define LSB(word) (BYTE)((WORD)(word) & 0xff)
37
38
// MAX3420E Registers
39
#define rEP0FIFO    0<<3
40
#define rEP1OUTFIFO 1<<3
41
#define rEP2INFIFO  2<<3
42
#define rEP3INFIFO  3<<3
43
#define rSUDFIFO    4<<3
44
#define rEP0BC      5<<3
45
#define rEP1OUTBC   6<<3
46
#define rEP2INBC    7<<3
47
#define rEP3INBC    8<<3
48
#define rEPSTALLS   9<<3
49
#define rCLRTOGS    10<<3
50
#define rEPIRQ      11<<3
51
#define rEPIEN      12<<3
52
#define rUSBIRQ     13<<3
53
#define rUSBIEN     14<<3
54
#define rUSBCTL     15<<3
55
#define rCPUCTL     16<<3
56
#define rPINCTL     17<<3
57
#define rRevision   18<<3
58
#define rFNADDR     19<<3
59
#define rGPIO       20<<3
60
61
62
63
64
// MAX3420E bit masks for register bits
65
// R9 EPSTALLS Register
66
#define bmACKSTAT   0x40
67
#define bmSTLSTAT   0x20
68
#define bmSTLEP3IN  0x10
69
#define bmSTLEP2IN  0x08
70
#define bmSTLEP1OUT 0x04
71
#define bmSTLEP0OUT 0x02
72
#define bmSTLEP0IN  0x01
73
74
// R10 CLRTOGS Register
75
#define bmEP3DISAB  0x80
76
#define bmEP2DISAB  0x40
77
#define bmEP1DISAB  0x20
78
#define bmCTGEP3IN  0x10
79
#define bmCTGEP2IN  0x08
80
#define bmCTGEP1OUT 0x04
81
82
// R11 EPIRQ register bits
83
#define bmSUDAVIRQ  0x20
84
#define bmIN3BAVIRQ 0x10
85
#define bmIN2BAVIRQ 0x08
86
#define bmOUT1DAVIRQ 0x04
87
#define bmOUT0DAVIRQ 0x02
88
#define bmIN0BAVIRQ 0x01
89
90
// R12 EPIEN register bits
91
#define bmSUDAVIE   0x20
92
#define bmIN3BAVIE  0x10
93
#define bmIN2BAVIE  0x08
94
#define bmOUT1DAVIE 0x04
95
#define bmOUT0DAVIE 0x02
96
#define bmIN0BAVIE  0x01
97
98
// R13 USBIRQ register bits
99
#define bmURESDNIRQ 0x80
100
#define bmVBUSIRQ   0x40
101
#define bmNOVBUSIRQ 0x20
102
#define bmSUSPIRQ   0x10
103
#define bmURESIRQ   0x08
104
#define bmBUSACTIRQ 0x04
105
#define bmRWUDNIRQ  0x02
106
#define bmOSCOKIRQ  0x01
107
108
// R14 USBIEN register bits
109
#define bmURESDNIE  0x80
110
#define bmVBUSIE    0x40
111
#define bmNOVBUSIE  0x20
112
#define bmSUSPIE    0x10
113
#define bmURESIE    0x08
114
#define bmBUSACTIE  0x04
115
#define bmRWUDNIE   0x02
116
#define bmOSCOKIE   0x01
117
118
// R15 USBCTL Register
119
#define bmHOSCSTEN  0x80
120
#define bmVBGATE    0x40
121
#define bmCHIPRES   0x20
122
#define bmPWRDOWN   0x10
123
#define bmCONNECT   0x08
124
#define bmSIGRWU    0x04
125
126
// R16 CPUCTL Register
127
#define bmIE        0x01
128
129
// R17 PINCTL Register
130
#define bmFDUPSPI   0x10
131
#define bmINTLEVEL  0x08
132
#define bmPOSINT    0x04
133
#define bmGPOB      0x02
134
#define  bmGPOA      0x01
135
136
//
137
// GPX[B:A] settings (PINCTL register)
138
#define gpxOPERATE  0x00
139
#define gpxVBDETECT 0x01
140
#define gpxBUSACT   0x02
141
#define gpxSOF      0x03
142
143
// ************************
144
// Standard USB Requests
145
#define SR_GET_STATUS 0x00 // Get Status
146
#define SR_CLEAR_FEATURE 0x01 // Clear Feature
147
#define SR_RESERVED 0x02 // Reserved
148
#define SR_SET_FEATURE 0x03 // Set Feature
149
#define SR_SET_ADDRESS 0x05 // Set Address
150
#define SR_GET_DESCRIPTOR 0x06 // Get Descriptor
151
#define SR_SET_DESCRIPTOR 0x07 // Set Descriptor
152
#define SR_GET_CONFIGURATION 0x08 // Get Configuration
153
#define SR_SET_CONFIGURATION 0x09 // Set Configuration
154
#define SR_GET_INTERFACE 0x0a // Get Interface
155
#define SR_SET_INTERFACE 0x0b // Set Interface
156
157
// Get Descriptor codes
158
#define GD_DEVICE 0x01 // Get device descriptor: Device
159
#define GD_CONFIGURATION 0x02 // Get device descriptor: Configuration
160
#define GD_STRING 0x03 // Get device descriptor: String
161
#define GD_REPORT 0x22 // Get descriptor: Report
162
#define CS_INTERFACE 0x24 // Get descriptor: Interface
163
#define CS_ENDPOINT 0x25 // Get descriptor: Endpoint
164
165
// SETUP packet offsets
166
#define bmRequestType 0
167
#define bRequest 1
168
#define wValueL 2
169
#define wValueH 3
170
#define wIndexL 4
171
#define wIndexH 5
172
#define wLengthL 6
173
#define wLengthH 7
174
175
// CDC bRequest values
176
#define SEND_ENCAPSULATED_COMMAND 0x00
177
#define GET_ENCAPSULATED_RESPONSE 0x01
178
#define SET_COMM_FEATURE 0x02
179
#define GET_COMM_FEATURE 0x03
180
#define CLEAR_COMM_FEATURE 0x04
181
#define SET_LINE_CODING 0x20
182
#define GET_LINE_CODING 0x21
183
#define SET_CONTROL_LINE_STATE 0x22
184
#define SEND_BREAK 0x23

1
/*
2
 * MAX3420E_BF1.c
3
 *
4
 *  Created on: Jul 10, 2014
5
 *      Author: rnv5kor
6
 */
7
8
9
10
#include "xspi.h"
11
#include "xspi_l.h"
12
#include "xparameters.h"
13
#include "MAX3420E_BF1.h"
14
#include <stdio.h>
15
#include "platform.h"
16
#include "xbasic_types.h"
17
#include "time.h"
18
#include "EnumApp_enum_data.h"
19
20
21
typedef unsigned char BYTE;     // these save typing
22
typedef unsigned long uint32;
23
typedef unsigned long uint16;
24
typedef unsigned long uint8;
25
typedef unsigned short WORD;
26
27
#define TWENTY_MSEC 14200           // adjust this constant for 20 msec button checks
28
#define BLINKTIME 25                // blink every 500 msec
29
30
//Global variables
31
BYTE SUD[8];    // Local copy of the 8 setup data read from the MAX3420E SUDFIFO
32
BYTE msgidx,msglen;  // Text string in EnumApp_enum_data.h--index and length
33
BYTE configval;    // Set/Get_Configuration value
34
BYTE ep3stall;    // Flag for EP3 Stall, set by Set_Feature, reported back in Get_Status
35
BYTE interfacenum;      // Set/Get interface value
36
BYTE inhibit_send;  // Flag for the keyboard character send routine
37
BYTE RWU_enabled;       // Set by Set/Clear_Feature RWU request, sent back for Get_Status-RWU
38
BYTE Suspended;         // Tells the main loop to look for host resume and RWU pushbutton
39
WORD msec_timer;        // Count off time in the main loop
40
WORD blinktimer;        // Count milliseconds to blink the "loop active" light
41
BYTE send3zeros;        // EP3-IN function uses this to send HID (key up) codes between keystrokes
42
43
uint8 test_1,test_2,test_3,data;
44
45
46
47
48
static XSpi  mySPI;   /* The instance of the SPI device */
49
static XSpi SPI_SCK;
50
uint32  NumBytesSent = 0;
51
uint32  NumBytesRcvd = 0;
52
int PC_DTR=0;
53
#define ENABLE_IRQS Max_wreg(rEPIEN,(bmSUDAVIE+bmIN3BAVIE)); Max_wreg(rUSBIEN,(bmURESIE+bmURESDNIE));
54
// Note: the SUSPEND IRQ will be enabled later, when the device is configured.
55
// This prevents repeated SUSPEND IRQ's
56
57
58
extern void Max_wreg(BYTE r,BYTE v) ;
59
extern void Xps_SpiInit(void);
60
extern void Xps_Spi_Max_Transmit(void);
61
extern void IntialiseMax3420E(void);
62
extern void MAX_Reset(void);
63
extern BYTE Max_rreg(BYTE reg);
64
extern void Max_wregAS(BYTE reg, BYTE val);
65
extern BYTE Max_rregAS(BYTE reg);
66
extern void Max_readbytes(BYTE reg, BYTE N, BYTE *p);
67
extern void Max_writebytes(BYTE reg, BYTE N, BYTE *p);
68
BYTE MAX_Int_Pending(void);     // Poll the MAX3420E INT pin (set for active low level)
69
70
// USB functions
71
void std_request(void);
72
void class_request(void);
73
void vendor_request(void);
74
void send_descriptor(void);
75
void send_keystroke(BYTE);
76
void feature(BYTE);
77
void get_status(void);
78
void set_interface(void);
79
void get_interface(void);
80
void set_configuration(void);
81
void get_configuration(void);
82
83
// Application code
84
void do_SETUP(void);      // Handle a USB SETUP transfer
85
void do_IN3(void);        // Send keyboard characters over Endpoint 3-IN
86
void check_for_resume(void);
87
void service_irqs(void);
88
void initialize_MAX(void);
89
90
91
void check_for_resume(void)
92
{
93
94
  if(Max_rreg(rUSBIRQ) & bmBUSACTIRQ) // THE HOST RESUMEDBUS TRAFFIC
95
  {
96
    Suspended=0; // no longer suspended
97
  }
98
}
99
//
100
101
void service_irqs(void)
102
{
103
  BYTE itest1,itest2;
104
  itest1 = Max_rreg(rEPIRQ);            // Check the EPIRQ bits
105
  itest2 = Max_rreg(rUSBIRQ);           // Check the USBIRQ bits
106
107
108
  if(itest1 & bmSUDAVIRQ)
109
  {
110
    Max_wreg(rEPIRQ,bmSUDAVIRQ);     // clear the SUDAV IRQ
111
    do_SETUP();
112
  }
113
  if(itest1 & bmIN3BAVIRQ)          // Was an EP3-IN packet just dispatched to the host?
114
  {
115
    //do_IN3();                     // Yes--load another keystroke and arm the endpoint
116
  }                             // NOTE: don't clear the IN3BAVIRQ bit here--loading the EP3-IN byte
117
  // count register in the do_IN3() function does it.
118
  if((configval != 0) && (itest2&bmSUSPIRQ))   // HOST suspended bus for 3 msec
119
  {
120
    Max_wreg(rUSBIRQ,(bmSUSPIRQ+bmBUSACTIRQ));  // clear the IRQ and bus activity IRQ
121
    Suspended=1;                  // signal the main loop
122
  }
123
  if(Max_rreg(rUSBIRQ)& bmURESIRQ)
124
  {
125
    Max_wreg(rUSBIRQ,bmURESIRQ);      // clear the IRQ
126
  }
127
  if(Max_rreg(rUSBIRQ) & bmURESDNIRQ)
128
  {
129
    Max_wreg(rUSBIRQ,bmURESDNIRQ);    // clear the IRQ bit
130
    Suspended=0;                  // in case we were suspended
131
    ENABLE_IRQS                   // ...because a bus reset clears the IE bits
132
  }
133
}
134
135
void do_SETUP(void)
136
{
137
  int i;
138
  for (i=0;i<8;i++)
139
  {
140
    SUD[i]= Max_rreg(rSUDFIFO);          // got a SETUP packet. Read 8 SETUP bytes
141
  }
142
143
  switch(SUD[bmRequestType]&0x60)     // Parse the SETUP packet. For request type, look only at b6&b5
144
  {
145
  case 0x00:  std_request();    break;
146
  case 0x20:  class_request();  break;  // just a stub in this program
147
  case 0x40:  vendor_request();  break;  // just a stub in this program
148
  default:  STALL_EP0                       // unrecognized request type
149
150
  }
151
152
}
153
154
155
//*******************
156
void std_request(void)
157
{
158
  switch(SUD[bRequest])
159
  {
160
  case  SR_GET_DESCRIPTOR:  send_descriptor();    break;
161
  //case  SR_SET_FEATURE:    feature(1);           break;
162
  //case  SR_CLEAR_FEATURE:  feature(0);           break;
163
  //case  SR_GET_STATUS:    get_status();         break;
164
  case  SR_SET_INTERFACE:  set_interface();      break;
165
  case  SR_GET_INTERFACE:  get_interface();      break;
166
  case  SR_GET_CONFIGURATION:   get_configuration();  break;
167
  case  SR_SET_CONFIGURATION:   set_configuration();  break;
168
  case  SR_SET_ADDRESS:         Max_rregAS(rFNADDR);      break;  // discard return value
169
  default:  STALL_EP0
170
  }
171
}
172
173
//**************************
174
void set_configuration(void)
175
{
176
  configval=  wValueL; //SUD[wValueL];           // Store the config value
177
  if(configval != 0)                // If we are configured,
178
    SETBIT(rUSBIEN,bmSUSPIE);       // start looking for SUSPEND interrupts
179
  Max_rregAS(rFNADDR);                  // dummy read to set the ACKSTAT bit
180
}
181
182
void get_configuration(void)
183
{
184
  Max_wreg(rEP0FIFO,configval);         // Send the config value
185
  Max_wregAS(rEP0BC,1);
186
}
187
188
//**********************
189
void set_interface(void)  // All we accept are Interface=0 and AlternateSetting=0, otherwise send STALL
190
{
191
  BYTE dumval;
192
  if((SUD[wValueL]==0)    // wValueL=Alternate Setting index
193
      &&(SUD[wIndexL]==0))    // wIndexL=Interface index
194
    dumval = Max_rregAS(rFNADDR);  // dummy read to set the ACKSTAT bit
195
  else STALL_EP0
196
}
197
198
//**********************
199
void get_interface(void)  // Check for Interface=0, always report AlternateSetting=0
200
{
201
  if(SUD[wIndexL]==0)    // wIndexL=Interface index
202
  {
203
    Max_wreg(rEP0FIFO,0);    // AS=0
204
    Max_wregAS(rEP0BC,1);    // send one byte, ACKSTAT
205
  }
206
  else STALL_EP0
207
}
208
209
//*******************
210
void get_status(void)
211
{
212
  BYTE testbyte;
213
  testbyte=SUD[bmRequestType];
214
  switch(testbyte)
215
  {
216
  case 0x80:       // directed to DEVICE
217
    Max_wreg(rEP0FIFO,(RWU_enabled+1));  // first byte is 000000rs where r=enabled for RWU and s=self-powered.
218
    Max_wreg(rEP0FIFO,0x00);    // second byte is always 0
219
    Max_wregAS(rEP0BC,2);     // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer
220
    break;
221
  case 0x81:       // directed to INTERFACE
222
    Max_wreg(rEP0FIFO,0x00);    // this one is easy--two zero bytes
223
    Max_wreg(rEP0FIFO,0x00);
224
    Max_wregAS(rEP0BC,2);     // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer
225
    break;
226
  case 0x82:       // directed to ENDPOINT
227
    if(SUD[wIndexL]==0x83)    // We only reported ep3, so it's the only one the host can stall IN3=83
228
    {
229
      Max_wreg(rEP0FIFO,ep3stall);  // first byte is 0000000h where h is the halt (stall) bit
230
      Max_wreg(rEP0FIFO,0x00);    // second byte is always 0
231
      Max_wregAS(rEP0BC,2);     // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer
232
      break;
233
    }
234
    else  STALL_EP0    // Host tried to stall an invalid endpoint (not 3)
235
  default:      STALL_EP0    // don't recognize the request
236
  }
237
}
238
239
// **********************************************************************************************
240
// FUNCTION: Set/Get_Feature. Call as feature(1) for Set_Feature or feature(0) for Clear_Feature.
241
// There are two set/clear feature requests:
242
//  To a DEVICE:   Remote Wakeup (RWU).
243
//    To an ENDPOINT:  Stall (EP3 only for this app)
244
//
245
void feature(BYTE sc)
246
{
247
  BYTE mask;
248
  if((SUD[bmRequestType]==0x02)  // dir=h->p, recipient = ENDPOINT
249
      &&  (SUD[wValueL]==0x00)  // wValueL is feature selector, 00 is EP Halt
250
      &&  (SUD[wIndexL]==0x83))  // wIndexL is endpoint number IN3=83
251
  {
252
    mask= Max_rreg(rEPSTALLS);   // read existing bits
253
    if(sc==1)               // set_feature
254
    {
255
      mask += bmSTLEP3IN;       // Halt EP3IN
256
      ep3stall=1;
257
    }
258
    else                        // clear_feature
259
    {
260
      mask &= ~bmSTLEP3IN;      // UnHalt EP3IN
261
      ep3stall=0;
262
      Max_wreg(rCLRTOGS,bmCTGEP3IN);  // clear the EP3 data toggle
263
    }
264
    Max_wreg(rEPSTALLS,(mask|bmACKSTAT)); // Don't use wregAS for this--directly writing the ACKSTAT bit
265
  }
266
  else if ((SUD[bmRequestType]==0x00)  // dir=h->p, recipient = DEVICE
267
      &&  (SUD[wValueL]==0x01))  // wValueL is feature selector, 01 is Device_Remote_Wakeup
268
  {
269
    RWU_enabled = sc<<1;  // =2 for set, =0 for clear feature. The shift puts it in the get_status bit position.
270
    Max_rregAS(rFNADDR);    // dummy read to set ACKSTAT
271
  }
272
  else STALL_EP0
273
}
274
275
//************************
276
void send_descriptor(void)
277
{
278
  uint16 reqlen,sendlen,desclen;
279
  BYTE *pDdata; // pointer to ROM Descriptor data to send
280
281
  // NOTE This function assumes all descriptors are 64 or fewer bytes and canbe sent in a single packet
282
283
  desclen = 0; // check for zero as error condition (no casestatements satisfied)
284
  reqlen = SUD[wLengthL] + 256*SUD[wLengthH]; // 16-bit
285
  switch (SUD[wValueH]) // wValueH is descriptor type
286
  {
287
  case GD_DEVICE:
288
    desclen = device_descriptor[0]; // descriptor length
289
    pDdata = device_descriptor;
290
    break;
291
  case GD_CONFIGURATION:
292
    desclen = configuration_descriptor[2]; // Config descriptorincludes interface, HID, report and ep descriptors
293
    pDdata = configuration_descriptor;
294
    break;
295
  case GD_STRING:
296
    desclen = string_descriptor[SUD[wValueL]][0]; // wValueL=stringindex, array[0] is the length
297
    pDdata = string_descriptor[SUD[wValueL]]; // point to firstarray element
298
    break;
299
  case CS_INTERFACE:
300
    if(SUD[wIndexL]==0) // Interface Number=0. Del EndPoint 2(interrupción), Communication
301
    {
302
      //if(SUD[wLengthL]>configuration_descriptor[9])
303
      desclen = configuration_descriptor[9];
304
      //else desclen = SUD[wLengthL];
305
      pDdata = (BYTE *)&configuration_descriptor[9];
306
    }
307
    else if (SUD[wIndexL]==1) // InterfaceNumber=1. Del EndPoint 1 (bulk), Datos
308
    {
309
      //if(SUD[wLengthL]>configuration_descriptor[44])
310
      desclen = configuration_descriptor[44];
311
      //else desclen = SUD[wLengthL];
312
      pDdata = (BYTE *)&configuration_descriptor[44];
313
    }
314
    break;
315
    /* case GD_REPORT:
316
  desclen = configuration_descriptor[25];
317
  pDdata = report_descriptor;
318
  break;*/
319
  } // end switch on descriptor type
320
321
  if (desclen!=0)
322
  {
323
    sendlen = (reqlen <= desclen) ? reqlen : desclen;
324
    if(sendlen<=64) //if just one frame
325
    {
326
      Max_writebytes(rEP0FIFO,sendlen,pDdata);
327
      Max_wregAS(rEP0BC,sendlen);
328
    }
329
    else //if sendlen > 64, like your configuration descriptor,67 byte require 2 frame
330
    {
331
      do
332
      {
333
334
        sendlen = 64; //first time i send 64 bytes, because 67 = 64+ 3
335
        Max_writebytes(rEP0FIFO,sendlen,pDdata);
336
        Max_wreg(rEP0BC,sendlen);
337
        desclen=desclen-sendlen;
338
        pDdata=pDdata+sendlen;
339
340
      } while(desclen>64);
341
342
      sendlen = desclen;
343
      while(!Max_rreg(rEPIRQ& bmIN0BAVIRQ));
344
      if(sendlen>0) Max_writebytes(rEP0FIFO,sendlen,pDdata); //3 bytesmore
345
      Max_wregAS(rEP0BC,sendlen);
346
    }
347
  }
348
349
  else STALL_EP0 // none of the descriptor types match
350
}
351
352
void class_request(void)
353
{
354
  int i;
355
  switch (SUD[bRequest])
356
  {
357
  case SEND_ENCAPSULATED_COMMAND: Max_wregAS(rEP0BC, 0); break; // send_encapsulated_command(); break;
358
  case GET_ENCAPSULATED_RESPONSE: Max_wregAS(rEP0BC, 0); break; // send_encapsulated_command(); break; //get_encapsulated_response(); break;
359
360
  case SET_COMM_FEATURE: break;
361
  case GET_COMM_FEATURE: break;
362
  case CLEAR_COMM_FEATURE:break;
363
  case SET_LINE_CODING:
364
  {
365
    Max_wregAS(rEP0BC, 0);
366
    if(SUD[wLengthL]>0)
367
    {
368
      while(!(Max_rreg(rEPIRQ) & bmOUT0DAVIRQ) &&SUD[7]<=5) SUD[7]++;
369
      for(i=0;i<=SUD[wLengthL];)
370
        Max_readbytes(rEP0FIFO,SUD[wLengthL],(unsigned char *)&SUD[0]);
371
    }
372
  } break;
373
  case GET_LINE_CODING:
374
  {
375
    Max_wregAS(rEP0BC, 0);
376
    Max_writebytes(rEP0FIFO,SUD[wLengthL],(unsigned char*)&SerialConf[0]);
377
    Max_wreg(rEP0BC, SUD[wLengthL]);
378
  } break;
379
  case SET_CONTROL_LINE_STATE:
380
  {
381
    if(configval)
382
    {
383
      //Xps_SpiInit();
384
      if((SUD[wValueL]&0x01)==0x01)
385
        PC_DTR=1;
386
      if(SUD[wValueL]==0x00)
387
        PC_DTR=0;
388
    }
389
    Max_wregAS(rEP3INBC, 0);
390
  } break;
391
  case SEND_BREAK: break;
392
  default: STALL_EP0;
393
  }
394
}
395
396
void vendor_request(void)
397
{
398
  STALL_EP0
399
}
400
401
402
403
extern void Xps_SpiInit()   // Parmeters need to be Intialized
404
{
405
406
  XStatus status = XST_SUCCESS;
407
408
  status =      XSpi_Initialize(&mySPI, XPAR_SPI_0_DEVICE_ID );//XPAR_SPI_0_DEVICE_ID);
409
410
  switch(status)
411
  {
412
  case XST_SUCCESS: print("Status: Erfolgreich initialisiert\n\r");
413
  break;
414
  case XST_DEVICE_IS_STARTED: print("Status: Device is started\n\r");
415
  break;
416
  case XST_DEVICE_NOT_FOUND: print("Status: Device not found\n\r");
417
  break;
418
419
  }
420
421
  status =   XSpi_SetOptions(&mySPI, XSP_MASTER_OPTION );//XSP_MANUAL_SSELECT_OPTION
422
423
424
  //status   =  XSpi_SetSlaveSelect(&mySPI, 1);
425
426
  //status =   XSpi_SetOptions(&mySPI, XSP_CLK_ACTIVE_LOW_OPTION);
427
428
429
  status =    XSpi_Start(&mySPI);
430
431
432
}
433
434
extern void Xps_Spi_Max_Transmit(void)
435
{
436
437
}
438
439
extern void IntialiseMax3420E(void)
440
{
441
442
  ep3stall=0;      // EP3 inintially un-halted (no stall) (CH9 testing)
443
  msgidx = 0;      // start of KB Message[]
444
  inhibit_send = 0x01;    // 0 means send, 1 means inhibit sending
445
  send3zeros=1;
446
  msec_timer=0;
447
  blinktimer=0;
448
  // software flags
449
  configval=0;                    // at pwr on OR bus reset we're unconfigured
450
  Suspended=0;
451
  RWU_enabled=0;                  // Set by host Set_Feature(enable RWU) request
452
  //
453
     BYTE dum;
454
  //Xps_SpiInit();
455
456
  Max_wreg(rPINCTL,(bmFDUPSPI+bmINTLEVEL+gpxSOF)); // MX3420: SPI=full-duplex, INT=neg level, GPX=SOF
457
458
  data = Max_rreg(rPINCTL);
459
460
  //Max_wreg(rPINCTL,bmFDUPSPI);    // MAX3420: SPI=full-duplex
461
  Max_wreg(rUSBCTL,bmCHIPRES);    // reset the MAX3420E
462
  Max_wreg(rUSBCTL,0);// remove the reset
463
464
  //MAX_Reset();
465
  //Max_wreg(rGPIO,0x01);                   // lites off (Active HIGH)
466
  // This is a self-powered design, so the host could turn off Vbus while we are powered.
467
  // Therefore set the VBGATE bit to have the MAX3420E automatically disconnect the D+
468
  // pullup resistor in the absense of Vbus. Note: the VBCOMP pin must be connected to Vbus
469
  // or pulled high for this code to work--a low on VBCOMP will prevent USB connection.
470
  Max_wreg(rUSBCTL, (bmCONNECT));
471
472
  //ENABLE_IRQS;
473
474
  //Max_wreg(rCPUCTL,bmIE);                 // Enable the INT pin
475
}
476
477
extern void MAX_Reset(void)
478
{
479
480
  BYTE dum;
481
  Max_wreg(rUSBCTL,0x20);  // chip reset
482
  Max_wreg(rUSBCTL,0x00);  // remove the reset
483
  do                  // Chip reset stops the oscillator. Wait for it to stabilize.
484
  {
485
    dum = Max_rreg(rUSBIRQ);
486
    dum &= bmOSCOKIRQ;
487
  }
488
  while (dum==0);
489
490
}
491
492
extern void  Max_wreg(BYTE reg,BYTE val)              // write a MAX3420E register byte
493
{
494
  u8 spiWCmd = 0;
495
496
497
498
  XStatus status = XST_SUCCESS;
499
500
  status   =    XSpi_IntrGlobalDisable(&mySPI);
501
502
  status   =    XSpi_SetSlaveSelect(&mySPI, 0);
503
504
  spiWCmd  =    reg + 2;
505
506
  status   =    XSpi_Transfer(&mySPI,&spiWCmd,NULL,1);
507
508
  spiWCmd  =    val;
509
510
  status   =    XSpi_Transfer(&mySPI,&spiWCmd,NULL,1);
511
512
513
  switch(status)
514
  {
515
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
516
  break;
517
518
  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
519
  break;
520
521
  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
522
  break;
523
524
  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
525
  break;
526
  };
527
528
  status =    XSpi_SetSlaveSelect(&mySPI, 1);
529
530
  //status =    XSpi_IntrGlobalEnable(&mySPI);
531
}
532
533
extern BYTE Max_rreg(BYTE reg)
534
{
535
  BYTE dum;
536
  u8 spiRCmd = 0;
537
538
  XStatus status = XST_SUCCESS;
539
540
  status =    XSpi_IntrGlobalDisable(&mySPI);
541
542
  status = XSpi_SetSlaveSelect(&mySPI, 0);
543
544
  spiRCmd  = reg;
545
546
  status = XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,1);
547
548
  dum =  spiRCmd;
549
550
  spiRCmd = 0x00;
551
552
  status = XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,1);
553
554
  switch(status)
555
  {
556
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
557
  break;
558
559
  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
560
  break;
561
562
  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
563
  break;
564
565
  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
566
  break;
567
  };
568
569
  status = XSpi_SetSlaveSelect(&mySPI,1);
570
571
//  status =    XSpi_IntrGlobalEnable(&mySPI);
572
573
  return dum;
574
}
575
576
// Write a MAX3410E register with the "ACK STATUS" bit set in the command byte
577
extern void Max_wregAS(BYTE reg, BYTE val)
578
{
579
  u8 spiWCmd = 0;
580
581
  XStatus Status = XST_SUCCESS;
582
583
  Status = XSpi_SetSlaveSelect(&mySPI, 0);                   // Set SS# low
584
585
  spiWCmd = reg+3;             // reg number with DIR=1 (write) and ACKSTAT=1
586
587
  Status = XSpi_Transfer(&mySPI,&spiWCmd,NULL,1);
588
589
  spiWCmd = val;               // send the data
590
591
  Status = XSpi_Transfer(&mySPI,&spiWCmd,NULL,1);
592
593
594
  switch(Status)
595
  {
596
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
597
  break;
598
599
  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
600
  break;
601
602
  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
603
  break;
604
605
  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
606
  break;
607
  };
608
609
  Status = XSpi_SetSlaveSelect(&mySPI, 1);
610
}
611
612
// Read a byte (as rreg), but also set the AckStat bit in the command byte.
613
extern BYTE Max_rregAS(BYTE reg)
614
{
615
  BYTE dum;
616
  u8 spiRCmd = 0;
617
618
  XStatus Status = XST_SUCCESS;
619
620
  XSpi_SetSlaveSelect(&mySPI, 0);
621
622
  spiRCmd  = reg +1;
623
624
  XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,2);
625
626
  dum =  spiRCmd;
627
  spiRCmd = 0xFF;
628
629
  XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,2);
630
631
  switch(Status)
632
  {
633
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
634
  break;
635
636
  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
637
  break;
638
639
  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
640
  break;
641
642
  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
643
  break;
644
  };
645
646
  XSpi_SetSlaveSelect(&mySPI,1);
647
648
  return dum;
649
}
650
651
extern void Max_readbytes(BYTE reg, BYTE N, BYTE *p)
652
{
653
  BYTE j;
654
  u8 spiRCmd = 0;
655
656
  XStatus Status = XST_SUCCESS;
657
658
  Status = XSpi_SetSlaveSelect(&mySPI, 0);
659
660
  spiRCmd  = reg +1;                            // write bit b1=0 to command a read operation
661
662
  Status = XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,N);
663
664
  j = spiRCmd;                 // NECESSARY TO RE-ENABLE THE INPUT BUFFER in BYTE MODE
665
666
  for(j=0; j<N; j++)
667
  {
668
    spiRCmd = 0x00;            // dummy value to get the next read byte
669
    Status = XSpi_Transfer(&mySPI,&spiRCmd,&spiRCmd,N);   // loop if data still being sent
670
    *p = spiRCmd;              // store it in the data array
671
    p++;                    // bump the pointer
672
  }
673
674
  switch(Status)
675
  {
676
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
677
  break;
678
679
  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
680
  break;
681
682
  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
683
  break;
684
685
  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
686
  break;
687
  };
688
689
  Status = XSpi_SetSlaveSelect(&mySPI, 1);
690
}
691
void Max_writebytes(BYTE reg, BYTE N, BYTE *p)
692
{
693
  BYTE j,spiWCmd;
694
  // uint32 spiWCmd = 0;
695
696
  XStatus Status = XST_SUCCESS;
697
698
  Status = XSpi_SetSlaveSelect(&mySPI, 0);
699
700
  spiWCmd = reg+2;             // write bit b1=1 to command a write operation
701
702
  Status = XSpi_Transfer(&mySPI,&spiWCmd,NULL,N);
703
704
  for(j=0; j<N; j++)
705
  {
706
    spiWCmd = *p;                // write the array value
707
    Status = XSpi_Transfer(&mySPI,&spiWCmd,NULL,N);
708
    p++;                    // bump the pointer
709
  }
710
711
  switch(Status)
712
  {
713
  case XST_SUCCESS :print("driver for transfer. Otherwise, returns:");
714
  break;
715
716
  case XST_DEVICE_IS_STOPPED : print("if the device must be started before transferring data.");
717
  break;
718
719
  case XST_DEVICE_BUSY : print(" indicates that a data transfer is already in  progress. This is determined by the driver.");
720
  break;
721
722
  case XST_SPI_NO_SLAVE : print( "indicates the device is configured as a  master and a slave has not yet been selected.");
723
  break;
724
  };
725
726
  Status = XSpi_SetSlaveSelect(&mySPI, 1);
727
}
728
729
BYTE MAX_Int_Pending(void)
730
{
731
  return (BYTE)((0xA1&0x01)==0);
732
}
733
734
int main()
735
{
736
  init_platform();
737
738
  Xps_SpiInit();
739
740
  IntialiseMax3420E();
741
742
  test_1 = Max_rreg(rFNADDR);
743
  test_2 = Max_rreg(rEPIRQ);
744
  test_3 = Max_rreg(rUSBIRQ);
745
746
  while(1)    // endless loop
747
  {
748
    if(Suspended)
749
      check_for_resume();
750
751
    service_irqs();
752
753
    msec_timer++;
754
755
    if(msec_timer==TWENTY_MSEC)
756
    {
757
      msec_timer=0;
758
      if((Max_rreg(rGPIO) & 0x10) == 0) // Check the pushbutton on GPI-0
759
      {
760
        inhibit_send = 0x00;      // Tell the "do_IN3" function to send the text string
761
        //L0_ON                     // Turn on the SEND light
762
      }
763
      blinktimer++;                 // blink the loop active light every half second
764
      if(blinktimer==BLINKTIME)
765
      {
766
        blinktimer=0;
767
        //L3_BLINK
768
      }
769
    }// msec_timer==ONE_MSEC
770
  } // while(1)
771
772
  return 0;
773
}

von Daniel (Guest)


Rate this post
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

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.