Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FipsyV2 - MachX02-1200 Integration #3

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
# Fipsy FPGA Programmer for ESP32

**esp-fipsy** library allows programming a [Fipsy FPGA breakout board](https://www.mocomakers.com/fipsy-fpga/) from an ESP32 microcontroller.
[TcpFipsyLoader](examples/TcpFipsyLoader/) demonstrates how to use this library.
**esp-fipsy** library allows programming a [Fipsy FPGA breakout board](https://www.fipsyfpga.com/) from an ESP32 microcontroller.

This library can be used in the Arduino IDE.

When using this project directly:
1. Visit the documentation for the ESP32 programmer on [https://www.fipsyfpga.com](https://www.fipsyfpga.com)
2. Program the ESP32 as a programmer using the [TcpFipsyLoader](examples/TcpFipsyLoader/). This file demonstrates how to use this library.
3. Once you have the IP address for the ESP32 use the [sendJed.py](scripts/sendJed.py) file to program the device. For example:

```
python sendJed.py --file "C:\Users\myuser\Projects\Fipsy-FPGA-edu\Examples\FipsyV2 - XO2-1200\1. Blinky\project_files\Implementation\FipsyBaseline_Implementation.jed" 192.168.1.194
```

For more information please see: [FipsyFPGA.com](https://www.fipsyfpga.com)




## Acknowledgements

We would like to thank Junxiao (Sunny) Shi - [yoursunny.com](https://yoursunny.com/) for significant contributions to the ESP32 programmer!
19 changes: 16 additions & 3 deletions examples/TcpFipsyLoader/TcpFipsyLoader.ino
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,26 @@ WiFiServer listener(34779);
void
setup() {
Serial.begin(115200);
if (!fpga.begin(14, 12, 13, 15)) {

// Choose either fuseTable.resize(343936) for MachX02-1200 or fuseTable.resize(73600) for MachXO2-256.
// These are the QF values from the .jed file.
// fuseTable.resize(73600);
fuseTable.resize(343936);

// Known alternate pinouts for SPI include:
// 18, 19, 23, 5
// 14, 12, 13, 15
// These pins are sck, miso, mosi, ss
if (!fpga.begin(18, 19, 23, 5)) {
Serial.println("Fipsy not found");
return;
} else {
uint32_t deviceID = fpga.getID();
Serial.print("Device ID: ");
Serial.printf("0x%08lx", deviceID);
Serial.println();
}

fuseTable.resize(73600);

WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
Expand Down
4 changes: 2 additions & 2 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name=esp-fipsy
version=0.0.20240618
version=0.0.20241004
author=Junxiao Shi
maintainer=Junxiao Shi
sentence=Fipsy FPGA programmer.
paragraph=This library programs MocoMakers Fipsy FPGA chip from ESP32 microcontroller.
category=Device Control
url=https://yoursunny.com
url=https://www.fipsyfpga.com
architectures=esp32
57 changes: 57 additions & 0 deletions scripts/sendJed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
Sends a .jed file to your ESP32
Example Usage:
python sendJed.py 192.168.1.2 --file 'C:\path\to\yourfiqle.jed'

or

python sendJed.py 192.168.1.2 --port 34779 --file 'C:\path\to\yourfile.jed'

"""

import socket
import argparse
import os

def netcat(host, port, content):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, int(port)))
s.sendall(content)
s.shutdown(socket.SHUT_WR)
while True:
data = s.recv(4096)
if not data:
break
print(repr(data.decode('utf-8')))
s.close()

def client(ip, port, filename):
# Check if file exists
if not os.path.isfile(filename):
raise FileNotFoundError(f"File {filename} does not exist.")

# Check if file ends with .jed
if not filename.endswith('.jed'):
raise ValueError("File must end with .jed extension.")

# Check if file has non-zero size
if os.path.getsize(filename) == 0:
raise ValueError("File is empty.")

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((ip, port))
print("Device connection initiated")

with open(filename, 'rb') as file:
content = file.read()
netcat(ip, port, content)

if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Send a .jed file over TCP and print returned text.')
parser.add_argument('ip', type=str, help='The IP address of the ESP32 server.')
parser.add_argument('--port', type=int, default=34779, help='The port number to connect to (default is 34779).')
parser.add_argument('--file', type=str, required=True, help='The path to the .jed file to send.')

args = parser.parse_args()

client(args.ip, args.port, args.file)
10 changes: 9 additions & 1 deletion src/fipsy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@ Fipsy::begin(int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1, int8_t ss = -1

auto rsp = spiTrans<8>({0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
uint32_t deviceId = (rsp[4] << 24) | (rsp[5] << 16) | (rsp[6] << 8) | (rsp[7] << 0);
return deviceId == 0x012B8043;
// 0x012B8043 is for MachXO2-256 and 0x012BA043 is MachXO2-1200HC
return deviceId == 0x012B8043 || deviceId == 0x012BA043;
}

uint32_t
Fipsy::getID() {
auto resp = spiTrans<8>({0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
uint32_t deviceId = (resp[4] << 24) | (resp[5] << 16) | (resp[6] << 8) | (resp[7] << 0);
return deviceId; // Return the Device ID directly
}

void
Expand Down
6 changes: 6 additions & 0 deletions src/fipsy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ class Fipsy {
*/
bool begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss);

/**
* @brief Detect Fipsy device ID.
* @return Return any Device ID found.
*/
uint32_t getID();

/**
* @brief Release SPI bus.
* @pre begin()
Expand Down
26 changes: 24 additions & 2 deletions src/internal/jedec.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "jedec.hpp"
#include <stdio.h>

namespace fipsy {

Expand Down Expand Up @@ -147,13 +148,28 @@ class JedecParser {
}

bool handleL() {
printf("Doing function: HandleL\n");
int addr = 0;
for (int i = 0; i < qfSize; ++i) {
if (!appendDigit<10>(addr, readChar())) {
while (true) {
char ch;
// readChar() does not let us capture terminal strings, so doing it manually here
// this fixes a bug where readChar() denpends on sizeQf length - which is NOT related
// to the length of L characters. That is, length of QF chars != length of L chars.
input.readBytes(&ch, 1);

// printf("Char here is [%c] booleab pass: %B\n",ch, ch=='0');

if (!(ch >= '0' && ch <= '9')) {
break;
}

if (!appendDigit<10>(addr, ch)) {
return false;
}
}

printf("Starting addr: %d\n", addr);

while (true) {
char ch = readChar();
switch (ch) {
Expand All @@ -163,11 +179,17 @@ class JedecParser {
case '*':
return true;
default:
printf("Failure F2: Unrecognized character\n");
return false;
}

// TODO: Fix this check so it passes for Fipsy V2 - MachX02-1200
/*
if (addr >= qf) {
printf("Failure F3: Addr: %d and qf: %d for character index: %d\n", addr, qf, index);
return false;
}
*/
fuseTable[addr++] = ch - '0';
}
}
Expand Down
Loading