diff --git a/.c9/plugins/beagle.bone101/github-markdown.css b/.c9/plugins/beagle.bone101/github-markdown.css
new file mode 100644
index 0000000..8321bd7
--- /dev/null
+++ b/.c9/plugins/beagle.bone101/github-markdown.css
@@ -0,0 +1,656 @@
+@font-face {
+ font-family: octicons-anchor;
+ src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff');
+}
+
+.markdown-body {
+ -webkit-text-size-adjust: 100%;
+ text-size-adjust: 100%;
+ color: #333;
+ font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
+ font-size: 16px;
+ line-height: 1.6;
+ word-wrap: break-word;
+}
+
+.markdown-body a {
+ background-color: transparent;
+}
+
+.markdown-body a:active,
+.markdown-body a:hover {
+ outline: 0;
+}
+
+.markdown-body strong {
+ font-weight: bold;
+}
+
+.markdown-body h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+.markdown-body img {
+ border: 0;
+}
+
+.markdown-body hr {
+ box-sizing: content-box;
+ height: 0;
+}
+
+.markdown-body pre {
+ overflow: auto;
+}
+
+.markdown-body code,
+.markdown-body kbd,
+.markdown-body pre {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+
+.markdown-body input {
+ color: inherit;
+ font: inherit;
+ margin: 0;
+}
+
+.markdown-body html input[disabled] {
+ cursor: default;
+}
+
+.markdown-body input {
+ line-height: normal;
+}
+
+.markdown-body input[type="checkbox"] {
+ box-sizing: border-box;
+ padding: 0;
+}
+
+.markdown-body table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.markdown-body td,
+.markdown-body th {
+ padding: 0;
+}
+
+.markdown-body * {
+ box-sizing: border-box;
+}
+
+.markdown-body input {
+ font: 13px/1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
+}
+
+.markdown-body a {
+ color: #4078c0;
+ text-decoration: none;
+}
+
+.markdown-body a:hover,
+.markdown-body a:active {
+ text-decoration: underline;
+}
+
+.markdown-body hr {
+ height: 0;
+ margin: 15px 0;
+ overflow: hidden;
+ background: transparent;
+ border: 0;
+ border-bottom: 1px solid #ddd;
+}
+
+.markdown-body hr:before {
+ display: table;
+ content: "";
+}
+
+.markdown-body hr:after {
+ display: table;
+ clear: both;
+ content: "";
+}
+
+.markdown-body h1,
+.markdown-body h2,
+.markdown-body h3,
+.markdown-body h4,
+.markdown-body h5,
+.markdown-body h6 {
+ margin-top: 15px;
+ margin-bottom: 15px;
+ line-height: 1.1;
+}
+
+.markdown-body h1 {
+ font-size: 30px;
+}
+
+.markdown-body h2 {
+ font-size: 21px;
+}
+
+.markdown-body h3 {
+ font-size: 16px;
+}
+
+.markdown-body h4 {
+ font-size: 14px;
+}
+
+.markdown-body h5 {
+ font-size: 12px;
+}
+
+.markdown-body h6 {
+ font-size: 11px;
+}
+
+.markdown-body blockquote {
+ margin: 0;
+}
+
+.markdown-body ul,
+.markdown-body ol {
+ padding: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.markdown-body ol ol,
+.markdown-body ul ol {
+ list-style-type: lower-roman;
+}
+
+.markdown-body ul ul ol,
+.markdown-body ul ol ol,
+.markdown-body ol ul ol,
+.markdown-body ol ol ol {
+ list-style-type: lower-alpha;
+}
+
+.markdown-body dd {
+ margin-left: 0;
+}
+
+.markdown-body code {
+ font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ font-size: 12px;
+}
+
+.markdown-body pre {
+ margin-top: 0;
+ margin-bottom: 0;
+ font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
+}
+
+.markdown-body .select::-ms-expand {
+ opacity: 0;
+}
+
+.markdown-body .octicon {
+ font: normal normal normal 16px/1 octicons-anchor;
+ display: inline-block;
+ text-decoration: none;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.markdown-body .octicon-link:before {
+ content: '\f05c';
+}
+
+.markdown-body>*:first-child {
+ margin-top: 0 !important;
+}
+
+.markdown-body>*:last-child {
+ margin-bottom: 0 !important;
+}
+
+.markdown-body a:not([href]) {
+ color: inherit;
+ text-decoration: none;
+}
+
+.markdown-body .anchor {
+ display: inline-block;
+ padding-right: 2px;
+ margin-left: -18px;
+}
+
+.markdown-body .anchor:focus {
+ outline: none;
+}
+
+.markdown-body h1,
+.markdown-body h2,
+.markdown-body h3,
+.markdown-body h4,
+.markdown-body h5,
+.markdown-body h6 {
+ margin-top: 1em;
+ margin-bottom: 16px;
+ font-weight: bold;
+ line-height: 1.4;
+}
+
+.markdown-body h1 .octicon-link,
+.markdown-body h2 .octicon-link,
+.markdown-body h3 .octicon-link,
+.markdown-body h4 .octicon-link,
+.markdown-body h5 .octicon-link,
+.markdown-body h6 .octicon-link {
+ color: #000;
+ vertical-align: middle;
+ visibility: hidden;
+}
+
+.markdown-body h1:hover .anchor,
+.markdown-body h2:hover .anchor,
+.markdown-body h3:hover .anchor,
+.markdown-body h4:hover .anchor,
+.markdown-body h5:hover .anchor,
+.markdown-body h6:hover .anchor {
+ text-decoration: none;
+}
+
+.markdown-body h1:hover .anchor .octicon-link,
+.markdown-body h2:hover .anchor .octicon-link,
+.markdown-body h3:hover .anchor .octicon-link,
+.markdown-body h4:hover .anchor .octicon-link,
+.markdown-body h5:hover .anchor .octicon-link,
+.markdown-body h6:hover .anchor .octicon-link {
+ visibility: visible;
+}
+
+.markdown-body h1 {
+ padding-bottom: 0.3em;
+ font-size: 2.25em;
+ line-height: 1.2;
+ border-bottom: 1px solid #eee;
+}
+
+.markdown-body h1 .anchor {
+ line-height: 1;
+}
+
+.markdown-body h2 {
+ padding-bottom: 0.3em;
+ font-size: 1.75em;
+ line-height: 1.225;
+ border-bottom: 1px solid #eee;
+}
+
+.markdown-body h2 .anchor {
+ line-height: 1;
+}
+
+.markdown-body h3 {
+ font-size: 1.5em;
+ line-height: 1.43;
+}
+
+.markdown-body h3 .anchor {
+ line-height: 1.2;
+}
+
+.markdown-body h4 {
+ font-size: 1.25em;
+}
+
+.markdown-body h4 .anchor {
+ line-height: 1.2;
+}
+
+.markdown-body h5 {
+ font-size: 1em;
+}
+
+.markdown-body h5 .anchor {
+ line-height: 1.1;
+}
+
+.markdown-body h6 {
+ font-size: 1em;
+ color: #777;
+}
+
+.markdown-body h6 .anchor {
+ line-height: 1.1;
+}
+
+.markdown-body p,
+.markdown-body blockquote,
+.markdown-body ul,
+.markdown-body ol,
+.markdown-body dl,
+.markdown-body table,
+.markdown-body pre {
+ margin-top: 0;
+ margin-bottom: 16px;
+}
+
+.markdown-body hr {
+ height: 4px;
+ padding: 0;
+ margin: 16px 0;
+ background-color: #e7e7e7;
+ border: 0 none;
+}
+
+.markdown-body ul,
+.markdown-body ol {
+ padding-left: 2em;
+}
+
+.markdown-body ul ul,
+.markdown-body ul ol,
+.markdown-body ol ol,
+.markdown-body ol ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.markdown-body li>p {
+ margin-top: 16px;
+}
+
+.markdown-body dl {
+ padding: 0;
+}
+
+.markdown-body dl dt {
+ padding: 0;
+ margin-top: 16px;
+ font-size: 1em;
+ font-style: italic;
+ font-weight: bold;
+}
+
+.markdown-body dl dd {
+ padding: 0 16px;
+ margin-bottom: 16px;
+}
+
+.markdown-body blockquote {
+ padding: 0 15px;
+ color: #777;
+ border-left: 4px solid #ddd;
+}
+
+.markdown-body blockquote>:first-child {
+ margin-top: 0;
+}
+
+.markdown-body blockquote>:last-child {
+ margin-bottom: 0;
+}
+
+.markdown-body table {
+ display: block;
+ width: 100%;
+ overflow: auto;
+ word-break: normal;
+ word-break: keep-all;
+}
+
+.markdown-body table th {
+ font-weight: bold;
+}
+
+.markdown-body table th,
+.markdown-body table td {
+ padding: 6px 13px;
+ border: 1px solid #ddd;
+}
+
+.markdown-body table tr {
+ background-color: #fff;
+ border-top: 1px solid #ccc;
+}
+
+.markdown-body table tr:nth-child(2n) {
+ background-color: #f8f8f8;
+}
+
+.markdown-body img {
+ max-width: 100%;
+ box-sizing: content-box;
+ background-color: #e7e7e7;
+}
+
+.markdown-body code {
+ padding: 0;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+ margin: 0;
+ font-size: 85%;
+ background-color: rgba(0,0,0,0.04);
+ border-radius: 3px;
+}
+
+.markdown-body code:before,
+.markdown-body code:after {
+ letter-spacing: -0.2em;
+ content: "\00a0";
+}
+
+.markdown-body pre>code {
+ padding: 0;
+ margin: 0;
+ font-size: 100%;
+ word-break: normal;
+ white-space: pre;
+ background: transparent;
+ border: 0;
+}
+
+.markdown-body .highlight {
+ margin-bottom: 16px;
+}
+
+.markdown-body .highlight pre,
+.markdown-body pre {
+ padding: 16px;
+ overflow: auto;
+ font-size: 85%;
+ line-height: 1.45;
+ background-color: #f7f7f7;
+ border-radius: 3px;
+}
+
+.markdown-body .highlight pre {
+ margin-bottom: 0;
+ word-break: normal;
+}
+
+.markdown-body pre {
+ word-wrap: normal;
+}
+
+.markdown-body pre code {
+ display: inline;
+ max-width: initial;
+ padding: 0;
+ margin: 0;
+ overflow: initial;
+ line-height: inherit;
+ word-wrap: normal;
+ background-color: transparent;
+ border: 0;
+}
+
+.markdown-body pre code:before,
+.markdown-body pre code:after {
+ content: normal;
+}
+
+.markdown-body kbd {
+ display: inline-block;
+ padding: 3px 5px;
+ font-size: 11px;
+ line-height: 10px;
+ color: #555;
+ vertical-align: middle;
+ background-color: #fcfcfc;
+ border: solid 1px #ccc;
+ border-bottom-color: #bbb;
+ border-radius: 3px;
+ box-shadow: inset 0 -1px 0 #bbb;
+}
+
+.markdown-body .pl-c {
+ color: #969896;
+}
+
+.markdown-body .pl-c1,
+.markdown-body .pl-s .pl-v {
+ color: #0086b3;
+}
+
+.markdown-body .pl-e,
+.markdown-body .pl-en {
+ color: #795da3;
+}
+
+.markdown-body .pl-s .pl-s1,
+.markdown-body .pl-smi {
+ color: #333;
+}
+
+.markdown-body .pl-ent {
+ color: #63a35c;
+}
+
+.markdown-body .pl-k {
+ color: #a71d5d;
+}
+
+.markdown-body .pl-pds,
+.markdown-body .pl-s,
+.markdown-body .pl-s .pl-pse .pl-s1,
+.markdown-body .pl-sr,
+.markdown-body .pl-sr .pl-cce,
+.markdown-body .pl-sr .pl-sra,
+.markdown-body .pl-sr .pl-sre {
+ color: #183691;
+}
+
+.markdown-body .pl-v {
+ color: #ed6a43;
+}
+
+.markdown-body .pl-id {
+ color: #b52a1d;
+}
+
+.markdown-body .pl-ii {
+ background-color: #b52a1d;
+ color: #f8f8f8;
+}
+
+.markdown-body .pl-sr .pl-cce {
+ color: #63a35c;
+ font-weight: bold;
+}
+
+.markdown-body .pl-ml {
+ color: #693a17;
+}
+
+.markdown-body .pl-mh,
+.markdown-body .pl-mh .pl-en,
+.markdown-body .pl-ms {
+ color: #1d3e81;
+ font-weight: bold;
+}
+
+.markdown-body .pl-mq {
+ color: #008080;
+}
+
+.markdown-body .pl-mi {
+ color: #333;
+ font-style: italic;
+}
+
+.markdown-body .pl-mb {
+ color: #333;
+ font-weight: bold;
+}
+
+.markdown-body .pl-md {
+ background-color: #ffecec;
+ color: #bd2c00;
+}
+
+.markdown-body .pl-mi1 {
+ background-color: #eaffea;
+ color: #55a532;
+}
+
+.markdown-body .pl-mdr {
+ color: #795da3;
+ font-weight: bold;
+}
+
+.markdown-body .pl-mo {
+ color: #1d3e81;
+}
+
+.markdown-body kbd {
+ display: inline-block;
+ padding: 3px 5px;
+ font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ line-height: 10px;
+ color: #555;
+ vertical-align: middle;
+ background-color: #fcfcfc;
+ border: solid 1px #ccc;
+ border-bottom-color: #bbb;
+ border-radius: 3px;
+ box-shadow: inset 0 -1px 0 #bbb;
+}
+
+.markdown-body:before {
+ display: table;
+ content: "";
+}
+
+.markdown-body:after {
+ display: table;
+ clear: both;
+ content: "";
+}
+
+.markdown-body .task-list-item {
+ list-style-type: none;
+}
+
+.markdown-body .task-list-item+.task-list-item {
+ margin-top: 3px;
+}
+
+.markdown-body .task-list-item input {
+ margin: 0 0.35em 0.25em -1.6em;
+ vertical-align: middle;
+}
+
+.markdown-body :checked+.radio-label {
+ z-index: 1;
+ position: relative;
+ border-color: #4078c0;
+}
\ No newline at end of file
diff --git a/.c9/plugins/beagle.bone101/markdown.html b/.c9/plugins/beagle.bone101/markdown.html
new file mode 100644
index 0000000..c60bcf4
--- /dev/null
+++ b/.c9/plugins/beagle.bone101/markdown.html
@@ -0,0 +1,2547 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.c9/plugins/beagle.bone101/plugin.js b/.c9/plugins/beagle.bone101/plugin.js
index 69ab3ba..a90d172 100644
--- a/.c9/plugins/beagle.bone101/plugin.js
+++ b/.c9/plugins/beagle.bone101/plugin.js
@@ -1,137 +1,446 @@
define(function(require, exports, module) {
main.consumes = [
- "Plugin", "ui", "commands", "menus", "tabManager",
- "Previewer", "Editor", "editors", "layout", "settings"
+ "c9", "Previewer", "fs", "dialog.error", "commands", "tabManager",
+ "layout", "settings", "vfs",
+ "menus", "ui"
];
- main.provides = ["beagle.bone101"];
+ main.provides = ["preview.markdown"];
return main;
function main(options, imports, register) {
- var Plugin = imports.Plugin;
- var ui = imports.ui;
+ var c9 = imports.c9;
+ var Previewer = imports.Previewer;
+ var fs = imports.fs;
+ var showError = imports["dialog.error"].show;
var commands = imports.commands;
- var menus = imports.menus;
var tabManager = imports.tabManager;
- var Previewer = imports.Previewer;
- var Editor = imports.Editor;
- var editors = imports.editors;
var layout = imports.layout;
var settings = imports.settings;
- var path = require("path");
+ var vfs = imports.vfs;
+ var menus = imports.menus;
+ var ui = imports.ui;
- var basename = path.basename;
- var extensions = ["bone101"];
- var handle = editors.register("bone101", "Bone101", Bone101Editor, extensions);
- console.log("editors: " + JSON.stringify(editors));
- var BGCOLOR = {
- "flat-light": "#F1F1F1",
- "light": "#D3D3D3",
- "light-gray": "#D3D3D3",
- "dark": "#3D3D3D",
- "dark-gray": "#3D3D3D"
+ var highlighter = require("ace/ext/static_highlight");
+ var modelist = require("ace/ext/modelist");
+
+ /***** Initialization *****/
+
+ var plugin = new Previewer("Ajax.org", main.consumes, {
+ caption: "Beagle Markdown",
+ index: 100,
+ selector: function(path) {
+ return path && path.match(/(?:\.md|\.markdown)$/i);
+ }
+ });
+ var emit = plugin.getEmitter();
+
+ var BGCOLOR = {
+ "flat-light": "rgb(255,255,255)",
+ "flat-dark": "rgba(255, 255, 255, 0.88)",
+ "light": "rgba(255, 255, 255, 0.88)",
+ "light-gray": "rgba(255, 255, 255, 0.88)",
+ "dark": "rgba(255, 255, 255, 0.88)",
+ "dark-gray": "rgba(255, 255, 255, 0.88)"
};
- function Bone101Editor(){
- console.log("bone101: build editor");
- var plugin = new Editor("BeagleBoard.org", main.consumes, extensions);
+ var counter = 0;
+ var HTMLURL, previewOrigin;
- var container, contents;
- var currentSession, currentDocument;
-
- plugin.on("draw", function(e) {
- console.log("bone101: draw");
- container = e.htmlNode;
- var tab = e.tab;
- tab.title = "bone101";
- tab.tooltip = "bone101";
+ /***** Methods *****/
+
+ function getPreviewUrl(fn) {
+ /*global location*/
+ if (options.local && document.baseURI.substr(0, 5) == "file:")
+ return setTimeout(getPreviewUrl.bind(null, fn), 100);
+ else if (HTMLURL)
+ return fn(HTMLURL);
+
+ HTMLURL = vfs.serviceUrl
+ + "/workspace/.c9/plugins/beagle.bone101/markdown.html"
+ + "?host=" + (options.local ? "local" : location.origin);
+
+ if (HTMLURL.charAt(0) == "/")
+ HTMLURL = location.protocol + "//" + location.host + HTMLURL;
+
+ previewOrigin = HTMLURL.match(/^(?:[^\/]|\/\/)*/)[0];
+
+ fn(HTMLURL);
+ }
+
+ function enableScroll(session) {
+ if (!session.previewTab || !session.previewTab.loaded)
+ return;
+ if (session.scrollHook && session.scrollHook == session.previewTab)
+ return;
+
+ var aceSession = session.previewTab.document.getSession().session;
+ if (!aceSession) return;
+
+ var listen = function(scrollTopPx) {
+ if (!session.source) return; // Renderer is not loaded yet
- var iframe = document.createElement("iframe");
- iframe.style.width = "100%";
- iframe.style.height = "100%";
- iframe.style.border = 0;
- iframe.src = "http://192.168.7.2:8000/";
- try {
- iframe.src = "http://" + location.host + ":8000/";
- } catch(ex) {
- console.log("bone101: location.host not defined");
- }
- console.log("bone101 src: " + iframe.src);
- container.appendChild(iframe);
- });
- plugin.on("documentLoad", function(e){
- console.log("bone101: documentLoad");
- currentDocument = e.doc;
- currentSession = currentDocument.getSession();
- currentDocument.tab.on("setPath", setTitle, currentSession);
- function setTitle(e) {
- currentDocument.title = "bone101";
- currentDocument.tooltip = "bone101";
- }
- setTitle();
- });
- plugin.on("documentActivate", function(e){
- console.log("bone101: documentActivate");
- });
- plugin.on("documentUnload", function(e){
- console.log("bone101: documentUnload");
+ var visibleRow = aceSession.c9doc.editor.ace.renderer.getFirstFullyVisibleRow();
+ setTimeout(function() {
+ session.source.postMessage({
+ type: "scroll",
+ lineNumber: visibleRow
+ }, "*");
+ });
+ };
+
+ aceSession.on("changeScrollTop", listen);
+ session.previewTab.on("unload", function() {
+ aceSession.removeListener("changeScrollTop", listen);
});
- plugin.freezePublicAPI({
- bone101: bone101
- });
- plugin.load(null, "beagle.bone101");
- return plugin;
+
+ session.scrollHook = session.previewTab;
+ }
+
+ function bone101(page) {
+ switch(page) {
+ case "about":
+ tabManager.preview({
+ "path": "/About.md",
+ "editorType": "preview",
+ "active": true,
+ "focus": true
+ }, function(err, tab) {
+ if (err) return console.error(err);
+ });
+ break;
+ case "intro":
+ tabManager.preview({
+ "path": "/Introduction.md",
+ "editorType": "preview",
+ "active": true,
+ "focus": true
+ }, function(err, tab) {
+ if (err) return console.error(err);
+ });
+ break;
+ case "examples":
+ tabManager.preview({
+ "path": "/README.md",
+ "editorType": "preview",
+ "active": true,
+ "focus": true
+ }, function(err, tab) {
+ if (err) return console.error(err);
+ });
+ break;
+ case "node-red":
+ tabManager.preview({
+ "path": "/extras/node-red.html",
+ "editorType": "preview",
+ "active": true,
+ "focus": true
+ }, function(err, tab) {
+ if (err) return console.error(err);
+ });
+ break;
+ case "mjpg-stream":
+ tabManager.preview({
+ "path": "/extras/mjpg-stream.html",
+ "editorType": "preview",
+ "active": true,
+ "focus": true
+ }, function(err, tab) {
+ if (err) return console.error(err);
+ });
+ break;
+ default:
+ }
}
- handle.on("load", function(){
+ /***** Lifecycle *****/
+
+ plugin.on("load", function() {
console.log("bone101: load");
- //commands.addCommand({
- // name: "bone101_about",
- // isAvailable: function(){ return true; },
- // exec: function() {
- // bone101("about");
- // }
- //}, handle);
+ commands.addCommand({
+ name: "bone101_about",
+ isAvailable: function(){ return true; },
+ exec: function() {
+ bone101("about");
+ }
+ }, plugin);
commands.addCommand({
name: "bone101_intro",
isAvailable: function(){ return true; },
exec: function() {
bone101("intro");
}
- }, handle);
+ }, plugin);
+ commands.addCommand({
+ name: "bone101_examples",
+ isAvailable: function(){ return true; },
+ exec: function() {
+ bone101("examples");
+ }
+ }, plugin);
+ commands.addCommand({
+ name: "bone101_node-red",
+ isAvailable: function(){ return true; },
+ exec: function() {
+ bone101("node-red");
+ }
+ }, plugin);
+ commands.addCommand({
+ name: "bone101_mjpg-stream",
+ isAvailable: function(){ return true; },
+ exec: function() {
+ bone101("mjpg-stream");
+ }
+ }, plugin);
- menus.addItemByPath("BeagleBone", null, 20, handle);
- //menus.addItemByPath("BeagleBone/About",new ui.item({
- // command: "bone101_about"
- //}), 22, handle);
+ menus.addItemByPath("BeagleBone", null, 20, plugin);
+ menus.addItemByPath("BeagleBone/About",new ui.item({
+ command: "bone101_about"
+ }), 22, plugin);
menus.addItemByPath("BeagleBone/Introduction", new ui.item({
command: "bone101_intro"
- }), 24, handle);
+ }), 24, plugin);
+ menus.addItemByPath("BeagleBone/Examples", new ui.item({
+ command: "bone101_examples"
+ }), 26, plugin);
+ menus.addItemByPath("BeagleBone/Node-RED", new ui.item({
+ command: "bone101_node-red"
+ }), 28, plugin);
+ menus.addItemByPath("BeagleBone/MJPG-Streamer", new ui.item({
+ command: "bone101_mjpg-stream"
+ }), 30, plugin);
});
+ plugin.on("sessionStart", function(e) {
+ var doc = e.doc;
+ var session = e.session;
+ var tab = e.tab;
+ var editor = e.editor;
+
+ if (session.iframe) {
+ session.editor = editor;
+ editor.container.appendChild(session.iframe);
+ return;
+ }
+
+ var iframe = document.createElement("iframe");
+
+ iframe.setAttribute("nwfaketop", true);
+ iframe.setAttribute("nwdisable", true);
- tabManager.on("ready", function(){
- bone101("intro");
+ iframe.style.width = "100%";
+ iframe.style.height = "100%";
+ iframe.style.border = 0;
+
+ function setTheme(e) {
+ iframe.style.backgroundColor = BGCOLOR[e.theme];
+ }
+ layout.on("themeChange", setTheme, doc);
+ setTheme({ theme: settings.get("user/general/@skin") });
+
+ if (options.local) {
+ iframe.addEventListener("load", function() {
+ // @todo to do this correctly stack needs to allow switching previewer
+ // plugin.activeSession.add(iframe.contentWindow.location.href);
+
+ iframe.contentWindow.opener = window;
+ if (iframe.contentWindow.start)
+ iframe.contentWindow.start(window);
+ });
+ }
+
+ var onMessage = function(e) {
+ if (c9.hosted && e.origin !== previewOrigin)
+ return;
+
+ if (e.data.id != session.id)
+ return;
+
+ if (e.data.message == "exec") {
+ commands.exec(e.data.command);
+ }
+ else if (e.data.message == "focus") {
+ tabManager.focusTab(tab);
+ }
+ else if (e.data.message == "highlight") {
+ var mode = (modelist.modesByName[e.data.lang]
+ || modelist.getModeForPath("file." + e.data.lang)
+ || 0).mode || "ace/mode/" + e.data.lang;
+ var theme = "ace/theme/cloud9_day";
+ var value = e.data.content.replace(/[\n\r]*$/, "");
+
+ highlighter.render(value, mode, theme, 0, true, function (highlighted) {
+ session.source.postMessage({
+ type: "highlight",
+ hid: e.data.hid,
+ html: highlighted.html,
+ css: highlighted.css
+ }, "*");
+ });
+ }
+ else if (e.data.message == "stream.document") {
+ session.source = e.source;
+
+ if (session.previewTab) {
+ var doc = session.previewTab.document;
+
+ if (!doc.hasValue())
+ doc.once("setValue", function() {
+ emit("update", { previewDocument: doc });
+ });
+ else
+ emit("update", { previewDocument: doc });
+ }
+ else {
+ //showError("Testing: " + session.path);
+ fs.stat(session.path, function (err, data) {
+ if (err)
+ return showError(err.message);
+
+ if(data.mime == "inode/directory") {
+ fs.readFile(session.path+"/README.md", function(err, data) {
+ if (err)
+ return showError(err.message);
+
+ session.source.postMessage({
+ type: "document",
+ content: data
+ }, "*");
+ });
+ } else {
+ fs.readFile(session.path, function(err, data) {
+ if (err)
+ return showError(err.message);
+
+ session.source.postMessage({
+ type: "document",
+ content: data
+ }, "*");
+ });
+ }
+ });
+ }
+
+ session.source.postMessage({
+ type: "keys",
+ keys: commands.getExceptionBindings()
+ }, "*");
+
+ tab.classList.remove("loading");
+ }
+ };
+ window.addEventListener("message", onMessage, false);
+
+ // Set iframe
+ session.iframe = iframe;
+ session.id = "markdown" + counter++;
+
+ session.destroy = function() {
+ delete session.editor;
+ delete session.iframe;
+
+ window.removeEventListener("message", onMessage, false);
+ };
+
+ // Load the markup renderer
+ getPreviewUrl(function(url) {
+ iframe.src = url + "&id=" + session.id;
+ });
+
+ session.editor = editor;
+ editor.container.appendChild(session.iframe);
+ });
+ plugin.on("sessionEnd", function(e) {
+ var tab = e.tab;
+ var session = e.session;
+ var iframe = session.iframe;
+
+ iframe.parentNode.removeChild(iframe);
+
+ tab.classList.remove("loading");
+ });
+ plugin.on("sessionActivate", function(e) {
+ var session = e.session;
+
+ session.iframe.style.display = "block";
+ session.editor.setLocation(session.path);
+ session.editor.setButtonStyle("Markdown", "page_white.png");
});
+ plugin.on("sessionDeactivate", function(e) {
+ var session = e.session;
+ session.iframe.style.display = "none";
+ });
+ plugin.on("navigate", function(e) {
+ var tab = plugin.activeDocument.tab;
+ var iframe = plugin.activeSession.iframe;
+ var editor = plugin.activeSession.editor;
+ var session = e.session;
+
+ tab.classList.add("loading");
+
+ tab.title =
+ tab.tooltip = "[M] " + e.url;
+ editor.setLocation(e.url);
+
+ iframe.src = iframe.src;
+
+ enableScroll(session);
+ });
+ plugin.on("update", function(e) {
+ var session = plugin.activeSession;
+ if (!session.source) return; // Renderer is not loaded yet
+
+ session.source.postMessage({
+ type: "document",
+ content: e.previewDocument.value,
+ fontSize: settings.get("user/ace/fontSize"),
+ fontFamily: settings.get("user/ace/fontFamily")
+ }, "*");
+
+ enableScroll(session);
- function bone101(page) {
- //var filename = options.packagePath + ".bone101";
- var filename = "/var/lib/cloud9/.c9/plugins/beagle.bone101/plugin.bone101";
- console.log("opening " + filename);
- //var pane = tabManager.getPanes()[0];
- //var newPane = pane.hsplit();
- var tab = tabManager.open({
- "path": filename,
- //"pane": newPane,
- "editorType": "bone101",
- "title": "bone101",
- "tooltip": "bone101",
- "focus": true
- }, function(err, tab){
- if (err) return console.error(err);
- });
- }
+if(0) { // not working right now, but also don't know that it is needed
+ setTimeout(function() {
+ if (!session.previewTab || !session.previewTab.loaded)
+ return;
+
+ var doc = session.previewTab.document;
+ doc.getSession().session._emit("changeScrollTop");
+ }, 100);
+}
+ });
+ plugin.on("reload", function() {
+ var iframe = plugin.activeSession.iframe;
+ var tab = plugin.activeDocument.tab;
+ tab.classList.add("loading");
+ iframe.src = iframe.src;
+ });
+ plugin.on("popout", function() {
+ var src = plugin.activeSession.iframe.src;
+ window.open(src);
+ });
+ plugin.on("enable", function() {
+ console.log("beagle.bone101: enabled");
+ });
+ plugin.on("disable", function() {
+ console.log("beagle.bone101: disabled")
+ });
+ plugin.on("unload", function() {
+ });
+
+ /***** Register and define API *****/
+
+ /**
+ * Previewer for markdown content.
+ **/
+ plugin.freezePublicAPI({
+ });
+
+ // Cannot quite figure out what event to do this on
+ setTimeout(function() {
+ bone101("intro");
+ }, 500);
register(null, {
- "beagle.bone101": handle
+ "preview.markdown": plugin
});
}
});
diff --git a/.c9/plugins/beagle.bone101/remarkable.min.js b/.c9/plugins/beagle.bone101/remarkable.min.js
new file mode 100644
index 0000000..60a15a2
--- /dev/null
+++ b/.c9/plugins/beagle.bone101/remarkable.min.js
@@ -0,0 +1,4 @@
+/*! remarkable 1.5.0 https://github.com//jonschlinkert/remarkable @license MIT */
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.Remarkable=e()}}(function(){var e;return function t(e,r,n){function s(i,l){if(!r[i]){if(!e[i]){var a="function"==typeof require&&require;if(!l&&a)return a(i,!0);if(o)return o(i,!0);var c=new Error("Cannot find module '"+i+"'");throw c.code="MODULE_NOT_FOUND",c}var u=r[i]={exports:{}};e[i][0].call(u.exports,function(t){var r=e[i][1][t];return s(r?r:t)},u,u.exports,t,e,r,n)}return r[i].exports}for(var o="function"==typeof require&&require,i=0;i",Gt:"≫",gt:">",gtcc:"⪧",gtcir:"⩺",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",hArr:"⇔",harr:"↔",harrcir:"⥈",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",Hfr:"ℌ",hfr:"𝔥",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",Hopf:"ℍ",hopf:"𝕙",horbar:"―",HorizontalLine:"─",Hscr:"ℋ",hscr:"𝒽",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",Ifr:"ℑ",ifr:"𝔦",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Im:"ℑ",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",imof:"⊷",imped:"Ƶ",Implies:"⇒","in":"∈",incare:"℅",infin:"∞",infintie:"⧝",inodot:"ı",Int:"∬","int":"∫",intcal:"⊺",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"",InvisibleTimes:"",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",Iscr:"ℐ",iscr:"𝒾",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",Lang:"⟪",lang:"⟨",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",Larr:"↞",lArr:"⇐",larr:"←",larrb:"⇤",larrbfs:"⤟",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",lat:"⪫",lAtail:"⤛",latail:"⤙",late:"⪭",lates:"⪭︀",lBarr:"⤎",lbarr:"⤌",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",lE:"≦",le:"≤",LeftAngleBracket:"⟨",LeftArrow:"←",Leftarrow:"⇐",leftarrow:"←",LeftArrowBar:"⇤",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVector:"⇃",LeftDownVectorBar:"⥙",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrow:"↔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTee:"⊣",LeftTeeArrow:"↤",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangle:"⊲",LeftTriangleBar:"⧏",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVector:"↿",LeftUpVectorBar:"⥘",LeftVector:"↼",LeftVectorBar:"⥒",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",les:"⩽",lescc:"⪨",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",Ll:"⋘",ll:"≪",llarr:"⇇",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoust:"⎰",lmoustache:"⎰",lnap:"⪉",lnapprox:"⪉",lnE:"≨",lne:"⪇",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftarrow:"⟵",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longleftrightarrow:"⟷",longmapsto:"⟼",LongRightArrow:"⟶",Longrightarrow:"⟹",longrightarrow:"⟶",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"",lrtri:"⊿",lsaquo:"‹",Lscr:"ℒ",lscr:"𝓁",Lsh:"↰",lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",LT:"<",Lt:"≪",lt:"<",ltcc:"⪦",ltcir:"⩹",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",mid:"∣",midast:"*",midcir:"⫰",middot:"·",minus:"−",minusb:"⊟",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",Mscr:"ℳ",mscr:"𝓂",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natur:"♮",natural:"♮",naturals:"ℕ",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",ne:"≠",nearhk:"⤤",neArr:"⇗",nearr:"↗",nearrow:"↗",nedot:"≐̸",NegativeMediumSpace:"",NegativeThickSpace:"",NegativeThinSpace:"",NegativeVeryThinSpace:"",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nhArr:"⇎",nharr:"↮",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlArr:"⇍",nlarr:"↚",nldr:"‥",nlE:"≦̸",nle:"≰",nLeftarrow:"⇍",nleftarrow:"↚",nLeftrightarrow:"⇎",nleftrightarrow:"↮",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"",NonBreakingSpace:" ",Nopf:"ℕ",nopf:"𝕟",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangle:"⋪",NotLeftTriangleBar:"⧏̸",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangle:"⋫",NotRightTriangleBar:"⧐̸",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",npar:"∦",nparallel:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",npre:"⪯̸",nprec:"⊀",npreceq:"⪯̸",nrArr:"⇏",nrarr:"↛",nrarrc:"⤳̸",nrarrw:"↝̸",nRightarrow:"⇏",nrightarrow:"↛",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nVDash:"⊯",nVdash:"⊮",nvDash:"⊭",nvdash:"⊬",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwArr:"⇖",nwarr:"↖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",ocir:"⊚",Ocirc:"Ô",ocirc:"ô",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",Or:"⩔",or:"∨",orarr:"↻",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",Otimes:"⨷",otimes:"⊗",otimesas:"⨶",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",par:"∥",para:"¶",parallel:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plus:"+",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",Popf:"ℙ",popf:"𝕡",pound:"£",Pr:"⪻",pr:"≺",prap:"⪷",prcue:"≼",prE:"⪳",pre:"⪯",prec:"≺",precapprox:"⪷",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",precsim:"≾",Prime:"″",prime:"′",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportion:"∷",Proportional:"∝",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",Qopf:"ℚ",qopf:"𝕢",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",QUOT:'"',quot:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",Rang:"⟫",rang:"⟩",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",Rarr:"↠",rArr:"⇒",rarr:"→",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",rAtail:"⤜",ratail:"⤚",ratio:"∶",rationals:"ℚ",RBarr:"⤐",rBarr:"⤏",rbarr:"⤍",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",Re:"ℜ",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",rect:"▭",REG:"®",reg:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",Rfr:"ℜ",rfr:"𝔯",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrow:"→",Rightarrow:"⇒",rightarrow:"→",RightArrowBar:"⇥",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVector:"⇂",RightDownVectorBar:"⥕",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTee:"⊢",RightTeeArrow:"↦",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangle:"⊳",RightTriangleBar:"⧐",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVector:"↾",RightUpVectorBar:"⥔",RightVector:"⇀",RightVectorBar:"⥓",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"",rmoust:"⎱",rmoustache:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",Ropf:"ℝ",ropf:"𝕣",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",Rscr:"ℛ",rscr:"𝓇",Rsh:"↱",rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",Sc:"⪼",sc:"≻",scap:"⪸",Scaron:"Š",scaron:"š",sccue:"≽",scE:"⪴",sce:"⪰",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdot:"⋅",sdotb:"⊡",sdote:"⩦",searhk:"⤥",seArr:"⇘",searr:"↘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",sol:"/",solb:"⧄",solbar:"⌿",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",squ:"□",Square:"□",square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",Sub:"⋐",sub:"⊂",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",Subset:"⋐",subset:"⊂",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succ:"≻",succapprox:"⪸",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",Sum:"∑",sum:"∑",sung:"♪",Sup:"⋑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",Supset:"⋑",supset:"⊃",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swArr:"⇙",swarr:"↙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:" ",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",Therefore:"∴",therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:" ",thinsp:" ",ThinSpace:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",Tilde:"∼",tilde:"˜",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",times:"×",timesb:"⊠",timesbar:"⨱",timesd:"⨰",tint:"∭",toea:"⤨",top:"⊤",topbot:"⌶",topcir:"⫱",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",TRADE:"™",trade:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",Uarr:"↟",uArr:"⇑",uarr:"↑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrow:"↑",Uparrow:"⇑",uparrow:"↑",UpArrowBar:"⤒",UpArrowDownArrow:"⇅",UpDownArrow:"↕",Updownarrow:"⇕",updownarrow:"↕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",Upsi:"ϒ",upsi:"υ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTee:"⊥",UpTeeArrow:"↥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",vArr:"⇕",varr:"↕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",Vbar:"⫫",vBar:"⫨",vBarv:"⫩",Vcy:"В",vcy:"в",VDash:"⊫",Vdash:"⊩",vDash:"⊨",vdash:"⊢",Vdashl:"⫦",Vee:"⋁",vee:"∨",veebar:"⊻",veeeq:"≚",vellip:"⋮",Verbar:"‖",verbar:"|",Vert:"‖",vert:"|",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",Wedge:"⋀",wedge:"∧",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xhArr:"⟺",xharr:"⟷",Xi:"Ξ",xi:"ξ",xlArr:"⟸",xlarr:"⟵",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrArr:"⟹",xrarr:"⟶",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",Yuml:"Ÿ",yuml:"ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"",Zeta:"Ζ",zeta:"ζ",Zfr:"ℨ",zfr:"𝔷",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",Zopf:"ℤ",zopf:"𝕫",Zscr:"𝒵",zscr:"𝓏",zwj:"",zwnj:""}},{}],2:[function(e,t){"use strict";var r={};["article","aside","button","blockquote","body","canvas","caption","col","colgroup","dd","div","dl","dt","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","iframe","li","map","object","ol","output","p","pre","progress","script","section","style","table","tbody","td","textarea","tfoot","th","tr","thead","ul","video"].forEach(function(e){r[e]=!0}),t.exports=r},{}],3:[function(e,t){"use strict";function r(e,t){return e=e.source,t=t||"",function r(n,s){return n?(s=s.source||s,e=e.replace(n,s),r):new RegExp(e,t)}}var n=/[a-zA-Z_:][a-zA-Z0-9:._-]*/,s=/[^"'=<>`\x00-\x20]+/,o=/'[^']*'/,i=/"[^"]*"/,l=r(/(?:unquoted|single_quoted|double_quoted)/)("unquoted",s)("single_quoted",o)("double_quoted",i)(),a=r(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/)("attr_name",n)("attr_value",l)(),c=r(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/)("attribute",a)(),u=/<\/[A-Za-z][A-Za-z0-9]*\s*>/,p=//,h=/<[?].*?[?]>/,f=/]*>/,d=/])*\]\]>/,g=r(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)("open_tag",c)("close_tag",u)("comment",p)("processing",h)("declaration",f)("cdata",d)();t.exports.HTML_TAG_RE=g},{}],4:[function(e,t){"use strict";t.exports=["coap","doi","javascript","aaa","aaas","about","acap","cap","cid","crid","data","dav","dict","dns","file","ftp","geo","go","gopher","h323","http","https","iax","icap","im","imap","info","ipp","iris","iris.beep","iris.xpc","iris.xpcs","iris.lwz","ldap","mailto","mid","msrp","msrps","mtqp","mupdate","news","nfs","ni","nih","nntp","opaquelocktoken","pop","pres","rtsp","service","session","shttp","sieve","sip","sips","sms","snmp","soap.beep","soap.beeps","tag","tel","telnet","tftp","thismessage","tn3270","tip","tv","urn","vemmi","ws","wss","xcon","xcon-userid","xmlrpc.beep","xmlrpc.beeps","xmpp","z39.50r","z39.50s","adiumxtra","afp","afs","aim","apt","attachment","aw","beshare","bitcoin","bolo","callto","chrome","chrome-extension","com-eventbrite-attendee","content","cvs","dlna-playsingle","dlna-playcontainer","dtn","dvb","ed2k","facetime","feed","finger","fish","gg","git","gizmoproject","gtalk","hcp","icon","ipn","irc","irc6","ircs","itms","jar","jms","keyparc","lastfm","ldaps","magnet","maps","market","message","mms","ms-help","msnim","mumble","mvn","notes","oid","palm","paparazzi","platform","proxy","psyc","query","res","resource","rmi","rsync","rtmp","secondlife","sftp","sgn","skype","smb","soldat","spotify","ssh","steam","svn","teamspeak","things","udp","unreal","ut2004","ventrilo","view-source","webcal","wtai","wyciwyg","xfire","xri","ymsgr"]},{}],5:[function(e,t,r){"use strict";function n(e){return Object.prototype.toString.call(e)}function s(e){return"[object String]"===n(e)}function o(e,t){return e?d.call(e,t):!1}function i(e){var t=Array.prototype.slice.call(arguments,1);return t.forEach(function(t){if(t){if("object"!=typeof t)throw new TypeError(t+"must be object");Object.keys(t).forEach(function(r){e[r]=t[r]})}}),e}function l(e){return e.indexOf("\\")<0?e:e.replace(g,"$1")}function a(e){return e>=55296&&57343>=e?!1:e>=64976&&65007>=e?!1:65535===(65535&e)||65534===(65535&e)?!1:e>=0&&8>=e?!1:11===e?!1:e>=14&&31>=e?!1:e>=127&&159>=e?!1:e>1114111?!1:!0}function c(e){if(e>65535){e-=65536;var t=55296+(e>>10),r=56320+(1023&e);return String.fromCharCode(t,r)}return String.fromCharCode(e)}function u(e,t){var r=0;return o(v,t)?v[t]:35===t.charCodeAt(0)&&b.test(t)&&(r="x"===t[1].toLowerCase()?parseInt(t.slice(2),16):parseInt(t.slice(1),10),a(r))?c(r):e}function p(e){return e.indexOf("&")<0?e:e.replace(m,u)}function h(e){return y[e]}function f(e){return k.test(e)?e.replace(_,h):e}var d=Object.prototype.hasOwnProperty,g=/\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g,m=/&([a-z#][a-z0-9]{1,31});/gi,b=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i,v=e("./entities"),k=/[&<>"]/,_=/[&<>"]/g,y={"&":"&","<":"<",">":">",'"':"""};r.assign=i,r.isString=s,r.has=o,r.unescapeMd=l,r.isValidEntityCode=a,r.fromCodePoint=c,r.replaceEntities=p,r.escapeHtml=f},{"./entities":1}],6:[function(e,t){"use strict";t.exports={options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:20},components:{core:{rules:["block","inline","references","abbr2"]},block:{rules:["blockquote","code","fences","heading","hr","htmlblock","lheading","list","paragraph"]},inline:{rules:["autolink","backticks","emphasis","entity","escape","htmltag","links","newline","text"]}}}},{}],7:[function(e,t){"use strict";t.exports={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:20},components:{core:{rules:["block","inline","references","replacements","linkify","smartquotes","references","abbr2","footnote_tail"]},block:{rules:["blockquote","code","fences","heading","hr","htmlblock","lheading","list","paragraph","table"]},inline:{rules:["autolink","backticks","del","emphasis","entity","escape","footnote_ref","htmltag","links","newline","text"]}}}},{}],8:[function(e,t){"use strict";t.exports={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:20},components:{core:{},block:{},inline:{}}}},{}],9:[function(e,t){"use strict";var r=e("../common/utils").replaceEntities;t.exports=function(e){var t=r(e);try{t=decodeURI(t)}catch(n){}return encodeURI(t)}},{"../common/utils":5}],10:[function(e,t){"use strict";t.exports=function(e){return e.trim().replace(/\s+/g," ").toUpperCase()}},{}],11:[function(e,t){"use strict";var r=e("./normalize_link"),n=e("../common/utils").unescapeMd;t.exports=function(e,t){var s,o,i,l=t,a=e.posMax;if(60===e.src.charCodeAt(t)){for(t++;a>t;){if(s=e.src.charCodeAt(t),10===s)return!1;if(62===s)return i=r(n(e.src.slice(l+1,t))),e.parser.validateLink(i)?(e.pos=t+1,e.linkContent=i,!0):!1;92===s&&a>t+1?t+=2:t++}return!1}for(o=0;a>t&&(s=e.src.charCodeAt(t),32!==s)&&!(32>s||127===s);)if(92===s&&a>t+1)t+=2;else{if(40===s&&(o++,o>1))break;if(41===s&&(o--,0>o))break;t++}return l===t?!1:(i=r(n(e.src.slice(l,t))),e.parser.validateLink(i)?(e.linkContent=i,e.pos=t,!0):!1)}},{"../common/utils":5,"./normalize_link":9}],12:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o=-1,i=e.posMax,l=e.pos,a=e.isInLabel;
+if(e.isInLabel)return-1;if(e.labelUnmatchedScopes)return e.labelUnmatchedScopes--,-1;for(e.pos=t+1,e.isInLabel=!0,r=1;e.post;){if(n=e.src.charCodeAt(t),n===i)return e.pos=t+1,e.linkContent=r(e.src.slice(s+1,t)),!0;92===n&&o>t+1?t+=2:t++}return!1}},{"../common/utils":5}],14:[function(e,t){"use strict";function r(e,t,r){this.src=t,this.env=r,this.options=e.options,this.tokens=[],this.inlineMode=!1,this.inline=e.inline,this.block=e.block,this.renderer=e.renderer,this.typographer=e.typographer}function n(e,t){t||o(e)||(t=e||{},e="default"),this.inline=new c,this.block=new a,this.core=new l,this.renderer=new i,this.ruler=new u,this.options={},this.configure(p[e]),t&&this.set(t)}var s=e("./common/utils").assign,o=e("./common/utils").isString,i=e("./renderer"),l=e("./parser_core"),a=e("./parser_block"),c=e("./parser_inline"),u=e("./ruler"),p={"default":e("./configs/default"),full:e("./configs/full"),commonmark:e("./configs/commonmark")};n.prototype.set=function(e){s(this.options,e)},n.prototype.configure=function(e){var t=this;if(!e)throw new Error("Wrong `remarkable` preset, check name/content");e.options&&t.set(e.options),e.components&&Object.keys(e.components).forEach(function(r){e.components[r].rules&&t[r].ruler.enable(e.components[r].rules,!0)})},n.prototype.use=function(e,t){return e(this,t),this},n.prototype.parse=function(e,t){var n=new r(this,e,t);return this.core.process(n),n.tokens},n.prototype.render=function(e,t){return t=t||{},this.renderer.render(this.parse(e,t),this.options,t)},n.prototype.parseInline=function(e,t){var n=new r(this,e,t);return n.inlineMode=!0,this.core.process(n),n.tokens},n.prototype.renderInline=function(e,t){return t=t||{},this.renderer.render(this.parseInline(e,t),this.options,t)},t.exports=n,t.exports.utils=e("./common/utils")},{"./common/utils":5,"./configs/commonmark":6,"./configs/default":7,"./configs/full":8,"./parser_block":15,"./parser_core":16,"./parser_inline":17,"./renderer":18,"./ruler":19}],15:[function(e,t){"use strict";function r(){this.ruler=new n;for(var e=0;el&&(e.line=l=e.skipEmptyLines(l),!(l>=r))&&!(e.tShift[l]s&&!(n=o[s](e,l,r,!1));s++);if(e.tight=!a,e.isEmpty(e.line-1)&&(a=!0),l=e.line,r>l&&e.isEmpty(l)){if(a=!0,l++,r>l&&"list"===e.parentType&&e.isEmpty(l))break;e.line=l}}};var i=/[\n\t]/g,l=/\r[\n\u0085]|[\u2424\u2028\u0085]/g,a=/\u00a0/g;r.prototype.parse=function(e,t,r,n){var o,c=0,u=0;return e?(e=e.replace(a," "),e=e.replace(l,"\n"),e.indexOf(" ")>=0&&(e=e.replace(i,function(t,r){var n;return 10===e.charCodeAt(r)?(c=r+1,u=0,t):(n=" ".slice((r-c-u)%4),u=r-c+1,n)})),o=new s(e,this,t,r,n),void this.tokenize(o,o.line,o.lineMax)):[]},t.exports=r},{"./ruler":19,"./rules_block/blockquote":20,"./rules_block/code":21,"./rules_block/deflist":22,"./rules_block/fences":23,"./rules_block/footnote":24,"./rules_block/heading":25,"./rules_block/hr":26,"./rules_block/htmlblock":27,"./rules_block/lheading":28,"./rules_block/list":29,"./rules_block/paragraph":30,"./rules_block/state_block":31,"./rules_block/table":32}],16:[function(e,t){"use strict";function r(){this.options={},this.ruler=new n;for(var e=0;et;t++)n[t](e)},t.exports=r},{"./ruler":19,"./rules_core/abbr":33,"./rules_core/abbr2":34,"./rules_core/block":35,"./rules_core/footnote_tail":36,"./rules_core/inline":37,"./rules_core/linkify":38,"./rules_core/references":39,"./rules_core/replacements":40,"./rules_core/smartquotes":41}],17:[function(e,t){"use strict";function r(e){var t=e.trim().toLowerCase();return t=i(t),t.indexOf(":")>=0&&a.indexOf(t.split(":")[0])>=0?!1:!0}function n(){this.validateLink=r,this.ruler=new s;for(var e=0;e0)return void(e.pos=r);for(t=0;o>t;t++)if(s[t](e,!0))return void e.cacheSet(n,e.pos);e.pos++,e.cacheSet(n,e.pos)},n.prototype.tokenize=function(e){for(var t,r,n=this.ruler.getRules(""),s=n.length,o=e.posMax;e.posr&&!(t=n[r](e,!1));r++);if(t){if(e.pos>=o)break}else e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()},n.prototype.parse=function(e,t,r,n){var s=new o(e,this,t,r,n);this.tokenize(s)},t.exports=n},{"./common/utils":5,"./ruler":19,"./rules_inline/autolink":42,"./rules_inline/backticks":43,"./rules_inline/del":44,"./rules_inline/emphasis":45,"./rules_inline/entity":46,"./rules_inline/escape":47,"./rules_inline/footnote_inline":48,"./rules_inline/footnote_ref":49,"./rules_inline/htmltag":50,"./rules_inline/ins":51,"./rules_inline/links":52,"./rules_inline/mark":53,"./rules_inline/newline":54,"./rules_inline/state_inline":55,"./rules_inline/sub":56,"./rules_inline/sup":57,"./rules_inline/text":58}],18:[function(e,t){"use strict";function r(e,t){return++t>=e.length-2?t:"paragraph_open"===e[t].type&&e[t].tight&&"inline"===e[t+1].type&&0===e[t+1].content.length&&"paragraph_close"===e[t+2].type&&e[t+2].tight?r(e,t+2):t}function n(e,t){return t=r(e,t),t\n"},u.blockquote_close=function(e,t){return""+n(e,t)},u.code=function(e,t){return e[t].block?""+c(e[t].content)+"
"+n(e,t):""+c(e[t].content)+""},u.fence=function(e,t,r,s,o){var u,p,h=e[t],f="",d=r.langPrefix,g="";if(h.params){if(u=h.params.split(/\s+/g)[0],i(o.rules.fence_custom,u))return o.rules.fence_custom[u](e,t,r,s,o);g=c(a(l(u))),f=' class="'+d+g+'"'}return p=r.highlight?r.highlight(h.content,g)||c(h.content):c(h.content),""+p+"
"+n(e,t)},u.fence_custom={},u.heading_open=function(e,t){return""},u.heading_close=function(e,t){return"\n"},u.hr=function(e,t,r){return(r.xhtmlOut?"
":"
")+n(e,t)},u.bullet_list_open=function(){return"\n"},u.bullet_list_close=function(e,t){return"
"+n(e,t)},u.list_item_open=function(){return""},u.list_item_close=function(){return"\n"},u.ordered_list_open=function(e,t){var r=e[t];return"1?' start="'+r.order+'"':"")+">\n"},u.ordered_list_close=function(e,t){return"
"+n(e,t)},u.paragraph_open=function(e,t){return e[t].tight?"":""},u.paragraph_close=function(e,t){var r=!(e[t].tight&&t&&"inline"===e[t-1].type&&!e[t-1].content);return(e[t].tight?"":"
")+(r?n(e,t):"")},u.link_open=function(e,t){var r=e[t].title?' title="'+c(a(e[t].title))+'"':"";return'"},u.link_close=function(){return""},u.image=function(e,t,r){var n=' src="'+c(e[t].src)+'"',s=e[t].title?' title="'+c(a(e[t].title))+'"':"",o=' alt="'+(e[t].alt?c(a(e[t].alt)):"")+'"',i=r.xhtmlOut?" /":"";return"
"},u.table_open=function(){return"\n"},u.table_close=function(){return"
\n"},u.thead_open=function(){return"\n"},u.thead_close=function(){return"\n"},u.tbody_open=function(){return"\n"},u.tbody_close=function(){return"\n"},u.tr_open=function(){return""},u.tr_close=function(){return"
\n"},u.th_open=function(e,t){var r=e[t];return""},u.th_close=function(){return" | "},u.td_open=function(e,t){var r=e[t];return""},u.td_close=function(){return" | "},u.strong_open=function(){return""},u.strong_close=function(){return""},u.em_open=function(){return""},u.em_close=function(){return""},u.del_open=function(){return""},u.del_close=function(){return""},u.ins_open=function(){return""},u.ins_close=function(){return""},u.mark_open=function(){return""},u.mark_close=function(){return""},u.sub=function(e,t){return""+c(e[t].content)+""},u.sup=function(e,t){return""+c(e[t].content)+""},u.hardbreak=function(e,t,r){return r.xhtmlOut?"
\n":"
\n"},u.softbreak=function(e,t,r){return r.breaks?r.xhtmlOut?"
\n":"
\n":"\n"},u.text=function(e,t){return c(e[t].content)},u.htmlblock=function(e,t){return e[t].content},u.htmltag=function(e,t){return e[t].content},u.abbr_open=function(e,t){return''},u.abbr_close=function(){return""},u.footnote_ref=function(e,t){var r=Number(e[t].id+1).toString(),n="fnref"+r;return e[t].subId>0&&(n+=":"+e[t].subId),'"},u.footnote_block_open=function(e,t,r){return(r.xhtmlOut?'\n':'\n')+'\n"},u.footnote_open=function(e,t){var r=Number(e[t].id+1).toString();return'\n"},u.footnote_anchor=function(e,t){var r=Number(e[t].id+1).toString(),n="fnref"+r;return e[t].subId>0&&(n+=":"+e[t].subId),' '},u.dl_open=function(){return"\n"},u.dt_open=function(){return"- "},u.dd_open=function(){return"
- "},u.dl_close=function(){return"
\n"},u.dt_close=function(){return"\n"},u.dd_close=function(){return"\n"},s.prototype.renderInline=function(e,t,r){for(var n="",s=this.rules,o=0,i=e.length;i>o;o++)n+=s[e[o].type](e,o,t,r,this);return n},s.prototype.render=function(e,t,r){var n,s,o="",i=this.rules;for(n=0,s=e.length;s>n;n++)o+="inline"===e[n].type?this.renderInline(e[n].children,t,r):i[e[n].type](e,n,t,r,this);return o},t.exports=s},{"./common/utils":5}],19:[function(e,t){"use strict";function r(){this.__rules__=[],this.__cache__=null}r.prototype.__find__=function(e){for(var t=0;tt)throw new Error("Rules manager: invalid rule name "+e);this.__rules__[t].enabled=!0},this),this.__cache__=null},r.prototype.disable=function(e){Array.isArray(e)||(e=[e]),e.forEach(function(e){var t=this.__find__(e);if(0>t)throw new Error("Rules manager: invalid rule name "+e);this.__rules__[t].enabled=!1},this),this.__cache__=null},r.prototype.getRules=function(e){return null===this.__cache__&&this.__compile__(),this.__cache__[e]},t.exports=r},{}],20:[function(e,t){"use strict";t.exports=function(e,t,r,n){var s,o,i,l,a,c,u,p,h,f,d,g=e.bMarks[t]+e.tShift[t],m=e.eMarks[t];if(g>m)return!1;if(62!==e.src.charCodeAt(g++))return!1;if(e.level>=e.options.maxNesting)return!1;if(n)return!0;for(32===e.src.charCodeAt(g)&&g++,a=e.blkIndent,e.blkIndent=0,l=[e.bMarks[t]],e.bMarks[t]=g,g=m>g?e.skipSpaces(g):g,o=g>=m,i=[e.tShift[t]],e.tShift[t]=g-e.bMarks[t],p=e.parser.ruler.getRules("blockquote"),s=t+1;r>s&&(g=e.bMarks[s]+e.tShift[s],m=e.eMarks[s],!(g>=m));s++)if(62!==e.src.charCodeAt(g++)){if(o)break;for(d=!1,h=0,f=p.length;f>h;h++)if(p[h](e,s,r,!0)){d=!0;break}if(d)break;l.push(e.bMarks[s]),i.push(e.tShift[s]),e.tShift[s]=-1337}else 32===e.src.charCodeAt(g)&&g++,l.push(e.bMarks[s]),e.bMarks[s]=g,g=m>g?e.skipSpaces(g):g,o=g>=m,i.push(e.tShift[s]),e.tShift[s]=g-e.bMarks[s];for(c=e.parentType,e.parentType="blockquote",e.tokens.push({type:"blockquote_open",lines:u=[t,0],level:e.level++}),e.parser.tokenize(e,t,s),e.tokens.push({type:"blockquote_close",level:--e.level}),e.parentType=c,u[1]=e.line,h=0;hn;)if(e.isEmpty(n))n++;else{if(!(e.tShift[n]-e.blkIndent>=4))break;n++,s=n}return e.line=n,e.tokens.push({type:"code",content:e.getLines(t,s,4+e.blkIndent,!0),block:!0,lines:[t,e.line],level:e.level}),!0}},{}],22:[function(e,t){"use strict";function r(e,t){var r,n,s=e.bMarks[t]+e.tShift[t],o=e.eMarks[t];return s>=o?-1:(n=e.src.charCodeAt(s++),126!==n&&58!==n?-1:(r=e.skipSpaces(s),s===r?-1:r>=o?-1:r))}function n(e,t){var r,n,s=e.level+2;for(r=t+2,n=e.tokens.length-2;n>r;r++)e.tokens[r].level===s&&"paragraph_open"===e.tokens[r].type&&(e.tokens[r+2].tight=!0,e.tokens[r].tight=!0,r+=2)}t.exports=function(e,t,s,o){var i,l,a,c,u,p,h,f,d,g,m,b,v,k;if(o)return e.ddIndent<0?!1:r(e,t)>=0;if(h=t+1,e.isEmpty(h)&&++h>s)return!1;if(e.tShift[h]i)return!1;if(e.level>=e.options.maxNesting)return!1;p=e.tokens.length,e.tokens.push({type:"dl_open",lines:u=[t,0],level:e.level++}),a=t,l=h;e:for(;;){for(k=!0,v=!1,e.tokens.push({type:"dt_open",lines:[a,a],level:e.level++}),e.tokens.push({type:"inline",content:e.getLines(a,a+1,e.blkIndent,!1).trim(),level:e.level+1,lines:[a,a],children:[]}),e.tokens.push({type:"dt_close",level:--e.level});;){if(e.tokens.push({type:"dd_open",lines:c=[h,0],level:e.level++}),b=e.tight,d=e.ddIndent,f=e.blkIndent,m=e.tShift[l],g=e.parentType,e.blkIndent=e.ddIndent=e.tShift[l]+2,e.tShift[l]=i-e.bMarks[l],e.tight=!0,e.parentType="deflist",e.parser.tokenize(e,l,s,!0),(!e.tight||v)&&(k=!1),v=e.line-l>1&&e.isEmpty(e.line-1),e.tShift[l]=m,e.tight=b,e.parentType=g,e.blkIndent=f,e.ddIndent=d,e.tokens.push({type:"dd_close",level:--e.level}),c[1]=h=e.line,h>=s)break e;if(e.tShift[h]i)break;l=h}if(h>=s)break;if(a=h,e.isEmpty(a))break;if(e.tShift[a]=s)break;if(e.isEmpty(l)&&l++,l>=s)break;if(e.tShift[l]i)break}return e.tokens.push({type:"dl_close",level:--e.level}),u[1]=h,e.line=h,k&&n(e,p),!0}},{}],23:[function(e,t){"use strict";t.exports=function(e,t,r,n){var s,o,i,l,a,c=!1,u=e.bMarks[t]+e.tShift[t],p=e.eMarks[t];if(u+3>p)return!1;if(s=e.src.charCodeAt(u),126!==s&&96!==s)return!1;if(a=u,u=e.skipChars(u,s),o=u-a,3>o)return!1;if(i=e.src.slice(u,p).trim(),i.indexOf("`")>=0)return!1;if(n)return!0;for(l=t;(l++,!(l>=r))&&(u=a=e.bMarks[l]+e.tShift[l],p=e.eMarks[l],!(p>u&&e.tShift[l]=4||(u=e.skipChars(u,s),o>u-a||(u=e.skipSpaces(u),p>u)))){c=!0;break}return o=e.tShift[t],e.line=l+(c?1:0),e.tokens.push({type:"fence",params:i,content:e.getLines(t+1,l,o,!0),lines:[t,e.line],level:e.level}),!0}},{}],24:[function(e,t){"use strict";t.exports=function(e,t,r,n){var s,o,i,l,a,c=e.bMarks[t]+e.tShift[t],u=e.eMarks[t];if(c+4>u)return!1;if(91!==e.src.charCodeAt(c))return!1;if(94!==e.src.charCodeAt(c+1))return!1;if(e.level>=e.options.maxNesting)return!1;for(l=c+2;u>l;l++){if(32===e.src.charCodeAt(l))return!1;if(93===e.src.charCodeAt(l))break}return l===c+2?!1:l+1>=u||58!==e.src.charCodeAt(++l)?!1:n?!0:(l++,e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.refs||(e.env.footnotes.refs={}),a=e.src.slice(c+2,l-2),e.env.footnotes.refs[":"+a]=-1,e.tokens.push({type:"footnote_reference_open",label:a,level:e.level++}),s=e.bMarks[t],o=e.tShift[t],i=e.parentType,e.tShift[t]=e.skipSpaces(l)-l,e.bMarks[t]=l,e.blkIndent+=4,e.parentType="footnote",e.tShift[t]=a)return!1;if(s=e.src.charCodeAt(l),35!==s||l>=a)return!1;for(o=1,s=e.src.charCodeAt(++l);35===s&&a>l&&6>=o;)o++,s=e.src.charCodeAt(++l);return o>6||a>l&&32!==s?!1:n?!0:(a=e.skipCharsBack(a,32,l),i=e.skipCharsBack(a,35,l),i>l&&32===e.src.charCodeAt(i-1)&&(a=i),e.line=t+1,e.tokens.push({type:"heading_open",hLevel:o,lines:[t,e.line],level:e.level}),a>l&&e.tokens.push({type:"inline",content:e.src.slice(l,a).trim(),level:e.level+1,lines:[t,e.line],children:[]}),e.tokens.push({type:"heading_close",hLevel:o,level:e.level}),!0)}},{}],26:[function(e,t){"use strict";t.exports=function(e,t,r,n){var s,o,i,l=e.bMarks[t],a=e.eMarks[t];if(l+=e.tShift[t],l>a)return!1;if(s=e.src.charCodeAt(l++),42!==s&&45!==s&&95!==s)return!1;for(o=1;a>l;){if(i=e.src.charCodeAt(l++),i!==s&&32!==i)return!1;i===s&&o++}return 3>o?!1:n?!0:(e.line=t+1,e.tokens.push({type:"hr",lines:[t,e.line],level:e.level}),!0)}},{}],27:[function(e,t){"use strict";function r(e){var t=32|e;return t>=97&&122>=t}var n=e("../common/html_blocks"),s=/^<([a-zA-Z]{1,15})[\s\/>]/,o=/^<\/([a-zA-Z]{1,15})[\s>]/;t.exports=function(e,t,i,l){var a,c,u,p=e.bMarks[t],h=e.eMarks[t],f=e.tShift[t];if(p+=f,!e.options.html)return!1;if(f>3||p+2>=h)return!1;if(60!==e.src.charCodeAt(p))return!1;if(a=e.src.charCodeAt(p+1),33===a||63===a){if(l)return!0}else{if(47!==a&&!r(a))return!1;if(47===a){if(c=e.src.slice(p,h).match(o),!c)return!1}else if(c=e.src.slice(p,h).match(s),!c)return!1;if(n[c[1].toLowerCase()]!==!0)return!1;if(l)return!0}for(u=t+1;u=r?!1:e.tShift[i]3?!1:(s=e.bMarks[i]+e.tShift[i],o=e.eMarks[i],s>=o?!1:(n=e.src.charCodeAt(s),45!==n&&61!==n?!1:(s=e.skipChars(s,n),s=e.skipSpaces(s),o>s?!1:(s=e.bMarks[t]+e.tShift[t],e.line=i+1,e.tokens.push({type:"heading_open",hLevel:61===n?1:2,lines:[t,e.line],level:e.level}),e.tokens.push({type:"inline",content:e.src.slice(s,e.eMarks[t]).trim(),level:e.level+1,lines:[t,e.line-1],children:[]}),e.tokens.push({type:"heading_close",hLevel:61===n?1:2,level:e.level}),!0))))}},{}],29:[function(e,t){"use strict";function r(e,t){var r,n,s;return n=e.bMarks[t]+e.tShift[t],s=e.eMarks[t],n>=s?-1:(r=e.src.charCodeAt(n++),42!==r&&45!==r&&43!==r?-1:s>n&&32!==e.src.charCodeAt(n)?-1:n)}function n(e,t){var r,n=e.bMarks[t]+e.tShift[t],s=e.eMarks[t];if(n+1>=s)return-1;if(r=e.src.charCodeAt(n++),48>r||r>57)return-1;for(;;){if(n>=s)return-1;if(r=e.src.charCodeAt(n++),!(r>=48&&57>=r)){if(41===r||46===r)break;return-1}}return s>n&&32!==e.src.charCodeAt(n)?-1:n}function s(e,t){var r,n,s=e.level+2;for(r=t+2,n=e.tokens.length-2;n>r;r++)e.tokens[r].level===s&&"paragraph_open"===e.tokens[r].type&&(e.tokens[r+2].tight=!0,e.tokens[r].tight=!0,r+=2)}t.exports=function(e,t,o,i){var l,a,c,u,p,h,f,d,g,m,b,v,k,_,y,x,w,A,q,C,S,M,E=!0;if((d=n(e,t))>=0)k=!0;else{if(!((d=r(e,t))>=0))return!1;k=!1}if(e.level>=e.options.maxNesting)return!1;if(v=e.src.charCodeAt(d-1),i)return!0;for(y=e.tokens.length,k?(f=e.bMarks[t]+e.tShift[t],b=Number(e.src.substr(f,d-f-1)),e.tokens.push({type:"ordered_list_open",order:b,lines:w=[t,0],level:e.level++})):e.tokens.push({type:"bullet_list_open",lines:w=[t,0],level:e.level++}),l=t,x=!1,q=e.parser.ruler.getRules("list");!(!(o>l)||(_=e.skipSpaces(d),g=e.eMarks[l],m=_>=g?1:_-d,m>4&&(m=1),1>m&&(m=1),a=d-e.bMarks[l]+m,e.tokens.push({type:"list_item_open",lines:A=[t,0],level:e.level++}),u=e.blkIndent,p=e.tight,c=e.tShift[t],h=e.parentType,e.tShift[t]=_-e.bMarks[t],e.blkIndent=a,e.tight=!0,e.parentType="list",e.parser.tokenize(e,t,o,!0),(!e.tight||x)&&(E=!1),x=e.line-t>1&&e.isEmpty(e.line-1),e.blkIndent=u,e.tShift[t]=c,e.tight=p,e.parentType=h,e.tokens.push({type:"list_item_close",level:--e.level}),l=t=e.line,A[1]=l,_=e.bMarks[t],l>=o)||e.isEmpty(l)||e.tShift[l]C;C++)if(q[C](e,l,o,!0)){M=!0;break}if(M)break;if(k){if(d=n(e,l),0>d)break}else if(d=r(e,l),0>d)break;if(v!==e.src.charCodeAt(d-1))break}return e.tokens.push({type:k?"ordered_list_close":"bullet_list_close",level:--e.level}),w[1]=l,e.line=l,E&&s(e,y),!0}},{}],30:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l,a=t+1;if(r=e.lineMax,r>a&&!e.isEmpty(a))for(l=e.parser.ruler.getRules("paragraph");r>a&&!e.isEmpty(a);a++)if(!(e.tShift[a]-e.blkIndent>3)){for(s=!1,o=0,i=l.length;i>o;o++)if(l[o](e,a,r,!0)){s=!0;break}if(s)break}return n=e.getLines(t,a,e.blkIndent,!1).trim(),e.line=a,n.length&&(e.tokens.push({type:"paragraph_open",tight:!1,lines:[t,e.line],level:e.level}),e.tokens.push({type:"inline",content:n,level:e.level+1,lines:[t,e.line],children:[]}),e.tokens.push({type:"paragraph_close",tight:!1,level:e.level})),!0}},{}],31:[function(e,t){"use strict";function r(e,t,r,n,s){var o,i,l,a,c,u,p;for(this.src=e,this.parser=t,this.options=r,this.env=n,this.tokens=s,this.bMarks=[],this.eMarks=[],this.tShift=[],this.blkIndent=0,this.line=0,this.lineMax=0,this.tight=!1,this.parentType="root",this.ddIndent=-1,this.level=0,this.result="",i=this.src,u=0,p=!1,l=a=u=0,c=i.length;c>a;a++){if(o=i.charCodeAt(a),!p){if(32===o){u++;continue}p=!0}(10===o||a===c-1)&&(10!==o&&a++,this.bMarks.push(l),this.eMarks.push(a),this.tShift.push(u),p=!1,u=0,l=a+1)}this.bMarks.push(i.length),this.eMarks.push(i.length),this.tShift.push(0),this.lineMax=this.bMarks.length-1}r.prototype.isEmpty=function(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]},r.prototype.skipEmptyLines=function(e){for(var t=this.lineMax;t>e&&!(this.bMarks[e]+this.tShift[e]e&&32===this.src.charCodeAt(e);e++);return e},r.prototype.skipChars=function(e,t){for(var r=this.src.length;r>e&&this.src.charCodeAt(e)===t;e++);return e},r.prototype.skipCharsBack=function(e,t,r){if(r>=e)return e;for(;e>r;)if(t!==this.src.charCodeAt(--e))return e+1;return e},r.prototype.getLines=function(e,t,r,n){var s,o,i,l,a,c=e;if(e>=t)return"";if(c+1===t)return o=this.bMarks[c]+Math.min(this.tShift[c],r),i=n?this.bMarks[t]:this.eMarks[t-1],this.src.slice(o,i);for(l=new Array(t-e),s=0;t>c;c++,s++)a=this.tShift[c],a>r&&(a=r),0>a&&(a=0),o=this.bMarks[c]+a,i=t>c+1||n?this.eMarks[c]+1:this.eMarks[c],l[s]=this.src.slice(o,i);return l.join("")},t.exports=r},{}],32:[function(e,t){"use strict";function r(e,t){var r=e.bMarks[t]+e.blkIndent,n=e.eMarks[t];return e.src.substr(r,n-r)}t.exports=function(e,t,n,s){var o,i,l,a,c,u,p,h,f,d;if(t+2>n)return!1;if(c=t+1,e.tShift[c]=e.eMarks[c])return!1;if(o=e.src.charCodeAt(l),124!==o&&45!==o&&58!==o)return!1;if(i=r(e,t+1),!/^[-:| ]+$/.test(i))return!1;if(u=i.split("|"),2>=u)return!1;for(p=[],a=0;ac&&!(e.tShift[c]l||58!==e.charCodeAt(l+1))return-1;for(c=i.posMax,a=l+2;c>a&&10!==i.src.charCodeAt(a);a++);return u=e.slice(2,l),p=e.slice(l+2,a).trim(),0===p.length?-1:(o.abbreviations||(o.abbreviations={}),"undefined"==typeof o.abbreviations[":"+u]&&(o.abbreviations[":"+u]=p),a)}var n=e("../rules_inline/state_inline"),s=e("../helpers/parse_link_label");t.exports=function(e){var t,n,s,o,i=e.tokens;if(!e.inlineMode)for(t=1,n=i.length-1;n>t;t++)if("paragraph_open"===i[t-1].type&&"inline"===i[t].type&&"paragraph_close"===i[t+1].type){for(s=i[t].content;s.length&&(o=r(s,e.inline,e.options,e.env),!(0>o));)s=s.slice(o).trim();i[t].content=s,s.length||(i[t-1].tight=!0,i[t+1].tight=!0)}}},{"../helpers/parse_link_label":12,"../rules_inline/state_inline":55}],34:[function(e,t){"use strict";function r(e){return e.replace(/([-()\[\]{}+?*.$\^|,:#s;s++)if("inline"===g[s].type)for(i=g[s].children,t=i.length-1;t>=0;t--)if(l=i[t],"text"===l.type){for(u=0,a=l.content,h.lastIndex=0,p=l.level,c=[];f=h.exec(a);)h.lastIndex>u&&c.push({type:"text",content:a.slice(u,f.index+f[1].length),level:p}),c.push({type:"abbr_open",title:e.env.abbreviations[":"+f[2]],level:p++}),c.push({type:"text",content:f[2],level:p}),c.push({type:"abbr_close",level:--p}),u=h.lastIndex-f[3].length;c.length&&(ut;t++){for(e.tokens.push({type:"footnote_open",id:t,level:u++}),i[t].tokens?(l=[],l.push({type:"paragraph_open",tight:!1,level:u++}),l.push({type:"inline",content:"",level:u,children:i[t].tokens}),l.push({type:"paragraph_close",tight:!1,level:--u})):i[t].label&&(l=h[":"+i[t].label]),e.tokens=e.tokens.concat(l),o="paragraph_close"===e.tokens[e.tokens.length-1].type?e.tokens.pop():null,s=i[t].count>0?i[t].count:1,n=0;s>n;n++)e.tokens.push({type:"footnote_anchor",id:t,subId:n,level:u});o&&e.tokens.push(o),e.tokens.push({type:"footnote_close",level:--u})}e.tokens.push({type:"footnote_block_close",level:--u})}}},{}],37:[function(e,t){"use strict";t.exports=function(e){var t,r,n,s=e.tokens;for(r=0,n=s.length;n>r;r++)t=s[r],"inline"===t.type&&e.inline.parse(t.content,e.options,e.env,t.children)}},{}],38:[function(e,t){"use strict";function r(e){return/^\s]/i.test(e)}function n(e){return/^<\/a\s*>/i.test(e)}function s(){var e=[],t=new o({stripPrefix:!1,url:!0,email:!0,twitter:!1,replaceFn:function(t,r){switch(r.getType()){case"url":e.push({text:r.matchedText,url:r.getUrl()});break;case"email":e.push({text:r.matchedText,url:"mailto:"+r.getEmail().replace(/^mailto:/i,"")})}return!1}});return{links:e,autolinker:t}}var o=e("autolinker"),i=/www|@|\:\/\//;t.exports=function(e){var t,o,l,a,c,u,p,h,f,d,g,m,b,v=e.tokens,k=null;if(e.options.linkify)for(o=0,l=v.length;l>o;o++)if("inline"===v[o].type)for(a=v[o].children,g=0,t=a.length-1;t>=0;t--)if(c=a[t],"link_close"!==c.type){if("htmltag"===c.type&&(r(c.content)&&g>0&&g--,n(c.content)&&g++),!(g>0)&&"text"===c.type&&i.test(c.content)){if(k||(k=s(),m=k.links,b=k.autolinker),u=c.content,m.length=0,b.link(u),!m.length)continue;for(p=[],d=c.level,h=0;hu||58!==e.charCodeAt(u+1))return-1;for(h=c.posMax,p=u+2;h>p&&(f=c.src.charCodeAt(p),32===f||10===f);p++);if(!o(c,p))return-1;for(g=c.linkContent,p=c.pos,d=p,p+=1;h>p&&(f=c.src.charCodeAt(p),32===f||10===f);p++);for(h>p&&d!==p&&i(c,p)?(m=c.linkContent,p=c.pos):(m="",p=d);h>p&&32===c.src.charCodeAt(p);)p++;return h>p&&10!==c.src.charCodeAt(p)?-1:(b=l(e.slice(1,u)),"undefined"==typeof a.references[b]&&(a.references[b]={title:m,href:g}),p)}var n=e("../rules_inline/state_inline"),s=e("../helpers/parse_link_label"),o=e("../helpers/parse_link_destination"),i=e("../helpers/parse_link_title"),l=e("../helpers/normalize_reference");t.exports=function(e){var t,n,s,o,i=e.tokens;if(e.env.references=e.env.references||{},!e.inlineMode)for(t=1,n=i.length-1;n>t;t++)if("inline"===i[t].type&&"paragraph_open"===i[t-1].type&&"paragraph_close"===i[t+1].type){for(s=i[t].content;s.length&&(o=r(s,e.inline,e.options,e.env),!(0>o));)s=s.slice(o).trim();i[t].content=s,s.length||(i[t-1].tight=!0,i[t+1].tight=!0)}}},{"../helpers/normalize_reference":10,"../helpers/parse_link_destination":11,"../helpers/parse_link_label":12,"../helpers/parse_link_title":13,"../rules_inline/state_inline":55}],40:[function(e,t){"use strict";function r(e){return e.indexOf("(")<0?e:e.replace(s,function(e,t){return o[t.toLowerCase()]})}var n=/\+-|\.\.|\?\?\?\?|!!!!|,,|--/,s=/\((c|tm|r|p)\)/gi,o={c:"©",r:"®",p:"§",tm:"™"};t.exports=function(e){var t,s,o,i,l;if(e.options.typographer)for(l=e.tokens.length-1;l>=0;l--)if("inline"===e.tokens[l].type)for(i=e.tokens[l].children,t=i.length-1;t>=0;t--)s=i[t],"text"===s.type&&(o=s.content,o=r(o),n.test(o)&&(o=o.replace(/\+-/g,"±").replace(/\.{2,}/g,"…").replace(/([?!])…/g,"$1..").replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",").replace(/(^|[^-])---([^-]|$)/gm,"$1—$2").replace(/(^|\s)--(\s|$)/gm,"$1–$2").replace(/(^|[^-\s])--([^-\s]|$)/gm,"$1–$2")),s.content=o)}},{}],41:[function(e,t){"use strict";function r(e,t){return 0>t||t>=e.length?!1:!i.test(e[t])}function n(e,t,r){return e.substr(0,t)+r+e.substr(t+1)}var s=/['"]/,o=/['"]/g,i=/[-\s()\[\]]/,l="’";t.exports=function(e){var t,i,a,c,u,p,h,f,d,g,m,b,v,k,_,y,x;if(e.options.typographer)for(x=[],_=e.tokens.length-1;_>=0;_--)if("inline"===e.tokens[_].type)for(y=e.tokens[_].children,x.length=0,t=0;t=0&&!(x[v].level<=h);v--);x.length=v+1,a=i.content,u=0,p=a.length;e:for(;p>u&&(o.lastIndex=u,c=o.exec(a));)if(f=!r(a,c.index-1),u=c.index+1,k="'"===c[0],d=!r(a,u),d||f){if(m=!d,b=!f)for(v=x.length-1;v>=0&&(g=x[v],!(x[v].level/,o=/^<([a-zA-Z.\-]{1,25}):([^<>\x00-\x20]*)>/;t.exports=function(e,t){var i,l,a,c,u,p=e.pos;return 60!==e.src.charCodeAt(p)?!1:(i=e.src.slice(p),i.indexOf(">")<0?!1:(l=i.match(o))?r.indexOf(l[1].toLowerCase())<0?!1:(c=l[0].slice(1,-1),u=n(c),e.parser.validateLink(c)?(t||(e.push({type:"link_open",href:u,level:e.level}),e.push({type:"text",content:c,level:e.level+1}),e.push({type:"link_close",level:e.level})),e.pos+=l[0].length,!0):!1):(a=i.match(s),a?(c=a[0].slice(1,-1),u=n("mailto:"+c),e.parser.validateLink(u)?(t||(e.push({type:"link_open",href:u,level:e.level}),e.push({type:"text",content:c,level:e.level+1}),e.push({type:"link_close",level:e.level})),e.pos+=a[0].length,!0):!1):!1))}},{"../common/url_schemas":4,"../helpers/normalize_link":9}],43:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l=e.pos,a=e.src.charCodeAt(l);if(96!==a)return!1;for(r=l,l++,n=e.posMax;n>l&&96===e.src.charCodeAt(l);)l++;for(s=e.src.slice(r,l),o=i=l;-1!==(o=e.src.indexOf("`",i));){for(i=o+1;n>i&&96===e.src.charCodeAt(i);)i++;if(i-o===s.length)return t||e.push({type:"code",content:e.src.slice(l,o).replace(/[ \n]+/g," ").trim(),block:!1,level:e.level}),e.pos=i,!0}return t||(e.pending+=s),e.pos+=s.length,!0}},{}],44:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l=e.posMax,a=e.pos;if(126!==e.src.charCodeAt(a))return!1;if(t)return!1;if(a+4>=l)return!1;if(126!==e.src.charCodeAt(a+1))return!1;if(e.level>=e.options.maxNesting)return!1;if(o=a>0?e.src.charCodeAt(a-1):-1,i=e.src.charCodeAt(a+2),126===o)return!1;if(126===i)return!1;if(32===i||10===i)return!1;for(n=a+2;l>n&&126===e.src.charCodeAt(n);)n++;if(n>a+3)return e.pos+=n-a,t||(e.pending+=e.src.slice(a,n)),!0;for(e.pos=a+2,s=1;e.pos+1=s))){r=!0;break}e.parser.skipToken(e)}return r?(e.posMax=e.pos,e.pos=a+2,t||(e.push({type:"del_open",level:e.level++}),e.parser.tokenize(e),e.push({type:"del_close",level:--e.level})),e.pos=e.posMax+2,e.posMax=l,!0):(e.pos=a,!1)}},{}],45:[function(e,t){"use strict";function r(e){return e>=48&&57>=e||e>=65&&90>=e||e>=97&&122>=e}function n(e,t){var n,s,o,i=t,l=!0,a=!0,c=e.posMax,u=e.src.charCodeAt(t);for(n=t>0?e.src.charCodeAt(t-1):-1;c>i&&e.src.charCodeAt(i)===u;)i++;return i>=c&&(l=!1),o=i-t,o>=4?l=a=!1:(s=c>i?e.src.charCodeAt(i):-1,(32===s||10===s)&&(l=!1),(32===n||10===n)&&(a=!1),95===u&&(r(n)&&(l=!1),r(s)&&(a=!1))),{can_open:l,can_close:a,delims:o}}t.exports=function(e,t){var r,s,o,i,l,a,c,u=e.posMax,p=e.pos,h=e.src.charCodeAt(p);if(95!==h&&42!==h)return!1;if(t)return!1;if(c=n(e,p),r=c.delims,!c.can_open)return e.pos+=r,t||(e.pending+=e.src.slice(p,e.pos)),!0;if(e.level>=e.options.maxNesting)return!1;for(e.pos=p+r,a=[r];e.posl){a.push(i-l);break}if(l-=i,0===a.length)break;e.pos+=i,i=a.pop()}if(0===a.length){r=i,o=!0;break}e.pos+=s;continue}c.can_open&&a.push(s),e.pos+=s}return o?(e.posMax=e.pos,e.pos=p+r,t||((2===r||3===r)&&e.push({type:"strong_open",level:e.level++}),(1===r||3===r)&&e.push({type:"em_open",level:e.level++}),e.parser.tokenize(e),(1===r||3===r)&&e.push({type:"em_close",level:--e.level}),(2===r||3===r)&&e.push({type:"strong_close",level:--e.level})),e.pos=e.posMax+r,e.posMax=u,!0):(e.pos=p,!1)}},{}],46:[function(e,t){"use strict";var r=e("../common/entities"),n=e("../common/utils").has,s=e("../common/utils").isValidEntityCode,o=e("../common/utils").fromCodePoint,i=/^((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i,l=/^&([a-z][a-z0-9]{1,31});/i;t.exports=function(e,t){var a,c,u,p=e.pos,h=e.posMax;if(38!==e.src.charCodeAt(p))return!1;if(h>p+1)if(a=e.src.charCodeAt(p+1),35===a){if(u=e.src.slice(p).match(i))return t||(c="x"===u[1][0].toLowerCase()?parseInt(u[1].slice(1),16):parseInt(u[1],10),e.pending+=o(s(c)?c:65533)),e.pos+=u[0].length,!0}else if(u=e.src.slice(p).match(l),u&&n(r,u[1]))return t||(e.pending+=r[u[1]]),e.pos+=u[0].length,!0;return t||(e.pending+="&"),e.pos++,!0}},{"../common/entities":1,"../common/utils":5}],47:[function(e,t){"use strict";for(var r=[],n=0;256>n;n++)r.push(0);"\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("").forEach(function(e){r[e.charCodeAt(0)]=1}),t.exports=function(e,t){var n,s=e.pos,o=e.posMax;if(92!==e.src.charCodeAt(s))return!1;if(s++,o>s){if(n=e.src.charCodeAt(s),256>n&&0!==r[n])return t||(e.pending+=e.src[s]),e.pos+=2,!0;if(10===n){for(t||e.push({type:"hardbreak",level:e.level}),s++;o>s&&32===e.src.charCodeAt(s);)s++;return e.pos=s,!0}}return t||(e.pending+="\\"),e.pos++,!0}},{}],48:[function(e,t){"use strict";var r=e("../helpers/parse_link_label");t.exports=function(e,t){var n,s,o,i,l=e.posMax,a=e.pos;return a+2>=l?!1:94!==e.src.charCodeAt(a)?!1:91!==e.src.charCodeAt(a+1)?!1:e.level>=e.options.maxNesting?!1:(n=a+2,s=r(e,a+1),0>s?!1:(t||(e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.list||(e.env.footnotes.list=[]),o=e.env.footnotes.list.length,e.pos=n,e.posMax=s,e.push({type:"footnote_ref",id:o,level:e.level}),e.linkLevel++,i=e.tokens.length,e.parser.tokenize(e),e.env.footnotes.list[o]={tokens:e.tokens.splice(i)},e.linkLevel--),e.pos=s+1,e.posMax=l,!0))}},{"../helpers/parse_link_label":12}],49:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i=e.posMax,l=e.pos;if(l+3>i)return!1;if(!e.env.footnotes||!e.env.footnotes.refs)return!1;if(91!==e.src.charCodeAt(l))return!1;if(94!==e.src.charCodeAt(l+1))return!1;if(e.level>=e.options.maxNesting)return!1;for(n=l+2;i>n;n++){if(32===e.src.charCodeAt(n))return!1;if(10===e.src.charCodeAt(n))return!1;if(93===e.src.charCodeAt(n))break}return n===l+2?!1:n>=i?!1:(n++,r=e.src.slice(l+2,n-1),"undefined"==typeof e.env.footnotes.refs[":"+r]?!1:(t||(e.env.footnotes.list||(e.env.footnotes.list=[]),e.env.footnotes.refs[":"+r]<0?(s=e.env.footnotes.list.length,e.env.footnotes.list[s]={label:r,count:0},e.env.footnotes.refs[":"+r]=s):s=e.env.footnotes.refs[":"+r],o=e.env.footnotes.list[s].count,e.env.footnotes.list[s].count++,e.push({type:"footnote_ref",id:s,subId:o,level:e.level})),e.pos=n,e.posMax=i,!0))}},{}],50:[function(e,t){"use strict";function r(e){var t=32|e;return t>=97&&122>=t}var n=e("../common/html_re").HTML_TAG_RE;t.exports=function(e,t){var s,o,i,l=e.pos;return e.options.html?(i=e.posMax,60!==e.src.charCodeAt(l)||l+2>=i?!1:(s=e.src.charCodeAt(l+1),(33===s||63===s||47===s||r(s))&&(o=e.src.slice(l).match(n))?(t||e.push({type:"htmltag",content:e.src.slice(l,l+o[0].length),level:e.level}),e.pos+=o[0].length,!0):!1)):!1}},{"../common/html_re":3}],51:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l=e.posMax,a=e.pos;if(43!==e.src.charCodeAt(a))return!1;if(t)return!1;if(a+4>=l)return!1;if(43!==e.src.charCodeAt(a+1))return!1;if(e.level>=e.options.maxNesting)return!1;if(o=a>0?e.src.charCodeAt(a-1):-1,i=e.src.charCodeAt(a+2),43===o)return!1;if(43===i)return!1;if(32===i||10===i)return!1;for(n=a+2;l>n&&43===e.src.charCodeAt(n);)n++;if(n!==a+2)return e.pos+=n-a,t||(e.pending+=e.src.slice(a,n)),!0;for(e.pos=a+2,s=1;e.pos+1=s))){r=!0;break}e.parser.skipToken(e)}return r?(e.posMax=e.pos,e.pos=a+2,t||(e.push({type:"ins_open",level:e.level++}),e.parser.tokenize(e),e.push({type:"ins_close",level:--e.level})),e.pos=e.posMax+2,e.posMax=l,!0):(e.pos=a,!1)}},{}],52:[function(e,t){"use strict";var r=e("../helpers/parse_link_label"),n=e("../helpers/parse_link_destination"),s=e("../helpers/parse_link_title"),o=e("../helpers/normalize_reference");t.exports=function(e,t){var i,l,a,c,u,p,h,f,d=!1,g=e.pos,m=e.posMax,b=e.pos,v=e.src.charCodeAt(b);if(33===v&&(d=!0,v=e.src.charCodeAt(++b)),91!==v)return!1;if(e.level>=e.options.maxNesting)return!1;if(i=b+1,l=r(e,b),0>l)return!1;if(p=l+1,m>p&&40===e.src.charCodeAt(p)){for(p++;m>p&&(f=e.src.charCodeAt(p),32===f||10===f);p++);if(p>=m)return!1;for(b=p,n(e,p)?(c=e.linkContent,p=e.pos):c="",b=p;m>p&&(f=e.src.charCodeAt(p),32===f||10===f);p++);if(m>p&&b!==p&&s(e,p))for(u=e.linkContent,p=e.pos;m>p&&(f=e.src.charCodeAt(p),32===f||10===f);p++);else u="";if(p>=m||41!==e.src.charCodeAt(p))return e.pos=g,!1;p++}else{if(e.linkLevel>0)return!1;for(;m>p&&(f=e.src.charCodeAt(p),32===f||10===f);p++);if(m>p&&91===e.src.charCodeAt(p)&&(b=p+1,p=r(e,p),p>=0?a=e.src.slice(b,p++):p=b-1),a||(a=e.src.slice(i,l)),h=e.env.references[o(a)],!h)return e.pos=g,!1;c=h.href,u=h.title}return t||(e.pos=i,e.posMax=l,d?e.push({type:"image",src:c,title:u,alt:e.src.substr(i,l-i),level:e.level}):(e.push({type:"link_open",href:c,title:u,level:e.level++}),e.linkLevel++,e.parser.tokenize(e),e.linkLevel--,e.push({type:"link_close",level:--e.level}))),e.pos=p,e.posMax=m,!0}},{"../helpers/normalize_reference":10,"../helpers/parse_link_destination":11,"../helpers/parse_link_label":12,"../helpers/parse_link_title":13}],53:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l=e.posMax,a=e.pos;if(61!==e.src.charCodeAt(a))return!1;if(t)return!1;if(a+4>=l)return!1;if(61!==e.src.charCodeAt(a+1))return!1;if(e.level>=e.options.maxNesting)return!1;if(o=a>0?e.src.charCodeAt(a-1):-1,i=e.src.charCodeAt(a+2),61===o)return!1;if(61===i)return!1;if(32===i||10===i)return!1;for(n=a+2;l>n&&61===e.src.charCodeAt(n);)n++;if(n!==a+2)return e.pos+=n-a,t||(e.pending+=e.src.slice(a,n)),!0;for(e.pos=a+2,s=1;e.pos+1=s))){r=!0;break}e.parser.skipToken(e)}return r?(e.posMax=e.pos,e.pos=a+2,t||(e.push({type:"mark_open",level:e.level++}),e.parser.tokenize(e),e.push({type:"mark_close",level:--e.level})),e.pos=e.posMax+2,e.posMax=l,!0):(e.pos=a,!1)}},{}],54:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s=e.pos;if(10!==e.src.charCodeAt(s))return!1;for(r=e.pending.length-1,n=e.posMax,t||(r>=0&&32===e.pending.charCodeAt(r)?r>=1&&32===e.pending.charCodeAt(r-1)?(e.pending=e.pending.replace(/ +$/,""),e.push({type:"hardbreak",level:e.level})):(e.pending=e.pending.slice(0,-1),e.push({type:"softbreak",level:e.level})):e.push({type:"softbreak",level:e.level})),s++;n>s&&32===e.src.charCodeAt(s);)s++;return e.pos=s,!0}},{}],55:[function(e,t){"use strict";function r(e,t,r,n,s){this.src=e,this.env=n,this.options=r,this.parser=t,this.tokens=s,this.pos=0,this.posMax=this.src.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache=[],this.isInLabel=!1,this.linkLevel=0,this.linkContent="",this.labelUnmatchedScopes=0}r.prototype.pushPending=function(){this.tokens.push({type:"text",content:this.pending,level:this.pendingLevel}),this.pending=""},r.prototype.push=function(e){this.pending&&this.pushPending(),this.tokens.push(e),this.pendingLevel=this.level},r.prototype.cacheSet=function(e,t){for(var r=this.cache.length;e>=r;r++)this.cache.push(0);this.cache[e]=t},r.prototype.cacheGet=function(e){return e?@[\]^_`{|}~-])/g;t.exports=function(e,t){var n,s,o=e.posMax,i=e.pos;if(126!==e.src.charCodeAt(i))return!1;if(t)return!1;if(i+2>=o)return!1;if(e.level>=e.options.maxNesting)return!1;for(e.pos=i+1;e.pos?@[\]^_`{|}~-])/g;t.exports=function(e,t){var n,s,o=e.posMax,i=e.pos;if(94!==e.src.charCodeAt(i))return!1;if(t)return!1;if(i+2>=o)return!1;if(e.level>=e.options.maxNesting)return!1;for(e.pos=i+1;e.posl;l++){var c=n[l],u=r.processTextNode(c);i.push(u)}else i.push(t)}}),i.join("")},getHtmlParser:function(){var t=this.htmlParser;return t||(t=this.htmlParser=new e.HtmlParser),t},getTagBuilder:function(){var t=this.tagBuilder;return t||(t=this.tagBuilder=new e.AnchorTagBuilder({newWindow:this.newWindow,truncate:this.truncate,className:this.className})),t},processTextNode:function(e){var t=this;return e.replace(this.matcherRegex,function(e,r,n,s,o,i,l,a,c){var u=t.processCandidateMatch(e,r,n,s,o,i,l,a,c);if(u){var p=t.createMatchReturnVal(u.match,u.matchStr);return u.prefixStr+p+u.suffixStr}return e})},processCandidateMatch:function(t,r,n,s,o,i,l,a,c){var u,p=a||c,h="",f="";if(r&&!this.twitter||o&&!this.email||i&&!this.urls||!this.matchValidator.isValidMatch(i,l,p))return null;if(this.matchHasUnbalancedClosingParen(t)&&(t=t.substr(0,t.length-1),f=")"),o)u=new e.match.Email({matchedText:t,email:o});else if(r)n&&(h=n,t=t.slice(1)),u=new e.match.Twitter({matchedText:t,twitterHandle:s});else{if(p){var d=p.match(this.charBeforeProtocolRelMatchRegex)[1]||"";d&&(h=d,t=t.slice(1))}u=new e.match.Url({matchedText:t,url:t,protocolUrlMatch:!!l,protocolRelativeMatch:!!p,stripPrefix:this.stripPrefix})}return{prefixStr:h,suffixStr:f,matchStr:t,match:u}},matchHasUnbalancedClosingParen:function(e){var t=e.charAt(e.length-1);if(")"===t){var r=e.match(/\(/g),n=e.match(/\)/g),s=r&&r.length||0,o=n&&n.length||0;if(o>s)return!0}return!1},createMatchReturnVal:function(t,r){var n;if(this.replaceFn&&(n=this.replaceFn.call(this,this,t)),"string"==typeof n)return n;if(n===!1)return r;if(n instanceof e.HtmlTag)return n.toString();var s=this.getTagBuilder(),o=s.build(t);return o.toString()}},e.link=function(t,r){var n=new e(r);return n.link(t)},e.match={},e.Util={abstractMethod:function(){throw"abstract"},assign:function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e},extend:function(t,r){var n=t.prototype,s=function(){};s.prototype=n;var o;o=r.hasOwnProperty("constructor")?r.constructor:function(){n.constructor.apply(this,arguments)};var i=o.prototype=new s;return i.constructor=o,i.superclass=n,delete r.constructor,e.Util.assign(i,r),o},ellipsis:function(e,t,r){return e.length>t&&(r=null==r?"..":r,e=e.substring(0,t-r.length)+r),e},indexOf:function(e,t){if(Array.prototype.indexOf)return e.indexOf(t);for(var r=0,n=e.length;n>r;r++)if(e[r]===t)return r;return-1},splitAndCapture:function(e,t){if(!t.global)throw new Error("`splitRegex` must have the 'g' flag set");for(var r,n=[],s=0;r=t.exec(e);)n.push(e.substring(s,r.index)),n.push(r[0]),s=r.index+r[0].length;return n.push(e.substring(s)),n}},e.HtmlParser=e.Util.extend(Object,{htmlRegex:function(){var e=/[0-9a-zA-Z][0-9a-zA-Z:]*/,t=/[^\s\0"'>\/=\x01-\x1F\x7F]+/,r=/(?:".*?"|'.*?'|[^'"=<>`\s]+)/,n=t.source+"(?:\\s*=\\s*"+r.source+")?";return new RegExp(["(?:","<(!DOCTYPE)","(?:","\\s+","(?:",n,"|",r.source+")",")*",">",")","|","(?:","<(/)?","("+e.source+")","(?:","\\s+",n,")*","\\s*/?",">",")"].join(""),"gi")}(),parse:function(e,t){t=t||{};for(var r,n=t.processHtmlNode||function(){},s=t.processTextNode||function(){},o=this.htmlRegex,i=0;null!==(r=o.exec(e));){var l=r[0],a=r[1]||r[3],c=!!r[2],u=e.substring(i,r.index);u&&s(u),n(l,a.toLowerCase(),c),i=r.index+l.length}if(i",this.getInnerHtml(),"",e,">"].join("")},buildAttrsStr:function(){if(!this.attrs)return"";var e=this.getAttrs(),t=[];for(var r in e)e.hasOwnProperty(r)&&t.push(r+'="'+e[r]+'"');return t.join(" ")}}),e.MatchValidator=e.Util.extend(Object,{invalidProtocolRelMatchRegex:/^[\w]\/\//,hasFullProtocolRegex:/^[A-Za-z][-.+A-Za-z0-9]+:\/\//,uriSchemeRegex:/^[A-Za-z][-.+A-Za-z0-9]+:/,hasWordCharAfterProtocolRegex:/:[^\s]*?[A-Za-z]/,isValidMatch:function(e,t,r){return t&&!this.isValidUriScheme(t)||this.urlMatchDoesNotHaveProtocolOrDot(e,t)||this.urlMatchDoesNotHaveAtLeastOneWordChar(e,t)||this.isInvalidProtocolRelativeMatch(r)?!1:!0},isValidUriScheme:function(e){var t=e.match(this.uriSchemeRegex)[0];return"javascript:"!==t&&"vbscript:"!==t},urlMatchDoesNotHaveProtocolOrDot:function(e,t){return!(!e||t&&this.hasFullProtocolRegex.test(t)||-1!==e.indexOf("."))},urlMatchDoesNotHaveAtLeastOneWordChar:function(e,t){return e&&t?!this.hasWordCharAfterProtocolRegex.test(e):!1},isInvalidProtocolRelativeMatch:function(e){return!!e&&this.invalidProtocolRelMatchRegex.test(e)}}),e.AnchorTagBuilder=e.Util.extend(Object,{constructor:function(t){e.Util.assign(this,t)},build:function(t){var r=new e.HtmlTag({tagName:"a",attrs:this.createAttrs(t.getType(),t.getAnchorHref()),innerHtml:this.processAnchorText(t.getAnchorText())});return r},createAttrs:function(e,t){var r={href:t},n=this.createCssClass(e);return n&&(r["class"]=n),this.newWindow&&(r.target="_blank"),r},createCssClass:function(e){var t=this.className;return t?t+" "+t+"-"+e:""},processAnchorText:function(e){return e=this.doTruncate(e)},doTruncate:function(t){return e.Util.ellipsis(t,this.truncate||Number.POSITIVE_INFINITY)}}),e.match.Match=e.Util.extend(Object,{constructor:function(t){e.Util.assign(this,t)},getType:e.Util.abstractMethod,getMatchedText:function(){return this.matchedText},getAnchorHref:e.Util.abstractMethod,getAnchorText:e.Util.abstractMethod}),e.match.Email=e.Util.extend(e.match.Match,{getType:function(){return"email"},getEmail:function(){return this.email},getAnchorHref:function(){return"mailto:"+this.email},getAnchorText:function(){return this.email}}),e.match.Twitter=e.Util.extend(e.match.Match,{getType:function(){return"twitter"},getTwitterHandle:function(){return this.twitterHandle},getAnchorHref:function(){return"https://twitter.com/"+this.twitterHandle},getAnchorText:function(){return"@"+this.twitterHandle}}),e.match.Url=e.Util.extend(e.match.Match,{urlPrefixRegex:/^(https?:\/\/)?(www\.)?/i,protocolRelativeRegex:/^\/\//,protocolPrepended:!1,getType:function(){return"url"},getUrl:function(){var e=this.url;return this.protocolRelativeMatch||this.protocolUrlMatch||this.protocolPrepended||(e=this.url="http://"+e,this.protocolPrepended=!0),e},getAnchorHref:function(){var e=this.getUrl();return e.replace(/&/g,"&")},getAnchorText:function(){var e=this.getUrl();return this.protocolRelativeMatch&&(e=this.stripProtocolRelativePrefix(e)),this.stripPrefix&&(e=this.stripUrlPrefix(e)),e=this.removeTrailingSlash(e)},stripUrlPrefix:function(e){return e.replace(this.urlPrefixRegex,"")},stripProtocolRelativePrefix:function(e){return e.replace(this.protocolRelativeRegex,"")},removeTrailingSlash:function(e){return"/"===e.charAt(e.length-1)&&(e=e.slice(0,-1)),e}}),e})},{}],"/":[function(e,t){"use strict";t.exports=e("./lib/")},{"./lib/":14}]},{},[])("/")});
\ No newline at end of file
diff --git a/.c9/runners/C (make).run b/.c9/plugins/beagle.bone101/runners/C (make)
similarity index 92%
rename from .c9/runners/C (make).run
rename to .c9/plugins/beagle.bone101/runners/C (make)
index 3e50c8b..3fdbe8f 100644
--- a/.c9/runners/C (make).run
+++ b/.c9/plugins/beagle.bone101/runners/C (make)
@@ -7,7 +7,7 @@
],
"info" : "Started $project_path: $file_name\nFile path: $file_path\nFile: $file\nArguments: $args\nFile name: $file_name\nFile extension: $file_extension\nFile base name: $file_base_name\nPackages: $packages\nProject path: $project_path\nProject name: $project_name\nHostname: $hostname\nHostname path: $hostname_path\nURL: $url\nPort: $port\nIP: $ip\nCommand: $command\nPython: $python\nPython path: $python_path",
- "env" : {},
- "selector": "^.*\\.c$",
+ "env" : { "MYPORT": "$port" },
+ "selector": "^.*\\.c",
"$debugDefaultState": false
}
diff --git a/.c9/plugins/beagle.bone101/runners/C++ (simple) b/.c9/plugins/beagle.bone101/runners/C++ (simple)
new file mode 100644
index 0000000..3fdbe8f
--- /dev/null
+++ b/.c9/plugins/beagle.bone101/runners/C++ (simple)
@@ -0,0 +1,13 @@
+// Create a custom Cloud9 runner - similar to the Sublime build system
+// For more information see https://docs.c9.io/docs/custom-runners
+{
+ "cmd": [
+ "make", "-f", "/var/lib/cloud9/common/Makefile",
+ "TARGET=$file_base_name", "$args"
+ ],
+
+ "info" : "Started $project_path: $file_name\nFile path: $file_path\nFile: $file\nArguments: $args\nFile name: $file_name\nFile extension: $file_extension\nFile base name: $file_base_name\nPackages: $packages\nProject path: $project_path\nProject name: $project_name\nHostname: $hostname\nHostname path: $hostname_path\nURL: $url\nPort: $port\nIP: $ip\nCommand: $command\nPython: $python\nPython path: $python_path",
+ "env" : { "MYPORT": "$port" },
+ "selector": "^.*\\.c",
+ "$debugDefaultState": false
+}
diff --git a/.c9/project.settings b/.c9/project.settings
index 45a6d2b..2edf4ee 100644
--- a/.c9/project.settings
+++ b/.c9/project.settings
@@ -17,6 +17,9 @@
}
}
},
+ "preview": {
+ "@url": "http://$C9_HOSTNAME:8080"
+ },
"python": {
"@path": "/usr/lib/python3.7/dist-packages:/usr/local/lib/python3.7/dist-packages",
"@version": "python3"
diff --git a/.c9/runners/C or C++ (Beagle Makefile).run b/.c9/runners/C or C++ (Beagle Makefile).run
new file mode 100644
index 0000000..3fdbe8f
--- /dev/null
+++ b/.c9/runners/C or C++ (Beagle Makefile).run
@@ -0,0 +1,13 @@
+// Create a custom Cloud9 runner - similar to the Sublime build system
+// For more information see https://docs.c9.io/docs/custom-runners
+{
+ "cmd": [
+ "make", "-f", "/var/lib/cloud9/common/Makefile",
+ "TARGET=$file_base_name", "$args"
+ ],
+
+ "info" : "Started $project_path: $file_name\nFile path: $file_path\nFile: $file\nArguments: $args\nFile name: $file_name\nFile extension: $file_extension\nFile base name: $file_base_name\nPackages: $packages\nProject path: $project_path\nProject name: $project_name\nHostname: $hostname\nHostname path: $hostname_path\nURL: $url\nPort: $port\nIP: $ip\nCommand: $command\nPython: $python\nPython path: $python_path",
+ "env" : { "MYPORT": "$port" },
+ "selector": "^.*\\.c",
+ "$debugDefaultState": false
+}
diff --git a/.gitignore b/.gitignore
index e3263ed..1f19ab6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
*.out
+*.so
.c9/state.settings
.c9/metadata/
+.c9/.nakignore
diff --git a/About.md b/About.md
new file mode 100644
index 0000000..f40885d
--- /dev/null
+++ b/About.md
@@ -0,0 +1,93 @@
+
+# About [BeagleBoard.org](https://beagleboard.org/about)
+
+BeagleBoard.org is a registered trademark of the BeagleBoard.org Foundation,
+a US-based 501(c)3 tax-exempt non-profit corporation with a focus on education
+on using and creating open source software and hardware and fostering
+open source collaboration.
+
+# Current board members
+
+* Jason Kridner
+* Drew Fustini
+* Robert Nelson
+* Mark Yoder
+* Kipp Bradford
+
+# Thanks to our contributors
+Significant contributions have come from the BeagleBoard.org, Linux and other
+open source developer communities as well as Texas Instruments and other
+technology suppliers. This location is meant to capture some of their names
+and contributions.
+
+* Gerald Coley - designs of all Beagles up to BeagleBoard-X15
+* Khasim Syed Mohammed - brainstorming and debug
+* Steve Kipisz - debug
+* Joel Fernandes - debug
+* Koen Kooi - kernel and distro support on all Beagles up to BeagleBone Black
+* Pantelis Antoniou - dynamic overlays
+* Mans Rullgard
+* Matt Porter
+* Cathy Wicks - GSoC, blog, manuals, university engagements
+* Bill Mills
+* Nishanth Menon
+* Tom Rini
+* David Anders - Bacon Cape
+* Michael Welling
+* James Strawson - librobotcontrol, Robotics Cape,
+* Matthijs van Duin - show-pins.pl, udev rules, #beagle
+* Cody Lacey
+* Erik Welsh - BeagleBone Blue layout, BeagleBone Black Wireless debug
+* Charles Steinkuehler - machinekit, cape-universal*
+* Trammell Hudson - ledscape
+* Anuj Deshpande
+* David Lechner
+* Robert P. J. Day
+* Andrew Henderson
+* Baozhu Zuo
+* Vlad Ungureanu
+* Víctor Mayoral Vilches
+* Henner Zeller
+* Andrew McPherson
+* Derek Molloy
+* Vaishnav M A
+* Parthi
+* Dick Hollenbeck
+* William Hermans
+* John Syne
+* Maxim Podbereznyy
+* Josh Datko
+* Shabaz Yousaf
+* Matt Ranostay
+* Vagrant Cascadian
+* Elias Bakken
+* Matt Richardson
+* David Scheltema
+* Steven Barrett
+* Mirko Denecke
+* Patrick Poirier
+* Damjan Marion
+* Tim Kientzle
+* Frank Hunleth
+* Justin Cooper
+* David Planella
+* Yiğit Yüce
+* Thomas Freiherr
+* Brian Cooke
+* John Seamons
+* Bill Mar
+* Grégoire Gentil
+* Eric Stackpole
+* Jack Armitage
+* Jessica Calloway
+* Philip Parker
+* Alejandro Erives
+* Gerard Andrews
+* Hunyue Yau
+* Zubeen Tolani
+* Kumar Abhishek
+* Ravi Kumar Prasad
+* Victor Meyerson
+* Steve Sakoman
+
+TODO: Please help with the above list
diff --git a/BeagleBone/AI/.work-in-progress/README.md b/BeagleBone/AI/.work-in-progress/README.md
new file mode 100644
index 0000000..db43251
--- /dev/null
+++ b/BeagleBone/AI/.work-in-progress/README.md
@@ -0,0 +1,2 @@
+# Issues/TODO
+* bonescript needs porting to the AI
diff --git a/BeagleBone/AI/checkEQEP.sh b/BeagleBone/AI/.work-in-progress/checkEQEP.sh
similarity index 100%
rename from BeagleBone/AI/checkEQEP.sh
rename to BeagleBone/AI/.work-in-progress/checkEQEP.sh
diff --git a/BeagleBone/AI/checkInputs.js b/BeagleBone/AI/.work-in-progress/checkInputs.js
similarity index 89%
rename from BeagleBone/AI/checkInputs.js
rename to BeagleBone/AI/.work-in-progress/checkInputs.js
index e8b8442..cc238aa 100755
--- a/BeagleBone/AI/checkInputs.js
+++ b/BeagleBone/AI/.work-in-progress/checkInputs.js
@@ -6,9 +6,9 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
+const b = require('bonescript');
-var inputs = ["P8_9", "P8_10", "P8_11", "P8_12", "P8_15", "P8_16",
+const inputs = ["P8_9", "P8_10", "P8_11", "P8_12", "P8_15", "P8_16",
"P8_33", "P8_35", "P8_38",
"P9_11", "P9_17", "P9_18", "P9_19", "P9_20",
"P9_22", "P9_25", "P9_27", "P9_29", "P9_42"];
diff --git a/BeagleBone/AI/checkInputs.sh b/BeagleBone/AI/.work-in-progress/checkInputs.sh
similarity index 100%
rename from BeagleBone/AI/checkInputs.sh
rename to BeagleBone/AI/.work-in-progress/checkInputs.sh
diff --git a/BeagleBone/AI/checkInputsREADME.md b/BeagleBone/AI/.work-in-progress/checkInputsREADME.md
similarity index 100%
rename from BeagleBone/AI/checkInputsREADME.md
rename to BeagleBone/AI/.work-in-progress/checkInputsREADME.md
diff --git a/BeagleBone/AI/.work-in-progress/fadeLED.js b/BeagleBone/AI/.work-in-progress/fadeLED.js
new file mode 100755
index 0000000..91aeab1
--- /dev/null
+++ b/BeagleBone/AI/.work-in-progress/fadeLED.js
@@ -0,0 +1,37 @@
+#!/usr/bin/env node
+////////////////////////////////////////
+// fade.js
+// Fades the LED wired to P9_14 using the PWM.
+// Wiring: P9_14 connects to the plus lead of an LED. The negative lead of the
+// LED goes to a 220 Ohm resistor. The other lead of the resistor goes
+// to ground.
+// Setup:
+// See:
+////////////////////////////////////////
+const b = require('bonescript');
+const LED = 'P9_14'; // Pin to use
+var step = 0.02; // Step size
+const min = 0.02, // dimmest value
+ max = 1; // brightest value
+var brightness = min; // Current brightness;
+
+b.pinMode(LED, b.ANALOG_OUTPUT);
+setTimeout(doInterval, 200); // work-around to wait for PWM permissions
+
+console.log('Hit ^C to stop');
+
+function doInterval(err, x) {
+ if(err) {
+ console.log('err = ' + err);
+ return;
+ }
+ setInterval(fade, 20); // Step every 20 ms
+}
+
+function fade() {
+ b.analogWrite(LED, brightness);
+ brightness += step;
+ if(brightness >= max || brightness <= min) {
+ step = -1 * step;
+ }
+}
diff --git a/BeagleBone/AI/.work-in-progress/input.js b/BeagleBone/AI/.work-in-progress/input.js
new file mode 100755
index 0000000..990c142
--- /dev/null
+++ b/BeagleBone/AI/.work-in-progress/input.js
@@ -0,0 +1,36 @@
+#!/usr/bin/env node
+////////////////////////////////////////
+// input.js
+// Responds to changes on P8_18 via a callback.
+// Wiring: Connect P8_18 to P8_14 with a 1kOhm resistor.
+// Setup:
+// See:
+////////////////////////////////////////
+const b = require('bonescript');
+
+const outputPin = "P8_14";
+const inputPin = "P8_18";
+const ledPin = "USR3";
+const mydelay = 250;
+var state = b.LOW;
+
+console.log('Please connect ' + inputPin + ' to ' + outputPin +
+ ' with a 1kOhm resistor');
+b.pinMode(inputPin, b.INPUT);
+b.pinMode(outputPin, b.OUTPUT);
+b.pinMode(ledPin, b.OUTPUT);
+
+b.digitalWrite(outputPin, b.LOW);
+b.attachInterrupt(inputPin, setLED, b.CHANGE);
+
+toggle();
+
+function setLED(x) {
+ b.digitalWrite(ledPin, x.value);
+}
+
+function toggle() {
+ state = (state == b.LOW) ? b.HIGH : b.LOW;
+ b.digitalWrite(outputPin, state);
+ setTimeout(toggle, mydelay); // Waut a bit, and then toggle again
+}
diff --git a/BeagleBone/AI/.work-in-progress/input2.js b/BeagleBone/AI/.work-in-progress/input2.js
new file mode 100755
index 0000000..9a04835
--- /dev/null
+++ b/BeagleBone/AI/.work-in-progress/input2.js
@@ -0,0 +1,60 @@
+#!/usr/bin/env node
+////////////////////////////////////////
+// input2.js
+// Responds to changes on P8_19 and P9_16 via callbacks.
+// Wiring: Connect P8_19 to P9_14 with a 1kOhm resistor
+// Connect P9_15 to P9_16 with a 1kOhm resistor
+// Setup:
+// See:
+////////////////////////////////////////
+const b = require('bonescript');
+
+const outputPin = "P9_14";
+const inputPin = "P8_19";
+const outputPin2 = "P9_16";
+const inputPin2 = "P9_15";
+const ledPin = "USR3";
+const ledPin2 = "USR2";
+const mydelay = 100;
+const mydelay2 = 33;
+var toggleState = b.LOW;
+var toggleState2 = b.LOW;
+
+console.log('Please connect ' + inputPin + ' to ' + outputPin +
+ ' with a 1kOhm resistor');
+console.log('Please connect ' + inputPin2 + ' to ' + outputPin2 +
+ ' with a 1kOhm resistor');
+b.pinMode(inputPin, b.INPUT);
+b.pinMode(outputPin, b.OUTPUT);
+b.pinMode(ledPin, b.OUTPUT);
+b.pinMode(inputPin2, b.INPUT);
+b.pinMode(outputPin2, b.OUTPUT);
+b.pinMode(ledPin2, b.OUTPUT);
+
+b.digitalWrite(outputPin, b.LOW);
+b.digitalWrite(outputPin2, b.LOW);
+b.attachInterrupt(inputPin, inputHandler, b.CHANGE);
+b.attachInterrupt(inputPin2, inputHandler2, b.CHANGE);
+
+toggle();
+toggle2();
+
+function inputHandler(x) {
+ b.digitalWrite(ledPin, x.value);
+}
+
+function inputHandler2(x) {
+ b.digitalWrite(ledPin2, x.value);
+}
+
+function toggle() {
+ toggleState = (toggleState == b.LOW) ? b.HIGH : b.LOW;
+ b.digitalWrite(outputPin, toggleState);
+ setTimeout(toggle, mydelay);
+}
+
+function toggle2() {
+ toggleState2 = (toggleState2 == b.LOW) ? b.HIGH : b.LOW;
+ b.digitalWrite(outputPin2, toggleState2);
+ setTimeout(toggle2, mydelay2);
+}
diff --git a/BeagleBone/AI/README.md b/BeagleBone/AI/README.md
index 681616f..96366d5 100644
--- a/BeagleBone/AI/README.md
+++ b/BeagleBone/AI/README.md
@@ -2,11 +2,8 @@
Learn more at https://beagleboard.org/ai.
-# Directories
-
-* tidl - Learn how to use the built-in embedded machine learning accelerators.
-* pru - Learn how to use the on-board ultra-low latency PRU microcontrollers.
-
-# Issues/TODO
-* bonescript needs porting to the AI
-* analog in isn't working
+Directory | Learn how to use the ...
+---------- | -----------
+[tidl](tidl) | built-in embedded machine learning accelerators.
+[pru](pru) | on-board ultra-low latency PRU microcontrollers.
+[c66](c66) | on-board digital signal processors.
diff --git a/BeagleBone/AI/analogInCallback.js b/BeagleBone/AI/analogInCallback.js
new file mode 100755
index 0000000..2fd284c
--- /dev/null
+++ b/BeagleBone/AI/analogInCallback.js
@@ -0,0 +1,34 @@
+#!/usr/bin/env node
+////////////////////////////////////////
+// analogInCallback.js
+// Reads analog in on P9_36 and prints it via a callback.
+// Wiring: Attach the outer pins on a variable resistor to P9_32 and P9_34.
+// Attach the wiper (middle pin) of the resistor to P9_36.
+// Setup:
+// See:
+////////////////////////////////////////
+const b = require('bonescript');
+
+const inputPin = "A3";
+
+console.log('Hit ^C to stop');
+b.analogRead(inputPin, printStatus);
+
+function printStatus(err, x) {
+ if(err) {
+ console.log('Got error: ' + err);
+ return;
+ };
+ process.stdout.write(inputPin + ': ' + (x*100).toFixed(1) + '%, ' + (1.8*x).toFixed(3) + 'V \r');
+ b.analogRead(inputPin, printStatus);
+}
+
+// Bone | Pocket | AIN
+// ----- | ------ | ---
+// P9_39 | P1_19 | A0
+// P9_40 | P1_21 | A1
+// P9_37 | P1_23 | A2
+// P9_38 | P1_25 | A3
+// P9_33 | P1_27 | A4
+// P9_36 | P2_35 | A5
+// P9_35 | P1_02 | A6
diff --git a/BeagleBone/AI/analogInOut.js b/BeagleBone/AI/analogInOut.js
new file mode 100755
index 0000000..9fb40a9
--- /dev/null
+++ b/BeagleBone/AI/analogInOut.js
@@ -0,0 +1,37 @@
+#!/usr/bin/env node
+////////////////////////////////////////
+// analogInOut.js
+// Reads analog in on P9_36 and adjusts the PWM on P9_14.
+// Wiring: Attach the outer pins on a variable resistor to P9_32 and P9_34.
+// Attach the wiper (middle pin) of the resistor to P9_36.
+// P9_14 connects to the plus lead of an LED. The negative lead of the
+// LED goes to a 220 Ohm resistor. The other lead of the resistor goes
+// to ground.
+// Setup:
+// See:
+////////////////////////////////////////
+const b = require('bonescript');
+
+const inputPin = "A3";
+const outputPin = "P9_14";
+
+console.log('Hit ^C to stop');
+b.pinMode(outputPin, b.ANALOG_OUTPUT);
+setTimeout(loop, 200); // work-around to wait for PWM permissions
+
+function loop() {
+ var value = b.analogRead(inputPin);
+ process.stdout.write(inputPin + '-->' + outputPin + ': ' + (value*100).toFixed(1) + '% \r');
+ b.analogWrite(outputPin, value);
+ setTimeout(loop, 10);
+}
+
+// Bone | Pocket | AIN
+// ----- | ------ | ---
+// P9_39 | P1_19 | A0
+// P9_40 | P1_21 | A1
+// P9_37 | P1_23 | A2
+// P9_38 | P1_25 | A3
+// P9_33 | P1_27 | A4
+// P9_36 | P2_35 | A5
+// P9_35 | P1_02 | A6
diff --git a/BeagleBone/AI/analogInSync.js b/BeagleBone/AI/analogInSync.js
index b42fc09..3b3cb2c 100755
--- a/BeagleBone/AI/analogInSync.js
+++ b/BeagleBone/AI/analogInSync.js
@@ -1,15 +1,15 @@
#!/usr/bin/env node
////////////////////////////////////////
-// analog2.js
-// Reads analog in on P9_36 synchronously and prints it.
+// analogSync.js
+// Reads analog in on P9_38 synchronously and prints it.
// Wiring: Attach the outer pins on a variable resistor to P9_32 and P9_34.
-// Attach the wiper (middle pin) of the resistor to P9_36.
+// Attach the wiper (middle pin) of the resistor to P9_38.
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
+const b = require('bonescript');
-var inputPin = "P9_36";
+const inputPin = "A3";
loop();
@@ -18,3 +18,13 @@ function loop() {
process.stdout.write(inputPin + ': ' + (value*100).toFixed(1) + '%, ' + (1.8*value).toFixed(3) + 'V \r');
setTimeout(loop, 100);
}
+
+// Bone | Pocket | AIN
+// ----- | ------ | ---
+// P9_39 | P1_19 | A0
+// P9_40 | P1_21 | A1
+// P9_37 | P1_23 | A2
+// P9_38 | P1_25 | A3
+// P9_33 | P1_27 | A4
+// P9_36 | P2_35 | A5
+// P9_35 | P1_02 | A6
diff --git a/BeagleBone/AI/blinkLED.js b/BeagleBone/AI/blinkLED.js
index c0b2e12..b4edd8c 100755
--- a/BeagleBone/AI/blinkLED.js
+++ b/BeagleBone/AI/blinkLED.js
@@ -8,9 +8,9 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
+const b = require('bonescript');
-var leds = ["USR0", "USR1", "USR2", "USR3", "P9_15"];
+const leds = ["USR0", "USR1", "USR2", "USR3", "P9_15"];
for(var i in leds) {
b.pinMode(leds[i], b.OUTPUT);
diff --git a/BeagleBone/AI/c66/README.md b/BeagleBone/AI/c66/README.md
new file mode 100644
index 0000000..fa14ad8
--- /dev/null
+++ b/BeagleBone/AI/c66/README.md
@@ -0,0 +1,6 @@
+# C66 DSP programming with OpenCL
+
+See https://training.ti.com/sites/default/files/docs/Introduction_to_OpenCL_slides.pdf
+
+See also /usr/share/ti/examples/opencl
+
diff --git a/BeagleBone/AI/swipeLED.js b/BeagleBone/AI/swipeLED.js
index ad1bf7b..d6df912 100755
--- a/BeagleBone/AI/swipeLED.js
+++ b/BeagleBone/AI/swipeLED.js
@@ -6,10 +6,10 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
-var leds = ['USR0', 'USR1', 'USR2', 'USR3'];
+const b = require('bonescript');
+const leds = ['USR0', 'USR1', 'USR2', 'USR3'];
var i = 0;
-var delay = 100;
+const delay = 100;
console.log('Hit ^C to stop');
diff --git a/BeagleBone/AI/tidl/.work-in-progress/segmentation.tidl.cpp b/BeagleBone/AI/tidl/.work-in-progress/segmentation.tidl.cpp
new file mode 100644
index 0000000..675f7da
--- /dev/null
+++ b/BeagleBone/AI/tidl/.work-in-progress/segmentation.tidl.cpp
@@ -0,0 +1,320 @@
+/******************************************************************************
+ * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments Incorporated nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "executor.h"
+#include "execution_object.h"
+#include "execution_object_pipeline.h"
+#include "configuration.h"
+#include "imgutil.h"
+
+#include "opencv2/opencv.hpp"
+#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/highgui.hpp"
+#include "opencv2/videoio.hpp"
+
+#define MAX_EOPS 8
+#define MAX_CLASSES 1100
+
+using namespace tidl;
+using namespace cv;
+using namespace std;
+
+int current_eop = 0;
+int num_eops = 0;
+Configuration configuration;
+Executor *e_eve = nullptr;
+Executor *e_dsp = nullptr;
+std::vector eops;
+int last_rpt_id = -1;
+
+bool CreateExecutionObjectPipelines(uint32_t num_eves, uint32_t num_dsps,
+ uint32_t num_layers_groups);
+void AllocateMemory(const std::vector& eops);
+bool ProcessFrame(ExecutionObjectPipeline* eop, Mat &src);
+void DisplayFrame(const ExecutionObjectPipeline* eop, Mat& src, Mat& dst);
+void CreateMask(uchar *classes, uchar *mb, uchar *mg, uchar* mr,
+ int channel_size);
+
+// exports for the filter
+extern "C" {
+ bool filter_init(const char* args, void** filter_ctx);
+ void filter_process(void* filter_ctx, Mat& src, Mat& dst);
+ void filter_free(void* filter_ctx);
+}
+
+bool verbose = false;
+
+/**
+ Initializes the filter. If you return something, it will be passed to the
+ filter_process function, and should be freed by the filter_free function
+*/
+bool filter_init(const char* args, void** filter_ctx) {
+ uint32_t num_eves = 0;
+ uint32_t num_dsps = 2;
+ int num_layers_groups = 1;
+
+ std::cout << "Initializing filter" << std::endl;
+
+ std::cout << "loading configuration" << std::endl;
+ configuration.numFrames = 1;
+ configuration.preProcType = 0;
+ configuration.inData =
+ "/usr/share/ti/examples/tidl/test/testvecs/input/input/000100_1024x512_bgr.y";
+ configuration.outData =
+ "./stats_tool_out.bin";
+ configuration.netBinFile =
+ "/usr/share/ti/examples/tidl/test/testvecs/config/tidl_models/tidl_net_jsegnet21v2.bin";
+ configuration.paramsBinFile =
+ "/usr/share/ti/examples/tidl/test/testvecs/config/tidl_models/tidl_param_jsegnet21v2.bin";
+ configuration.inWidth = 1024;
+ configuration.inHeight = 512;
+ configuration.inNumChannels = 3;
+ //configuration.layerIndex2LayerGroupId = { {12, 2}, {13, 2}, {14, 2} };
+ //configuration.enableApiTrace = false;
+ //configuration.runFullNet = true;
+
+ try
+ {
+ std::cout << "allocating execution object pipelines (EOP)" << std::endl;
+
+ // Create ExecutionObjectPipelines
+ if (! CreateExecutionObjectPipelines(num_eves, num_dsps,
+ num_layers_groups))
+ return false;
+
+ // Allocate input/output memory for each EOP
+ std::cout << "allocating I/O memory for each EOP" << std::endl;
+ AllocateMemory(eops);
+ num_eops = eops.size();
+ std::cout << "num_eops=" << num_eops << std::endl;
+ std::cout << "About to start ProcessFrame loop!!" << std::endl;
+ std::cout << "http://localhost:8080/?action=stream" << std::endl;
+ }
+ catch (tidl::Exception &e)
+ {
+ std::cerr << e.what() << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ Called by the OpenCV plugin upon each frame
+*/
+void filter_process(void* filter_ctx, Mat& src, Mat& dst) {
+ try
+ {
+ // Process frames with available EOPs in a pipelined manner
+ // additional num_eops iterations to flush the pipeline (epilogue)
+ ExecutionObjectPipeline* eop = eops[current_eop];
+
+ // Wait for previous frame on the same eo to finish processing
+ //std::cout << "+" << std::endl;
+ if (eop->ProcessFrameWait())
+ {
+ //std::cout << "-" << std::endl;
+ if(configuration.enableApiTrace)
+ std::cout << "display()" << std::endl;
+ DisplayFrame(eop, src, dst);
+ }
+ else
+ {
+ //std::cout << "." << std::endl;
+ if(configuration.enableApiTrace)
+ std::cout << "copy()" << std::endl;
+ dst = src;
+ }
+
+ if(configuration.enableApiTrace)
+ std::cout << "process()" << std::endl;
+
+ ProcessFrame(eop, src);
+
+ current_eop++;
+ if(current_eop >= num_eops)
+ current_eop = 0;
+ }
+ catch (tidl::Exception &e)
+ {
+ std::cerr << e.what() << std::endl;
+ dst = src;
+ }
+
+ return;
+}
+
+/**
+ Called when the input plugin is cleaning up
+*/
+void filter_free(void* filter_ctx) {
+ try
+ {
+ // Cleanup
+ for (auto eop : eops)
+ {
+ free(eop->GetInputBufferPtr());
+ free(eop->GetOutputBufferPtr());
+ delete eop;
+ }
+ if (e_dsp) delete e_dsp;
+ if (e_eve) delete e_eve;
+ }
+ catch (tidl::Exception& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return;
+}
+
+bool CreateExecutionObjectPipelines(uint32_t num_eves, uint32_t num_dsps,
+ uint32_t num_layers_groups)
+{
+ DeviceIds ids_eve, ids_dsp;
+ for (uint32_t i = 0; i < num_eves; i++)
+ ids_eve.insert(static_cast(i));
+ for (uint32_t i = 0; i < num_dsps; i++)
+ ids_dsp.insert(static_cast(i));
+ const uint32_t buffer_factor = 1;
+
+ std::cout << "allocating executors" << std::endl;
+ e_eve = num_eves == 0 ? nullptr :
+ new Executor(DeviceType::EVE, ids_eve, configuration);
+ e_dsp = num_dsps == 0 ? nullptr :
+ new Executor(DeviceType::DSP, ids_dsp, configuration);
+
+ // Construct ExecutionObjectPipeline with single Execution Object to
+ // process each frame. This is parallel processing of frames with
+ // as many DSP and EVE cores that we have on hand.
+ // If buffer_factor == 2, duplicating EOPs for double buffering
+ // and overlapping host pre/post-processing with device processing
+ std::cout << "allocating individual EOPs" << std::endl;
+ for (uint32_t j = 0; j < buffer_factor; j++)
+ {
+ for (uint32_t i = 0; i < num_eves; i++)
+ eops.push_back(new ExecutionObjectPipeline({(*e_eve)[i]}));
+ for (uint32_t i = 0; i < num_dsps; i++)
+ eops.push_back(new ExecutionObjectPipeline({(*e_dsp)[i]}));
+ }
+
+ return true;
+}
+
+
+void AllocateMemory(const std::vector& eops)
+{
+ for (auto eop : eops)
+ {
+ size_t in_size = eop->GetInputBufferSizeInBytes();
+ size_t out_size = eop->GetOutputBufferSizeInBytes();
+ std::cout << "Allocating input and output buffers" << std::endl;
+ void* in_ptr = malloc(in_size);
+ void* out_ptr = malloc(out_size);
+ assert(in_ptr != nullptr && out_ptr != nullptr);
+
+ ArgInfo in(in_ptr, in_size);
+ ArgInfo out(out_ptr, out_size);
+ eop->SetInputOutputBuffer(in, out);
+ }
+}
+
+
+bool ProcessFrame(ExecutionObjectPipeline* eop, Mat &src)
+{
+ if(configuration.enableApiTrace)
+ std::cout << "preprocess()" << std::endl;
+ imgutil::PreprocessImage(src,
+ eop->GetInputBufferPtr(), configuration);
+ eop->ProcessFrameStartAsync();
+
+ return false;
+}
+
+
+void DisplayFrame(const ExecutionObjectPipeline* eop, Mat& src, Mat& dst)
+{
+ unsigned char *out = (unsigned char *) eop->GetOutputBufferPtr();
+ int width = configuration.inWidth;
+ int height = configuration.inHeight;
+ int channel_size = width * height;
+
+ Mat mask, frame, blend, r_blend, bgr[3];
+ // Create overlay mask
+ bgr[0] = Mat(height, width, CV_8UC(1));
+ bgr[1] = Mat(height, width, CV_8UC(1));
+ bgr[2] = Mat(height, width, CV_8UC(1));
+ CreateMask(out, bgr[0].ptr(), bgr[1].ptr(), bgr[2].ptr(), channel_size);
+ cv::merge(bgr, 3, mask);
+
+ // Asseembly original frame
+ unsigned char *in = (unsigned char *) eop.GetInputBufferPtr();
+ bgr[0] = Mat(height, width, CV_8UC(1), in);
+ bgr[1] = Mat(height, width, CV_8UC(1), in + channel_size);
+ bgr[2] = Mat(height, width, CV_8UC(1), in + channel_size*2);
+ cv::merge(bgr, 3, frame);
+
+ // Create overlayed frame
+ cv::addWeighted(frame, 0.7, mask, 0.3, 0.0, blend);
+
+ // Resize to output width/height, keep aspect ratio
+ uint32_t output_width = opts.output_width;
+ if (output_width == 0) output_width = orig_width;
+ uint32_t output_height = (output_width*1.0f) / orig_width * orig_height;
+ cv::resize(blend, r_blend, Size(output_width, output_height));
+
+ dst = r_blend;
+}
+
+// Create Overlay mask for pixel-level segmentation
+void CreateMask(uchar *classes, uchar *mb, uchar *mg, uchar* mr,
+ int channel_size)
+{
+ for (int i = 0; i < channel_size; i++)
+ {
+ const ObjectClass& object_class = object_classes->At(classes[i]);
+ mb[i] = object_class.color.blue;
+ mg[i] = object_class.color.green;
+ mr[i] = object_class.color.red;
+ }
+}
+
diff --git a/BeagleBone/AI/tidl/Makefile b/BeagleBone/AI/tidl/Makefile
index 7f38e68..35fe257 100644
--- a/BeagleBone/AI/tidl/Makefile
+++ b/BeagleBone/AI/tidl/Makefile
@@ -1,11 +1,13 @@
-all: classification.tidl.so
+all: dummy.tidl.so classification.tidl.so
include /var/lib/cloud9/common/Makefile
run:
ti-mct-heap-check -c
- mjpg_streamer -i "input_opencv.so -r 640x480 --filter ./classification.tidl.so" -o "output_http.so -p 8090 -w /usr/share/mjpg-streamer/www" 2> /dev/null
+ sudo mjpg_streamer -i "input_opencv.so -r 640x480 -d /dev/$(shell fgrep -v vpe /sys/class/video4linux/video*/name | perl -ne '/\/(video\d+)\/name/ && print $$1') --filter ./classification.tidl.so" -o "output_http.so -p 8090 -w /usr/share/mjpg-streamer/www" 2> /dev/null
clean:
+ rm -f dummy.tidl.so
rm -f classification.tidl.so
+ rm -f /tmp/cloud9-examples/classification.tidl.so || true
diff --git a/BeagleBone/AI/tidl/README.md b/BeagleBone/AI/tidl/README.md
new file mode 100644
index 0000000..c897c6a
--- /dev/null
+++ b/BeagleBone/AI/tidl/README.md
@@ -0,0 +1,25 @@
+# TI Deep Learning (TIDL) API with mjpg-streamer
+
+Demo project: https://beagleboard.org/+1ee263
+
+See https://training.ti.com/texas-instruments-deep-learning-tidl-overview
+
+See also /usr/share/ti/examples/tidl
+
+# Setup
+
+Make sure the mjpg-streamer with opencv support and TIDL library with
+examples are installed:
+
+```
+sudo apt update
+sudo apt install -y ti-tidl mjpg-streamer-opencv-python
+```
+
+# Execution notes
+
+Select the "C or C++ (Beagle Makefile)" runner in the Run Configuration window.
+
+Default user password is 'temppwd'. You'll need to type it in the Run Configuration window.
+
+You can open the viewer window using "BeagleBone->MJPG-Streamer".
diff --git a/BeagleBone/AI/tidl/classification.tidl.cpp b/BeagleBone/AI/tidl/classification.tidl.cpp
index bd31391..b87d183 100644
--- a/BeagleBone/AI/tidl/classification.tidl.cpp
+++ b/BeagleBone/AI/tidl/classification.tidl.cpp
@@ -71,11 +71,10 @@ Executor *e_dsp = nullptr;
std::vector eops;
int last_rpt_id = -1;
-bool CreateExecutionObjectPipelines(uint32_t num_eves, uint32_t num_dsps,
- uint32_t num_layers_groups);
+bool CreateExecutionObjectPipelines();
void AllocateMemory(const std::vector& eops);
bool ProcessFrame(ExecutionObjectPipeline* eop, Mat &src);
-void DisplayFrame(const ExecutionObjectPipeline* eop, Mat& src, Mat& dst);
+void DisplayFrame(const ExecutionObjectPipeline* eop, Mat& dst);
int tf_postprocess(uchar *in);
bool tf_expected_id(int id);
void populate_labels(const char* filename);
@@ -94,15 +93,11 @@ bool verbose = false;
filter_process function, and should be freed by the filter_free function
*/
bool filter_init(const char* args, void** filter_ctx) {
- uint32_t num_eves = 0;
- uint32_t num_dsps = 2;
- int num_layers_groups = 1;
-
std::cout << "Initializing filter" << std::endl;
-
- populate_labels("/home/debian/tidl-api/examples/classification/imagenet.txt");
- selected_items_size = 5;
+ populate_labels("/usr/share/ti/examples/tidl/classification/imagenet.txt");
+
+ selected_items_size = 10;
selected_items = (int *)malloc(selected_items_size*sizeof(int));
if (!selected_items) {
std::cout << "selected_items malloc failed" << std::endl;
@@ -113,17 +108,22 @@ bool filter_init(const char* args, void** filter_ctx) {
selected_items[2] = 504; /* coffee_mug */
selected_items[3] = 441; /* beer_glass */
selected_items[4] = 898; /* water_bottle */
+ selected_items[5] = 931; /* bagel */
+ selected_items[6] = 531; /* digital_watch */
+ selected_items[7] = 487; /* cellular_telephone */
+ selected_items[8] = 722; /* ping-pong_ball */
+ selected_items[9] = 720; /* pill_bottle */
std::cout << "loading configuration" << std::endl;
configuration.numFrames = 0;
configuration.inData =
- "/home/debian/tidl-api/examples/test/testvecs/input/preproc_0_224x224.y";
+ "/usr/share/ti/examples/tidl/test/testvecs/input/preproc_0_224x224.y";
configuration.outData =
- "/home/debian/tidl-api/examples/classification/stats_tool_out.bin";
+ "/usr/share/ti/examples/tidl/classification/stats_tool_out.bin";
configuration.netBinFile =
- "/home/debian/tidl-api/examples/test/testvecs/config/tidl_models/tidl_net_imagenet_jacintonet11v2.bin";
+ "/usr/share/ti/examples/tidl/test/testvecs/config/tidl_models/tidl_net_imagenet_jacintonet11v2.bin";
configuration.paramsBinFile =
- "/home/debian/tidl-api/examples/test/testvecs/config/tidl_models/tidl_param_imagenet_jacintonet11v2.bin";
+ "/usr/share/ti/examples/tidl/test/testvecs/config/tidl_models/tidl_param_imagenet_jacintonet11v2.bin";
configuration.preProcType = 0;
configuration.inWidth = 224;
configuration.inHeight = 224;
@@ -137,8 +137,7 @@ bool filter_init(const char* args, void** filter_ctx) {
std::cout << "allocating execution object pipelines (EOP)" << std::endl;
// Create ExecutionObjectPipelines
- if (! CreateExecutionObjectPipelines(num_eves, num_dsps,
- num_layers_groups))
+ if (! CreateExecutionObjectPipelines())
return false;
// Allocate input/output memory for each EOP
@@ -147,7 +146,7 @@ bool filter_init(const char* args, void** filter_ctx) {
num_eops = eops.size();
std::cout << "num_eops=" << num_eops << std::endl;
std::cout << "About to start ProcessFrame loop!!" << std::endl;
- std::cout << "http://192.168.6.2:8090/?action=stream" << std::endl;
+ std::cout << "http://localhost:8080/?action=stream" << std::endl;
}
catch (tidl::Exception &e)
{
@@ -162,6 +161,9 @@ bool filter_init(const char* args, void** filter_ctx) {
Called by the OpenCV plugin upon each frame
*/
void filter_process(void* filter_ctx, Mat& src, Mat& dst) {
+ int doDisplay = 0;
+ dst = src;
+
try
{
// Process frames with available EOPs in a pipelined manner
@@ -169,27 +171,11 @@ void filter_process(void* filter_ctx, Mat& src, Mat& dst) {
ExecutionObjectPipeline* eop = eops[current_eop];
// Wait for previous frame on the same eo to finish processing
- //std::cout << "+" << std::endl;
- if (eop->ProcessFrameWait())
- {
- //std::cout << "-" << std::endl;
- if(configuration.enableApiTrace)
- std::cout << "display()" << std::endl;
- DisplayFrame(eop, src, dst);
- }
- else
- {
- //std::cout << "." << std::endl;
- if(configuration.enableApiTrace)
- std::cout << "copy()" << std::endl;
- dst = src;
- }
-
- if(configuration.enableApiTrace)
- std::cout << "process()" << std::endl;
+ if(eop->ProcessFrameWait()) doDisplay = 1;
ProcessFrame(eop, src);
-
+ if(doDisplay) DisplayFrame(eop, dst);
+
current_eop++;
if(current_eop >= num_eops)
current_eop = 0;
@@ -197,7 +183,6 @@ void filter_process(void* filter_ctx, Mat& src, Mat& dst) {
catch (tidl::Exception &e)
{
std::cerr << e.what() << std::endl;
- dst = src;
}
return;
@@ -227,17 +212,43 @@ void filter_free(void* filter_ctx) {
return;
}
-bool CreateExecutionObjectPipelines(uint32_t num_eves, uint32_t num_dsps,
- uint32_t num_layers_groups)
+bool CreateExecutionObjectPipelines()
{
+ const uint32_t num_eves = 4;
+ const uint32_t num_dsps = 0;
+ const uint32_t buffer_factor = 1;
+
DeviceIds ids_eve, ids_dsp;
for (uint32_t i = 0; i < num_eves; i++)
ids_eve.insert(static_cast(i));
for (uint32_t i = 0; i < num_dsps; i++)
ids_dsp.insert(static_cast(i));
- const uint32_t buffer_factor = 1;
+#if 0
+ // Create Executors with the approriate core type, number of cores
+ // and configuration specified
+ // EVE will run layersGroupId 1 in the network, while
+ // DSP will run layersGroupId 2 in the network
std::cout << "allocating executors" << std::endl;
+ e_eve = num_eves == 0 ? nullptr :
+ new Executor(DeviceType::EVE, ids_eve, configuration, 1);
+ e_dsp = num_dsps == 0 ? nullptr :
+ new Executor(DeviceType::DSP, ids_dsp, configuration, 2);
+
+ // Construct ExecutionObjectPipeline that utilizes multiple
+ // ExecutionObjects to process a single frame, each ExecutionObject
+ // processes one layerGroup of the network
+ // If buffer_factor == 2, duplicating EOPs for pipelining at
+ // EO level rather than at EOP level, in addition to double buffering
+ // and overlapping host pre/post-processing with device processing
+ std::cout << "allocating individual EOPs" << std::endl;
+ for (uint32_t j = 0; j < buffer_factor; j++)
+ {
+ for (uint32_t i = 0; i < std::max(num_eves, num_dsps); i++)
+ eops.push_back(new ExecutionObjectPipeline(
+ {(*e_eve)[i%num_eves], (*e_dsp)[i%num_dsps]}));
+ }
+#else
e_eve = num_eves == 0 ? nullptr :
new Executor(DeviceType::EVE, ids_eve, configuration);
e_dsp = num_dsps == 0 ? nullptr :
@@ -248,7 +259,6 @@ bool CreateExecutionObjectPipelines(uint32_t num_eves, uint32_t num_dsps,
// as many DSP and EVE cores that we have on hand.
// If buffer_factor == 2, duplicating EOPs for double buffering
// and overlapping host pre/post-processing with device processing
- std::cout << "allocating individual EOPs" << std::endl;
for (uint32_t j = 0; j < buffer_factor; j++)
{
for (uint32_t i = 0; i < num_eves; i++)
@@ -256,6 +266,7 @@ bool CreateExecutionObjectPipelines(uint32_t num_eves, uint32_t num_dsps,
for (uint32_t i = 0; i < num_dsps; i++)
eops.push_back(new ExecutionObjectPipeline({(*e_dsp)[i]}));
}
+#endif
return true;
}
@@ -291,9 +302,8 @@ bool ProcessFrame(ExecutionObjectPipeline* eop, Mat &src)
}
-void DisplayFrame(const ExecutionObjectPipeline* eop, Mat& src, Mat& dst)
+void DisplayFrame(const ExecutionObjectPipeline* eop, Mat& dst)
{
- dst = src;
if(configuration.enableApiTrace)
std::cout << "postprocess()" << std::endl;
int is_object = tf_postprocess((uchar*) eop->GetOutputBufferPtr());
@@ -339,7 +349,7 @@ int tf_postprocess(uchar *in)
int rpt_id = -1;
typedef std::pair val_index;
- auto constexpr cmp = [](val_index &left, val_index &right) { return left.first > right.first; };
+ auto cmp = [](val_index &left, val_index &right) { return left.first > right.first; };
std::priority_queue, decltype(cmp)> queue(cmp);
// initialize priority queue with smallest value on top
for (int i = 0; i < k; i++) {
@@ -391,7 +401,7 @@ void populate_labels(const char* filename)
}
file.close();
}
-#if 1
+#if 0
std::cout << "==Total of " << size << " items!" << std::endl;
for (int i = 0; i < size; i ++)
std::cout << i << ") " << *(labels_classes[i]) << std::endl;
diff --git a/BeagleBone/AI/tidl/dummy.tidl.cpp b/BeagleBone/AI/tidl/dummy.tidl.cpp
new file mode 100644
index 0000000..4ad8c53
--- /dev/null
+++ b/BeagleBone/AI/tidl/dummy.tidl.cpp
@@ -0,0 +1,33 @@
+// dummy.tidl.cpp - empty filter to test mjpg-streamer only
+#include "opencv2/opencv.hpp"
+#include "opencv2/core.hpp"
+
+// exports for the filter
+extern "C" {
+ bool filter_init(const char* args, void** filter_ctx);
+ void filter_process(void* filter_ctx, cv::Mat& src, cv::Mat& dst);
+ void filter_free(void* filter_ctx);
+}
+
+/**
+ Initializes the filter. If you return something, it will be passed to the
+ filter_process function, and should be freed by the filter_free function
+*/
+bool filter_init(const char* args, void** filter_ctx) {
+ return true;
+}
+
+/**
+ Called by the OpenCV plugin upon each frame
+*/
+void filter_process(void* filter_ctx, cv::Mat& src, cv::Mat& dst) {
+ dst = src;
+ return;
+}
+
+/**
+ Called when the input plugin is cleaning up
+*/
+void filter_free(void* filter_ctx) {
+ return;
+}
diff --git a/BeagleBone/Black/notWorking/Blink.ino b/BeagleBone/Black/.work-in-progress/Blink.ino
similarity index 100%
rename from BeagleBone/Black/notWorking/Blink.ino
rename to BeagleBone/Black/.work-in-progress/Blink.ino
diff --git a/BeagleBone/Black/.work-in-progress/README.md b/BeagleBone/Black/.work-in-progress/README.md
new file mode 100644
index 0000000..c43f669
--- /dev/null
+++ b/BeagleBone/Black/.work-in-progress/README.md
@@ -0,0 +1,11 @@
+Not Working or not able to test:
+```
+Blink.ino
+blinky.rb // -- beaglebone/spi (LoadError)
+pwmTest.sh
+shiftout.js // Demonstrate shiftOut with a 7 segment display
+
+pushbutton.js
+sensorTag.js
+servoMotor.js
+```
diff --git a/BeagleBone/Black/notWorking/blinky.rb b/BeagleBone/Black/.work-in-progress/blinky.rb
similarity index 100%
rename from BeagleBone/Black/notWorking/blinky.rb
rename to BeagleBone/Black/.work-in-progress/blinky.rb
diff --git a/BeagleBone/Black/notWorking/pwmTest.sh b/BeagleBone/Black/.work-in-progress/pwmTest.sh
similarity index 100%
rename from BeagleBone/Black/notWorking/pwmTest.sh
rename to BeagleBone/Black/.work-in-progress/pwmTest.sh
diff --git a/BeagleBone/Black/notWorking/shiftout.js b/BeagleBone/Black/.work-in-progress/shiftout.js
similarity index 100%
rename from BeagleBone/Black/notWorking/shiftout.js
rename to BeagleBone/Black/.work-in-progress/shiftout.js
diff --git a/BeagleBone/Black/README.md b/BeagleBone/Black/README.md
index 8028d4b..615f7e3 100644
--- a/BeagleBone/Black/README.md
+++ b/BeagleBone/Black/README.md
@@ -1,42 +1,22 @@
This folder contains live demos that run on the BeagleBone Black.
Cookbook - contains support material for [BeagleBone Cookbook:
-Software and Hardware Problems and Solutions](http://shop.oreilly.com/product/0636920033899.do) published by O'Reilly Media.
+Software and Hardware Problems and Solutions](http:|shop.oreilly.com/product/0636920033899.do) published by O'Reilly Media.
pru - contains demos for the Programmable Real-time Unit
-Notes:
-I'm using P9_14 for the PRU, so we need to find another GPIO to use
-
-blink.c compiles/runs from command line but get the following from c9:
-Compiling /var/lib/cloud9/BeagleBone/Black/blink.c ...
-
-cc blink.c -o blink
-ERROR while launching the debugger:
- "gdbserver" is not installed
-gbdserver IS installed
-
The following files are:
-```
-analogInOut.js // Reads analog in on P9_36 and adjusts the PWM on P9_14.
-analogInSync.js // Reads analog in on P9_36 synchronously and prints it.
-analogInCallback.js // Reads analog in on P9_36 and prints it via a callback.
-blinkLED.c // Blinks the USR3 LED via c
-blinkLED.js // Blinks the USR LEDs and P9_14
-blinkLED.py // Blinks one LED wired to P9_14 via python
-fadeLED.js // Fades the LED wired to P9_14 using the PWM.
-input.js // Responds to changes on P8_19 via a callback.
-input2.js // Responds to changes on P8_19 and P9_16 via callbacks.
-swipeLED.js // Blinks the USR LEDs in sequence.
-```
-Not Working or not able to test:
-```
-Blink.ino
-blinky.rb // -- beaglebone/spi (LoadError)
-pwmTest.sh
-shiftout.js // Demonstrate shiftOut with a 7 segment display
-pushbutton.js
-sensorTag.js
-servoMotor.js
-```
+File | Description
+---- | -----------
+[analogInOut.js](analogInOut.js) | Reads analog in and adjusts the PWM.
+[analogInSync.js](nalogInSync.js) | Reads analog in synchronously and prints it.
+[analogInCallback.js](analogInCallback.js) | Reads analog in and prints it via a callback.
+[blinkLED.c](blinkLED.c ) | Blinks the USR3 LED via c.
+[blinkLED.js](blinkLED.js) | Blinks the USR LEDs and P9_14.
+[blinkLED.py](blinkLED.py) | Blinks one LED via python.
+[fadeLED.js](fadeLED.js) | Fades the LED using the PWM.
+[input.js](input.js) | Responds to changes on input via a callback.
+[input2.js](input2.js) | Responds to changes on 2 inputs via callbacks.
+[seqLED.py](seqLED.py) | Blinks the USR LEDs in sequence in python.
+[swipeLED.js](swipeLED.js) | Blinks the USR LEDs in sequence.
diff --git a/BeagleBone/Black/analogInCallback.js b/BeagleBone/Black/analogInCallback.js
index d2d3baa..e64f165 100755
--- a/BeagleBone/Black/analogInCallback.js
+++ b/BeagleBone/Black/analogInCallback.js
@@ -7,9 +7,9 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
+const b = require('bonescript');
-var inputPin = "A5";
+const inputPin = "A5";
console.log('Hit ^C to stop');
b.analogRead(inputPin, printStatus);
diff --git a/BeagleBone/Black/analogInOut.js b/BeagleBone/Black/analogInOut.js
index cb7d115..9fb40a9 100755
--- a/BeagleBone/Black/analogInOut.js
+++ b/BeagleBone/Black/analogInOut.js
@@ -1,6 +1,6 @@
#!/usr/bin/env node
////////////////////////////////////////
-// analog.js
+// analogInOut.js
// Reads analog in on P9_36 and adjusts the PWM on P9_14.
// Wiring: Attach the outer pins on a variable resistor to P9_32 and P9_34.
// Attach the wiper (middle pin) of the resistor to P9_36.
@@ -10,10 +10,10 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
+const b = require('bonescript');
-var inputPin = "A5";
-var outputPin = "P9_14";
+const inputPin = "A3";
+const outputPin = "P9_14";
console.log('Hit ^C to stop');
b.pinMode(outputPin, b.ANALOG_OUTPUT);
diff --git a/BeagleBone/Black/analogInSync.js b/BeagleBone/Black/analogInSync.js
index e6fa8d3..3b3cb2c 100755
--- a/BeagleBone/Black/analogInSync.js
+++ b/BeagleBone/Black/analogInSync.js
@@ -1,15 +1,15 @@
#!/usr/bin/env node
////////////////////////////////////////
-// analog2.js
-// Reads analog in on P9_36 synchronously and prints it.
+// analogSync.js
+// Reads analog in on P9_38 synchronously and prints it.
// Wiring: Attach the outer pins on a variable resistor to P9_32 and P9_34.
-// Attach the wiper (middle pin) of the resistor to P9_36.
+// Attach the wiper (middle pin) of the resistor to P9_38.
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
+const b = require('bonescript');
-var inputPin = "A5";
+const inputPin = "A3";
loop();
diff --git a/BeagleBone/Black/blinkLED.js b/BeagleBone/Black/blinkLED.js
index 9e2e1c1..f468c7e 100755
--- a/BeagleBone/Black/blinkLED.js
+++ b/BeagleBone/Black/blinkLED.js
@@ -8,9 +8,9 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
+const b = require('bonescript');
-var leds = ["USR0", "USR1", "USR2", "USR3", "P9_14"];
+const leds = ["USR0", "USR1", "USR2", "USR3", "P9_14"];
for(var i in leds) {
b.pinMode(leds[i], b.OUTPUT);
diff --git a/BeagleBone/Black/fadeLED.js b/BeagleBone/Black/fadeLED.js
index 0da3c36..91aeab1 100755
--- a/BeagleBone/Black/fadeLED.js
+++ b/BeagleBone/Black/fadeLED.js
@@ -8,12 +8,12 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
-var LED = 'P9_14'; // Pin to use
-var step = 0.02, // Step size
- min = 0.02, // dimmest value
- max = 1, // brightest value
- brightness = min; // Current brightness;
+const b = require('bonescript');
+const LED = 'P9_14'; // Pin to use
+var step = 0.02; // Step size
+const min = 0.02, // dimmest value
+ max = 1; // brightest value
+var brightness = min; // Current brightness;
b.pinMode(LED, b.ANALOG_OUTPUT);
setTimeout(doInterval, 200); // work-around to wait for PWM permissions
diff --git a/BeagleBone/Black/input.js b/BeagleBone/Black/input.js
index 05a33a7..ff982eb 100755
--- a/BeagleBone/Black/input.js
+++ b/BeagleBone/Black/input.js
@@ -6,12 +6,12 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
+const b = require('bonescript');
-var outputPin = "P9_14";
-var inputPin = "P8_19";
-var ledPin = "USR3";
-var mydelay = 250;
+const outputPin = "P9_14";
+const inputPin = "P8_19";
+const ledPin = "USR3";
+const mydelay = 250;
var state = b.LOW;
console.log('Please connect ' + inputPin + ' to ' + outputPin +
diff --git a/BeagleBone/Black/input2.js b/BeagleBone/Black/input2.js
index e16da80..9a04835 100755
--- a/BeagleBone/Black/input2.js
+++ b/BeagleBone/Black/input2.js
@@ -7,16 +7,16 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
-
-var outputPin = "P9_14";
-var inputPin = "P8_19";
-var outputPin2 = "P9_16";
-var inputPin2 = "P9_15";
-var ledPin = "USR3";
-var ledPin2 = "USR2";
-var mydelay = 100;
-var mydelay2 = 33;
+const b = require('bonescript');
+
+const outputPin = "P9_14";
+const inputPin = "P8_19";
+const outputPin2 = "P9_16";
+const inputPin2 = "P9_15";
+const ledPin = "USR3";
+const ledPin2 = "USR2";
+const mydelay = 100;
+const mydelay2 = 33;
var toggleState = b.LOW;
var toggleState2 = b.LOW;
diff --git a/BeagleBone/Black/seqLEDs.py b/BeagleBone/Black/seqLEDs.py
new file mode 100755
index 0000000..fe8fdd3
--- /dev/null
+++ b/BeagleBone/Black/seqLEDs.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# ////////////////////////////////////////
+# // seqLED.py
+# // Blinks the USR LEDs in sequence.
+# // Wiring:
+# // Setup:
+# // See:
+# ////////////////////////////////////////
+import Adafruit_BBIO.GPIO as GPIO
+import time
+
+LEDs=4
+
+for i in range(LEDs):
+ GPIO.setup("USR%d" % i, GPIO.OUT)
+
+while True:
+ for i in range(LEDs):
+ GPIO.output("USR%d" % i, GPIO.HIGH)
+ time.sleep(0.25)
+ for i in range(LEDs):
+ GPIO.output("USR%d" % i, GPIO.LOW)
+ time.sleep(0.25)
\ No newline at end of file
diff --git a/BeagleBone/Black/swipeLED.js b/BeagleBone/Black/swipeLED.js
index ad1bf7b..d6df912 100755
--- a/BeagleBone/Black/swipeLED.js
+++ b/BeagleBone/Black/swipeLED.js
@@ -6,10 +6,10 @@
// Setup:
// See:
////////////////////////////////////////
-var b = require('bonescript');
-var leds = ['USR0', 'USR1', 'USR2', 'USR3'];
+const b = require('bonescript');
+const leds = ['USR0', 'USR1', 'USR2', 'USR3'];
var i = 0;
-var delay = 100;
+const delay = 100;
console.log('Hit ^C to stop');
diff --git a/BeagleBone/Blue/EduMIP/python/README.md b/BeagleBone/Blue/EduMIP/python/README.md
index adae64a..75ef8d7 100644
--- a/BeagleBone/Blue/EduMIP/python/README.md
+++ b/BeagleBone/Blue/EduMIP/python/README.md
@@ -9,15 +9,19 @@ The following are python3 examples that run on the

The following use the [Adafruit BeagleBone python library](https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/overview).
-```
-internalLED.py // Blink an interal LED
-button.py // Read the PAUSE button and flash an internal LED
-seqLEDs.py // Flashes the four USR LEDs in sequence
-```
+
+File | Description
+---- | -----------
+internalLED.py | Blink an interal LED
+button.py | Read the PAUSE button and flash an internal LED
+seqLEDs.py | Flashes the four USR LEDs in sequence
+
These use the Strawson Design [Robotics Cape library](http://strawsondesign.com/#!manual-install).
-```
-encoders.py // Reads the motors encoders and displays the position
-imu.py // Read the Inertial Measurement Unit and displays the Acceraltion, Gyro, Compas and Temerature.
-motors.py // pins the motors
-balance.py // Balances the robot. Use the arrow keys to drive around
-```
+
+File | Description
+---- | -----------
+encoders.py | Reads the motors encoders and displays the position
+imu.py | Read the Inertial Measurement Unit and displays the Acceraltion, Gyro, Compas and Temerature.
+motors.py | pins the motors
+balance.py | Balances the robot. Use the arrow keys to drive around
+
diff --git a/BeagleBone/README.md b/BeagleBone/README.md
index 04a7e07..5f973f1 100644
--- a/BeagleBone/README.md
+++ b/BeagleBone/README.md
@@ -2,5 +2,9 @@ This folder contains live demos that run on the various BeagleBones.
Pick the folder corresponding to your Beagle and try them out.
-The "Black" folder has demos that run on the Black and Green and the wireless
-versions.
+Folder | Description
+------ | -----------
+[AI](AI) | Demos for the [BeagleBone AI](https://beagleboard.org/ai)
+Black | Has demos that run on the Black and Green and the wireless versions
+Blue | Examples for [EduMIP Robot](http://www.strawsondesign.com)
+Green | Uses the [Grove](https://www.seeedstudio.com/category/Grove-c-1003.html) system for interfacing devices
diff --git a/Introduction.md b/Introduction.md
new file mode 100644
index 0000000..17d8ba2
--- /dev/null
+++ b/Introduction.md
@@ -0,0 +1,28 @@
+
+# Please upgrade your software
+
+Visit [bbb.io/upgrade](https://beagleboard.org/upgrade) to learn how
+
+## Need to connect to a WiFi access point first?
+Use the command-line terminal block below to run the commands in bold, modifying as appropriate for your network.
+
+
+debian@beaglebone:/var/lib/cloud9$ sudo connmanctl⏎
+[sudo] password for debian: temppwd⏎
+connmanctl> scan wifi⏎
+Scan completed for wifi
+connmanctl> services⏎
+ MyWifi wifi_1234567890_1234567890123456_managed_psk
+connmanctl> agent on⏎
+Agent registered
+connmanctl> connect wifi_1234567890_1234567890123456_managed_psk⏎
+Agent RequestInput wifi_1234567890_1234567890123456_managed_psk
+ Passphrase = [ Type=psk, Requirement=mandatory, Alternates=[ WPS ] ]
+ WPS = [ Type=wpspin, Requirement=alternate ]
+Passphrase? MySecretPassphrase⏎
+Connected wifi_1234567890_1234567890123456_managed_psk
+connmanctl> quit⏎
+debian@beaglebone:/var/lib/cloud9$
+
+
+Now you can click [bbb.io/upgrade](https://beagleboard.org/upgrade)
diff --git a/PocketBeagle/Grove/ADC.py b/PocketBeagle/Grove/ADC.py
new file mode 100644
index 0000000..c2fc3e9
--- /dev/null
+++ b/PocketBeagle/Grove/ADC.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+import iio
+import time
+class ADC:
+ """ADC of PocketBeagle"""
+ def __init__(self):
+ """Initialize the ADC of PocketBeagle using iio python library
+ """
+ self.AIN = []
+ #Scan the ADC of PocketBeagle by using IIO python library
+ self.contexts = iio.scan_contexts()
+ self.ctx = iio.Context("local:")
+ for dev in self.ctx.devices:
+ if 'adc.0.auto' in dev.name:
+ self.name = dev.name
+ self.dev = self.ctx.find_device(self.name)
+ if not self.dev:
+ print("maybe you should reinstall the driver of ADC")
+ return
+ #Integrate all channels to self.AIN
+ self.AIN.append(self.dev.find_channel("voltage0", False))
+ self.AIN.append(self.dev.find_channel("voltage1", False))
+ self.AIN.append(self.dev.find_channel("voltage2", False))
+ self.AIN.append(self.dev.find_channel("voltage3", False))
+ self.AIN.append(self.dev.find_channel("voltage4", False))
+ self.AIN.append(self.dev.find_channel("voltage5", False))
+ self.AIN.append(self.dev.find_channel("voltage6", False))
+ self.AIN.append(self.dev.find_channel("voltage7", False))
+ def get(self, n):
+ """Get ADC's data
+ n:The channel of ADC(0~7)
+ return: data of ADC[n]
+ """
+ return int(self.AIN[n].attrs["raw"].value)
+def main():
+ AIN = ADC()
+ while True:
+ for i in range(8):
+ x = AIN.get(i)
+ print('%04d ' % (x), end='')
+ print('\r', end='')
+ time.sleep(0.1)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Accelerometer.py b/PocketBeagle/Grove/Accelerometer.py
new file mode 100644
index 0000000..f185e88
--- /dev/null
+++ b/PocketBeagle/Grove/Accelerometer.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - 3 Axis Digital Accelerometer]
+# (http://wiki.seeedstudio.com/Grove-3-Axis_Digital_Accelerometer-16g/) on I2C2
+import time
+from Shell import ReinstallModule,InstallDTBO
+import os
+import iio
+import math
+class ADX134X:
+ """ADXL345 triple-axis accelerometer."""
+ def __init__(self):
+ """Initialize the ADXL345 accelerometer using iio python library
+ """
+ self._Acceleration_xyz = []
+ self.data_x = [0] * 5
+ self.data_y = [0] * 5
+ self.data_z = [0] * 5
+ self.Path = '/proc/device-tree/aliases/adxl345'
+ try:
+ # Check BB-I2C2-ADXL34X whether install successfully
+ # if not reinstall it
+ if not os.path.exists(self.Path):
+ InstallDTBO('BB-I2C2-ADXL34X')
+ while not os.path.exists(self.Path):
+ time.sleep(0.1)
+ # Reinstall adxl345_xxx module to support hot plug
+ ReinstallModule('adxl345_i2c')
+ # Scan the adxl345 by using IIO python library
+ self.contexts = iio.scan_contexts()
+ self.ctx = iio.Context("local:")
+ self.dev = self.ctx.find_device("adxl345")
+ # Initialize the data of adxl345 for SlidingAverage function
+ self._Acceleration_xyz.append(self.dev.find_channel("accel_x", False))
+ self._Acceleration_xyz.append(self.dev.find_channel("accel_y", False))
+ self._Acceleration_xyz.append(self.dev.find_channel("accel_z", False))
+ for i in range(5):
+ self.data_x[i] = int(self._Acceleration_xyz[0].attrs["raw"].value)
+ self.data_y[i] = int(self._Acceleration_xyz[1].attrs["raw"].value)
+ self.data_z[i] = int(self._Acceleration_xyz[2].attrs["raw"].value)
+ except IOError as err:
+ print("File Error:"+str(err))
+ print("maybe you should reinstall the driver of adxl345")
+ def SlidingAverage(self,inputs,n,per):
+ """Sliding filter algorithm for adxl345 to make data smooth
+ inputs:raw data of adxl345
+ n:The axis of adxl345(0 = X 1 = Y 2 = Z)
+ per:The times of Sliding
+ return:data that more than raw data smooth
+ """
+ sum = 0
+ # Slide data to out
+ inputs.remove(inputs[0])
+ # Slide data to in
+ inputs.append(int(self._Acceleration_xyz[n].attrs["raw"].value))
+ # Get average
+ for i in range(per):
+ sum = sum + inputs[i]
+ return (sum // per)
+ def MotionDetection(self):
+ """ Simple gesture detection for adxl345
+ return: Which of the six sides is adxl345 on
+ """
+ data = [0]*3
+ #Make data of adxl345 smooth
+ x = self.SlidingAverage(self.data_x,0,5)
+ y = self.SlidingAverage(self.data_y,1,5)
+ z = self.SlidingAverage(self.data_z,2,5)
+ #Set data to angle
+ data[2] = math.atan2(z,math.sqrt((x*x+y*y)))
+ data[0] = math.atan2(x,math.sqrt((z*z+y*y)))
+ data[1] = math.atan2(y,math.sqrt((z*z+x*x)))
+ data[2] = int(data[2] / math.pi*180)
+ data[0] = int(data[0] / math.pi*180)
+ data[1] = int(data[1] / math.pi*180)
+ print(data)
+ # Get which one of six sides
+ if abs(data[2] - 90) < 10:
+ return 1
+ elif abs(data[2] - 90) > 165 :
+ return 4
+ elif abs(data[0] - 90) < 10:
+ return 2
+ elif abs(data[0] - 90) > 170 :
+ return 5
+ elif abs(data[1] - 90) < 10:
+ return 3
+ elif abs(data[1] - 90) > 175:
+ return 6
+ else :
+ return 0
+def main():
+ Adx134x = ADX134X()
+ while True:
+ print(Adx134x.MotionDetection(),end= ' \r')
+ time.sleep(0.5)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Button.py b/PocketBeagle/Grove/Button.py
new file mode 100644
index 0000000..726e1d3
--- /dev/null
+++ b/PocketBeagle/Grove/Button.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - Button](http://wiki.seeedstudio.com/Grove-Button/) on UART4
+# [Grove - Button](http://wiki.seeedstudio.com/Grove-Button/) on A5
+import time
+from Shell import InstallDTBO,ConfigGPIO,GetCmdReturn
+import os
+import evdev
+class BUTTON:
+ def __init__(self):
+ """Initialize the BUTTON using evdev python library"""
+ self.Path = '/proc/device-tree/gpio_keys/grove_button_1057_0@0'
+ try:
+ # Config p2_35 and p2_05 to GPIO mode
+ ConfigGPIO('P2_35')
+ ConfigGPIO('P2_05')
+ # Check BB-GPIO-GROVE-BUTTON whether install successfully
+ # if not reinstall it
+ if not os.path.exists(self.Path):
+ InstallDTBO('BB-GPIO-GROVE-BUTTON')
+ while not os.path.exists(self.Path):
+ time.sleep(0.1)
+ #Input Button using evdev python library
+ try:
+ self.button = evdev.InputDevice("/dev/input/event1")
+ except IOError as err:
+ GetCmdReturn('sudo chmod 777 /dev/input/event1')
+ self.button = evdev.InputDevice("/dev/input/event1")
+ except IOError as err:
+ print("File Error:"+str(err))
+ print("maybe you should reinstall the driver of button")
+ def GetKeyStatus(self):
+ """Get two button's Value
+ return:[](Button isn't pressed),[256],[257](Button is pressed)
+ """
+ return self.button.active_keys()
+ def read_loop(self):
+ """Read two button's status constantly
+ return:two button's status
+ """
+ return self.button.read_loop()
+def main():
+ d = BUTTON()
+ for event in d.read_loop():
+ if event.type == evdev.ecodes.EV_KEY:
+ print(d.GetKeyStatus())
+ print(evdev.categorize(event))
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Captouch.py b/PocketBeagle/Grove/Captouch.py
new file mode 100644
index 0000000..c26043e
--- /dev/null
+++ b/PocketBeagle/Grove/Captouch.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - 12 Key Capacitive I2C Touch Sensor V2]
+# (http://wiki.seeedstudio.com/Grove-12_Key_Capacitive_I2C_Touch_Sensor_V2-MPR121/) on I2C2
+import time
+from Shell import ReinstallModule,InstallDTBO,GetCmdReturn
+import os
+class MPR121:
+ """MPR121 12 Key Capacitive I2C Touch Sensor"""
+ def __init__(self):
+ """Initialize the MPR121 using file python library"""
+ self.Path = '/proc/device-tree/aliases/mpr121'
+ self.Mpr121Init = '/sys/bus/i2c/drivers/mpr121/2-005b/mpr121_init'
+ self.Mpr121Data = '/sys/bus/i2c/drivers/mpr121/2-005b/mpr121_data'
+ try:
+ # Check BB-I2C2-mpr121 whether install successfully
+ # if not reinstall it
+ if not os.path.exists(self.Path):
+ InstallDTBO('BB-I2C2-mpr121')
+ while not os.path.exists(self.Path):
+ time.sleep(0.1)
+ #Reinstall mpr121 module to support hot plug
+ ReinstallModule('mpr121')
+ if not os.path.exists(self.Mpr121Init):
+ ReinstallModule('mpr121')
+ #Enable mpr121
+ GetCmdReturn('sudo chmod 777 %s'%self.Mpr121Init)
+ GetCmdReturn('echo 1 > %s'%self.Mpr121Init)
+ #Open the mpr121_data using file python library
+ self.f = open(self.Mpr121Data, 'r')
+ except IOError as err:
+ print("File Error:"+str(err))
+ print("maybe you should reinstall the driver of mpr121")
+ def parse_and_print_Input(self,Input):
+ """Parse the raw data form MPR121 to List
+ that describes which one is touched on
+ 12 Key Capacitive I2C Touch Sensor.
+ Input:raw data form MPR121
+ return:List that describes which one is touched on
+ 12 Key Capacitive I2C Touch Sensor.
+ """
+ CHANNEL_NUM = 12
+ InputStr = [1, 1, 1]
+ TouchValue = [0]*CHANNEL_NUM
+ #Parse the raw data form MPR121 to List,if MPR121 is touched.
+ if Input != 0:
+ # Set raw data to decimal
+ Input = Input % 1000
+ InputStr[0] = Input // 100
+ InputStr[1] = Input % 100 // 10
+ InputStr[2] = Input % 100 % 10
+ Input = InputStr[0] * (1<<8) | InputStr[1] * (1<<4) | InputStr[2]
+ # Set to decimal to List
+ for i in range(CHANNEL_NUM):
+ if(Input & 1 << i):
+ if(0 == TouchValue[i]):
+ TouchValue[i] = 1
+ else:
+ if(1 == TouchValue[i]):
+ TouchValue[i] = 0
+ return TouchValue
+ def get(self):
+ """Get the raw data form MPR121
+ return:Raw data form MPR121
+ """
+ value = 0
+ try:
+ self.f.seek(0)
+ text = self.f.readlines()
+ try:
+ if(len(text)>=1):
+ value = int(text[0].strip('\n'))
+ except IndexError as err:
+ print("Bug!")
+ except ValueError as err:
+ print("Multi-touch is not supported")
+ except IOError as err:
+ print("File Error:"+str(err))
+ print("maybe you should reinstall the driver of mpr121")
+ return [value, self.parse_and_print_Input(value)]
+def main():
+ t = MPR121()
+ while True:
+ print(t.get(), end = ' \r')
+ time.sleep(0.05)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Control_the_Light.py b/PocketBeagle/Grove/Control_the_Light.py
new file mode 100644
index 0000000..d69c0a2
--- /dev/null
+++ b/PocketBeagle/Grove/Control_the_Light.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - Slide Potentiometer](https://www.seeedstudio.com/Grove-Slide-Potentiometer.html)
+# on A0
+# [Grove - Rotary Angle Sensor](http://wiki.seeedstudio.com/Grove-Rotary_Angle_Sensor/)
+# on A5
+# [Grove - Chainable RGB LED](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/) on A2
+# [Grove - 16x2 LCD](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/) on I2C1
+import time
+from ADC import ADC
+from RGBLed import P981X
+from LCD import JHD1802
+def main():
+ AIN = ADC()
+ LED = P981X()
+ Display = JHD1802()
+ while True:
+ Rainbow = [[1,0,0],[1,0.5,0],[1,1,0],[0,1,0],[0,1,1],[0,0,1],[1,0,1]]
+ SlidePotentiometerData = AIN.get(0)
+ RotaryAngleData = AIN.get(5)
+ #Scale down the value of ADC to 0~255
+ SlidePotentiometerData = int(SlidePotentiometerData)*255//3800
+ RotaryAngleData = int(RotaryAngleData)*255//3800
+ if RotaryAngleData > 240:
+ RotaryAngleData = 240
+ if SlidePotentiometerData > 255 :
+ SlidePotentiometerData = 255
+ print("SlidePotentiometerData is %3d RotaryAngleData is %3d \r" %
+ (SlidePotentiometerData, RotaryAngleData), end = '')
+ #Display the Slide Potentiometer Data and Rotary Angle Data on LCD
+ Display.SetText("Slider is %03d\nRotary is %03d" \
+ % (SlidePotentiometerData, RotaryAngleData))
+ #Get the Rainbow Index by Rotary Angle
+ RainbowIndex = RotaryAngleData//40
+ #Set the brightness of LED by Slide Potentiometer
+ for i in range(len(Rainbow[RainbowIndex])):
+ Rainbow[RainbowIndex][i] = Rainbow[RainbowIndex][i] * SlidePotentiometerData
+ #Light up the LED
+ LED.set(0,Rainbow[RainbowIndex][0],Rainbow\
+ [RainbowIndex][1],Rainbow[RainbowIndex][2])
+ LED.set(1,Rainbow[RainbowIndex][0],Rainbow\
+ [RainbowIndex][1],Rainbow[RainbowIndex][2])
+ time.sleep(0.1)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/KeyBoard_Player.py b/PocketBeagle/Grove/KeyBoard_Player.py
new file mode 100644
index 0000000..87a575b
--- /dev/null
+++ b/PocketBeagle/Grove/KeyBoard_Player.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - 12 Key Capacitive I2C Touch Sensor V2]
+# (http://wiki.seeedstudio.com/Grove-12_Key_Capacitive_I2C_Touch_Sensor_V2-MPR121/) on I2C2
+# [Grove – Speaker](http://wiki.seeedstudio.com/Grove-Speaker/) on UART2
+import time
+import wave
+import pyaudio
+from Captouch import MPR121
+_SCALE_DEFS = [
+ 'do.wav',
+ 're.wav',
+ 'me.wav',
+ 'fa.wav',
+ 'so.wav',
+ 'la.wav',
+ 'ti.wav',
+ 'do+.wav'
+ ]
+def PlayMusic(file):
+ """Play WAV format music when the Mpr121 is pressed
+ file:the Wav format music
+ """
+ # define stream chunk
+ chunk = 1024
+ # open a wav format music
+ f = wave.open(file,"rb")
+ # instantiate PyAudio
+ p = pyaudio.PyAudio()
+ #define callback function
+ def callback(in_data, frame_count, time_info, status):
+ data = f.readframes(frame_count)
+ #the function will return pyaudio.paContinue when the Mpr121 is pressed
+ if Mpr121Data[0] != 0:
+ return (data,pyaudio.paContinue)
+ return (data,pyaudio.paComplete)
+ # open stream
+ stream = p.open(format = p.get_format_from_width(f.getsampwidth()),
+ channels = f.getnchannels(),
+ rate = f.getframerate(),
+ output = True,
+ stream_callback=callback)
+ #Start stream
+ stream.start_stream()
+ #Enter the while loop,when the Mpr121 is pressed
+ while stream.is_active():
+ global Mpr121Data
+ Mpr121Data = Mpr121.get()
+ time.sleep(0.01)
+ # stop stream
+ stream.stop_stream()
+ stream.close()
+ f.close()
+ # close PyAudio
+ p.terminate()
+def main():
+ global Mpr121
+ Mpr121 = MPR121()
+ while True:
+ GetMpr121 = Mpr121.get()
+ Mpr121Result = GetMpr121[1]
+ #Mpr121Result isn't empty when the Mpr121 is pressed
+ if any(Mpr121Result) != False:
+ #Check the which one button is pressed on Mpr12 then play different music
+ for i in range(12):
+ if(Mpr121Result[i] == 1):
+ if i > 3 :
+ PlayMusic("/tmp/scale/%s"%_SCALE_DEFS[i-4])
+ else :
+ PlayMusic("/tmp/scale/%s"%_SCALE_DEFS[i])
+ time.sleep(0.05)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Kit-setup.md b/PocketBeagle/Grove/Kit-setup.md
new file mode 100644
index 0000000..af99208
--- /dev/null
+++ b/PocketBeagle/Grove/Kit-setup.md
@@ -0,0 +1,61 @@
+# PocketBeagle Grove Kit setup
+
+See the [Kit tutorials](Kit.md) document to learn more about using PocketBeagle Grove Kit. These setup
+instructions document what was done in the customization of the microSD card images and are not required
+if using one of the provided grove-kit images.
+
+## Make and install the seeed-linux-dtoverlays on pocketbeagle
+
+- Step 1. update the Kernel.
+
+```bash
+sudo apt update
+sudo apt install linux-headers-$(uname -r) -y
+```
+
+- Step 2. Get the `seeed-linux-dtoverlay` source code, install and reboot.
+
+seeed-linux-dtoverlay is a packet that can make some Grove become a file that can be read and write on Linux.
+
+```bash
+cd ~
+git clone https://github.com/Seeed-Studio/seeed-linux-dtoverlays
+cd ~/seeed-linux-dtoverlays
+make && sudo make install_bb
+sudo echo uboot_overlay_addr0=/lib/firmware/PB-I2C1-TLV320AIC3104.dtbo >> /boot/uEnv.txt
+sudo echo uboot_overlay_addr1=/lib/firmware/BB-GPIO-P9813.dtbo >> /boot/uEnv.txt
+sudo echo uboot_overlay_addr2=/lib/firmware/BB-GPIO-HCSR04.dtbo >> /boot/uEnv.txt
+sudo echo uboot_overlay_addr3=/lib/firmware/BB-GPIO-GROVE-BUTTON.dtbo >> /boot/uEnv.txt
+sudo echo uboot_overlay_addr4=/lib/firmware/BB-I2C1-JHD1802.dtbo >> /boot/uEnv.txt
+sudo echo uboot_overlay_addr5=/lib/firmware/BB-I2C2-ADXL34X.dtbo >> /boot/uEnv.txt
+sudo echo uboot_overlay_addr6=/lib/firmware/BB-I2C2-MPR121.dtbo >> /boot/uEnv.txt
+sudo reboot
+```
+
+!!!Note
+ Please connect Grove with PocketBeagle with Grove shield firstly, then reboot.
+
+- Step 3.Use `alsactl` command to configure TLV320AIC3104 codec
+
+```bash
+cd ~/seeed-linux-dtoverlays/extras/
+sudo alsactl restore 0 -f tlv320aic3104.state.txt
+```
+
+- Step 4.Check if the driver of codec install successfully
+
+if the driver of codec installed successfully , you should view below information.
+
+```bash
+debian@beaglebone:~$ aplay -l
+**** List of PLAYBACK Hardware Devices ****
+card 0: Audio [GroveBaseCape Audio], device 0: davinci-mcasp.0-tlv320aic3x-hifi tlv320aic3x-hifi-0 [davinci-mcasp.0-tlv320aic3x-hifi tlv320aic3x-hifi-0]
+ Subdevices: 1/1
+ Subdevice #0: subdevice #0
+```
+- Step 5.Set default sound card
+
+```bash
+cd ~/seeed-linux-dtoverlays/extras/
+sudo cp tlv320aic3104.conf.txt /etc/asound.conf
+```
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Kit.md b/PocketBeagle/Grove/Kit.md
new file mode 100644
index 0000000..da791ae
--- /dev/null
+++ b/PocketBeagle/Grove/Kit.md
@@ -0,0 +1,382 @@
+# BeagleBoard.org PocketBeagle Grove Kit
+
+
+
+PocketBeagle is an ultra-tiny-yet-complete open-source USB-key-fob computer. PocketBeagle features an incredibly low cost, slick design, and simple usage, making PocketBeagle the ideal development board for beginners and professionals alike. Its rich features allow users to programmatically control external devices and obtain data from external devices.
+
+Grove is a modular, standardized connector prototyping system. Consisting of Sensor, Actuator, Display, Communication, and Other function modules. Grove takes a building block approach to assemble electronics. Compared to the jumper or solder based system, it is easier to connect, experiment and build and simplifies the learning system.
+
+BeagleBoard.org PocketBeagle Grove Kit combines the Grove sensor modules with the powerful programming capabilities of PocketBeagle, allowing students to interact with music using real-world information such as light, touch, keyboard, Slide Potentiometer, posture and so on, to create cool projects.
+
+## Hardware Overview
+
+
+
+**Part List:**
+
+- ① [Grove - Analog Microphone](TBD)
+- ② [Grove - Chainable RGB LED](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/)
+- ③ [Grove - Ultrasonic Distance Sensor](http://wiki.seeedstudio.com/Grove-Ultrasonic_Ranger/)
+- ④ [Grove - Rotary Angle Sensor](http://wiki.seeedstudio.com/Grove-Rotary_Angle_Sensor/)
+- ⑤ [Grove - Slide Potentiometer](http://wiki.seeedstudio.com/Grove-Slide_Potentiometer/)
+- ⑥ [Grove - Button](http://wiki.seeedstudio.com/Grove-Button/)
+- ⑦ [Grove - 12 Key Capacitive I2C Touch Sensor](http://wiki.seeedstudio.com/Grove-12_Key_Capacitive_I2C_Touch_Sensor_V2-MPR121/)
+- ⑧ [Grove - 3 Axis Digital Accelerometer](http://wiki.seeedstudio.com/Grove-3-Axis_Digital_Accelerometer-16g/)
+- ⑨ [Grove - Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/)
+- ⑩ [Grove - 16x2 LCD](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/)
+- ⑪ [BeagleBoard.org PocketBeagle](https://beagleboard.org/pocket)
+- ⑫ [10pcs Alligator Cable](https://www.seeedstudio.com/10pcs-alligator-clip-test-lead-500mm-22awg-p-3087.html)
+- ⑬ SD+TF Card Reader
+- ⑭ WiFi Dongle
+- ⑮ Acrylic shell
+
+## Setup the drivers on PocketBeagle
+
+When using the provided microSD card, or a microSD card programmed using one of the provided grove-kit images, drivers and overlays to configure those drivers are already setup.
+
+Visit [PocketBeagle Getting Started section in the System Reference Manual](https://github.com/beagleboard/pocketbeagle/wiki/System-Reference-Manual#331_Getting_Started) for information about getting started with PocketBeagle.
+
+See https://debian.beagleboard.org/images/grove for the latest provided grove-kit images. Use the Getting Started instructions for programming the microSD card.
+
+Read [PocketBeagle Grove Kit-setup](Kit-setup.md) to learn more about the customizations applied to this image.
+
+Then maybe you can read below information to get how to connect wifi and get IP.`connmanctl` is a tool that connects Pockbeagle to the internet with WiFi Dongle, please refer below command
+
+```bash
+debian@beaglebone:~$ sudo connmanctl
+Error getting VPN connections: The name net.connman.vpn was not provided by any
+connmanctl> enable wifi
+Enabled wifi
+connmanctl> scan wifi
+Scan completed for wifi
+connmanctl> services
+*AO Wired ethernet_b827ebbde13c_cable
+ wifi_e8de27077de3_hidden_managed_none
+ AH04044914 wifi_e8de27077de3_41483034303434393134_managed_psk
+ Frissie wifi_e8de27077de3_46726973736965_managed_psk
+ ruijgt gast wifi_e8de27077de3_7275696a67742067617374_managed_psk
+ schuur wifi_e8de27077de3_736368757572_managed_psk
+connmanctl> agent on
+Agent registered
+connmanctl> connect wifi_e8de27077de3_41 # You can use the TAB key at this point to autocomplete the name
+connmanctl> connect wifi_e8de27077de3_41483034303434393134_managed_psk
+Agent RequestInput wifi_e8de27077de3_41483034303434393134_managed_psk
+ Passphrase = [ Type=psk, Requirement=mandatory ]
+Passphrase? *************
+Connected wifi_e8de27077de3_41483034303434393134_managed_psk
+connmanctl> quit
+```
+we can use `ifconfig` to get IP of PocketBeagle.
+```bash
+debian@beaglebone:~$ ifconfig
+lo: flags=73 mtu 65536
+ inet 127.0.0.1 netmask 255.0.0.0
+ inet6 ::1 prefixlen 128 scopeid 0x10
+ loop txqueuelen 1000 (Local Loopback)
+ RX packets 160 bytes 11840 (11.5 KiB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 160 bytes 11840 (11.5 KiB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+usb0: flags=4163 mtu 1500
+ inet 192.168.7.2 netmask 255.255.255.252 broadcast 192.168.7.3
+ inet6 fe80::9a5d:adff:fed1:14e1 prefixlen 64 scopeid 0x20
+ ether 98:5d:ad:d1:14:e1 txqueuelen 1000 (Ethernet)
+ RX packets 1469 bytes 121754 (118.9 KiB)
+ RX errors 0 dropped 6 overruns 0 frame 0
+ TX packets 203 bytes 37968 (37.0 KiB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+usb1: flags=4099 mtu 1500
+ inet 192.168.6.2 netmask 255.255.255.252 broadcast 192.168.6.3
+ ether 98:5d:ad:d1:14:e4 txqueuelen 1000 (Ethernet)
+ RX packets 0 bytes 0 (0.0 B)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 0 bytes 0 (0.0 B)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+wlan0: flags=-28605 mtu 1500
+ inet 192.168.0.153 netmask 255.255.255.0 broadcast 192.168.0.255
+ inet6 fe80::bade:5eff:fe4d:4d9a prefixlen 64 scopeid 0x20
+ ether b8:de:5e:4d:4d:9a txqueuelen 1000 (Ethernet)
+ RX packets 5922 bytes 545244 (532.4 KiB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 7317 bytes 1453920 (1.3 MiB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+```
+
+The wlan0's inet is the IP that you want. The IP may be different on different local.
+
+## Lesson - 1. Control the Light
+
+### Description:
+
+In this lesson, students will light up the RGB LED and LCD, and learn how to use Slide Potentiometer and Rotary Angle Sensor to change the light of RGB LED.
+
+### Hardware Requirement:
+
+- [Grove - Slide Potentiometer](https://www.seeedstudio.com/Grove-Slide-Potentiometer.html)
+- [Grove - Rotary Angle Sensor](http://wiki.seeedstudio.com/Grove-Rotary_Angle_Sensor/)
+- [Grove - Chainable RGB LED](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/)
+- [Grove - 16x2 LCD](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/)
+
+### Hardware Connection
+
+- Plug the Grove - Slide Potentiometer into **A0** port
+- Plug the Grove - Rotary Angle Sensor into **A5** port
+- Plug the Grove - Chainable RGB LED into **A2** port
+- Plug the Grove - 16x2 LCD into **I2C1** port
+- Plug the WiFi dongle into the **USB** Port
+- Power PocketBeagle via the **micro USB** port
+
+
+
+
+### Software
+
+- Step 1. Enter Cloud9 IDE by typing IP of PocketBeagle
+- Step 2. Select PocketBeagle -> Grove
+- Step 3. Run the Control_the_Light.py by using Runner:Python.
+
+### Success
+ Now please turn the rotary angle sensor slowly and slide Slide Potentiometer, and see how the RGB LED changes it's light and color.
+
+
+## Lesson - 2. Musical Note
+
+### Description:
+
+In this lesson, students can move their hands in front of the ultrasonic distance sensor, the LCD will show the distance of the hand, and the speaker will play different musical notes based on different distances.
+
+### Hardware Requirement:
+
+- [Grove - Ultrasonic Distance Sensor](http://wiki.seeedstudio.com/Grove-Ultrasonic_Ranger/)
+- [Grove - 16x2 LCD](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/)
+- [Grove - Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/)
+
+
+### Hardware Connection
+
+- Plug the Grove - Ultrasonic Distance Sensor into **A0** port
+- Plug the Grove - 16x2 LCD into **I2C1** port
+- Plug the Grove - Speaker Plus into **UART2** port
+- Plug the WiFi dongle into the **USB** Port
+- Power PocketBeagle via the **micro USB** port
+
+
+
+### Software
+
+- Step 1. Enter Cloud9 IDE by typing IP of PocketBeagle
+- Step 2. Select PocketBeagle -> Grove
+- Step 3. Run the ToneGenerator.py by using Runner:Python.
+
+**NOTE** : we should run ToneGenerator.py when we restart after.
+
+- Step 4. Run the Musical_Note.py by using Runner:Python.
+
+### Success
+ Now please please slowly change the distance between your hand and the ultrasonic distance sensor, you can find the distance value in the LCD change and the music switched by the distance.
+
+
+## Lesson - 3. Switch the Music
+
+### Description:
+
+In this lesson, students will learn how to use the 2 buttons to select the next song or the last song. the buttons not only can select the next song or the last song by press instantly but also can play music by Press longly.
+
+The LCD will show the name of the song.
+
+### Hardware Requirement:
+
+- [Grove – Button x 2](http://wiki.seeedstudio.com/Grove-Button/)
+- [Grove – Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/)
+- [Grove – 16x2 LCD](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/)
+
+### Hardware Connection
+
+- Plug the Grove – Button into **A5** and **UART4** port
+- Plug the Grove – 16x2 LCD into **I2C1** port
+- Plug the Grove – Speaker Plus into **UART2** port
+- Plug the WiFi dongle into the **USB** Port
+- Power PocketBeagle via the **micro USB** port
+
+
+
+### Software
+
+- Step 1. Enter Cloud9 IDE by typing IP of PocketBeagle
+- Step 2. Select PocketBeagle -> Grove
+- Step 3. Run the Switch_the_Music.py by using Runner:Python.
+
+### success
+ Now please try to press the two buttons, check the LCD, and listen to music.
+
+## Lesson - 4. Download Music via the WIFI dongle
+
+### Description:
+
+In this lesson, students will learn how to use the 2 buttons to select the next song or the last song. the buttons not only can select the next song or the last song by press instantly but also can play music by Press longly.
+
+The LCD will show the name of the song.
+
+### Hardware Requirement:
+
+- [Grove - Button x 2](http://wiki.seeedstudio.com/Grove-Button/)
+- [Grove - Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/)
+- [Grove - 16x2 LCD](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/)
+
+### Hardware Connection
+
+- Plug the Grove - Button into **A5** and **UART4** port
+- Plug the Grove - 16x2 LCD into **I2C1** port
+- Plug the Grove - Speaker Plus into **UART2** port
+- Plug the WiFi dongle into the **USB** Port
+- Power PocketBeagle via the **micro USB** port
+
+
+
+### Software
+
+- Step 1. Enter Cloud9 by typing IP of PocketBeagle
+- Step 2. Select PocketBeagle -> Grove
+- Step 3. Select File -> Upload Local Files.
+- Step 4. Drag `xxx.wav` that you want to play to Cloud9.
+- Step 5. Run the Switch_the_Music.py by using Runner:Python.
+
+### success
+ Default music is boring and bad taste? Now, with the help of WiFi, you can download the music to meet your own flavor.
+
+## Lesson - 5. Keyboard Player
+
+### Description:
+
+In this lesson, students will learn how to use the capacitive touch sensor to play different musical note.
+
+### Hardware Requirement:
+
+- [Grove - 12 Key Capacitive I2C Touch Sensor](http://wiki.seeedstudio.com/Grove-12_Key_Capacitive_I2C_Touch_Sensor_V2-MPR121/)
+- [Grove – Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/)
+
+### Hardware Connection
+
+- Plug the Grove – Speaker Plus into **UART2** port
+- Plug the Grove - 12 Key Capacitive I2C Touch Sensor into **I2C2** port
+- Plug the WiFi dongle into the **USB** Port
+- Power the PocketBeagle via the **micro USB** port
+
+
+
+
+### Software
+
+- Step 1. Enter Cloud9 by typing IP of PocketBeagle
+- Step 2. Select PocketBeagle -> Grove
+- Step 3. Run the KeyBoard_Player.py by using Runner:Python.
+
+### success
+ Try to touch the Capacitive key, image it as a keyboard, and play your music.
+
+
+## Lesson - 6. Start the Party
+
+### Description:
+
+In this lesson, students will learn how to use the capacitive touch sensor to play the song. And the RGB LED will have different colors based on a different musical notes.
+
+### Hardware Requirement:
+
+- [Grove - 12 Key Capacitive I2C Touch Sensor V2](http://wiki.seeedstudio.com/Grove-12_Key_Capacitive_I2C_Touch_Sensor_V2-MPR121/)
+- [Grove - Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/)
+- [Grove - Chainable RGB LED](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/)
+
+
+### Hardware Connection
+
+- Plug the Grove - Speaker Plus into **UART2** port
+- Plug the Grove - 12 Key Capacitive I2C Touch Sensor V2 into **I2C2** port
+- Plug the Grove - Chainable RGB LED into **A2** port
+- Plug the WiFi dongle into the **USB** Port
+- Power PocketBeagle via the **micro USB** port
+
+
+
+
+### Software
+
+- Step 1. Enter Cloud9 by typing IP of PocketBeagle
+- Step 2. Select PocketBeagle -> Grove
+- Step 3. Run the Start_the_Party.py by using Runner:Python.
+
+### success
+ Just control the music as lesson 5, and you can see the color of RGB LED change.
+
+
+## Lesson - 7. Music Box
+
+### Description:
+
+In this lesson, students will learn how to use the Grove - 3-Axis Accelerometer to control RGB LED and Speaker Plus. At last, he can make a smart box, by putting the different side of the box on the table, the box will have different color and play different music.
+
+### Hardware Requirement:
+
+- [Grove - 3 Axis Digital Accelerometer](http://wiki.seeedstudio.com/Grove-3-Axis_Digital_Accelerometer-16g/)
+- [Grove - Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/)
+- [Grove - Chainable RGB LED](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/)
+
+### Hardware Connection
+
+- Plug the Grove - Speaker Plus into **UART2** port
+- Plug the Grove - 3 Axis Digital Accelerometer into **I2C2** port
+- Plug the Chainable RGB LED into **A2** port
+- Plug the WiFi dongle into the **USB** Port
+- Power PocketBeagle via the **micro USB** port
+
+
+
+
+### Software
+
+- Step 1. Enter Cloud9 by typing IP of PocketBeagle
+- Step 2. Select PocketBeagle -> Grove
+- Step 3. Run the KeyBoard_Player.py by using Runner:Python.
+
+### success
+ Here you go, a smart music box. Just rotate the music box and dance with different music.
+
+
+## Lesson - 8. Hello Kitt-AI
+
+### Description:
+
+In this lesson, students will learn how to install the snowboy of Kitt-AI and use it.
+
+### Hardware Requirement:
+
+- [Grove - Analog Microphone](http://wiki.seeedstudio.com/Grove-Analog-Microphone)
+- [Grove - Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/)
+- [Grove - Chainable RGB LED](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/)
+
+### Hardware Connection
+
+- Plug the Grove - Speaker Plus into **UART2** port
+- Plug the Grove - Analog Microphone into **PWM** port
+- Plug the Chainable RGB LED into **A2** port
+- Plug the WiFi dongle into the **USB** Port
+- Power PocketBeagle via the micro **USB** port
+
+
+
+
+### Software
+
+- Step 1. Enter Cloud9 IDE by typing IP of PocketBeagle
+- Step 2. Select PocketBeagle -> Grove
+- Step 3. Search Ok_Beagle hotword model through [snowboy](https://snowboy.kitt.ai/dashboard)
+- Step 4. Click the `Record and Download` to provide data of sound for Ok_Beagle.
+- Step 5. Download the Ok_Beagle.pmdl from the [website](https://snowboy.kitt.ai/hotword/46889)
+- Step 6. Darg Ok_Beagle.pmdl to Cloud9 like lesson4
+- Step 7. Run the Ok_Beagle.py by using Runner:Python.
+
+### success
+ The RGB LED will light up when we say Ok_Beagle to mic.
diff --git a/PocketBeagle/Grove/LCD.py b/PocketBeagle/Grove/LCD.py
new file mode 100644
index 0000000..e0d2617
--- /dev/null
+++ b/PocketBeagle/Grove/LCD.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - 16x2 LCD](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/) on I2C1
+import time
+from Shell import ReinstallModule,InstallDTBO,GetCmdReturn
+import os
+class JHD1802:
+ """JHD1802 LCD Driver"""
+ def __init__(self):
+ """Initialize the JHD1802 using file python library"""
+ self.Path = '/proc/device-tree/aliases/jhd1802'
+ self.Lcd0 = '/dev/lcd0'
+ try:
+ # Check BB-I2C1-JHD1802 whether install successfully
+ # if not reinstall it
+ if not os.path.exists(self.Path):
+ InstallDTBO('BB-I2C1-JHD1802')
+ while not os.path.exists(self.Path):
+ time.sleep(0.1)
+ #Reinstall hd44780 module to support hot plug
+ ReinstallModule('seeed-hd44780')
+ try:
+ #Open the /dev/lcd0 using file python library
+ self.f = open(self.Lcd0, 'w')
+ except IOError as err:
+ GetCmdReturn('sudo chmod 777 %s'%self.Lcd0)
+ self.f = open(self.Lcd0, 'w')
+ #Clean LCD
+ self.f.write('\x1b[2J')
+ self.f.write('\x1b[H')
+ self.f.flush()
+ except IOError as err:
+ print("File Error:"+str(err))
+ print("maybe you should reinstall the driver of hd44780")
+ def SetText(self, text):
+ """Display the string on LCD
+ text:content on LCD
+ """
+ try:
+ self.f.write('\x1b[H')
+ self.f.flush()
+ self.f.write('%s'%text)
+ self.f.flush()
+ except IOError as err:
+ print("File Error:"+str(err))
+ print("maybe you should reinstall the driver of hd44780")
+def main():
+ d = JHD1802()
+ d.SetText("abcdefghijklmnopqrstuvwxyz012345")
+ time.sleep(0.25)
+ d.SetText("ABCDEFGHIJKLMNOPQRSTUVWXYZ6789!@")
+ time.sleep(0.25)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Music_Box.py b/PocketBeagle/Grove/Music_Box.py
new file mode 100644
index 0000000..4c47ae4
--- /dev/null
+++ b/PocketBeagle/Grove/Music_Box.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - 3 Axis Digital Accelerometer]
+# (http://wiki.seeedstudio.com/Grove-3-Axis_Digital_Accelerometer-16g/) on I2C2
+# [Grove - Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/) on UART2
+# [Grove - Chainable RGB LED X 2](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/)
+# on A2
+import time
+import wave
+import pyaudio
+from tqdm import tqdm
+import math
+import threading
+from RGBLed import P981X
+from Accelerometer import ADX134X
+_SCALE_DEFS = [
+ 'do.wav',
+ 're.wav',
+ 'me.wav',
+ 'fa.wav',
+ 'so.wav',
+ 'la.wav',
+ 'ti.wav'
+ ]
+def FunTimer():
+ """Make the LED will shine like rainbow color"""
+ Rainbow = [[255,0,0],[255,126,0],[255,255,0],[0,255,0],[0,255,255]\
+ ,[0,0,255],[255,0,255]]
+ global RainbowIndex
+ global RainbowFlash
+ if RainbowFlash:
+ RainbowIndex = RainbowIndex + 1
+ if RainbowIndex > 6 :
+ RainbowIndex = 0
+ LED.set(0,Rainbow[RainbowIndex][0],Rainbow\
+ [RainbowIndex][1],Rainbow[RainbowIndex][2])
+ LED.set(1,Rainbow[RainbowIndex][0],Rainbow\
+ [RainbowIndex][1],Rainbow[RainbowIndex][2])
+ else:
+ RainbowIndex = 0
+ global timer
+ timer = threading.Timer(0.5, FunTimer)
+ timer.start()
+def Play_Music(file):
+ """Play WAV format music
+ file:the Wav format music
+ """
+ # end the timer
+ global timer
+ timer.cancel()
+ # define stream chunk
+ chunk = 1024
+ # open a wav format music
+ f = wave.open(file,"rb")
+ # instantiate PyAudio
+ p = pyaudio.PyAudio()
+ # open stream
+ stream = p.open(format = p.get_format_from_width(f.getsampwidth()),
+ channels = f.getnchannels(),
+ rate = f.getframerate(),
+ output = True)
+ # read data
+ data = f.readframes(chunk)
+ # append data to datas
+ datas = []
+ while len(data) > 0:
+ data = f.readframes(chunk)
+ datas.append(data)
+ time = 0
+ # play datas and display the progress bar of the music
+ for d in tqdm(datas):
+ time = time + 1
+ stream.write(d)
+ if time > len(datas)//10:
+ break
+ # stop stream
+ stream.stop_stream()
+ stream.close()
+ # close PyAudio
+ p.terminate()
+ # start the timer
+ timer = threading.Timer(0.5, FunTimer)
+ timer.start()
+def main():
+ Adx134x = ADX134X()
+ global LED
+ LED = P981X()
+ global RainbowFlash
+ RainbowFlash = False
+ global RainbowIndex
+ RainbowIndex = 0
+ GetAttitude = 0
+ # Create timer thread that weak up after 0.5s
+ # The timer will execute the FunTimer after 0.5s
+ global timer
+ timer = threading.Timer(0.5, FunTimer)
+ timer.start()
+ time.sleep(1)
+ while True:
+ GetAttitudeLast = GetAttitude
+ GetAttitude = Adx134x.MotionDetection()
+ # the LED will shine like rainbow color if GetAttitude = 4
+ if GetAttitude == 4:
+ RainbowFlash = True
+ else:
+ RainbowFlash = False
+ LED.set(0,(GetAttitude&0x01)*255,(GetAttitude\
+ &0x02)*255,(GetAttitude&0x04)*255)
+ LED.set(1,(GetAttitude&0x01)*255,(GetAttitude\
+ &0x02)*255,(GetAttitude&0x04)*255)
+ # the Speaker will play music when the Attitude changed.
+ if GetAttitudeLast != GetAttitude and GetAttitude != 0:
+ Play_Music("/tmp/scale/%s"%_SCALE_DEFS[GetAttitude])
+ time.sleep(0.05)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Musical_Note.py b/PocketBeagle/Grove/Musical_Note.py
new file mode 100644
index 0000000..7cc8836
--- /dev/null
+++ b/PocketBeagle/Grove/Musical_Note.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - Ultrasonic Distance Sensor](http://wiki.seeedstudio.com/Grove-Ultrasonic_Ranger/)
+# on A0
+# [Grove - 16x2 LCD](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/) on I2C1
+# [Grove - Speaker Plus](http://wiki.seeedstudio.com/Grove-Speaker/) on UART2
+import wave
+import pyaudio
+from tqdm import tqdm
+import time
+from UltrasonicSensor import HCSR04
+from LCD import JHD1802
+_SCALE_DEFS = [
+ 'do.wav',
+ 're.wav',
+ 'me.wav',
+ 'fa.wav',
+ 'so.wav',
+ 'la.wav',
+ 'ti.wav'
+ ]
+def Play_Music(file):
+ """Play WAV format music
+ file:the Wav format music
+ """
+ # define stream chunk
+ chunk = 1024
+ # open a wav format music
+ f = wave.open(file,"rb")
+ # instantiate PyAudio
+ p = pyaudio.PyAudio()
+ # open stream
+ stream = p.open(format = p.get_format_from_width(f.getsampwidth()),
+ channels = f.getnchannels(),
+ rate = f.getframerate(),
+ output = True)
+ # read data
+ data = f.readframes(chunk)
+ # append data to datas
+ datas = []
+ while len(data) > 0:
+ data = f.readframes(chunk)
+ datas.append(data)
+ # play stream
+ time = 0
+ for d in tqdm(datas):
+ time = time + 1
+ stream.write(d)
+ if time > len(datas)//10:
+ break
+ # stop stream
+ stream.stop_stream()
+ stream.close()
+ # close PyAudio
+ p.terminate()
+def main():
+ Distance = HCSR04()
+ Lcd = JHD1802()
+ while True:
+ distance = Distance.GetDistance()
+ #Display the distance
+ Lcd.SetText("The Distance: \r\n{} cm".format(distance))
+ print("Distance is %3d \r" %distance, end = '')
+ #Speaker will play different music When the HCSR04 get different distance
+ if distance < 240:
+ Play_Music("/tmp/scale/%s"%_SCALE_DEFS[distance//40])
+ time.sleep(1)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Ok_Beagle.py b/PocketBeagle/Grove/Ok_Beagle.py
new file mode 100644
index 0000000..5777a0b
--- /dev/null
+++ b/PocketBeagle/Grove/Ok_Beagle.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - Analog Microphone](http://wiki.seeedstudio.com/Grove-Speaker/) on PWM
+# [Grove - Chainable RGB LED](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/)
+# on A2
+import time
+from RGBLed import P981X
+import signal
+from snowboy import snowboydecoder
+from Shell import GetCmdReturn,os
+interrupted = False
+def signal_handler(signal, frame):
+ global interrupted
+ interrupted = True
+def interrupt_callback():
+ global interrupted
+ return interrupted
+# Check the Ok_Beagle.pmdl whether exist.
+if not os.path.exists('/usr/lib/python3/dist-packages/snowboy/resources\
+/models/Ok_Beagle.pmdl'):
+ if os.path.exists('/var/lib/cloud9/PocketBeagle/Grove/Ok_Beagle.pmdl'):
+ GetCmdReturn('sudo mv /var/lib/cloud9/PocketBeagle/Grove/Ok_Beagle.pmdl\
+ /usr/lib/python3/dist-packages/snowboy/resources/models/')
+ else:
+ print('Maybe you should Drag Ok_Beagle.pmdl to Could9')
+ exit(1)
+
+detector = snowboydecoder.HotwordDetector('/usr/lib/python3/dist-packages/\
+snowboy/resources/models/Ok_Beagle.pmdl', sensitivity=0.5)
+# capture SIGINT signal, e.g., Ctrl+C
+signal.signal(signal.SIGINT, signal_handler)
+print('Listening... Press Ctrl+C to exit')
+def callback():
+ """Make LED blink once
+ """
+ LED.set(0,255,255,0)
+ LED.set(1,255,255,0)
+ time.sleep(1)
+ LED.set(0,0,0,0)
+ LED.set(1,0,0,0)
+LED = P981X()
+LED.set(0,0,0,0)
+LED.set(1,0,0,0)
+# main loop
+detector.start(detected_callback=callback,
+ interrupt_check=interrupt_callback,
+ sleep_time=0.03)
+detector.terminate()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/README.md b/PocketBeagle/Grove/README.md
index 2179825..58abead 100644
--- a/PocketBeagle/Grove/README.md
+++ b/PocketBeagle/Grove/README.md
@@ -4,6 +4,8 @@ This is a set of examples for using Seeed Grove modules with PocketBeagle, prima
the BeagleBoard.org PocketBeagle Grove Cape, but some other wiring options are examined as
well.
+Forthcoming documentation fixes: https://github.com/SeeedDocument/wiki_english/pull/28
+
# BeagleBoard.org PocketBeagle Grove Cape
| Grove socket and pin | PocketBeagle pin(s) | default |
@@ -33,27 +35,35 @@ To use these ports as 3.3V I2C, the default configuration should be ready-to-go.
on the sensor you are using, you'll simply need to enable the kernel driver and interact
using the newly created SYSFS entries. This is easy and can be quickly learned by example.
-Take the [Grove time of flight distance sensor](http://wiki.seeedstudio.com/Grove-Time_of_Flight_Distance_Sensor-VL53L0X/)
-as a first example. As long as the kernel is new enough or the module is installed, you'll
-simply need to write to a file called ```/sys/bus/i2c_devices/i2c-2/new_device``` to
-trigger the loading of the driver, assuming you've connected it to I2C2. Swap i2c-2 with
-i2c-1 if you've connected it to I2C1. What you'll need to write is the string ```vl53l0x 0x29```.
-This is the device driver name and the I2C address of the device on the Grove module.
+Take the [Grove - 3 Axis Digital Accelerometer](http://wiki.seeedstudio.com/Grove-3-Axis_Digital_Accelerometer-16g/)
+as a first example. As long as the kernel and overlay library are new enough, you'll
+simply need to write to a file to load the overlay with configuration information,
+triggering the loading of the driver. Note that the overlay file specifies the I2C port
+where the sensor is connected, so you'll need to choose the correct overlay file based
+on the port.
In this directory, you'll find numerous examples in various programming languages to
perform this task, but you can also simply do everything necessary from the Linux
command shell. You'll see the shell in your Cloud9 IDE window as 'bash'. Simply type
-in these two lines to read from the time of flight sensor.
+in these lines to read from the accelerometer connected on I2C2.
+
+TODO: Ugh. Most drivers need interrupts and the Grove modules don't have them. :-(
+
+TODO: Ugh. The Seeed provided driver is an input driver, not an iio driver. :-(
```sh
-echo vl53l0x 0x29 | sudo tee /sys/bus/i2c/devices/i2c-2/new_device
-cat /sys/bus/iio/devices/iio\:device1/in_distance_raw
+sudo mkdir -p /sys/kernel/config/device-tree/overlays/adxl34x
+sudo dd if=/lib/firmware/BB-I2C2-ADXL34X.dtbo of=/sys/kernel/config/device-tree/overlays/adxl34x/dtbo
+cat /sys/bus/iio/devices/iio\:device1/in_accel_x_raw
```
-The first line loads the driver and the second line reads the sensor. If you have more
+The first line tells the kernel we'd like to add a new overlay, the second line provides the
+overlay data loading the driver and the third line reads the sensor. If you have more
sensor drivers loaded, the ```iio:device1``` might be incremented to ```iio:device2```
or whatever the next available index is.
+Note that
+
To read it continuously, you can do something like:
```sh
@@ -94,7 +104,11 @@ sudo gpsctl add /dev/ttyS4
gpsmon
```
-
+# Python setup for examples
+```
+sudo apt install -y python3-libiio portaudio19-dev python3-all-dev -y
+sudo pip3 install python-periphery python-uinput pyaudio tqdm
+```
# [mikroBus Grove Adapter](https://www.tindie.com/products/pmunts/mikrobus-grove-adapter-3/)
| Grove socket and pin | mikroBUS name | Position 1 PocketBeagle pin | Position 2 PocketBeagle pin |
@@ -106,4 +120,4 @@ gpsmon
| J3 - SER - 1 | RX | ```P2_5``` (UART4) | ```P1_32``` (UART0) |
| J3 - SER - 2 | TX | ```P2_7``` (UART4) | ```P1_30``` (UART0) |
| J4 - I2C - 1 | SCL | ```P2_9``` (I2C1) | ```P1_28``` (I2C2) |
-| J4 - I2C - 2 | SDA | ```P2_11``` (I2C1) | ```P1_26``` (I2C2) |
+| J4 - I2C - 2 | SDA | ```P2_11``` (I2C1) | ```P1_26``` (I2C2) |
\ No newline at end of file
diff --git a/PocketBeagle/Grove/RGBLed.py b/PocketBeagle/Grove/RGBLed.py
new file mode 100644
index 0000000..164cdae
--- /dev/null
+++ b/PocketBeagle/Grove/RGBLed.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - Chainable RGB LED X 2](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/)
+# on A2
+import time
+from Shell import InstallDTBO
+import os
+class P981X:
+ """P981X RGB LED Driver"""
+ def __init__(self, leds = 2):
+ """Initialize the P981X using file python library
+ leds:the LED's chain length (defult leds = 2)
+ """
+ self.Path = '/proc/device-tree/p981x_1057@20'
+ self.P981x0 = '/dev/p981x0'
+ try:
+ # Check BB-GPIO-P9813 whether install successfully
+ # if not reinstall it
+ if not os.path.exists(self.Path):
+ InstallDTBO('BB-GPIO-P9813')
+ while not os.path.exists(self.Path):
+ time.sleep(0.1)
+ #Open the /dev/p981x0 using file python library
+ self.f = open(self.P981x0, 'w')
+ #Set the LED's chain length
+ self.f.write('N %d\n'%leds)
+ self.f.flush()
+ except IOError as err:
+ print("File Error:"+str(err))
+ print("maybe you should reinstall the driver of p981x")
+ def set(self, led, red, green, blue):
+ """Set LED's value of R,G,B
+ led:which one on LED's chain(defult 0 or 1)
+ red:The value that describes R of R,G,B(0~255)
+ green:The value that describes G of R,G,B(0~255)
+ blue:The value that describes B of R,G,B(0~255)
+ """
+ try:
+ self.f.write('D %d %d %d %d\n'%(led,red,green,blue))
+ self.f.flush()
+ except IOError as err:
+ print("File Error:"+str(err))
+ print("maybe you should reinstall the driver of p981x")
+def main():
+ LED = P981X()
+ while True:
+ LED.set(0,0x20,0,0)
+ LED.set(1,0,0x20,0)
+ time.sleep(0.25)
+ LED.set(0,0,0x20,0)
+ LED.set(1,0x20,0,0)
+ time.sleep(0.25)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Shell.py b/PocketBeagle/Grove/Shell.py
new file mode 100644
index 0000000..70f0ee9
--- /dev/null
+++ b/PocketBeagle/Grove/Shell.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+import os
+import time
+def GetCmdReturn(cmd):
+ """Run CMD using os.popen and get the CMD's output.
+ cmd : The shell cmd
+ return :the CMD's output
+ """
+ r = os.popen(cmd)
+ text = r.read()
+ r.close()
+ return text.strip('\n')
+def InstallDTBO(DTBO):
+ """Install Dtbo using dd cmd
+ DTBO : name of DTBO
+ """
+ # Build file using mkdir
+ GetCmdReturn('sudo mkdir -p \
+ /sys/kernel/config/device-tree/overlays/$DTBO')
+ # Install dtbo using dd
+ DTBO_PATH = DTBO + '.dtbo'
+ GetCmdReturn('sudo dd \
+ of=/sys/kernel/config/device-tree/overlays/$DTBO/dtbo \
+ if=/lib/firmware/$DTBO_PATH')
+def ConfigGPIO(PinName):
+ """config pin function to GPIO
+ PinName : Name of pin
+ """
+ PinName = PinName + '_pinmux'
+ PinName = open('/sys/devices/platform/ocp/ocp:%s/state'%PinName, 'w')
+ print('gpio', file=PinName)
+ PinName.close()
+def InstallModule(Module):
+ """Install Module
+ Module : Name of Module
+ """
+ GetCmdReturn('sudo modprobe -s %s'%Module)
+ Module = Module.replace('-','_')
+ while not Module in GetCmdReturn('lsmod | grep %s'%Module):
+ time.sleep(0.1)
+def RemoveModule(Module):
+ """Install Module
+ Module : Name of Module
+ """
+ Module = Module.replace('-','_')
+ GetCmdReturn('sudo rmmod -s %s || true '%Module)
+ while Module in GetCmdReturn('lsmod | grep %s'%Module):
+ time.sleep(0.1)
+def ReinstallModule(Module):
+ """Reinstall Module using InstallModule and RemoveModule
+ Module : Name of Module
+ """
+ RemoveModule(Module)
+ InstallModule(Module)
+def main():
+ print(GetCmdReturn('pwd'))
+ ConfigGPIO('P1_31')
+ ReinstallModule('adxl345_i2c')
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Start_the_Party.py b/PocketBeagle/Grove/Start_the_Party.py
new file mode 100644
index 0000000..8cf0b1c
--- /dev/null
+++ b/PocketBeagle/Grove/Start_the_Party.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - 12 Key Capacitive I2C Touch Sensor V2]
+# (http://wiki.seeedstudio.com/Grove-12_Key_Capacitive_I2C_Touch_Sensor_V2-MPR121/) on I2C2
+# [Grove – Speaker](http://wiki.seeedstudio.com/Grove-Speaker/)
+# on UART2
+# [Grove - Chainable RGB LED X 2](http://wiki.seeedstudio.com/Grove-Chainable_RGB_LED/)
+# on A2
+import time
+import wave
+import pyaudio
+from Captouch import MPR121
+from RGBLed import P981X
+_SCALE_DEFS = [
+ 'do.wav',
+ 're.wav',
+ 'me.wav',
+ 'fa.wav',
+ 'so.wav',
+ 'la.wav',
+ 'ti.wav',
+ 'do+.wav'
+ ]
+def Play_Music(file):
+ """Play WAV format music when the Mpr121 is pressed
+ file:the Wav format music
+ """
+ # define stream chunk
+ chunk = 1024
+ # open a wav format music
+ f = wave.open(file,"rb")
+ # instantiate PyAudio
+ p = pyaudio.PyAudio()
+ #define callback function
+ def callback(in_data, frame_count, time_info, status):
+ data = f.readframes(frame_count)
+ #the function will return pyaudio.paContinue when the Mpr121 is pressed
+ if Mpr121Data[0] != 0:
+ return (data,pyaudio.paContinue)
+ return (data,pyaudio.paComplete)
+ # open stream
+ stream = p.open(format = p.get_format_from_width(f.getsampwidth()),
+ channels = f.getnchannels(),
+ rate = f.getframerate(),
+ output = True,
+ stream_callback=callback)
+ #Start stream
+ stream.start_stream()
+ #Enter the while loop,when the Mpr121 is pressed
+ while stream.is_active():
+ global Mpr121Data
+ Mpr121Data = Mpr121.get()
+ time.sleep(0.01)
+ # stop stream
+ stream.stop_stream()
+ stream.close()
+ f.close()
+ # close PyAudio
+ p.terminate()
+def main():
+ LED = P981X()
+ global Mpr121
+ Mpr121 = MPR121()
+ while True:
+ GetMpr121 = Mpr121.get()
+ Mpr121Result = GetMpr121[1]
+ #Mpr121Result isn't empty when the Mpr121 is pressed
+ if any(Mpr121Result) != False:
+ #Check the which one button is pressed on Mpr12 then play
+ #different music and turn on LED that will display different color
+ for i in range(12):
+ if(Mpr121Result[i] == 1):
+ if i > 3 :
+ LED.set(0,((i-4)&0x01)*255,((i-4)&0x02)*255,((i-4)&0x04)*255)
+ LED.set(1,((i-4)&0x01)*255,((i-4)&0x02)*255,((i-4)&0x04)*255)
+ Play_Music("/tmp/scale/%s"%_SCALE_DEFS[i-4])
+
+ else :
+ LED.set(0,(i&0x01)*255,(i&0x02)*255,(i&0x04)*255)
+ LED.set(1,(i&0x01)*255,(i&0x02)*255,(i&0x04)*255)
+ if i == 0:
+ LED.set(0,50,50,200)
+ LED.set(1,50,50,200)
+ Play_Music("/tmp/scale/%s"%_SCALE_DEFS[i])
+ else :
+ LED.set(0,0,0,0)
+ LED.set(1,0,0,0)
+ time.sleep(0.05)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/Switch_the_Music.py b/PocketBeagle/Grove/Switch_the_Music.py
new file mode 100644
index 0000000..5b02b04
--- /dev/null
+++ b/PocketBeagle/Grove/Switch_the_Music.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - 16x2 LCD](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/) on I2C1
+# [Grove - Speaker Plus ](http://wiki.seeedstudio.com/Grove-16x2_LCD_Series/) on UART2
+# [Grove - Button x 2](https://www.seeedstudio.com/Grove-Button.html) on A5 and UART4
+import wave
+import pyaudio
+import os
+import time
+import threading
+from Button import BUTTON
+from LCD import JHD1802
+from Shell import GetCmdReturn
+def FunTimer():
+ """Update the LCD every 0.25 seconds"""
+ global MusciIndex
+ global files
+ Lcd.SetText("scale: \r\n{}".format(files[MusciIndex]))
+ global timer
+ timer = threading.Timer(0.25, FunTimer)
+ timer.start()
+def PlayMusic(file):
+ """Play WAV format music when the Button is pressed
+ file:the Wav format music
+ """
+ # define stream chunk
+ chunk = 512
+ # open a wav format music
+ f = wave.open(file,"rb")
+ # instantiate PyAudio
+ p = pyaudio.PyAudio()
+ #define callback function
+ def callback(in_data, frame_count, time_info, status):
+ data = f.readframes(frame_count)
+ #the function will return pyaudio.paContinue when the Button is pressed
+ if len(MusicKeyStatus):
+ return (data,pyaudio.paContinue)
+ return (data,pyaudio.paComplete)
+ # open stream
+ stream = p.open(format = p.get_format_from_width(f.getsampwidth()),
+ channels = f.getnchannels(),
+ rate = f.getframerate(),
+ output = True,
+ stream_callback=callback)
+ # start data
+ stream.start_stream()
+ #Enter the while loop,when the Button is pressed
+ while stream.is_active():
+ global MusicKeyStatus
+ MusicKeyStatus = keys.GetKeyStatus()
+ time.sleep(0.01)
+ # stop stream
+ stream.stop_stream()
+ stream.close()
+ # close PyAudio
+ p.terminate()
+def main():
+ #Check the xxx.wav whether exist
+ #Move to /tmp/scale/ if exist
+ if os.path.exists('/var/lib/cloud9/PocketBeagle/Grove/*.wav'):
+ GetCmdReturn('sudo mv /var/lib/cloud9/PocketBeagle/Grove/*.wav \
+ /tmp/scale/')
+ global files
+ files= os.listdir("/tmp/scale")
+ print(files)
+ global MusciIndex
+ MusciIndex = 0
+ global keys
+ keys = BUTTON()
+ global Lcd
+ Lcd = JHD1802()
+ # Create timer thread that weak up after 0.25s
+ # The timer will execute the FunTimer after 0.25s
+ global timer
+ timer = threading.Timer(0.25, FunTimer)
+ timer.start()
+ while True:
+ KeyStatus = keys.GetKeyStatus()
+ #KeyStatus isn't empty when the Button is pressed
+ if(len(KeyStatus)):
+ #The KeyStatus[0] = 256 will play next music and the music name display on LCD
+ if KeyStatus[0] == 256:
+ MusciIndex = MusciIndex + 1
+ if MusciIndex > 6:
+ MusciIndex = 0
+ #The KeyStatus[0] = 257 will play last music and the music namedisplay on LCD
+ if KeyStatus[0] == 257:
+ MusciIndex = MusciIndex - 1
+ if MusciIndex < 0:
+ MusciIndex = 6
+ PlayMusic("/tmp/scale/%s"%files[MusciIndex])
+ time.sleep(0.05)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/ToneGenerator.py b/PocketBeagle/Grove/ToneGenerator.py
new file mode 100644
index 0000000..ba00a2f
--- /dev/null
+++ b/PocketBeagle/Grove/ToneGenerator.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+import numpy as np
+import pyaudio
+import wave
+import time
+from Shell import GetCmdReturn
+import os
+tone_freq_map={"do": 261.5, "re": 293.4,"me": 329.5,"fa": 349.1,"so": 391.7, \
+"la": 440,"ti": 493.8,"do+":523}
+_SCALE_DEFS = [
+ 'do.wav',
+ 're.wav',
+ 'me.wav',
+ 'fa.wav',
+ 'so.wav',
+ 'la.wav',
+ 'ti.wav',
+ 'do+.wav'
+ ]
+channels = 1
+sampwidth = 2
+framerate = 44100
+def synthesizer(freq,duration = 10,amp=250,sampling_freq=framerate):
+ """produce the tone list
+ freq:frequency of tone
+ duration: duration of tone
+ amp:Gain of tone
+ sampling_freq : sampling frequency of tone
+ """
+ samples = amp * (np.sin(2*np.pi*np.arange(sampling_freq*duration)*freq/sampling_freq))
+ samples = samples.astype(np.float16)
+ return samples
+def main():
+ # Rebuild the /tmp/scale
+ GetCmdReturn('sudo rm -rf /tmp/scale')
+ while os.path.exists('/tmp/scale'):
+ time.sleep(0.1)
+ GetCmdReturn('sudo mkdir /tmp/scale')
+ while not os.path.exists('/tmp/scale'):
+ time.sleep(0.1)
+ GetCmdReturn('sudo chown debian:debian /tmp/scale')
+ tone_freq = [ v for v in sorted(tone_freq_map.values())]
+ for i in range(len(tone_freq)):
+ # Set tone to wav
+ f = wave.open( "/tmp/scale/%s"%_SCALE_DEFS[i],"wb")
+ f.setnchannels(channels)
+ f.setsampwidth(sampwidth)
+ f.setframerate(framerate)
+ f.writeframes(synthesizer(tone_freq[i]).tostring())
+ f.close()
+ print("/tmp/scale/%s generated successfully"%_SCALE_DEFS[i])
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/UltrasonicSensor.py b/PocketBeagle/Grove/UltrasonicSensor.py
new file mode 100644
index 0000000..3153dd7
--- /dev/null
+++ b/PocketBeagle/Grove/UltrasonicSensor.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+# [Grove - Ultrasonic Distance Sensor]
+# (http://wiki.seeedstudio.com/Grove-Ultrasonic_Ranger/) on A0
+import iio
+import time
+from Shell import ConfigGPIO,InstallDTBO
+import os
+class HCSR04:
+ """HCSR04 Ultrasonic distance sensor"""
+ def __init__(self):
+ """Initialize the HCSR04 using iio python library
+ """
+ self.Path = '/proc/device-tree/hcsr04_1057@20'
+ try:
+ # Config P1_31 to GPIO mode
+ ConfigGPIO('P1_31')
+ # Check BB-GPIO-HCSR04 whether install successfully
+ # if not reinstall it
+ if not os.path.exists(self.Path):
+ InstallDTBO('BB-GPIO-P9813')
+ while not os.path.exists(self.Path):
+ time.sleep(0.1)
+ # Scan the adxl345 by using IIO python library
+ self.contexts = iio.scan_contexts()
+ self.ctx = iio.Context("local:")
+ self.dev = self.ctx.find_device("hcsr04_1057@20")
+ if not self.dev:
+ print("maybe you should reinstall the driver of hcsr")
+ return
+ except IOError as err:
+ print("File Error:"+str(err))
+ print("maybe you should reinstall the driver of hcsr04")
+ def GetDistance(self):
+ """Get the GetDistance using IIO python library
+ """
+ return int(self.dev.find_channel("distance", False).attrs["input"].value)
+def main():
+ Distance = HCSR04()
+ while True:
+ print('The Distance is:%d'%(Distance.GetDistance()), end = ' \r')
+ time.sleep(0.5)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/PocketBeagle/Grove/VL53L0X/Makefile b/PocketBeagle/Grove/VL53L0X/Makefile
deleted file mode 100644
index a9b8d02..0000000
--- a/PocketBeagle/Grove/VL53L0X/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-obj-m += vl53l0x-i2c.o
-
-
-export KROOT=/lib/modules/$(shell uname -r)/build
-
-all: modules
-
-modules modules_install clean::
- @$(MAKE) -C $(KROOT) M=$(shell pwd) $@
-
-clean::
- rm -rf Module.symvers modules.order
diff --git a/PocketBeagle/Grove/VL53L0X/vl53l0x-i2c.c b/PocketBeagle/Grove/VL53L0X/vl53l0x-i2c.c
deleted file mode 100644
index b48216c..0000000
--- a/PocketBeagle/Grove/VL53L0X/vl53l0x-i2c.c
+++ /dev/null
@@ -1,164 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for ST VL53L0X FlightSense ToF Ranging Sensor on a i2c bus.
- *
- * Copyright (C) 2016 STMicroelectronics Imaging Division.
- * Copyright (C) 2018 Song Qiang
- *
- * Datasheet available at
- *
- *
- * Default 7-bit i2c slave address 0x29.
- *
- * TODO: FIFO buffer, continuous mode, interrupts, range selection,
- * sensor ID check.
- */
-
-#include
-#include
-#include
-
-#include
-
-#define VL_REG_SYSRANGE_START 0x00
-
-#define VL_REG_SYSRANGE_MODE_MASK GENMASK(3, 0)
-#define VL_REG_SYSRANGE_MODE_SINGLESHOT 0x00
-#define VL_REG_SYSRANGE_MODE_START_STOP BIT(0)
-#define VL_REG_SYSRANGE_MODE_BACKTOBACK BIT(1)
-#define VL_REG_SYSRANGE_MODE_TIMED BIT(2)
-#define VL_REG_SYSRANGE_MODE_HISTOGRAM BIT(3)
-
-#define VL_REG_RESULT_INT_STATUS 0x13
-#define VL_REG_RESULT_RANGE_STATUS 0x14
-#define VL_REG_RESULT_RANGE_STATUS_COMPLETE BIT(0)
-
-struct vl53l0x_data {
- struct i2c_client *client;
-};
-
-static int vl53l0x_read_proximity(struct vl53l0x_data *data,
- const struct iio_chan_spec *chan,
- int *val)
-{
- struct i2c_client *client = data->client;
- u16 tries = 20;
- u8 buffer[12];
- int ret;
-
- ret = i2c_smbus_write_byte_data(client, VL_REG_SYSRANGE_START, 1);
- if (ret < 0)
- return ret;
-
- do {
- ret = i2c_smbus_read_byte_data(client,
- VL_REG_RESULT_RANGE_STATUS);
- if (ret < 0)
- return ret;
-
- if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE)
- break;
-
- usleep_range(1000, 5000);
- } while (--tries);
- if (!tries)
- return -ETIMEDOUT;
-
- ret = i2c_smbus_read_i2c_block_data(client, VL_REG_RESULT_RANGE_STATUS,
- 12, buffer);
- if (ret < 0)
- return ret;
- else if (ret != 12)
- return -EREMOTEIO;
-
- /* Values should be between 30~1200 in millimeters. */
- *val = (buffer[10] << 8) + buffer[11];
-
- return 0;
-}
-
-static const struct iio_chan_spec vl53l0x_channels[] = {
- {
- .type = IIO_DISTANCE,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
- BIT(IIO_CHAN_INFO_SCALE),
- },
-};
-
-static int vl53l0x_read_raw(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- int *val, int *val2, long mask)
-{
- struct vl53l0x_data *data = iio_priv(indio_dev);
- int ret;
-
- if (chan->type != IIO_DISTANCE)
- return -EINVAL;
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- ret = vl53l0x_read_proximity(data, chan, val);
- if (ret < 0)
- return ret;
-
- return IIO_VAL_INT;
- case IIO_CHAN_INFO_SCALE:
- *val = 0;
- *val2 = 1000;
-
- return IIO_VAL_INT_PLUS_MICRO;
- default:
- return -EINVAL;
- }
-}
-
-static const struct iio_info vl53l0x_info = {
- .read_raw = vl53l0x_read_raw,
-};
-
-static int vl53l0x_probe(struct i2c_client *client)
-{
- struct vl53l0x_data *data;
- struct iio_dev *indio_dev;
-
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
- if (!indio_dev)
- return -ENOMEM;
-
- data = iio_priv(indio_dev);
- data->client = client;
- i2c_set_clientdata(client, indio_dev);
-
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_I2C_BLOCK |
- I2C_FUNC_SMBUS_BYTE_DATA))
- return -EOPNOTSUPP;
-
- indio_dev->dev.parent = &client->dev;
- indio_dev->name = "vl53l0x";
- indio_dev->info = &vl53l0x_info;
- indio_dev->channels = vl53l0x_channels;
- indio_dev->num_channels = ARRAY_SIZE(vl53l0x_channels);
- indio_dev->modes = INDIO_DIRECT_MODE;
-
- return devm_iio_device_register(&client->dev, indio_dev);
-}
-
-static const struct of_device_id st_vl53l0x_dt_match[] = {
- { .compatible = "st,vl53l0x", },
- { }
-};
-MODULE_DEVICE_TABLE(of, st_vl53l0x_dt_match);
-
-static struct i2c_driver vl53l0x_driver = {
- .driver = {
- .name = "vl53l0x-i2c",
- .of_match_table = st_vl53l0x_dt_match,
- },
- .probe_new = vl53l0x_probe,
-};
-module_i2c_driver(vl53l0x_driver);
-
-MODULE_AUTHOR("Song Qiang ");
-MODULE_DESCRIPTION("ST vl53l0x ToF ranging sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/PocketBeagle/Grove/img/Overview.jpg b/PocketBeagle/Grove/img/Overview.jpg
new file mode 100644
index 0000000..710735b
Binary files /dev/null and b/PocketBeagle/Grove/img/Overview.jpg differ
diff --git a/PocketBeagle/Grove/img/PocketBeagleKit.jpg b/PocketBeagle/Grove/img/PocketBeagleKit.jpg
new file mode 100644
index 0000000..def9927
Binary files /dev/null and b/PocketBeagle/Grove/img/PocketBeagleKit.jpg differ
diff --git a/PocketBeagle/Grove/img/project1.jpg b/PocketBeagle/Grove/img/project1.jpg
new file mode 100644
index 0000000..6972530
Binary files /dev/null and b/PocketBeagle/Grove/img/project1.jpg differ
diff --git a/PocketBeagle/Grove/img/project2.jpg b/PocketBeagle/Grove/img/project2.jpg
new file mode 100644
index 0000000..637197d
Binary files /dev/null and b/PocketBeagle/Grove/img/project2.jpg differ
diff --git a/PocketBeagle/Grove/img/project3.jpg b/PocketBeagle/Grove/img/project3.jpg
new file mode 100644
index 0000000..c61609c
Binary files /dev/null and b/PocketBeagle/Grove/img/project3.jpg differ
diff --git a/PocketBeagle/Grove/img/project4.jpg b/PocketBeagle/Grove/img/project4.jpg
new file mode 100644
index 0000000..c61609c
Binary files /dev/null and b/PocketBeagle/Grove/img/project4.jpg differ
diff --git a/PocketBeagle/Grove/img/project5.jpg b/PocketBeagle/Grove/img/project5.jpg
new file mode 100644
index 0000000..8914074
Binary files /dev/null and b/PocketBeagle/Grove/img/project5.jpg differ
diff --git a/PocketBeagle/Grove/img/project6.jpg b/PocketBeagle/Grove/img/project6.jpg
new file mode 100644
index 0000000..38f7237
Binary files /dev/null and b/PocketBeagle/Grove/img/project6.jpg differ
diff --git a/PocketBeagle/Grove/img/project7.jpg b/PocketBeagle/Grove/img/project7.jpg
new file mode 100644
index 0000000..79e2776
Binary files /dev/null and b/PocketBeagle/Grove/img/project7.jpg differ
diff --git a/PocketBeagle/Grove/img/project8.jpg b/PocketBeagle/Grove/img/project8.jpg
new file mode 100644
index 0000000..6ca7d9e
Binary files /dev/null and b/PocketBeagle/Grove/img/project8.jpg differ
diff --git a/PocketBeagle/Grove/internalLED.py b/PocketBeagle/Grove/internalLED.py
new file mode 100644
index 0000000..64e56bb
--- /dev/null
+++ b/PocketBeagle/Grove/internalLED.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+import time
+state = 0 # Initial state
+led = open('/sys/class/leds/beaglebone:green:usr3/brightness', 'w')
+while True:
+ print(state, file=led)
+ led.flush()
+ if(state == 1):
+ state = 0
+ else:
+ state = 1
+ time.sleep(0.25)
diff --git a/PocketBeagle/Grove/workshop-handouts.md b/PocketBeagle/Grove/workshop-handouts.md
new file mode 100644
index 0000000..f51503e
--- /dev/null
+++ b/PocketBeagle/Grove/workshop-handouts.md
@@ -0,0 +1,102 @@
+# PocketBeagle Grove Kit Hands-On Coding Workshop
+
+* microSD software image and other materials available from bbb.io/grove
+
+See bbb.io/start for instructions on using Etcher.io to write a microSD card
+
+TODO: Add image for getting-started web page
+
+TOOD: Determine if all wires should be hooked up in this phase.
+
+Plug into the microUSB on PocketBeagle to provide power and a network connection. Look for the “heartbeat” pulse on the USR0 LED to know the board has Linux up-and-running.
+
+TODO: Add image for power connection to PocketBeagle
+
+## Get to the Cloud9 IDE
+Windows: http://192.168.7.2
+Linux/Mac: http://192.168.6.2
+
+TODO: Move to a single server type supported by latest Windows and Mac
+
+TODO: Add image of Cloud9 IDE startup
+
+----
+
+# PocketBeagle Grove Kit
+
+TODO: Add image of kit
+
+# PocketBeagle Grove Kit wiring summary
+
+TOOD: Document interconnections
+
+----
+
+# PocketBeagle
+
+TODO: add image of PocketBeagle
+
+* PocketBeagle® is an ultra-tiny-yet-complete, low-cost, open-source USB-key-fob computer.
+* Processor System:
Octavo Systems OSD3358-SM 21mm x 21mm system-in-package that includes 512MB DDR3 RAM, 1-GHz ARM Cortex-A8 CPU, 2x 200-MHz PRUs, ARM Cortex-M3, 3D accelerator, power/battery management and EEPROM
+* 72 expansion pin headers with power and battery I/Os, high-speed USB, 8 analog inputs, 44 digital I/Os and numerous digital interface peripherals
+* microUSB host/client and microSD connectors
+
+## PocketBeagle Expansion Header Pin-out
+
+TODO: add image of PocketBeagle expansion header
+
+Great getting started information is at beagleboard.org/pocket
+
+----
+
+# Blink PocketBeagle on-board USRx LED
+**Goal:** Blink USR3 LED on PocketBeagle
+**Overview:** Python is a popular programming language used by beginners. Linux exposes hardware interfaces as files, making it easy to use any programming language to interact with hardware. Here we will use Python and Linux to blink an LED built into your PocketBeagle.
+**Do this in the Cloud9 IDE:**
+
+1. Navigate to *PocketBeagle/Grove/internalLED.py* and double-click on it.
+2. Click the ```Run``` button in the toolbar to execute the script in the ```active file window```.
+3. You will see the ```run configuration window``` open with a ```Stop``` button. Click the ```Stop``` button to halt the program.
+4. Try changing the LED or blink time, save the program and run again.
+
+TODO: Add image of Cloud9 IDE.
+
+## internalLED.py
+
+```
+#!/usr/bin/env python3
+import time
+state = 0 # Initial state
+led = open('/sys/class/leds/beaglebone:green:usr3/brightness', 'w')
+while True:
+ print(state, file=led)
+ led.flush()
+ if(state == 1):
+ state = 0
+ else:
+ state = 1
+ time.sleep(0.25)
+```
+
+----
+
+# Read a button
+
+**Goal:** Sense the external world by reading a digital input.
+**Overview:** Reading a switch attached to a GPIO (general purpose input/output) port isn't
+as easy as just reading and writing a file anymore. They call that progress. Learn how to
+map the Grove ports to PocketBeagle pins to OSD3358 balls to AM3358 balls to GPIO identifiers
+and access them using ```libgpiod```.
+ Note the
+buttons are “active low”.
+**Do this in the Cloud9 IDE:**
+
+1. Navigate to TechLab/pushbutton.js and double-click on it.
+2. Click the Run button in the toolbar to execute the script in the active file window
+3. Press the “L” button on TechLab and check the output (Value=1 or Value=0) in the configuration window.
Click the Stop button on the IDE to halt the program.
+
+**Challenge #1:** Can you modify the program to read from the “R” button?
+**Challenge #2:** Can you modify the program to toggle the USR3 LED?
+**Challenge #3:** Can you modify the program to turn the USR3 LED on with the “L” button and off with the “R” button?
+
+
diff --git a/PocketBeagle/README.md b/PocketBeagle/README.md
index 89c7c18..c0fb0fb 100644
--- a/PocketBeagle/README.md
+++ b/PocketBeagle/README.md
@@ -4,18 +4,20 @@ These examples have been taken from many places and customized for PocketBeagle.
* Digi-Key shopping list: http://www.digikey.com/short/q8tmdv
-
+
The following files are:
-```
-analogInOut.js // Reads analog in on P1_19 and adjusts the PWM on P1_36.
-analogInSync.js // Reads analog in on P1_19 synchronously and prints it.
-analogInCallback.js // Reads analog in on P1_19 and prints it via a callback.
-blinkLED.c // Blinks the USR3 LED via c
-blinkLED.js // Blinks the USR LEDs and P1_36
-blinkLED.py // Blinks one LED wired to P1_36 via python
-fadeLED.js // Fades the LED wired to P1_36 using the PWM.
-input.js // Responds to changes on P8_19 via a callback.
-input2.js // Responds to changes on P8_19 and P9_16 via callbacks.
-swipeLED.js // Blinks the USR LEDs in sequence.
-```
+
+File | Description
+---- | -----------
+[analogInOut.js](analogInOut.js) | Reads analog in and adjusts the PWM.
+[analogInSync.js](nalogInSync.js) | Reads analog in synchronously and prints it.
+[analogInCallback.js](analogInCallback.js) | Reads analog in and prints it via a callback.
+[blinkLED.c](blinkLED.c ) | Blinks the USR3 LED via c.
+[blinkLED.js](blinkLED.js) | Blinks the USR LEDs and P9_14.
+[blinkLED.py](blinkLED.py) | Blinks one LED via python.
+[fadeLED.js](fadeLED.js) | Fades the LED using the PWM.
+[input.js](input.js) | Responds to changes on input via a callback.
+[input2.js](input2.js) | Responds to changes on 2 inputs via callbacks.
+[seqLED.py](seqLED.py) | Blinks the USR LEDs in sequence in python.
+[swipeLED.js](swipeLED.js) | Blinks the USR LEDs in sequence.
diff --git a/PocketBeagle/TechLab/.challenges/analogIn.pru0.c b/PocketBeagle/TechLab/.challenges/analogIn.pru0.c
new file mode 100644
index 0000000..747e870
--- /dev/null
+++ b/PocketBeagle/TechLab/.challenges/analogIn.pru0.c
@@ -0,0 +1,182 @@
+////////////////////////////////////////
+// analogIn.pru0.c
+// Reads AIN0 and outputs to /dev/rpmsg_pru30 when sent a message
+// Usage: echo x > /dev/rpmsg_pru30, cat /dev/rpmsg_pru30
+// Wiring: PocketBeagle + TechLab
+// Setup: tested with 4.14.108-ti-r124 kernel
+// See:
+// PRU: pru0
+////////////////////////////////////////
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "resource_table_0.h"
+#include "prugpio.h"
+#include "hw_types.h"
+#include "tsc_adc.h"
+#include "soc_AM335x.h"
+#include "hw_control_AM335x.h"
+#include "hw_cm_per.h"
+#include "hw_cm_wkup.h"
+
+
+static void ADCConfigure(void);
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+/* Host-0 Interrupt sets bit 30 in register R31 */
+#define HOST_INT ((uint32_t) 1 << 30)
+
+/* The PRU-ICSS system events used for RPMsg are defined in the Linux device tree
+ * PRU0 uses system event 16 (To ARM) and 17 (From ARM)
+ * PRU1 uses system event 18 (To ARM) and 19 (From ARM)
+ * Be sure to change the values in resource_table_0.h too.
+ */
+#define TO_ARM_HOST 16
+#define FROM_ARM_HOST 17
+
+/*
+* Using the name 'rpmsg-pru' will probe the rpmsg_pru driver found
+* at linux-x.y.z/drivers/rpmsg/rpmsg_pru.c
+*/
+#define CHAN_NAME "rpmsg-pru"
+#define CHAN_DESC "Channel 30"
+#define CHAN_PORT 30
+
+/*
+ * Used to make sure the Linux drivers are ready for RPMsg communication
+ * Found at linux-x.y.z/include/uapi/linux/virtio_config.h
+ */
+#define VIRTIO_CONFIG_S_DRIVER_OK 4
+
+char payload[RPMSG_BUF_SIZE];
+
+/*
+ * main.c
+ */
+void main(void)
+{
+ struct pru_rpmsg_transport transport;
+ uint16_t src, dst, len;
+ volatile uint8_t *status;
+ unsigned int i, count, data, sample;
+
+ ADCConfigure();
+
+ /* Allow OCP master port access by the PRU so the PRU can read external memories */
+ CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+ /* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
+ CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
+
+ /* Make sure the Linux drivers are ready for RPMsg communication */
+ status = &resourceTable.rpmsg_vdev.status;
+ while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));
+
+ /* Initialize the RPMsg transport structure */
+ pru_rpmsg_init(&transport, &resourceTable.rpmsg_vring0, &resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);
+
+ /* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
+ while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC, CHAN_PORT) != PRU_RPMSG_SUCCESS);
+ while (1) {
+ /* Check bit 30 of register R31 to see if the ARM has kicked us */
+ if (__R31 & HOST_INT) {
+ /* Clear the event status */
+ CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
+ /* Receive all available messages, multiple messages can be sent per kick */
+ while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) {
+ /* Start step */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPENABLE) = 0xfe;
+
+ /* Wait for interrupt */
+ while (!(HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_IRQSTATUS)&0x02));
+
+ /* Clear interrupt */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_IRQSTATUS) = 0x02;
+
+ sample = 0xFFFFFFFF;
+
+ count = HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_FIFOCOUNT(0));
+ //sample = count;
+ for (i = 0; i < count; i++) {
+ data = HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_FIFODATA(0));
+ if ((data & 0x000F0000) == 0) {
+ /* if channel == 0 */
+ sample = data & 0xFFF;
+ }
+ }
+ memcpy(payload, "\0\0\0\0\0\0\0\0\0\0", 10);
+ ltoa((long)sample, payload);
+ //len = strlen(payload) + 1;
+ pru_rpmsg_send(&transport, dst, src, payload, 10);
+ }
+ }
+ }
+}
+
+static void ADCConfigure(void)
+{
+ unsigned int i, count, data;
+
+ /* Enable ADC module clock */
+ HWREG(SOC_CM_WKUP_REGS + CM_WKUP_ADC_TSC_CLKCTRL) = 0x02;
+
+ /* Disable ADC module for configuration */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) &= ~0x01;
+
+ /* fs = 24MHz / ((CLKDIV+1)*2*Channels*(OpenDly+Average*(14+SampleDly)))
+ * = 53.57kHz
+ * CLKDIV = 0
+ * Channels = 1
+ * Average = 16
+ * OpenDly = 0
+ * SampleDly = 0
+ */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_ADC_CLKDIV) = 0;
+
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_ADCRANGE) = 0xFFF << 16;
+
+ /* Disable all steps for now */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPENABLE) &= 0xFF;
+
+ /* Unlock step configuration */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) |= 0x04;
+
+ /* Step 1 config: SW mode, one shot mode, fifo 0, channel 0 */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPCONFIG(0)) = 0x00000000;
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_STEPDELAY(0)) = 0xFF000000;
+
+ /* Enable channel ID tag */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) |= 0x02;
+
+ /* Clear end-of-sequence interrupt */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_IRQSTATUS) = 0x02;
+
+ /* Enable end-of-sequence interrupt */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_IRQENABLE_SET) = 0x02;
+
+ /* Lock step configuration */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) &= ~0x04;
+
+ /* Empty FIFO 0 */
+ count = HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_FIFOCOUNT(0));
+ for (i = 0; i < count; i++) {
+ data = HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_FIFODATA(0));
+ }
+
+ /* Enable ADC module */
+ HWREG(SOC_ADC_TSC_0_REGS + TSC_ADC_SS_CTRL) |= 0x01;
+}
+
+// Sets pinmux
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =
+ "/sys/bus/platform/drivers/ti_am3359-tscadc/unbind\00044e0d000.tscadc\0"
+ "\0\0";
diff --git a/PocketBeagle/TechLab/.challenges/buzz-button.pru0c b/PocketBeagle/TechLab/.challenges/buzz-button.pru0.c
similarity index 100%
rename from PocketBeagle/TechLab/.challenges/buzz-button.pru0c
rename to PocketBeagle/TechLab/.challenges/buzz-button.pru0.c
diff --git a/PocketBeagle/TechLab/.challenges/buzz.pru0c b/PocketBeagle/TechLab/.challenges/buzz.pru0.c
similarity index 100%
rename from PocketBeagle/TechLab/.challenges/buzz.pru0c
rename to PocketBeagle/TechLab/.challenges/buzz.pru0.c
diff --git a/PocketBeagle/TechLab/.challenges/rgbLEDrpmsg.js b/PocketBeagle/TechLab/.challenges/rgbLEDrpmsg.js
new file mode 100644
index 0000000..bdd8420
--- /dev/null
+++ b/PocketBeagle/TechLab/.challenges/rgbLEDrpmsg.js
@@ -0,0 +1,41 @@
+#!/usr/bin/env node
+var fs = require('fs');
+var os = require('os');
+var process = require('process');
+
+var buffer = Buffer.alloc(64);
+
+fs.open("/dev/rpmsg_pru30", "r+", null, onOpen);
+
+function onOpen(err, fd) {
+ if (err) {
+ console.log("Unble to open /dev/rpmsg_pru30");
+ os.exit(-1);
+ }
+ fs.read(fd, buffer, 0, 60, null, onData);
+
+ process.stdin.setEncoding('utf8');
+ process.stdin.on('readable', onStdin);
+ console.log("Type red, green, blue or white and press ");
+
+ function onStdin(err) {
+ var chunk;
+ if (err) {
+ console.log("Error reading from /dev/rpmsg_pru30");
+ os.exit(-1);
+ }
+ while ((chunk = process.stdin.read()) !== null) {
+ fs.write(fd, chunk);
+ }
+ }
+
+ function onData(err, bytes, data) {
+ if(err) {
+ console.log("Error reading from /dev/rpmsg_pru30");
+ os.exit(-1);
+ }
+ console.log('response: ' + data.toString('ascii'));
+ fs.read(fd, buffer, 0, 60, null, onData);
+ }
+}
+
diff --git a/PocketBeagle/TechLab/.challenges/rgbLEDrpmsg.pru0.c b/PocketBeagle/TechLab/.challenges/rgbLEDrpmsg.pru0.c
new file mode 100644
index 0000000..7bcecac
--- /dev/null
+++ b/PocketBeagle/TechLab/.challenges/rgbLEDrpmsg.pru0.c
@@ -0,0 +1,161 @@
+////////////////////////////////////////
+// rgbLEDrpmsg.pru0
+// Uses rpmsg accept messages to /dev/rpmsg_pru30 by the ARM
+// Usage: echo green > /dev/rpmsg_pru30 to set the TechLab RGB LED green
+// Wiring: PocketBeagle + TechLab
+// Setup: tested with 4.14.108-ti-r124 kernel
+// See:
+// PRU: pru0
+////////////////////////////////////////
+#include
+#include
+#include // atoi
+#include
+#include
+#include
+#include
+#include
+#include "resource_table_0.h"
+#include "prugpio.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+/* Host-0 Interrupt sets bit 30 in register R31 */
+#define HOST_INT ((uint32_t) 1 << 30)
+
+/* The PRU-ICSS system events used for RPMsg are defined in the Linux device tree
+ * PRU0 uses system event 16 (To ARM) and 17 (From ARM)
+ * PRU1 uses system event 18 (To ARM) and 19 (From ARM)
+ * Be sure to change the values in resource_table_0.h too.
+ */
+#define TO_ARM_HOST 16
+#define FROM_ARM_HOST 17
+
+/*
+* Using the name 'rpmsg-pru' will probe the rpmsg_pru driver found
+* at linux-x.y.z/drivers/rpmsg/rpmsg_pru.c
+*/
+#define CHAN_NAME "rpmsg-pru"
+#define CHAN_DESC "Channel 30"
+#define CHAN_PORT 30
+
+/*
+ * Used to make sure the Linux drivers are ready for RPMsg communication
+ * Found at linux-x.y.z/include/uapi/linux/virtio_config.h
+ */
+#define VIRTIO_CONFIG_S_DRIVER_OK 4
+
+/* GPIO1 */
+unsigned int volatile * const GPIO1_CLEAR = ((unsigned int *) GPIO1) + (GPIO_CLEARDATAOUT);
+unsigned int volatile * const GPIO1_SET = ((unsigned int *) GPIO1) + (GPIO_SETDATAOUT);
+
+/* PRU GPIO */
+volatile register unsigned int __R30;
+volatile register unsigned int __R31;
+
+#define DECAY_RATE 75
+#define DELAY_CYCLES 2
+#define RED 1
+#define GREEN 2
+#define BLUE 3
+#define WHITE 4
+
+void setLED(void);
+
+char payload[RPMSG_BUF_SIZE];
+volatile int state = RED;
+
+/*
+ * main.c
+ */
+void main(void)
+{
+ struct pru_rpmsg_transport transport;
+ uint16_t src, dst, len;
+ volatile uint8_t *status;
+
+ /* Allow OCP master port access by the PRU so the PRU can read external memories */
+ CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+ setLED();
+
+ /* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
+ CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
+
+ /* Make sure the Linux drivers are ready for RPMsg communication */
+ status = &resourceTable.rpmsg_vdev.status;
+ while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));
+
+ /* Initialize the RPMsg transport structure */
+ pru_rpmsg_init(&transport, &resourceTable.rpmsg_vring0, &resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);
+
+ /* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
+ while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC, CHAN_PORT) != PRU_RPMSG_SUCCESS);
+ while (1) {
+ /* Check bit 30 of register R31 to see if the ARM has kicked us */
+ if (__R31 & HOST_INT) {
+ /* Clear the event status */
+ CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
+ /* Receive all available messages, multiple messages can be sent per kick */
+ while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) {
+ /* Set the state based on the payload */
+ if(!strncmp("red\n", payload, 1)) {
+ pru_rpmsg_send(&transport, dst, src, "r", 2);
+ state = RED;
+ } else if(!strncmp("blue\n", payload, 1)) {
+ pru_rpmsg_send(&transport, dst, src, "b", 2);
+ state = BLUE;
+ } else if(!strncmp("green\n", payload, 1)) {
+ pru_rpmsg_send(&transport, dst, src, "g", 2);
+ state = GREEN;
+ } else if(!strncmp("white\n", payload, 1)) {
+ pru_rpmsg_send(&transport, dst, src, "w", 2);
+ state = WHITE;
+ } else {
+ pru_rpmsg_send(&transport, dst, src, "w", 2);
+ state = 0;
+ }
+
+ setLED();
+ }
+ }
+ }
+}
+
+void setLED(void) {
+ /* Clear all LEDs */
+ *GPIO1_CLEAR = (P2_1 | USR3);
+ __R30 &= ~(P1_33 | P1_36);
+
+ /* Turn on correct LEDs */
+ switch(state) {
+ case RED:
+ *GPIO1_SET = (USR3);
+ __R30 |= (P1_33);
+ break;
+ case GREEN:
+ *GPIO1_SET = (P2_1 | USR3);
+ break;
+ case BLUE:
+ *GPIO1_SET = (USR3);
+ __R30 |= (P1_36);
+ break;
+ case WHITE:
+ *GPIO1_SET = (P2_1 | USR3);
+ __R30 |= (P1_33 | P1_36);
+ break;
+ default:
+ break;
+ }
+}
+// Sets pinmux
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =
+ "/sys/class/leds/beaglebone:green:usr3/trigger\0none\0" \
+ "/sys/devices/platform/ocp/ocp:P1_36_pinmux/state\0pruout\0" \
+ "/sys/devices/platform/ocp/ocp:P1_33_pinmux/state\0pruout\0" \
+ "/sys/devices/platform/ocp/ocp:P2_01_pinmux/state\0gpio\0" \
+ "/sys/class/gpio/gpio50/direction\0out\0" \
+ "\0\0";
diff --git a/PocketBeagle/TechLab/README.md b/PocketBeagle/TechLab/README.md
index 9d17ad4..4b529df 100644
--- a/PocketBeagle/TechLab/README.md
+++ b/PocketBeagle/TechLab/README.md
@@ -2,7 +2,7 @@
## Setup microSD card
-Use http://debian.beagleboard.org/images/bone-debian-9.9-iot-armhf-2019-08-03-4gb.img.xz image or newer
+Use https://debian.beagleboard.org/images/bone-debian-10.3-iot-armhf-2020-04-06-4gb.img.xz image
## Login
@@ -22,11 +22,22 @@ With overlays, you'll be looking at interfaces provided by relatively complete d
about how those drivers are built and configured, once you understand how to use them. They often expose interesting
features of the Linux kernel.
+### Single overlay
+If you do this one, don't do the individual overlays.
+
+```
+sudo perl -pe 's%#?uboot_overlay_addr0=.*$%uboot_overlay_addr0=/lib/firmware/BBORG_TECHLAB-00A2.dtbo%;' -i /boot/uEnv.txt
+sudo shutdown -r now
+```
+
+### Individual overlays
+If you do the single overlay, don't do these individual overlays. These provide more fine-grained
+control over what drivers are loaded and simpler examples to read.
+
```
sudo perl -pe 's%#?uboot_overlay_addr0=.*$%uboot_overlay_addr0=/lib/firmware/PB-I2C2-ACCEL-TECHLAB-CAPE.dtbo%;' -i /boot/uEnv.txt
sudo perl -pe 's%#?uboot_overlay_addr1=.*$%uboot_overlay_addr1=/lib/firmware/PB-PWM-RGB-TECHLAB-CAPE.dtbo%;' -i /boot/uEnv.txt
sudo perl -pe 's%#?uboot_overlay_addr2=.*$%uboot_overlay_addr2=/lib/firmware/PB-SPI1-7SEG-TECHLAB-CAPE.dtbo%;' -i /boot/uEnv.txt
-sudo perl -pe 's%#?uboot_overlay_pru=.*RPROC.*$%uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-14-TI-00A0.dtbo%;' -i /boot/uEnv.txt
sudo shutdown -r now
```
diff --git a/PocketBeagle/TechLab/fadeLED.js b/PocketBeagle/TechLab/fadeLED.js
index 325b170..643c19b 100755
--- a/PocketBeagle/TechLab/fadeLED.js
+++ b/PocketBeagle/TechLab/fadeLED.js
@@ -1,5 +1,5 @@
#!/usr/bin/env node
-var b = require('bonescript');
+var fs = require('fs');
var LED = '/sys/class/leds/techlab::blue/brightness';
var step = 10, // Step size
min = 0, // dimmest value
@@ -17,7 +17,7 @@ function doInterval(err, x) {
}
function fade() {
- b.writeTextFile(LED, brightness);
+ fs.writeFileSync(LED, brightness);
brightness += step;
if(brightness >= max || brightness <= min) {
step = -1 * step;
diff --git a/PocketBeagle/TechLab/handouts/media/image2.png b/PocketBeagle/TechLab/handouts/media/image2.png
new file mode 100644
index 0000000..ef98fe3
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image2.png differ
diff --git a/PocketBeagle/TechLab/handouts/media/image20.png b/PocketBeagle/TechLab/handouts/media/image20.png
new file mode 100644
index 0000000..f870d8b
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image20.png differ
diff --git a/PocketBeagle/TechLab/handouts/media/image21.png b/PocketBeagle/TechLab/handouts/media/image21.png
new file mode 100644
index 0000000..29a1699
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image21.png differ
diff --git a/PocketBeagle/TechLab/handouts/media/image22.jpeg b/PocketBeagle/TechLab/handouts/media/image22.jpeg
new file mode 100644
index 0000000..795ea15
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image22.jpeg differ
diff --git a/PocketBeagle/TechLab/handouts/media/image23.jpeg b/PocketBeagle/TechLab/handouts/media/image23.jpeg
new file mode 100644
index 0000000..5affbf1
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image23.jpeg differ
diff --git a/PocketBeagle/TechLab/handouts/media/image24.png b/PocketBeagle/TechLab/handouts/media/image24.png
new file mode 100644
index 0000000..1588407
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image24.png differ
diff --git a/PocketBeagle/TechLab/handouts/media/image25.jpeg b/PocketBeagle/TechLab/handouts/media/image25.jpeg
new file mode 100644
index 0000000..9ec2cad
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image25.jpeg differ
diff --git a/PocketBeagle/TechLab/handouts/media/image26.jpeg b/PocketBeagle/TechLab/handouts/media/image26.jpeg
new file mode 100644
index 0000000..6feeca9
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image26.jpeg differ
diff --git a/PocketBeagle/TechLab/handouts/media/image27.jpeg b/PocketBeagle/TechLab/handouts/media/image27.jpeg
new file mode 100644
index 0000000..5e03249
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image27.jpeg differ
diff --git a/PocketBeagle/TechLab/handouts/media/image28.png b/PocketBeagle/TechLab/handouts/media/image28.png
new file mode 100644
index 0000000..8e7d96b
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image28.png differ
diff --git a/PocketBeagle/TechLab/handouts/media/image29.jpeg b/PocketBeagle/TechLab/handouts/media/image29.jpeg
new file mode 100644
index 0000000..acb42c2
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image29.jpeg differ
diff --git a/PocketBeagle/TechLab/handouts/media/image3.jpeg b/PocketBeagle/TechLab/handouts/media/image3.jpeg
new file mode 100644
index 0000000..6391273
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image3.jpeg differ
diff --git a/PocketBeagle/TechLab/handouts/media/image30.jpeg b/PocketBeagle/TechLab/handouts/media/image30.jpeg
new file mode 100644
index 0000000..832e24d
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image30.jpeg differ
diff --git a/PocketBeagle/TechLab/handouts/media/image4.png b/PocketBeagle/TechLab/handouts/media/image4.png
new file mode 100644
index 0000000..30a1c48
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image4.png differ
diff --git a/PocketBeagle/TechLab/handouts/media/image5.png b/PocketBeagle/TechLab/handouts/media/image5.png
new file mode 100644
index 0000000..fde9569
Binary files /dev/null and b/PocketBeagle/TechLab/handouts/media/image5.png differ
diff --git a/PocketBeagle/TechLab/internalLED.js b/PocketBeagle/TechLab/internalLED.js
index 8001285..41b9975 100755
--- a/PocketBeagle/TechLab/internalLED.js
+++ b/PocketBeagle/TechLab/internalLED.js
@@ -1,16 +1,15 @@
#!/usr/bin/env node
-var b = require('bonescript');
-var LED = 'USR3';
-var state = b.HIGH; // Initial state
-b.pinMode(LED, b.OUTPUT);
+var fs = require('fs');
+var LED = '/sys/class/leds/beaglebone:green:usr3/brightness';
+var state = 0; // Initial state
setInterval(flash, 250); // Change state every 250 ms
function flash() {
- b.digitalWrite(LED, state);
- if(state === b.HIGH) {
- state = b.LOW;
+ fs.writeFileSync(LED, state);
+ if(state == 1) {
+ state = 0;
} else {
- state = b.HIGH;
+ state = 1;
}
}
diff --git a/PocketBeagle/TechLab/pushbutton.js b/PocketBeagle/TechLab/pushbutton.js
index db3fcfc..d75a383 100755
--- a/PocketBeagle/TechLab/pushbutton.js
+++ b/PocketBeagle/TechLab/pushbutton.js
@@ -1,26 +1,28 @@
#!/usr/bin/env node
-var b = require('bonescript');
-var button = "P2_33";
+// Pre-steps (may need to eventually put in this program):
+// * Make sure /sys/class/gpio/gpio45 is exported
+// * Make sure pinmux is in gpio mode
+// * Make sure gpio is in input mode
+var Epoll = require('epoll').Epoll;
+var fs = require('fs');
+var button = fs.openSync("/sys/class/gpio/gpio45/value", "r"); // P2_33
+var buffer = Buffer.alloc(1);
-console.log('Hit ^C to stop');
-b.pinMode(button, b.INPUT, 7, null, null, doAttach);
+fs.writeFileSync('/sys/class/gpio/gpio45/edge', "both");
+doRead(button);
+var poller = new Epoll(printStatus);
+poller.add(button, Epoll.EPOLLPRI);
+console.log("Ready. Please press 'L' button on TechLab. Hit ^C to stop.");
-function doAttach(err, x) {
- if(err) {
- console.log('pinMode err = ' + err);
- return;
- }
- b.attachInterrupt(button, true, b.CHANGE, printStatus);
+function doRead(fd) {
+ fs.readSync(fd, buffer, 0, 1, 0);
+ process.stdout.write('value = ' + buffer.toString() + ' \r');
}
-function printStatus(err, x) {
+function printStatus(err, fd, events) {
if(err) {
- console.log('attachInterrupt err = ' + err);
+ console.log('err = ' + err);
return;
}
- if(x.attached) {
- console.log("Ready. Please press 'L' button on TechLab.");
- return;
- }
- process.stdout.write('value = ' + x.value + ' \r');
-}
\ No newline at end of file
+ doRead(fd);
+}
diff --git a/PocketBeagle/TechLab/slides/media/image1.jpeg b/PocketBeagle/TechLab/slides/media/image1.jpeg
new file mode 100644
index 0000000..8476067
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image1.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image10.png b/PocketBeagle/TechLab/slides/media/image10.png
new file mode 100644
index 0000000..280533a
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image10.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image11.png b/PocketBeagle/TechLab/slides/media/image11.png
new file mode 100644
index 0000000..2b936b7
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image11.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image12.png b/PocketBeagle/TechLab/slides/media/image12.png
new file mode 100644
index 0000000..87a713c
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image12.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image14.png b/PocketBeagle/TechLab/slides/media/image14.png
new file mode 100644
index 0000000..7dfc726
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image14.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image15.png b/PocketBeagle/TechLab/slides/media/image15.png
new file mode 100644
index 0000000..23b1f6e
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image15.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image16.jpeg b/PocketBeagle/TechLab/slides/media/image16.jpeg
new file mode 100644
index 0000000..8d2690a
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image16.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image17.png b/PocketBeagle/TechLab/slides/media/image17.png
new file mode 100644
index 0000000..a958cb7
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image17.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image18.png b/PocketBeagle/TechLab/slides/media/image18.png
new file mode 100644
index 0000000..e7b4069
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image18.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image19.png b/PocketBeagle/TechLab/slides/media/image19.png
new file mode 100644
index 0000000..372e736
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image19.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image20.png b/PocketBeagle/TechLab/slides/media/image20.png
new file mode 100644
index 0000000..6b95dbc
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image20.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image21.png b/PocketBeagle/TechLab/slides/media/image21.png
new file mode 100644
index 0000000..68af15b
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image21.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image22.jpeg b/PocketBeagle/TechLab/slides/media/image22.jpeg
new file mode 100644
index 0000000..92345b8
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image22.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image23.jpeg b/PocketBeagle/TechLab/slides/media/image23.jpeg
new file mode 100644
index 0000000..950ddc7
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image23.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image24.png b/PocketBeagle/TechLab/slides/media/image24.png
new file mode 100644
index 0000000..8e5a386
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image24.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image25.png b/PocketBeagle/TechLab/slides/media/image25.png
new file mode 100644
index 0000000..7f8b831
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image25.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image26.jpeg b/PocketBeagle/TechLab/slides/media/image26.jpeg
new file mode 100644
index 0000000..b3b71fd
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image26.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image27.png b/PocketBeagle/TechLab/slides/media/image27.png
new file mode 100644
index 0000000..6afda11
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image27.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image28.jpeg b/PocketBeagle/TechLab/slides/media/image28.jpeg
new file mode 100644
index 0000000..2462515
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image28.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image29.jpeg b/PocketBeagle/TechLab/slides/media/image29.jpeg
new file mode 100644
index 0000000..1b1e640
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image29.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image3.png b/PocketBeagle/TechLab/slides/media/image3.png
new file mode 100644
index 0000000..902d0ce
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image3.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image30.png b/PocketBeagle/TechLab/slides/media/image30.png
new file mode 100644
index 0000000..fe67e10
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image30.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image31.jpeg b/PocketBeagle/TechLab/slides/media/image31.jpeg
new file mode 100644
index 0000000..cf331a7
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image31.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image32.jpeg b/PocketBeagle/TechLab/slides/media/image32.jpeg
new file mode 100644
index 0000000..3ce407d
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image32.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image33.jpeg b/PocketBeagle/TechLab/slides/media/image33.jpeg
new file mode 100644
index 0000000..cae9c13
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image33.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image34.png b/PocketBeagle/TechLab/slides/media/image34.png
new file mode 100644
index 0000000..00f8605
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image34.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image35.png b/PocketBeagle/TechLab/slides/media/image35.png
new file mode 100644
index 0000000..5f3c2fe
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image35.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image36.png b/PocketBeagle/TechLab/slides/media/image36.png
new file mode 100644
index 0000000..bf8e55d
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image36.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image37.jpeg b/PocketBeagle/TechLab/slides/media/image37.jpeg
new file mode 100644
index 0000000..3a95134
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image37.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image38.png b/PocketBeagle/TechLab/slides/media/image38.png
new file mode 100644
index 0000000..5740719
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image38.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image39.png b/PocketBeagle/TechLab/slides/media/image39.png
new file mode 100644
index 0000000..973368d
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image39.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image4.png b/PocketBeagle/TechLab/slides/media/image4.png
new file mode 100644
index 0000000..42cfc74
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image4.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image40.png b/PocketBeagle/TechLab/slides/media/image40.png
new file mode 100644
index 0000000..305e9a4
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image40.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image41.jpeg b/PocketBeagle/TechLab/slides/media/image41.jpeg
new file mode 100644
index 0000000..8651ed0
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image41.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image42.jpeg b/PocketBeagle/TechLab/slides/media/image42.jpeg
new file mode 100644
index 0000000..ea80927
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image42.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image43.png b/PocketBeagle/TechLab/slides/media/image43.png
new file mode 100644
index 0000000..d090484
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image43.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image44.png b/PocketBeagle/TechLab/slides/media/image44.png
new file mode 100644
index 0000000..2f284fb
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image44.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image45.jpeg b/PocketBeagle/TechLab/slides/media/image45.jpeg
new file mode 100644
index 0000000..a56abe8
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image45.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image46.png b/PocketBeagle/TechLab/slides/media/image46.png
new file mode 100644
index 0000000..9e660fc
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image46.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image47.jpeg b/PocketBeagle/TechLab/slides/media/image47.jpeg
new file mode 100644
index 0000000..711a2f0
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image47.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image48.jpeg b/PocketBeagle/TechLab/slides/media/image48.jpeg
new file mode 100644
index 0000000..b759bf2
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image48.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image49.jpeg b/PocketBeagle/TechLab/slides/media/image49.jpeg
new file mode 100644
index 0000000..6ec812e
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image49.jpeg differ
diff --git a/PocketBeagle/TechLab/slides/media/image50.png b/PocketBeagle/TechLab/slides/media/image50.png
new file mode 100644
index 0000000..bf4e93a
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image50.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image6.png b/PocketBeagle/TechLab/slides/media/image6.png
new file mode 100644
index 0000000..1631681
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image6.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image7.png b/PocketBeagle/TechLab/slides/media/image7.png
new file mode 100644
index 0000000..b0b04ab
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image7.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image8.png b/PocketBeagle/TechLab/slides/media/image8.png
new file mode 100644
index 0000000..8b032e4
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image8.png differ
diff --git a/PocketBeagle/TechLab/slides/media/image9.png b/PocketBeagle/TechLab/slides/media/image9.png
new file mode 100644
index 0000000..57d679b
Binary files /dev/null and b/PocketBeagle/TechLab/slides/media/image9.png differ
diff --git a/PocketBeagle/TechLab/workshop-handouts.asciidoc b/PocketBeagle/TechLab/workshop-handouts.asciidoc
new file mode 100644
index 0000000..90d7822
--- /dev/null
+++ b/PocketBeagle/TechLab/workshop-handouts.asciidoc
@@ -0,0 +1,510 @@
+= PocketBeagle® TechLab Cape Hands-On Coding Workshop
+
+[[microsd-software-image-and-other-materials-available-from-bbb.iotechlab]]
+* MicroSD software image and other materials available from *bbb.io/techlab*
+
+[.left]
+See *bbb.io/start* for instructions on using Etcher.io to write a
+microSD card
+
+[.right]
+image:handouts/media/image2.png[image,width=557,height=294]
+
+[.left]
+image:handouts/media/image3.jpeg[image,width=441,height=280]
+
+[.right]
+Plug into
+the microUSB on PocketBeagle to provide power and a network connection.
+Look for the “heartbeat” pulse on the USR0 LED to know the board has
+Linux up-and-running.
+
+image:handouts/media/image4.png[image]
+
+_______________________________________________________________
+[[Slide 2]]
+== TechLab Pocket Cape
+
+image:handouts/media/image5.png[image]**USB Host A with power**
+
+*mikroBus Header*
+
+http://www.mikroe.com/click[*www.mikroe.com/click*]
+
+*ADC Light Sensor*
+
+*Reset Button*
+
+*USB-to-Serial Micro B*
+
+*SPI 2-Digit 7-Segment Displays*
+
+*I2C Accelerometer Buzzer*
+
+*2 GPIO Push Buttons PWM Controlled Tri-Color LED*
+
+*TechLab Wiring Summary*
+_______________________________________________________________
+
+image:handouts/media/image20.png[image]
+
+* image:handouts/media/image21.png[image]
+[[Slide 3]][[slide-3]]
+PocketBeagle®
+is an ultra-tiny-yet-complete, low-cost, open-source USB-key-fob
+computer.
+* Processor System:
+
+______________________________________________________________________________________________________________________
+Octavo Systems OSD3358-SM 21mm x 21mm system-in-package that includes
+512MB DDR3 RAM, 1-GHz ARM Cortex-A8 CPU, 2x 200-
+
+MHz PRUs, ARM Cortex-M3, 3D accelerator, power/battery management and
+EEPROM
+______________________________________________________________________________________________________________________
+
+* 72 expansion pin headers with power and battery I/Os, high-speed USB,
+8 analog inputs, 44 digital I/Os and numerous digital interface
+peripherals
+* microUSB host/client and microSD connectors
+
+_____________________________________________________________________________________________________________________________________________________________________________________________
+.PocketBeagle Expansion Header Pin-out
+image:handouts/media/image22.jpeg[image,width=815,height=335]
+
+Great getting started information is at
+https://beagleboard.org/pocket[*_beagleboard.org/pocket_*]
+
+[[Slide 4]]**Goal:** Blink USR3 LED on PocketBeagle.
+
+*Overview:* BoneScript is a Node.js library customized for the Beagle
+family and featuring familiar Arduino function calls. Here we will use
+it to blink an LED built into your PocketBeagle.
+
+*Do this in the Cloud9 IDE:*
+
+\1. Navigate to *TechLab/internalLED.js* and double-click on it.
+
+\2. Click the Run button in the toolbar to execute the script in the
+active file window
+
+\3. You will see the run configuration window open with a Stop button.
+Click the Stop button to halt the program.
+
+\4. Try changing the LED or blink time, save the program and run again.
+
+TIP: Click the green bug to disable the debugger and begin execution
+quicker.
+_____________________________________________________________________________________________________________________________________________________________________________________________
+
+image:handouts/media/image23.jpeg[image]
+
+[[internalled.js]]
+internalLED.js
+--------------
+
+_____________________________________________________________________________________________________________________________________
+
+
+[source,javascript]
+----
+#!/usr/bin/env node
+var b = require('bonescript'); var LED = 'USR3';
+var state = b.HIGH; // Initial state
+b.pinMode(LED, b.OUTPUT);
+
+setInterval(flash, 250); // Change state every 250 ms
+
+function flash() \{
+ b.digitalWrite(LED, state);
+ if(state === b.HIGH) {
+ state = b.LOW;
+ } else {
+ state = b.HIGH;
+ }
+}
+----
+
+[[Slide 5]]**Goal:** Sense the external world by reading a digital
+input.
+
+*Overview:* Reading a switch attached to a GPIO (general purpose
+input/output) port is as
+
+easy as configuring the port as an input and attaching an interrupt
+handler to it. Note the buttons are “active low”.
+
+*Do this in the Cloud9 IDE:*
+_____________________________________________________________________________________________________________________________________
+
+1. Navigate to *TechLab/pushbutton.js* and double-click on it.
+2. Click the Run button in the toolbar to execute the script in the
+active file window
+3. Press the “L” button on TechLab and check the output (Value=1 or
+Value=0) in the configuration window. Click the Stop button on the IDE
+to halt the program.
+
+___________________________________________________________________________________________________________________
+*Challenge #1:* Can you modify the program to read from the “R” button?
+
+*Challenge #2*: Can you modify the program to toggle the USR3 LED?
+
+*Challenge #3*: Can you modify the program to turn the USR3 LED on with
+the “L” button and off with the “R” button?
+___________________________________________________________________________________________________________________
+
+image:handouts/media/image25.jpeg[image,width=774,height=440]
+
+[[pushbutton.js]]
+pushbutton.js
+-------------
+
+[[usrbinenv-node]]
+### #!/usr/bin/env node
+
+_________________________________________________________________________________________________________________________________________________________________________________
+var b = require('bonescript'); var button = "P2_33";
+
+console.log('Hit ^C to stop');
+
+b.pinMode(button, b.INPUT, 7, null, null, doAttach);
+
+function doAttach(err, x) \{ if(err) \{
+
+console.log('pinMode err = ' + err); return;
+
+}
+
+b.attachInterrupt(button, true, b.CHANGE, printStatus);
+
+}
+
+function printStatus(err, x) \{ if(err) \{
+
+console.log('attachInterrupt err = ' + err); return;
+
+}
+
+if(x.attached) \{
+
+console.log("Interrupt handler attached"); return;
+
+}
+
+process.stdout.write('value = ' + x.value + ' \r');
+
+}
+
+[[Slide 7]]**Goal:** Sense the external world by reading a variable
+analog input *Overview:* Reading a light sensor attached to an analog
+input pin. *Do this in the Cloud9 IDE:*
+_________________________________________________________________________________________________________________________________________________________________________________
+
+1. Navigate to *TechLab/analogIn.js* and double-click on it.
+2. Click the Run button in the toolbar to execute the script in the
+active file window
+3. Cover the light sensor and check the output in the configuration
+window. Click the Stop button to halt the program.
+
+____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+*Challenge #1*: Can you change how often the light sensor is read? What
+happens and why? *Challenge #2*: Can you activate the USR3 LED based
+upon a voltage threshold from the light sensor? *Challenge #3*:
+*(Advanced Coding Lab)*
+
+Try using the I2C accelerometer input from
+/sys/bus/iio/devices/iio:device1/in_accel_x_raw. Hint: use
+b.readTextFile()
+____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+
+image:handouts/media/image26.jpeg[image,width=771,height=397]
+
+[[analogin.js]]
+analogIn.js
+-----------
+
+[[usrbinenv-node-1]]
+#!/usr/bin/env node
+~~~~~~~~~~~~~~~~~~~
+
+___________________________________________________________________________________________________________________________________________________________________________________________________________________
+var b = require('bonescript'); var pin = 'P1_19';
+
+console.log('Hit ^C to stop'); doAnalogRead();
+
+function printStatus(err, x) \{
+
+if(err) \{console.log('Got error: ' + err); return;};
+process.stdout.write(pin + ': ' + (x*100).toFixed(1) +
+
+'%, ' + (1.8*x).toFixed(3) + 'V \r'); setTimeout(doAnalogRead, 100);
+
+}
+
+function doAnalogRead() \{ b.analogRead(pin, printStatus);
+
+}
+
+[[Slide 9]]**Goal:** Utilize a hardware pulse-width-modulator (PWM) to
+light an LED with variable brightness
+
+*Overview:* Linux provides LED drivers that understand how to utilize
+PWM drivers, making use of PocketBeagle’s built-in PWM hardware. They
+are controlled with simple text files where you can set the brightness.
+
+*Do this in the Cloud9 IDE:*
+___________________________________________________________________________________________________________________________________________________________________________________________________________________
+
+1. Navigate to *TechLab/fadeLED.js* and double-click on it.
+2. Click the Run button in the toolbar to execute the script in the
+active file window
+3. You will see the run configuration window open with a Stop button.
+Click the Stop button to halt the program.
+
+_______________________________________________________________________________
+*Challenge #1*: Try changing the fade interval, save the program and run
+again.
+
+*Challenge #2*: Try using the light sensor input to set the LED
+brightness.
+
+*Challenge #3*: *(Advanced Coding Lab)*
+
+Try using the I2C accelerometer input for all 3 color LEDs..
+_______________________________________________________________________________
+
+image:handouts/media/image27.jpeg[image,width=778,height=422]
+
+[[fadeled.js]]
+fadeLED.js
+----------
+
+[[usrbinenv-node-2]]
+=== #!/usr/bin/env node
+
+________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+var b = require('bonescript');
+
+var LED = '/sys/class/leds/techlab::blue/brightness'; var step = 10, //
+Step size
+
+min = 0, // dimmest value max = 255, // brightest value
+
+brightness = min; // Current brightness;
+
+doInterval();
+
+function doInterval(err, x) \{ if(err) \{
+
+console.log('err = ' + err); return;
+
+}
+
+setInterval(fade, 20); // Step every 20 ms
+
+}
+
+function fade() \{ b.writeTextFile(LED, brightness); brightness += step;
+
+if(brightness >= max || brightness <= min) \{ step = -1 * step;
+
+}
+
+}
+
+[[Slide 11]]**Goal:** Read light sensor data and output to green LED
+brightness
+
+*Overview:* Node-RED is a flow-based development tool developed
+originally by IBM for wiring together hardware devices, APIs and online
+services as part of the Internet of Things. Node-RED provides a
+browser-based flow editor, which can be used to create JavaScript
+functions. Linux turns devices into virtual files, making Node-RED well
+suited to interacting with the physical world.
+
+*Do this:*
+________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+
+1. Open Node-RED by pointing your browser to *http://192.168.7.2:1880*
+
+image:handouts/media/image28.png[image]
+
+1. Make sure the big “DEPLOY” button in the top right corner is
+greyed-out by clicking it. This makes sure any changes you’ve made have
+been started on your PocketBeagle. The program will run continuously.
+2. Click the highlightable button to the left of the “ON”. Cover the
+light sensor to notice the brightness of the green LED adjust.
+3. Try double-clicking on each node to see the parameters used for the
+demo.
+4. Click the highlightable button to the left of the “OFF” to stop
+adjusting the brightness of the green LED.
+5. Explore
+
+_______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+*Challenge #1*: Try updating the blue LED rather than the green LED.
+Remember to click the “DEPLOY” button to save and run your changes.
+
+*Challenge #2*: Try reading from the I2C accelerometer rather than the
+light sensor.
+
+*Challenge #3*: Use a “gpio in” node to use the status of the “L” or “R”
+buttons to update the LED.
+
+[[Slide 12]]**Goal:** Learn to send several basic commands to the shell
+
+*Overview:* The true power of Linux to automate many aspects of your
+life cannot be achieved without some utilization of the command line
+shell. The Cloud9 IDE makes it easy to access this directly from your
+web browser. Another great resource for learning is *linuxcommand.org*.
+
+*Do this in the Cloud9 IDE:*
+_______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+
+1. Click in the terminal window at the bottom half of the IDE. You can
+also open a new terminal by clicking the “+” in the window tabs and
+selecting “New Terminal”.
+2. Try typing in the “commands to try”. Press after each
+command. Take note of how the prompt changes to show you the current
+active directory. Use the up and down arrows to cycle through commands
+you’ve typed before, in case you want to repeat any.
+
+__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+*Challenge #1*: Can you repeat the last command below that prints GPIO
+values and change the values?
+
+*Challenge #2*: Using the “watch” command, can you monitor the I2C
+accelerometer status?
+
+*Challenge #3*: Can you use the “config-pin” command to switch the red
+LED to a GPIO, set it high and low and then switch it back to PWM mode?
+What happens if the red LED is in GPIO mode and you change the
+brightness with the “/sys/class/leds” entry?
+__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+
+image:handouts/media/image29.jpeg[image,width=508,height=286]
+
+[[commands-to-try]]
+commands to try
+---------------
+
+______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+cd /sys/class/leds ls
+
+echo 1 > techlab\:\:seg0/brightness config-pin p1.33 pwm
+
+echo 10 > techlab\:\:red/brightness
+
+cd /sys/class/gpio config-pin p1.29 gpio
+
+cat gpio45/value gpio117/value
+
+[[Slide 13]]**Goal:** Utilize a programmable real-time unit (PRU) to
+read and set GPIOs.
+
+*Overview:* A PRU is a microcontroller built into the PocketBeagle that
+can be programmed in C or assembly and controlled by the main ARM
+processor that runs Linux. Some pins can be directly mapped to PRU
+registered for the lowest possible latency, but other GPIOs can be
+utilized via the on-chip-peripheral (OCP) bus inside the processor. Here
+we’ll learn to execute an example written in C to access the
+direct-mapped PRU GPIOs.
+
+*Do this in the Cloud9 IDE:*
+______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+
+1. Navigate to *TechLab/led-button.pru0c* and double-click on it.
+2. Click the Run button in the toolbar to execute the script in the
+active file window.
+3. Click the run configuration window and type ‘temppwd’ when prompted
+for the password.
+
+______________________________________________________________________________________
+*Note*: The program will keep running until you execute a different
+program or reboot.
+______________________________________________________________________________________
+
+1. Press the ‘R’ button to note the red RGB LED light up.
+
+____________________________________________________________________________________________________________________________________________________________________
+*Challenge #1*: The buzzer is on PRU0 output 3 (P2_30). Try setting its
+output at the same time as the LED.
+
+*Challenge #2*: Try toggling the buzzer with a for loop when the button
+is pressed. You can use the
+
+‘ delay_cycles’ function to add a delay. Each delay cycle should be 5ns,
+so 800Hz is 250000 cycles, a reasonable number to try.
+
+*Challenge #3*: *(Advanced Coding Lab)*
+
+Run *TechLab/rgb.pru0c* and note how the on-chip-peripherals are
+accessed as well as how a fade effect can be done easily creating a
+software pulse-width-modulator.
+____________________________________________________________________________________________________________________________________________________________________
+
+image:handouts/media/image30.jpeg[image,width=768,height=432]
+
+[[led-button.pru0c]]
+led-button.pru0c
+----------------
+
+[[include-stdint.h-include-pru_cfg.h-include-pru_ctrl.h-include-stddef.h-include-rsc_types.h]]
+#include #include #include #include
+ #include
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+_____________________________________________________________________________________________________________________________________________________________
+volatile register unsigned int R30; volatile register unsigned int R31;
+
+#pragma DATA_SECTION(init_pins, ".init_pins") #pragma RETAIN(init_pins)
+
+const char init_pins[] =
+"/sys/devices/platform/ocp/ocp:P1_33_pinmux/state\0pruout\0" \
+"/sys/devices/platform/ocp/ocp:P1_29_pinmux/state\0pruin\0" \ "\0\0";
+
+void main(void) \{
+
+/* Invert GPIO input 7 to GPIO output 1 */
+
+/* On TechLab, input 7 is the R button */
+
+/* On TechLab, output 1 is the red in the RGB LED */ while(1) \{
+
+if( R31 & (1<<7)) \{
+
+/* Clear output */
+
+R30 &= ~(1<<1);
+
+} else \{
+
+/* Set outputs */
+
+R30 |= (1<<1);
+
+}
+
+}
+
+}
+
+struct my_resource_table \{
+
+struct resource_table base;
+
+uint32_t offset[1];
+
+};
+
+#pragma DATA_SECTION(pru_remoteproc_ResourceTable, ".resource_table")
+#pragma RETAIN(pru_remoteproc_ResourceTable)
+
+struct my_resource_table pru_remoteproc_ResourceTable = \{
+
+1, /* we're the first version that implements this */ 0, /* number of
+entries in the table */
+
+0, 0, /* reserved, must be zero */ 0, /* offset[0] */
+
+};
+_____________________________________________________________________________________________________________________________________________________________
diff --git a/PocketBeagle/TechLab/workshop-handouts.pptx b/PocketBeagle/TechLab/workshop-handouts.pptx
deleted file mode 100644
index 887ae15..0000000
Binary files a/PocketBeagle/TechLab/workshop-handouts.pptx and /dev/null differ
diff --git a/PocketBeagle/TechLab/workshop-slides.asciidoc b/PocketBeagle/TechLab/workshop-slides.asciidoc
new file mode 100644
index 0000000..04df5c5
--- /dev/null
+++ b/PocketBeagle/TechLab/workshop-slides.asciidoc
@@ -0,0 +1,1210 @@
+image:slides/media/image1.jpeg[image]
+
+[[pocketbeagle-techlab-workshop]]
+PocketBeagle TechLab Workshop
+-----------------------------
+
+_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+image:slides/media/image4.png[image]image:slides/media/image3.png[image,width=225,height=42]
+
+PocketBeagle walk-through
+
+Friendly to novices and experts alike, the Beagle experience tracks
+mainline u-boot, Linux and Debian development, while augmenting it to
+enable development to start as quickly as possible. Attendees will get
+started interacting with the hardware via the command-line, shell
+scripts, Python and JavaScript. Attendees will be walked through the
+configuration details for the boot configuration, pin multiplexing, USB
+networking and other helper scripts they should get to know. Support and
+development processes within the BeagleBoard.org community will be
+covered. Exercises will pave the way for the other workshops to dive
+into their topic without needing to backtrack excessively on
+PocketBeagle- specific details.
+
+