├── README.md └── xvc_srv.lua /README.md: -------------------------------------------------------------------------------- 1 | # esp-wifi-xvc 2 | Wi-Fi enabled XVC programmer/debugger based on ESP8266 3 | 4 | First version of the sources were also published on alt.sources: 5 | https://groups.google.com/forum/#!topic/alt.sources/RZbOS12JgMI 6 | -------------------------------------------------------------------------------- /xvc_srv.lua: -------------------------------------------------------------------------------- 1 | -- a simple xvc server 2 | -- structure implementing the JTAG server 3 | -- For ISE server should be defined as: 4 | -- xilinx_xvc host=172.200.1.23:6767 maxpacketsize=1024 disableversioncheck=true 5 | -- Definition of pins used for JTAG 6 | TCK=6 -- GPIO 12 7 | TMS=7 -- GPIO 13 8 | TDI=5 -- GPIO 14 9 | TDO=0 -- GPIO 16 10 | gpio.mode(TCK,gpio.OUTPUT) 11 | gpio.mode(TMS,gpio.OUTPUT) 12 | gpio.mode(TDI,gpio.OUTPUT) 13 | gpio.mode(TDO,gpio.INPUT) 14 | 15 | jtag_connected = 0 16 | thresh = 10 17 | count = 0 18 | buf_in = "" 19 | 20 | function jtag_start() 21 | count = 0 22 | jtag_connected = 1 23 | buf_in = "" 24 | end 25 | 26 | function jtag_stop() 27 | count = 0 28 | jtag_connected = 0 29 | buf_in = "" 30 | end 31 | 32 | -- Function pulse uses the global buffer buf_in 33 | -- index i1 points to the begining of the TMS data 34 | -- index i2 points to the begining of the TDI data 35 | -- len - defines number of bits to be shifted 36 | function pulse(i1,i2,len) 37 | dout="" 38 | obyte=0 39 | mask=1 40 | a=tmr.now() 41 | for i=1,len do 42 | if bit.band(buf_in:byte(i2),mask)~=0 then 43 | gpio.write(TDI,gpio.HIGH) 44 | else 45 | gpio.write(TDI,gpio.LOW) 46 | end 47 | if bit.band(buf_in:byte(i1),mask)~=0 then 48 | gpio.write(TMS,gpio.HIGH) 49 | else 50 | gpio.write(TMS,gpio.LOW) 51 | end 52 | if gpio.read(TDO)==1 then 53 | obyte = bit.bor(obyte,mask) 54 | end 55 | gpio.write(TCK,gpio.HIGH) 56 | mask = bit.lshift(mask,1) 57 | if mask==256 then 58 | i1 = i1 + 1 59 | i2 = i2 + 1 60 | mask = 1 61 | dout = dout .. string.char(obyte) 62 | obyte = 0 63 | tmr.wdclr() 64 | end 65 | gpio.write(TCK,gpio.LOW) 66 | end 67 | -- Add the last, uncompleted byte to the output data 68 | if mask ~= 1 then 69 | dout = dout .. string.char(obyte) 70 | end 71 | b=tmr.now() 72 | print("time="..tostring(b-a)) 73 | print("heap="..tostring(node.heap())) 74 | return dout 75 | end 76 | 77 | 78 | function jtag_feed(c,new_data) 79 | buf_in = buf_in .. new_data 80 | -- check if there is a known command at the begining of the buffer 81 | if buf_in:sub(1,8)=="getinfo:" then 82 | print("received getinfo\n") 83 | -- Service getinfo command 84 | c:send("xvcServer_v1.0:512\n") 85 | -- Remove the command from the buffer 86 | buf_in = buf_in:sub(9,-1) 87 | return true 88 | elseif buf_in:sub(1,7)=="settck:" then 89 | -- Service settck command 90 | print("received settck\n") 91 | if buf_in:len() >= 11 then 92 | -- Currently we simply claim, that we have set the clock 93 | -- period, even though it doesn't work! 94 | fck=buf_in:sub(8,11) 95 | -- We accept only 1000Hz 96 | fck=string.char(0x40)..string.char(0x42)..string.char(0x0f)..string.char(0) 97 | c:send(fck) 98 | -- What really should be done: 99 | -- Read the TCK period 100 | -- Program the new clock frequency 101 | -- Prepare and send the answer 102 | -- Remove the command from the buffer 103 | buf_in = buf_in:sub(12,-1) 104 | end 105 | return true 106 | elseif buf_in:sub(1,6)=="shift:" then 107 | -- Service shift command 108 | if buf_in:len() >= 10 then 109 | -- Read the length 110 | length=buf_in:byte(7)+256*buf_in:byte(8)+65536*buf_in:byte(9)+16777216*buf_in:byte(10) 111 | print("received shift ".. tostring(length) .." bits\n") 112 | -- Calculate length in bytes 113 | blen=math.floor((length+7)/8) 114 | -- Check if the whole vector is received 115 | if buf_in:len() >= 10+2*blen then 116 | -- Shift the whole vector 117 | dout = pulse(11,11+blen,length) 118 | -- Send the results 119 | c:send(dout) 120 | -- remove the command from the buffer 121 | buf_in = buf_in:sub(10+2*blen+1,-1) 122 | end 123 | end 124 | end 125 | end 126 | 127 | s=net.createServer(net.TCP,1000) 128 | s:listen(6767,function(c) 129 | -- Check, if we can accept a client 130 | if jtag_connected > 0 then 131 | print("Other client already connected\n") 132 | c:close() 133 | return 134 | else 135 | print("Client connected\n") 136 | jtag_start() 137 | end 138 | c:on("receive",function(c,l) 139 | jtag_feed(c,l) 140 | end) 141 | c:on("disconnection",function(c) 142 | print("Client disconnected\n") 143 | jtag_stop() 144 | end) 145 | end) 146 | 147 | 148 | --------------------------------------------------------------------------------