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