/*----------------------------------------------------------------------------- * Hardware-dependent code for usb_jtag *----------------------------------------------------------------------------- * Copyright (C) 2007 Kolja Waschk, ixo.de *----------------------------------------------------------------------------- * This code is part of usbjtag. usbjtag is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. usbjtag is distributed in the hope * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. You should have received a * copy of the GNU General Public License along with this program in the file * COPYING; if not, write to the Free Software Foundation, Inc., 51 Franklin * St, Fifth Floor, Boston, MA 02110-1301 USA *----------------------------------------------------------------------------- */ #include #include "hardware.h" #include "delay.h" //----------------------------------------------------------------------------- #define HAVE_OE_LED 1 //----------------------------------------------------------------------------- /* JTAG TDI */ sbit at 0xB3 TDI; /* Port D.3 */ #define bmTDIOE bmBIT3 #define SetTDI(x) do{TDI=(x);}while(0) /* JTAG TCK */ sbit at 0xB2 TCK; /* Port D.2 */ #define bmTCKOE bmBIT2 #define SetTCK(x) do{TCK=(x);}while(0) /* JTAG TMS */ sbit at 0xB1 TMS; /* Port D.1 */ #define bmTMSOE bmBIT1 #define SetTMS(x) do{TMS=(x);}while(0) /* JTAG TDO */ sbit at 0xB0 TDO; /* Port D.0 */ #define bmTDOOE bmBIT0 #define GetTDO(x) TDO //----------------------------------------------------------------------------- #ifdef HAVE_OE_LED sbit at 0xB4 OELED; /* Port D.4 */ #define bmOELEDOE bmBIT4 #define SetOELED(x) do{OELED=(x);}while(0) #else #define bmOELEDOE 0 #define SetOELED(x) while(0){} #endif //----------------------------------------------------------------------------- #define bmPROGOUTOE (bmTCKOE|bmTDIOE|bmTMSOE|bmOELEDOE) #define bmPROGINOE (bmTDOOE) //----------------------------------------------------------------------------- void ProgIO_Poll(void) {} // These aren't called anywhere in usbjtag.c, but I plan to do so... void ProgIO_Enable(void) {} void ProgIO_Disable(void) {} void ProgIO_Deinit(void) {} void ProgIO_Init(void) { /* The following code depends on your actual circuit design. Make required changes _before_ you try the code! */ // set the CPU clock to 48MHz, enable clock output to FPGA CPUCS = bmCLKOE | bmCLKSPD1; // put the system in FIFO mode by default // internal clock source at 48Mhz, drive output pin, synchronous mode // NOTE: Altera USB-Blaster does not work in another mode IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmIFCFG1 | bmIFCFG0; // Output enable (TDO input, others output) OED = (OED&~bmPROGINOE) | bmPROGOUTOE; } void ProgIO_Set_State(unsigned char d) { /* Set state of output pins: * * d.0 => TCK * d.1 => TMS * d.4 => TDI * d.5 => LED / Output Enable */ SetTCK((d & bmBIT0) ? 1 : 0); SetTMS((d & bmBIT1) ? 1 : 0); SetTDI((d & bmBIT4) ? 1 : 0); #ifdef HAVE_OE_LED SetOELED((d & bmBIT5) ? 0 : 1); #endif } unsigned char ProgIO_Set_Get_State(unsigned char d) { /* Set state of output pins (s.a.) * then read state of input pins: * * TDO => d.0 */ ProgIO_Set_State(d); return 2|GetTDO(); } //----------------------------------------------------------------------------- void ProgIO_ShiftOut(unsigned char c) { /* Shift out byte C: * * 8x { * Output least significant bit on TDI * Raise TCK * Shift c right * Lower TCK * } */ (void)c; /* argument passed in DPL */ _asm MOV A,DPL ;; Bit0 RRC A MOV _TDI,C SETB _TCK ;; Bit1 RRC A CLR _TCK MOV _TDI,C SETB _TCK ;; Bit2 RRC A CLR _TCK MOV _TDI,C SETB _TCK ;; Bit3 RRC A CLR _TCK MOV _TDI,C SETB _TCK ;; Bit4 RRC A CLR _TCK MOV _TDI,C SETB _TCK ;; Bit5 RRC A CLR _TCK MOV _TDI,C SETB _TCK ;; Bit6 RRC A CLR _TCK MOV _TDI,C SETB _TCK ;; Bit7 RRC A CLR _TCK MOV _TDI,C SETB _TCK NOP CLR _TCK ret _endasm; } /* ;; For ShiftInOut, the timing is a little more ;; critical because we have to read _TDO/shift/set _TDI ;; when _TCK is low. But 20% duty cycle at 48/4/5 MHz ;; is just like 50% at 6 Mhz, and that's still acceptable */ unsigned char ProgIO_ShiftInOut(unsigned char c) { /* Shift out byte C, shift in from TDO: * * 8x { * Read carry from TDO * Output least significant bit on TDI * Raise TCK * Shift c right, append carry (TDO) at left * Lower TCK * } * Return c. */ (void)c; /* argument passed in DPL */ _asm MOV A,DPL ;; Bit0 MOV C,_TDO RRC A MOV _TDI,C SETB _TCK CLR _TCK ;; Bit1 MOV C,_TDO RRC A MOV _TDI,C SETB _TCK CLR _TCK ;; Bit2 MOV C,_TDO RRC A MOV _TDI,C SETB _TCK CLR _TCK ;; Bit3 MOV C,_TDO RRC A MOV _TDI,C SETB _TCK CLR _TCK ;; Bit4 MOV C,_TDO RRC A MOV _TDI,C SETB _TCK CLR _TCK ;; Bit5 MOV C,_TDO RRC A MOV _TDI,C SETB _TCK CLR _TCK ;; Bit6 MOV C,_TDO RRC A MOV _TDI,C SETB _TCK CLR _TCK ;; Bit7 MOV C,_TDO RRC A MOV _TDI,C SETB _TCK CLR _TCK MOV DPL,A ret _endasm; /* return value in DPL */ return c; }