diff options
Diffstat (limited to 'src/target/embeddedice.c')
-rw-r--r-- | src/target/embeddedice.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c index f601c1eb..e86a81cd 100644 --- a/src/target/embeddedice.c +++ b/src/target/embeddedice.c @@ -274,6 +274,75 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) return ERROR_OK; } +/* receive <size> words of 32 bit from the DCC + * we pretend the target is always going to be fast enough + * (relative to the JTAG clock), so we don't need to handshake + */ +int embeddedice_receive(arm_jtag_t *jtag_info, u32 *data, u32 size) +{ + u8 reg_addr = 0x5; + scan_field_t fields[3]; + + jtag_add_end_state(TAP_RTI); + arm_jtag_scann(jtag_info, 0x2); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); + + fields[0].device = jtag_info->chain_pos; + fields[0].num_bits = 32; + fields[0].out_value = NULL; + fields[0].out_mask = NULL; + fields[0].in_value = NULL; + fields[0].in_check_value = NULL; + fields[0].in_check_mask = NULL; + fields[0].in_handler = NULL; + fields[0].in_handler_priv = NULL; + + fields[1].device = jtag_info->chain_pos; + fields[1].num_bits = 5; + fields[1].out_value = malloc(1); + buf_set_u32(fields[1].out_value, 0, 5, reg_addr); + fields[1].out_mask = NULL; + fields[1].in_value = NULL; + fields[1].in_check_value = NULL; + fields[1].in_check_mask = NULL; + fields[1].in_handler = NULL; + fields[1].in_handler_priv = NULL; + + fields[2].device = jtag_info->chain_pos; + fields[2].num_bits = 1; + fields[2].out_value = malloc(1); + buf_set_u32(fields[2].out_value, 0, 1, 0); + fields[2].out_mask = NULL; + fields[2].in_value = NULL; + fields[2].in_check_value = NULL; + fields[2].in_check_mask = NULL; + fields[2].in_handler = NULL; + fields[2].in_handler_priv = NULL; + + jtag_add_dr_scan(3, fields, -1, NULL); + + while (size > 0) + { + /* when reading the last item, set the register address to the DCC control reg, + * to avoid reading additional data from the DCC data reg + */ + if (size == 1) + buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_CTRL]); + + fields[0].in_handler = arm_jtag_buf_to_u32; + fields[0].in_handler_priv = data; + jtag_add_dr_scan(3, fields, -1, NULL); + + data++; + size--; + } + + free(fields[1].out_value); + free(fields[2].out_value); + + return jtag_execute_queue(); +} + int embeddedice_read_reg(reg_t *reg) { return embeddedice_read_reg_w_check(reg, NULL, NULL); |