/*
 Bit-bang JTAG interface functions
 
 Copyright (c) 2008-2011 Dimtel, Inc., All Rights Reserved

 $Id: jtag.c,v 1.4 2013/09/05 03:22:42 dim Exp $
 $Date: 2013/09/05 03:22:42 $
 $Author: dim $
 $Revision: 1.4 $
 $Log: jtag.c,v $
 Revision 1.4  2013/09/05 03:22:42  dim
 Converted count from ushort to uchar, to specify 4-byte blocks (128 max)

 Revision 1.3  2013/06/06 04:35:11  dim
 Added EP8 OUT to interface 0 for fast JTAG block loading

 Revision 1.2  2013/06/05 05:04:30  dim
 Added slightly more efficient JTAG code (5.5 cycles per bit vs. 8)

 Revision 1.1  2012/11/11 01:24:32  dim
 Moved from BxB, adapted to compile for both LLRF4 and IGP12

 Revision 1.1  2011/12/27 19:31:46  dim
 Updated to remove deprecated constructs (at, sfr, xdata, sbit)


*/

#include "fx2regs.h"
#include "common.h"
#include "jtag.h"
#include "hwdef.h"

uchar jtag_rxtx(uchar value)
{
  unsigned char ret;
  
  JTAG_TCK = 0;
  JTAG_TMS = (value >> 1) & 1;
  JTAG_TDI = value & 1;
  JTAG_TCK = 1;
  ret = JTAG_TDO;
            
  return ret;
}

void jtag_block_write(__xdata uchar *buf, uchar len)
{
	(void) buf; /* only used in assembly */
	(void) len; /* only used in assembly */
    __asm
	mov     r2, _jtag_block_write_PARM_2
00001$:
	movx    a, @dptr	/* 2 cycles */
	
        rlc     a		/* 1 cycle */
	clr	_JTAG_TCK	/* 2 cycles */
	mov     _JTAG_TDI, c	/* 2 cycles */

	setb    _JTAG_TCK	/* 2 cycles */
	rlc     a		/* 1 cycle */
	clr     _JTAG_TCK	/* 2 cycles */
	mov     _JTAG_TDI, c	/* 2 cycles */

	setb    _JTAG_TCK   	/* 2 cycles */
	rlc     a	    	/* 1 cycle */
	clr     _JTAG_TCK   	/* 2 cycles */
	mov     _JTAG_TDI, c	/* 2 cycles */

	setb    _JTAG_TCK   	/* 2 cycles */
	rlc     a	    	/* 1 cycle */
	clr     _JTAG_TCK   	/* 2 cycles */
	mov     _JTAG_TDI, c	/* 2 cycles */

	setb    _JTAG_TCK   	/* 2 cycles */
	rlc     a	    	/* 1 cycle */
	clr     _JTAG_TCK   	/* 2 cycles */
	mov     _JTAG_TDI, c	/* 2 cycles */

	setb    _JTAG_TCK   	/* 2 cycles */
	rlc     a	    	/* 1 cycle */
	clr     _JTAG_TCK   	/* 2 cycles */
	mov     _JTAG_TDI, c	/* 2 cycles */

	setb    _JTAG_TCK   	/* 2 cycles */
	rlc     a	    	/* 1 cycle */
	clr     _JTAG_TCK   	/* 2 cycles */
	mov     _JTAG_TDI, c	/* 2 cycles */

	setb    _JTAG_TCK   	/* 2 cycles */
	rlc     a	    	/* 1 cycle */
	clr     _JTAG_TCK   	/* 2 cycles */
	mov     _JTAG_TDI, c	/* 2 cycles */

	setb    _JTAG_TCK   	/* 2 cycles */

	inc     dptr		/* 3 cycles */
	djnz    r2, 00001$	/* 3 cycles */
    __endasm;
}

void jtag_block_write_ep8(uchar count)
{
  /* This function reads the data buffer from EP8 and clocks out the bits
     to JTAG_TDI. For higher speed, buffer data is arranged as follows:
     0000a000
     0000b000
     0000c000
     0000d000
     
     Where a, b, c, d are four consecutive bits to output. While inefficient
     in USB data transfer (8x data size), this allows the poor 8051 to only spend
     5 cycles per bit, vs. 8 cycles for shift style data.
  */
  (void)count;

    __asm
        mov	r2, _DPL	/* Data packet is 512 long, so max 128 cycles */
	mov     _AUTOPTRH1, #(_EP8FIFOBUF>>8)
	mov     _AUTOPTRL1, #(_EP8FIFOBUF&0xff)
00001$:
	mov	_IOA, _AUTODAT1	/* 3 cycles */
	setb    _JTAG_TCK   	/* 2 cycles */
	mov	_IOA, _AUTODAT1 /* 3 cycles */
	setb    _JTAG_TCK   	/* 2 cycles */
	mov	_IOA, _AUTODAT1	/* 3 cycles */
	setb    _JTAG_TCK   	/* 2 cycles */
	mov	_IOA, _AUTODAT1 /* 3 cycles */
	setb    _JTAG_TCK   	/* 2 cycles */
	mov	_IOA, _AUTODAT1	/* 3 cycles */
	setb    _JTAG_TCK   	/* 2 cycles */
	mov	_IOA, _AUTODAT1 /* 3 cycles */
	setb    _JTAG_TCK   	/* 2 cycles */
	mov	_IOA, _AUTODAT1	/* 3 cycles */
	setb    _JTAG_TCK   	/* 2 cycles */
	mov	_IOA, _AUTODAT1 /* 3 cycles */
	setb    _JTAG_TCK   	/* 2 cycles */
	
	djnz    r2, 00001$	/* 3 cycles */

    __endasm;
  
  /* We are done, now skip the packet */
  OUTPKTEND = 0x88;
}
