diff options
author | drath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2006-06-02 10:36:31 +0000 |
---|---|---|
committer | drath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2006-06-02 10:36:31 +0000 |
commit | 8b4e882a1630d63bbc9840fa3f968e36b6ac3702 (patch) | |
tree | e8f8ab1ba76fc7bef013fed6e5fea28e1cb7a554 /src/jtag/bitbang.c |
- prepare OpenOCD for branching, created ./trunk/
git-svn-id: svn://svn.berlios.de/openocd/trunk@64 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/jtag/bitbang.c')
-rw-r--r-- | src/jtag/bitbang.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/src/jtag/bitbang.c b/src/jtag/bitbang.c new file mode 100644 index 00000000..d6ff2898 --- /dev/null +++ b/src/jtag/bitbang.c @@ -0,0 +1,219 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dominic.Rath@gmx.de * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "bitbang.h" + +/* project specific includes */ +#include "log.h" +#include "types.h" +#include "jtag.h" +#include "configuration.h" + +/* system includes */ +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#include <sys/time.h> +#include <time.h> + +bitbang_interface_t *bitbang_interface; + +int bitbang_execute_queue(void); + +void bitbang_end_state(enum tap_state state) +{ + if (tap_move_map[state] != -1) + end_state = state; + else + { + ERROR("BUG: %i is not a valid end state", state); + exit(-1); + } +} + +void bitbang_state_move(void) { + + int i=0, tms=0; + u8 tms_scan = TAP_MOVE(cur_state, end_state); + + for (i = 0; i < 7; i++) + { + tms = (tms_scan >> i) & 1; + bitbang_interface->write(0, tms, 0); + bitbang_interface->write(1, tms, 0); + } + bitbang_interface->write(0, tms, 0); + + cur_state = end_state; +} + +void bitbang_runtest(int num_cycles) +{ + int i; + + enum tap_state saved_end_state = end_state; + + /* only do a state_move when we're not already in RTI */ + if (cur_state != TAP_RTI) + { + bitbang_end_state(TAP_RTI); + bitbang_state_move(); + } + + /* execute num_cycles */ + bitbang_interface->write(0, 0, 0); + for (i = 0; i < num_cycles; i++) + { + bitbang_interface->write(1, 0, 0); + bitbang_interface->write(0, 0, 0); + } + + /* finish in end_state */ + bitbang_end_state(saved_end_state); + if (cur_state != end_state) + bitbang_state_move(); +} + +void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) +{ + enum tap_state saved_end_state = end_state; + int bit_cnt; + + if (ir_scan) + bitbang_end_state(TAP_SI); + else + bitbang_end_state(TAP_SD); + + bitbang_state_move(); + bitbang_end_state(saved_end_state); + + for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) + { + if ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1) { + bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 1); + bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 1); + } else { + bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 0); + bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 0); + } + + if (type != SCAN_OUT) + { + if (bitbang_interface->read()) + buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8); + else + buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8)); + } + } + + /* Exit1 -> Pause */ + bitbang_interface->write(0, 0, 0); + bitbang_interface->write(1, 0, 0); + + if (ir_scan) + cur_state = TAP_PI; + else + cur_state = TAP_PD; + + if (cur_state != end_state) + bitbang_state_move(); +} + +int bitbang_execute_queue(void) +{ + jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ + int scan_size; + enum scan_type type; + u8 *buffer; + + if (!bitbang_interface) + { + ERROR("BUG: Bitbang interface called, but not yet initialized"); + exit(-1); + } + + while (cmd) + { + switch (cmd->type) + { + case JTAG_END_STATE: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("end_state: %i", cmd->cmd.end_state->end_state); +#endif + if (cmd->cmd.end_state->end_state != -1) + bitbang_end_state(cmd->cmd.end_state->end_state); + break; + case JTAG_RESET: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); +#endif + if (cmd->cmd.reset->trst == 1) + { + cur_state = TAP_TLR; + } + bitbang_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); + break; + case JTAG_RUNTEST: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); +#endif + if (cmd->cmd.runtest->end_state != -1) + bitbang_end_state(cmd->cmd.runtest->end_state); + bitbang_runtest(cmd->cmd.runtest->num_cycles); + break; + case JTAG_STATEMOVE: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); +#endif + if (cmd->cmd.statemove->end_state != -1) + bitbang_end_state(cmd->cmd.statemove->end_state); + bitbang_state_move(); + break; + case JTAG_SCAN: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("scan end in %i", cmd->cmd.scan->end_state); +#endif + if (cmd->cmd.scan->end_state != -1) + bitbang_end_state(cmd->cmd.scan->end_state); + scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); + type = jtag_scan_type(cmd->cmd.scan); + bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); + if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) + return ERROR_JTAG_QUEUE_FAILED; + if (buffer) + free(buffer); + break; + case JTAG_SLEEP: +#ifdef _DEBUG_JTAG_IO_ + DEBUG("sleep", cmd->cmd.sleep->us); +#endif + jtag_sleep(cmd->cmd.sleep->us); + break; + default: + ERROR("BUG: unknown JTAG command type encountered"); + exit(-1); + } + cmd = cmd->next; + } + + return ERROR_OK; +} + |