+uint8_t* jtag_trans_many(uint8_t *data,
+ uint8_t bitcount,
+ enum eTransFlags flags)
+{
+ uint8_t bit;
+ uint16_t high;
+ uint16_t mask;
+ uint16_t hmask;
+ uint8_t bitnum = 0;
+
+ if (!in_state(SHIFT_IR | SHIFT_DR))
+ {
+ debugstr("jtag_trans_many from invalid TAP state");
+ return 0;
+ }
+
+ SAVETCLK;
+
+ if (flags & LSB)
+ {
+ high = (1L << (min(bitcount,8) - 1));
+ mask = high - 1;
+
+ for (bit = bitcount; bit > 0; bit--,bitnum++)
+ {
+ if (bitnum == 8)
+ {
+ high = (1L << (min(bit,8) - 1));
+ mask = high - 1;
+ bitnum = 0;
+ data ++;
+ }
+ /* write MOSI on trailing edge of previous clock */
+ if (*data & 1)
+ {
+ SETMOSI;
+ }
+ else
+ {
+ CLRMOSI;
+ }
+ *data >>= 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)
+ {
+ *data |= (high);
+ }
+
+ }
+ hmask = (high<<1) - 1;
+ *data &= hmask;
+ }
+ else
+ {
+ // MSB... we need to start at the end of the byte array
+ data += (bitcount/8);
+ bitnum = bitcount % 8;
+ high = (1L << (min(bitnum,8) - 1));
+ mask = high - 1;
+ hmask = (high<<1) - 1;
+
+ for (bit = bitcount; bit > 0; bit--,bitnum--)
+ {
+ if (bitnum == 0)
+ {
+ *data &= hmask;
+
+ high = (1L << (min(bit,8) - 1));
+ mask = high - 1;
+ hmask = (high<<1) - 1;
+ bitnum = 8;
+
+ data --;
+ }
+
+ /* write MOSI on trailing edge of previous clock */
+ if (*data & high)
+ {
+ SETMOSI;
+ }
+ else
+ {
+ CLRMOSI;
+ }
+ *data = (*data & 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 */
+ *data |= (READMISO);
+
+ }
+ }
+
+ //This is needed for 20-bit MSP430 chips.
+ //Might break another 20-bit chip, if one exists.
+ //
+ //UGH... this needs to be fixed... doesn't work with char*
+/* if(bitcount==20){
+ *data = ((*data << 16) | (*data >> 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 &data[2];
+}