|
- /***************************************************************************
- * Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
-
- #include "target.h"
- #include "jtag/jtag.h"
- #include "avr32_jtag.h"
-
- static int avr32_jtag_set_instr(struct avr32_jtag *jtag_info, int new_instr)
- {
- struct jtag_tap *tap;
- int busy = 0;
-
- tap = jtag_info->tap;
- if (!tap)
- return ERROR_FAIL;
-
- if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) {
- do {
- struct scan_field field;
- uint8_t t[4] = { 0 };
- uint8_t ret[4];
-
- field.num_bits = tap->ir_length;
- field.out_value = t;
- buf_set_u32(t, 0, field.num_bits, new_instr);
- field.in_value = ret;
-
- jtag_add_ir_scan(tap, &field, TAP_IDLE);
- if (jtag_execute_queue() != ERROR_OK) {
- LOG_ERROR("%s: setting address failed", __func__);
- return ERROR_FAIL;
- }
- busy = buf_get_u32(ret, 2, 1);
- } while (busy); /* check for busy bit */
- }
-
- return ERROR_OK;
- }
-
- static int avr32_jtag_nexus_set_address(struct avr32_jtag *jtag_info,
- uint32_t addr, int mode)
- {
- struct scan_field fields[2];
- uint8_t addr_buf[4];
- uint8_t busy_buf[4];
- int busy;
-
- memset(fields, 0, sizeof(fields));
-
- do {
- memset(addr_buf, 0, sizeof(addr_buf));
- memset(busy_buf, 0, sizeof(busy_buf));
-
- buf_set_u32(addr_buf, 0, 1, mode);
- buf_set_u32(addr_buf, 1, 7, addr);
-
- fields[0].num_bits = 26;
- fields[0].in_value = NULL;
- fields[0].out_value = NULL;
-
- fields[1].num_bits = 8;
- fields[1].in_value = busy_buf;
- fields[1].out_value = addr_buf;
-
- jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
- if (jtag_execute_queue() != ERROR_OK) {
- LOG_ERROR("%s: setting address failed", __func__);
- return ERROR_FAIL;
- }
- busy = buf_get_u32(busy_buf, 6, 1);
- } while (busy);
-
- return ERROR_OK;
- }
-
-
- static int avr32_jtag_nexus_read_data(struct avr32_jtag *jtag_info,
- uint32_t *pdata)
- {
-
- struct scan_field fields[2];
- uint8_t data_buf[4];
- uint8_t busy_buf[4];
- int busy;
-
- do {
- memset(data_buf, 0, sizeof(data_buf));
- memset(busy_buf, 0, sizeof(busy_buf));
-
- fields[0].num_bits = 32;
- fields[0].out_value = NULL;
- fields[0].in_value = data_buf;
-
-
- fields[1].num_bits = 2;
- fields[1].in_value = busy_buf;
- fields[1].out_value = NULL;
-
- jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
-
- if (jtag_execute_queue() != ERROR_OK) {
- LOG_ERROR("%s: reading data failed", __func__);
- return ERROR_FAIL;
- }
-
- busy = buf_get_u32(busy_buf, 0, 1);
- } while (busy);
-
- *pdata = buf_get_u32(data_buf, 0, 32);
-
- return ERROR_OK;
- }
-
- static int avr32_jtag_nexus_write_data(struct avr32_jtag *jtag_info,
- uint32_t data)
- {
-
- struct scan_field fields[2];
- uint8_t data_buf[4];
- uint8_t busy_buf[4];
- uint8_t dummy_buf[4];
- int busy;
-
- do {
- memset(data_buf, 0, sizeof(data_buf));
- memset(busy_buf, 0, sizeof(busy_buf));
- memset(dummy_buf, 0, sizeof(dummy_buf));
-
- fields[0].num_bits = 2;
- fields[0].in_value = busy_buf;
- fields[0].out_value = dummy_buf;
-
-
- buf_set_u32(data_buf, 0, 32, data);
- fields[1].num_bits = 32;
- fields[1].in_value = NULL;
- fields[1].out_value = data_buf;
-
- jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
-
- if (jtag_execute_queue() != ERROR_OK) {
- LOG_ERROR("%s: reading data failed", __func__);
- return ERROR_FAIL;
- }
-
- busy = buf_get_u32(busy_buf, 0, 0);
- } while (busy);
-
-
- return ERROR_OK;
- }
-
- int avr32_jtag_nexus_read(struct avr32_jtag *jtag_info,
- uint32_t addr, uint32_t *value)
- {
- avr32_jtag_set_instr(jtag_info, AVR32_INST_NEXUS_ACCESS);
- avr32_jtag_nexus_set_address(jtag_info, addr, MODE_READ);
- return avr32_jtag_nexus_read_data(jtag_info, value);
- }
-
- int avr32_jtag_nexus_write(struct avr32_jtag *jtag_info,
- uint32_t addr, uint32_t value)
- {
- avr32_jtag_set_instr(jtag_info, AVR32_INST_NEXUS_ACCESS);
- avr32_jtag_nexus_set_address(jtag_info, addr, MODE_WRITE);
- return avr32_jtag_nexus_write_data(jtag_info, value);
- }
-
- static int avr32_jtag_mwa_set_address(struct avr32_jtag *jtag_info, int slave,
- uint32_t addr, int mode)
- {
- struct scan_field fields[2];
- uint8_t addr_buf[4];
- uint8_t slave_buf[4];
- uint8_t busy_buf[4];
- int busy;
-
- memset(fields, 0, sizeof(fields));
-
- do {
- memset(addr_buf, 0, sizeof(addr_buf));
- memset(busy_buf, 0, sizeof(busy_buf));
- memset(slave_buf, 0, sizeof(slave_buf));
-
- buf_set_u32(slave_buf, 0, 4, slave);
- buf_set_u32(addr_buf, 0, 1, mode);
- buf_set_u32(addr_buf, 1, 30, addr >> 2);
-
- fields[0].num_bits = 31;
- fields[0].in_value = NULL;
- fields[0].out_value = addr_buf;
-
- fields[1].num_bits = 4;
- fields[1].in_value = busy_buf;
- fields[1].out_value = slave_buf;
-
- jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
- if (jtag_execute_queue() != ERROR_OK) {
- LOG_ERROR("%s: setting address failed", __func__);
- return ERROR_FAIL;
- }
- busy = buf_get_u32(busy_buf, 1, 1);
- } while (busy);
-
- return ERROR_OK;
- }
-
- static int avr32_jtag_mwa_read_data(struct avr32_jtag *jtag_info,
- uint32_t *pdata)
- {
-
- struct scan_field fields[2];
- uint8_t data_buf[4];
- uint8_t busy_buf[4];
- int busy;
-
- do {
- memset(data_buf, 0, sizeof(data_buf));
- memset(busy_buf, 0, sizeof(busy_buf));
-
- fields[0].num_bits = 32;
- fields[0].out_value = NULL;
- fields[0].in_value = data_buf;
-
-
- fields[1].num_bits = 3;
- fields[1].in_value = busy_buf;
- fields[1].out_value = NULL;
-
- jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
-
- if (jtag_execute_queue() != ERROR_OK) {
- LOG_ERROR("%s: reading data failed", __func__);
- return ERROR_FAIL;
- }
-
- busy = buf_get_u32(busy_buf, 0, 1);
- } while (busy);
-
- *pdata = buf_get_u32(data_buf, 0, 32);
-
- return ERROR_OK;
- }
-
- static int avr32_jtag_mwa_write_data(struct avr32_jtag *jtag_info,
- uint32_t data)
- {
-
- struct scan_field fields[2];
- uint8_t data_buf[4];
- uint8_t busy_buf[4];
- uint8_t zero_buf[4];
- int busy;
-
- do {
- memset(data_buf, 0, sizeof(data_buf));
- memset(busy_buf, 0, sizeof(busy_buf));
- memset(zero_buf, 0, sizeof(zero_buf));
-
- buf_set_u32(data_buf, 0, 32, data);
- fields[0].num_bits = 3;
- fields[0].in_value = busy_buf;
- fields[0].out_value = zero_buf;
-
- fields[1].num_bits = 32;
- fields[1].out_value = data_buf;
- fields[1].in_value = NULL;
-
-
- jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
-
- if (jtag_execute_queue() != ERROR_OK) {
- LOG_ERROR("%s: reading data failed", __func__);
- return ERROR_FAIL;
- }
-
- busy = buf_get_u32(busy_buf, 0, 1);
- } while (busy);
-
- return ERROR_OK;
- }
-
- int avr32_jtag_mwa_read(struct avr32_jtag *jtag_info, int slave,
- uint32_t addr, uint32_t *value)
- {
- avr32_jtag_set_instr(jtag_info, AVR32_INST_MW_ACCESS);
- avr32_jtag_mwa_set_address(jtag_info, slave, addr, MODE_READ);
- avr32_jtag_mwa_read_data(jtag_info, value);
-
- return ERROR_OK;
- }
-
- int avr32_jtag_mwa_write(struct avr32_jtag *jtag_info, int slave,
- uint32_t addr, uint32_t value)
- {
- avr32_jtag_set_instr(jtag_info, AVR32_INST_MW_ACCESS);
- avr32_jtag_mwa_set_address(jtag_info, slave, addr, MODE_WRITE);
- avr32_jtag_mwa_write_data(jtag_info, value);
-
- return ERROR_OK;
- }
-
- int avr32_jtag_exec(struct avr32_jtag *jtag_info, uint32_t inst)
- {
- int retval;
- uint32_t ds;
-
- retval = avr32_jtag_nexus_write(jtag_info, AVR32_OCDREG_DINST, inst);
- if (retval != ERROR_OK)
- return retval;
-
- do {
- retval = avr32_jtag_nexus_read(jtag_info, AVR32_OCDREG_DS, &ds);
- if (retval != ERROR_OK)
- return retval;
- } while ((ds & OCDREG_DS_DBA) && !(ds & OCDREG_DS_INC));
-
- return ERROR_OK;
- }
-
- int avr32_ocd_setbits(struct avr32_jtag *jtag, int reg, uint32_t bits)
- {
- uint32_t value;
- int res;
-
- res = avr32_jtag_nexus_read(jtag, reg, &value);
- if (res)
- return res;
-
- value |= bits;
- res = avr32_jtag_nexus_write(jtag, reg, value);
- if (res)
- return res;
-
- return ERROR_OK;
- }
-
- int avr32_ocd_clearbits(struct avr32_jtag *jtag, int reg, uint32_t bits)
- {
- uint32_t value;
- int res;
-
- res = avr32_jtag_nexus_read(jtag, reg, &value);
- if (res)
- return res;
-
- value &= ~bits;
- res = avr32_jtag_nexus_write(jtag, reg, value);
- if (res)
- return res;
-
- return ERROR_OK;
- }
|