1 /***************************************************************************
2 * Copyright (C) 2011 by Rodrigo L. Rosa *
3 * rodrigorosa.LG@gmail.com *
5 * Based on dsp563xx_once.h written by Mathias Kuester *
6 * mkdorg@users.sourceforge.net *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
28 #include "target_type.h"
29 #include "dsp5680xx.h"
31 #define err_check(retval,err_msg) if(retval != ERROR_OK){LOG_ERROR("%s: %s.",__FUNCTION__,err_msg);return retval;}
32 #define err_check_propagate(retval) if(retval!=ERROR_OK){return retval;}
34 // Forward declarations, could try to optimize this.
35 static int eonce_instruction_exec(struct target
* target
, uint8_t instr
, uint8_t rw
, uint8_t go
, uint8_t ex
, uint8_t * eonce_status
);
36 static int eonce_load_TX_RX_to_r0(struct target
* target
);
37 static int eonce_enter_debug_mode(struct target
* target
, uint16_t * eonce_status
);
38 static int eonce_read_status_reg(struct target
* target
, uint16_t * data
);
39 static int eonce_pc_store(struct target
* target
);
40 static int eonce_move_value_to_pc(struct target
* target
, uint32_t value
);
41 static int dsp5680xx_jtag_status(struct target
*target
, uint8_t * status
);
42 static int dsp5680xx_resume(struct target
*target
, int current
, uint32_t address
,int handle_breakpoints
, int debug_execution
);
43 static int dsp5680xx_halt(struct target
*target
);
44 static int dsp5680xx_write(struct target
*target
, uint32_t address
, uint32_t size
, uint32_t count
, const uint8_t * buffer
);
46 int dsp5680xx_execute_queue(void){
48 retval
= jtag_execute_queue();
49 err_check_propagate(retval
);
53 static int eonce_exit_debug_mode(struct target
* target
,uint8_t * eonce_status
){
55 retval
= eonce_instruction_exec(target
,0x1F,0,0,1,eonce_status
);
56 err_check_propagate(retval
);
61 static int dsp5680xx_drscan(struct target
* target
, uint8_t * data_to_shift_into_dr
, uint8_t * data_shifted_out_of_dr
, int len
){
62 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
65 // - data_to_shift_into_dr: This is the data that will be shifted into the JTAG DR reg.
66 // - data_shifted_out_of_dr: The data that will be shifted out of the JTAG DR reg will stored here
67 // - len: Length of the data to be shifted to JTAG DR.
69 // Note: If data_shifted_out_of_dr == NULL, discard incoming bits.
71 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
72 int retval
= ERROR_OK
;
73 if (NULL
== target
->tap
){
75 err_check(retval
,"Invalid tap");
79 err_check(retval
,"dr_len overflow, maxium is 32");
81 //TODO what values of len are valid for jtag_add_plain_dr_scan?
82 //can i send as many bits as i want?
83 //is the casting necessary?
84 jtag_add_plain_dr_scan(len
,data_to_shift_into_dr
,data_shifted_out_of_dr
, TAP_IDLE
);
86 retval
= dsp5680xx_execute_queue();
87 err_check_propagate(retval
);
89 if(data_shifted_out_of_dr
!=NULL
){
90 LOG_DEBUG("Data read (%d bits): 0x%04X",len
,*data_shifted_out_of_dr
);
92 LOG_DEBUG("Data read was discarded.");
96 static int dsp5680xx_irscan(struct target
* target
, uint32_t * data_to_shift_into_ir
, uint32_t * data_shifted_out_of_ir
, uint8_t ir_len
){
97 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
99 // - data_to_shift_into_ir: This is the data that will be shifted into the JTAG IR reg.
100 // - data_shifted_out_of_ir: The data that will be shifted out of the JTAG IR reg will stored here
101 // - len: Length of the data to be shifted to JTAG IR.
103 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
104 int retval
= ERROR_OK
;
105 if (NULL
== target
->tap
){
107 err_check(retval
,"Invalid tap");
109 if (ir_len
!= target
->tap
->ir_length
){
110 LOG_WARNING("%s: Invalid ir_len of core tap. If you are removing protection on flash then do not worry about this warninig.",__FUNCTION__
);
111 //return ERROR_FAIL;//TODO this was commented out to enable unlocking using the master tap. did not find a way to enable the master tap without using tcl.
113 //TODO what values of len are valid for jtag_add_plain_ir_scan?
114 //can i send as many bits as i want?
115 //is the casting necessary?
116 jtag_add_plain_ir_scan(ir_len
,(uint8_t *)data_to_shift_into_ir
,(uint8_t *)data_shifted_out_of_ir
, TAP_IDLE
);
118 retval
= dsp5680xx_execute_queue();
119 err_check_propagate(retval
);
124 static int dsp5680xx_read_core_reg(struct target
* target
, uint8_t reg_addr
, uint16_t * data_read
)
126 //TODO implement a general version of this which matches what openocd uses.
128 uint32_t dummy_data_to_shift_into_dr
;
129 retval
= eonce_instruction_exec(target
,reg_addr
,1,0,0,NULL
);
130 err_check_propagate(retval
);
131 retval
= dsp5680xx_drscan(target
,(uint8_t *)& dummy_data_to_shift_into_dr
,(uint8_t *) data_read
, 8);
132 err_check_propagate(retval
);
133 LOG_DEBUG("Reg. data: 0x%02X.",*data_read
);
137 static int dsp5680xx_target_create(struct target
*target
, Jim_Interp
* interp
){
138 struct dsp5680xx_common
*dsp5680xx
= calloc(1, sizeof(struct dsp5680xx_common
));
139 target
->arch_info
= dsp5680xx
;
143 static int dsp5680xx_init_target(struct command_context
*cmd_ctx
, struct target
*target
){
144 context
.stored_pc
= 0;
146 LOG_DEBUG("target initiated!");
147 //TODO core tap must be enabled before running these commands, currently this is done in the .cfg tcl script.
151 static int dsp5680xx_arch_state(struct target
*target
){
152 LOG_USER("%s not implemented yet.",__FUNCTION__
);
156 int dsp5680xx_target_status(struct target
* target
, uint8_t * jtag_st
, uint16_t * eonce_st
){
157 return target
->state
;
160 static int dsp5680xx_assert_reset(struct target
*target
){
161 //TODO verify the sleeps are necessary
163 target
->state
= TARGET_RESET
;
169 static int dsp5680xx_deassert_reset(struct target
*target
){
171 target
->state
= TARGET_RUNNING
;
175 static int dsp5680xx_poll(struct target
*target
){
178 uint8_t eonce_status
;
180 retval
= dsp5680xx_jtag_status(target
,&jtag_status
);
181 err_check_propagate(retval
);
182 LOG_DEBUG("JTAG 0x%02X",jtag_status
);//TODO remove!!
183 if (jtag_status
== JTAG_STATUS_DEBUG
)
184 if (target
->state
!= TARGET_HALTED
){
185 retval
= eonce_enter_debug_mode(target
,&read_tmp
);
186 err_check_propagate(retval
);
187 eonce_status
= (uint8_t) read_tmp
;
188 if((eonce_status
&EONCE_STAT_MASK
) != DSP5680XX_ONCE_OSCR_DEBUG_M
){
189 LOG_WARNING("%s: Failed to put EOnCE in debug mode. Is flash locked?...",__FUNCTION__
);
190 return ERROR_TARGET_FAILURE
;
192 target
->state
= TARGET_HALTED
;
196 if (jtag_status
== JTAG_STATUS_NORMAL
){
197 if(target
->state
== TARGET_RESET
){
198 retval
= dsp5680xx_halt(target
);
199 err_check_propagate(retval
);
200 retval
= eonce_exit_debug_mode(target
,&eonce_status
);
201 err_check_propagate(retval
);
202 if((eonce_status
&EONCE_STAT_MASK
) != DSP5680XX_ONCE_OSCR_NORMAL_M
){
203 LOG_WARNING("%s: JTAG running, but cannot make EOnCE run. Try resetting...",__FUNCTION__
);
204 return ERROR_TARGET_FAILURE
;
206 target
->state
= TARGET_RUNNING
;
210 if(target
->state
!= TARGET_RUNNING
){
211 retval
= eonce_read_status_reg(target
,&read_tmp
);
212 err_check_propagate(retval
);
213 eonce_status
= (uint8_t) read_tmp
;
214 if((eonce_status
&EONCE_STAT_MASK
) != DSP5680XX_ONCE_OSCR_NORMAL_M
){
215 LOG_WARNING("Inconsistent target status. Restart!");
216 return ERROR_TARGET_FAILURE
;
219 target
->state
= TARGET_RUNNING
;
222 if(jtag_status
== JTAG_STATUS_DEAD
){
223 LOG_ERROR("%s: Cannot communicate with JTAG. Check connection...",__FUNCTION__
);
224 target
->state
= TARGET_UNKNOWN
;
225 return ERROR_TARGET_FAILURE
;
227 if (target
->state
== TARGET_UNKNOWN
){
228 LOG_ERROR("%s: Target status invalid - communication failure",__FUNCTION__
);
229 return ERROR_TARGET_FAILURE
;
234 static int dsp5680xx_jtag_status(struct target
*target
, uint8_t * status
){
235 uint32_t read_from_ir
;
238 instr
= JTAG_INSTR_ENABLE_ONCE
;
239 retval
= dsp5680xx_irscan(target
,& instr
, & read_from_ir
,DSP5680XX_JTAG_CORE_TAP_IRLEN
);
240 err_check_propagate(retval
);
242 *status
= (uint8_t)read_from_ir
;
246 static int eonce_read_status_reg(struct target
* target
, uint16_t * data
){
248 retval
= dsp5680xx_read_core_reg(target
,DSP5680XX_ONCE_OSR
,data
);
249 err_check_propagate(retval
);
253 static int dsp5680xx_obase_addr(struct target
* target
, uint32_t * addr
){
254 // Finds out the default value of the OBASE register address.
256 uint32_t data_to_shift_into_dr
;// just to make jtag happy
257 retval
= eonce_instruction_exec(target
,DSP5680XX_ONCE_OBASE
,1,0,0,NULL
);
258 err_check_propagate(retval
);
259 retval
= dsp5680xx_drscan(target
,(uint8_t *)& data_to_shift_into_dr
,(uint8_t *) addr
, 8);
260 err_check_propagate(retval
);
264 static int dsp5680xx_halt(struct target
*target
){
267 uint16_t eonce_status
;
268 if(target
->state
== TARGET_HALTED
){
269 LOG_USER("Target already halted.");
272 retval
= eonce_enter_debug_mode(target
,&eonce_status
);
273 err_check_propagate(retval
);
274 retval
= dsp5680xx_jtag_status(target
,&jtag_status
);
275 err_check_propagate(retval
);
276 retval
= eonce_pc_store(target
);
277 err_check_propagate(retval
);
278 //TODO is it useful to store the pc?
282 static int dsp5680xx_resume(struct target
*target
, int current
, uint32_t address
,int handle_breakpoints
, int debug_execution
){
283 if(target
->state
== TARGET_RUNNING
){
284 LOG_USER("Target already running.");
289 uint16_t eonce_status
;
291 // Verify that EOnCE is enabled (enable it if necessary)
292 uint16_t data_read_from_dr
= 0;
293 retval
= eonce_read_status_reg(target
,&data_read_from_dr
);
294 err_check_propagate(retval
);
295 if((data_read_from_dr
&DSP5680XX_ONCE_OSCR_DEBUG_M
) != DSP5680XX_ONCE_OSCR_DEBUG_M
){
296 retval
= eonce_enter_debug_mode(target
,NULL
);
297 err_check_propagate(retval
);
300 retval
= eonce_move_value_to_pc(target
,address
);
301 err_check_propagate(retval
);
306 retval
= eonce_exit_debug_mode(target
,(uint8_t *)&eonce_status
);
307 err_check_propagate(retval
);
308 retval
= dsp5680xx_jtag_status(target
,&jtag_status
);
309 err_check_propagate(retval
);
310 if((jtag_status
& 0xff) == JTAG_STATUS_NORMAL
){
315 retval
= ERROR_TARGET_FAILURE
;
316 err_check(retval
,"Failed to resume...");
318 target
->state
= TARGET_RUNNING
;
320 LOG_DEBUG("JTAG status: 0x%02X.",jtag_status
);
321 LOG_DEBUG("EOnCE status: 0x%02X.",eonce_status
);
325 static int jtag_data_read(struct target
* target
, uint32_t * data_read
, int num_bits
){
326 uint32_t bogus_instr
;
327 int retval
= dsp5680xx_drscan(target
,(uint8_t *) & bogus_instr
,(uint8_t *) data_read
,num_bits
);
328 LOG_DEBUG("Data read (%d bits): 0x%04X",num_bits
,*data_read
);//TODO remove this or move to jtagio?
332 #define jtag_data_read8(target,data_read) jtag_data_read(target,data_read,8)
333 #define jtag_data_read16(target,data_read) jtag_data_read(target,data_read,16)
334 #define jtag_data_read32(target,data_read) jtag_data_read(target,data_read,32)
336 static int jtag_data_write(struct target
* target
, uint32_t instr
,int num_bits
, uint32_t * data_read
){
338 uint32_t data_read_dummy
;
339 retval
= dsp5680xx_drscan(target
,(uint8_t *) & instr
,(uint8_t *) & data_read_dummy
,num_bits
);
340 err_check_propagate(retval
);
341 if(data_read
!= NULL
)
342 *data_read
= data_read_dummy
;
346 #define jtag_data_write8(target,instr,data_read) jtag_data_write(target,instr,8,data_read)
347 #define jtag_data_write16(target,instr,data_read) jtag_data_write(target,instr,16,data_read)
348 #define jtag_data_write24(target,instr,data_read) jtag_data_write(target,instr,24,data_read)
349 #define jtag_data_write32(target,instr,data_read) jtag_data_write(target,instr,32,data_read)
351 static int eonce_enter_debug_mode(struct target
* target
, uint16_t * eonce_status
){
353 uint32_t instr
= JTAG_INSTR_DEBUG_REQUEST
;
354 uint32_t ir_out
;//not used, just to make jtag happy.
356 retval
= dsp5680xx_irscan(target
,& instr
,& ir_out
,DSP5680XX_JTAG_CORE_TAP_IRLEN
);
357 err_check_propagate(retval
);
359 // Enable EOnCE module
360 instr
= JTAG_INSTR_ENABLE_ONCE
;
361 //Two rounds of jtag 0x6 (enable eonce) to enable EOnCE.
362 retval
= dsp5680xx_irscan(target
, & instr
, & ir_out
,DSP5680XX_JTAG_CORE_TAP_IRLEN
);
363 err_check_propagate(retval
);
364 retval
= dsp5680xx_irscan(target
, & instr
, & ir_out
,DSP5680XX_JTAG_CORE_TAP_IRLEN
);
365 err_check_propagate(retval
);
366 // Verify that debug mode is enabled
367 uint16_t data_read_from_dr
;
368 retval
= eonce_read_status_reg(target
,&data_read_from_dr
);
369 err_check_propagate(retval
);
370 if((data_read_from_dr
&0x30) == 0x30){
371 LOG_DEBUG("EOnCE successfully entered debug mode.");
372 target
->state
= TARGET_HALTED
;
375 retval
= ERROR_TARGET_FAILURE
;
376 err_check(retval
,"Failed to set EOnCE module to debug mode.");
378 if(eonce_status
!=NULL
)
379 *eonce_status
= data_read_from_dr
;
383 static int eonce_instruction_exec(struct target
* target
, uint8_t instr
, uint8_t rw
, uint8_t go
, uint8_t ex
,uint8_t * eonce_status
){
386 uint8_t instr_with_flags
= instr
|(rw
<<7)|(go
<<6)|(ex
<<5);
387 retval
= jtag_data_write(target
,instr_with_flags
,8,&dr_out_tmp
);
388 err_check_propagate(retval
);
389 if(eonce_status
!= NULL
)
390 *eonce_status
= (uint8_t) dr_out_tmp
;
394 /* Executes DSP instruction */
395 /* wrappers for parameter conversion between eonce_execute_instruction and eonce_execute_instructionX */
396 #define eonce_execute_instruction_1(target,opcode1,opcode2,opcode3) eonce_execute_instruction1(target,opcode1)
397 #define eonce_execute_instruction_2(target,opcode1,opcode2,opcode3) eonce_execute_instruction2(target,opcode1,opcode2)
398 #define eonce_execute_instruction_3(target,opcode1,opcode2,opcode3) eonce_execute_instruction3(target,opcode1,opcode2,opcode3)
399 /* the macro itself */
400 #define eonce_execute_instruction(target,words,opcode1,opcode2,opcode3) eonce_execute_instruction_##words(target,opcode1,opcode2,opcode3)
402 /* Executes one word DSP instruction */
403 static int eonce_execute_instruction1(struct target
* target
, uint16_t opcode
){
405 retval
= eonce_instruction_exec(target
,0x04,0,1,0,NULL
);
406 err_check_propagate(retval
);
407 retval
= jtag_data_write16(target
,opcode
,NULL
);
408 err_check_propagate(retval
);
412 /* Executes two word DSP instruction */
413 static int eonce_execute_instruction2(struct target
* target
,uint16_t opcode1
, uint16_t opcode2
){
415 retval
= eonce_instruction_exec(target
,0x04,0,0,0,NULL
);
416 err_check_propagate(retval
);
417 retval
= jtag_data_write16(target
,opcode1
,NULL
);
418 err_check_propagate(retval
);
419 retval
= eonce_instruction_exec(target
,0x04,0,1,0,NULL
);
420 err_check_propagate(retval
);
421 retval
= jtag_data_write16(target
,opcode2
,NULL
);
422 err_check_propagate(retval
);
426 /* Executes three word DSP instruction */
427 static int eonce_execute_instruction3(struct target
* target
, uint16_t opcode1
,uint16_t opcode2
,uint16_t opcode3
){
429 retval
= eonce_instruction_exec(target
,0x04,0,0,0,NULL
);
430 err_check_propagate(retval
);
431 retval
= jtag_data_write16(target
,opcode1
,NULL
);
432 err_check_propagate(retval
);
433 retval
= eonce_instruction_exec(target
,0x04,0,0,0,NULL
);
434 err_check_propagate(retval
);
435 retval
= jtag_data_write16(target
,opcode2
,NULL
);
436 err_check_propagate(retval
);
437 retval
= eonce_instruction_exec(target
,0x04,0,1,0,NULL
);
438 err_check_propagate(retval
);
439 retval
= jtag_data_write16(target
,opcode3
,NULL
);
440 err_check_propagate(retval
);
444 /* --------------- Real-time data exchange --------------- */
446 The EOnCE Transmit (OTX) and Receive (ORX) registers are data memory mapped, each with an upper and lower 16 bit word.
447 Transmit and receive directions are defined from the core’s perspective.
448 The core writes to the Transmit register and reads the Receive register, and the host through JTAG writes to the Receive register and reads the Transmit register.
449 Both registers have a combined data memory mapped OTXRXSR which provides indication when each may be accessed.
450 ref: eonce_rev.1.0_0208081.pdf@36
453 static int eonce_tx_upper_data(struct target
* target
, uint16_t data
, uint32_t * eonce_status_low
){
455 retval
= eonce_instruction_exec(target
,DSP5680XX_ONCE_ORX1
,0,0,0,NULL
);
456 err_check_propagate(retval
);
457 retval
= jtag_data_write16(target
,data
,eonce_status_low
);
458 err_check_propagate(retval
);
462 /* writes data into lower ORx register of the target */
463 #define eonce_tx_lower_data(target,data) eonce_instruction_exec(target,DSP5680XX_ONCE_ORX,0,0,0,NULL);\
464 jtag_data_write16(target,data)
469 * @param data_read: Returns the data read from the upper OTX register via JTAG.
470 * @return: Returns an error code (see error code documentation)
472 static int eonce_rx_upper_data(struct target
* target
, uint16_t * data_read
)
475 retval
= eonce_instruction_exec(target
,DSP5680XX_ONCE_OTX1
,1,0,0,NULL
);
476 err_check_propagate(retval
);
477 retval
= jtag_data_read16(target
,(uint32_t *)data_read
);
478 err_check_propagate(retval
);
485 * @param data_read: Returns the data read from the lower OTX register via JTAG.
486 * @return: Returns an error code (see error code documentation)
488 static int eonce_rx_lower_data(struct target
* target
,uint16_t * data_read
)
491 retval
= eonce_instruction_exec(target
,DSP5680XX_ONCE_OTX
,1,0,0,NULL
);
492 err_check_propagate(retval
);
493 retval
= jtag_data_read16(target
,(uint32_t *)data_read
);
494 err_check_propagate(retval
);
498 /* -- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -*/
499 /* -- -- -- -- --- -- -- -Core Instructions- -- -- -- --- -- -- -- --- -- -*/
500 /* -- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -*/
501 /* move.l #value,r0 */
502 #define eonce_move_long_to_r0(target,value) eonce_execute_instruction(target,3,0xe418,value&0xffff,value>>16)
504 /* move.l #value,n */
505 #define eonce_move_long_to_n(target,value) eonce_execute_instruction(target,3,0xe41e,value&0xffff,value>>16)
508 #define eonce_move_at_r0_to_y0(target) eonce_execute_instruction(target,1,0xF514,0,0)
511 #define eonce_move_at_r0_to_y1(target) eonce_execute_instruction(target,1,0xF714,0,0)
513 /* move.l x:(r0),y */
514 #define eonce_move_long_at_r0_y(target) eonce_execute_instruction(target,1,0xF734,0,0)
517 #define eonce_move_y0_at_r0(target) eonce_execute_instruction(target,1,0xd514,0,0)
519 /* bfclr #value,x:(r0) */
520 #define eonce_bfclr_at_r0(target,value) eonce_execute_instruction(target,2,0x8040,value,0)
523 #define eonce_move_value_to_y0(target,value) eonce_execute_instruction(target,2,0x8745,value,0)
525 /* move.w y0,x:(r0)+ */
526 #define eonce_move_y0_at_r0_inc(target) eonce_execute_instruction(target,1,0xd500,0,0)
528 /* move.w y0,p:(r0)+ */
529 #define eonce_move_y0_at_pr0_inc(target) eonce_execute_instruction(target,1,0x8560,0,0)
531 /* move.w p:(r0)+,y0 */
532 #define eonce_move_at_pr0_inc_to_y0(target) eonce_execute_instruction(target,1,0x8568,0,0)
534 /* move.w p:(r0)+,y1 */
535 #define eonce_move_at_pr0_inc_to_y1(target) eonce_execute_instruction(target,1,0x8768,0,0)
537 /* move.l #value,r2 */
538 #define eonce_move_long_to_r2(target,value) eonce_execute_instruction(target,3,0xe41A,value&0xffff,value>>16)
541 #define eonce_move_y0_at_r2(target) eonce_execute_instruction(target,1,0xd516,0,0)
543 /* move.w #<value>,x:(r2) */
544 #define eonce_move_value_at_r2(target,value) eonce_execute_instruction(target,2,0x8642,value,0)
546 /* move.w #<value>,x:(r0) */
547 #define eonce_move_value_at_r0(target,value) eonce_execute_instruction(target,2,0x8640,value,0)
549 /* move.w #<value>,x:(R2+<disp>) */
550 #define eonce_move_value_at_r2_disp(target,value,disp) eonce_execute_instruction(target,3,0x8646,value,disp)
552 /* move.w x:(r2),Y0 */
553 #define eonce_move_at_r2_to_y0(target) eonce_execute_instruction(target,1,0xF516,0,0)
555 /* move.w p:(r2)+,y0 */
556 #define eonce_move_at_pr2_inc_to_y0(target) eonce_execute_instruction(target,1,0x856A,0,0)
558 /* move.l #value,r3 */
559 #define eonce_move_long_to_r1(target,value) eonce_execute_instruction(target,3,0xE419,value&0xffff,value>>16)
561 /* move.l #value,r3 */
562 #define eonce_move_long_to_r3(target,value) eonce_execute_instruction(target,3,0xE41B,value&0xffff,value>>16)
564 /* move.w y0,p:(r3)+ */
565 #define eonce_move_y0_at_pr3_inc(target) eonce_execute_instruction(target,1,0x8563,0,0)
567 /* move.w y0,x:(r3) */
568 #define eonce_move_y0_at_r3(target) eonce_execute_instruction(target,1,0xD503,0,0)
571 #define eonce_move_pc_to_r4(target) eonce_execute_instruction(target,1,0xE716,0,0)
574 #define eonce_move_r4_to_y(target) eonce_execute_instruction(target,1,0xe764,0,0)
576 /* move.w p:(r0)+,y0 */
577 #define eonce_move_at_pr0_inc_to_y0(target) eonce_execute_instruction(target,1,0x8568,0,0)
579 /* move.w x:(r0)+,y0 */
580 #define eonce_move_at_r0_inc_to_y0(target) eonce_execute_instruction(target,1,0xf500,0,0)
583 #define eonce_move_at_r0_y0(target) eonce_execute_instruction(target,1,0xF514,0,0)
586 #define eonce_nop(target) eonce_execute_instruction(target,1,0xe700,0,0)
588 /* move.w x:(R2+<disp>),Y0 */
589 #define eonce_move_at_r2_disp_to_y0(target,disp) eonce_execute_instruction(target,2,0xF542,disp,0)
591 /* move.w y1,x:(r2) */
592 #define eonce_move_y1_at_r2(target) eonce_execute_instruction(target,1,0xd716,0,0)
594 /* move.w y1,x:(r0) */
595 #define eonce_move_y1_at_r0(target) eonce_execute_instruction(target,1,0xd714,0,0)
597 /* move.bp y0,x:(r0)+ */
598 #define eonce_move_byte_y0_at_r0(target) eonce_execute_instruction(target,1,0xd5a0,0,0)
600 /* move.w y1,p:(r0)+ */
601 #define eonce_move_y1_at_pr0_inc(target) eonce_execute_instruction(target,1,0x8760,0,0)
603 /* move.w y1,x:(r0)+ */
604 #define eonce_move_y1_at_r0_inc(target) eonce_execute_instruction(target,1,0xD700,0,0)
606 /* move.l #value,y */
607 #define eonce_move_long_to_y(target,value) eonce_execute_instruction(target,3,0xe417,value&0xffff,value>>16)
609 static int eonce_move_value_to_pc(struct target
* target
, uint32_t value
)
611 if (!(target
->state
== TARGET_HALTED
)){
612 LOG_ERROR("Target must be halted to move PC. Target state = %d.",target
->state
);
613 return ERROR_TARGET_NOT_HALTED
;
616 retval
= eonce_execute_instruction(target
,3,0xE71E,value
&0xffff,value
>>16);
617 err_check_propagate(retval
);
621 static int eonce_load_TX_RX_to_r0(struct target
* target
)
623 //TODO add error control
625 int retval
= dsp5680xx_obase_addr(target
,& obase_addr
);
626 eonce_move_long_to_r0(target
,((MC568013_EONCE_TX_RX_ADDR
)+(obase_addr
<<16)));
630 static int eonce_load_TX_RX_high_to_r0(struct target
* target
)
632 //TODO add error control
634 int retval
= dsp5680xx_obase_addr(target
,& obase_addr
);
635 err_check_propagate(retval
);
636 if(!(obase_addr
&& 0xff)){
637 LOG_USER("%s: OBASE address read as 0x%04X instead of 0xFF.",__FUNCTION__
,obase_addr
);
640 eonce_move_long_to_r0(target
,((MC568013_EONCE_TX1_RX1_HIGH_ADDR
)+(obase_addr
<<16)));
641 err_check_propagate(retval
);
645 static int eonce_pc_store(struct target
* target
){
648 retval
= eonce_move_pc_to_r4(target
);
649 err_check_propagate(retval
);
650 retval
= eonce_move_r4_to_y(target
);
651 err_check_propagate(retval
);
652 retval
= eonce_load_TX_RX_to_r0(target
);
653 err_check_propagate(retval
);
654 retval
= eonce_move_y0_at_r0(target
);
655 err_check_propagate(retval
);
656 retval
= eonce_rx_lower_data(target
,(uint16_t *)&tmp
);
657 err_check_propagate(retval
);
658 LOG_USER("PC value: 0x%06X\n",tmp
);
659 context
.stored_pc
= (uint32_t)tmp
;
663 static int dsp5680xx_convert_address(uint32_t * address
, int * pmem
){
664 // Distinguish data memory (x:) from program memory (p:) by the address.
665 // Addresses over S_FILE_DATA_OFFSET are considered (x:) memory.
666 if(*address
>= S_FILE_DATA_OFFSET
){
668 if(((*address
)&0xff0000)!=0xff0000)
669 *address
-= S_FILE_DATA_OFFSET
;
674 static int dsp5680xx_read_16_single(struct target
* target
, uint32_t address
, uint16_t * data_read
, int r_pmem
){
675 //TODO add error control!
677 retval
= eonce_move_long_to_r0(target
,address
);
678 err_check_propagate(retval
);
680 retval
= eonce_move_at_pr0_inc_to_y0(target
);
682 retval
= eonce_move_at_r0_to_y0(target
);
683 err_check_propagate(retval
);
684 retval
= eonce_load_TX_RX_to_r0(target
);
685 err_check_propagate(retval
);
686 retval
= eonce_move_y0_at_r0(target
);
687 err_check_propagate(retval
);
688 // at this point the data i want is at the reg eonce can read
689 retval
= eonce_rx_lower_data(target
,data_read
);
690 err_check_propagate(retval
);
691 LOG_DEBUG("%s: Data read from 0x%06X: 0x%04X",__FUNCTION__
, address
,*data_read
);
695 static int dsp5680xx_read_32_single(struct target
* target
, uint32_t address
, uint32_t * data_read
, int r_pmem
){
697 address
= (address
& 0xFFFFFE);
698 // Get data to an intermediate register
699 retval
= eonce_move_long_to_r0(target
,address
);
700 err_check_propagate(retval
);
702 retval
= eonce_move_at_pr0_inc_to_y0(target
);
703 err_check_propagate(retval
);
704 retval
= eonce_move_at_pr0_inc_to_y1(target
);
705 err_check_propagate(retval
);
707 retval
= eonce_move_at_r0_inc_to_y0(target
);
708 err_check_propagate(retval
);
709 retval
= eonce_move_at_r0_to_y1(target
);
710 err_check_propagate(retval
);
712 // Get lower part of data to TX/RX
713 retval
= eonce_load_TX_RX_to_r0(target
);
714 err_check_propagate(retval
);
715 retval
= eonce_move_y0_at_r0_inc(target
); // This also load TX/RX high to r0
716 err_check_propagate(retval
);
717 // Get upper part of data to TX/RX
718 retval
= eonce_move_y1_at_r0(target
);
719 err_check_propagate(retval
);
720 // at this point the data i want is at the reg eonce can read
721 retval
= eonce_rx_lower_data(target
,(uint16_t * )data_read
);
722 err_check_propagate(retval
);
724 retval
= eonce_rx_upper_data(target
,&tmp
);
725 err_check_propagate(retval
);
726 *data_read
= (((*data_read
)<<16) | tmp
);
730 static int dsp5680xx_read(struct target
* target
, uint32_t address
, unsigned size
, unsigned count
, uint8_t * buffer
){
731 if(target
->state
!= TARGET_HALTED
){
732 LOG_USER("Target must be halted.");
735 uint32_t * buff32
= (uint32_t *) buffer
;
736 uint16_t * buff16
= (uint16_t *) buffer
;
737 int retval
= ERROR_OK
;
741 retval
= dsp5680xx_convert_address(&address
, &pmem
);
742 err_check_propagate(retval
);
744 for (unsigned i
=0; i
<count
; i
++){
748 retval
= dsp5680xx_read_16_single(target
, address
+ i
/2, &tmp_wrd
, pmem
);
749 buffer
[i
] = (uint8_t) (tmp_wrd
>>8);
750 buffer
[i
+1] = (uint8_t) (tmp_wrd
&0xff);
754 retval
= dsp5680xx_read_16_single(target
, address
+ i
, buff16
+ i
, pmem
);
757 retval
= dsp5680xx_read_32_single(target
, address
+ 2*i
, buff32
+ i
, pmem
);
760 LOG_USER("%s: Invalid read size.",__FUNCTION__
);
763 err_check_propagate(retval
);
769 static int dsp5680xx_write_16_single(struct target
*target
, uint32_t address
, uint16_t data
, uint8_t w_pmem
){
771 retval
= eonce_move_long_to_r0(target
,address
);
772 err_check_propagate(retval
);
774 retval
= eonce_move_value_to_y0(target
,data
);
775 err_check_propagate(retval
);
776 retval
= eonce_move_y0_at_pr0_inc(target
);
777 err_check_propagate(retval
);
779 retval
= eonce_move_value_at_r0(target
,data
);
780 err_check_propagate(retval
);
786 static int dsp5680xx_write_32_single(struct target
*target
, uint32_t address
, uint32_t data
, int w_pmem
){
788 retval
= eonce_move_long_to_r0(target
,address
);
789 err_check_propagate(retval
);
790 retval
= eonce_move_long_to_y(target
,data
);
791 err_check_propagate(retval
);
793 retval
= eonce_move_y0_at_pr0_inc(target
);
795 retval
= eonce_move_y0_at_r0_inc(target
);
796 err_check_propagate(retval
);
798 retval
= eonce_move_y1_at_pr0_inc(target
);
800 retval
= eonce_move_y1_at_r0_inc(target
);
801 err_check_propagate(retval
);
805 static int dsp5680xx_write_8(struct target
* target
, uint32_t address
, uint32_t count
, uint8_t * data
, int pmem
){
806 if(target
->state
!= TARGET_HALTED
){
807 LOG_ERROR("%s: Target must be halted.",__FUNCTION__
);
811 uint16_t * data_w
= (uint16_t *)data
;
814 int counter_reset
= FLUSH_COUNT_WRITE
;
815 int counter
= counter_reset
;
817 for(iter
= 0; iter
<count
/2; iter
++){
820 counter
= counter_reset
;
823 retval
= dsp5680xx_write_16_single(target
,address
+iter
,data_w
[iter
], pmem
);
824 if(retval
!= ERROR_OK
){
825 LOG_ERROR("%s: Could not write to p:0x%04X",__FUNCTION__
,address
);
833 // Only one byte left, let's not overwrite the other byte (mem is 16bit)
834 // Need to retrieve the part we do not want to overwrite.
836 if((count
==1)||(count
%2)){
837 retval
= dsp5680xx_read(target
,address
+iter
,1,1,(uint8_t *)&data_old
);
838 err_check_propagate(retval
);
840 data_old
=(((data_old
&0xff)<<8)|data
[0]);// preserve upper byte
842 data_old
=(((data_old
&0xff)<<8)|data
[2*iter
+1]);
843 retval
= dsp5680xx_write_16_single(target
,address
+iter
,data_old
, pmem
);
844 err_check_propagate(retval
);
849 static int dsp5680xx_write_16(struct target
* target
, uint32_t address
, uint32_t count
, uint16_t * data
, int pmem
){
850 int retval
= ERROR_OK
;
851 if(target
->state
!= TARGET_HALTED
){
852 retval
= ERROR_TARGET_NOT_HALTED
;
853 err_check(retval
,"Target must be halted.");
857 int counter_reset
= FLUSH_COUNT_WRITE
;
858 int counter
= counter_reset
;
860 for(iter
= 0; iter
<count
; iter
++){
863 counter
= counter_reset
;
865 retval
= dsp5680xx_write_16_single(target
,address
+iter
,data
[iter
], pmem
);
866 if(retval
!= ERROR_OK
){
867 LOG_ERROR("%s: Could not write to p:0x%04X",__FUNCTION__
,address
);
877 static int dsp5680xx_write_32(struct target
* target
, uint32_t address
, uint32_t count
, uint32_t * data
, int pmem
){
878 int retval
= ERROR_OK
;
879 if(target
->state
!= TARGET_HALTED
){
880 retval
= ERROR_TARGET_NOT_HALTED
;
881 err_check(retval
,"Target must be halted.");
885 int counter_reset
= FLUSH_COUNT_WRITE
;
886 int counter
= counter_reset
;
888 for(iter
= 0; iter
<count
; iter
++){
891 counter
= counter_reset
;
893 retval
= dsp5680xx_write_32_single(target
,address
+(iter
<<1),data
[iter
], pmem
);
894 if(retval
!= ERROR_OK
){
895 LOG_ERROR("%s: Could not write to p:0x%04X",__FUNCTION__
,address
);
906 static int dsp5680xx_write(struct target
*target
, uint32_t address
, uint32_t size
, uint32_t count
, const uint8_t * buffer
){
907 //TODO Cannot write 32bit to odd address, will write 0x1234567 to as 0x5678 0x0012
908 if(target
->state
!= TARGET_HALTED
){
909 LOG_USER("Target must be halted.");
914 retval
= dsp5680xx_convert_address(&address
, &p_mem
);
915 err_check_propagate(retval
);
919 retval
= dsp5680xx_write_8(target
, address
, count
,(uint8_t *) buffer
, p_mem
);
922 retval
= dsp5680xx_write_16(target
, address
, count
, (uint16_t *)buffer
, p_mem
);
925 retval
= dsp5680xx_write_32(target
, address
, count
, (uint32_t *)buffer
, p_mem
);
928 retval
= ERROR_TARGET_DATA_ABORT
;
929 err_check(retval
,"Invalid data size.")
935 static int dsp5680xx_bulk_write_memory(struct target
* target
,uint32_t address
, uint32_t aligned
, const uint8_t * buffer
){
936 LOG_ERROR("Not implemented yet.");
940 // Writes to pram at address
941 // r3 holds the destination address-> p:(r3)
942 // r2 hold 0xf151 to flash a led (probably cannot see it due to high freq.)
943 // r0 holds TX/RX address.
944 //0x00000073 0x8A44FFFE017B brclr #1,X:(R0-2),*-2
945 //0x00000076 0xE700 nop
946 //0x00000077 0xF514 move.w X:(R0),Y0
947 //0x00000078 0xE700 nop
948 //0x00000079 0x8563 move.w Y0,P:(R3)+
949 //0x0000007A 0x84420003 bfchg #3,X:(R2)
950 //0x0000007C 0xA976 bra *-9
951 uint16_t pgm_write_pram
[] = {0x8A44,0xFFFE,0x017D,0xE700,0xF514,0xE700,0x8563,0x8442,0x0003,0xA976};
952 uint16_t pgm_write_pram_length
= 10;
954 static int dsp5680xx_write_buffer(struct target
* target
, uint32_t address
, uint32_t size
, const uint8_t * buffer
){
955 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
956 // this solution works, but it's slow. it flushes USB all the time.
957 return dsp5680xx_write(target
, address
, 1, size
, buffer
);
958 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
961 static int dsp5680xx_read_buffer(struct target
* target
, uint32_t address
, uint32_t size
, uint8_t * buffer
){
962 if(target
->state
!= TARGET_HALTED
){
963 LOG_USER("Target must be halted.");
967 int retval
= ERROR_OK
;
971 retval
= dsp5680xx_convert_address(&address
, &pmem
);
972 err_check_propagate(retval
);
974 for (unsigned i
=0; i
<size
; i
++)
976 retval
= dsp5680xx_read_16_single(target
, address
+ i
/2, &tmp_wrd
, pmem
);
977 err_check_propagate(retval
);
978 //TODO find a better solution. endiannes differs from normal read, otherwise the openocd crc would do weird stuff.
979 buffer
[i
+1] = (uint8_t) (tmp_wrd
>>8);
980 buffer
[i
] = (uint8_t) (tmp_wrd
&0xff);
985 static int dsp5680xx_checksum_memory(struct target
* target
, uint32_t address
, uint32_t size
, uint32_t * checksum
){
986 return ERROR_FAIL
; //this makes openocd do the crc
989 int dsp5680xx_f_SIM_reset(struct target
* target
){
990 int retval
= ERROR_OK
;
991 uint16_t sim_cmd
= SIM_CMD_RESET
;
993 if(strcmp(target
->tap
->chip
,"dsp568013")==0){
994 sim_addr
= MC568013_SIM_BASE_ADDR
+S_FILE_DATA_OFFSET
;
995 retval
= dsp5680xx_write(target
,sim_addr
,1,2,(const uint8_t *)&sim_cmd
);
996 err_check_propagate(retval
);
1002 static int dsp5680xx_soft_reset_halt(struct target
*target
){
1003 //TODO is this what this function is expected to do...?
1005 retval
= dsp5680xx_halt(target
);
1006 err_check_propagate(retval
);
1007 retval
= dsp5680xx_f_SIM_reset(target
);
1008 err_check_propagate(retval
);
1012 int dsp5680xx_f_protect_check(struct target
* target
, uint8_t * protected) {
1015 if (dsp5680xx_target_status(target
,NULL
,NULL
) != TARGET_HALTED
){
1016 retval
= dsp5680xx_halt(target
);
1017 err_check_propagate(retval
);
1019 retval
= eonce_load_TX_RX_high_to_r0(target
);
1020 err_check_propagate(retval
);
1021 retval
= eonce_move_value_to_y0(target
,0x1234);
1022 err_check_propagate(retval
);
1023 retval
= eonce_move_y0_at_r0(target
);
1024 err_check_propagate(retval
);
1025 retval
= eonce_rx_upper_data(target
,&i
);
1026 err_check_propagate(retval
);
1027 retval
= eonce_move_value_to_y0(target
,0x4321);
1028 err_check_propagate(retval
);
1029 retval
= eonce_move_y0_at_r0(target
);
1030 err_check_propagate(retval
);
1031 retval
= eonce_rx_upper_data(target
,&j
);
1032 err_check_propagate(retval
);
1034 *protected = (uint8_t) ((i
!=0x1234)||(j
!=0x4321));
1038 static int dsp5680xx_f_execute_command(struct target
* target
, uint16_t command
, uint32_t address
, uint16_t * hfm_ustat
, int pmem
){
1040 retval
= eonce_load_TX_RX_high_to_r0(target
);
1041 err_check_propagate(retval
);
1042 retval
= eonce_move_long_to_r2(target
,HFM_BASE_ADDR
);
1043 err_check_propagate(retval
);
1047 retval
= eonce_move_at_r2_disp_to_y0(target
,HFM_USTAT
); // read HMF_USTAT
1048 err_check_propagate(retval
);
1049 retval
= eonce_move_y0_at_r0(target
);
1050 err_check_propagate(retval
);
1051 retval
= eonce_rx_upper_data(target
,&i
);
1052 err_check_propagate(retval
);
1053 if((watchdog
--)==1){
1054 retval
= ERROR_TARGET_FAILURE
;
1055 err_check(retval
,"FM execute command failed.");
1057 }while (!(i
&0x40)); // wait until current command is complete
1058 retval
= eonce_move_value_at_r2_disp(target
,0x00,HFM_CNFG
); // write to HFM_CNFG (lock=0, select bank) -- flash_desc.bank&0x03,0x01 == 0x00,0x01 ???
1059 err_check_propagate(retval
);
1060 retval
= eonce_move_value_at_r2_disp(target
,0x04,HFM_USTAT
); // write to HMF_USTAT, clear PVIOL, ACCERR & BLANK bits
1061 err_check_propagate(retval
);
1062 retval
= eonce_move_value_at_r2_disp(target
,0x10,HFM_USTAT
); // clear only one bit at a time
1063 err_check_propagate(retval
);
1064 retval
= eonce_move_value_at_r2_disp(target
,0x20,HFM_USTAT
);
1065 err_check_propagate(retval
);
1066 retval
= eonce_move_value_at_r2_disp(target
,0x00,HFM_PROT
); // write to HMF_PROT, clear protection
1067 err_check_propagate(retval
);
1068 retval
= eonce_move_value_at_r2_disp(target
,0x00,HFM_PROTB
); // write to HMF_PROTB, clear protection
1069 err_check_propagate(retval
);
1070 retval
= eonce_move_long_to_r3(target
,address
); // write to the flash block
1071 err_check_propagate(retval
);
1073 retval
= eonce_move_y0_at_pr3_inc(target
);
1074 err_check_propagate(retval
);
1076 retval
= eonce_move_y0_at_r3(target
);
1077 err_check_propagate(retval
);
1079 retval
= eonce_move_value_at_r2_disp(target
,command
,HFM_CMD
); // write command to the HFM_CMD reg
1080 err_check_propagate(retval
);
1081 retval
= eonce_move_value_at_r2_disp(target
,0x80,HFM_USTAT
); // start the command
1082 err_check_propagate(retval
);
1085 retval
= eonce_move_at_r2_disp_to_y0(target
,HFM_USTAT
); // read HMF_USTAT
1086 err_check_propagate(retval
);
1087 retval
= eonce_move_y0_at_r0(target
);
1088 err_check_propagate(retval
);
1089 retval
= eonce_rx_upper_data(target
,&i
);
1090 err_check_propagate(retval
);
1091 if((watchdog
--)==1){
1092 retval
= ERROR_TARGET_FAILURE
;
1093 err_check(retval
,"FM execution did not finish.");
1095 }while (!(i
&0x40)); // wait until the command is complete
1100 static int eonce_set_hfmdiv(struct target
* target
){
1103 retval
= eonce_move_long_to_r2(target
,HFM_BASE_ADDR
);
1104 err_check_propagate(retval
);
1105 retval
= eonce_load_TX_RX_high_to_r0(target
);
1106 err_check_propagate(retval
);
1107 retval
= eonce_move_at_r2_to_y0(target
);// read HFM_CLKD
1108 err_check_propagate(retval
);
1109 retval
= eonce_move_y0_at_r0(target
);
1110 err_check_propagate(retval
);
1111 retval
= eonce_rx_upper_data(target
,&i
);
1112 err_check_propagate(retval
);
1113 unsigned int hfm_at_wrong_value
= 0;
1114 if ((i
&0x7f)!=HFM_CLK_DEFAULT
) {
1115 LOG_DEBUG("HFM CLK divisor contained incorrect value (0x%02X).",i
&0x7f);
1116 hfm_at_wrong_value
= 1;
1118 LOG_DEBUG("HFM CLK divisor was already set to correct value (0x%02X).",i
&0x7f);
1121 retval
= eonce_move_value_at_r2(target
,HFM_CLK_DEFAULT
); // write HFM_CLKD
1122 err_check_propagate(retval
);
1123 retval
= eonce_move_at_r2_to_y0(target
); // verify HFM_CLKD
1124 err_check_propagate(retval
);
1125 retval
= eonce_move_y0_at_r0(target
);
1126 err_check_propagate(retval
);
1127 retval
= eonce_rx_upper_data(target
,&i
);
1128 err_check_propagate(retval
);
1129 if (i
!=(0x80|(HFM_CLK_DEFAULT
&0x7f))) {
1130 retval
= ERROR_TARGET_FAILURE
;
1131 err_check(retval
,"Unable to set HFM CLK divisor.");
1133 if(hfm_at_wrong_value
)
1134 LOG_DEBUG("HFM CLK divisor set to 0x%02x.",i
&0x7f);
1138 int dsp5680xx_f_erase_check(struct target
* target
, uint8_t * erased
){
1141 if (dsp5680xx_target_status(target
,NULL
,NULL
) != TARGET_HALTED
){
1142 retval
= dsp5680xx_halt(target
);
1143 err_check_propagate(retval
);
1145 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1147 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1149 retval
= dsp5680xx_f_protect_check(target
,&protected);
1150 err_check_propagate(retval
);
1152 retval
= ERROR_TARGET_FAILURE
;
1153 err_check(retval
,"Failed to erase, flash is still protected.");
1155 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1157 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1158 retval
= eonce_set_hfmdiv(target
);
1159 err_check_propagate(retval
);
1161 // Check if chip is already erased.
1162 // Since only mass erase is currently implemented, only the first sector is checked (assuming no code will leave it unused)
1163 retval
= dsp5680xx_f_execute_command(target
,HFM_ERASE_VERIFY
,HFM_FLASH_BASE_ADDR
+0*HFM_SECTOR_SIZE
,&hfm_ustat
,1); // blank check
1164 err_check_propagate(retval
);
1165 if (hfm_ustat
&HFM_USTAT_MASK_PVIOL_ACCER
){
1166 retval
= ERROR_TARGET_FAILURE
;
1167 err_check(retval
,"pviol and/or accer bits set. EraseVerify HFM command execution error");;
1170 *erased
= (uint8_t)(hfm_ustat
&HFM_USTAT_MASK_BLANK
);
1174 int dsp5680xx_f_erase(struct target
* target
, int first
, int last
){
1175 //TODO implement erasing individual sectors.
1178 retval
= ERROR_FAIL
;
1179 err_check(retval
,"Sector erasing not implemented. Call with first=last=0.");
1181 if (dsp5680xx_target_status(target
,NULL
,NULL
) != TARGET_HALTED
){
1182 retval
= dsp5680xx_halt(target
);
1183 err_check_propagate(retval
);
1185 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1187 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1188 retval
= dsp5680xx_f_SIM_reset(target
);
1189 err_check_propagate(retval
);
1190 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1192 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1194 retval
= dsp5680xx_f_protect_check(target
,&protected);
1195 err_check_propagate(retval
);
1197 retval
= ERROR_TARGET_FAILURE
;
1198 err_check(retval
,"Cannot flash, security is still enabled.");
1200 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1202 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1203 retval
= eonce_set_hfmdiv(target
);
1204 err_check_propagate(retval
);
1206 // Check if chip is already erased.
1207 // Since only mass erase is currently implemented, only the first sector is checked (assuming no code will leave it unused)
1209 retval
= dsp5680xx_f_erase_check(target
,&erased
);
1210 err_check_propagate(retval
);
1212 LOG_USER("Flash blank - mass erase skipped.");
1214 // Execute mass erase command.
1216 uint16_t hfm_cmd
= HFM_MASS_ERASE
;
1217 retval
= dsp5680xx_f_execute_command(target
,hfm_cmd
,HFM_FLASH_BASE_ADDR
+0*HFM_SECTOR_SIZE
,&hfm_ustat
,1);
1218 err_check_propagate(retval
);
1219 if (hfm_ustat
&HFM_USTAT_MASK_PVIOL_ACCER
){
1220 retval
= ERROR_TARGET_FAILURE
;
1221 err_check(retval
,"pviol and/or accer bits set. HFM command execution error");
1223 // Verify flash was successfully erased.
1224 retval
= dsp5680xx_f_erase_check(target
,&erased
);
1225 err_check_propagate(retval
);
1226 if(retval
== ERROR_OK
){
1228 LOG_USER("Flash mass erased and checked blank.");
1230 LOG_WARNING("Flash mass erased, but still not blank!");
1236 // Algorithm for programming normal p: flash
1237 // Follow state machine from "56F801x Peripheral Reference Manual"@163.
1238 // Registers to set up before calling:
1239 // r0: TX/RX high address.
1240 // r2: FM module base address.
1241 // r3: Destination address in flash.
1243 // hfm_wait: // wait for command to finish
1244 // brclr #0x40,x:(r2+0x13),hfm_wait
1245 // rx_check: // wait for input buffer full
1246 // brclr #0x01,x:(r0-2),rx_check
1247 // move.w x:(r0),y0 // read from Rx buffer
1248 // move.w y0,p:(r3)+
1249 // move.w #0x20,x:(r2+0x14) // write PGM command
1250 // move.w #0x80,x:(r2+0x13) // start the command
1251 // brclr #0x20,X:(R2+0x13),accerr_check // protection violation check
1252 // bfset #0x20,X:(R2+0x13) // clear pviol
1255 // brclr #0x10,X:(R2+0x13),hfm_wait // access error check
1256 // bfset #0x10,X:(R2+0x13) // clear accerr
1257 // bra hfm_wait // loop
1258 //0x00000073 0x8A460013407D brclr #0x40,X:(R2+0x13),*+0
1259 //0x00000076 0xE700 nop
1260 //0x00000077 0xE700 nop
1261 //0x00000078 0x8A44FFFE017B brclr #1,X:(R0-2),*-2
1262 //0x0000007B 0xE700 nop
1263 //0x0000007C 0xF514 move.w X:(R0),Y0
1264 //0x0000007D 0x8563 move.w Y0,P:(R3)+
1265 //0x0000007E 0x864600200014 move.w #0x20,X:(R2+0x14)
1266 //0x00000081 0x864600800013 move.w #0x80,X:(R2+0x13)
1267 //0x00000084 0x8A4600132004 brclr #0x20,X:(R2+0x13),*+7
1268 //0x00000087 0x824600130020 bfset #0x20,X:(R2+0x13)
1269 //0x0000008A 0xA968 bra *-23
1270 //0x0000008B 0x8A4600131065 brclr #0x10,X:(R2+0x13),*-24
1271 //0x0000008E 0x824600130010 bfset #0x10,X:(R2+0x13)
1272 //0x00000091 0xA961 bra *-30
1273 const uint16_t pgm_write_pflash
[] = {0x8A46,0x0013,0x407D,0xE700,0xE700,0x8A44,0xFFFE,0x017B,0xE700,0xF514,0x8563,0x8646,0x0020,0x0014,0x8646,0x0080,0x0013,0x8A46,0x0013,0x2004,0x8246,0x0013,0x0020,0xA968,0x8A46,0x0013,0x1065,0x8246,0x0013,0x0010,0xA961};
1274 const uint32_t pgm_write_pflash_length
= 31;
1276 int dsp5680xx_f_wr(struct target
* target
, uint8_t *buffer
, uint32_t address
, uint32_t count
){
1277 int retval
= ERROR_OK
;
1278 uint16_t* buff16
= (uint16_t *) buffer
;
1279 if (dsp5680xx_target_status(target
,NULL
,NULL
) != TARGET_HALTED
){
1280 retval
= dsp5680xx_halt(target
);
1281 err_check_propagate(retval
);
1283 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1284 // Check if flash is erased
1285 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1287 retval
= dsp5680xx_f_erase_check(target
,&erased
);
1288 err_check_propagate(retval
);
1290 retval
= ERROR_FAIL
;
1291 err_check(retval
,"Flash must be erased before flashing.");
1293 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1294 // Download the pgm that flashes.
1295 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1296 uint32_t my_favourite_ram_address
= 0x8700; // This seems to be a safe address. This one is the one used by codewarrior in 56801x_flash.cfg
1297 retval
= dsp5680xx_write(target
, my_favourite_ram_address
, 1, pgm_write_pflash_length
*2,(uint8_t *) pgm_write_pflash
);
1298 err_check_propagate(retval
);
1299 retval
= dsp5680xx_execute_queue();
1300 err_check_propagate(retval
);
1301 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1303 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1304 retval
= eonce_set_hfmdiv(target
);
1305 err_check_propagate(retval
);
1306 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1307 // Setup registers needed by pgm_write_pflash
1308 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1309 retval
= eonce_move_long_to_r3(target
,address
); // Destination address to r3
1310 err_check_propagate(retval
);
1311 eonce_load_TX_RX_high_to_r0(target
); // TX/RX reg address to r0
1312 err_check_propagate(retval
);
1313 retval
= eonce_move_long_to_r2(target
,HFM_BASE_ADDR
);// FM base address to r2
1314 err_check_propagate(retval
);
1315 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1316 // Run flashing program.
1317 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1318 retval
= eonce_move_value_at_r2_disp(target
,0x00,HFM_CNFG
); // write to HFM_CNFG (lock=0, select bank)
1319 err_check_propagate(retval
);
1320 retval
= eonce_move_value_at_r2_disp(target
,0x04,HFM_USTAT
);// write to HMF_USTAT, clear PVIOL, ACCERR & BLANK bits
1321 err_check_propagate(retval
);
1322 retval
= eonce_move_value_at_r2_disp(target
,0x10,HFM_USTAT
);// clear only one bit at a time
1323 err_check_propagate(retval
);
1324 retval
= eonce_move_value_at_r2_disp(target
,0x20,HFM_USTAT
);
1325 err_check_propagate(retval
);
1326 retval
= eonce_move_value_at_r2_disp(target
,0x00,HFM_PROT
);// write to HMF_PROT, clear protection
1327 err_check_propagate(retval
);
1328 retval
= eonce_move_value_at_r2_disp(target
,0x00,HFM_PROTB
);// write to HMF_PROTB, clear protection
1329 err_check_propagate(retval
);
1331 //TODO implement handling of odd number of words.
1332 retval
= ERROR_FAIL
;
1333 err_check(retval
,"Cannot handle odd number of words.");
1335 uint32_t drscan_data
;
1336 retval
= eonce_tx_upper_data(target
,buff16
[0],&drscan_data
);
1337 err_check_propagate(retval
);
1339 retval
= dsp5680xx_resume(target
,0,my_favourite_ram_address
,0,0);
1340 err_check_propagate(retval
);
1342 int counter_reset
= FLUSH_COUNT_FLASH
;
1343 int counter
= counter_reset
;
1345 for(uint32_t i
=1; (i
<count
/2)&&(i
<HFM_SIZE_REAL
); i
++){
1348 counter
= counter_reset
;
1350 retval
= eonce_tx_upper_data(target
,buff16
[i
],&drscan_data
);
1351 if(retval
!=ERROR_OK
){
1353 err_check_propagate(retval
);
1361 int dsp5680xx_f_unlock(struct target
* target
){
1363 if(target
->tap
->enabled
){
1364 //TODO find a way to switch to the master tap here.
1365 LOG_ERROR("Master tap must be enabled to unlock flash.");
1366 return ERROR_TARGET_FAILURE
;
1368 uint32_t data_to_shift_in
= MASTER_TAP_CMD_FLASH_ERASE
;
1369 uint32_t data_shifted_out
;
1370 retval
= dsp5680xx_irscan(target
,&data_to_shift_in
,&data_shifted_out
,8);
1371 err_check_propagate(retval
);
1372 data_to_shift_in
= HFM_CLK_DEFAULT
;
1373 retval
= dsp5680xx_drscan(target
,((uint8_t *) & data_to_shift_in
),((uint8_t *)&data_shifted_out
),8);
1374 err_check_propagate(retval
);
1378 int dsp5680xx_f_lock(struct target
* target
){
1380 uint16_t lock_word
[] = {HFM_LOCK_FLASH
,HFM_LOCK_FLASH
};
1381 retval
= dsp5680xx_f_wr(target
,(uint8_t *)(lock_word
),HFM_LOCK_ADDR_L
,4);
1382 err_check_propagate(retval
);
1386 static int dsp5680xx_step(struct target
* target
,int current
, uint32_t address
, int handle_breakpoints
){
1387 err_check(ERROR_FAIL
,"Not implemented yet.");
1390 /** Holds methods for dsp5680xx targets. */
1391 struct target_type dsp5680xx_target
= {
1392 .name
= "dsp5680xx",
1394 .poll
= dsp5680xx_poll
,
1395 .arch_state
= dsp5680xx_arch_state
,
1397 .target_request_data
= NULL
,
1399 .halt
= dsp5680xx_halt
,
1400 .resume
= dsp5680xx_resume
,
1401 .step
= dsp5680xx_step
,
1403 .write_buffer
= dsp5680xx_write_buffer
,
1404 .read_buffer
= dsp5680xx_read_buffer
,
1406 .assert_reset
= dsp5680xx_assert_reset
,
1407 .deassert_reset
= dsp5680xx_deassert_reset
,
1408 .soft_reset_halt
= dsp5680xx_soft_reset_halt
,
1410 .read_memory
= dsp5680xx_read
,
1411 .write_memory
= dsp5680xx_write
,
1412 .bulk_write_memory
= dsp5680xx_bulk_write_memory
,
1414 .checksum_memory
= dsp5680xx_checksum_memory
,
1416 .target_create
= dsp5680xx_target_create
,
1417 .init_target
= dsp5680xx_init_target
,