1 /*******************************************************/
2 /* file: ports.c */
3 /* abstract: This file contains the routines to */
4 /* output values on the JTAG ports, to read */
5 /* the TDO bit, and to read a byte of data */
6 /* from the prom */
7 /* Revisions: */
8 /* 12/01/2008: Same code as before (original v5.01). */
9 /* Updated comments to clarify instructions.*/
10 /* Add print in setPort for xapp058_example.exe.*/
11 /*******************************************************/
12 #include "ports.h"
13
14 #include "hackrf_core.h"
15 #include "cpld_jtag.h"
16
17 #include "gpio.h"
18
delay_jtag(uint32_t duration)19 void delay_jtag(uint32_t duration)
20 {
21 #define DIVISOR (1024)
22 #define MIN_NOP (8)
23
24 uint32_t i;
25 uint32_t delay_nop;
26
27 /* @204Mhz duration of about 400ns for delay_nop=20 */
28 if(duration < DIVISOR)
29 {
30 delay_nop = MIN_NOP;
31 }else
32 {
33 delay_nop = (duration / DIVISOR) + MIN_NOP;
34 }
35
36 for (i = 0; i < delay_nop; i++)
37 __asm__("nop");
38 }
39
40 /* setPort: Implement to set the named JTAG signal (p) to the new value (v).*/
41 /* if in debugging mode, then just set the variables */
setPort(jtag_gpio_t * const gpio,short p,short val)42 void setPort(jtag_gpio_t* const gpio, short p, short val)
43 {
44 if (p==TMS) {
45 if (val)
46 gpio_set(gpio->gpio_tms);
47 else
48 gpio_clear(gpio->gpio_tms);
49 } if (p==TDI) {
50 if (val)
51 gpio_set(gpio->gpio_tdi);
52 else
53 gpio_clear(gpio->gpio_tdi);
54 } if (p==TCK) {
55 if (val)
56 gpio_set(gpio->gpio_tck);
57 else
58 gpio_clear(gpio->gpio_tck);
59 }
60
61 /* conservative delay */
62 delay_jtag(20000);
63 }
64
65
66 /* toggle tck LH. No need to modify this code. It is output via setPort. */
pulseClock(jtag_gpio_t * const gpio)67 void pulseClock(jtag_gpio_t* const gpio)
68 {
69 setPort(gpio, TCK,0); /* set the TCK port to low */
70 delay_jtag(200);
71 setPort(gpio, TCK,1); /* set the TCK port to high */
72 delay_jtag(200);
73 }
74
75
76 /* readByte: Implement to source the next byte from your XSVF file location */
77 /* read in a byte of data from the prom */
readByte(unsigned char * data)78 void readByte(unsigned char *data)
79 {
80 *data = cpld_jtag_get_next_byte();
81 }
82
83 /* readTDOBit: Implement to return the current value of the JTAG TDO signal.*/
84 /* read the TDO bit from port */
readTDOBit(jtag_gpio_t * const gpio)85 unsigned char readTDOBit(jtag_gpio_t* const gpio)
86 {
87 delay_jtag(2000);
88 return gpio_read(gpio->gpio_tdo);;
89 }
90
91 /* waitTime: Implement as follows: */
92 /* REQUIRED: This function must consume/wait at least the specified number */
93 /* of microsec, interpreting microsec as a number of microseconds.*/
94 /* REQUIRED FOR SPARTAN/VIRTEX FPGAs and indirect flash programming: */
95 /* This function must pulse TCK for at least microsec times, */
96 /* interpreting microsec as an integer value. */
97 /* RECOMMENDED IMPLEMENTATION: Pulse TCK at least microsec times AND */
98 /* continue pulsing TCK until the microsec wait */
99 /* requirement is also satisfied. */
waitTime(jtag_gpio_t * const gpio,long microsec)100 void waitTime(jtag_gpio_t* const gpio, long microsec)
101 {
102 static long tckCyclesPerMicrosec = 1; /* must be at least 1 */
103 long tckCycles = microsec * tckCyclesPerMicrosec;
104 long i;
105
106 /* This implementation is highly recommended!!! */
107 /* This implementation requires you to tune the tckCyclesPerMicrosec
108 variable (above) to match the performance of your embedded system
109 in order to satisfy the microsec wait time requirement. */
110 for ( i = 0; i < tckCycles; ++i )
111 {
112 pulseClock(gpio);
113 }
114 }
115