Skip to content

Commit

Permalink
WiFi support for xvc-pico using Pico W
Browse files Browse the repository at this point in the history
  • Loading branch information
kholia committed Apr 21, 2024
1 parent 0e850f4 commit 2f59988
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 2 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ Update: This project was tested with `Vivado ML Standard 2023.1`, Raspberry Pi
Pico as the JTAG programmer (XVC server), and EBAZ4205 'Development' FPGA Board
in May 2023.

Update (April-2024): The `xvc-pico-wifi` version was tested successfully with
Vivado v2023.1 (64-bit).


### Building pico-xvc (for Linux users)

Expand Down Expand Up @@ -183,5 +186,3 @@ Note: /dev/ttyACM(n) will appear when Pico's USB is connected.
- https://github.com/phdussud/pico-dirtyJtag/
- https://github.com/kholia/Colorlight-5A-75B
- https://github.com/fusesoc/blinky#ebaz4205-development-board
- https://github.com/maxnet/pico-webserver/ approach (LWIP_SOCKET is not available yet!)
- [NEXT] Do a 100% standalone port to Pico W ;)
2 changes: 2 additions & 0 deletions xvc-pico-wifi/credentials.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
static const char* MY_SSID = "home";
static const char* MY_PASSPHRASE = "password";
255 changes: 255 additions & 0 deletions xvc-pico-wifi/xvc-pico-wifi.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
// https://github.com/gtortone/esp-xvcd (upstream)

#include <ESP8266WiFi.h>
#include "credentials.h"
#include <stdint.h>

// Pin out
static constexpr const int tdi_gpio = 16;
static constexpr const int tdo_gpio = 17;
static constexpr const int tck_gpio = 18;
static constexpr const int tms_gpio = 19;

//#define VERBOSE
#define MAX_WRITE_SIZE 512
#define ERROR_OK 1
// #define XVCD_AP_MODE
#define XVCD_STATIC_IP

IPAddress ip(192, 168, 1, 13);
IPAddress gateway(192, 168, 1, 1);
IPAddress netmask(255, 255, 255, 0);
const int port = 2542;

WiFiServer server(port);
WiFiClient client;

// JTAG buffers
uint8_t cmd[16];
uint8_t buffer[1024], result[512];

/* Transition delay coefficients */
static const unsigned int jtag_delay = 10; // NOTE!

static uint32_t jtag_xfer(uint8_t n, uint32_t tms, uint32_t tdi)
{
uint32_t tdo = 0;
for (uint8_t i = 0; i < n; i++) {
jtag_write(0, tms & 1, tdi & 1);
tdo |= jtag_read() << i;
jtag_write(1, tms & 1, tdi & 1);
tms >>= 1;
tdi >>= 1;
}
return tdo;
}

static bool jtag_read(void)
{
return digitalRead(tdo_gpio) & 1;
}

static void jtag_write(uint8_t tck, uint8_t tms, uint8_t tdi)
{
digitalWrite(tck_gpio, tck);
digitalWrite(tms_gpio, tms);
digitalWrite(tdi_gpio, tdi);

for (uint32_t i = 0; i < jtag_delay; i++)
asm volatile ("nop");
}

static int jtag_init(void)
{
pinMode(tdo_gpio, INPUT);
pinMode(tdi_gpio, OUTPUT);
pinMode(tck_gpio, OUTPUT);
pinMode(tms_gpio, OUTPUT);

digitalWrite(tdi_gpio, 0);
digitalWrite(tck_gpio, 0);
digitalWrite(tms_gpio, 1);

return ERROR_OK;
}

int sread(void *target, int len) {

uint8_t *t = (uint8_t *) target;

while (len) {
int r = client.read(t, len);
if (r <= 0)
return r;
t += r;
len -= r;
}
return 1;
}

int srcmd(void * target, int maxlen) {
uint8_t *t = (uint8_t *) target;

while (maxlen) {
int r = client.read(t, 1);
if (r <= 0)
return r;

if (*t == ':') {
return 1;
}

t += r;
maxlen -= r;
}

return 0;
}

void setup() {
delay(1000);

Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println();
#ifdef XVCD_AP_MODE
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(ip, ip, netmask);
WiFi.softAP(MY_SSID, MY_PASSPHRASE);
#else
#ifdef XVCD_STATIC_IP
WiFi.config(ip, gateway, netmask);
#endif
WiFi.begin(MY_SSID, MY_PASSPHRASE);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
#endif
Serial.print("Starting XVC Server on port ");
Serial.println(port);

jtag_init();

server.begin();
server.setNoDelay(true);
}

void loop() {

start: if (!client.connected()) {
// try to connect to a new client
client = server.available();
} else {
// read data from the connected client
if (client.available()) {
while (client.connected()) {

do {

if (srcmd(cmd, 8) != 1)
goto start;

if (memcmp(cmd, "getinfo:", 8) == 0) {
#ifdef VERBOSE
Serial.write("XVC_info\n");
#endif
client.write("xvcServer_v1.0:");
client.print(MAX_WRITE_SIZE);
client.write("\n");
goto start;
}

if (memcmp(cmd, "settck:", 7) == 0) {
#ifdef VERBOSE
Serial.write("XVC_tck\n");
#endif
int ntck;
if (sread(&ntck, 4) != 1) {
Serial.println("reading tck failed\n");
goto start;
}
// Actually TCK frequency is fixed, but replying a fixed TCK will halt hw_server
client.write((const uint8_t *)&ntck, 4);
goto start;
}

if (memcmp(cmd, "shift:", 6) != 0) {
cmd[15] = '\0';
Serial.print("invalid cmd ");
Serial.println((char *)cmd);
goto start;
}

int len;
if (sread(&len, 4) != 1) {
Serial.println("reading length failed\n");
goto start;
}

unsigned int nr_bytes = (len + 7) / 8;

#ifdef VERBOSE
Serial.print("len = ");
Serial.print(len);
Serial.print(" nr_bytes = ");
Serial.println(nr_bytes);
#endif
if (nr_bytes * 2 > sizeof(buffer)) {
Serial.println("buffer size exceeded");
goto start;
}

if (sread(buffer, nr_bytes * 2) != 1) {
Serial.println("reading data failed\n");
goto start;
}

memset((uint8_t *)result, 0, nr_bytes);

jtag_write(0, 1, 1);

int bytesLeft = nr_bytes;
int bitsLeft = len;
int byteIndex = 0;
uint32_t tdi, tms, tdo;

while (bytesLeft > 0) {
tms = 0;
tdi = 0;
tdo = 0;
if (bytesLeft >= 4) {
memcpy(&tms, &buffer[byteIndex], 4);
memcpy(&tdi, &buffer[byteIndex + nr_bytes], 4);
tdo = jtag_xfer(32, tms, tdi);
memcpy(&result[byteIndex], &tdo, 4);
bytesLeft -= 4;
bitsLeft -= 32;
byteIndex += 4;
} else {
memcpy(&tms, &buffer[byteIndex], bytesLeft);
memcpy(&tdi, &buffer[byteIndex + nr_bytes], bytesLeft);
tdo = jtag_xfer(bitsLeft, tms, tdi);
memcpy(&result[byteIndex], &tdo, bytesLeft);
bytesLeft = 0;
break;
}
}

jtag_write(0, 1, 0);

if (client.write(result, nr_bytes) != nr_bytes) {
Serial.println("write");
}
} while (1);
}
}
}
}

0 comments on commit 2f59988

Please sign in to comment.