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