d556699ab09d754826ee38bbf0ac81eb7f3664ac
[openocd.git] / src / jtag / zy1000 / jtag_minidriver.h
1 /***************************************************************************
2 * Copyright (C) 2007-2009 by Øyvind Harboe *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20 /* used to test manual mode */
21 #define TEST_MANUAL() 0
22 #define VERBOSE(a)
23
24 #if BUILD_ECOSBOARD
25
26 #include <cyg/hal/hal_io.h> // low level i/o
27 #include <cyg/hal/hal_intr.h> // low level i/o
28
29 #if 0
30 int diag_printf(const char *fmt, ...);
31 #define ZY1000_POKE(a, b) HAL_WRITE_UINT32(a, b); diag_printf("poke 0x%08x,0x%08x\n", a, b)
32 #define ZY1000_PEEK(a, b) HAL_READ_UINT32(a, b); diag_printf("peek 0x%08x = 0x%08x\n", a, b)
33 #else
34 #define ZY1000_PEEK(a, b) HAL_READ_UINT32(a, b)
35 #define ZY1000_POKE(a, b) HAL_WRITE_UINT32(a, b)
36 #endif
37
38 #else
39
40 /* redirect this to TCP/IP */
41 #define ZY1000_JTAG_BASE 0
42 extern void zy1000_tcpout(uint32_t address, uint32_t data);
43 extern uint32_t zy1000_tcpin(uint32_t address);
44 #define ZY1000_PEEK(a, b) b=zy1000_tcpin(a)
45 #define ZY1000_POKE(a, b) zy1000_tcpout(a, b)
46
47 #endif
48
49
50
51 // FIFO empty?
52 static __inline__ void waitIdle(void)
53 {
54 uint32_t empty;
55 do
56 {
57 ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, empty);
58 } while ((empty & 0x100) == 0);
59 }
60
61 static __inline__ void waitQueue(void)
62 {
63 // waitIdle();
64 }
65
66 static __inline__ void sampleShiftRegister(void)
67 {
68 #if 0
69 uint32_t dummy;
70 waitIdle();
71 ZY1000_PEEK(ZY1000_JTAG_BASE + 0xc, dummy);
72 #endif
73 }
74
75 static __inline__ void setCurrentState(enum tap_state state)
76 {
77 uint32_t a;
78 a = state;
79 int repeat = 0;
80 if (state == TAP_RESET)
81 {
82 // The FPGA nor we know the current state of the CPU TAP
83 // controller. This will move it to TAP for sure.
84 //
85 // 5 should be enough here, 7 is what OpenOCD uses
86 repeat = 7;
87 }
88 waitQueue();
89 sampleShiftRegister();
90 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | a);
91
92 }
93
94 /*
95 * Enter state and cause repeat transitions *out* of that state. So if the endState != state, then
96 * the transition from state to endState counts as a transition out of state.
97 */
98 static __inline__ void shiftValueInner(const enum tap_state state, const enum tap_state endState, int repeat, uint32_t value)
99 {
100 uint32_t a,b;
101 a = state;
102 b = endState;
103 waitQueue();
104 sampleShiftRegister();
105 ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value);
106 #if 1
107 #if TEST_MANUAL()
108 if ((state == TAP_DRSHIFT) && (endState != TAP_DRSHIFT))
109 {
110 int i;
111 setCurrentState(state);
112 for (i = 0; i < repeat; i++)
113 {
114 int tms;
115 tms = 0;
116 if ((i == repeat-1) && (state != endState))
117 {
118 tms = 1;
119 }
120 /* shift out value */
121 waitIdle();
122 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, (((value >> i)&1) << 1) | tms);
123 }
124 waitIdle();
125 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
126 waitIdle();
127 //ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); // set this state and things break => expected
128 ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRPAUSE); // set this and things will work => expected. Not setting this is not sufficient to make things break.
129 setCurrentState(endState);
130 } else
131 {
132 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
133 }
134 #else
135 /* fast version */
136 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
137 #endif
138 #else
139 /* maximum debug version */
140 if ((repeat > 0) && ((state == TAP_DRSHIFT)||(state == TAP_SI)))
141 {
142 int i;
143 /* sample shift register for every bit. */
144 for (i = 0; i < repeat-1; i++)
145 {
146 sampleShiftRegister();
147 ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> i);
148 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | a);
149 }
150 sampleShiftRegister();
151 ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> (repeat-1));
152 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | b);
153 } else
154 {
155 sampleShiftRegister();
156 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b);
157 }
158 sampleShiftRegister();
159 #endif
160 }
161
162
163
164 static __inline__ void interface_jtag_add_dr_out_core(struct jtag_tap *target_tap,
165 int num_fields,
166 const int *num_bits,
167 const uint32_t *value,
168 enum tap_state end_state)
169 {
170 enum tap_state pause_state = TAP_DRSHIFT;
171
172 struct jtag_tap *tap, *nextTap;
173 for (tap = jtag_tap_next_enabled(NULL); tap!= NULL; tap = nextTap)
174 {
175 nextTap = jtag_tap_next_enabled(tap);
176 if (nextTap == NULL)
177 {
178 pause_state = end_state;
179 }
180 if (tap == target_tap)
181 {
182 int j;
183 for (j = 0; j < (num_fields-1); j++)
184 {
185 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[j], value[j]);
186 }
187 shiftValueInner(TAP_DRSHIFT, pause_state, num_bits[j], value[j]);
188 } else
189 {
190 /* program the scan field to 1 bit length, and ignore it's value */
191 shiftValueInner(TAP_DRSHIFT, pause_state, 1, 0);
192 }
193 }
194 }
195
196 static __inline__ void interface_jtag_add_dr_out(struct jtag_tap *target_tap,
197 int num_fields,
198 const int *num_bits,
199 const uint32_t *value,
200 enum tap_state end_state)
201 {
202
203 int singletap = (jtag_tap_next_enabled(jtag_tap_next_enabled(NULL)) == NULL);
204 if ((singletap) && (num_fields == 3))
205 {
206 /* used by embeddedice_write_reg_inner() */
207 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[0], value[0]);
208 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[1], value[1]);
209 shiftValueInner(TAP_DRSHIFT, end_state, num_bits[2], value[2]);
210 } else if ((singletap) && (num_fields == 2))
211 {
212 /* used by arm7 code */
213 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, num_bits[0], value[0]);
214 shiftValueInner(TAP_DRSHIFT, end_state, num_bits[1], value[1]);
215 } else
216 {
217 interface_jtag_add_dr_out_core(target_tap, num_fields, num_bits, value, end_state);
218 }
219 }
220
221 #define interface_jtag_add_callback(callback, in) callback(in)
222
223 #define interface_jtag_add_callback4(callback, in, data1, data2, data3) jtag_set_error(callback(in, data1, data2, data3))

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)