#include "defines.h" #include #include #include #include "jtag.h" #include "jtag_commands.h" static uint8_t jtag_current_command = 0; static uint16_t jtag_pos = 0; static uint32_t jtag_tck_delay_value = 0; static uint32_t jtag_num_tck = 0; static uint32_t jtag_usecs = 0; static uint16_t jtag_multi_count = 0; static uint16_t jtag_multi_pos = 0; static uint16_t jtag_multi_multi = 0; static void tck_delay(uint8_t tms, uint32_t num_tck, uint32_t usecs) { if (tms) PORT |= (1<= 0) { if (tdi) PORT |= (1<> TDO_PIN) & 1) == tdo; } static int jtag_parse_byte(uint8_t data) { int i, tms, tdi, tdo; switch (jtag_current_command) { case 0: jtag_current_command = data; jtag_pos = 0; break; case JTAG_PULSE_TCK_DELAY: if (jtag_pos == 0) { jtag_num_tck = 0; jtag_usecs = 0; jtag_tck_delay_value = data; } else { if ((jtag_pos < 4) && (jtag_tck_delay_value & 0b10)) // num_tck { jtag_num_tck |= (uint32_t)data << (8*(jtag_pos-1)); } else if ((jtag_pos < 4) && !(jtag_tck_delay_value & 0b10)) // usecs { jtag_usecs |= (uint32_t)data << (8*(jtag_pos-1)); } else { jtag_usecs |= (uint32_t)data << (8*(jtag_pos-5)); } } if ( ((jtag_tck_delay_value & 0b110) == 0) || (((((jtag_tck_delay_value & 0b110) == 0b100) || (jtag_tck_delay_value & 0b110) == 0b010)) && jtag_pos == 4) || (((jtag_tck_delay_value & 0b110) == 0b110) && jtag_pos == 8) ) { tck_delay(jtag_tck_delay_value&1, jtag_num_tck, jtag_usecs); jtag_current_command = 0; } jtag_pos++; break; case JTAG_PULSE_TCK_MULTI: if (jtag_pos == 0) { jtag_multi_count = data; jtag_multi_pos = 0; jtag_multi_multi = 0; } else if (jtag_pos == 1) { jtag_multi_count |= (uint16_t)data << 8; } else { if (!jtag_multi_multi && !(data & 0x80)) { jtag_multi_multi = data; } else { if (!jtag_multi_multi) jtag_multi_multi = 1; tms = data&1; tdi = (data>>1)&1; tdo = -1; if (data & (1<<2)) { tdo = (data>>3)&1; } for (i = 0; i < jtag_multi_multi; i++) { if (!pulse_tck(tms, tdi, tdo)) return 0; jtag_multi_pos++; } jtag_multi_multi = 0; } if (jtag_multi_pos >= jtag_multi_count) jtag_current_command = 0; } jtag_pos++; break; /* case JTAG_PULSE_TCK: tms = data&1; tdi = (data>>1)&1; tdo = -1; if (data & (1<<2)) { tdo = (data>>3)&1; } if (!pulse_tck(tms, tdi, tdo)) return 0; jtag_current_command = 0; break; */ default: return 0; } return 1; } void jtag_setup() { PORT &= ~((1<