📄 jtag.c
字号:
/* * Copyright (C) 2004 Tobias Lorenz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. *//* tap+jtag+sc functions *//* This file contains all of the JTAG hardware calls, it can * be changed to suit the hardware that you have.... */#include <stdlib.h>#include <stdio.h>#include "jtag.h"#include "pp.h"const unsigned char TAPSM_Next[16][2] = { { TAPSM_Shift_DR , TAPSM_Update_DR }, /* Exit2-DR */ { TAPSM_Pause_DR , TAPSM_Update_DR }, /* Exit1-DR */ { TAPSM_Shift_DR , TAPSM_Exit1_DR }, /* Shift-DR */ { TAPSM_Pause_DR , TAPSM_Exit2_DR }, /* Pause-DR */ { TAPSM_Capture_IR , TAPSM_Test_Logic_Reset }, /* Select-IR-Scan */ { TAPSM_Run_Test_Idle , TAPSM_Select_DR_Scan }, /* Update-DR */ { TAPSM_Shift_DR , TAPSM_Exit1_DR }, /* Capture-DR */ { TAPSM_Capture_DR , TAPSM_Select_IR_Scan }, /* Select-DR-Scan */ { TAPSM_Shift_IR , TAPSM_Update_IR }, /* Exit2-IR */ { TAPSM_Pause_IR , TAPSM_Update_IR }, /* Exit1-IR */ { TAPSM_Shift_IR , TAPSM_Exit1_IR }, /* Shift-IR */ { TAPSM_Pause_IR , TAPSM_Exit2_IR }, /* Pause-IR */ { TAPSM_Run_Test_Idle , TAPSM_Select_DR_Scan }, /* Run-Test/Idle */ { TAPSM_Run_Test_Idle , TAPSM_Select_DR_Scan }, /* Update-IR */ { TAPSM_Shift_IR , TAPSM_Exit1_IR }, /* Capture-IR */ { TAPSM_Run_Test_Idle , TAPSM_Test_Logic_Reset }}; /* Test-Logic Reset */const unsigned int SC_sizes[32] = { 184, 67, 38, 0, /* last one is user-defined */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};unsigned char tapsm_state = TAPSM_Test_Logic_Reset;short sc_current = -1;unsigned long jtag_idcode;void tapsm_next_state(unsigned char tms, unsigned char tdi){ unsigned char c = PP_PWR; if (tms) c |= PP_TMS; if (tdi) c |= PP_TDI; pp_outb(c ); pp_outb(c | PP_CLK); tapsm_state = TAPSM_Next[tapsm_state][tms];}void tapsm_reset(unsigned char wire_reset){ int loop_count; if (wire_reset) { /* Reset */ pp_outb(PP_nTRST); pp_outb(0); } else { for(loop_count = 0; loop_count < 5; loop_count++) /* goto Test-Logic Reset and stay there */ tapsm_next_state(1, 0); } tapsm_state = TAPSM_Test_Logic_Reset; /* Test-Logic Reset --> Run-Test/Idle */ tapsm_next_state(0, 0); jtag_instruction(JTAG_RESTART, NULL, 0);}void tapsm_reg(unsigned long *data, unsigned int length, unsigned char to_dr_scan){ unsigned long * input_pointer; unsigned long * output_pointer; unsigned long input, value; unsigned int count; unsigned long output = 0; input_pointer = data; output_pointer = data; /* Select --> Capture */ tapsm_next_state(0, 0); /* Capture --> Shift */ tapsm_next_state(0, 0); /* read/writing */ for (count = 0; count < length; count ++) { if ((count & 0x1f) == 0) { /* fetch next word of data */ input = *input_pointer; input_pointer ++; } /* Shift --> Shift, Exit1 */ tapsm_next_state((count==length-1), input & 0x01); if ((pp_inb() & PP_TDO) == 0) output = output | (1 << (count & 0x1f)); input = input >> 1; if ((count & 0x1f) == 0x1f) { /* store received word of data */ *output_pointer = output; output_pointer ++; output = 0; } } /* ensure that the output is captured if less than whole long word */ *output_pointer = output; /* Exit1 --> Update */ tapsm_next_state(1, 0); /* Update --> Select-DR-Scan, Run-Test/Idle */ tapsm_next_state(to_dr_scan, 0);}void jtag_ireg(unsigned long *data, unsigned int length){ if (tapsm_state == TAPSM_Run_Test_Idle) /* Run-Test/Idle --> Select-DR-Scan */ tapsm_next_state(1, 0); /* Select-DR-Scan --> Select-IR-Scan */ tapsm_next_state(1, 0); /* Select-IR-Scan --> Select-DR-Scan, Run-Test/Idle */ tapsm_reg(data, length, (*data != JTAG_RESTART));}void jtag_dreg(unsigned long *data, unsigned int length){ if (tapsm_state == TAPSM_Run_Test_Idle) /* Run-Test/Idle --> Select-DR-Scan */ tapsm_next_state(1, 0); /* we always go via Idle/Run for data register stuff */ tapsm_reg(data, length, 0);}void jtag_instruction(unsigned long cmd, unsigned long *data, unsigned int size){ jtag_ireg(&cmd, JTAG_REG_IR); if (data && size) jtag_dreg(data, size); if (cmd == JTAG_RESTART) sc_current = -1;}void jtag_get_idcode(void){ unsigned long idcode[2]; jtag_instruction(JTAG_IDCODE, idcode, JTAG_REG_DIR); jtag_instruction(JTAG_RESTART, NULL, 0); jtag_idcode = idcode[0];}void sc_select(unsigned long sc){ if (sc_current != sc) { jtag_instruction(JTAG_SCAN_N, &sc, JTAG_REG_SCSR); sc_current = sc; }}unsigned long sc_read(unsigned long *data, unsigned int hibit, unsigned int lobit){ unsigned int bit; unsigned int bits; unsigned long retval = 0; hibit--; // bit=number-1 lobit--; // bit=number-1 bits = abs(hibit-lobit) + 1; for (bit=hibit; bits > 0; bits--, bit+=(hibit>lobit ? -1 : 1)) { retval = (retval << 1) | ((data[bit%32] & (1<<(bit/32))) ? 1:0); } return (retval);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -