web: add prototype web terminal
This commit is contained in:
parent
7957e5d74e
commit
7fb9d8bebc
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 132 KiB |
|
|
@ -0,0 +1,65 @@
|
||||||
|
// serial.js
|
||||||
|
let port;
|
||||||
|
|
||||||
|
async function connect() {
|
||||||
|
try {
|
||||||
|
port = await navigator.serial.requestPort();
|
||||||
|
await port.open({ baudRate: 115200 });
|
||||||
|
console.log('Connected to serial device:', port);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error connecting to serial device:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function write(addr, data) {
|
||||||
|
try {
|
||||||
|
if (!port) {
|
||||||
|
console.error('Serial port not connected');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the data to be sent
|
||||||
|
const sendData = `W${addr.toString(16).padStart(4, '0')}${data.toString(16).padStart(4, '0')}\r\n`;
|
||||||
|
|
||||||
|
// Example: Sending data to the device
|
||||||
|
const writer = port.writable.getWriter();
|
||||||
|
await writer.write(new TextEncoder().encode(sendData));
|
||||||
|
await writer.releaseLock();
|
||||||
|
console.log('Sent:', sendData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error sending data:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function read(addr) {
|
||||||
|
try {
|
||||||
|
if (!port) {
|
||||||
|
console.error('Serial port not connected');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the read command
|
||||||
|
const readCmd = `R${addr.toString(16).padStart(4, '0')}\r\n`;
|
||||||
|
|
||||||
|
// Send the read command to the device
|
||||||
|
const writer = port.writable.getWriter();
|
||||||
|
await writer.write(new TextEncoder().encode(readCmd));
|
||||||
|
await writer.releaseLock();
|
||||||
|
console.log('Sent:', readCmd);
|
||||||
|
|
||||||
|
// Read back the response
|
||||||
|
const reader = port.readable.getReader(); // Create a new reader
|
||||||
|
const { value, done } = await reader.read(); // Read from the stream
|
||||||
|
reader.releaseLock(); // Release the reader's lock
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
const responseData = new TextDecoder().decode(value);
|
||||||
|
console.log('Received:', responseData);
|
||||||
|
return responseData;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error reading data:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('connectButton').addEventListener('click', connect);
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
let data;
|
||||||
|
let fileUploaded = false;
|
||||||
|
|
||||||
|
document.getElementById('fileInput').addEventListener('change', function(event) {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = function(e) {
|
||||||
|
data = e.target.result;
|
||||||
|
fileUploaded = true; // Set the flag to indicate file upload completion
|
||||||
|
};
|
||||||
|
reader.readAsText(file);
|
||||||
|
});
|
||||||
|
|
||||||
|
function runAfterUpload() {
|
||||||
|
if (!fileUploaded) {
|
||||||
|
setTimeout(runAfterUpload, 100); // Check again after 100ms
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Your additional JavaScript code to run after file upload
|
||||||
|
web_terminal(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
runAfterUpload(); // Start checking for file upload completion
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
async function web_terminal(data){
|
||||||
|
let pyodide = await loadPyodide();
|
||||||
|
|
||||||
|
// Load Manta.yaml into pyodide's file system
|
||||||
|
pyodide.FS.writeFile("/manta.yaml", data, { encoding: "utf8" });
|
||||||
|
|
||||||
|
// Load micropip, setuptools, manta
|
||||||
|
await pyodide.loadPackage("micropip");
|
||||||
|
await pyodide.loadPackage("setuptools");
|
||||||
|
const micropip = pyodide.pyimport("micropip");
|
||||||
|
await micropip.install('../assets/manta-1.0.0-py3-none-any.whl');
|
||||||
|
|
||||||
|
pyodide.runPythonAsync(`
|
||||||
|
import asyncio
|
||||||
|
import time
|
||||||
|
|
||||||
|
from js import read, write
|
||||||
|
from manta.utils import value_to_words
|
||||||
|
|
||||||
|
from manta import Manta
|
||||||
|
m = Manta("/manta.yaml")
|
||||||
|
print(m.my_io_core)
|
||||||
|
|
||||||
|
async def set_probe(name, value):
|
||||||
|
# Write value to core
|
||||||
|
probe = m.my_io_core._memory_map.get(name)
|
||||||
|
addrs = probe["addrs"]
|
||||||
|
datas = value_to_words(value, len(addrs))
|
||||||
|
for a, d in zip(addrs, datas):
|
||||||
|
await write(a, d)
|
||||||
|
|
||||||
|
# Pulse strobe register
|
||||||
|
await write(m.my_io_core._base_addr, 0)
|
||||||
|
await write(m.my_io_core._base_addr, 1)
|
||||||
|
await write(m.my_io_core._base_addr, 0)
|
||||||
|
|
||||||
|
async def foobar():
|
||||||
|
for i in range(10):
|
||||||
|
await set_probe(f"LED{i%4}", 1)
|
||||||
|
await set_probe(f"LED{i%4}", 0)
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
#loop = asyncio.get_event_loop()
|
||||||
|
#loop.run_until_complete(foobar())
|
||||||
|
|
||||||
|
async def barfoo():
|
||||||
|
print("entering barfoo")
|
||||||
|
print(await read(m.my_io_core._base_addr))
|
||||||
|
print(await read(m.my_io_core._base_addr + 1))
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
loop.run_until_complete(barfoo())
|
||||||
|
#asyncio.run(foobar()) # doesn't work! asyncio.run() cannot be called from a running event loop
|
||||||
|
#await foobar() # doesn't work either! await outside function
|
||||||
|
#await barfoo() # doesn't work either! await outside function
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
|
||||||
|
|
||||||
|
## Open Serial Port
|
||||||
|
<button class="md-button" id="connectButton">Connect</button>
|
||||||
|
|
||||||
|
## Load Manta Configuration File
|
||||||
|
<button class="md-button" id="uploadButton">Upload File</button>
|
||||||
|
<input type="file" id="fileInput" accept=".yaml,.yml" style="display: none">
|
||||||
|
<div id="filePath"></div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Load Javascript -->
|
||||||
|
<script src="../javascripts/web_terminal.js"></script>
|
||||||
|
<script src="../javascripts/serial.js"></script>
|
||||||
|
<script src="../javascripts/upload.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/pyodide/v0.25.1/full/pyodide.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
const uploadButton = document.getElementById("uploadButton");
|
||||||
|
const fileInput = document.getElementById("fileInput");
|
||||||
|
const filePathDisplay = document.getElementById("filePath");
|
||||||
|
|
||||||
|
uploadButton.addEventListener("click", function() {
|
||||||
|
fileInput.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
fileInput.addEventListener("change", function() {
|
||||||
|
const filePath = fileInput.value; // Get the file path from the file input
|
||||||
|
filePathDisplay.textContent = "Loaded " + filePath; // Display the file path
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- <iframe src="https://app.surfer-project.org/?load_url=https://app.surfer-project.org/picorv32.vcd&startup_commands=show_quick_start;module_add%20testbench.top;toggle_menu" ,="" style="width: 100%; height: 100%"></iframe> -->
|
||||||
|
|
@ -66,6 +66,7 @@ nav:
|
||||||
- Getting Started: getting_started.md
|
- Getting Started: getting_started.md
|
||||||
- Alternatives: alternatives.md
|
- Alternatives: alternatives.md
|
||||||
- Architecture: architecture.md
|
- Architecture: architecture.md
|
||||||
|
- Web Terminal: web_terminal.md
|
||||||
- Usage:
|
- Usage:
|
||||||
- IO Core: io_core.md
|
- IO Core: io_core.md
|
||||||
- Logic Analyzer Core: logic_analyzer_core.md
|
- Logic Analyzer Core: logic_analyzer_core.md
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue