view src/jtag.c @ 4:6b1594fb668f

Improve performance of jtag.c and test it with Python scripts. - cp_tditdo.py send bits to TDI and hope it will feed back from TDO. - Expand loops in jtag.c to improve performance.
author Thinker K.F. Li <thinker@branda.to>
date Sun, 22 Feb 2009 12:54:45 +0800
parents abf221bf3ce4
children eb14cac68cbb
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()

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_lo(JTAG_PORT, JTAG_TCK);
    pin_lo(JTAG_PORT, JTAG_TMS);
    pin_lo(JTAG_PORT, JTAG_TDI);
}

#define TCK_LO() pin_lo(JTAG_PORT, JTAG_TCK)
#define TCK_HI() pin_hi(JTAG_PORT, JTAG_TCK)
#define SEND_BIT(pin, bit)			\
    do {					\
	if(bit)					\
	    pin_hi(JTAG_PORT, pin);		\
	else					\
	    pin_lo(JTAG_PORT, pin);		\
	CLK_DELAY();				\
	TCK_HI();				\
	CLK_DELAY();				\
    } while(0)
#define GET_TDO() (JTAG_PIN & _BV(JTAG_TDO))

void jtag_tms(char *buf, int nbits) {
    int i;
    int nbytes, byte;
    int byteoff, bitoff;
    int bit;
    
    nbytes = nbits / 8;
    for(i = 0; i < nbytes; i++) {
	byte = buf[i];
	
	bit = byte & 0x01;
	SEND_BIT(JTAG_TMS, bit);
	TCK_LO();
	
	bit = byte & 0x02;
	SEND_BIT(JTAG_TMS, bit);
	TCK_LO();
	
	bit = byte & 0x04;
	SEND_BIT(JTAG_TMS, bit);
	TCK_LO();
	
	bit = byte & 0x08;
	SEND_BIT(JTAG_TMS, bit);
	TCK_LO();
	
	bit = byte & 0x10;
	SEND_BIT(JTAG_TMS, bit);
	TCK_LO();
	
	bit = byte & 0x20;
	SEND_BIT(JTAG_TMS, bit);
	TCK_LO();
	
	bit = byte & 0x40;
	SEND_BIT(JTAG_TMS, bit);
	TCK_LO();
	
	bit = byte & 0x80;
	SEND_BIT(JTAG_TMS, bit);
	TCK_LO();
    }
    
    byte = buf[i];
    nbits %= 8;
    for(i = 0; i < nbits; i++) {
	bit = byte & (1 << i);
	SEND_BIT(JTAG_TMS, bit);
	TCK_LO();
    }
}

void jtag_shift(char *buf, int nbits) {
    int i;
    int nbytes, byte;
    int byteoff, bitoff;
    int bit;
    
    nbytes = nbits / 8;
    for(i = 0; i < nbytes; i++) {
	byte = buf[i];
	
	bit = byte & 0x01;
	SEND_BIT(JTAG_TDI, bit);
	TCK_LO();
	
	bit = byte & 0x02;
	SEND_BIT(JTAG_TDI, bit);
	TCK_LO();
	
	bit = byte & 0x04;
	SEND_BIT(JTAG_TDI, bit);
	TCK_LO();
	
	bit = byte & 0x08;
	SEND_BIT(JTAG_TDI, bit);
	TCK_LO();
	
	bit = byte & 0x10;
	SEND_BIT(JTAG_TDI, bit);
	TCK_LO();
	
	bit = byte & 0x20;
	SEND_BIT(JTAG_TDI, bit);
	TCK_LO();
	
	bit = byte & 0x40;
	SEND_BIT(JTAG_TDI, bit);
	TCK_LO();
	
	bit = byte & 0x80;
	SEND_BIT(JTAG_TDI, bit);
	TCK_LO();
    }
    
    nbits %= 8;
    if(nbits) {
	byte = buf[i];
	for(i = 0; i < nbits; i++) {
	    bit = byte & (1 << i);
	    SEND_BIT(JTAG_TDI, bit);
	    TCK_LO();
	}
    }
}

void jtag_shift_inout(char *ibuf, char *obuf, int nbits) {
    int i, j;
    int nbytes, byte, obyte;
    int tdo;
    int byteoff, bitoff;
    int bit;
    
    nbytes = nbits / 8;
    for(i = 0; i < nbytes; i++) {
	byte = ibuf[i];
	obyte = 0;
	
	bit = byte & 0x01;
	SEND_BIT(JTAG_TDI, bit);
	tdo = GET_TDO();
	if(tdo)
	    obyte |= 0x01;
	else
	    obyte &= ~0x01;
	TCK_LO();
	
	bit = byte & 0x02;
	SEND_BIT(JTAG_TDI, bit);
	tdo = GET_TDO();
	if(tdo)
	    obyte |= 0x02;
	else
	    obyte &= ~0x02;
	TCK_LO();
	
	bit = byte & 0x04;
	SEND_BIT(JTAG_TDI, bit);
	tdo = GET_TDO();
	if(tdo)
	    obyte |= 0x04;
	else
	    obyte &= ~0x04;
	TCK_LO();
	
	bit = byte & 0x08;
	SEND_BIT(JTAG_TDI, bit);
	tdo = GET_TDO();
	if(tdo)
	    obyte |= 0x08;
	else
	    obyte &= ~0x08;
	TCK_LO();
	
	bit = byte & 0x10;
	SEND_BIT(JTAG_TDI, bit);
	tdo = GET_TDO();
	if(tdo)
	    obyte |= 0x10;
	else
	    obyte &= ~0x10;
	TCK_LO();
	
	bit = byte & 0x20;
	SEND_BIT(JTAG_TDI, bit);
	tdo = GET_TDO();
	if(tdo)
	    obyte |= 0x20;
	else
	    obyte &= ~0x20;
	TCK_LO();
	
	bit = byte & 0x40;
	SEND_BIT(JTAG_TDI, bit);
	tdo = GET_TDO();
	if(tdo)
	    obyte |= 0x40;
	else
	    obyte &= ~0x40;
	TCK_LO();
	
	bit = byte & 0x80;
	SEND_BIT(JTAG_TDI, bit);
	tdo = GET_TDO();
	if(tdo)
	    obyte |= 0x80;
	else
	    obyte &= ~0x80;
	TCK_LO();

	obuf[i] = obyte;
    }
    
    nbits %= 8;
    if(nbits) {
	byte = ibuf[i];
	obyte = 0;
	for(j = 0; j < nbits; j++) {
	    bit = byte & (1 << j);
	    SEND_BIT(JTAG_TDI, bit);
	    tdo = GET_TDO();
	    if(tdo)
		obyte |= 1 << j;
	    else
		obyte &= ~(1 << j);
	    TCK_LO();
	}
	obuf[i] = obyte;
    }
}