diff --git a/client/public/index.html b/client/public/index.html index aa069f27..93f05a51 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -24,7 +24,22 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + STEM+C + + + + + + + + + + + + + + + diff --git a/client/src/lib/arduino_compressed.js b/client/public/lib/arduino_compressed.js similarity index 100% rename from client/src/lib/arduino_compressed.js rename to client/public/lib/arduino_compressed.js diff --git a/client/src/lib/blockly_compressed.js b/client/public/lib/blockly_compressed.js similarity index 100% rename from client/src/lib/blockly_compressed.js rename to client/public/lib/blockly_compressed.js diff --git a/client/src/lib/blocks_compressed.js b/client/public/lib/blocks_compressed.js similarity index 100% rename from client/src/lib/blocks_compressed.js rename to client/public/lib/blocks_compressed.js diff --git a/client/src/lib/en.js b/client/public/lib/en.js similarity index 100% rename from client/src/lib/en.js rename to client/public/lib/en.js diff --git a/client/src/lib/javascript_compressed.js b/client/public/lib/javascript_compressed.js similarity index 100% rename from client/src/lib/javascript_compressed.js rename to client/public/lib/javascript_compressed.js diff --git a/client/src/lib/off.cpp.hex b/client/public/lib/off.cpp.hex similarity index 100% rename from client/src/lib/off.cpp.hex rename to client/public/lib/off.cpp.hex diff --git a/client/src/lib/on.cpp.hex b/client/public/lib/on.cpp.hex similarity index 100% rename from client/src/lib/on.cpp.hex rename to client/public/lib/on.cpp.hex diff --git a/client/src/App.css b/client/src/App.css index 74b5e053..ac26c54b 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -1,38 +1,79 @@ -.App { - text-align: center; +body { + margin: 0; } -.App-logo { - height: 40vmin; - pointer-events: none; +h3, p { + margin: 0; } -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } +.flex { + display: flex; } -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; +.flex-column { flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); +} + +.space-between { + justify-content: space-between; +} + +#container { + height: 100vh; + background-color: rgb(241, 241, 241); +} + +.vertical-container { + margin: 1.5em; +} + +#nav-container { + margin: 0; + background-color: rgb(32, 145, 173); color: white; + align-items: center; +} + +#title { + flex: 10; + margin: 0.5em; } -.App-link { - color: #61dafb; +#action-btn-container { + flex: 1; + margin: 1em; } -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } +#top-container { + flex: 1; + margin-bottom: 0.75em } + +.card { + background-color: white; + padding: 1em; +} + +#description-container { + height: 100%; +} + +#bottom-container { + flex: 6; + margin-top: 0.75em +} + +#blockly-canvas { + flex: 2; +} + +#models-container { + flex: 1; + margin-left: 1.5em; +} + +#mode-img { + width: auto; + height: auto; +} + diff --git a/client/src/App.js b/client/src/App.js index ce9cbd29..82edcdbf 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,26 +1,124 @@ -import React from 'react'; -import logo from './logo.svg'; -import './App.css'; +import React, {useState, useRef} from "react"; +import "./App.css"; +import {getArduino, getJS, compileArduinoCode} from "./scripts"; function App() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); + const [board, updateBoard] = useState("uno"); + + const alertArduino = () => { + alert(getArduino()); + }; + + const alertJS = () => { + alert(getJS()); + }; + + const alertCompile = () => { + alert(compileArduinoCode()); + }; + + return ( + +
+ +
+
+

Maker Activity X

+

Instructions / Science Brief: + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt + ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in + voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat + non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
+
+
+

Activity Models

