Mercurial > avr_jtag
view src/jtag.c @ 13:1ea479d26fce tip
Make sure shifting phase and add bypass.py.
- shifting phase is started after entering SHIFT state
Transition from CAP to SHIFT does not induce shifting.
- shifting phase is stoped after leaving SHIFT state.
Transition from SHIFT to EXIT1 also induce a bit of shifting.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 25 Feb 2009 20:08:29 +0800 |
parents | cc106f278d7d |
children |
line wrap: on
line source
#include <stdio.h> #include <util/delay.h> #include "jtag.h" #include "avriotools.h" /* It is supposed to work at 1Mbps */ #define CLK_DELAY() _delay_us(2) void jtag_init(void) { pin_mode(&JTAG_PORT, JTAG_TCK, PM_OUTPUT); pin_mode(&JTAG_PORT, JTAG_TMS, PM_OUTPUT); pin_mode(&JTAG_PORT, JTAG_TDI, PM_OUTPUT); pin_mode(&JTAG_PORT, JTAG_TDO, PM_INPUT); pin_mode(&JTAG_PORT, JTAG_TRST, PM_OUTPUT); pin_lo(JTAG_PORT, JTAG_TCK); pin_lo(JTAG_PORT, JTAG_TMS); pin_lo(JTAG_PORT, JTAG_TDI); pin_hi(JTAG_PORT, JTAG_TRST); } #define _TDI_TMS_TCK(tdi, tms, tck) \ ((tms? _BV(JTAG_TMS): 0) | \ (tdi? _BV(JTAG_TDI): 0) | \ (tck? _BV(JTAG_TCK): 0)) #define _SET_PINS(pv, tdi, tms, tck) \ do { \ pv = JTAG_PORT; \ pv &= ~_TDI_TMS_TCK(1, 1, 1); \ pv |= _TDI_TMS_TCK(tdi, tms, tck); \ JTAG_PORT = pv; \ } while(0) #define SEND_BIT(pv, tdi, tms) \ do { \ _SET_PINS(pv, tdi, tms, 0); \ CLK_DELAY(); \ _SET_PINS(pv, tdi, tms, 1); \ CLK_DELAY(); \ } while(0) #define GET_TDO() (JTAG_PIN & _BV(JTAG_TDO)) #define SEND_GET_BIT(pv, tdi, tms, out) \ do { \ _SET_PINS(pv, tdi, tms, 0); \ CLK_DELAY(); \ out = GET_TDO(); \ _SET_PINS(pv, tdi, tms, 1); \ CLK_DELAY(); \ } while(0) void jtag_trst(void) { unsigned char pv; pin_lo(JTAG_PORT, JTAG_TCK); pin_lo(JTAG_PORT, JTAG_TRST); SEND_BIT(pv, 1, 1); SEND_BIT(pv, 1, 1); SEND_BIT(pv, 1, 1); SEND_BIT(pv, 1, 1); SEND_BIT(pv, 1, 1); pin_lo(JTAG_PORT, JTAG_TCK); pin_hi(JTAG_PORT, JTAG_TRST); SEND_BIT(pv, 1, 1); } /*! * Before shifting registers, TAP controller must move to last state before * shift state. The state machine transite to shift state when shifting * starts. */ void jtag_tms(unsigned char *buf, int nbits) { int i; int nbytes; int byteoff, bitoff; unsigned char byte; unsigned char bit; unsigned char pv; nbytes = nbits / 8; for(i = 0; i < nbytes; i++) { byte = buf[i]; bit = byte & 0x01; SEND_BIT(pv, 1, bit); bit = byte & 0x02; SEND_BIT(pv, 1, bit); bit = byte & 0x04; SEND_BIT(pv, 1, bit); bit = byte & 0x08; SEND_BIT(pv, 1, bit); bit = byte & 0x10; SEND_BIT(pv, 1, bit); bit = byte & 0x20; SEND_BIT(pv, 1, bit); bit = byte & 0x40; SEND_BIT(pv, 1, bit); bit = byte & 0x80; SEND_BIT(pv, 1, bit); } byte = buf[i]; nbits %= 8; for(i = 0; i < nbits; i++) { bit = byte & (1 << i); SEND_BIT(pv, 1, bit); } } void jtag_shift(unsigned char *buf, int nbits) { int i; int nbits_1; int nbytes; int remain; int byteoff, bitoff; unsigned char byte; unsigned char bit; unsigned char pv; if(nbits == 0) return; nbits_1 = nbits - 1; nbytes = nbits_1 / 8; for(i = 0; i < nbytes; i++) { byte = buf[i]; bit = byte & 0x01; SEND_BIT(pv, bit, 0); bit = byte & 0x02; SEND_BIT(pv, bit, 0); bit = byte & 0x04; SEND_BIT(pv, bit, 0); bit = byte & 0x08; SEND_BIT(pv, bit, 0); bit = byte & 0x10; SEND_BIT(pv, bit, 0); bit = byte & 0x20; SEND_BIT(pv, bit, 0); bit = byte & 0x40; SEND_BIT(pv, bit, 0); bit = byte & 0x80; SEND_BIT(pv, bit, 0); } remain = nbits_1 % 8; byte = buf[i]; for(i = 0; i < remain; i++) { bit = byte & (1 << i); SEND_BIT(pv, bit, 0); } byte = buf[nbits / 8]; bit = byte & (1 << (nbits_1 % 8)); SEND_BIT(pv, bit, 1); } void jtag_shift_inout(unsigned char *ibuf, unsigned char *obuf, int nbits) { int i, j; int nbits_1; int nbytes; int tdo; int byteoff, bitoff; int remain; unsigned char byte, obyte; unsigned char bit; unsigned char pv; if(nbits == 0) return; nbits_1 = nbits - 1; nbytes = nbits_1 / 8; for(i = 0; i < nbytes; i++) { byte = ibuf[i]; obyte = 0; bit = byte & 0x01; SEND_GET_BIT(pv, bit, 0, tdo); if(tdo) obyte |= 0x01; bit = byte & 0x02; SEND_GET_BIT(pv, bit, 0, tdo); tdo = GET_TDO(); if(tdo) obyte |= 0x02; bit = byte & 0x04; SEND_GET_BIT(pv, bit, 0, tdo); if(tdo) obyte |= 0x04; bit = byte & 0x08; SEND_GET_BIT(pv, bit, 0, tdo); if(tdo) obyte |= 0x08; bit = byte & 0x10; SEND_GET_BIT(pv, bit, 0, tdo); if(tdo) obyte |= 0x10; bit = byte & 0x20; SEND_GET_BIT(pv, bit, 0, tdo); if(tdo) obyte |= 0x20; bit = byte & 0x40; SEND_GET_BIT(pv, bit, 0, tdo); if(tdo) obyte |= 0x40; bit = byte & 0x80; SEND_GET_BIT(pv, bit, 0, tdo); if(tdo) obyte |= 0x80; obuf[i] = obyte; } remain = nbits_1 % 8; byte = ibuf[i]; obyte = 0; for(j = 0; j < remain; j++) { bit = byte & (1 << j); SEND_GET_BIT(pv, bit, 0, tdo); if(tdo) obyte |= 1 << j; else obyte &= ~(1 << j); } obuf[i] = obyte; byte = ibuf[nbits / 8]; bit = byte & (1 << (nbits_1 % 8)); SEND_GET_BIT(pv, bit, 1, tdo); if(tdo) obuf[nbits / 8] |= 1 << j; else obuf[nbits / 8] &= ~(1 << j); }