]> git.sur5r.net Git - openocd/blob - src/target/dsp563xx_once.c
aa8c96910c5238649b0e4d51f8c67588aea8752a
[openocd] / src / target / dsp563xx_once.c
1 /***************************************************************************
2  *   Copyright (C) 2009 by Mathias Kuester                                 *
3  *   mkdorg@users.sourceforge.net                                          *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
19  ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <jim.h>
26
27 #include "target.h"
28 #include "target_type.h"
29 #include "register.h"
30 #include "dsp563xx.h"
31 #include "dsp563xx_once.h"
32
33 #define JTAG_STATUS_STATIC_MASK         0x03
34 #define JTAG_STATUS_STATIC_VALUE        0x01
35
36 #define JTAG_STATUS_NORMAL              0x01
37 #define JTAG_STATUS_STOPWAIT            0x05
38 #define JTAG_STATUS_BUSY                0x09
39 #define JTAG_STATUS_DEBUG               0x0d
40
41 #define JTAG_INSTR_EXTEST               0x00
42 #define JTAG_INSTR_SAMPLE_PRELOAD       0x01
43 #define JTAG_INSTR_IDCODE               0x02
44 #define JTAG_INSTR_HIZ                  0x04
45 #define JTAG_INSTR_CLAMP                0x05
46 #define JTAG_INSTR_ENABLE_ONCE          0x06
47 #define JTAG_INSTR_DEBUG_REQUEST        0x07
48 #define JTAG_INSTR_BYPASS               0x0F
49
50 /** */
51 static inline int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8_t * dr_out, int dr_len, int rti)
52 {
53         jtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE);
54
55         return ERROR_OK;
56 }
57
58 /** */
59 static inline int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t * dr_in, uint8_t dr_out, int dr_len, int rti)
60 {
61         return dsp563xx_write_dr(tap, dr_in, &dr_out, dr_len, rti);
62 }
63
64 /** */
65 static inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out, int dr_len, int rti)
66 {
67         return dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) &dr_out, dr_len, rti);
68 }
69
70 /** single word instruction */
71 static inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex)
72 {
73         int err;
74
75         err = dsp563xx_write_dr_u8(tap, 0, instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
76         if (err != ERROR_OK)
77                 return err;
78         if (flush)
79                 err = jtag_execute_queue();
80         return err;
81 }
82
83 /* IR and DR functions */
84 static inline int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t * ir_in, uint8_t * ir_out, int ir_len, int rti)
85 {
86         jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE);
87
88         return ERROR_OK;
89 }
90
91 static inline int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out, int ir_len, int rti)
92 {
93         return dsp563xx_write_ir(tap, ir_in, &ir_out, ir_len, rti);
94 }
95
96 static inline int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out)
97 {
98         return dsp563xx_write_ir_u8(tap, ir_in, ir_out, tap->ir_length, 1);
99 }
100
101 /** */
102 int dsp563xx_once_target_status(struct jtag_tap *tap)
103 {
104         int err;
105         uint8_t jtag_status;
106
107         err = dsp563xx_jtag_sendinstr(tap, &jtag_status, JTAG_INSTR_ENABLE_ONCE);
108         if (err != ERROR_OK)
109                 return TARGET_UNKNOWN;
110         err = jtag_execute_queue();
111         if (err != ERROR_OK)
112                 return TARGET_UNKNOWN;
113
114         /* verify correct static status pattern */
115         if ((jtag_status & JTAG_STATUS_STATIC_MASK) != JTAG_STATUS_STATIC_VALUE)
116                 return TARGET_UNKNOWN;
117
118         if (jtag_status != JTAG_STATUS_DEBUG)
119                 return TARGET_RUNNING;
120
121         return TARGET_HALTED;
122 }
123
124 /** */
125 int dsp563xx_once_request_debug(struct jtag_tap *tap, int reset_state)
126 {
127         int err;
128         uint8_t ir_in = 0, pattern = 0;
129         uint32_t retry = 0;
130
131         /* in reset state we only get a ACK
132          * from the interface */
133         if (reset_state)
134                 pattern = 1;
135         else
136                 pattern = JTAG_STATUS_DEBUG;
137
138         /* wait until we get the ack */
139         while (ir_in != pattern) {
140                 err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST);
141                 if (err != ERROR_OK)
142                         return err;
143                 err = jtag_execute_queue();
144                 if (err != ERROR_OK)
145                         return err;
146
147                 LOG_DEBUG("debug request: %02X", ir_in);
148
149                 if (retry++ == 100)
150                         return ERROR_TARGET_FAILURE;
151         }
152
153         /* we cant enable the once in reset state */
154         if (pattern == 1)
155                 return ERROR_OK;
156
157         /* try to enable once */
158         retry = 0;
159         ir_in = 0;
160         while (ir_in != pattern) {
161                 err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE);
162                 if (err != ERROR_OK)
163                         return err;
164                 err = jtag_execute_queue();
165                 if (err != ERROR_OK)
166                         return err;
167
168                 LOG_DEBUG("enable once: %02X", ir_in);
169
170                 if (retry++ == 100) {
171                         LOG_DEBUG("error");
172                         return ERROR_TARGET_FAILURE;
173                 }
174         }
175
176         if (ir_in != JTAG_STATUS_DEBUG)
177                 return ERROR_TARGET_FAILURE;
178
179         return ERROR_OK;
180 }
181
182 /** once read registers */
183 int dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg *regs, int len)
184 {
185         int i;
186         int err = ERROR_OK;
187
188         for (i = 0; i < len; i++) {
189                 err = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, &regs[i].reg);
190                 if (err != ERROR_OK)
191                         return err;
192         }
193
194         if (flush)
195                 err = jtag_execute_queue();
196         return err;
197 }
198
199 /** once read register with register len */
200 int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t * data)
201 {
202         int err;
203
204         err = dsp563xx_once_ir_exec(tap, 1, reg, 1, 0, 0);
205         if (err != ERROR_OK)
206                 return err;
207         err = dsp563xx_write_dr_u32(tap, data, 0x00, len, 0);
208         if (err != ERROR_OK)
209                 return err;
210         if (flush)
211                 err = jtag_execute_queue();
212
213         return err;
214 }
215
216 /** once read register */
217 int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t * data)
218 {
219         int err;
220
221         err = dsp563xx_once_ir_exec(tap, flush, reg, 1, 0, 0);
222         if (err != ERROR_OK)
223                 return err;
224         err = dsp563xx_write_dr_u32(tap, data, 0x00, 24, 0);
225         if (err != ERROR_OK)
226                 return err;
227         if (flush)
228                 err = jtag_execute_queue();
229
230         return err;
231 }
232
233 /** once write register */
234 int dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t data)
235 {
236         int err;
237
238         err = dsp563xx_once_ir_exec(tap, flush, reg, 0, 0, 0);
239         if (err != ERROR_OK)
240                 return err;
241         err = dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0);
242         if (err != ERROR_OK)
243                 return err;
244         if (flush)
245                 err = jtag_execute_queue();
246         return err;
247 }
248
249 /** single word instruction */
250 int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, int flush, uint32_t opcode)
251 {
252         int err;
253
254         err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);
255         if (err != ERROR_OK)
256                 return err;
257         err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
258         if (err != ERROR_OK)
259                 return err;
260         if (flush)
261                 err = jtag_execute_queue();
262         return err;
263 }
264
265 /** double word instruction */
266 int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, int flush, uint32_t opcode, uint32_t operand)
267 {
268         int err;
269
270         err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 0, 0);
271         if (err != ERROR_OK)
272                 return err;
273         err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
274         if (err != ERROR_OK)
275                 return err;
276         if (flush) {
277                 err = jtag_execute_queue();
278                 if (err != ERROR_OK)
279                         return err;
280         }
281
282         err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);
283         if (err != ERROR_OK)
284                 return err;
285         err = dsp563xx_write_dr_u32(tap, 0, operand, 24, 0);
286         if (err != ERROR_OK)
287                 return err;
288         if (flush) {
289                 err = jtag_execute_queue();
290                 if (err != ERROR_OK)
291                         return err;
292         }
293
294         return ERROR_OK;
295 }