mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-11 18:40:45 +00:00
add html extra for webusb example
This commit is contained in:
parent
2b521e0c10
commit
b5d218e684
@ -122,7 +122,7 @@ in your project.
|
|||||||
.. |Build Status| image:: https://github.com/hathach/tinyusb/workflows/Build/badge.svg
|
.. |Build Status| image:: https://github.com/hathach/tinyusb/workflows/Build/badge.svg
|
||||||
:target: https://github.com/hathach/tinyusb/actions
|
:target: https://github.com/hathach/tinyusb/actions
|
||||||
.. |Documentation Status| image:: https://readthedocs.org/projects/tinyusb/badge/?version=latest
|
.. |Documentation Status| image:: https://readthedocs.org/projects/tinyusb/badge/?version=latest
|
||||||
:target: https://openinput.readthedocs.io/en/latest/?badge=latest
|
:target: https://tinyusb.readthedocs.io/en/latest/?badge=latest
|
||||||
.. |License| image:: https://img.shields.io/badge/license-MIT-brightgreen.svg
|
.. |License| image:: https://img.shields.io/badge/license-MIT-brightgreen.svg
|
||||||
:target: https://opensource.org/licenses/MIT
|
:target: https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
@ -39,4 +39,7 @@ html_theme_options = {
|
|||||||
'sidebar_hide_name': True,
|
'sidebar_hide_name': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# examples for webusb
|
||||||
|
html_extra_path = ['html_extra']
|
||||||
|
|
||||||
todo_include_todos = True
|
todo_include_todos = True
|
||||||
|
107
docs/html_extra/examples/webusb-serial/application.css
Normal file
107
docs/html_extra/examples/webusb-serial/application.css
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
.main-content {
|
||||||
|
width: 1440px;
|
||||||
|
margin: auto;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connect-container {
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender, .receiver {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.receiver {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lines-header {
|
||||||
|
height: 30px;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #444;
|
||||||
|
line-height: 30px;
|
||||||
|
color: white;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lines-body {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #222;
|
||||||
|
min-height: 300px;
|
||||||
|
padding: 10px 0 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line, .command-line {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
color: #f1f1f1;
|
||||||
|
background-color: #222;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line:hover {
|
||||||
|
background-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button::before {
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
-webkit-box-shadow: #959595 0 2px 5px;
|
||||||
|
-moz-box-shadow: #959595 0 2px 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: #959595 0 2px 5px;
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
left: 0;
|
||||||
|
padding: 2px 0 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:active::before { padding: 1px 0 0; }
|
||||||
|
|
||||||
|
.button.black {
|
||||||
|
background: #656565;
|
||||||
|
background: -webkit-gradient(linear, 0 0, 0 bottom, from(#656565), to(#444));
|
||||||
|
background: -moz-linear-gradient(#656565, #444);
|
||||||
|
background: linear-gradient(#656565, #444);
|
||||||
|
border: solid 1px #535353;
|
||||||
|
border-bottom: solid 3px #414141;
|
||||||
|
box-shadow: inset 0 0 0 1px #939393;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 1px 0 #2f2f2f;
|
||||||
|
padding: 8px 16px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.black:hover {
|
||||||
|
background: #4c4c4c;
|
||||||
|
background: -webkit-gradient(linear, 0 0, 0 bottom, from(#4c4c4c), to(#565656));
|
||||||
|
background: -moz-linear-gradient(#4c4c4c, #565656);
|
||||||
|
background: linear-gradient(#4c4c4c, #565656);
|
||||||
|
border: solid 1px #464646;
|
||||||
|
border-bottom: solid 3px #414141;
|
||||||
|
box-shadow: inset 0 0 0 1px #818181;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.black:active {
|
||||||
|
background: #474747;
|
||||||
|
background: -webkit-gradient(linear, 0 0, 0 bottom, from(#474747), to(#444));
|
||||||
|
background: -moz-linear-gradient(#474747, #444);
|
||||||
|
background: linear-gradient(#474747, #444);
|
||||||
|
border: solid 1px #2f2f2f;
|
||||||
|
box-shadow: inset 0 10px 15px 0 #3e3e3e;
|
||||||
|
}
|
90
docs/html_extra/examples/webusb-serial/application.js
Normal file
90
docs/html_extra/examples/webusb-serial/application.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', event => {
|
||||||
|
let connectButton = document.querySelector("#connect");
|
||||||
|
let statusDisplay = document.querySelector('#status');
|
||||||
|
let port;
|
||||||
|
|
||||||
|
function addLine(linesId, text) {
|
||||||
|
var senderLine = document.createElement("div");
|
||||||
|
senderLine.className = 'line';
|
||||||
|
var textnode = document.createTextNode(text);
|
||||||
|
senderLine.appendChild(textnode);
|
||||||
|
document.getElementById(linesId).appendChild(senderLine);
|
||||||
|
return senderLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentReceiverLine;
|
||||||
|
|
||||||
|
function appendLine(linesId, text) {
|
||||||
|
if (currentReceiverLine) {
|
||||||
|
currentReceiverLine.innerHTML = currentReceiverLine.innerHTML + text;
|
||||||
|
} else {
|
||||||
|
currentReceiverLine = addLine(linesId, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function connect() {
|
||||||
|
port.connect().then(() => {
|
||||||
|
statusDisplay.textContent = '';
|
||||||
|
connectButton.textContent = 'Disconnect';
|
||||||
|
|
||||||
|
port.onReceive = data => {
|
||||||
|
let textDecoder = new TextDecoder();
|
||||||
|
console.log(textDecoder.decode(data));
|
||||||
|
if (data.getInt8() === 13) {
|
||||||
|
currentReceiverLine = null;
|
||||||
|
} else {
|
||||||
|
appendLine('receiver_lines', textDecoder.decode(data));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
port.onReceiveError = error => {
|
||||||
|
console.error(error);
|
||||||
|
};
|
||||||
|
}, error => {
|
||||||
|
statusDisplay.textContent = error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
connectButton.addEventListener('click', function() {
|
||||||
|
if (port) {
|
||||||
|
port.disconnect();
|
||||||
|
connectButton.textContent = 'Connect';
|
||||||
|
statusDisplay.textContent = '';
|
||||||
|
port = null;
|
||||||
|
} else {
|
||||||
|
serial.requestPort().then(selectedPort => {
|
||||||
|
port = selectedPort;
|
||||||
|
connect();
|
||||||
|
}).catch(error => {
|
||||||
|
statusDisplay.textContent = error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
serial.getPorts().then(ports => {
|
||||||
|
if (ports.length === 0) {
|
||||||
|
statusDisplay.textContent = 'No device found.';
|
||||||
|
} else {
|
||||||
|
statusDisplay.textContent = 'Connecting...';
|
||||||
|
port = ports[0];
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let commandLine = document.getElementById("command_line");
|
||||||
|
|
||||||
|
commandLine.addEventListener("keypress", function(event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
if (commandLine.value.length > 0) {
|
||||||
|
addLine('sender_lines', commandLine.value);
|
||||||
|
commandLine.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
port.send(new TextEncoder('utf-8').encode(String.fromCharCode(event.which || event.keyCode)));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
33
docs/html_extra/examples/webusb-serial/index.html
Normal file
33
docs/html_extra/examples/webusb-serial/index.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>TinyUSB</title>
|
||||||
|
<script src="serial.js"></script>
|
||||||
|
<script src="application.js"></script>
|
||||||
|
<link rel="stylesheet" href="application.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="main-content">
|
||||||
|
<h1>TinyUSB - WebUSB Serial Example</h1>
|
||||||
|
<div class="connect-container">
|
||||||
|
<button id="connect" class="button black">Connect</button>
|
||||||
|
<span id="status"></span>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="sender">
|
||||||
|
<div class="lines-header">Sender</div>
|
||||||
|
<div class="lines-body">
|
||||||
|
<div id="sender_lines" class="lines"></div>
|
||||||
|
<input id="command_line" class="command-line" placeholder="Start typing ...." />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="receiver">
|
||||||
|
<div class="lines-header">Receiver</div>
|
||||||
|
<div class="lines-body">
|
||||||
|
<div id="receiver_lines" class="lines"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
89
docs/html_extra/examples/webusb-serial/serial.js
Normal file
89
docs/html_extra/examples/webusb-serial/serial.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
var serial = {};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
serial.getPorts = function() {
|
||||||
|
return navigator.usb.getDevices().then(devices => {
|
||||||
|
return devices.map(device => new serial.Port(device));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
serial.requestPort = function() {
|
||||||
|
const filters = [
|
||||||
|
{ 'vendorId': 0x239A }, // Adafruit boards
|
||||||
|
{ 'vendorId': 0xcafe }, // TinyUSB example
|
||||||
|
];
|
||||||
|
return navigator.usb.requestDevice({ 'filters': filters }).then(
|
||||||
|
device => new serial.Port(device)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
serial.Port = function(device) {
|
||||||
|
this.device_ = device;
|
||||||
|
this.interfaceNumber = 0;
|
||||||
|
this.endpointIn = 0;
|
||||||
|
this.endpointOut = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
serial.Port.prototype.connect = function() {
|
||||||
|
let readLoop = () => {
|
||||||
|
this.device_.transferIn(this.endpointIn, 64).then(result => {
|
||||||
|
this.onReceive(result.data);
|
||||||
|
readLoop();
|
||||||
|
}, error => {
|
||||||
|
this.onReceiveError(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.device_.open()
|
||||||
|
.then(() => {
|
||||||
|
if (this.device_.configuration === null) {
|
||||||
|
return this.device_.selectConfiguration(1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
var interfaces = this.device_.configuration.interfaces;
|
||||||
|
interfaces.forEach(element => {
|
||||||
|
element.alternates.forEach(elementalt => {
|
||||||
|
if (elementalt.interfaceClass==0xFF) {
|
||||||
|
this.interfaceNumber = element.interfaceNumber;
|
||||||
|
elementalt.endpoints.forEach(elementendpoint => {
|
||||||
|
if (elementendpoint.direction == "out") {
|
||||||
|
this.endpointOut = elementendpoint.endpointNumber;
|
||||||
|
}
|
||||||
|
if (elementendpoint.direction=="in") {
|
||||||
|
this.endpointIn =elementendpoint.endpointNumber;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(() => this.device_.claimInterface(this.interfaceNumber))
|
||||||
|
.then(() => this.device_.selectAlternateInterface(this.interfaceNumber, 0))
|
||||||
|
.then(() => this.device_.controlTransferOut({
|
||||||
|
'requestType': 'class',
|
||||||
|
'recipient': 'interface',
|
||||||
|
'request': 0x22,
|
||||||
|
'value': 0x01,
|
||||||
|
'index': this.interfaceNumber}))
|
||||||
|
.then(() => {
|
||||||
|
readLoop();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
serial.Port.prototype.disconnect = function() {
|
||||||
|
return this.device_.controlTransferOut({
|
||||||
|
'requestType': 'class',
|
||||||
|
'recipient': 'interface',
|
||||||
|
'request': 0x22,
|
||||||
|
'value': 0x00,
|
||||||
|
'index': this.interfaceNumber})
|
||||||
|
.then(() => this.device_.close());
|
||||||
|
};
|
||||||
|
|
||||||
|
serial.Port.prototype.send = function(data) {
|
||||||
|
return this.device_.transferOut(this.endpointOut, data);
|
||||||
|
};
|
||||||
|
})();
|
Loading…
x
Reference in New Issue
Block a user