+ if (!in_state(SHIFT_IR | SHIFT_DR))
+ {
+ debugstr("jtag_trans_n from invalid TAP state");
+ return 0;
+ }
+
+ SAVETCLK;
+
+ if (flags & LSB)
+ {
+ for (bit = bitcount; bit > 0; bit--)
+ {
+ /* write MOSI on trailing edge of previous clock */
+ if (word & 1)
+ {
+ SETMOSI;
+ }
+ else
+ {
+ CLRMOSI;
+ }
+ word >>= 1;
+
+ if ((bit == 1) && !(flags & NOEND))
+ SETTMS; //TMS high on last bit to exit.
+
+ jtag_tcktock();
+
+ if ((bit == 1) && !(flags & NOEND))
+ jtag_state <<= 1; // Exit1-DR or Exit1-IR
+
+ /* read MISO on trailing edge */
+ if (READMISO)
+ {
+ word += (high);
+ }
+ }
+ }
+ else
+ {
+ for (bit = bitcount; bit > 0; bit--)
+ {
+ /* write MOSI on trailing edge of previous clock */
+ if (word & high)
+ {
+ SETMOSI;
+ }
+ else
+ {
+ CLRMOSI;
+ }
+ word = (word & mask) << 1;
+
+ if ((bit==1) && !(flags & NOEND))
+ SETTMS; //TMS high on last bit to exit.
+
+ jtag_tcktock();
+
+ if ((bit == 1) && !(flags & NOEND))
+ jtag_state <<= 1; // Exit1-DR or Exit1-IR
+
+ /* read MISO on trailing edge */
+ word |= (READMISO);
+ }
+ }
+
+ //This is needed for 20-bit MSP430 chips.
+ //Might break another 20-bit chip, if one exists.
+ if(bitcount==20){
+ word = ((word << 16) | (word >> 4)) & 0x000FFFFF;
+ }
+
+ RESTORETCLK;
+
+ if (!(flags & NOEND))
+ {
+ // exit state
+ jtag_tcktock();
+
+ jtag_state <<= 3; // Update-DR or Update-IR
+
+ // update state
+ if (!(flags & NORETIDLE))
+ {
+ CLRTMS;
+ jtag_tcktock();
+
+ jtag_state = RUN_TEST_IDLE;
+ }
+ }
+
+ return word;
+}
+
+//! Detects the width of the IR register
+uint16_t jtag_detect_ir_width()
+{
+ int i;
+ uint16_t width = 0;
+
+ if (!in_run_test_idle())
+ {
+ debugstr("Not in run-test-idle state");
+ return 0;
+ }
+
+ // get to shift-ir state
+ jtag_capture_ir();
+ jtag_shift_register();
+
+ // first we shift in 1024 zeros
+ CLRMOSI;
+ for(i = 0; i < 1024; i++)
+ {
+ jtag_tcktock();
+ }
+
+ // now we'll clock in ones until we see one
+ SETMOSI;
+ for(i = 0; i < 1024; i++)
+ {
+ jtag_tcktock();
+ if(READMISO)
+ break;
+ width++;
+ }
+
+ // now get back to run-test-idle
+ jtag_run_test_idle();
+
+ return width;
+}
+
+//! Detects how many TAPs are in the JTAG chain
+uint16_t jtag_detect_chain_length()
+{
+ int i;
+ int bit;
+ uint16_t length = 0;
+
+ if (!in_run_test_idle())
+ {
+ debugstr("detect chain length must start from run-test-idle");
+ return 0;
+ }
+
+ // The standard JTAG instruction for "bypass" mode is to set all 1's in the
+ // instruction register. When in "bypass" mode, the DR acts like a 1-bit
+ // shift regiser. So we can use that to detect how many TAPs are in the
+ // chain.
+
+ // first get into shift IR mode
+ jtag_capture_ir();
+ jtag_shift_register();
+
+ // then we flood the IR chain with all 1's to put all device's DRs
+ // into bypass mode
+ CLRTMS;
+ SETMOSI;
+ for (i = 0; i < 1024; i++)
+ {
+ if (i == 1023)
+ SETTMS; // exit on last bit
+ jtag_tcktock();
+ }
+ jtag_state = EXIT1_IR;
+
+ // go to Update-IR
+ CLRMOSI;
+ jtag_tcktock();
+ jtag_state = UPDATE_IR;
+
+ // go to Shift-DR state
+ jtag_capture_dr();
+ jtag_shift_register();
+
+ // flush the DR's with zeros
+ CLRTMS;
+ CLRMOSI;
+ for (i = 0; i < 1024; i++)
+ {
+ jtag_tcktock();
+ }
+
+ // send 1's into the DRs until we see one come out the other side
+ SETMOSI;
+ for (i = 0; i < 1024; i++)
+ {
+ jtag_tcktock();
+ bit = READMISO;
+ if (bit)
+ break;
+ length++;
+ }
+
+ // now get back to run-test-idle
+ jtag_run_test_idle();
+
+ return length;