From 2b521e0c101c371d1b0f36d594aa1e20642b9603 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Aug 2021 12:29:32 +0700 Subject: [PATCH 1/4] rename to .readthedocs.yaml exclude all submodules for docs --- .readthedocs.yml => .readthedocs.yaml | 5 +++++ 1 file changed, 5 insertions(+) rename .readthedocs.yml => .readthedocs.yaml (83%) diff --git a/.readthedocs.yml b/.readthedocs.yaml similarity index 83% rename from .readthedocs.yml rename to .readthedocs.yaml index 215b5fed..e83cd90f 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yaml @@ -11,3 +11,8 @@ python: version: 3.8 install: - requirements: docs/requirements.txt + +submodules: + include: [] + recursive: false + \ No newline at end of file From b5d218e6845da43f693e5caa31d883de3b997f41 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Aug 2021 14:06:08 +0700 Subject: [PATCH 2/4] add html extra for webusb example --- README.rst | 2 +- docs/conf.py | 3 + .../examples/webusb-serial/application.css | 107 ++++++++++++++++++ .../examples/webusb-serial/application.js | 90 +++++++++++++++ .../examples/webusb-serial/index.html | 33 ++++++ .../examples/webusb-serial/serial.js | 89 +++++++++++++++ 6 files changed, 323 insertions(+), 1 deletion(-) create mode 100644 docs/html_extra/examples/webusb-serial/application.css create mode 100644 docs/html_extra/examples/webusb-serial/application.js create mode 100644 docs/html_extra/examples/webusb-serial/index.html create mode 100644 docs/html_extra/examples/webusb-serial/serial.js diff --git a/README.rst b/README.rst index 9e7c3139..8a92c267 100644 --- a/README.rst +++ b/README.rst @@ -122,7 +122,7 @@ in your project. .. |Build Status| image:: https://github.com/hathach/tinyusb/workflows/Build/badge.svg :target: https://github.com/hathach/tinyusb/actions .. |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 :target: https://opensource.org/licenses/MIT diff --git a/docs/conf.py b/docs/conf.py index c7a17478..1d05d7cb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -39,4 +39,7 @@ html_theme_options = { 'sidebar_hide_name': True, } +# examples for webusb +html_extra_path = ['html_extra'] + todo_include_todos = True diff --git a/docs/html_extra/examples/webusb-serial/application.css b/docs/html_extra/examples/webusb-serial/application.css new file mode 100644 index 00000000..4ae0138b --- /dev/null +++ b/docs/html_extra/examples/webusb-serial/application.css @@ -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; +} diff --git a/docs/html_extra/examples/webusb-serial/application.js b/docs/html_extra/examples/webusb-serial/application.js new file mode 100644 index 00000000..283121e3 --- /dev/null +++ b/docs/html_extra/examples/webusb-serial/application.js @@ -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))); + }); + }); +})(); diff --git a/docs/html_extra/examples/webusb-serial/index.html b/docs/html_extra/examples/webusb-serial/index.html new file mode 100644 index 00000000..2f1432b0 --- /dev/null +++ b/docs/html_extra/examples/webusb-serial/index.html @@ -0,0 +1,33 @@ + + + + TinyUSB + + + + + +
+

TinyUSB - WebUSB Serial Example

+
+ + +
+
+
+
Sender
+
+
+ +
+
+
+
Receiver
+
+
+
+
+
+
+ + diff --git a/docs/html_extra/examples/webusb-serial/serial.js b/docs/html_extra/examples/webusb-serial/serial.js new file mode 100644 index 00000000..8e985d89 --- /dev/null +++ b/docs/html_extra/examples/webusb-serial/serial.js @@ -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); + }; +})(); From 188bc0e991df95390d2965febf9a7cf483e6ab21 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Aug 2021 18:00:41 +0700 Subject: [PATCH 3/4] change webusb-serial landing page - to example.tinyusb.org/webusb-serial/ - remove landing page from doc --- docs/conf.py | 3 - .../examples/webusb-serial/application.css | 107 ------------------ .../examples/webusb-serial/application.js | 90 --------------- .../examples/webusb-serial/index.html | 33 ------ .../examples/webusb-serial/serial.js | 89 --------------- examples/device/webusb_serial/src/main.c | 2 +- 6 files changed, 1 insertion(+), 323 deletions(-) delete mode 100644 docs/html_extra/examples/webusb-serial/application.css delete mode 100644 docs/html_extra/examples/webusb-serial/application.js delete mode 100644 docs/html_extra/examples/webusb-serial/index.html delete mode 100644 docs/html_extra/examples/webusb-serial/serial.js diff --git a/docs/conf.py b/docs/conf.py index 1d05d7cb..c7a17478 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -39,7 +39,4 @@ html_theme_options = { 'sidebar_hide_name': True, } -# examples for webusb -html_extra_path = ['html_extra'] - todo_include_todos = True diff --git a/docs/html_extra/examples/webusb-serial/application.css b/docs/html_extra/examples/webusb-serial/application.css deleted file mode 100644 index 4ae0138b..00000000 --- a/docs/html_extra/examples/webusb-serial/application.css +++ /dev/null @@ -1,107 +0,0 @@ -.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; -} diff --git a/docs/html_extra/examples/webusb-serial/application.js b/docs/html_extra/examples/webusb-serial/application.js deleted file mode 100644 index 283121e3..00000000 --- a/docs/html_extra/examples/webusb-serial/application.js +++ /dev/null @@ -1,90 +0,0 @@ -(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))); - }); - }); -})(); diff --git a/docs/html_extra/examples/webusb-serial/index.html b/docs/html_extra/examples/webusb-serial/index.html deleted file mode 100644 index 2f1432b0..00000000 --- a/docs/html_extra/examples/webusb-serial/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - TinyUSB - - - - - -
-

TinyUSB - WebUSB Serial Example

-
- - -
-
-
-
Sender
-
-
- -
-
-
-
Receiver
-
-
-
-
-
-
- - diff --git a/docs/html_extra/examples/webusb-serial/serial.js b/docs/html_extra/examples/webusb-serial/serial.js deleted file mode 100644 index 8e985d89..00000000 --- a/docs/html_extra/examples/webusb-serial/serial.js +++ /dev/null @@ -1,89 +0,0 @@ -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); - }; -})(); diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index c85b3cc9..aba4aedf 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -71,7 +71,7 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -#define URL "www.tinyusb.org/examples/webusb-serial" +#define URL "example.tinyusb.org/webusb-serial/" const tusb_desc_webusb_url_t desc_url = { From 6be2d46b53cba37ad9cbfb1737a446bc76ec7fd4 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 5 Aug 2021 18:32:44 +0700 Subject: [PATCH 4/4] update link to docs.tinyusb.org --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 8a92c267..2119c26d 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function. -Please take a look at the online `documentation `__. +Please take a look at the online `documentation `__. .. figure:: docs/assets/stack.svg :width: 500px @@ -122,7 +122,7 @@ in your project. .. |Build Status| image:: https://github.com/hathach/tinyusb/workflows/Build/badge.svg :target: https://github.com/hathach/tinyusb/actions .. |Documentation Status| image:: https://readthedocs.org/projects/tinyusb/badge/?version=latest - :target: https://tinyusb.readthedocs.io/en/latest/?badge=latest + :target: https://docs.tinyusb.org/en/latest/?badge=latest .. |License| image:: https://img.shields.io/badge/license-MIT-brightgreen.svg :target: https://opensource.org/licenses/MIT