+ +
+ + + + + + + + + + + + +
+
+
+
+ + {/* This xml is for the blocks' menu we will provide. Here are examples on how to include categories and subcategories */} + {/**/} + +); + } -export default App; +export default App; \ No newline at end of file diff --git a/client/src/assets/arduino.png b/client/src/assets/arduino.png new file mode 100644 index 00000000..8f4451a5 Binary files /dev/null and b/client/src/assets/arduino.png differ diff --git a/client/src/assets/maker.png b/client/src/assets/maker.png new file mode 100644 index 00000000..5eda01cb Binary files /dev/null and b/client/src/assets/maker.png differ diff --git a/client/src/assets/science.png b/client/src/assets/science.png new file mode 100644 index 00000000..cbe141d2 Binary files /dev/null and b/client/src/assets/science.png differ diff --git a/client/src/assets/style.css b/client/src/assets/style.css new file mode 100644 index 00000000..3fa80890 --- /dev/null +++ b/client/src/assets/style.css @@ -0,0 +1,79 @@ +body { + margin: 0; +} + +h3, p { + margin: 0; +} + +.flex { + display: flex; +} + +.flex-column { + flex-direction: column; +} + +.space-between { + justify-content: space-between; +} + +#container { + height: 100vh; + background-color: rgb(241, 241, 241); +} + +.vertical-container { + margin: 1.5em; +} + +#nav-container { + margin: 0; + background-color: rgb(32, 145, 173); + color: white; + align-items: center; +} + +#title { + flex: 10; + margin: 0.5em; +} + +#action-btn-container { + flex: 1; + margin: 1em; +} + +#top-container { + flex: 1; + margin-bottom: 0.75em +} + +.card { + background-color: white; + padding: 1em; +} + +#description-container { + height: 100%; +} + +#bottom-container { + flex: 6; + margin-top: 0.75em +} + +#blockly-canvas { + flex: 2; +} + +#models-container { + flex: 1; + margin-left: 1.5em; +} + +#mode-img { + width: auto; + height: auto; +} + diff --git a/client/src/lib/avrgirl-arduino.js b/client/src/avrgirl-arduino.js similarity index 99% rename from client/src/lib/avrgirl-arduino.js rename to client/src/avrgirl-arduino.js index 15ca993a..45339890 100644 --- a/client/src/lib/avrgirl-arduino.js +++ b/client/src/avrgirl-arduino.js @@ -1,3 +1,5 @@ +/* eslint-disable */ + (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); @@ -10411,139 +10413,139 @@ module.exports = Array.isArray || function (arr) { /* 22 */ /***/ (function(module, exports, __webpack_require__) { -/* WEBPACK VAR INJECTION */(function(Buffer) {//Intel Hex record types -const DATA = 0, - END_OF_FILE = 1, - EXT_SEGMENT_ADDR = 2, - START_SEGMENT_ADDR = 3, - EXT_LINEAR_ADDR = 4, - START_LINEAR_ADDR = 5; - -const EMPTY_VALUE = 0xFF; - -/* intel_hex.parse(data) - `data` - Intel Hex file (string in ASCII format or Buffer Object) - `bufferSize` - the size of the Buffer containing the data (optional) - - returns an Object with the following properties: - - data - data as a Buffer Object, padded with 0xFF - where data is empty. - - startSegmentAddress - the address provided by the last - start segment address record; null, if not given - - startLinearAddress - the address provided by the last - start linear address record; null, if not given - Special thanks to: http://en.wikipedia.org/wiki/Intel_HEX -*/ -exports.parse = function parseIntelHex(data, bufferSize) { - if(data instanceof Buffer) - data = data.toString("ascii"); - //Initialization - var buf = new Buffer(bufferSize || 8192), - bufLength = 0, //Length of data in the buffer - highAddress = 0, //upper address - startSegmentAddress = null, - startLinearAddress = null, - lineNum = 0, //Line number in the Intel Hex string - pos = 0; //Current position in the Intel Hex string - const SMALLEST_LINE = 11; - while(pos + SMALLEST_LINE <= data.length) - { - //Parse an entire line - if(data.charAt(pos++) != ":") - throw new Error("Line " + (lineNum+1) + - " does not start with a colon (:)."); - else - lineNum++; - //Number of bytes (hex digit pairs) in the data field - var dataLength = parseInt(data.substr(pos, 2), 16); - pos += 2; - //Get 16-bit address (big-endian) - var lowAddress = parseInt(data.substr(pos, 4), 16); - pos += 4; - //Record type - var recordType = parseInt(data.substr(pos, 2), 16); - pos += 2; - //Data field (hex-encoded string) - var dataField = data.substr(pos, dataLength * 2), - dataFieldBuf = new Buffer(dataField, "hex"); - pos += dataLength * 2; - //Checksum - var checksum = parseInt(data.substr(pos, 2), 16); - pos += 2; - //Validate checksum - var calcChecksum = (dataLength + (lowAddress >> 8) + - lowAddress + recordType) & 0xFF; - for(var i = 0; i < dataLength; i++) - calcChecksum = (calcChecksum + dataFieldBuf[i]) & 0xFF; - calcChecksum = (0x100 - calcChecksum) & 0xFF; - if(checksum != calcChecksum) - throw new Error("Invalid checksum on line " + lineNum + - ": got " + checksum + ", but expected " + calcChecksum); - //Parse the record based on its recordType - switch(recordType) - { - case DATA: - var absoluteAddress = highAddress + lowAddress; - //Expand buf, if necessary - if(absoluteAddress + dataLength >= buf.length) - { - var tmp = new Buffer((absoluteAddress + dataLength) * 2); - buf.copy(tmp, 0, 0, bufLength); - buf = tmp; - } - //Write over skipped bytes with EMPTY_VALUE - if(absoluteAddress > bufLength) - buf.fill(EMPTY_VALUE, bufLength, absoluteAddress); - //Write the dataFieldBuf to buf - dataFieldBuf.copy(buf, absoluteAddress); - bufLength = Math.max(bufLength, absoluteAddress + dataLength); - break; - case END_OF_FILE: - if(dataLength != 0) - throw new Error("Invalid EOF record on line " + - lineNum + "."); - return { - "data": buf.slice(0, bufLength), - "startSegmentAddress": startSegmentAddress, - "startLinearAddress": startLinearAddress - }; - break; - case EXT_SEGMENT_ADDR: - if(dataLength != 2 || lowAddress != 0) - throw new Error("Invalid extended segment address record on line " + - lineNum + "."); - highAddress = parseInt(dataField, 16) << 4; - break; - case START_SEGMENT_ADDR: - if(dataLength != 4 || lowAddress != 0) - throw new Error("Invalid start segment address record on line " + - lineNum + "."); - startSegmentAddress = parseInt(dataField, 16); - break; - case EXT_LINEAR_ADDR: - if(dataLength != 2 || lowAddress != 0) - throw new Error("Invalid extended linear address record on line " + - lineNum + "."); - highAddress = parseInt(dataField, 16) << 16; - break; - case START_LINEAR_ADDR: - if(dataLength != 4 || lowAddress != 0) - throw new Error("Invalid start linear address record on line " + - lineNum + "."); - startLinearAddress = parseInt(dataField, 16); - break; - default: - throw new Error("Invalid record type (" + recordType + - ") on line " + lineNum); - break; - } - //Advance to the next line - if(data.charAt(pos) == "\r") - pos++; - if(data.charAt(pos) == "\n") - pos++; - } - throw new Error("Unexpected end of input: missing or invalid EOF record."); +/* WEBPACK VAR INJECTION */(function(Buffer) {//Intel Hex record types +const DATA = 0, + END_OF_FILE = 1, + EXT_SEGMENT_ADDR = 2, + START_SEGMENT_ADDR = 3, + EXT_LINEAR_ADDR = 4, + START_LINEAR_ADDR = 5; + +const EMPTY_VALUE = 0xFF; + +/* intel_hex.parse(data) + `data` - Intel Hex file (string in ASCII format or Buffer Object) + `bufferSize` - the size of the Buffer containing the data (optional) + + returns an Object with the following properties: + - data - data as a Buffer Object, padded with 0xFF + where data is empty. + - startSegmentAddress - the address provided by the last + start segment address record; null, if not given + - startLinearAddress - the address provided by the last + start linear address record; null, if not given + Special thanks to: http://en.wikipedia.org/wiki/Intel_HEX +*/ +exports.parse = function parseIntelHex(data, bufferSize) { + if(data instanceof Buffer) + data = data.toString("ascii"); + //Initialization + var buf = new Buffer(bufferSize || 8192), + bufLength = 0, //Length of data in the buffer + highAddress = 0, //upper address + startSegmentAddress = null, + startLinearAddress = null, + lineNum = 0, //Line number in the Intel Hex string + pos = 0; //Current position in the Intel Hex string + const SMALLEST_LINE = 11; + while(pos + SMALLEST_LINE <= data.length) + { + //Parse an entire line + if(data.charAt(pos++) != ":") + throw new Error("Line " + (lineNum+1) + + " does not start with a colon (:)."); + else + lineNum++; + //Number of bytes (hex digit pairs) in the data field + var dataLength = parseInt(data.substr(pos, 2), 16); + pos += 2; + //Get 16-bit address (big-endian) + var lowAddress = parseInt(data.substr(pos, 4), 16); + pos += 4; + //Record type + var recordType = parseInt(data.substr(pos, 2), 16); + pos += 2; + //Data field (hex-encoded string) + var dataField = data.substr(pos, dataLength * 2), + dataFieldBuf = new Buffer(dataField, "hex"); + pos += dataLength * 2; + //Checksum + var checksum = parseInt(data.substr(pos, 2), 16); + pos += 2; + //Validate checksum + var calcChecksum = (dataLength + (lowAddress >> 8) + + lowAddress + recordType) & 0xFF; + for(var i = 0; i < dataLength; i++) + calcChecksum = (calcChecksum + dataFieldBuf[i]) & 0xFF; + calcChecksum = (0x100 - calcChecksum) & 0xFF; + if(checksum != calcChecksum) + throw new Error("Invalid checksum on line " + lineNum + + ": got " + checksum + ", but expected " + calcChecksum); + //Parse the record based on its recordType + switch(recordType) + { + case DATA: + var absoluteAddress = highAddress + lowAddress; + //Expand buf, if necessary + if(absoluteAddress + dataLength >= buf.length) + { + var tmp = new Buffer((absoluteAddress + dataLength) * 2); + buf.copy(tmp, 0, 0, bufLength); + buf = tmp; + } + //Write over skipped bytes with EMPTY_VALUE + if(absoluteAddress > bufLength) + buf.fill(EMPTY_VALUE, bufLength, absoluteAddress); + //Write the dataFieldBuf to buf + dataFieldBuf.copy(buf, absoluteAddress); + bufLength = Math.max(bufLength, absoluteAddress + dataLength); + break; + case END_OF_FILE: + if(dataLength != 0) + throw new Error("Invalid EOF record on line " + + lineNum + "."); + return { + "data": buf.slice(0, bufLength), + "startSegmentAddress": startSegmentAddress, + "startLinearAddress": startLinearAddress + }; + break; + case EXT_SEGMENT_ADDR: + if(dataLength != 2 || lowAddress != 0) + throw new Error("Invalid extended segment address record on line " + + lineNum + "."); + highAddress = parseInt(dataField, 16) << 4; + break; + case START_SEGMENT_ADDR: + if(dataLength != 4 || lowAddress != 0) + throw new Error("Invalid start segment address record on line " + + lineNum + "."); + startSegmentAddress = parseInt(dataField, 16); + break; + case EXT_LINEAR_ADDR: + if(dataLength != 2 || lowAddress != 0) + throw new Error("Invalid extended linear address record on line " + + lineNum + "."); + highAddress = parseInt(dataField, 16) << 16; + break; + case START_LINEAR_ADDR: + if(dataLength != 4 || lowAddress != 0) + throw new Error("Invalid start linear address record on line " + + lineNum + "."); + startLinearAddress = parseInt(dataField, 16); + break; + default: + throw new Error("Invalid record type (" + recordType + + ") on line " + lineNum); + break; + } + //Advance to the next line + if(data.charAt(pos) == "\r") + pos++; + if(data.charAt(pos) == "\n") + pos++; + } + throw new Error("Unexpected end of input: missing or invalid EOF record."); }; /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(0).Buffer)) @@ -17847,256 +17849,256 @@ module.exports = Avr109; /* 62 */ /***/ (function(module, exports, __webpack_require__) { -/* WEBPACK VAR INJECTION */(function(process, Buffer) {var - intelHex = __webpack_require__(22), - Stream = __webpack_require__(63).Stream, - util = __webpack_require__(8); - -var out = module.exports = {}; - -var d = function(c) { - return (c + '').charCodeAt(0); -}; - -out.Flasher = function(serialport, options) { - var that = this; - this.options = options || {}; - this.sp = serialport; - this.signature = this.options.signature || 'LUFACDC'; - - if (this.options.debug) { - this.sp.on('data', function(d) { - process.stdout.write(' -> '); - - for (var i=0; i 126) { - c = '.'; - } - - process.stdout.write(c + ' [' + d.readUInt8(i).toString(16) + '] '); - } - process.stdout.write('\n'); - }); - } - - this.c = function(value, fn, expectedResponseLength) { - that.cmds.push({ - value : value, - callback : function(data) { - fn && fn(data); - }, - expectedResponseLength: expectedResponseLength - }); - return this; - } - - this.flashChunkSize = 0; - this.bytes = []; - this.cmds = []; -}; - -out.Flasher.prototype = { - run : function(fn) { - var that = this; - process.nextTick(function() { - if (that.running) { return; } - var cmd = that.cmds.shift(); - - if (cmd) { - running = true; - that.options.debug && process.stdout.write('Send: ' + cmd.value); - var response = new Buffer(0); - var onData = function(d) { - response = Buffer.concat([ - response, - d - ]); - - if (cmd.expectedResponseLength === undefined || // optional expected length not passed in - cmd.expectedResponseLength <= response.length) { - that.sp.removeListener('data', onData); - that.running = false; - cmd.callback(response); - - process.nextTick(function() { - if (that.cmds.length > 0) { - that.run(fn); - } else { - fn && fn(); - } - }); - } - }; - - that.sp.on('data', onData); - - that.sp.write(cmd.value); - } - }); - }, - - prepare : function(fn) { - var that = this; - this.c('S', function(d) { - if (d.toString() !== that.signature) { - fn(new Error('Invalid device signature; expecting: ' + that.signature + ' received: ' + d.toString())); - } - }) - .c('V') - .c('v') - .c('p') - .c('a') - .c('b', function(d) { - if ((d.toString() || 'X')[0] != 'Y') { - fn(new Error('Buffered memory access not supported.')); - } - that.flashChunkSize = d.readUInt16BE(1); - }) - .c('t') - .c('TD') - .c('P') - .c('F') - .c('F') - .c('F') - .c('N') - .c('N') - .c('N') - .c('Q') - .c('Q') - .c('Q') - .c([d('A'), 0x03, 0xfc]) - .c([d('g'), 0x00, 0x01, d('E')]) - .c([d('A'), 0x03, 0xff]) - .c([d('g'), 0x00, 0x01, d('E')]) - .c([d('A'), 0x03, 0xff]) - .c([d('g'), 0x00, 0x01, d('E')]) - .c([d('A'), 0x03, 0xff]) - .c([d('g'), 0x00, 0x01, d('E')]) - - this.run(function() { - fn(null, that); - }); - }, - - erase : function(fn) { - this.c('e', function() { - fn && fn(); - }) // erase - - this.run(); - }, - - program : function(fullString, fn) { - - var - that = this, - converter, - bytes = []; - - this.totalBytes = 0; - - this.c([d('A'), 0x00, 0x00], function() { - converter = intelHex.parse(fullString); - - that.totalBytes = converter.data.length; - // buffer the bytes so we can push them in the expected size on 'end' - Array.prototype.push.apply(bytes, converter.data); - // copy this array so we can use it strictly for comparing later - that.allBytes = bytes; - - that.options.debug && console.log('programming', bytes.length, 'bytes'); - that.chunksSent = []; - - for (var i=0; i> 8) & 0xFF, chunk.length & 0xFF, d('F')].concat(chunk)); - } - }); - - this.run(function() { fn && fn() }); - }, - - verify : function(fn) { - var that = this; - // compare flash on device with the chunks we sent - this.c([d('A'), 0x00, 0x00], function() { - - var - index = 0, - compare = function(deviceData) { - var error = null; - index++; - - if (!that.allBytes.length) { - fn && fn(); - return; - } - - var deviceDataLength = deviceData.length; - var localChunk = that.allBytes.splice(0, deviceDataLength); - - // iterate through the bytes sent to compare with the latest bytes received - localChunk.forEach(function(val, idx) { - if (val !== deviceData.readUInt8(idx)) { - error = new Error('Firmware on the device does not match local data'); - } - }); - - if (error) { - return fn(error); - } - - process.nextTick(function() { - var readSize = that.flashChunkSize; - that.options.debug && console.log(that.totalBytes - index*that.flashChunkSize); - if (that.totalBytes - index*that.flashChunkSize < that.flashChunkSize) { - readSize = that.totalBytes - index*that.flashChunkSize; - } - that.c([d('g'), (readSize >> 8) & 0xFF, readSize & 0xFF, d('F')], compare, readSize); - that.run(); - }); - }; - - that.options.debug && console.log('\n\nVerifying flash..') - - that.c([d('g'), (that.flashChunkSize >> 8) & 0xFF, that.flashChunkSize & 0xFF, d('F')], compare, that.flashChunkSize); - that.run(); - }); - that.run(); - }, - - fuseCheck : fuseCheck = function(fn) { - this.options.debug && console.log('checking fuses'); - // fuse check - this.c('F') - .c('F') - .c('F') - .c('N') - .c('N') - .c('N') - .c('Q') - .c('Q') - .c('Q') - .c('L') - .c('E'); - - this.run(function() { - fn(); - }); - } -}; - -out.init = function(serialport, options, fn) { - if (typeof options === 'function' && !fn) { - fn = options; - options = {}; - } - - var flasher = new out.Flasher(serialport, options); - flasher.prepare(fn); -}; +/* WEBPACK VAR INJECTION */(function(process, Buffer) {var + intelHex = __webpack_require__(22), + Stream = __webpack_require__(63).Stream, + util = __webpack_require__(8); + +var out = module.exports = {}; + +var d = function(c) { + return (c + '').charCodeAt(0); +}; + +out.Flasher = function(serialport, options) { + var that = this; + this.options = options || {}; + this.sp = serialport; + this.signature = this.options.signature || 'LUFACDC'; + + if (this.options.debug) { + this.sp.on('data', function(d) { + process.stdout.write(' -> '); + + for (var i=0; i 126) { + c = '.'; + } + + process.stdout.write(c + ' [' + d.readUInt8(i).toString(16) + '] '); + } + process.stdout.write('\n'); + }); + } + + this.c = function(value, fn, expectedResponseLength) { + that.cmds.push({ + value : value, + callback : function(data) { + fn && fn(data); + }, + expectedResponseLength: expectedResponseLength + }); + return this; + } + + this.flashChunkSize = 0; + this.bytes = []; + this.cmds = []; +}; + +out.Flasher.prototype = { + run : function(fn) { + var that = this; + process.nextTick(function() { + if (that.running) { return; } + var cmd = that.cmds.shift(); + + if (cmd) { + running = true; + that.options.debug && process.stdout.write('Send: ' + cmd.value); + var response = new Buffer(0); + var onData = function(d) { + response = Buffer.concat([ + response, + d + ]); + + if (cmd.expectedResponseLength === undefined || // optional expected length not passed in + cmd.expectedResponseLength <= response.length) { + that.sp.removeListener('data', onData); + that.running = false; + cmd.callback(response); + + process.nextTick(function() { + if (that.cmds.length > 0) { + that.run(fn); + } else { + fn && fn(); + } + }); + } + }; + + that.sp.on('data', onData); + + that.sp.write(cmd.value); + } + }); + }, + + prepare : function(fn) { + var that = this; + this.c('S', function(d) { + if (d.toString() !== that.signature) { + fn(new Error('Invalid device signature; expecting: ' + that.signature + ' received: ' + d.toString())); + } + }) + .c('V') + .c('v') + .c('p') + .c('a') + .c('b', function(d) { + if ((d.toString() || 'X')[0] != 'Y') { + fn(new Error('Buffered memory access not supported.')); + } + that.flashChunkSize = d.readUInt16BE(1); + }) + .c('t') + .c('TD') + .c('P') + .c('F') + .c('F') + .c('F') + .c('N') + .c('N') + .c('N') + .c('Q') + .c('Q') + .c('Q') + .c([d('A'), 0x03, 0xfc]) + .c([d('g'), 0x00, 0x01, d('E')]) + .c([d('A'), 0x03, 0xff]) + .c([d('g'), 0x00, 0x01, d('E')]) + .c([d('A'), 0x03, 0xff]) + .c([d('g'), 0x00, 0x01, d('E')]) + .c([d('A'), 0x03, 0xff]) + .c([d('g'), 0x00, 0x01, d('E')]) + + this.run(function() { + fn(null, that); + }); + }, + + erase : function(fn) { + this.c('e', function() { + fn && fn(); + }) // erase + + this.run(); + }, + + program : function(fullString, fn) { + + var + that = this, + converter, + bytes = []; + + this.totalBytes = 0; + + this.c([d('A'), 0x00, 0x00], function() { + converter = intelHex.parse(fullString); + + that.totalBytes = converter.data.length; + // buffer the bytes so we can push them in the expected size on 'end' + Array.prototype.push.apply(bytes, converter.data); + // copy this array so we can use it strictly for comparing later + that.allBytes = bytes; + + that.options.debug && console.log('programming', bytes.length, 'bytes'); + that.chunksSent = []; + + for (var i=0; i> 8) & 0xFF, chunk.length & 0xFF, d('F')].concat(chunk)); + } + }); + + this.run(function() { fn && fn() }); + }, + + verify : function(fn) { + var that = this; + // compare flash on device with the chunks we sent + this.c([d('A'), 0x00, 0x00], function() { + + var + index = 0, + compare = function(deviceData) { + var error = null; + index++; + + if (!that.allBytes.length) { + fn && fn(); + return; + } + + var deviceDataLength = deviceData.length; + var localChunk = that.allBytes.splice(0, deviceDataLength); + + // iterate through the bytes sent to compare with the latest bytes received + localChunk.forEach(function(val, idx) { + if (val !== deviceData.readUInt8(idx)) { + error = new Error('Firmware on the device does not match local data'); + } + }); + + if (error) { + return fn(error); + } + + process.nextTick(function() { + var readSize = that.flashChunkSize; + that.options.debug && console.log(that.totalBytes - index*that.flashChunkSize); + if (that.totalBytes - index*that.flashChunkSize < that.flashChunkSize) { + readSize = that.totalBytes - index*that.flashChunkSize; + } + that.c([d('g'), (readSize >> 8) & 0xFF, readSize & 0xFF, d('F')], compare, readSize); + that.run(); + }); + }; + + that.options.debug && console.log('\n\nVerifying flash..') + + that.c([d('g'), (that.flashChunkSize >> 8) & 0xFF, that.flashChunkSize & 0xFF, d('F')], compare, that.flashChunkSize); + that.run(); + }); + that.run(); + }, + + fuseCheck : fuseCheck = function(fn) { + this.options.debug && console.log('checking fuses'); + // fuse check + this.c('F') + .c('F') + .c('F') + .c('N') + .c('N') + .c('N') + .c('Q') + .c('Q') + .c('Q') + .c('L') + .c('E'); + + this.run(function() { + fn(); + }); + } +}; + +out.init = function(serialport, options, fn) { + if (typeof options === 'function' && !fn) { + fn = options; + options = {}; + } + + var flasher = new out.Flasher(serialport, options); + flasher.prepare(fn); +}; /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1), __webpack_require__(0).Buffer)) diff --git a/client/src/lib/index.js b/client/src/scripts.js similarity index 61% rename from client/src/lib/index.js rename to client/src/scripts.js index a42ac820..06cb1fae 100644 --- a/client/src/lib/index.js +++ b/client/src/scripts.js @@ -1,28 +1,30 @@ +import AvrgirlArduino from './avrgirl-arduino'; + var workspace = Blockly.inject('blockly-canvas', {toolbox: document.getElementById('toolbox')}); -function getJS() { +export function getJS() { // Generates Arduino code to display it. - Blockly.JavaScript.INFINITE_LOOP_TRAP = null; - var code = Blockly.JavaScript.workspaceToCode(workspace); + window.Blockly.JavaScript.INFINITE_LOOP_TRAP = null; + var code = window.Blockly.JavaScript.workspaceToCode(workspace); return code; } -function getArduino() { +export function getArduino() { // Generates Arduino code to display it. - Blockly.Arduino.INFINITE_LOOP_TRAP = null; - var code = Blockly.Arduino.workspaceToCode(workspace); + window.Blockly.Arduino.INFINITE_LOOP_TRAP = null; + var code = window.Blockly.Arduino.workspaceToCode(workspace); return code; } -function compileArduinoCode() { - body = { +export function compileArduinoCode() { + let body = { "board": "arduino:avr:uno", "sketch": getArduino() }; // gets compiled hex from server let Hex; - $.post("http://174.138.32.52:3000/compile", body, (data) => { + window.$.post("http://174.138.32.52:3000/compile", body, (data) => { // converting base 64 to hex Hex = atob(data.hex).toString(); console.log(Hex); @@ -46,8 +48,8 @@ function compileArduinoCode() { } -$(document).ready(function() { - $('input[type=radio][name=model-btn]').change(function() { +window.$(document).ready(function() { + window.$('input[type=radio][name=model-btn]').change(function() { document.getElementById('model-img').src = `./assets/${this.value}.png` }); -}) \ No newline at end of file +}); \ No newline at end of file