Hardware Design: SIE
Sign in or create your account | Project List | Help
Hardware Design: SIE Git Source Tree
Root/
| 1 | /* JTAG routines |
| 2 | |
| 3 | Copyright (C) 2004 Andrew Rogers |
| 4 | |
| 5 | This program is free software; you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by |
| 7 | the Free Software Foundation; either version 2 of the License, or |
| 8 | (at your option) any later version. |
| 9 | |
| 10 | This program is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | GNU General Public License for more details. |
| 14 | |
| 15 | You should have received a copy of the GNU General Public License |
| 16 | along with this program; if not, write to the Free Software |
| 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
| 18 | |
| 19 | #include "jtag.h" |
| 20 | |
| 21 | Jtag::Jtag(IOBase *iob) |
| 22 | { |
| 23 | io=iob; |
| 24 | postDRState=IOBase::RUN_TEST_IDLE; |
| 25 | postIRState=IOBase::RUN_TEST_IDLE; |
| 26 | deviceIndex=-1; |
| 27 | shiftDRincomplete=false; |
| 28 | } |
| 29 | |
| 30 | int Jtag::getChain() |
| 31 | { |
| 32 | io->tapTestLogicReset(); |
| 33 | io->setTapState(IOBase::SHIFT_DR); |
| 34 | byte idx[4]; |
| 35 | byte zero[4]; |
| 36 | numDevices=0; |
| 37 | for(int i=0; i<4; i++)zero[i]=0; |
| 38 | do{ |
| 39 | io->shiftTDITDO(zero,idx,32,false); |
| 40 | unsigned long id=byteArrayToLong(idx); |
| 41 | if(id!=0){ |
| 42 | numDevices++; |
| 43 | chainParam_t dev; |
| 44 | dev.idcode=id; |
| 45 | printf("Device with ID=%x found\n", id); |
| 46 | devices.insert(devices.begin(),dev); |
| 47 | } |
| 48 | else break; |
| 49 | }while(numDevices<MAXNUMDEVICES); |
| 50 | io->setTapState(IOBase::TEST_LOGIC_RESET); |
| 51 | return numDevices; |
| 52 | } |
| 53 | |
| 54 | int Jtag::selectDevice(int dev) |
| 55 | { |
| 56 | if(dev>=numDevices)deviceIndex=-1; |
| 57 | else deviceIndex=dev; |
| 58 | return deviceIndex; |
| 59 | } |
| 60 | |
| 61 | int Jtag::setDeviceIRLength(int dev, int len) |
| 62 | { |
| 63 | if(dev>=numDevices||dev<0)return -1; |
| 64 | devices[dev].irlen=len; |
| 65 | return dev; |
| 66 | } |
| 67 | |
| 68 | void Jtag::shiftDR(const byte *tdi, byte *tdo, int length, int align, bool exit) |
| 69 | { |
| 70 | if(deviceIndex<0)return; |
| 71 | int post=deviceIndex; |
| 72 | if(!shiftDRincomplete){ |
| 73 | io->setTapState(IOBase::SHIFT_DR); |
| 74 | int pre=numDevices-deviceIndex-1; |
| 75 | if(align){ |
| 76 | pre=-post; |
| 77 | while(pre<=0)pre+=align; |
| 78 | } |
| 79 | io->shift(false,pre,false); |
| 80 | } |
| 81 | if(tdi!=0&&tdo!=0)io->shiftTDITDO(tdi,tdo,length,post==0&&exit); |
| 82 | else if(tdi!=0&&tdo==0)io->shiftTDI(tdi,length,post==0&&exit); |
| 83 | else if(tdi==0&&tdo!=0)io->shiftTDO(tdo,length,post==0&&exit); |
| 84 | else io->shift(false,length,post==0&&exit); |
| 85 | if(exit){ |
| 86 | io->shift(false,post); |
| 87 | io->setTapState(postDRState); |
| 88 | shiftDRincomplete=false; |
| 89 | } |
| 90 | else shiftDRincomplete=true; |
| 91 | } |
| 92 | |
| 93 | void Jtag::shiftIR(const byte *tdi, byte *tdo) |
| 94 | { |
| 95 | if(deviceIndex<0)return; |
| 96 | io->setTapState(IOBase::SHIFT_IR); |
| 97 | int pre=0; |
| 98 | for(int dev=deviceIndex+1; dev<numDevices; dev++)pre+=devices[dev].irlen; // Calculate number of pre BYPASS bits. |
| 99 | int post=0; |
| 100 | for(int dev=0; dev<deviceIndex; dev++)post+=devices[dev].irlen; // Calculate number of post BYPASS bits. |
| 101 | io->shift(true,pre,false); |
| 102 | if(tdo!=0)io->shiftTDITDO(tdi,tdo,devices[deviceIndex].irlen,post==0); |
| 103 | else if(tdo==0)io->shiftTDI(tdi,devices[deviceIndex].irlen,post==0); |
| 104 | io->shift(true,post); |
| 105 | io->setTapState(postIRState); |
| 106 | } |
| 107 |
Branches:
master
