diff --git a/.travis.yml b/.travis.yml index 3e933c61..39d8caa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,9 @@ +sudo: required language: node_js -dist: trusty node_js: - - "0.10" - - "0.12" - - "4" - "6" - - "7" + - "8" + - "10" after_script: - npm run-script coveralls notifications: diff --git a/README.md b/README.md index d84517f0..eb5b6ff0 100644 --- a/README.md +++ b/README.md @@ -23,37 +23,30 @@ and to further provide support for rapidly creating GUIs for your embedded applications through the use of HTML5/JavaScript web pages. -Installation ------------- -BoneScript comes installed on your BeagleBone. To update -to the latest revision or install it on another distribution, use 'npm': - +Global Installation +------------------- +BoneScript comes installed on your BeagleBone. To update to the latest revision, use 'npm' +on a recent BeagleBoard.org Debian image from https://beagleboard.org/latest-images +and perform: ````sh -TERM=none npm install -g bonescript +TERM=none sudo npm cache clear +TERM=none sudo npm install -g --prefix /usr/local --unsafe-perm bonescript +sudo shutdown -r now ```` -Angstrom prerequisites: -````sh -opkg update -opkg install python-misc python-modules -```` - -Debian and Ubuntu prerequisites: -* Credit to http://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree/compiling-an-overlay -````sh -sudo apt-get install -y build-essential g++ python-setuptools python2.7-dev -wget -c https://raw.github.com/RobertCNelson/tools/master/pkgs/dtc.sh -chmod +x dtc.sh -./dtc.sh -```` +Testing on other distributions is limited. -Some steps to consider: +There are some additional installation steps that can be performed, but are typically +installed by other mechanisms on the BeagleBoard.org Debian images. These setup +background services (bone101 webserver with bonescript RPC and bonescript autorun +service) as well as configure environment variables for these services and other +globally run scripts. ````sh -cp bonescript/etc/default/node /etc/default/node -cp bonescript/etc/profile.d/node.sh /etc/profile.d/node.sh -cp bonescript/systemd/\* /lib/systemd/system -systemctl enable bonescript.socket -systemctl enable bonescript-autorun.service +sudo cp bonescript/etc/default/node /etc/default/node +sudo cp bonescript/etc/profile.d/node.sh /etc/profile.d/node.sh +sudo cp bonescript/systemd/\* /lib/systemd/system +sudo systemctl enable bonescript.socket +sudo systemctl enable bonescript-autorun.service ```` Launching applications persistently @@ -83,7 +76,7 @@ Directory layout Template ======== -For a Bonescript application, you must currently manually 'require' the +For a BoneScript application, you must currently manually 'require' the bonescript library. Functions are then referenced through the object provided back from require. @@ -159,6 +152,19 @@ Uses https://github.com/korevec/node-i2c * i2cReadBytes(port, command, length, [callback]) * i2cStream(port, command, length, [callback]) +Robot Control +------------- +__new in 0.7.0__ Runs on BeagleBone Blue; or BeagleBone Black or BeagleBone Black Wireless with BeagleBoard.org Robotics Cape +* rcInitialize([callback]) +* rcState([state], [callback]) -> state +* rcLED(led, [value], [callback]) -> value +* rcOn(event, [callback]) +* rcMotor(motor, value, [callback]) +* rcServo(option, value, [callback]) +* rcBMP([option], [callback]) -> value +* rcIMU([option], [callback]) -> value +* rcEncoder(encoder, [value], [callback]) -> value + Bits/Bytes, Math, Trigonometry and Random Numbers ------------------------------------------------- * lowByte(value) @@ -210,6 +216,16 @@ that respond to events in the system. What makes JavaScript so much easier than other languages for doing this is that it keeps the full context around the handler, so you don't have to worry about it. +What's New +========== + +0.7.0 key updates +----------------- +Most of these fixes came from a [Google Summer of Code 2018 project](https://github.com/vaishnav98/bone101/wiki/BeagleBoard-GSoC'18:-Fixing-Bugs-in-BoneScript-and-Improving-BeagleBone-User-Interface) +* Fixes in PWM output during analogWrite updates +* Added function calls for Robot Control library support on BeagleBone Blue or Robotics Cape +* Added support for node-style callbacks with error and data separated (optional) + Plans ===== * SPI support diff --git a/autorun.js b/autorun.js index 2f0c87d5..7c432557 100644 --- a/autorun.js +++ b/autorun.js @@ -2,4 +2,4 @@ var b = require('bonescript'); var directory = (process.env.AUTORUN_DIR) ? process.env.AUTORUN_DIR : '/var/lib/cloud9/autorun'; -b.autorun(directory); +b.autorun(directory); \ No newline at end of file diff --git a/lint-config.json b/lint-config.json new file mode 100644 index 00000000..a43d08d6 --- /dev/null +++ b/lint-config.json @@ -0,0 +1,23 @@ +{ + "indent_size": 4, + "indent_char": " ", + "indent_with_tabs": false, + "eol": "\n", + "end_with_newline": false, + "indent_level": 0, + "preserve_newlines": true, + "max_preserve_newlines": 10, + "space_in_paren": false, + "space_in_empty_paren": false, + "jslint_happy": true, + "space_after_anon_function": false, + "brace_style": "collapse", + "unindent_chained_methods": false, + "break_chained_methods": false, + "keep_array_indentation": false, + "unescape_strings": false, + "wrap_line_length": 0, + "e4x": false, + "comma_first": false, + "operator_position": "before-newline" +} diff --git a/main.js b/main.js index 59c3a56c..8b31d7e7 100644 --- a/main.js +++ b/main.js @@ -1,3 +1,3 @@ -module.exports = process.env.BONESCRIPT_COV - ? require('./src-cov/index') - : require('./src/index'); +module.exports = process.env.BONESCRIPT_COV ? + require('./src-cov/index') : + require('./src/index'); \ No newline at end of file diff --git a/package.json b/package.json index 1750b27d..baf7b078 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "gpio", "arduino" ], - "version": "0.6.1", + "version": "0.7.1", "homepage": "http://beagleboard.org/bonescript", "license": "MIT", "repository": { @@ -23,31 +23,39 @@ "url": "git://github.com/jadonk/bonescript" }, "main": "main", + "types": "./src/index.d.ts", "engines": { - "node": ">= 0.12.1" + "node": ">= 6.0.0" }, "dependencies": { + "chokidar": "2.0.3", + "express": "4.13.4", "socket.io": "1.4.5", - "systemd": "0.2.6", + "systemd": "0.3.1", "winston": "2.1.1", - "express": "4.13.4", - "ffi": "2.0.0" + "@types/verror": "latest", + "shelljs": "0.8.2" }, "optionalDependencies": { - "serialport": "3.1.2", + "serialport": "6.0.5", + "@types/serialport": "latest", "i2c": "0.2.3", "epoll": "0.1.18", - "pi-spi": "1.0.1", - "roboticscape": "0.0.2" + "pi-spi": "1.0.2", + "roboticscape": "0.0.8", + "ffi": "2.2.0" }, "devDependencies": { - "jscoverage": "~0.5.1", - "nodeunit": "~0.9.0", - "coveralls": "~2.10.0" + "coveralls": "~3.0.1", + "js-beautify": "^1.7.5", + "jscoverage": "~0.6.0", + "nodeunit": "^0.11.2", + "socket.io-client": "1.4.5" }, "scripts": { "start": "node server.js", "test": "NODE_PATH=.. nodeunit test", + "beautify": "NODE_PATH=.. js-beautify --config lint-config.json -r -f *.js src/*.js test/*.js", "coveralls": "NODE_PATH=.. jscoverage src && NODE_PATH=.. BONESCRIPT_COV=1 nodeunit --reporter=lcov test | coveralls" } } diff --git a/server.js b/server.js index b364fa30..9d218302 100644 --- a/server.js +++ b/server.js @@ -1,21 +1,38 @@ var b = require('bonescript'); var util = require('util'); +var fs = require('fs'); +var configFile = '/etc/default/bonescript'; +var server; +//read the configuration from configFile +fs.readFile(configFile, { + encoding: 'ascii' +}, function read(err, data) { + if (err) { + server = b.serverStart(); //start server with default settings + } else { + data = JSON.parse(data); //start server with saved config + server = b.serverStart(data.port, data.directory, { + data: data.passphrase, + hash: data.hash + }); + } + onServerStart(); +}); -var server = b.serverStart(); - -server.on('server$listening', serverListening); -server.on('server$error', serverError); -server.on('server$connection', serverConnection); +function onServerStart() { + server.on('server$listening', serverListening); + server.on('server$error', serverError); + server.on('server$connection', serverConnection); +} function serverListening() { - if(debug) winston.debug('Server listening'); + if (debug) winston.debug('Server listening'); } function serverError(error) { - if(debug) winston.debug('Server error: ' + JSON.stringify(error)); + if (debug) winston.debug('Server error: ' + JSON.stringify(error)); } function serverConnection(connection) { - if(debug) winston.debug('Server connection: ' + connection); -} - + if (debug) winston.debug('Server connection: ' + connection); +} \ No newline at end of file diff --git a/src/autorun.js b/src/autorun.js index a36b552c..ec6133a3 100644 --- a/src/autorun.js +++ b/src/autorun.js @@ -4,23 +4,28 @@ var fs = require('fs'); var child_process = require('child_process'); var winston = require('winston'); +var events = require('events'); +var chokidar = require('chokidar'); -exports.autorun = function(dir) { - var ar = dir || '/var/lib/cloud9/autorun'; +var debug = process.env.DEBUG ? true : false; +var apps = {}; +var watchers = []; +var emitter = new events.EventEmitter(); - var apps = {}; +var autorun = function (dir) { + var ar = dir || '/var/lib/cloud9/autorun'; winston.info('Starting bonescript autorun service'); fs.exists(ar, arExists); function arExists(exists) { - if(!exists) fs.mkdir(ar, arWatch); + if (!exists) fs.mkdir(ar, arWatch); else fs.readdir(ar, arFound); } function arFound(err, files) { - if(err) { + if (err) { winston.err('Error reading directory: ' + err); arWatch(); return; @@ -29,105 +34,147 @@ exports.autorun = function(dir) { arTestNext(); function arTestNext() { - if(i == files.length) { + if (i == files.length) { arWatch(); return; } - appStart(files[i]); + if (debug) winston.debug("arTestNext: files[" + i + "] = " + ar + '/' + files[i]); + appStart(ar + '/' + files[i]); i++; arTestNext(); } } function appStart(file) { - if(apps[file]) return; + if (apps[file]) { + if (debug) winston.debug("already started: " + file); + return; + } appTest(); function appTest() { - fs.exists(ar + '/' + file, appExists); + fs.exists(file, appExists); } function appExists(exists) { function onStdout(data) { winston.info('stdout (' + file + '): ' + data); } + function onStderr(data) { winston.info('stderr (' + file + '):' + data); } - - if(exists) { - if(typeof apps[file] != 'undefined') { + + if (exists) { + if (typeof apps[file] != 'undefined') { winston.info('already running: ' + file); return; } - - if(file.match(/\.js$/)) { + + if (file.match(/\.js$/)) { winston.info('start: ' + file); - apps[file] = child_process.spawn(process.argv[0], [ar + '/' + file]); + apps[file] = child_process.spawn(process.argv[0], [file]); apps[file].on('close', appClosed); apps[file].stdout.on('data', onStdout); apps[file].stderr.on('data', onStderr); - } else if(file.match(/\.py$/)) { + } else if (file.match(/\.py$/)) { winston.info('start: ' + file); - apps[file] = child_process.spawn('/usr/bin/python', [ar + '/' + file]); + apps[file] = child_process.spawn('/usr/bin/python', [file]); apps[file].on('close', appClosed); apps[file].stdout.on('data', onStdout); apps[file].stderr.on('data', onStderr); - } else if(file.match(/\.sh$/)) { + } else if (file.match(/\.sh$/)) { winston.info('start: ' + file); - apps[file] = child_process.spawn('/bin/bash', [ar + '/' + file]); + apps[file] = child_process.spawn('/bin/bash', [file]); apps[file].on('close', appClosed); apps[file].stdout.on('data', onStdout); apps[file].stderr.on('data', onStderr); - } else if(file.match(/\.ino$/)) { + } else if (file.match(/\.ino$/)) { winston.info('start: ' + file); - apps[file] = child_process.spawn('/usr/bin/make', - [ - "-f", - "/var/lib/cloud9/extras/Userspace-Arduino/Makefile", - "TARGET=" + file.replace(/\.ino$/, ''), - "LOCAL_INO_SRCS=" + file, - "LOCAL_C_SRCS=", - "LOCAL_CPP_SRCS=", - "LOCAL_PDE_SRCS=", - "LOCAL_AS_SRCS=", - "COMMON_DEPS=" - ], - { 'cwd': ar } - ); + apps[file] = child_process.spawn('/usr/bin/make', [ + "-f", + "/var/lib/cloud9/extras/Userspace-Arduino/Makefile", + "TARGET=" + file.replace(/\.ino$/, ''), + "LOCAL_INO_SRCS=" + file, + "LOCAL_C_SRCS=", + "LOCAL_CPP_SRCS=", + "LOCAL_PDE_SRCS=", + "LOCAL_AS_SRCS=", + "COMMON_DEPS=" + ], { + 'cwd': ar + }); apps[file].on('close', appClosed); apps[file].stdout.on('data', onStdout); apps[file].stderr.on('data', onStderr); } + emitter.emit('start', file); } } - + function appClosed(code, signal) { + winston.info("closed: " + file); delete apps[file]; - setTimeout(appTest, 1000); + emitter.emit('closed', file); + //setTimeout(appTest, 1000); } } - + function arWatch() { - fs.watch(ar, arWatcher); + if (debug) winston.debug("arWatch: " + ar); + var w = chokidar.watch(ar, { + persistent: true + }); + w.on('add', arAdd); + w.on('change', arChange); + w.on('unlink', appStop); + watchers.push(w); } - function arWatcher(event, filename) { - if(event == 'change') { - winston.info('change: ' + filename); - appStop(filename); - appStart(filename); - } else if(event == 'rename') { - winston.info('rename: ' + filename); - appStop(filename); - appStart(filename); - } + function arAdd(filename) { + winston.info('add: ' + filename); + appStart(filename); + } + + function arChange(filename) { + winston.info('change: ' + filename); + appStop(filename); + appStart(filename); } function appStop(file) { - if(typeof apps[file] != 'undefined') { + if (debug) { + for (var x in apps) { + winston.debug('running: ' + x); + } + } + if (typeof apps[file] != 'undefined') { + emitter.emit('stop', file); winston.info('stop: ' + file + ' (pid: ' + apps[file].pid + ')'); apps[file].kill('SIGTERM'); + } else { + winston.info('already stopped: ' + file); } } -} + + return ({ + getApps: function () { + return (apps); + }, + getEmitter: function () { + return (emitter); + }, + stop: function () { + for (var app in apps) { + appStop(app); + } + for (var w in watchers) { + watchers[w].close(); + } + } + }); +}; + +module.exports = { + autorun: autorun +}; \ No newline at end of file diff --git a/src/bone.js b/src/bone.js index 382dea8b..d4868db9 100644 --- a/src/bone.js +++ b/src/bone.js @@ -4,13 +4,12 @@ // pins is an object whose keys are the pinIndex keys, e.g. P9_14. // uarts and i2c are objects describing the serial ports and i2c buses. -if(typeof exports === 'undefined') exports = {}; -var pinIndex = [ - { + +var pinIndex = [{ "name": "USR0", "gpio": 53, - "led": "usr0", + "led": "beaglebone:green:usr0", "mux": "gpmc_a5", "key": "USR0", "muxRegOffset": "0x054", @@ -23,12 +22,16 @@ var pinIndex = [ "pr1_mii1_rxd3", "eqep1b_in", "gpio1_21" - ] + ], + "ball": { + "ZCZ": "V15", + "BSM": "P13" + } }, { "name": "USR1", "gpio": 54, - "led": "usr1", + "led": "beaglebone:green:usr1", "mux": "gpmc_a6", "key": "USR1", "muxRegOffset": "0x058", @@ -41,12 +44,16 @@ var pinIndex = [ "pr1_mii1_rxd2", "eqep1_index", "gpio1_22" - ] + ], + "ball": { + "ZCZ": "U15", + "BSM": "T14" + } }, { "name": "USR2", "gpio": 55, - "led": "usr2", + "led": "beaglebone:green:usr2", "mux": "gpmc_a7", "key": "USR2", "muxRegOffset": "0x05c", @@ -59,12 +66,16 @@ var pinIndex = [ "pr1_mii1_rxd1", "eqep1_strobe", "gpio1_23" - ] + ], + "ball": { + "ZCZ": "T15", + "BSM": "R14" + } }, { "name": "USR3", "gpio": 56, - "led": "usr3", + "led": "beaglebone:green:usr3", "mux": "gpmc_a8", "key": "USR3", "muxRegOffset": "0x060", @@ -77,15 +88,19 @@ var pinIndex = [ "pr1_mii1_rxd0", "mcasp0_aclkx", "gpio1_24" - ] - }, - { - "name": "DGND", - "key": "P8_1" + ], + "ball": { + "ZCZ": "V16", + "BSM": "P14" + } }, { "name": "DGND", - "key": "P8_2" + "key": ["P8_1", "P8_2", "P9_1", "P9_2", "P9_43", "P9_44", "P9_45", "P9_46", + "P1_15", "P1_16", "P1_22", "P2_15", "P2_21", + "E1_1", "E2_1", "E3_1", "E4_1", "S1_1_1", "S1_2_1", "UT0_1", "UT1_1", "UT5_1", + "DSM2_2", "I2C_1", "GPS_2", "GPS_6", "GP0_1", "GP1_1" + ] }, { "name": "GPIO1_6", @@ -93,7 +108,7 @@ var pinIndex = [ "mux": "gpmc_ad6", "eeprom": 26, "key": "P8_3", - "universalName": "P8_03", + "universalName": ["ocp:P8_03_pinmux"], "muxRegOffset": "0x018", "options": [ "gpmc_ad6", @@ -104,7 +119,11 @@ var pinIndex = [ "NA", "NA", "gpio1_6" - ] + ], + "ball": { + "ZCZ": "R9", + "BSM": "P4" + } }, { "name": "GPIO1_7", @@ -112,7 +131,7 @@ var pinIndex = [ "mux": "gpmc_ad7", "eeprom": 27, "key": "P8_4", - "universalName": "P8_04", + "universalName": ["ocp:P8_04_pinmux"], "muxRegOffset": "0x01c", "options": [ "gpmc_ad7", @@ -123,7 +142,11 @@ var pinIndex = [ "NA", "NA", "gpio1_7" - ] + ], + "ball": { + "ZCZ": "T9", + "BSM": "R4" + } }, { "name": "GPIO1_2", @@ -131,7 +154,7 @@ var pinIndex = [ "mux": "gpmc_ad2", "eeprom": 22, "key": "P8_5", - "universalName": "P8_05", + "universalName": ["ocp:P8_05_pinmux"], "muxRegOffset": "0x008", "options": [ "gpmc_ad2", @@ -142,7 +165,11 @@ var pinIndex = [ "NA", "NA", "gpio1_2" - ] + ], + "ball": { + "ZCZ": "R8", + "BSM": "R1" + } }, { "name": "GPIO1_3", @@ -150,7 +177,7 @@ var pinIndex = [ "mux": "gpmc_ad3", "eeprom": 23, "key": "P8_6", - "universalName": "P8_06", + "universalName": ["ocp:P8_06_pinmux"], "muxRegOffset": "0x00c", "options": [ "gpmc_ad3", @@ -161,134 +188,111 @@ var pinIndex = [ "NA", "NA", "gpio1_3" - ] + ], + "ball": { + "ZCZ": "T8", + "BSM": "T3" + } }, { "name": "TIMER4", "gpio": 66, "mux": "gpmc_advn_ale", "eeprom": 41, - "key": "P8_7", - "universalName": "P8_07", - "muxRegOffset": "0x090", - "options": [ - "gpmc_advn_ale", - "NA", - "NA", - "NA", - "NA", - "NA", - "NA", - "mmc1_sdcd" - ] - }, - // Added for Blue - { - "name": "RED", - "gpio": 66, - "led": "red", - "mux": "gpmc_advn_ale", - "eeprom": 41, - "key": "RED", - "universalName": "RED", + "key": ["P8_7", "RED", "GP1_5"], + "led": [null, "red", "red"], + "universalName": ["ocp:P8_07_pinmux"], "muxRegOffset": "0x090", "options": [ "gpmc_advn_ale", "NA", + "timer4", "NA", "NA", "NA", "NA", - "NA", - "mmc1_sdcd" - ] + "gpio2_2" + ], + "ball": { + "ZCZ": "R7", + "BSM": "M1" + } }, { "name": "TIMER7", "gpio": 67, "mux": "gpmc_oen_ren", "eeprom": 44, - "key": "P8_8", - "universalName": "P8_08", - "muxRegOffset": "0x094", - "options": [ - "gpmc_oen_ren", - "NA", - "NA", - "NA", - "NA", - "NA", - "NA", - "gpio2_3" - ] - }, - - // Added for Blue - { - "name": "GREEN", - "gpio": 67, - "led": "green", - "mux": "gpmc_oen_ren", - "eeprom": 44, - "key": "GREEN", - "universalName": "GREEN", + "key": ["P8_8", "GREEN", "GP1_6"], + "led": [null, "green", "green"], + "universalName": ["ocp:P8_08_pinmux"], "muxRegOffset": "0x094", "options": [ "gpmc_oen_ren", "NA", - "NA", + "timer7", "NA", "NA", "NA", "NA", "gpio2_3" - ] + ], + "ball": { + "ZCZ": "T7", + "BSM": "N1" + } }, { "name": "TIMER5", "gpio": 69, "mux": "gpmc_ben0_cle", "eeprom": 42, - "key": "P8_9", - "key2": "PAUSE", - "universalName": "P8_09", + "key": ["P8_9", "PAUSE"], + "universalName": ["ocp:P8_09_pinmux"], "muxRegOffset": "0x09c", "options": [ "gpmc_ben0_cle", "NA", - "NA", + "timer5", "NA", "NA", "NA", "NA", "gpio2_5" - ] + ], + "ball": { + "ZCZ": "T6", + "BSM": "N3" + } }, { "name": "TIMER6", "gpio": 68, "mux": "gpmc_wen", "eeprom": 43, - "key": "P8_10", - "key2": "MODE", + "key": ["P8_10", "MODE"], "muxRegOffset": "0x098", "options": [ "gpmc_wen", "NA", - "NA", + "timer6", "NA", "NA", "NA", "NA", "gpio2_4" - ] + ], + "ball": { + "ZCZ": "U6", + "BSM": "N2" + } }, { "name": "GPIO1_13", "gpio": 45, "mux": "gpmc_ad13", "eeprom": 29, - "key": "P8_11", + "key": ["P8_11", "E3_4", "P2_33"], "muxRegOffset": "0x034", "options": [ "gpmc_ad13", @@ -299,14 +303,18 @@ var pinIndex = [ "pr1_mii0_txd", "pr1_pru0_pru_r30_15", "gpio1_13" - ] + ], + "ball": { + "ZCZ": "R12", + "BSM": "R6" + } }, { "name": "GPIO1_12", "gpio": 44, "mux": "gpmc_ad12", "eeprom": 28, - "key": "P8_12", + "key": ["P8_12", "E3_3", "P2_24"], "muxRegOffset": "0x030", "options": [ "gpmc_ad12", @@ -317,7 +325,11 @@ var pinIndex = [ "pr1_mii0_txd2", "pr1_pru0_pru_r30_14", "gpio1_12" - ] + ], + "ball": { + "ZCZ": "T12", + "BSM": "P6" + } }, { "name": "EHRPWM2B", @@ -336,7 +348,8 @@ var pinIndex = [ "chip": "48304000", "addr": "48304200" }, - "key": "P8_13", + "key": ["P8_13", "P2_3"], + "universalName": ["ocp:P8_13_pinmux", "ocp:P2_03_pinmux"], "muxRegOffset": "0x024", "options": [ "gpmc_ad9", @@ -347,34 +360,19 @@ var pinIndex = [ "pr1_mii0_col", "NA", "gpio0_23" - ] + ], + "ball": { + "ZCZ": "T10", + "BSM": "P5" + } }, { "name": "GPIO0_26", "gpio": 26, "mux": "gpmc_ad10", "eeprom": 16, - "key": "P8_14", - "muxRegOffset": "0x028", - "options": [ - "gpmc_ad10", - "lcd_data21", - "mmc1_dat2", - "mmc2_dat6", - "ehrpwm2_tripzone_input", - "pr1_mii0_txen", - "NA", - "gpio0_26" - ] - }, - // For Blue - { - "name": "BAT100", - "gpio": 26, - "led": "bat100", - "mux": "gpmc_ad10", - "eeprom": 16, - "key": "BAT100", + "key": ["P8_14", "BAT100", "P1_34"], + "led": [null, "bat100", null], "muxRegOffset": "0x028", "options": [ "gpmc_ad10", @@ -385,14 +383,18 @@ var pinIndex = [ "pr1_mii0_txen", "NA", "gpio0_26" - ] + ], + "ball": { + "ZCZ": "T11", + "BSM": "R5" + } }, { "name": "GPIO1_15", "gpio": 47, "mux": "gpmc_ad15", "eeprom": 31, - "key": "P8_15", + "key": ["P8_15", "E4_4", "P2_18"], "muxRegOffset": "0x03c", "options": [ "gpmc_ad15", @@ -403,14 +405,18 @@ var pinIndex = [ "pr1_ecap0_ecap_capin_apwm_o", "pr1_pru0_pru_r31_15", "gpio1_15" - ] + ], + "ball": { + "ZCZ": "U13", + "BSM": "P7" + } }, { "name": "GPIO1_14", "gpio": 46, "mux": "gpmc_ad14", "eeprom": 30, - "key": "P8_16", + "key": ["P8_16", "E4_3", "P2_22"], "muxRegOffset": "0x038", "options": [ "gpmc_ad14", @@ -421,34 +427,19 @@ var pinIndex = [ "pr1_mii0_txd0", "pr1_pru0_pru_r31_14", "gpio1_14" - ] + ], + "ball": { + "ZCZ": "V13", + "BSM": "T6" + } }, { "name": "GPIO0_27", "gpio": 27, "mux": "gpmc_ad11", "eeprom": 17, - "key": "P8_17", - "muxRegOffset": "0x02c", - "options": [ - "gpmc_ad11", - "lcd_data20", - "mmc1_dat3", - "mmc2_dat7", - "ehrpwm0_synco", - "pr1_mii0_txd3", - "NA", - "gpio0_27" - ] - }, - // For Blue - { - "name": "BAT25", - "gpio": 27, - "led": "bat25", - "mux": "gpmc_ad11", - "eeprom": 17, - "key": "BAT25", + "key": ["P8_17", "BAT25", "P2_19"], + "led": [null, "bat25", null], "muxRegOffset": "0x02c", "options": [ "gpmc_ad11", @@ -459,14 +450,18 @@ var pinIndex = [ "pr1_mii0_txd3", "NA", "gpio0_27" - ] + ], + "ball": { + "ZCZ": "U12", + "BSM": "T5" + } }, { "name": "GPIO2_1", "gpio": 65, "mux": "gpmc_clk", "eeprom": 40, - "key": "P8_18", + "key": ["P8_18", "P2_17"], "muxRegOffset": "0x08c", "options": [ "gpmc_clk", @@ -477,7 +472,11 @@ var pinIndex = [ "NA", "mcasp0_fsr", "gpio2_1" - ] + ], + "ball": { + "ZCZ": "V12", + "BSM": "T7" + } }, { "name": "EHRPWM2A", @@ -507,7 +506,11 @@ var pinIndex = [ "pr1_mii_mt0_clk", "NA", "gpio0_22" - ] + ], + "ball": { + "ZCZ": "U10", + "BSM": "T4" + } }, { "name": "GPIO1_31", @@ -525,7 +528,11 @@ var pinIndex = [ "pr1_pru1_pru_r30_13", "pr1_pru1_pru_r31_13", "gpio1_31" - ] + ], + "ball": { + "ZCZ": "V9", + "BSM": "P1" + } }, { "name": "GPIO1_30", @@ -543,7 +550,11 @@ var pinIndex = [ "pr1_pru1_pru_r30_12", "pr1_pru1_pru_r31_12", "gpio1_30" - ] + ], + "ball": { + "ZCZ": "U9", + "BSM": "P2" + } }, { "name": "GPIO1_5", @@ -561,7 +572,11 @@ var pinIndex = [ "NA", "NA", "gpio1_5" - ] + ], + "ball": { + "ZCZ": "V8", + "BSM": "T1" + } }, { "name": "GPIO1_4", @@ -579,7 +594,11 @@ var pinIndex = [ "NA", "NA", "gpio1_4" - ] + ], + "ball": { + "ZCZ": "U8", + "BSM": "T2" + } }, { "name": "GPIO1_1", @@ -597,7 +616,11 @@ var pinIndex = [ "NA", "NA", "gpio1_1" - ] + ], + "ball": { + "ZCZ": "V7", + "BSM": "R2" + } }, { "name": "GPIO1_0", @@ -615,34 +638,19 @@ var pinIndex = [ "NA", "NA", "gpio1_0" - ] + ], + "ball": { + "ZCZ": "U7", + "BSM": "R3" + } }, { "name": "GPIO1_29", "gpio": 61, "mux": "gpmc_csn0", "eeprom": 37, - "key": "P8_26", - "muxRegOffset": "0x07c", - "options": [ - "gpmc_csn0", - "NA", - "NA", - "NA", - "NA", - "NA", - "NA", - "gpio1_29" - ] - }, - // For Blue - { - "name": "BAT75", - "gpio": 61, - "led": "bat75", - "mux": "gpmc_csn0", - "eeprom": 37, - "key": "BAT75", + "key": ["P8_26", "BAT75"], + "led": [null, "bat75"], "muxRegOffset": "0x07c", "options": [ "gpmc_csn0", @@ -653,34 +661,41 @@ var pinIndex = [ "NA", "NA", "gpio1_29" - ] + ], + "ball": { + "ZCZ": "V6", + "BSM": "P3" + } }, - // For Blue, This is a guess { - "name": "WIFI", - "gpio": 10000, // Placeholder - "led": "wifi", - "mux": "gpmc_csn0", + "name": "GPIO0_19", + "gpio": 19, + "mux": "xdma_event_intr0", "eeprom": 37, - "key": "WIFI", - "muxRegOffset": "0x07c", + "key": ["WIFI", "P2_31"], + "led": ["wifi", null], + "muxRegOffset": "0x1b0", "options": [ - "gpmc_csn0", + "xdma_event_intr0", "NA", - "NA", - "NA", - "NA", - "NA", - "NA", - "gpio1_29" - ] + "timer4", + "clkout1", + "spi1_cs1", + "pr1_pru1_pru_r31", + "EMU2", + "gpio0_19" + ], + "ball": { + "ZCZ": "A15", + "BSM": "A4" + } }, { "name": "GPIO2_22", "gpio": 86, "mux": "lcd_vsync", "eeprom": 57, - "key": "P8_27", + "key": ["P8_27", "SERVO_1", "P2_35"], "muxRegOffset": "0x0e0", "options": [ "lcd_vsync", @@ -691,14 +706,18 @@ var pinIndex = [ "pr1_pru1_pru_r30_8", "pr1_pru1_pru_r31_8", "gpio2_22" - ] + ], + "ball": { + "ZCZ": "U5", + "BSM": "F3" + } }, { "name": "GPIO2_24", "gpio": 88, "mux": "lcd_pclk", "eeprom": 59, - "key": "P8_28", + "key": ["P8_28", "SERVO_2", "P1_35", "PRU1_10"], "muxRegOffset": "0x0e8", "options": [ "lcd_pclk", @@ -709,32 +728,40 @@ var pinIndex = [ "pr1_pru1_pru_r30_10", "pr1_pru1_pru_r31_10", "gpio2_24" - ] + ], + "ball": { + "ZCZ": "V5", + "BSM": "F1" + } }, { "name": "GPIO2_23", "gpio": 87, "mux": "lcd_hsync", "eeprom": 58, - "key": "P8_29", + "key": ["P8_29", "SERVO_3", "P1_2"], "muxRegOffset": "0x0e4", "options": [ "lcd_hsync", "gpmc_a9", - "NA", + "gpmc_a2", "pr1_edio_data_in3", "pr1_edio_data_out3", "pr1_pru1_pru_r30_9", "pr1_pru1_pru_r31_9", "gpio2_23" - ] + ], + "ball": { + "ZCZ": "R5", + "BSM": "F2" + } }, { "name": "GPIO2_25", "gpio": 89, "mux": "lcd_ac_bias_en", "eeprom": 60, - "key": "P8_30", + "key": ["P8_30", "SERVO_4", "P1_4", "PRU1_11"], "muxRegOffset": "0x0ec", "options": [ "lcd_ac_bias_en", @@ -745,7 +772,11 @@ var pinIndex = [ "pr1_pru1_pru_r30_11", "pr1_pru1_pru_r31_11", "gpio2_25" - ] + ], + "ball": { + "ZCZ": "R6", + "BSM": "E1" + } }, { "name": "UART5_CTSN", @@ -763,34 +794,19 @@ var pinIndex = [ "NA", "NA", "gpio0_10" - ] + ], + "ball": { + "ZCZ": "V4", + "BSM": "L1" + } }, { "name": "UART5_RTSN", "gpio": 11, "mux": "lcd_data15", "eeprom": 8, - "key": "P8_32", - "muxRegOffset": "0x0dc", - "options": [ - "lcd_data15", - "gpmc_a19", - "NA", - "mcasp0_ahclkx", - "mcasp0_axr3", - "NA", - "NA", - "gpio0_11" - ] - }, - // Added for Blue - { - "name": "BAT50", - "gpio": 11, - "led": "bat50", - "mux": "lcd_data15", - "eeprom": 8, - "key": "BAT50", + "key": ["P8_32", "BAT50"], + "led": [null, "bat50"], "muxRegOffset": "0x0dc", "options": [ "lcd_data15", @@ -801,14 +817,18 @@ var pinIndex = [ "NA", "NA", "gpio0_11" - ] + ], + "ball": { + "ZCZ": "T5", + "BSM": "M3" + } }, { "name": "UART4_RTSN", "gpio": 9, "mux": "lcd_data13", "eeprom": 6, - "key": "P8_33", + "key": ["P8_33", "E2_4"], "muxRegOffset": "0x0d4", "options": [ "lcd_data13", @@ -819,7 +839,11 @@ var pinIndex = [ "NA", "NA", "gpio0_9" - ] + ], + "ball": { + "ZCZ": "V3", + "BSM": "L2" + } }, { "name": "UART3_RTSN", @@ -849,14 +873,19 @@ var pinIndex = [ "NA", "NA", "gpio2_17" - ] + ], + "ball": { + "ZCZ": "V3", + "BSM": "K1" + } + }, { "name": "UART4_CTSN", "gpio": 8, "mux": "lcd_data12", "eeprom": 5, - "key": "P8_35", + "key": ["P8_35", "E2_3"], "muxRegOffset": "0x0d0", "options": [ "lcd_data12", @@ -867,7 +896,12 @@ var pinIndex = [ "NA", "NA", "gpio0_8" - ] + ], + "ball": { + "ZCZ": "V2", + "BSM": "L3" + } + }, { "name": "UART3_CTSN", @@ -886,7 +920,7 @@ var pinIndex = [ "chip": "48302000", "addr": "48302200" }, - "key": "P8_36", + "key": ["P8_36", "SERVO_PWR_EN"], "muxRegOffset": "0x0c8", "options": [ "lcd_data10", @@ -897,14 +931,19 @@ var pinIndex = [ "pr1_mii0_rxd1", "uart3_ctsn", "gpio2_16" - ] + ], + "ball": { + "ZCZ": "U3", + "BSM": "K2" + } + }, { "name": "UART5_TXD", "gpio": 78, "mux": "lcd_data8", "eeprom": 53, - "key": "P8_37", + "key": ["P8_37", "UT5_4"], "muxRegOffset": "0x0c0", "options": [ "lcd_data8", @@ -915,14 +954,19 @@ var pinIndex = [ "NA", "uart2_ctsn", "gpio2_14" - ] + ], + "ball": { + "ZCZ": "U1", + "BSM": "J1" + } + }, { "name": "UART5_RXD", "gpio": 79, "mux": "lcd_data9", "eeprom": 54, - "key": "P8_38", + "key": ["P8_38", "UT5_3"], "muxRegOffset": "0x0c4", "options": [ "lcd_data9", @@ -933,14 +977,19 @@ var pinIndex = [ "NA", "uart2_rtsn", "gpio2_15" - ] + ], + "ball": { + "ZCZ": "U2", + "BSM": "K3" + } + }, { "name": "GPIO2_12", "gpio": 76, "mux": "lcd_data6", "eeprom": 51, - "key": "P8_39", + "key": ["P8_39", "SERVO_5"], "muxRegOffset": "0x0b8", "options": [ "lcd_data6", @@ -951,32 +1000,42 @@ var pinIndex = [ "pr1_pru1_pru_r30_6", "pr1_pru1_pru_r31_6", "gpio2_12" - ] + ], + "ball": { + "ZCZ": "T3", + "BSM": "J3" + } + }, { "name": "GPIO2_13", "gpio": 77, "mux": "lcd_data7", "eeprom": 52, - "key": "P8_40", + "key": ["P8_40", "SERVO_6"], "muxRegOffset": "0x0bc", "options": [ "lcd_data7", "gpmc_a7", "pr1_edio_data_in7", "eqep2_strobe", + "pr1_edio_data_out_7", "pr1_pru1_pru_r30_7", - "pr1_pru_pru1_r30_7", "pr1_pru1_pru_r31_7", "gpio2_13" - ] + ], + "ball": { + "ZCZ": "T4", + "BSM": "J2" + } + }, { "name": "GPIO2_10", "gpio": 74, "mux": "lcd_data4", "eeprom": 49, - "key": "P8_41", + "key": ["P8_41", "SERVO_7"], "muxRegOffset": "0x0b0", "options": [ "lcd_data4", @@ -987,14 +1046,19 @@ var pinIndex = [ "pr1_pru1_pru_r30_4", "pr1_pru1_pru_r31_4", "gpio2_10" - ] + ], + "ball": { + "ZCZ": "T1", + "BSM": "H2" + } + }, { "name": "GPIO2_11", "gpio": 75, "mux": "lcd_data5", "eeprom": 50, - "key": "P8_42", + "key": ["P8_42", "SERVO_8"], "muxRegOffset": "0x0b4", "options": [ "lcd_data5", @@ -1005,7 +1069,12 @@ var pinIndex = [ "pr1_pru1_pru_r30_5", "pr1_pru1_pru_r31_5", "gpio2_11" - ] + ], + "ball": { + "ZCZ": "T2", + "BSM": "H1" + } + }, { "name": "GPIO2_8", @@ -1023,7 +1092,12 @@ var pinIndex = [ "pr1_pru1_pru_r30_2", "pr1_pru1_pru_r31_2", "gpio2_8" - ] + ], + "ball": { + "ZCZ": "R3", + "BSM": "G1" + } + }, { "name": "GPIO2_9", @@ -1041,7 +1115,12 @@ var pinIndex = [ "pr1_pru1_pru_r30_3", "pr1_pru1_pru_r31_3", "gpio2_9" - ] + ], + "ball": { + "ZCZ": "R4", + "BSM": "H3" + } + }, { "name": "GPIO2_6", @@ -1071,7 +1150,12 @@ var pinIndex = [ "pr1_pru1_pru_r30_0", "pr1_pru1_pru_r31_0", "gpio2_6" - ] + ], + "ball": { + "ZCZ": "R1", + "BSM": "G3" + } + }, { "name": "GPIO2_7", @@ -1101,72 +1185,71 @@ var pinIndex = [ "pr1_pru1_pru_r30_1", "pr1_pru1_pru_r31_1", "gpio2_7" - ] - }, - { - "name": "DGND", - "key": "P9_1" - }, - { - "name": "DGND", - "key": "P9_2" - }, - { - "name": "VDD_3V3", - "key": "P9_3" + ], + "ball": { + "ZCZ": "R2", + "BSM": "G2" + } + }, { "name": "VDD_3V3", - "key": "P9_4" - }, - { - "name": "VDD_5V", - "key": "P9_5" + "key": ["P9_3", "P9_4", "P1_14", "P2_23", + "E1_2", "E2_2", "E3_2", "E4_2", "GP0_2", "GP1_2", "S1_1_2", "S1_2_2", + "UT0_2", "UT1_2", "UT5_2", "DSM2_1", "I2C_2" + ] }, { "name": "VDD_5V", - "key": "P9_6" + "key": ["P9_5", "P9_6", "P1_1"] }, { "name": "SYS_5V", - "key": "P9_7" - }, - { - "name": "SYS_5V", - "key": "P9_8" + "key": ["P9_7", "P9_8", "P1_24", "P2_13", "GPS_5"] }, { "name": "PWR_BUT", - "key": "P9_9" + "key": ["P9_9", "P2_12"], + "ball": { + "BSM": "T11" + } }, { "name": "SYS_RESETn", - "key": "P9_10" + "key": ["P9_10", "P2_26"], + "ball": { + "ZCZ": "A10", + "BSM": "R11" + } }, { "name": "UART4_RXD", "gpio": 30, "mux": "gpmc_wait0", "eeprom": 18, - "key": "P9_11", + "key": ["P9_11", "DSM2_3", "P2_5"], "muxRegOffset": "0x070", "options": [ "gpmc_wait0", "mii2_crs", - "NA", + "gpmc_csn4", "rmii2_crs_dv", "mmc1_sdcd", - "NA", - "NA", + "pr1_mii1_col", + "uart4_rxd", "gpio0_30" - ] + ], + "ball": { + "ZCZ": "T17", + "BSM": "P15" + } }, { "name": "GPIO1_28", "gpio": 60, "mux": "gpmc_ben1", "eeprom": 36, - "key": "P9_12", + "key": ["P9_12", "P2_8"], "muxRegOffset": "0x078", "options": [ "gpmc_ben1", @@ -1177,14 +1260,19 @@ var pinIndex = [ "NA", "mcasp0_aclkr", "gpio1_28" - ] + ], + "ball": { + "ZCZ": "U18", + "BSM": "N14" + } + }, { "name": "UART4_TXD", "gpio": 31, "mux": "gpmc_wpn", "eeprom": 19, - "key": "P9_13", + "key": ["P9_13", "P2_7"], "muxRegOffset": "0x074", "options": [ "gpmc_wpn", @@ -1195,7 +1283,12 @@ var pinIndex = [ "NA", "NA", "gpio0_31" - ] + ], + "ball": { + "ZCZ": "U17", + "BSM": "R16" + } + }, { "name": "EHRPWM1A", @@ -1214,7 +1307,8 @@ var pinIndex = [ "chip": "48302000", "addr": "48302200" }, - "key": "P9_14", + "key": ["P9_14", "P2_1"], + "universalName": ["ocp:P9_14_pinmux", "ocp:P2_01_pinmux", "ocp:PWM_pinmux"], "muxRegOffset": "0x048", "options": [ "gpmc_a2", @@ -1225,7 +1319,12 @@ var pinIndex = [ "pr1_mii1_txd2", "ehrpwm1A", "gpio1_18" - ] + ], + "ball": { + "ZCZ": "U14", + "BSM": "P12" + } + }, { "name": "GPIO1_16", @@ -1243,7 +1342,33 @@ var pinIndex = [ "pr1_mii_mt1_clk", "ehrpwm1_tripzone_input", "gpio1_16" - ] + ], + "ball": { + "ZCZ": "R13", + "BSM": "T12" + } + + }, + { + "name": "GPIO1_16", + "gpio": 64, + "mux": "gpmc_csn3", + "eeprom": null, + "key": ["P9_15B", "P2_20"], + "muxRegOffset": "0x088", + "options": [ + "gpmc_csn3", + "gpmc_a3", + "rmii2_crs_dv", + "mmc2_cmd", + "pr1_mii0_crs", + "pr1_mdio_data", + "gpio2_0" + ], + "ball": { + "ZCZ": "T13", + "BSM": "R7" + } }, { "name": "EHRPWM1B", @@ -1273,68 +1398,84 @@ var pinIndex = [ "pr1_mii1_txd1", "ehrpwm1B", "gpio1_19" - ] + ], + "ball": { + "ZCZ": "T14", + "BSM": "T13" + } }, { "name": "I2C1_SCL", "gpio": 5, "mux": "spi0_cs0", "eeprom": 3, - "key": "P9_17", + "key": ["P9_17", "I2C_3", "P1_6"], "muxRegOffset": "0x15c", "options": [ "spi0_cs0", "mmc2_sdwp", "i2c1_scl", - "NA", - "NA", - "NA", - "NA", + "ehrpwm0_synci", + "pr1_uart0_txd", + "pr1_edio_data_in1", + "pr1_edio_data_out1", "gpio0_5" - ] + ], + "ball": { + "ZCZ": "A16", + "BSM": "A14" + } }, { "name": "I2C1_SDA", "gpio": 4, "mux": "spi0_d1", "eeprom": 2, - "key": "P9_18", + "key": ["P9_18", "I2C_4", "P1_12"], "muxRegOffset": "0x158", "options": [ "spi0_d1", "mmc1_sdwp", "i2c1_sda", - "NA", - "NA", - "NA", - "NA", + "ehrpwm0_tripzone_input", + "pr1_uart0_rxd", + "pr1_edio_data_in0", + "pr1_edio_data_out0", "gpio0_4" - ] + ], + "ball": { + "ZCZ": "B16", + "BSM": "B14" + } }, { "name": "I2C2_SCL", "gpio": 13, "mux": "uart1_rtsn", "eeprom": 9, - "key": "P9_19", + "key": ["P9_19", "P1_28"], "muxRegOffset": "0x17c", "options": [ "uart1_rtsn", - "NA", + "timer5", "d_can0_rx", "i2c2_scl", "spi1_cs1", - "NA", - "NA", + "pr1_uart0_rts_n", + "pr1_edc_latch1_in", "gpio0_13" - ] + ], + "ball": { + "ZCZ": "D17", + "BSM": "A10" + } }, { "name": "I2C2_SDA", "gpio": 12, "mux": "uart1_ctsn", "eeprom": 10, - "key": "P9_20", + "key": ["P9_20", "P1_26"], "muxRegOffset": "0x178", "options": [ "uart1_ctsn", @@ -1342,10 +1483,14 @@ var pinIndex = [ "d_can0_tx", "i2c2_sda", "spi1_cs0", - "NA", - "NA", + "pr1_uart0_cts_n", + "pr1_edc_latch0_in", "gpio0_12" - ] + ], + "ball": { + "ZCZ": "D18", + "BSM": "B10" + } }, { "name": "UART2_TXD", @@ -1364,18 +1509,22 @@ var pinIndex = [ "chip": "48300000", "addr": "48300200" }, - "key": "P9_21", + "key": ["P9_21", "GPS_4", "P1_10"], "muxRegOffset": "0x154", "options": [ "spi0_d0", "uart2_txd", "i2c2_scl", "ehrpwm0B", - "NA", - "NA", - "NA", + "pr1_uart_rts_n", + "pr1_edio_latch_in", + "EMU3", "gpio0_3" - ] + ], + "ball": { + "ZCZ": "B17", + "BSM": "B13" + } }, { "name": "UART2_RXD", @@ -1394,26 +1543,29 @@ var pinIndex = [ "chip": "48300000", "addr": "48300200" }, - "key": "P9_22", + "key": ["P9_22", "GPS_3", "P1_8"], "muxRegOffset": "0x150", "options": [ "spi0_sclk", "uart2_rxd", "i2c2_sda", "ehrpwm0A", - "NA", - "NA", - "NA", + "pr1_uart_cts_n", + "pr1_edio_sof", + "EMU2", "gpio0_2" - ] + ], + "ball": { + "ZCZ": "A17", + "BSM": "A13" + } }, { "name": "GPIO1_17", "gpio": 49, "mux": "gpmc_a1", "eeprom": 33, - "key": "P9_23", - "key2": "GP0_4", // Added for Blue + "key": ["P9_23", "GP0_4"], "muxRegOffset": "0x044", "options": [ "gpmc_a1", @@ -1424,92 +1576,85 @@ var pinIndex = [ "pr1_mii1_txd3", "ehrpwm0_synco", "gpio1_17" - ] + ], + "ball": { + "ZCZ": "V14", + "BSM": "R12" + } }, - { // The next four are hacks to get the Blue GP0 pins 3 and 5 - // and GP1 pins 3 and 4 to work + { "name": "GPIO1_25", "gpio": 57, - "mux": "gpmc_a1", - "eeprom": 33, - "key": "GP0_3", - "key2": "GP0_3", // Added for Blue - "muxRegOffset": "0x044", + "mux": "gpmc_wpn", + "eeprom": null, + "key": ["GP0_3", "P2_6"], + "muxRegOffset": "0x064", "options": [ - "gpmc_a1", - "gmii2_rxdv", - "rgmii2_rctl", - "mmc2_dat0", - "gpmc_a17", - "pr1_mii1_txd3", - "ehrpwm0_synco", + "gpmc_wpn", + "gmii2_rxer", + "gpmc_csn5", + "rmii2_rxer", + "mmc2_sdcd", + "pr1_mii1_txen", + "uart4_txd", "gpio1_25" - ] - }, - { - "name": "GPIO3_20", - "gpio": 116, - "mux": "gpmc_a1", - "eeprom": 33, - "key": "GP0_5", - "key2": "GP0_5", // Added for Blue - "muxRegOffset": "0x044", - "options": [ - "gpmc_a1", - "gmii2_rxdv", - "rgmii2_rctl", - "mmc2_dat0", - "gpmc_a17", - "pr1_mii1_txd3", - "ehrpwm0_synco", - "gpio3_20" - ] + ], + "ball": { + "ZCZ": "U16", + "BSM": "T15" + } }, { "name": "GPIO3_2", "gpio": 98, - "mux": "gpmc_a1", - "eeprom": 33, + "mux": "gmii1_rxer", + "eeprom": null, "key": "GP1_3", - "key2": "GP1_3", // Added for Blue - "muxRegOffset": "0x044", + "muxRegOffset": "0x110", "options": [ - "gpmc_a1", - "gmii2_rxdv", - "rgmii2_rctl", - "mmc2_dat0", - "gpmc_a17", - "pr1_mii1_txd3", - "ehrpwm0_synco", + "gmii1_rxer", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", "gpio3_2" - ] + ], + "ball": { + "ZCZ": "J15", + "BSM": "E15" + } }, { "name": "GPIO3_1", "gpio": 97, - "mux": "gpmc_a1", - "eeprom": 33, + "mux": "gmii1_crs", + "eeprom": null, "key": "GP1_4", - "key2": "GP1_4", // Added for Blue - "muxRegOffset": "0x044", + "muxRegOffset": "0x10c", "options": [ - "gpmc_a1", - "gmii2_rxdv", - "rgmii2_rctl", - "mmc2_dat0", - "gpmc_a17", - "pr1_mii1_txd3", - "ehrpwm0_synco", + "gmii1_crs", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", "gpio3_1" - ] - }, + ], + "ball": { + "ZCZ": "H17", + "BSM": "F14" + } + }, { "name": "UART1_TXD", "gpio": 15, "mux": "uart1_txd", "eeprom": 12, - "key": "P9_24", + "key": ["P9_24", "UT1_4", "P2_9"], "muxRegOffset": "0x184", "options": [ "uart1_txd", @@ -1520,14 +1665,18 @@ var pinIndex = [ "pr1_uart0_txd_mux1", "NA", "gpio0_15" - ] + ], + "ball": { + "ZCZ": "D15", + "BSM": "B11" + } }, { "name": "GPIO3_21", "gpio": 117, "mux": "mcasp0_ahclkx", "eeprom": 66, - "key": "P9_25", + "key": ["P9_25", "P1_29", "PRU0_7"], "muxRegOffset": "0x1ac", "options": [ "mcasp0_ahclkx", @@ -1538,14 +1687,18 @@ var pinIndex = [ "NA", "NA", "gpio3_21" - ] + ], + "ball": { + "ZCZ": "A14", + "BSM": "C4" + } }, { "name": "UART1_RXD", "gpio": 14, "mux": "uart1_rxd", "eeprom": 11, - "key": "P9_26", + "key": ["P9_26", "UT1_3", "P2_11"], "muxRegOffset": "0x180", "options": [ "uart1_rxd", @@ -1554,27 +1707,35 @@ var pinIndex = [ "i2c1_sda", "NA", "pr1_uart0_rxd_mux1", - "NA", + "pr1_pru1_pru_r31_16", "gpio0_14" - ] + ], + "ball": { + "ZCZ": "D16", + "BSM": "A11" + } }, { "name": "GPIO3_19", "gpio": 115, "mux": "mcasp0_fsr", "eeprom": 64, - "key": "P9_27", + "key": ["P9_27", "P2_34", "PRU0_5", "E1_4"], "muxRegOffset": "0x1a4", "options": [ "mcasp0_fsr", "NA", "mcasp0_axr3", "mcasp1_fsx", - "NA", + "EMU2", "pr1_pru0_pru_r30_5", - "NA", + "pr1_pru0_pru_r31_5", "gpio3_19" - ] + ], + "ball": { + "ZCZ": "C13", + "BSM": "B3" + } }, { "name": "SPI1_CS0", @@ -1590,12 +1751,11 @@ var pinIndex = [ "muxmode": 4, "path": "ecap.2", "name": "ECAPPWM2", - + "universalMode": "pwm2", "chip": "48304000", "addr": "48304100" }, - "key": "P9_28", - "key2": "GP0_6", // Added for Blue + "key": ["P9_28", "GP0_6", "P2_30", "PRU0_3"], "muxRegOffset": "0x19c", "options": [ "mcasp0_ahclkr", @@ -1603,10 +1763,14 @@ var pinIndex = [ "mcasp0_axr2", "spi1_cs0", "eCAP2_in_PWM2_out", - "NA", - "NA", + "pr1_pru0_pru_r30_3", + "pr1_pru0_pru_r31_3", "gpio3_17" - ] + ], + "ball": { + "ZCZ": "C12", + "BSM": "B1" + } }, { "name": "SPI1_D0", @@ -1625,7 +1789,7 @@ var pinIndex = [ "chip": "48300000", "addr": "48300200" }, - "key": "P9_29", + "key": ["P9_29", "S1_1_4", "S1_2_4", "P1_33", "PRU0_1"], "muxRegOffset": "0x194", "options": [ "mcasp0_fsx", @@ -1633,17 +1797,21 @@ var pinIndex = [ "NA", "spi1_d0", "mmc1_sdcd", - "NA", - "NA", + "pr1_pru0_pru_r30_1", + "pr1_pru0_pru_r31_1", "gpio3_15" - ] + ], + "ball": { + "ZCZ": "B13", + "BSM": "A2" + } }, { "name": "SPI1_D1", "gpio": 112, "mux": "mcasp0_axr0", "eeprom": 62, - "key": "P9_30", + "key": ["P9_30", "S1_1_3", "S1_2_3", "P2_32", "PRU0_2"], "muxRegOffset": "0x198", "options": [ "mcasp0_axr0", @@ -1651,10 +1819,14 @@ var pinIndex = [ "NA", "spi1_d1", "mmc2_sdcd", - "NA", - "NA", + "pr1_pru0_pru_r30_2", + "pr1_pru0_pru_r31_2", "gpio3_16" - ] + ], + "ball": { + "ZCZ": "D12", + "BSM": "B2" + } }, { "name": "SPI1_SCLK", @@ -1673,7 +1845,7 @@ var pinIndex = [ "chip": "48300000", "addr": "48300200" }, - "key": "P9_31", + "key": ["P9_31", "S1_1_5", "S1_2_5", "P1_36"], "muxRegOffset": "0x190", "options": [ "mcasp0_aclkx", @@ -1681,74 +1853,147 @@ var pinIndex = [ "NA", "spi1_sclk", "mmc0_sdcd", - "NA", - "NA", + "pr1_pru0_pru_r30_0", + "pr1_pru0_pru_r31_0", "gpio3_14" - ] + ], + "ball": { + "ZCZ": "A13", + "BSM": "A1" + } }, { "name": "VDD_ADC", - "key": "P9_32" + "key": ["P9_32", "ADC_2", "P1_17"], + "ball": { + "ZCZ": "A9", + "BSM": "B9" + } }, { "name": "AIN4", "ain": 4, "eeprom": 71, "scale": 4096, - "key": "P9_33" + "key": ["P9_33", "P1_27"], + "ball": { + "ZCZ": "C8", + "BSM": "C7" + } }, { "name": "GNDA_ADC", - "key": "P9_34" + "key": ["P9_34", "ADC_1", "P1_18"], + "ball": { + "ZCZ": "B9", + "BSM": "B7" + } }, { "name": "AIN6", "ain": 6, "eeprom": 73, "scale": 4096, - "key": "P9_35" + "key": ["P9_35", "P1_2"], + "ball": { + "ZCZ": "A8", + "BSM": "C9" + } }, { "name": "AIN5", "ain": 5, "eeprom": 72, "scale": 4096, - "key": "P9_36" + "key": ["P9_36", "P2_35"], + "ball": { + "ZCZ": "B8", + "BSM": "C8" + } }, { "name": "AIN2", "ain": 2, "eeprom": 69, "scale": 4096, - "key": "P9_37" + "key": ["P9_37", "ADC_5", "P1_23"], + "ball": { + "ZCZ": "B7", + "BSM": "B6" + } }, { "name": "AIN3", "ain": 3, "eeprom": 70, "scale": 4096, - "key": "P9_38" + "key": ["P9_38", "ADC_6", "P1_25"], + "ball": { + "ZCZ": "A7", + "BSM": "C6" + } }, { "name": "AIN0", "ain": 0, "eeprom": 67, "scale": 4096, - "key": "P9_39" + "key": ["P9_39", "ADC_3", "P1_19"], + "ball": { + "ZCZ": "B6", + "BSM": "A8" + } }, { "name": "AIN1", "ain": 1, "eeprom": 68, "scale": 4096, - "key": "P9_40" + "key": ["P9_40", "ADC_4", "P1_21"], + "ball": { + "ZCZ": "C7", + "BSM": "B8" + } + }, + { + "name": "AIN7", + "ain": 7, + "eeprom": null, + "scale": 4096, + "key": "P2_36", + "ball": { + "ZCZ": "C9", + "BSM": "D7" + } + }, + { + "name": "CLKOUT2", + "gpio": 116, + "mux": "mcasp0_axr1", + "eeprom": null, + "key": ["P9_41", "GP0_5", "P2_28", "PRU0_6"], + "muxRegOffset": "0x1a8", + "options": [ + "mcasp0_axr1", + "eQEP0_index", + "mcasp1_axr0", + "EMU3", + "NA", + "NA", + "NA", + "gpio3_20" + ], + "ball": { + "ZCZ": "D13", + "BSM": "C3" + } }, { "name": "CLKOUT2", "gpio": 20, "mux": "xdma_event_intr1", "eeprom": 13, - "key": "P9_41", + "key": ["P9_41B", "P1_20"], "muxRegOffset": "0x1b4", "options": [ "xdma_event_intr1", @@ -1759,7 +2004,11 @@ var pinIndex = [ "NA", "NA", "gpio0_20" - ] + ], + "ball": { + "ZCZ": "D14", + "BSM": "B4" + } }, { "name": "GPIO0_7", @@ -1778,7 +2027,7 @@ var pinIndex = [ "chip": "48300000", "addr": "48300100" }, - "key": "P9_42", + "key": ["P9_42", "S1_2_6", "P2_29"], "muxRegOffset": "0x164", "options": [ "eCAP0_in_PWM0_out", @@ -1789,37 +2038,949 @@ var pinIndex = [ "mmc0_sdwp", "xdma_event_intr2", "gpio0_7" - ] + ], + "ball": { + "ZCZ": "C18", + "BSM": "C5" + } }, { - "name": "DGND", - "key": "P9_43" + "name": "GPIO0_7", + "gpio": 114, + "mux": "ecap0_in_pwm0_out", + "eeprom": null, + "key": ["P9_42B", "E1_3", "P1_31", "PRU0_4"], + "muxRegOffset": "0x1a0", + "options": [ + "mcasp0_aclkr", + "eQEP0A_in", + "mcasp0_axr2", + "mcasp1_aclkx", + "mmc0_sdwp", + "pr1_pru0_pru_r30_4", + "pr1_pru0_pru_r31_4", + "gpio3_18" + ], + "ball": { + "ZCZ": "B12", + "BSM": "A3" + } }, { - "name": "DGND", - "key": "P9_44" + "name": "USB1_DRVVBUS", + "gpio": 109, + "key": "P1_3", + "muxRegOffset": "0x134", + "mux": "USB1_DRVVBUS", + "eeprom": null, + "options": [ + "USB1_DRVVBUS", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_13" + ], + "ball": { + "ZCZ": "F15", + "BSM": "M14" + } }, { - "name": "DGND", - "key": "P9_45" + "name": "USB1_VBUS", + "key": "P1_5", + "ball": { + "ZCZ": "T18", + "BSM": "M15" + }, + "muxRegOffset": "0x130" }, { - "name": "DGND", - "key": "P9_46" - } + "name": "VIN_USB", + "key": "P1_7", + "ball": { + "BSM": ["P9", "R9", "T9"] + }, + }, + { + "name": "USB1_DN", + "key": "P1_9", + "ball": { + "ZCZ": "R18", + "BSM": "L16" + }, + "muxRegOffset": "0x120" + }, + { + "name": "USB1_DP", + "key": "P1_11", + "ball": { + "ZCZ": "R17", + "BSM": "L15" + }, + "muxRegOffset": "0x124" + }, + { + "name": "USB1_ID", + "key": "P1_13", + "ball": { + "ZCZ": "P17", + "BSM": "L14" + }, + "muxRegOffset": "0x12c" + }, + { + "name": "VIN_BAT", + "key": "P2_14", + "ball": { + "BSM": ["P8", "R8", "T8"] + }, + }, + { + "name": "BAT_TEMP", + "key": "P2_16", + "ball": { + "BSM": "N6" + }, + }, + { + "name": "UART0_RXD", + "gpio": 42, + "mux": "uart0_rxd", + "eeprom": null, + "key": ["UT0_3", "P1_32"], + "muxRegOffset": "0x170", + "options": [ + "uart0_rxd", + "spi1_cs0", + "dcan0_tx", + "i2c2_sda", + "eCAP2_in_PWM2_out", + "pr1_pru1_pru_r30_14", + "pr1_pru1_pru_r31_14", + "gpio1_10" + ], + "ball": { + "ZCZ": "E15", + "BSM": "A12" + } + }, + { + "name": "UART0_TXD", + "gpio": 43, + "mux": "uart0_txd", + "eeprom": null, + "key": ["UT0_4", "P1_30"], + "muxRegOffset": "0x174", + "options": [ + "uart0_rxd", + "spi1_cs1", + "dcan0_4x", + "i2c2_scl", + "eCAP1_in_PWM1_out", + "pr1_pru1_pru_r30_15", + "pr1_pru1_pru_r31_15", + "gpio1_11" + ], + "ball": { + "ZCZ": "E16", + "BSM": "B12" + } + }, + { + "name": "GPIO1_20", + "gpio": 52, + "mux": "gpmc_a4", + "eeprom": null, + "key": "P2_10", + "muxRegOffset": "0x050", + "options": [ + "gpmc_a4", + "gmii2_txd1", + "rgmii2_td1", + "rmii2_txd1", + "gpmc_a20", + "pr1_mii1_txd0", + "eQEP1A_in", + "gpio1_20" + ], + "ball": { + "ZCZ": "R14", + "BSM": "R13" + } + }, + { + "name": "GPIO1_27", + "gpio": 59, + "mux": "gpmc_a11", + "eeprom": null, + "key": "P2_2", + "muxRegOffset": "0x06c", + "options": [ + "gpmc_a11", + "gmii2_rxd0", + "rgmii2_rd0", + "rmii2_rxd0", + "gpmc_a27", + "pr1_mii1_rxer", + "mcasp0_axr1", + "gpio1_27" + ], + "ball": { + "ZCZ": "V17", + "BSM": "T16" + } + }, + { + "name": "GPIO1_26", + "gpio": 58, + "mux": "gpmc_a10", + "eeprom": null, + "key": "P2_4", + "muxRegOffset": "0x068", + "options": [ + "gpmc_a10", + "gmii2_rxd1", + "rgmii2_rd1", + "rmii2_rxd1", + "gpmc_a26", + "pr1_mii1_rxdv", + "mcasp0_axr0", + "gpio1_26" + ], + "ball": { + "ZCZ": "T16", + "BSM": "R15" + } + }, + { + "name": "GPIO1_9", + "gpio": 41, + "mux": "uart0_rtsn", + "eeprom": null, + "key": "P2_25", + "muxRegOffset": "0x16c", + "options": [ + "uart0_rtsn", + "uart4_txd", + "dcan1_rx", + "i2c1_scl", + "spi1_d1", + "spi1_cs0", + "pr1_edc_sync1_out", + "gpio1_9" + ], + "ball": { + "ZCZ": "E17", + "BSM": "C13" + } + }, + { + "name": "GPIO1_8", + "gpio": 40, + "mux": "uart0_ctsn", + "eeprom": null, + "key": "P2_27", + "muxRegOffset": "0x168", + "options": [ + "uart0_ctsn", + "uart4_txd", + "dcan1_tx", + "i2c1_sda", + "spi1_d0", + "timer7", + "pr1_edc_sync0_out", + "gpio1_8" + ], + "ball": { + "ZCZ": "E18", + "BSM": "C12" + } + }, + { + "name": "MMC0_SDCD", + "gpio": 6, + "mux": "spi0_cs1", + "eeprom": null, + "muxRegOffset": "0x160", + "options": [ + "spi0_cs1", + "uart3_rxd", + "eCAP1_in_PWM1_out", + "mmc0_pow", + "xdma_event_intr2", + "mmc0_sdcd", + "EMU4", + "gpio0_6" + ], + "ball": { + "ZCZ": "C15", + "BSM": "C14" + } + }, + { + "name": "MDIO_DATA", + "gpio": 0, + "mux": "mdio_data", + "eeprom": null, + "muxRegOffset": "0x148", + "options": [ + "mdio_data", + "timer6", + "uart5_rxd", + "uart3_ctsn", + "mmc0_sdcd", + "mmc1_cmd", + "mmc2_cmd", + "gpio0_0" + ], + "ball": { + "ZCZ": "M17", + "BSM": "E13" + } + }, + { + "name": "MDIO_CLK", + "gpio": 1, + "mux": "mdio_clk", + "eeprom": null, + "muxRegOffset": "0x14c", + "options": [ + "mdio_clk", + "timer5", + "uart5_txd", + "uart3_rtsn", + "mmc0_wp", + "mmc1_clk", + "mmc2_clk", + "gpio0_1" + ], + "ball": { + "ZCZ": "M18", + "BSM": "D13" + } + }, + { + "name": "MII_TX3", + "gpio": 16, + "mux": "gmii1_txd3", + "eeprom": null, + "muxRegOffset": "0x11c", + "options": [ + "gmii1_txd3", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio0_16" + ], + "ball": { + "ZCZ": "J18", + "BSM": "G15" + } + }, + { + "name": "MII_TX2", + "gpio": 17, + "mux": "gmii1_txd2", + "eeprom": null, + "muxRegOffset": "0x120", + "options": [ + "gmii1_txd2", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio0_17" + ], + "ball": { + "ZCZ": "K15", + "BSM": "G16" + } + }, + { + "name": "USB0_DRVVBUS", + "gpio": 18, + "mux": "USB0_DRVVBUS", + "eeprom": null, + "muxRegOffset": "0x11c", + "options": [ + "USB0_DRVVBUS", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio0_18" + ], + "ball": { + "ZCZ": "F16", + "BSM": "J15" + } + }, + { + "name": "MII_TX1", + "gpio": 21, + "mux": "gmii1_txd1", + "eeprom": null, + "muxRegOffset": "0x124", + "options": [ + "gmii1_txd1", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio0_21" + ], + "ball": { + "ZCZ": "K16", + "BSM": "H14" + } + }, + { + "name": "MII_TX1", + "gpio": 21, + "mux": "gmii1_txd1", + "eeprom": null, + "muxRegOffset": "0x124", + "options": [ + "gmii1_txd1", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio0_21" + ], + "ball": { + "ZCZ": "K16", + "BSM": "H14" + } + }, + { + "name": "MII_TX0", + "gpio": 28, + "mux": "gmii1_txd0", + "eeprom": null, + "muxRegOffset": "0x128", + "options": [ + "gmii1_txd0", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio0_28" + ], + "ball": { + "ZCZ": "K17", + "BSM": "H15" + } + }, + { + "name": "MII_TX0", + "gpio": 28, + "mux": "gmii1_txd0", + "eeprom": null, + "muxRegOffset": "0x128", + "options": [ + "gmii1_txd0", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio0_28" + ], + "ball": { + "ZCZ": "K17", + "BSM": "H15" + } + }, + { + "name": "GPIO0_29", + "gpio": 29, + "mux": "rmii1_refclk", + "eeprom": null, + "key": "S1_1_6", + "muxRegOffset": "0x144", + "options": [ + "rmii1_refclk", + "NA", + "spi1_cs0", + "NA", + "NA", + "NA", + "NA", + "gpio0_28" + ], + "ball": { + "ZCZ": "H18", + "BSM": "J14" + } + }, + { + "name": "MII_RX3", + "gpio": 82, + "mux": "gmii1_rxd3", + "eeprom": null, + "muxRegOffset": "0x134", + "options": [ + "gmii1_rxd3", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_18" + ], + "ball": { + "ZCZ": "L17", + "BSM": "D14" + } + }, + { + "name": "MII_RX2", + "gpio": 83, + "mux": "gmii1_rxd2", + "eeprom": null, + "muxRegOffset": "0x138", + "options": [ + "gmii1_rxd2", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_19" + ], + "ball": { + "ZCZ": "L16", + "BSM": "D15" + } + }, + { + "name": "MII_RX1", + "gpio": 84, + "mux": "gmii1_rxd1", + "eeprom": null, + "muxRegOffset": "0x13c", + "options": [ + "gmii1_rxd1", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_20" + ], + "ball": { + "ZCZ": "L15", + "BSM": "D16" + } + }, + { + "name": "MII_RX0", + "gpio": 85, + "mux": "gmii1_rxd0", + "eeprom": null, + "muxRegOffset": "0x140", + "options": [ + "gmii1_rxd0", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_21" + ], + "ball": { + "ZCZ": "M16", + "BSM": "E14" + } + }, + { + "name": "MMC0_DAT3", + "gpio": 90, + "mux": "mmc0_dat3", + "eeprom": null, + "muxRegOffset": "0x0f0", + "options": [ + "mmc0_dat3", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_26" + ], + "ball": { + "ZCZ": "F17", + "BSM": "C15" + } + }, + { + "name": "MMC0_DAT2", + "gpio": 91, + "mux": "mmc0_dat2", + "eeprom": null, + "muxRegOffset": "0x0f4", + "options": [ + "mmc0_dat2", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_27" + ], + "ball": { + "ZCZ": "F18", + "BSM": "C16" + } + }, + { + "name": "MMC0_DAT1", + "gpio": 92, + "mux": "mmc0_dat1", + "eeprom": null, + "muxRegOffset": "0x0f8", + "options": [ + "mmc0_dat1", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_28" + ], + "ball": { + "ZCZ": "G15", + "BSM": "A15" + } + }, + { + "name": "MMC0_DAT0", + "gpio": 93, + "mux": "mmc0_dat0", + "eeprom": null, + "muxRegOffset": "0x0fc", + "options": [ + "mmc0_dat0", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_29" + ], + "ball": { + "ZCZ": "G16", + "BSM": "A16" + } + }, + { + "name": "MMC0_CLK", + "gpio": 94, + "mux": "mmc0_clk", + "eeprom": null, + "muxRegOffset": "0x100", + "options": [ + "mmc0_clk", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_30" + ], + "ball": { + "ZCZ": "G17", + "BSM": "B15" + } + }, + { + "name": "MMC0_CMD", + "gpio": 95, + "mux": "mmc0_cmd", + "eeprom": null, + "muxRegOffset": "0x104", + "options": [ + "mmc0_cmd", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio2_31" + ], + "ball": { + "ZCZ": "G18", + "BSM": "B16" + } + }, + { + "name": "MII_COL", + "gpio": 96, + "mux": "gmii1_col", + "eeprom": null, + "muxRegOffset": "0x108", + "options": [ + "gmii1_col", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_0" + ], + "ball": { + "ZCZ": "H16", + "BSM": "F15" + } + }, + { + "name": "MII_TXEN", + "gpio": 99, + "mux": "gmii1_txen", + "eeprom": null, + "muxRegOffset": "0x114", + "options": [ + "gmii1_txen", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_3" + ], + "ball": { + "ZCZ": "J16", + "BSM": "G14" + } + }, + { + "name": "MII_RXDV", + "gpio": 100, + "mux": "gmii1_rxdv", + "eeprom": null, + "muxRegOffset": "0x118", + "options": [ + "gmii1_rxdv", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_4" + ], + "ball": { + "ZCZ": "J17", + "BSM": "F16" + } + }, + { + "name": "I2C0_SDA", + "gpio": 101, + "mux": "I2C0_SDA", + "eeprom": null, + "muxRegOffset": "0x188", + "options": [ + "I2C0_SDA", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_5" + ], + "ball": { + "ZCZ": "C17", + "BSM": "C11" + } + }, + { + "name": "I2C0_SCL", + "gpio": 102, + "mux": "I2C0_SCL", + "eeprom": null, + "muxRegOffset": "0x18c", + "options": [ + "I2C0_SCL", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_6" + ], + "ball": { + "ZCZ": "C16", + "BSM": "C10" + } + }, + { + "name": "EMU0", + "gpio": 103, + "mux": "EMU0", + "eeprom": null, + "muxRegOffset": "0x1e4", + "options": [ + "EMU0", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_7" + ], + "ball": { + "ZCZ": "C14", + "BSM": "E2" + } + }, + { + "name": "EMU1", + "gpio": 104, + "mux": "EMU1", + "eeprom": null, + "muxRegOffset": "0x1e8", + "options": [ + "EMU1", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_8" + ], + "ball": { + "ZCZ": "B14", + "BSM": "E3" + } + }, + { + "name": "MII_TXCLK", + "gpio": 105, + "mux": "gmii1_txclk", + "eeprom": null, + "muxRegOffset": "0x12c", + "options": [ + "gmii1_txclk", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_9" + ], + "ball": { + "ZCZ": "K18", + "BSM": "H16" + } + }, + { + "name": "MII_RXCLK", + "gpio": 106, + "mux": "gmii1_rxclk", + "eeprom": null, + "muxRegOffset": "0x130", + "options": [ + "gmii1_rxclk", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_10" + ], + "ball": { + "ZCZ": "L18", + "BSM": "E16" + } + }, + { + "name": "MII_RXCLK", + "gpio": 106, + "mux": "gmii1_rxclk", + "eeprom": null, + "muxRegOffset": "0x130", + "options": [ + "gmii1_rxclk", + "NA", + "NA", + "NA", + "NA", + "NA", + "NA", + "gpio3_10" + ], + "ball": { + "ZCZ": "L18", + "BSM": "E16" + } + }, ]; var pins = {}; -for(var i in pinIndex) { - pins[pinIndex[i].key] = pinIndex[i]; - if(pinIndex[i].key2) { - pins[pinIndex[i].key2] = pinIndex[i]; +for (var i in pinIndex) { + if (Array.isArray(pinIndex[i].key)) { + for (var j = 0; j < pinIndex[i].key.length; j++) { + var myKey = pinIndex[i].key[j]; + //console.log("key[" + j + "].[" + myKey + "]: " + i); + pins[myKey] = i; + } + } else if (typeof pinIndex[i] != 'undefined') { + pins[pinIndex[i].key] = i; + } + if (typeof pinIndex[i].gpio == 'number') { + pins["GPIO_" + pinIndex[i].gpio] = i; + } + if (typeof pinIndex[i].eeprom == 'number') { + pins["EEPROM_" + pinIndex[i].eeprom] = i; + } + if (typeof pinIndex[i].ain == 'number') { + pins["A" + pinIndex[i].ain] = i; + } + if (typeof pinIndex[i].muxRegOffset == 'string') { + var offset = pinIndex[i].muxRegOffset.toUpperCase(); + pins["MUX_" + offset] = i; } } var uarts = { - "/dev/ttyO0": { - }, + "/dev/ttyO0": {}, "/dev/ttyO1": { "devicetree": "BB-UART1", "rx": "P9_26", @@ -1830,8 +2991,7 @@ var uarts = { "rx": "P9_22", "tx": "P9_21" }, - "/dev/ttyO3": { - }, + "/dev/ttyO3": {}, "/dev/ttyO4": { "devicetree": "BB-UART4", "rx": "P9_11", @@ -1845,8 +3005,7 @@ var uarts = { }; var i2c = { - "/dev/i2c-0": { - }, + "/dev/i2c-0": {}, "/dev/i2c-1": { "devicetree": "BB-I2C1", "path": "/dev/i2c-2", @@ -1866,7 +3025,88 @@ var i2c = { } }; -exports.pins = pins; -exports.pinIndex = pinIndex; -exports.uarts = uarts; -exports.i2c = i2c; +var getPinObject = function (key) { + if (typeof key == "string") { + // Ignore case + key = key.toUpperCase(); + // Replace alternate separators and leading zeros + key = key.replace(/[\.\-_ ]0*/g, "_"); + } + if (typeof key == "number") { + key = "GPIO_" + key; + } + //console.log(key); + //console.log(pins[key]); + if (typeof pinIndex[pins[key]] == "object") { + var pinObject = Object.assign({}, pinIndex[pins[key]]); + + // Only keep the matching index led + if (pinObject.led) { + //console.log("pinObject[" + key + "]: " + JSON.stringify(pinObject)); + if (Array.isArray(pinObject.led)) { + //console.log("pinObject.key: " + pinObject.key); + var i = pinObject.key.indexOf(key); + if (i >= 0) { + var led = pinObject.led[i]; + pinObject.led = led; + //console.log("pinObject.led[" + i + "]: " + led); + } else { + pinObject.led = null; + } + } + } + + // Remove other keys + pinObject.key = key; + } else { + return (null); + } + + return (pinObject); +}; + +var getPinKeys = function (filter) { + var keys = []; + for (var key in pins) { + if (typeof filter != 'undefined') { + if (key.search(filter) >= 0) { + keys.push(key); + } + } else { + keys.push(key); + } + } + return (keys); +}; + +// from https://stackoverflow.com/questions/15478954/sort-array-elements-string-with-numbers-natural-sort +var naturalCompare = function (a, b) { + var ax = [], + bx = []; + + a.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { + ax.push([$1 || Infinity, $2 || ""]) + }); + b.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { + bx.push([$1 || Infinity, $2 || ""]) + }); + + while (ax.length && bx.length) { + var an = ax.shift(); + var bn = bx.shift(); + var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]); + if (nn) return nn; + } + + return ax.length - bx.length; +} + + + +module.exports = { + getPinObject: getPinObject, + getPinKeys: getPinKeys, + naturalCompare: naturalCompare, + uarts: uarts, + i2c: i2c +} \ No newline at end of file diff --git a/src/bonescript.js b/src/bonescript.js index df9fbf71..38672bab 100644 --- a/src/bonescript.js +++ b/src/bonescript.js @@ -3,17 +3,32 @@ _bonescript.modules = {}; _bonescript._callbacks = {}; _bonescript._seqnum = 0; _bonescript.on = {}; -_bonescript.on.connect = function(){}; -_bonescript.on.connecting = function(){}; -_bonescript.on.disconnect = function(){}; -_bonescript.on.connect_failed = function(){}; -_bonescript.on.error = function(){}; -_bonescript.on.reconnect = function(){}; -_bonescript.on.reconnect_failed = function(){}; -_bonescript.on.reconnecting = function(){}; -_bonescript.on.initialized = function(){}; +_bonescript.on.connect = function () {}; +_bonescript.on.connecting = function () {}; +_bonescript.on.disconnect = function () {}; +_bonescript.on.connect_failed = function () {}; +_bonescript.on.error = function (err) { + throw (new Error(err)) +}; +_bonescript.on.reconnect = function () {}; +_bonescript.on.reconnect_failed = function () {}; +_bonescript.on.reconnecting = function () {}; +_bonescript.on.initialized = function () {}; -(function() { +(function () { + if (typeof document == 'undefined') { + var io = require('socket.io-client'); + var crypto = require('crypto'); + module.exports.startClient = function (host, callback) { + var passphrase_hash; + if (host.password) + passphrase_hash = crypto.createHash('sha256').update(host.password).digest("hex"); //generate sha256 hash for supplied password + _bonescript.on.initialized = callback; + var socket = _onSocketIOLoaded(host.address, host.port, io, passphrase_hash); + } + return; + } + require = myrequire; var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; @@ -23,9 +38,22 @@ _bonescript.on.initialized = function(){}; scriptObj.onload = _onSocketIOLoaded; }()); -function _onSocketIOLoaded() { +function _onSocketIOLoaded(host, port, socketio, passphrase_hash) { //console.log("socket.io loaded"); - var socket = io.connect('___INSERT_HOST___', {port:80}); + if (typeof host == 'undefined') host = '___INSERT_HOST___'; + if (typeof port == 'undefined') port = 80; + if (typeof socketio == 'undefined' && typeof io != 'undefined') socketio = io; + var socket; + if (typeof host == 'string') + socket = socketio('http://' + host + ':' + port, { + extraHeaders: { + 'Authorization': typeof passphrase_hash != 'undefined' ? passphrase_hash : null //send passphrase_has as Authorization extraheader + } + }); + else + socket = socketio('___INSERT_HOST___', { + port: port + }); socket.on('require', getRequireData); socket.on('bonescript', _seqcall); socket.on('connect', _bonescript.on.connect); @@ -39,24 +67,24 @@ function _onSocketIOLoaded() { socket.on('initialized', _bonescript.on.initialized); function getRequireData(m) { - if(!m.module || !m.data) - throw('Invalid "require" message sent for "' + m.module + '"'); + if (!m.module || !m.data) + throw ('Invalid "require" message sent for "' + m.module + '"'); //console.log('Initialized module: ' + m.module); _bonescript.modules[m.module] = {}; - for(var x in m.data) { - if(!m.data[x].type || !m.data[x].name || (typeof m.data[x].value == 'undefined')) - throw('Invalid data in "require" message sent for "' + m.module + '.' + m.data[x] + '"'); - if(m.data[x].type == 'function') { + for (var x in m.data) { + if (!m.data[x].type || !m.data[x].name || (typeof m.data[x].value == 'undefined')) + throw ('Invalid data in "require" message sent for "' + m.module + '.' + m.data[x] + '"'); + if (m.data[x].type == 'function') { // define the function - if(!m.data[x].value) - throw('Missing args in "require" message sent for "' + m.module + '.' + m.data[x] + '"'); + if (!m.data[x].value) + throw ('Missing args in "require" message sent for "' + m.module + '.' + m.data[x] + '"'); var myargs = m.data[x].value; // eval of objString builds the call data out of arguments passed in var objString = ''; - for(var y in myargs) { - if(isNaN(y)) continue; // Need to find the source of this bug - if(myargs[y] == 'callback') continue; + for (var y in myargs) { + if (isNaN(y)) continue; // Need to find the source of this bug + if (myargs[y] == 'callback') continue; objString += ' if(typeof ' + myargs[y] + ' == "function") {\n'; objString += ' ' + myargs[y] + ' = ' + myargs[y] + '.toString();\n'; objString += ' }\n'; @@ -71,6 +99,7 @@ function _onSocketIOLoaded() { ' if(callback) {\n' + ' _bonescript._callbacks[_bonescript._seqnum] = callback;\n' + ' calldata.seq = _bonescript._seqnum;\n' + + ' calldata.length = callback.length;\n' + ' _bonescript._seqnum++;\n' + ' }\n' + ' socket.emit("' + m.module + '$' + m.data[x].name + '", calldata);\n' + @@ -83,20 +112,31 @@ function _onSocketIOLoaded() { _bonescript.modules[m.module].socket = socket; _bonescript.on.initialized(); } + + return (socket); } function _seqcall(data) { - if((typeof data.seq != 'number') || (typeof _bonescript._callbacks[data.seq] != 'function')) + if ((typeof data.seq != 'number') || (typeof _bonescript._callbacks[data.seq] != 'function')) throw "Invalid callback message received: " + JSON.stringify(data); - _bonescript._callbacks[data.seq](data); - if(data.oneshot) delete _bonescript._callbacks[data.seq]; + if (_bonescript._callbacks[data.seq].length == 1) + _bonescript._callbacks[data.seq](data); + else + _bonescript._callbacks[data.seq](data.err, data.resp); + if (data.oneshot) delete _bonescript._callbacks[data.seq]; } // Require must be synchronous to be able to return data structures and // functions and therefore cannot call socket.io. All exported modules must // be exported ahead of time. -function require(module) { - if(typeof _bonescript.modules[module] == 'undefined') +function myrequire(module) { + if (typeof _bonescript == 'undefined') + throw 'No BoneScript modules are not currently available'; + if (typeof _bonescript.modules[module] == 'undefined') throw 'Module "' + module + '" is not currently available'; - return(_bonescript.modules[module]); + return (_bonescript.modules[module]); } + +if (typeof module != 'undefined') { + module.exports.require = myrequire; +} \ No newline at end of file diff --git a/src/constants.js b/src/constants.js index deec9de5..3b933bd2 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,13 +1,14 @@ // Copyright (C) 2013 - Texas Instruments, Jason Kridner - -exports.OUTPUT = "out"; -exports.INPUT = "in"; -exports.INPUT_PULLUP = "in_pullup"; -exports.HIGH = 1; -exports.LOW = 0; -exports.LSBFIRST = 1; // used in: shiftOut(dataPin, clockPin, bitOrder, val) -exports.MSBFIRST = 0; -exports.CHANGE = "both"; -exports.RISING = "rising"; -exports.FALLING = "falling"; -exports.ANALOG_OUTPUT = "analog_out"; \ No newline at end of file +module.exports = { + OUTPUT: "out", + INPUT: "in", + INPUT_PULLUP: "in_pullup", + HIGH: 1, + LOW: 0, + LSBFIRST: 1, // used in: shiftOut(dataPin, clockPin, bitOrder, val) + MSBFIRST: 0, + CHANGE: "both", + RISING: "rising", + FALLING: "falling", + ANALOG_OUTPUT: "analog_out" +} \ No newline at end of file diff --git a/src/eeprom.js b/src/eeprom.js index fca2453d..d22afc73 100644 --- a/src/eeprom.js +++ b/src/eeprom.js @@ -7,10 +7,10 @@ // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,27 +23,27 @@ var fs = require('fs'); var buffer = require('buffer'); var util = require('util'); var winston = require('winston'); -var bone = require('./bone').pins; +var bone = require('./bone'); var debug = process.env.DEBUG ? true : false; // Function derived from https://github.com/joyent/node/blob/master/lib/buffer.js -if(!buffer.Buffer.prototype.readUint16BE) { - buffer.Buffer.prototype.readUint16BE = function(offset) { +if (!buffer.Buffer.prototype.readUint16BE) { + buffer.Buffer.prototype.readUint16BE = function (offset) { var val = 0; val = this[offset] << 8; val |= this[offset + 1]; - return(val); + return (val); }; } // Function derived from https://github.com/joyent/node/blob/master/lib/buffer.js -if(!buffer.Buffer.prototype.hexSlice) { - var toHex = function(n) { +if (!buffer.Buffer.prototype.hexSlice) { + var toHex = function (n) { if (n < 16) return '0' + n.toString(16); return n.toString(16); }; - buffer.Buffer.prototype.hexSlice = function(start, end) { + buffer.Buffer.prototype.hexSlice = function (start, end) { var len = this.length; if (!start || start < 0) start = 0; if (!end || end < 0 || end > len) end = len; @@ -52,13 +52,13 @@ if(!buffer.Buffer.prototype.hexSlice) { for (var i = start; i < end; i++) { out += toHex(this[i]); } - return(out); + return (out); }; } // Function derived from https://github.com/joyent/node/blob/master/lib/buffer.js -if(!buffer.Buffer.prototype.writeUint16BE) { - buffer.Buffer.prototype.writeUint16BE = function(value, offset) { +if (!buffer.Buffer.prototype.writeUint16BE) { + buffer.Buffer.prototype.writeUint16BE = function (value, offset) { this[offset] = (value & 0xff00) >>> 8; this[offset + 1] = value & 0x00ff; }; @@ -66,24 +66,24 @@ if(!buffer.Buffer.prototype.writeUint16BE) { // Function derived from https://github.com/joyent/node/blob/master/lib/buffer.js // fill(value, start=0, end=buffer.length) -if(!buffer.Buffer.prototype.fill) { +if (!buffer.Buffer.prototype.fill) { buffer.Buffer.prototype.fill = function (value, start, end) { value || (value = 0); start || (start = 0); end || (end = this.length); - for(var i=start; i strLen / 2) { + if (length > strLen / 2) { length = strLen / 2; } - for(var i=0; i> 15; - if(used || debug) { + if (used || debug) { pinObject.used = used ? 'used' : 'available'; - if(debug) pinObject.data = x.hexSlice(pinOffset, pinOffset+2); + if (debug) pinObject.data = x.hexSlice(pinOffset, pinOffset + 2); var direction = (pinData & 0x6000) >> 13; - switch(direction) { + switch (direction) { case 1: pinObject.direction = 'in'; break; @@ -207,12 +209,12 @@ var parseCapeEeprom = function(x) { pinObject.direction = 'bidir'; break; default: - winston.error('Unknown direction value: '+direction); + winston.error('Unknown direction value: ' + direction); } pinObject.slew = (pinData & 0x40) ? 'slow' : 'fast'; pinObject.rx = (pinData & 0x20) ? 'enabled' : 'disabled'; var pullup = (pinData & 0x18) >> 3; - switch(pullup) { + switch (pullup) { case 1: pinObject.pullup = 'disabled'; break; @@ -223,45 +225,45 @@ var parseCapeEeprom = function(x) { pinObject.pullup = 'pulldown'; break; default: - winston.error('Unknown pullup value: '+pullup); + winston.error('Unknown pullup value: ' + pullup); } pinObject.mode = (pinData & 0x0007); try { // read mux from debugfs - var muxReadout= fs.readFileSync('/sys/kernel/debug/omap_mux/'+bone[pin].mux, 'ascii'); + var muxReadout = fs.readFileSync('/sys/kernel/debug/omap_mux/' + bone[pin].mux, 'ascii'); pinObject.function = muxReadout.split("\n")[2].split("|")[pinObject.mode].replace('signals:', '').trim(); - } catch(ex) { - if(debug) winston.debug('Unable to read pin mux function name: '+bone[pin].mux); + } catch (ex) { + if (debug) winston.debug('Unable to read pin mux function name: ' + bone[pin].mux); } data.mux[pin] = pinObject; } } } - return(data); + return (data); }; -var fillCapeEepromData = exports.fillCapeEepromData = function(data) { +var fillCapeEepromData = function (data) { eepromData.fill(); eepromData.hexWrite('aa5533ee', 0, 4); eepromData.write('A0', 4, 2, 'ascii'); - if(data.boardName.length > 32) { + if (data.boardName.length > 32) { data.boardName.length = 32; } eepromData.write(data.boardName, 6, 32, 'ascii'); - if(data.version.length > 4) { + if (data.version.length > 4) { data.version.length = 4; } eepromData.write(data.version, 38, 4, 'ascii'); - if(data.manufacturer.length > 16) { + if (data.manufacturer.length > 16) { data.manufacturer.length = 16; } eepromData.write(data.manufacturer, 42, 16, 'ascii'); - if(data.partNumber.length > 16) { + if (data.partNumber.length > 16) { data.partNumber.length = 16; } eepromData.write(data.partNumber, 58, 16, 'ascii'); eepromData.writeUint16BE(data.numPins, 74, 'ascii'); - if(data.serialNumber.length > 12) { + if (data.serialNumber.length > 12) { data.serialNumber.length = 12; } eepromData.write(data.serialNumber, 76, 12, 'ascii'); @@ -269,13 +271,13 @@ var fillCapeEepromData = exports.fillCapeEepromData = function(data) { eepromData.writeUint16BE(data.currentVDD_5V, 238); eepromData.writeUint16BE(data.currentSYS_5V, 240); eepromData.writeUint16BE(data.DCSupplied, 242); - for(var pin in data.mux) { - if(typeof bone[pin].eeprom != 'undefined') { + for (var pin in data.mux) { + if (typeof bone[pin].eeprom != 'undefined') { var pinOffset = bone[pin].eeprom * 2 + 88; var pinObject = data.mux[pin]; var pinData = 0; - if(pinObject.used == 'used') pinData |= 0x8000; - switch(pinObject.direction) { + if (pinObject.used == 'used') pinData |= 0x8000; + switch (pinObject.direction) { case 'in': pinData |= 0x2000; break; @@ -286,13 +288,13 @@ var fillCapeEepromData = exports.fillCapeEepromData = function(data) { pinData |= 0x6000; break; default: - winston.error('Unknown direction value: '+pinObject.direction); + winston.error('Unknown direction value: ' + pinObject.direction); pinData |= 0x2000; } - if(pinObject.slew == 'slow') pinData |= 0x40; - if(pinObject.rx == 'enabled') pinData |= 0x20; + if (pinObject.slew == 'slow') pinData |= 0x40; + if (pinObject.rx == 'enabled') pinData |= 0x20; var pullup = (pinData & 0x18) >> 3; - switch(pinObject.pullup) { + switch (pinObject.pullup) { case 'disabled': pinData |= 0x08; break; @@ -302,22 +304,42 @@ var fillCapeEepromData = exports.fillCapeEepromData = function(data) { case 'pulldown': break; default: - winston.error('Unknown pullup value: '+pullup); + winston.error('Unknown pullup value: ' + pullup); } pinData |= (pinObject.mode & 0x0007); eepromData.writeUint16BE(pinData, pinOffset); } } - return(eepromData); + return (eepromData); }; var defaultEepromFiles = { - '/sys/bus/i2c/drivers/at24/1-0050/eeprom': { type: 'bone' }, - '/sys/bus/i2c/drivers/at24/1-0051/eeprom': { type: 'bone' }, - '/sys/bus/i2c/drivers/at24/3-0054/eeprom': { type: 'cape' }, - '/sys/bus/i2c/drivers/at24/3-0055/eeprom': { type: 'cape' }, - '/sys/bus/i2c/drivers/at24/3-0056/eeprom': { type: 'cape' }, - '/sys/bus/i2c/drivers/at24/3-0057/eeprom': { type: 'cape' }, - 'test-bone.eeprom': { type: 'bone' }, - 'test-cape.eeprom': { type: 'cape' }, + '/sys/bus/i2c/drivers/at24/1-0050/eeprom': { + type: 'bone' + }, + '/sys/bus/i2c/drivers/at24/1-0051/eeprom': { + type: 'bone' + }, + '/sys/bus/i2c/drivers/at24/3-0054/eeprom': { + type: 'cape' + }, + '/sys/bus/i2c/drivers/at24/3-0055/eeprom': { + type: 'cape' + }, + '/sys/bus/i2c/drivers/at24/3-0056/eeprom': { + type: 'cape' + }, + '/sys/bus/i2c/drivers/at24/3-0057/eeprom': { + type: 'cape' + }, + 'test-bone.eeprom': { + type: 'bone' + }, + 'test-cape.eeprom': { + type: 'cape' + }, }; +module.exports = { + readEeproms: readEeproms, + fillCapeEepromData: fillCapeEepromData +} \ No newline at end of file diff --git a/src/ffiimp.js b/src/ffiimp.js new file mode 100644 index 00000000..769998e7 --- /dev/null +++ b/src/ffiimp.js @@ -0,0 +1,70 @@ +var bone = require('./bone'); +var fs = require('fs'); +var shell = require('shelljs'); +var winston = require('winston'); +var my = require('./my'); +var ffi = my.require('ffi'); + +var debug = process.env.DEBUG ? true : false; +//function to convert bonescript pin identifier to MRAA's format +var mraaGPIO = function (pin) { + var pinObject = bone.getPinObject(pin); + var pinNo; + if (typeof pinObject != 'object') { + throw ("Invalid pin: " + pin); + } + if (pinObject.key.indexOf('P8') != -1) { + pinNo = Number(pinObject.key.replace('P8_', '')); + } else if (pinObject.key.indexOf('P9') != -1) { + pinNo = Number(pinObject.key.replace('P9_', '')); + pinNo += 46; + } + return '0x' + pinNo.toString(16); +}; +// function to write a .c file at path , similar to writeTextFile +var writeCModule = function (filename, data, callback) { + if (filename.indexOf(".c") == -1) + filename += ".c"; + if (typeof callback == 'function') { + var cb = function (err) { + callback({ + 'err': err + }); + }; + fs.writeFile(filename, data, 'utf-8', cb); + } else { + try { + return fs.writeFileSync(filename, data, 'utf-8'); + } catch (ex) { + winston.error("writeCModule error: " + ex); + return (false); + } + } +}; +//load C module from shared object at path +var loadCModule = function (path, args, mraa) { + //compile at the path if shared object does not exist + if (path.indexOf('.c') != -1) + path = path.replace('.c', ''); + mraa = mraa || false; // link mraa + var inPath = path + '.c'; + var shellCmd = 'gcc -shared -fpic ' + inPath + ' -o ' + path + '.so'; + if (mraa) shellCmd += ' -lmraa'; + if (debug) winston.debug('loadCModule: shellCmd = ' + shellCmd); + + // Consider not running if .so newer than .c + shell.exec(shellCmd); + + if (ffi.exists) + return ffi.Library(path, args); + else { + winston.info("loadCModule: Could not load module FFI"); + return "ffi not loaded"; + } +}; + +module.exports = { + mraaGPIO: mraaGPIO, + loadCModule: loadCModule, + writeCModule: writeCModule +} \ No newline at end of file diff --git a/src/functions.js b/src/functions.js index 97f11d3e..714dd95b 100644 --- a/src/functions.js +++ b/src/functions.js @@ -1,5 +1,5 @@ // -// Copyright (C) 2012 - Cabin Programs, Ken Keller +// Copyright (C) 2012 - Cabin Programs, Ken Keller // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in @@ -7,10 +7,10 @@ // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is furnished to do // so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,9 +23,9 @@ // lowByte(value) // highByte(value) // bitRead(value, bitnum) -// bitWrite(value, bitnum, bitdata) -// bitSet(value, bitnum) -// bitClear(value, bitnum) +// bitWrite(value, bitnum, bitdata) +// bitSet(value, bitnum) +// bitClear(value, bitnum) // bit(bitnum) // // Trigonometry @@ -50,113 +50,133 @@ // Returns the lower 8 bits of value -exports.lowByte = function(value) { - return ( value & 0x0ff); +var lowByte = function (value) { + return (value & 0x0ff); }; // Returns the value shifted right by 8 bits -exports.highByte = function(value) { - return ( exports.lowByte(value >>8)); +var highByte = function (value) { + return (lowByte(value >> 8)); }; -// Returns the value of the bit number specified (return:0 or 1) -exports.bitRead = function(value, bitnum) { - return ((value>>bitnum)&0x01); +// Returns the value of the bit number specified (return:0 or 1) +var bitRead = function (value, bitnum) { + return ((value >> bitnum) & 0x01); }; -// Returns value with bit changed to specified data -exports.bitWrite = function(value, bitnum, bitdata) { - value = value & ~(0x01<b) x=b; - else if (x b) x = b; + else if (x < a) x = a; return (x); }; // Returns a value re-mapped from one range to another -exports.map = function(value, fromLow, fromHigh, toLow, toHigh) { - return( toLow + (((value-fromLow)*(toHigh-toLow))/(fromHigh-fromLow))); +var map = function (value, fromLow, fromHigh, toLow, toHigh) { + return (toLow + (((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow))); }; // Returns x raised to y power -exports.pow = function(x,y) { - return (Math.pow(x,y)); +var pow = function (x, y) { + return (Math.pow(x, y)); }; // Returns the aquare root of x -exports.sqrt = function(x) { +var sqrt = function (x) { return (Math.sqrt(x)); }; // Returns nothing var randomSeedValue; -exports.randomSeed = function(x) { +var randomSeed = function (x) { // empty - javascript has no random seed function randomSeedValue = x; }; // Returns a pseudo-random number // Valid calls: random(max) -// random(min, max) -exports.random = function(min, max) { - if (isNaN(max)) - { +// random(min, max) +var random = function (min, max) { + if (isNaN(max)) { max = min; min = 0; } - return ((Math.random()*(max-min))+min); -}; - + return ((Math.random() * (max - min)) + min); +}; + +module.exports = { + lowByte: lowByte, + highByte: highByte, + bitRead: bitRead, + bitWrite: bitWrite, + bitSet: bitSet, + bitClear: bitClear, + bit: bit, + sin: sin, + cos: cos, + tan: tan, + min: min, + max: max, + abs: abs, + constrain: constrain, + map: map, + pow: pow, + sqrt: sqrt, + randomSeed: randomSeed, + random: random +} \ No newline at end of file diff --git a/src/hw_capemgr.js b/src/hw_capemgr.js index bc09eebb..50f8010a 100644 --- a/src/hw_capemgr.js +++ b/src/hw_capemgr.js @@ -9,181 +9,180 @@ var gpioFile = {}; var pwmPrefix = {}; var ainPrefix = ""; -exports.logfile = '/var/lib/cloud9/bonescript.log'; +var logfile = '/var/lib/cloud9/bonescript.log'; -exports.readPWMFreqAndValue = function(pin, pwm) { +var readPWMFreqAndValue = function (pin, pwm) { var mode = {}; try { - var period = fs.readFileSync(pwmPrefix[pin.pwm.name]+'/period'); - var duty = fs.readFileSync(pwmPrefix[pin.pwm.name]+'/duty'); + var period = fs.readFileSync(pwmPrefix[pin.pwm.name] + '/period'); + var duty = fs.readFileSync(pwmPrefix[pin.pwm.name] + '/duty'); mode.freq = 1.0e9 / period; mode.value = duty / period; - } catch(ex) { - } - return(mode); + } catch (ex) {} + return (mode); }; -exports.readGPIODirection = function(n, gpio) { +var readGPIODirection = function (n, gpio) { var mode = {}; var directionFile = "/sys/class/gpio/gpio" + n + "/direction"; - if(my.file_existsSync(directionFile)) { + if (my.file_existsSync(directionFile)) { mode.active = true; var direction = fs.readFileSync(directionFile, 'utf-8'); direction = direction.replace(/^\s+|\s+$/g, ''); mode.direction = direction; } - return(mode); + return (mode); }; -exports.readPinMux = function(pin, mode, callback) { +var readPinMux = function (pin, mode, callback) { var pinctrlFile = '/sys/kernel/debug/pinctrl/44e10800.pinmux/pins'; var muxRegOffset = parseInt(pin.muxRegOffset, 16); - var readPinctrl = function(err, data) { - if(err) { + var readPinctrl = function (err, data) { + if (err) { mode.err = 'readPinctrl error: ' + err; - if(debug) winston.debug(mode.err); + if (debug) winston.debug(mode.err); callback(mode); } mode = parse.modeFromPinctrl(data, muxRegOffset, 0x44e10800, mode); callback(mode); }; - var tryPinctrl = function(exists) { - if(exists) { + var tryPinctrl = function (exists) { + if (exists) { fs.readFile(pinctrlFile, 'utf8', readPinctrl); } else { - if(debug) winston.debug('getPinMode(' + pin.key + '): no valid mux data'); + if (debug) winston.debug('getPinMode(' + pin.key + '): no valid mux data'); callback(mode); } }; - if(callback) { + if (callback) { my.file_exists(pinctrlFile, tryPinctrl); } else { try { var data2 = fs.readFileSync(pinctrlFile, 'utf8'); mode = parse.modeFromPinctrl(data2, muxRegOffset, 0x44e10800, mode); - } catch(ex) { - if(debug) winston.debug('getPinMode(' + pin.key + '): ' + ex); + } catch (ex) { + if (debug) winston.debug('getPinMode(' + pin.key + '): ' + ex); } } - return(mode); + return (mode); }; -exports.setPinMode = function(pin, pinData, template, resp, callback) { - if(debug) winston.debug('hw.setPinMode(' + [pin.key, pinData, template, JSON.stringify(resp)] + ');'); - if(debug) winston.debug('typeof callack = ' + typeof callback); - if(template == 'bspm') { +var setPinMode = function (pin, pinData, template, resp, callback) { + if (debug) winston.debug('hw.setPinMode(' + [pin.key, pinData, template, JSON.stringify(resp)] + ');'); + if (debug) winston.debug('typeof callack = ' + typeof callback); + if (template == 'bspm') { gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(callback) { + if (callback) { doCreateDT(resp); - return(resp); + return (resp); } - if(pin.led) { + if (pin.led) { gpioFile[pin.key] = '/sys/class/leds/beaglebone::' + pin.led + '/brightness'; } - } else if(template == 'bspwm') { - if(callback) { + } else if (template == 'bspwm') { + if (callback) { my.load_dt('am33xx_pwm', null, resp, doCreateDT); - return(resp); + return (resp); } - if(!my.load_dt('am33xx_pwm')) { + if (!my.load_dt('am33xx_pwm')) { resp.err = 'Error loading am33xx_pwm devicetree overlay'; - return(resp); + return (resp); } } else { resp.err = 'Unknown pin mode template'; - if(callback) { + if (callback) { callback(resp); - return(resp); + return (resp); } } - + // only synchronous stuff at this point - - if(!my.create_dt(pin, pinData, template)) { + + if (!my.create_dt(pin, pinData, template)) { resp.err = 'Error loading devicetree overlay for ' + pin.key + ' using template ' + template; - return(resp); + return (resp); } - if(template == 'bspwm') { + if (template == 'bspwm') { try { var ocp = my.is_ocp(); var p = 'bs_pwm_test_' + pin.key; var pwm_test = my.find_sysfsFile(p, ocp, p + '.'); pwmPrefix[pin.pwm.name] = pwm_test; - fs.writeFileSync(pwm_test+'/polarity', 0); - } catch(ex) { + fs.writeFileSync(pwm_test + '/polarity', 0); + } catch (ex) { resp.err = 'Error enabling PWM controls: ' + ex; winston.error(resp.err); } } - + // now to define the asynchronous calls - + function doCreateDT(resp) { - if(resp.err) { + if (resp.err) { callback(resp); return; } my.create_dt(pin, pinData, template, true, false, resp, onCreateDT); } - + function onCreateDT(resp) { - if(resp.err) { + if (resp.err) { callback(resp); return; } - if(template == 'bspwm') { + if (template == 'bspwm') { my.file_find('/sys/devices', 'ocp.', 1, onFindOCP); } else { callback(resp); } - + function onFindOCP(ocp) { - if(ocp.err) { + if (ocp.err) { resp.err = "Error searching for ocp: " + ocp.err; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); callback(resp); return; } my.file_find(ocp.path, 'bs_pwm_test_' + pin.key + '.', 1, onFindPWM); } - + function onFindPWM(pwm_test) { - if(pwm_test.err) { + if (pwm_test.err) { resp.err = "Error searching for pwm_test: " + pwm_test.err; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); callback(resp); return; } my.file_find(pwm_test.path, 'period', 1, onFindPeriod); - + function onFindPeriod(period) { - if(period.err) { + if (period.err) { resp.err = "Error searching for period: " + period.err; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); callback(resp); return; - } + } pwmPrefix[pin.pwm.name] = pwm_test.path; - fs.writeFile(pwm_test.path+'/polarity', 0, 'ascii', onPolarityWrite); - } + fs.writeFile(pwm_test.path + '/polarity', 0, 'ascii', onPolarityWrite); + } } - + function onPolarityWrite(err) { - if(err) { + if (err) { resp.err = "Error writing PWM polarity: " + err; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); } callback(resp); } } - - return(resp); + + return (resp); }; -exports.setLEDPinToGPIO = function(pin, resp) { +var setLEDPinToGPIO = function (pin, resp) { var path = "/sys/class/leds/beaglebone:green:" + pin.led + "/trigger"; - if(my.file_existsSync(path)) { + if (my.file_existsSync(path)) { fs.writeFileSync(path, "gpio"); } else { resp.err = "Unable to find LED " + pin.led; @@ -191,119 +190,119 @@ exports.setLEDPinToGPIO = function(pin, resp) { resp.value = false; } - return(resp); + return (resp); }; -exports.exportGPIOControls = function(pin, direction, resp, callback) { - if(debug) winston.debug('hw.exportGPIOControls(' + [pin.key, direction, resp] + ');'); +var exportGPIOControls = function (pin, direction, resp, callback) { + if (debug) winston.debug('hw.exportGPIOControls(' + [pin.key, direction, resp] + ');'); var n = pin.gpio; - if(callback) { + if (callback) { my.file_exists(gpioFile[pin.key], onFileExists); return; } var exists = my.file_existsSync(gpioFile[pin.key]); - if(exists) { - if(debug) winston.debug("gpio: " + n + " already exported."); + if (exists) { + if (debug) winston.debug("gpio: " + n + " already exported."); fs.writeFileSync("/sys/class/gpio/gpio" + n + "/direction", direction, null); } else { try { - if(debug) winston.debug("exporting gpio: " + n); + if (debug) winston.debug("exporting gpio: " + n); fs.writeFileSync("/sys/class/gpio/export", "" + n, null); - if(debug) winston.debug("setting gpio " + n + + if (debug) winston.debug("setting gpio " + n + " direction to " + direction); fs.writeFileSync("/sys/class/gpio/gpio" + n + "/direction", direction, null); - } catch(ex2) { + } catch (ex2) { resp.value = false; resp.err = 'Unable to export gpio-' + n + ': ' + ex2; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); var gpioUsers = fs.readFileSync('/sys/kernel/debug/gpio', 'utf-8'); gpioUsers = gpioUsers.split('\n'); } } - + function onFileExists(exists) { - if(exists) { - if(debug) winston.debug("gpio: " + n + " already exported."); + if (exists) { + if (debug) winston.debug("gpio: " + n + " already exported."); fs.writeFile("/sys/class/gpio/gpio" + n + "/direction", direction, null, onGPIODirectionSet); } else { - if(debug) winston.debug("exporting gpio: " + n); + if (debug) winston.debug("exporting gpio: " + n); fs.writeFile("/sys/class/gpio/export", "" + n, null, onGPIOExport); } } - + function onGPIOExport(err) { - if(err) onError(err); - if(debug) winston.debug("setting gpio " + n + + if (err) onError(err); + if (debug) winston.debug("setting gpio " + n + " direction to " + direction); fs.writeFile("/sys/class/gpio/gpio" + n + "/direction", direction, null, onGPIODirectionSet); } function onGPIODirectionSet(err) { - if(err) onError(err); + if (err) onError(err); else callback(resp); } - + function onError(err) { resp.err = 'Unable to export gpio-' + n + ': ' + err; resp.value = false; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); findOwner(); } - + function findOwner() { fs.readFile('/sys/kernel/debug/gpio', 'utf-8', onGPIOUsers); } - + function onGPIOUsers(err, data) { - if(!err) { + if (!err) { var gpioUsers = data.split('\n'); - for(var x in gpioUsers) { + for (var x in gpioUsers) { var y = gpioUsers[x].match(/gpio-(\d+)\s+\((\S+)\s*\)/); - if(y && y[1] == n) { + if (y && y[1] == n) { resp.err += '\nconsumed by ' + y[2]; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); } } } callback(resp); } - return(resp); + return (resp); }; -exports.writeGPIOValue = function(pin, value, callback) { - if(typeof gpioFile[pin.key] == 'undefined') { +var writeGPIOValue = function (pin, value, callback) { + if (typeof gpioFile[pin.key] == 'undefined') { gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(pin.led) { + if (pin.led) { gpioFile[pin.key] = "/sys/class/leds/beaglebone:"; gpioFile[pin.key] += "green:" + pin.led + "/brightness"; } - if(!my.file_existsSync(gpioFile[pin.key])) { + if (!my.file_existsSync(gpioFile[pin.key])) { winston.error("Unable to find gpio: " + gpioFile[pin.key]); } } - if(debug) winston.debug("gpioFile = " + gpioFile[pin.key]); - if(callback) { + if (debug) winston.debug("gpioFile = " + gpioFile[pin.key]); + if (callback) { fs.writeFile(gpioFile[pin.key], '' + value, null, callback); } else { try { fs.writeFileSync(gpioFile[pin.key], '' + value, null); - } catch(ex) { + } catch (ex) { winston.error("Unable to write to " + gpioFile[pin.key]); } } }; -exports.readGPIOValue = function(pin, resp, callback) { +var readGPIOValue = function (pin, resp, callback) { var gpioFile = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(callback) { - var readFile = function(err, data) { - if(err) { + if (callback) { + var readFile = function (err, data) { + if (err) { resp.err = 'digitalRead error: ' + err; winston.error(resp.err); } @@ -311,34 +310,36 @@ exports.readGPIOValue = function(pin, resp, callback) { callback(resp); }; fs.readFile(gpioFile, readFile); - return(true); + return (true); } resp.value = parseInt(fs.readFileSync(gpioFile), 2); - return(resp); + return (resp); }; -exports.enableAIN = function(callback) { +var enableAIN = function (callback) { var helper = ""; - if(my.load_dt('cape-bone-iio')) { + if (my.load_dt('cape-bone-iio')) { var ocp = my.is_ocp(); - if(ocp) { + if (ocp) { helper = my.find_sysfsFile('helper', ocp, 'helper.'); - if(helper) { + if (helper) { ainPrefix = helper + '/AIN'; } } } - if(callback) { - callback({'path': helper}) + if (callback) { + callback({ + 'path': helper + }) } - return(helper.length > 1); + return (helper.length > 1); }; -exports.readAIN = function(pin, resp, callback) { +var readAIN = function (pin, resp, callback) { var ainFile = ainPrefix + pin.ain.toString(); - if(callback) { - var readFile = function(err, data) { - if(err) { + if (callback) { + var readFile = function (err, data) { + if (err) { resp.err = 'analogRead error: ' + err; winston.error(resp.err); } @@ -346,22 +347,22 @@ exports.readAIN = function(pin, resp, callback) { callback(resp); }; fs.readFile(ainFile, readFile); - return(resp); + return (resp); } resp.value = parseInt(fs.readFileSync(ainFile), 10); - if(isNaN(resp.value)) { + if (isNaN(resp.value)) { resp.err = 'analogRead(' + pin.key + ') returned ' + resp.value; winston.error(resp.err); } resp.value = resp.value / 1800; - if(isNaN(resp.value)) { + if (isNaN(resp.value)) { resp.err = 'analogRead(' + pin.key + ') scaled to ' + resp.value; winston.error(resp.err); } - return(resp); + return (resp); }; -exports.writeGPIOEdge = function(pin, mode) { +var writeGPIOEdge = function (pin, mode) { fs.writeFileSync('/sys/class/gpio/gpio' + pin.gpio + '/edge', mode); var resp = {}; @@ -369,61 +370,81 @@ exports.writeGPIOEdge = function(pin, mode) { resp.valuefd = fs.openSync(resp.gpioFile, 'r'); resp.value = new Buffer(1); - return(resp); + return (resp); }; -exports.writePWMFreqAndValue = function(pin, pwm, freq, value, resp, callback) { - if(debug) winston.debug('hw.writePWMFreqAndValue(' + [pin.key,pwm,freq,value,resp] + ');'); +var writePWMFreqAndValue = function (pin, pwm, freq, value, resp, callback) { + if (debug) winston.debug('hw.writePWMFreqAndValue(' + [pin.key, pwm, freq, value, resp] + ');'); var path = pwmPrefix[pin.pwm.name]; try { - var period = Math.round( 1.0e9 / freq ); // period in ns - var duty = Math.round( period * value ); - fs.writeFileSync(path+'/duty', 0); - if(pwm.freq != freq) { - if(debug) winston.debug('Updating PWM period: ' + period); - fs.writeFileSync(path+'/period', period); + var period = Math.round(1.0e9 / freq); // period in ns + var duty = Math.round(period * value); + fs.writeFileSync(path + '/duty', 0); + if (pwm.freq != freq) { + if (debug) winston.debug('Updating PWM period: ' + period); + fs.writeFileSync(path + '/period', period); } - if(debug) winston.debug('Updating PWM duty: ' + duty); - fs.writeFileSync(path+'/duty', duty); - } catch(ex) { + if (debug) winston.debug('Updating PWM duty: ' + duty); + fs.writeFileSync(path + '/duty', duty); + } catch (ex) { resp.err = 'error updating PWM freq and value: ' + path + ', ' + ex; winston.error(resp.err); } - return(resp); + return (resp); }; -exports.readEeproms = function(eeproms) { +var readEeproms = function (eeproms) { var boardName = fs.readFileSync(my.is_capemgr() + '/baseboard/board-name', - 'ascii'); + 'ascii'); var version = fs.readFileSync(my.is_capemgr() + '/baseboard/revision', - 'ascii'); + 'ascii'); var serialNumber = fs.readFileSync(my.is_capemgr() + '/baseboard/serial-number', - 'ascii'); + 'ascii'); eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'] = {}; eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'].boardName = boardName; eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'].version = version; eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'].serialNumber = serialNumber; - return(eeproms); + return (eeproms); }; -exports.readPlatform = function(platform) { +var readPlatform = function (platform) { platform.name = fs.readFileSync(my.is_capemgr() + '/baseboard/board-name', 'ascii').trim(); - if(platform.name == 'A335BONE') platform.name = 'BeagleBone'; - if(platform.name == 'A335BNLT') platform.name = 'BeagleBone Black'; + if (platform.name == 'A335BONE') platform.name = 'BeagleBone'; + if (platform.name == 'A335BNLT') platform.name = 'BeagleBone Black'; + if (platform.name == 'A335PBGL') platform.name = 'PocketBeagle'; platform.version = fs.readFileSync(my.is_capemgr() + '/baseboard/revision', 'ascii').trim(); - if(platform.version[0] == 0x1A) { + if (platform.version[0] == 0x1A) { platform.version = '1A'; platform.name = 'BeagleBone Green'; - } - else if(platform.version.match(/^GR/)) { + } else if (platform.version.match(/^GR/)) { platform.version = platform.version.substr(2); platform.name = 'BeagleBone Green'; - } - else if(!platform.version.match(/^[\040-\176]*$/)) delete platform.version; + } else if (platform.version.match(/^BL/)) { + platform.version = platform.version.substr(2); + platform.name = 'BeagleBone Blue'; + } else if (!platform.version.match(/^[\040-\176]*$/)) delete platform.version; platform.serialNumber = fs.readFileSync(my.is_capemgr() + '/baseboard/serial-number', 'ascii').trim(); - if(!platform.serialNumber.match(/^[\040-\176]*$/)) delete platform.serialNumber; - return(platform); + if (!platform.serialNumber.match(/^[\040-\176]*$/)) delete platform.serialNumber; + return (platform); }; + +module.exports = { + logfile: logfile, + readPWMFreqAndValue: readPWMFreqAndValue, + readGPIODirection: readGPIODirection, + readPinMux: readPinMux, + setPinMode: setPinMode, + setLEDPinToGPIO: setLEDPinToGPIO, + exportGPIOControls: exportGPIOControls, + writeGPIOValue: writeGPIOValue, + readGPIOValue: readGPIOValue, + enableAIN: enableAIN, + readAIN: readAIN, + writeGPIOEdge: writeGPIOEdge, + writePWMFreqAndValue: writePWMFreqAndValue, + readEeproms: readEeproms, + readPlatform: readPlatform, +} \ No newline at end of file diff --git a/src/hw_mainline.js b/src/hw_mainline.js index d5222a9a..25544b01 100644 --- a/src/hw_mainline.js +++ b/src/hw_mainline.js @@ -1,14 +1,18 @@ var fs = require('fs'); +var async = require('async'); var my = require('./my'); var parse = require('./parse'); var eeprom = require('./eeprom'); var util = require('util'); var winston = require('winston'); +var shell = require('shelljs'); var debug = process.env.DEBUG ? true : false; -if(debug) { +if (debug) { winston.remove(winston.transports.Console); - winston.add(winston.transports.Console, {colorize: true}); + winston.add(winston.transports.Console, { + colorize: true + }); } var gpioFile = {}; @@ -17,124 +21,163 @@ var ainPrefix = "/sys/bus/iio/devices/iio:device0"; var SLOTS = "/sys/devices/platform/bone_capemgr/slots"; var AINdts = "BB-ADC"; -exports.logfile = '/var/lib/cloud9/bonescript.log'; +var logfile = '/var/lib/cloud9/bonescript.log'; -exports.readPWMFreqAndValue = function(pin, pwm) { +var readPWMFreqAndValue = function (pin, pwm) { var mode = {}; try { - var period = fs.readFileSync(pwmPrefix[pin.pwm.name]+'/period_ns'); - var duty = fs.readFileSync(pwmPrefix[pin.pwm.name]+'/duty_ns'); + var period = fs.readFileSync(pwmPrefix[pin.pwm.name] + '/period_ns'); + var duty = fs.readFileSync(pwmPrefix[pin.pwm.name] + '/duty_ns'); mode.freq = 1.0e9 / period; mode.value = duty / period; - } catch(ex) { - } - return(mode); + } catch (ex) {} + return (mode); }; -exports.readGPIODirection = function(n, gpio) { +var readGPIODirection = function (n, gpio) { var mode = {}; var directionFile = "/sys/class/gpio/gpio" + n + "/direction"; - if(my.file_existsSync(directionFile)) { + if (my.file_existsSync(directionFile)) { mode.active = true; var direction = fs.readFileSync(directionFile, 'utf-8'); direction = direction.replace(/^\s+|\s+$/g, ''); mode.direction = direction; } - return(mode); + return (mode); }; -exports.readPinMux = function(pin, mode, callback) { +var readPinMux = function (pin, mode, callback) { var pinctrlFile = '/sys/kernel/debug/pinctrl/44e10800.pinmux/pins'; var muxRegOffset = parseInt(pin.muxRegOffset, 16); - var readPinctrl = function(err, data) { - if(err) { + //handle the case when debugfs not mounted + if (!my.file_existsSync(pinctrlFile)) { + //exit code is 1 if /sys/kernel/debug not mounted + const umount = shell.exec('mountpoint -q /sys/kernel/debug/').code; + if (umount) + shell.exec('mount -t debugfs none /sys/kernel/debug/', { + silent: true + }); + } + var readPinctrl = function (err, data) { + if (err) { mode.err = 'readPinctrl error: ' + err; - if(debug) winston.debug(mode.err); - callback(mode); + if (debug) winston.debug(mode.err); + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(mode); + } else + callback(mode.err, data); } mode = parse.modeFromPinctrl(data, muxRegOffset, 0x44e10800, mode); - callback(mode); + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(mode); + } else + callback(null, mode); }; - var tryPinctrl = function(exists) { - if(exists) { + var tryPinctrl = function (exists) { + if (exists) { fs.readFile(pinctrlFile, 'utf8', readPinctrl); } else { - if(debug) winston.debug('getPinMode(' + pin.key + '): no valid mux data'); - callback(mode); + if (debug) winston.debug('getPinMode(' + pin.key + '): no valid mux data'); + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(mode); + } else + callback('readPinMux error: no valid mux data', mode); } }; - if(callback) { + if (callback) { my.file_exists(pinctrlFile, tryPinctrl); } else { try { var data2 = fs.readFileSync(pinctrlFile, 'utf8'); mode = parse.modeFromPinctrl(data2, muxRegOffset, 0x44e10800, mode); - } catch(ex) { - if(debug) winston.debug('getPinMode(' + pin.key + '): ' + ex); + } catch (ex) { + if (debug) winston.debug('getPinMode(' + pin.key + '): ' + ex); } } - return(mode); + return (mode); }; -exports.setPinMode = function(pin, pinData, template, resp, callback) { - if(debug) winston.debug('hw.setPinMode(' + [pin.key, pinData, template, JSON.stringify(resp)] + ');'); +var setPinMode = function (pin, pinData, template, resp, callback) { + if (debug) winston.debug('hw.setPinMode(' + [pin.key, pinData, template, JSON.stringify(resp)] + ');'); var p = "ocp:" + pin.key + "_pinmux"; - if(pin.universalName) p = "ocp:" + pin.universalName + "_pinmux"; - var pinmux = my.find_sysfsFile(p, my.is_ocp(), p); - // if(!pinmux) { throw p + " was not found under " + my.is_ocp(); } + if (!pin.universalName) { + pin.universalName = [p]; + if (pin.ball && pin.ball.ZCZ) pin.universalName.push("ocp:" + pin.ball.ZCZ + "_pinmux"); + } + var pinmux = my.find_sysfsFile(p, my.is_ocp(), pin.universalName); gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(pinmux) { // This is a hack for the new pins on the Blue that appear not to have a pinmux - if((pinData & 7) == 7) { - fs.writeFileSync(pinmux+"/state", 'gpio'); - } else if(template == 'bspwm') { - // at least P9_28 uses pwm2 - var state = pin.key.indexOf("P9_28") == -1 ? "pwm" : "pwm2"; - fs.writeFileSync(pinmux+"/state", state); - // Buld a path like: /sys/devices/platform/ocp/48304000.epwmss/48304200.ehrpwm/pwm/pwmchip5 - // pin.pwm.chip looks up the first address and pin.pwm.addr looks up the second - // file_find figures which pwmchip to use - // pin.pwm.index tells with half of the PWM to use (0 or 1) - // prefix is .ecap for P9_28 and P9_42 and .pwm or .ehrpwm for the rest - var prefix = pin.pwm.module.indexOf("ecap") == -1 ? ".pwm" : ".ecap"; - var pwmPath = my.file_find('/sys/devices/platform/ocp/'+pin.pwm.chip - + '.epwmss/'+pin.pwm.addr+prefix+'/pwm', 'pwmchip', 1); - // Some versions of kernel (4.4.15-bone11 for instance) still use - // .ehrpwm for address - if (pwmPath == null) { - pwmPath = my.file_find('/sys/devices/platform/ocp/'+pin.pwm.chip - + '.epwmss/'+pin.pwm.addr+'.ehrpwm/pwm', 'pwmchip', 1) - } - pwmPrefix[pin.pwm.name] = pwmPath + '/pwm' + pin.pwm.index; - if(debug) winston.debug("pwmPrefix[pin.pwm.name] = " + pwmPrefix[pin.pwm.name]); - if(debug) winston.debug("pin.pwm.sysfs = " + pin.pwm.sysfs); - if(!my.file_existsSync(pwmPrefix[pin.pwm.name])) { - fs.appendFileSync(pwmPath+'/export', pin.pwm.index); + if (pinmux) { + var state = undefined; + if ((pinData & 7) == 7) { + state = 'gpio'; + switch (pinData & 0x18) { + case 0x00: + state = 'gpio_pd'; + break; + case 0x10: + state = 'gpio_pu'; + break; + default: + break; } - fs.appendFileSync(pwmPrefix[pin.pwm.name]+'/enable', 1); + } else if (template == 'bspwm' || template == 'pwm') { + state = "pwm"; + if (pin.pwm.universalMode) state = pin.pwm.universalMode; } else { resp.err = 'Unknown pin mode template'; + winston.error(resp.err); } - } else { - winston.info("No pinmux for " + pin.key); + if (!resp.err) { + fs.writeFileSync(pinmux + "/state", state); + } + } else { + resp.err = 'No pinmux for ' + pin.key; + if (debug) winston.debug(resp.err); + } + + if (template == 'bspwm') { + // Buld a path like: /sys/devices/platform/ocp/48304000.epwmss/48304200.ehrpwm/pwm/pwmchip5/pwm5-:0 + // pin.pwm.chip looks up the first address and pin.pwm.addr looks up the second + // file_find figures which pwmchip to use + // pin.pwm.index tells with half of the PWM to use (0 or 1) + var chipPath = my.file_find('/sys/devices/platform/ocp', pin.pwm.chip, 1); + if (debug) winston.debug("chipPath = " + chipPath); + var addrPath = my.file_find(chipPath, pin.pwm.addr, 1); + if (debug) winston.debug("addrPath = " + addrPath); + var pwmchipPath = my.file_find(addrPath + '/pwm', 'pwmchip', 1); + if (debug) winston.debug("pwmchipPath = " + pwmchipPath); + var pwmPath = my.file_find(pwmchipPath, "pwm.*" + pin.pwm.index + "$", 1); + if (debug) winston.debug("pwmPath = " + pwmPath); + if (pwmchipPath && !pwmPath) { + fs.appendFileSync(pwmchipPath + '/export', pin.pwm.index); + pwmPath = my.file_find(pwmchipPath, "pwm.*" + pin.pwm.index + "$", 1); + if (debug) winston.debug("pwmPath = " + pwmPath); + } + if (pwmPath) { + pwmPrefix[pin.pwm.name] = pwmPath; + } + //fs.appendFileSync(pwmPrefix[pin.pwm.name]+'/enable', 1); } - if(callback) callback(resp); - return(resp); + + if (callback) callback(resp); + return (resp); }; -exports.setLEDPinToGPIO = function(pin, resp) { - winston.debug('setLEDPinTGPIO'); +var setLEDPinToGPIO = function (pin, resp) { + if (debug) winston.debug('setLEDPinTGPIO: ' + pin.key); var path; - // console.log("setLEDPinToGPIO " + pin); - if((pin.led === 'red') || (pin.led === 'green') - || (pin.led === 'bat25') || (pin.led === 'bat50') - || (pin.led === 'bat75') || (pin.led === 'bat100') - || (pin.led === 'wifi')) { - path = "/sys/class/leds/" + pin.led + "/trigger"; - } else { - path = "/sys/class/leds/beaglebone:green:" + pin.led + "/trigger"; + if (Array.isArray(pin.led)) { + resp.err = "Unable to handle LED definition as array " + pin.led; + winston.error(resp.err); + resp.value = false; + return (resp); } + path = "/sys/class/leds/" + pin.led + "/trigger"; - if(my.file_existsSync(path)) { + if (my.file_existsSync(path)) { fs.writeFileSync(path, "gpio"); } else { resp.err = "Unable to find LED " + pin.led; @@ -142,119 +185,119 @@ exports.setLEDPinToGPIO = function(pin, resp) { resp.value = false; } - return(resp); + return (resp); }; -exports.exportGPIOControls = function(pin, direction, resp, callback) { - if(debug) winston.debug('hw.exportGPIOControls(' + [pin.key, direction, resp] + ');'); +var exportGPIOControls = function (pin, direction, resp, callback) { + if (debug) winston.debug('hw.exportGPIOControls(' + [pin.key, direction, resp] + ');'); var n = pin.gpio; var exists = my.file_existsSync(gpioFile[pin.key]); - - if(!exists) { - if(debug) winston.debug("exporting gpio: " + n); + + if (!exists) { + if (debug) winston.debug("exporting gpio: " + n); fs.writeFileSync("/sys/class/gpio/export", "" + n, null); } var directionFile = "/sys/class/gpio/gpio" + n + "/direction"; - if(debug) winston.debug('Writing GPIO direction(' + direction + ') to ' + + if (debug) winston.debug('Writing GPIO direction(' + direction + ') to ' + directionFile + ');'); fs.writeFileSync(directionFile, direction); - return(resp); + return (resp); }; -exports.writeGPIOValue = function(pin, value, callback) { - if(typeof gpioFile[pin.key] == 'undefined') { +var writeGPIOValue = function (pin, value, callback) { + if (typeof gpioFile[pin.key] == 'undefined') { gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(pin.led) { - // Handle Blue LEDs - if((pin.led === 'red') || (pin.led === 'green') - || (pin.led === 'bat25') || (pin.led === 'bat50') - || (pin.led === 'bat75') || (pin.led === 'bat100') - || (pin.led === 'wifi')) { - gpioFile[pin.key] = "/sys/class/leds/"; - gpioFile[pin.key] += pin.led + "/brightness"; - } else { - gpioFile[pin.key] = "/sys/class/leds/beaglebone:"; - gpioFile[pin.key] += "green:" + pin.led + "/brightness"; - } + if (pin.led) { + gpioFile[pin.key] = "/sys/class/leds/" + pin.led + "/brightness"; } - if(!my.file_existsSync(gpioFile[pin.key])) { + if (!my.file_existsSync(gpioFile[pin.key])) { winston.error("Unable to find gpio: " + gpioFile[pin.key]); } } - if(debug) winston.debug("gpioFile = " + gpioFile[pin.key]); - if(callback) { + if (debug) winston.debug("gpioFile = " + gpioFile[pin.key]); + if (callback) { fs.writeFile(gpioFile[pin.key], '' + value, null, callback); } else { try { fs.writeFileSync(gpioFile[pin.key], '' + value, null); - } catch(ex) { + } catch (ex) { winston.error("Unable to write to " + gpioFile[pin.key]); } } }; -exports.readGPIOValue = function(pin, resp, callback) { +var readGPIOValue = function (pin, resp, callback) { var gpioFile = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(callback) { - var readFile = function(err, data) { - if(err) { + if (callback) { + var readFile = function (err, data) { + if (err) { resp.err = 'digitalRead error: ' + err; winston.error(resp.err); } resp.value = parseInt(data, 2); - callback(resp); + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(resp); + } else + callback(resp.err, resp.value); }; fs.readFile(gpioFile, readFile); - return(true); + return (true); } resp.value = parseInt(fs.readFileSync(gpioFile), 2); - return(resp); + return (resp); }; -exports.enableAIN = function(callback) { - if(!my.file_existsSync(ainPrefix)) { - if(debug) winston.debug('enableAIN: loading ' + AINdts); - fs.writeFileSync(SLOTS, AINdts); // Loads AINdts +var enableAIN = function (callback) { + if (!my.file_existsSync(ainPrefix)) { + if (debug) winston.debug('enableAIN: loading ' + AINdts); + fs.writeFileSync(SLOTS, AINdts); // Loads AINdts } - if(!my.file_existsSync(ainPrefix)) { - if(debug) winston.debug('enableAIN: load of ' + AINdts + ' failed'); + if (!my.file_existsSync(ainPrefix)) { + if (debug) winston.debug('enableAIN: load of ' + AINdts + ' failed'); } - if(callback) { - callback({'path': ainPrefix}); + if (callback) { + callback({ + 'path': ainPrefix + }); } - return(ainPrefix); + return (ainPrefix); }; -exports.readAIN = function(pin, resp, callback) { +var readAIN = function (pin, resp, callback) { var maxValue = 4095; var ainFile = ainPrefix + '/in_voltage' + pin.ain.toString() + '_raw'; - if(debug) winston.debug("readAIN: ainFile="+ainFile); - if(callback) { - var readFile = function(err, data) { - if(err) { + if (debug) winston.debug("readAIN: ainFile=" + ainFile); + if (callback) { + var readFile = function (err, data) { + if (err) { resp.err = 'analogRead error: ' + err; winston.error(resp.err); } resp.value = parseInt(data, 10) / maxValue; - callback(resp); + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(resp); + } else + callback(resp.err, resp.value); }; fs.readFile(ainFile, readFile); - return(resp); + return (resp); } resp.value = parseInt(fs.readFileSync(ainFile), 10); - if(isNaN(resp.value)) { + if (isNaN(resp.value)) { resp.err = 'analogRead(' + pin.key + ') returned ' + resp.value; winston.error(resp.err); } resp.value = resp.value / maxValue; - if(isNaN(resp.value)) { + if (isNaN(resp.value)) { resp.err = 'analogRead(' + pin.key + ') scaled to ' + resp.value; winston.error(resp.err); } - return(resp); + return (resp); }; -exports.writeGPIOEdge = function(pin, mode) { +var writeGPIOEdge = function (pin, mode) { fs.writeFileSync('/sys/class/gpio/gpio' + pin.gpio + '/edge', mode); var resp = {}; @@ -262,81 +305,163 @@ exports.writeGPIOEdge = function(pin, mode) { resp.valuefd = fs.openSync(resp.gpioFile, 'r'); resp.value = new Buffer(1); - return(resp); + return (resp); }; -exports.writePWMFreqAndValue = function(pin, pwm, freq, value, resp, callback) { - if(debug) winston.debug('hw.writePWMFreqAndValue(' + [pin.key,util.inspect(pwm),freq,value,resp] + ');'); +var writePWMFreqAndValue = function (pin, pwm, freq, value, resp, callback) { + if (debug) winston.debug('hw.writePWMFreqAndValue(' + [pin.key, util.inspect(pwm), freq, value, resp] + ');'); var path = pwmPrefix[pin.pwm.name]; try { - var period = Math.round( 1.0e9 / freq ); // period in ns - if(debug) winston.debug('hw.writePWMFreqAndValue: pwm.freq='+pwm.freq - +', freq='+freq+', period='+period); - if(pwm.freq != freq) { - // if(debug) winston.debug('Stopping PWM'); - // fs.writeFileSync(path+'/enable', "0\n"); - // It appears that the first time you set the pwm you have to - // set the period before you set the duty_cycle - try { - if(debug) winston.debug('Updating PWM period: ' + period); - fs.writeFileSync(path+'/period', period + "\n"); - } catch(ex2) { - period = fs.readFileSync(path+'/period'); - winston.info('Unable to update PWM period, period is set to ' - + period - + "\tIs other half of PWM enabled?"); + var period = Math.round(1.0e9 / freq); // period in ns + var duty = Math.round(period * value); + var currentPeriod = fs.readFileSync(path + '/period'); //read Current Period for smooth PWM + var currentDuty = fs.readFileSync(path + '/duty_cycle'); //read Current Duty for smooth PWM + var pwmEnabled = Number(fs.readFileSync(path + '/enable')); //check whether PWM is enabled + var disablePWM = !(duty * freq); //when duty||frequency ==0 , disablePWM to avoid spikes + + if (debug) winston.debug('hw.writePWMFreqAndValue: pwm.freq=' + pwm.freq + + ', freq=' + freq + ', period=' + period); + //smooth PWM Implementation + if (!disablePWM && pwmEnabled) { + if (period > currentDuty) { + if (debug) winston.debug('Updating PWM period: ' + period); + fs.writeFileSync(path + '/period', period); + if (debug) winston.debug('Updating PWM duty: ' + duty); + fs.writeFileSync(path + '/duty_cycle', duty); + } else if (duty < currentPeriod) { + if (debug) winston.debug('Updating PWM duty: ' + duty); + fs.writeFileSync(path + '/duty_cycle', duty); + if (debug) winston.debug('Updating PWM period: ' + period); + fs.writeFileSync(path + '/period', period); + } + } else { + var tryAgain = true; + var tries = 0; + + async.until(function () { //try accessing 'path/enable' until no EACCES error is thrown (max 10 times) + return !tryAgain; //to account for udev delay + }, stopPWM, updatePeriodAndDuty); //async.until(test,iteratee,callback) + + function stopPWM(callback) { + try { + if (debug) winston.debug('Stopping PWM'); + fs.writeFileSync(path + '/enable', "0\n"); + callback(null); //if no error + tryAgain = false; //do not try again + } catch (ex2) { + if (debug) winston.debug('Error stopping PWM: ' + ex2); + if (ex2.code == 'EACCES') { + tries++; + if (tries < 10) + tryAgain = true; //if EACCES error thrown try again for a maximum of 10 times + else + tryAgain = false; + callback(null); //async.until requires an err first format callback & + } else { //if there is an error iteration stops, so neglect the error if EACCES thrown + tryAgain = false; + callback(ex2); + } + } + } + + function updatePeriodAndDuty() { + // It appears that the first time you set the pwm you have to + // set the period before you set the duty_cycle + if (!disablePWM) { //if duty||frequency == 0 do not re-enable PWM (to avoid spikes) + try { + if (debug) winston.debug('Updating PWM period: ' + period); + fs.writeFileSync(path + '/period', period + "\n"); + } catch (ex2) { + winston.info('Unable to update PWM period, period is set to ' + + currentPeriod + + "\tIs other half of PWM enabled?"); + } + try { + if (debug) winston.debug('Starting PWM'); + fs.writeFileSync(path + '/enable', "1\n"); + } catch (ex2) { + if (debug) winston.debug('Error starting PWM: ' + ex2); + } + } + if (debug) winston.debug('Updating PWM duty: ' + duty); + //if(duty == 0) winston.error('Updating PWM duty: ' + duty); + if (!disablePWM) + fs.writeFileSync(path + '/duty_cycle', duty + "\n"); } - // if(debug) winston.debug('Starting PWM'); - // fs.writeFileSync(path+'/enable', "1\n"); } - var duty = Math.round( period * value ); - if(debug) winston.debug('Updating PWM duty: ' + duty); - //if(duty == 0) winston.error('Updating PWM duty: ' + duty); - fs.writeFileSync(path+'/duty_cycle', duty + "\n"); - } catch(ex) { + } catch (ex) { resp.err = 'error updating PWM freq and value: ' + path + ', ' + ex; winston.error(resp.err); } - return(resp); + return (resp); }; -exports.readEeproms = function(eeproms) { +var readEeproms = function (eeproms) { var EepromFiles = { - '/sys/bus/i2c/devices/0-0050/0-00500/nvmem': { type: 'bone' }, - '/sys/bus/i2c/devices/2-0054/2-00540/nvmem': { type: 'cape' }, - '/sys/bus/i2c/devices/2-0055/2-00550/nvmem': { type: 'cape' }, - '/sys/bus/i2c/devices/2-0056/2-00560/nvmem': { type: 'cape' }, - '/sys/bus/i2c/devices/2-0057/2-00570/nvmem': { type: 'cape' } + '/sys/bus/i2c/devices/0-0050/0-00500/nvmem': { + type: 'bone' + }, + '/sys/bus/i2c/devices/2-0054/2-00540/nvmem': { + type: 'cape' + }, + '/sys/bus/i2c/devices/2-0055/2-00550/nvmem': { + type: 'cape' + }, + '/sys/bus/i2c/devices/2-0056/2-00560/nvmem': { + type: 'cape' + }, + '/sys/bus/i2c/devices/2-0057/2-00570/nvmem': { + type: 'cape' + } }; eeproms = eeprom.readEeproms(EepromFiles); - return(eeproms); + return (eeproms); }; -exports.readPlatform = function(platform) { +var readPlatform = function (platform) { var eeproms = eeprom.readEeproms({ - '/sys/bus/i2c/devices/0-0050/0-00500/nvmem': { type: 'bone' } + '/sys/bus/i2c/devices/0-0050/0-00500/nvmem': { + type: 'bone' + } }); var x = eeproms['/sys/bus/i2c/devices/0-0050/0-00500/nvmem']; platform.name = fs.readFileSync('/proc/device-tree/model', 'ascii').trim().replace(/\0/g, ''); - if(platform.name.indexOf('Green') > 0) { + if (platform.name.indexOf('Green') > 0) { platform.name = platform.name.replace('TI AM335x', 'SeeedStudio') } - if(platform.name.indexOf('Arduino') > 0) { + if (platform.name.indexOf('Arduino') > 0) { platform.name = platform.name.replace('TI AM335x', '') } platform.name = platform.name.replace('TI AM335x BeagleBone', 'BeagleBoard.org BeagleBone'); platform.name = platform.name.replace('TI AM5728 BeagleBoard-X15', 'BeagleBoard.org BeagleBoard-X15'); - if(x && x.version) { + if (x && x.version) { platform.version = x.version; - if(!platform.version.match(/^[\040-\176]*$/)) delete platform.version; + if (!platform.version.match(/^[\040-\176]*$/)) delete platform.version; } - if(x && x.serialNumber) { + if (x && x.serialNumber) { platform.serialNumber = x.serialNumber; - if(!platform.serialNumber.match(/^[\040-\176]*$/)) delete platform.serialNumber; + if (!platform.serialNumber.match(/^[\040-\176]*$/)) delete platform.serialNumber; } try { platform.dogtag = fs.readFileSync('/etc/dogtag', 'ascii'); - } catch(ex) { - } - return(platform); + } catch (ex) {} + return (platform); }; + +module.exports = { + logfile: logfile, + readPWMFreqAndValue: readPWMFreqAndValue, + readGPIODirection: readGPIODirection, + readPinMux: readPinMux, + setPinMode: setPinMode, + setLEDPinToGPIO: setLEDPinToGPIO, + exportGPIOControls: exportGPIOControls, + writeGPIOValue: writeGPIOValue, + readGPIOValue: readGPIOValue, + enableAIN: enableAIN, + readAIN: readAIN, + writeGPIOEdge: writeGPIOEdge, + writePWMFreqAndValue: writePWMFreqAndValue, + readEeproms: readEeproms, + readPlatform: readPlatform +} \ No newline at end of file diff --git a/src/hw_oldkernel.js b/src/hw_oldkernel.js index 31989a48..51cf9a61 100644 --- a/src/hw_oldkernel.js +++ b/src/hw_oldkernel.js @@ -12,89 +12,89 @@ var debug = true; var gpioFile = {}; var pwmPrefix = {}; -exports.logfile = '/var/lib/cloud9/bonescript.log'; +var logfile = '/var/lib/cloud9/bonescript.log'; -exports.readPWMFreqAndValue = function(pin, pwm) { +var readPWMFreqAndValue = function (pin, pwm) { var mode = {}; try { - var duty_percent = fs.readFileSync(pwmPrefix[pin.pwm.name]+'/duty_percent'); - mode.freq = fs.readFileSync(pwmPrefix[pin.pwm.name]+'/period_freq'); + var duty_percent = fs.readFileSync(pwmPrefix[pin.pwm.name] + '/duty_percent'); + mode.freq = fs.readFileSync(pwmPrefix[pin.pwm.name] + '/period_freq'); mode.value = duty_percent / 100.0; - } catch(ex) { + } catch (ex) { mode.err = 'cannot set PWM frequency and value: ' + ex; } - return(mode); + return (mode); }; -exports.readGPIODirection = hw_capemgr.readGPIODirection; +var readGPIODirection = hw_capemgr.readGPIODirection; -exports.readPinMux = function(pin, mode, callback) { +var readPinMux = function (pin, mode, callback) { var muxFile = '/sys/kernel/debug/omap_mux/' + pin.mux; - var readOmapMux = function(err, data) { - if(err) { + var readOmapMux = function (err, data) { + if (err) { mode.err = 'readOmapMux error: ' + err; - if(debug) winston.debug(mode.err); + if (debug) winston.debug(mode.err); callback(mode); } mode = parse.modeFromOmapMux(data, mode); callback(mode); }; - var tryOmapMux = function(exists) { - if(exists) { + var tryOmapMux = function (exists) { + if (exists) { fs.readFile(muxFile, 'utf8', readOmapMux); } }; - if(callback) { + if (callback) { my.file_exists(muxFile, tryOmapMux); } else { try { var data = fs.readFileSync(muxFile, 'utf8'); mode = parse.modeFromOmapMux(data, mode); - } catch(ex) { - if(debug) winston.debug('getPinMode(' + pin.key + '): ' + ex); + } catch (ex) { + if (debug) winston.debug('getPinMode(' + pin.key + '): ' + ex); } } - return(mode); + return (mode); }; -exports.setPinMode = function(pin, pinData, template, resp) { +var setPinMode = function (pin, pinData, template, resp) { var muxFile = '/sys/kernel/debug/omap_mux/' + pin.mux; var n = pin.gpio; - + try { var fd = fs.openSync(muxFile, 'w'); fs.writeSync(fd, pinData.toString(16), null); - } catch(ex) { + } catch (ex) { resp.err = 'Error writing to ' + muxFile + ': ' + ex; - return(resp); + return (resp); } - if(template == 'bspm') { + if (template == 'bspm') { gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(pin.led) { + if (pin.led) { gpioFile[pin.key] = '/sys/class/leds/beaglebone::' + pin.led + '/brightness'; } - } else if(template == 'bspwm') { + } else if (template == 'bspwm') { resp.path = '/sys/class/pwm/' + pin.pwm.path; var path = resp.path; pwmPrefix[pin.pwm.name] = path; // Clear up any unmanaged usage - fs.writeFileSync(path+'/request', '0'); + fs.writeFileSync(path + '/request', '0'); // Allocate and configure the PWM - fs.writeFileSync(path+'/request', '1'); - fs.writeFileSync(path+'/period_freq', '0'); - fs.writeFileSync(path+'/polarity', '0'); - fs.writeFileSync(path+'/run', '1'); + fs.writeFileSync(path + '/request', '1'); + fs.writeFileSync(path + '/period_freq', '0'); + fs.writeFileSync(path + '/polarity', '0'); + fs.writeFileSync(path + '/run', '1'); } - return(resp); + return (resp); }; -exports.setLEDPinToGPIO = function(pin, resp) { +var setLEDPinToGPIO = function (pin, resp) { var path = "/sys/class/leds/beaglebone::" + pin.led + "/trigger"; - if(my.file_existsSync(path)) { + if (my.file_existsSync(path)) { fs.writeFileSync(path, "gpio"); } else { resp.err = "Unable to find LED: " + pin.led; @@ -102,45 +102,45 @@ exports.setLEDPinToGPIO = function(pin, resp) { resp.value = false; } - return(resp); + return (resp); }; -exports.exportGPIOControls = hw_capemgr.exportGPIOControls; +var exportGPIOControls = hw_capemgr.exportGPIOControls; -exports.writeGPIOValue = function(pin, value, callback) { - if(typeof gpioFile[pin.key] == 'undefined') { +var writeGPIOValue = function (pin, value, callback) { + if (typeof gpioFile[pin.key] == 'undefined') { gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(pin.led) { + if (pin.led) { gpioFile[pin.key] = "/sys/class/leds/beaglebone:"; gpioFile[pin.key] += ":" + pin.led + "/brightness"; } - if(!my.file_existsSync(gpioFile[pin.key])) { + if (!my.file_existsSync(gpioFile[pin.key])) { winston.error("Unable to find gpio: " + gpioFile[pin.key]); } } - if(debug) winston.debug("gpioFile = " + gpioFile[pin.key]); - if(callback) { + if (debug) winston.debug("gpioFile = " + gpioFile[pin.key]); + if (callback) { fs.writeFile(gpioFile[pin.key], '' + value, null, callback); } else { try { fs.writeFileSync(gpioFile[pin.key], '' + value, null); - } catch(ex) { + } catch (ex) { winston.error("Unable to write to " + gpioFile[pin.key]); } } }; -exports.readGPIOValue = hw_capemgr.readGPIOValue; +var readGPIOValue = hw_capemgr.readGPIOValue; -exports.enableAIN = function() { - return(true); +var enableAIN = function () { + return (true); }; -exports.readAIN = function(pin, resp, callback) { +var readAIN = function (pin, resp, callback) { var ainFile = '/sys/bus/platform/devices/tsc/ain' + (pin.ain + 1).toString(); - if(callback) { - var readFile = function(err, data) { - if(err) { + if (callback) { + var readFile = function (err, data) { + if (err) { resp.err = 'analogRead error: ' + err; winston.error(resp.err); } @@ -148,46 +148,74 @@ exports.readAIN = function(pin, resp, callback) { callback(resp); }; fs.readFile(ainFile, readFile); - return(resp); + return (resp); } resp.value = parseInt(fs.readFileSync(ainFile), 10); - if(isNaN(resp.value)) { + if (isNaN(resp.value)) { resp.err = 'analogRead(' + pin.key + ') returned ' + resp.value; winston.error(resp.err); } resp.value = resp.value / 4096; - if(isNaN(resp.value)) { + if (isNaN(resp.value)) { resp.err = 'analogRead(' + pin.key + ') scaled to ' + resp.value; } - return(resp); + return (resp); }; -exports.writeGPIOEdge = hw_capemgr.writeGPIOEdge; +var writeGPIOEdge = hw_capemgr.writeGPIOEdge; -exports.writePWMFreqAndValue = function(pin, pwm, freq, value, resp) { +var writePWMFreqAndValue = function (pin, pwm, freq, value, resp) { var path = pwmPrefix[pin.pwm.name]; - if(pwm.freq != freq) { - fs.writeFileSync(path+'/run', '0'); - fs.writeFileSync(path+'/duty_percent', '0'); - fs.writeFileSync(path+'/period_freq', Math.round(freq)); - fs.writeFileSync(path+'/run', '1'); + if (pwm.freq != freq) { + fs.writeFileSync(path + '/run', '0'); + fs.writeFileSync(path + '/duty_percent', '0'); + fs.writeFileSync(path + '/period_freq', Math.round(freq)); + fs.writeFileSync(path + '/run', '1'); } - fs.writeFileSync(path+'/duty_percent', Math.round(value*100)); - return(resp); + fs.writeFileSync(path + '/duty_percent', Math.round(value * 100)); + return (resp); }; -exports.readEeproms = function(eeproms) { +var readEeproms = function (eeproms) { var EepromFiles = { - '/sys/bus/i2c/drivers/at24/1-0050/eeprom': { type: 'bone' }, - '/sys/bus/i2c/drivers/at24/3-0054/eeprom': { type: 'cape' }, - '/sys/bus/i2c/drivers/at24/3-0055/eeprom': { type: 'cape' }, - '/sys/bus/i2c/drivers/at24/3-0056/eeprom': { type: 'cape' }, - '/sys/bus/i2c/drivers/at24/3-0057/eeprom': { type: 'cape' } + '/sys/bus/i2c/drivers/at24/1-0050/eeprom': { + type: 'bone' + }, + '/sys/bus/i2c/drivers/at24/3-0054/eeprom': { + type: 'cape' + }, + '/sys/bus/i2c/drivers/at24/3-0055/eeprom': { + type: 'cape' + }, + '/sys/bus/i2c/drivers/at24/3-0056/eeprom': { + type: 'cape' + }, + '/sys/bus/i2c/drivers/at24/3-0057/eeprom': { + type: 'cape' + } }; eeproms = eeprom.readEeproms(EepromFiles); - return(eeproms); + return (eeproms); }; -exports.readPlatform = function(platform) { - return(platform); +var readPlatform = function (platform) { + return (platform); }; + +module.exports = { + logfile: logfile, + readPWMFreqAndValue: readPWMFreqAndValue, + readGPIODirection: readGPIODirection, + readPinMux: readPinMux, + setPinMode: setPinMode, + setLEDPinToGPIO: setLEDPinToGPIO, + exportGPIOControls: exportGPIOControls, + writeGPIOValue: writeGPIOValue, + readGPIOValue: readGPIOValue, + enableAIN: enableAIN, + readAIN: readAIN, + writeGPIOEdge: writeGPIOEdge, + writePWMFreqAndValue: writePWMFreqAndValue, + readEeproms: readEeproms, + readPlatform: readPlatform +} \ No newline at end of file diff --git a/src/hw_simulator.js b/src/hw_simulator.js index 3285e2bf..00328e82 100644 --- a/src/hw_simulator.js +++ b/src/hw_simulator.js @@ -3,96 +3,106 @@ var winston = require('winston'); var gpioFile = {}; -exports.logfile = 'bonescript.log'; -exports.readPWMFreqAndValue = function(pin, pwm) { +var logfile = 'bonescript.log'; +var readPWMFreqAndValue = function (pin, pwm) { winston.info('readPWMFreqAndValue(' + [pin.key, pwm.key] + ')'); var mode = {}; mode.freq = pwm.freq; mode.value = pwm.value; - return(mode); + return (mode); }; -exports.readGPIODirection = function(n, gpio) { +var readGPIODirection = function (n, gpio) { winston.info('readGPIODirection(' + [n] + ')'); var mode = {}; - if(typeof gpio[n] != 'undefined') { - if(gpio[n].active) { + if (typeof gpio[n] != 'undefined') { + if (gpio[n].active) { mode.active = true; } else { mode.active = false; } mode.direction = gpio[n].direction; } - return(mode); + return (mode); }; -exports.readPinMux = function(pin, mode, callback) { +var readPinMux = function (pin, mode, callback) { winston.info('readPinMux(' + [pin.key] + ')'); - if(callback) { - callback(mode); + if (callback) { + if (callback.length == 1) + callback(mode); + else + callback(null, mode); } - return(mode); + return (mode); }; -exports.setPinMode = function(pin, pinData, template, resp) { +var setPinMode = function (pin, pinData, template, resp) { winston.info('setPinMode(' + [pin.key, pinData, template] + ')'); gpioFile[pin.key] = true; - return(resp); + return (resp); }; -exports.setLEDPinToGPIO = function(pin, resp) { +var setLEDPinToGPIO = function (pin, resp) { winston.info('setLEDPinToGPIO(' + [pin.key] + ')'); - return(resp); + return (resp); }; -exports.exportGPIOControls = function(pin, direction, resp) { +var exportGPIOControls = function (pin, direction, resp) { winston.info('expertGPIOControls(' + [pin.key, direction] + ')'); - return(resp); + return (resp); }; -exports.writeGPIOValue = function(pin, value, callback) { +var writeGPIOValue = function (pin, value, callback) { winston.info('writeGPIOValue(' + [pin.key, value] + ')'); - if(callback) { + if (callback) { callback(); } }; -exports.readGPIOValue = function(pin, resp, callback) { +var readGPIOValue = function (pin, resp, callback) { winston.info('readGPIOValue(' + [pin.key] + ')'); - if(callback) { - callback(0); - return(true); + if (callback) { + resp.value = 0; + if (callback.length == 1) + callback(resp); + else + callback(null, resp.value); + return (true); } resp.value = 0; - return(resp); + return (resp); }; -exports.enableAIN = function() { +var enableAIN = function () { winston.info('enableAIN()'); - return(true); + return (true); }; -exports.readAIN = function(pin, resp, callback) { +var readAIN = function (pin, resp, callback) { winston.info('readAIN(' + [pin.key] + ')'); resp.value = 0; - if(callback) { - callback(resp); + if (callback) { + if (callback.length == 1) + callback(resp); + else + callback(null, resp.value); } - return(resp); + return (resp); }; -exports.writeGPIOEdge = function(pin, mode) { +var writeGPIOEdge = function (pin, mode) { winston.info('writeGPIOEdge(' + [pin.key, mode] + ')'); var resp = {}; - return(resp); + return (resp); }; -exports.writePWMFreqAndValue = function(pin, pwm, freq, value, resp) { +var writePWMFreqAndValue = function (pin, pwm, freq, value, resp) { winston.info('writePWMFreqAndValue(' + [pin.key, pwm.name, freq, value] + ')'); - return(resp); + return (resp); }; -exports.readEeproms = function(eeproms) { +var readEeproms = function (eeproms) { winston.info('readEeproms()'); var boardName = 'A335BNLT'; var version = ''; @@ -101,11 +111,29 @@ exports.readEeproms = function(eeproms) { eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'].boardName = boardName; eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'].version = version; eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'].serialNumber = serialNumber; - return(eeproms); + return (eeproms); }; -exports.readPlatform = function(platform) { +var readPlatform = function (platform) { winston.info('readPlatform()'); platform.name = 'BeagleBone Simulator'; - return(platform); + return (platform); }; + +module.exports = { + logfile: logfile, + readPWMFreqAndValue: readPWMFreqAndValue, + readGPIODirection: readGPIODirection, + readPinMux: readPinMux, + setPinMode: setPinMode, + setLEDPinToGPIO: setLEDPinToGPIO, + exportGPIOControls: exportGPIOControls, + writeGPIOValue: writeGPIOValue, + readGPIOValue: readGPIOValue, + enableAIN: enableAIN, + readAIN: readAIN, + writeGPIOEdge: writeGPIOEdge, + writePWMFreqAndValue: writePWMFreqAndValue, + readEeproms: readEeproms, + readPlatform: readPlatform +} \ No newline at end of file diff --git a/src/hw_universal.js b/src/hw_universal.js index cbf1064b..09a04af9 100644 --- a/src/hw_universal.js +++ b/src/hw_universal.js @@ -10,92 +10,93 @@ var gpioFile = {}; var pwmPrefix = {}; var ainPrefix = ""; -exports.logfile = '/var/lib/cloud9/bonescript.log'; +var logfile = '/var/lib/cloud9/bonescript.log'; -exports.readPWMFreqAndValue = function(pin, pwm) { +var readPWMFreqAndValue = function (pin, pwm) { var mode = {}; try { - var period = fs.readFileSync(pwmPrefix[pin.pwm.name]+'/period_ns'); - var duty = fs.readFileSync(pwmPrefix[pin.pwm.name]+'/duty_ns'); + var period = fs.readFileSync(pwmPrefix[pin.pwm.name] + '/period_ns'); + var duty = fs.readFileSync(pwmPrefix[pin.pwm.name] + '/duty_ns'); mode.freq = 1.0e9 / period; mode.value = duty / period; - } catch(ex) { - } - return(mode); + } catch (ex) {} + return (mode); }; -exports.readGPIODirection = function(n, gpio) { +var readGPIODirection = function (n, gpio) { var mode = {}; var directionFile = "/sys/class/gpio/gpio" + n + "/direction"; - if(my.file_existsSync(directionFile)) { + if (my.file_existsSync(directionFile)) { mode.active = true; var direction = fs.readFileSync(directionFile, 'utf-8'); direction = direction.replace(/^\s+|\s+$/g, ''); mode.direction = direction; } - return(mode); + return (mode); }; -exports.readPinMux = function(pin, mode, callback) { +var readPinMux = function (pin, mode, callback) { var pinctrlFile = '/sys/kernel/debug/pinctrl/44e10800.pinmux/pins'; var muxRegOffset = parseInt(pin.muxRegOffset, 16); - var readPinctrl = function(err, data) { - if(err) { + var readPinctrl = function (err, data) { + if (err) { mode.err = 'readPinctrl error: ' + err; - if(debug) winston.debug(mode.err); + if (debug) winston.debug(mode.err); callback(mode); } mode = parse.modeFromPinctrl(data, muxRegOffset, 0x44e10800, mode); callback(mode); }; - var tryPinctrl = function(exists) { - if(exists) { + var tryPinctrl = function (exists) { + if (exists) { fs.readFile(pinctrlFile, 'utf8', readPinctrl); } else { - if(debug) winston.debug('getPinMode(' + pin.key + '): no valid mux data'); + if (debug) winston.debug('getPinMode(' + pin.key + '): no valid mux data'); callback(mode); } }; - if(callback) { + if (callback) { my.file_exists(pinctrlFile, tryPinctrl); } else { try { var data2 = fs.readFileSync(pinctrlFile, 'utf8'); mode = parse.modeFromPinctrl(data2, muxRegOffset, 0x44e10800, mode); - } catch(ex) { - if(debug) winston.debug('getPinMode(' + pin.key + '): ' + ex); + } catch (ex) { + if (debug) winston.debug('getPinMode(' + pin.key + '): ' + ex); } } - return(mode); + return (mode); }; -exports.setPinMode = function(pin, pinData, template, resp, callback) { - if(debug) winston.debug('hw.setPinMode(' + [pin.key, pinData, template, JSON.stringify(resp)] + ');'); +var setPinMode = function (pin, pinData, template, resp, callback) { + if (debug) winston.debug('hw.setPinMode(' + [pin.key, pinData, template, JSON.stringify(resp)] + ');'); var p = pin.key + "_pinmux"; - if(pin.universalName) p = pin.universalName + "_pinmux"; + if (pin.universalName) p = pin.universalName + "_pinmux"; var pinmux = my.find_sysfsFile(p, my.is_ocp(), p + '.'); - if(!pinmux) { throw p + " was not found under " + my.is_ocp(); } - if((pinData & 7) == 7) { + if (!pinmux) { + throw p + " was not found under " + my.is_ocp(); + } + if ((pinData & 7) == 7) { gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - fs.writeFileSync(pinmux+"/state", 'gpio'); - } else if(template == 'bspwm') { - fs.writeFileSync(pinmux+"/state", 'pwm'); + fs.writeFileSync(pinmux + "/state", 'gpio'); + } else if (template == 'bspwm') { + fs.writeFileSync(pinmux + "/state", 'pwm'); pwmPrefix[pin.pwm.name] = '/sys/class/pwm/pwm' + pin.pwm.sysfs; - if(!my.file_existsSync(pwmPrefix[pin.pwm.name])) { + if (!my.file_existsSync(pwmPrefix[pin.pwm.name])) { fs.appendFileSync('/sys/class/pwm/export', pin.pwm.sysfs); } - fs.appendFileSync(pwmPrefix[pin.pwm.name]+'/run', 1); + fs.appendFileSync(pwmPrefix[pin.pwm.name] + '/run', 1); } else { resp.err = 'Unknown pin mode template'; } - if(callback) callback(resp); - return(resp); + if (callback) callback(resp); + return (resp); }; -exports.setLEDPinToGPIO = function(pin, resp) { +var setLEDPinToGPIO = function (pin, resp) { var path = "/sys/class/leds/beaglebone:green:" + pin.led + "/trigger"; - if(my.file_existsSync(path)) { + if (my.file_existsSync(path)) { fs.writeFileSync(path, "gpio"); } else { resp.err = "Unable to find LED " + pin.led; @@ -103,53 +104,53 @@ exports.setLEDPinToGPIO = function(pin, resp) { resp.value = false; } - return(resp); + return (resp); }; -exports.exportGPIOControls = function(pin, direction, resp, callback) { - if(debug) winston.debug('hw.exportGPIOControls(' + [pin.key, direction, resp] + ');'); +var exportGPIOControls = function (pin, direction, resp, callback) { + if (debug) winston.debug('hw.exportGPIOControls(' + [pin.key, direction, resp] + ');'); var n = pin.gpio; var exists = my.file_existsSync(gpioFile[pin.key]); - - if(!exists) { - if(debug) winston.debug("exporting gpio: " + n); + + if (!exists) { + if (debug) winston.debug("exporting gpio: " + n); fs.writeFileSync("/sys/class/gpio/export", "" + n, null); } var directionFile = "/sys/class/gpio/gpio" + n + "/direction"; - if(debug) winston.debug('Writing GPIO direction(' + direction + ') to ' + + if (debug) winston.debug('Writing GPIO direction(' + direction + ') to ' + directionFile + ');'); fs.writeFileSync(directionFile, direction); - return(resp); + return (resp); }; -exports.writeGPIOValue = function(pin, value, callback) { - if(typeof gpioFile[pin.key] == 'undefined') { +var writeGPIOValue = function (pin, value, callback) { + if (typeof gpioFile[pin.key] == 'undefined') { gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(pin.led) { + if (pin.led) { gpioFile[pin.key] = "/sys/class/leds/beaglebone:"; gpioFile[pin.key] += "green:" + pin.led + "/brightness"; } - if(!my.file_existsSync(gpioFile[pin.key])) { + if (!my.file_existsSync(gpioFile[pin.key])) { winston.error("Unable to find gpio: " + gpioFile[pin.key]); } } - if(debug) winston.debug("gpioFile = " + gpioFile[pin.key]); - if(callback) { + if (debug) winston.debug("gpioFile = " + gpioFile[pin.key]); + if (callback) { fs.writeFile(gpioFile[pin.key], '' + value, null, callback); } else { try { fs.writeFileSync(gpioFile[pin.key], '' + value, null); - } catch(ex) { + } catch (ex) { winston.error("Unable to write to " + gpioFile[pin.key]); } } }; -exports.readGPIOValue = function(pin, resp, callback) { +var readGPIOValue = function (pin, resp, callback) { var gpioFile = '/sys/class/gpio/gpio' + pin.gpio + '/value'; - if(callback) { - var readFile = function(err, data) { - if(err) { + if (callback) { + var readFile = function (err, data) { + if (err) { resp.err = 'digitalRead error: ' + err; winston.error(resp.err); } @@ -157,36 +158,38 @@ exports.readGPIOValue = function(pin, resp, callback) { callback(resp); }; fs.readFile(gpioFile, readFile); - return(true); + return (true); } resp.value = parseInt(fs.readFileSync(gpioFile), 2); - return(resp); + return (resp); }; -exports.enableAIN = function(callback) { +var enableAIN = function (callback) { var helper = ""; - if(my.load_dt('cape-bone-iio')) { + if (my.load_dt('cape-bone-iio')) { var ocp = my.is_ocp(); - if(ocp) { + if (ocp) { helper = my.find_sysfsFile('helper', ocp, 'helper.'); - if(helper) { + if (helper) { ainPrefix = helper + '/AIN'; } } } else { - if(debug) winston.debug('enableAIN: load of cape-bone-iio failed'); + if (debug) winston.debug('enableAIN: load of cape-bone-iio failed'); } - if(callback) { - callback({'path': helper}) + if (callback) { + callback({ + 'path': helper + }) } - return(helper.length > 1); + return (helper.length > 1); }; -exports.readAIN = function(pin, resp, callback) { +var readAIN = function (pin, resp, callback) { var ainFile = ainPrefix + pin.ain.toString(); - if(callback) { - var readFile = function(err, data) { - if(err) { + if (callback) { + var readFile = function (err, data) { + if (err) { resp.err = 'analogRead error: ' + err; winston.error(resp.err); } @@ -194,22 +197,22 @@ exports.readAIN = function(pin, resp, callback) { callback(resp); }; fs.readFile(ainFile, readFile); - return(resp); + return (resp); } resp.value = parseInt(fs.readFileSync(ainFile), 10); - if(isNaN(resp.value)) { + if (isNaN(resp.value)) { resp.err = 'analogRead(' + pin.key + ') returned ' + resp.value; winston.error(resp.err); } resp.value = resp.value / 1800; - if(isNaN(resp.value)) { + if (isNaN(resp.value)) { resp.err = 'analogRead(' + pin.key + ') scaled to ' + resp.value; winston.error(resp.err); } - return(resp); + return (resp); }; -exports.writeGPIOEdge = function(pin, mode) { +var writeGPIOEdge = function (pin, mode) { fs.writeFileSync('/sys/class/gpio/gpio' + pin.gpio + '/edge', mode); var resp = {}; @@ -217,66 +220,95 @@ exports.writeGPIOEdge = function(pin, mode) { resp.valuefd = fs.openSync(resp.gpioFile, 'r'); resp.value = new Buffer(1); - return(resp); + return (resp); }; -exports.writePWMFreqAndValue = function(pin, pwm, freq, value, resp, callback) { - if(debug) winston.debug('hw.writePWMFreqAndValue(' + [pin.key,pwm,freq,value,resp] + ');'); +var writePWMFreqAndValue = function (pin, pwm, freq, value, resp, callback) { + if (debug) winston.debug('hw.writePWMFreqAndValue(' + [pin.key, pwm, freq, value, resp] + ');'); var path = pwmPrefix[pin.pwm.name]; try { - var period = Math.round( 1.0e9 / freq ); // period in ns - if(pwm.freq != freq) { - if(debug) winston.debug('Stopping PWM'); - fs.writeFileSync(path+'/run', "0\n"); - if(debug) winston.debug('Setting duty to 0'); - fs.writeFileSync(path+'/duty_ns', "0\n"); + var period = Math.round(1.0e9 / freq); // period in ns + if (pwm.freq != freq) { + if (debug) winston.debug('Stopping PWM'); + fs.writeFileSync(path + '/run', "0\n"); + if (debug) winston.debug('Setting duty to 0'); + fs.writeFileSync(path + '/duty_ns', "0\n"); try { - if(debug) winston.debug('Updating PWM period: ' + period); - fs.writeFileSync(path+'/period_ns', period + "\n"); - } catch(ex2) { - period = fs.readFileSync(path+'/period_ns'); + if (debug) winston.debug('Updating PWM period: ' + period); + fs.writeFileSync(path + '/period_ns', period + "\n"); + } catch (ex2) { + period = fs.readFileSync(path + '/period_ns'); winston.info('Unable to update PWM period, period is set to ' + period); } - if(debug) winston.debug('Starting PWM'); - fs.writeFileSync(path+'/run', "1\n"); + if (debug) winston.debug('Starting PWM'); + fs.writeFileSync(path + '/run', "1\n"); } - var duty = Math.round( period * value ); - if(debug) winston.debug('Updating PWM duty: ' + duty); + var duty = Math.round(period * value); + if (debug) winston.debug('Updating PWM duty: ' + duty); //if(duty == 0) winston.error('Updating PWM duty: ' + duty); - fs.writeFileSync(path+'/duty_ns', duty + "\n"); - } catch(ex) { + fs.writeFileSync(path + '/duty_ns', duty + "\n"); + } catch (ex) { resp.err = 'error updating PWM freq and value: ' + path + ', ' + ex; winston.error(resp.err); } - return(resp); + return (resp); }; -exports.readEeproms = function(eeproms) { +var readEeproms = function (eeproms) { var EepromFiles = { - '/sys/bus/i2c/drivers/at24/0-0050/eeprom': { type: 'bone' }, - '/sys/bus/i2c/drivers/at24/2-0054/eeprom': { type: 'cape' }, - '/sys/bus/i2c/drivers/at24/2-0055/eeprom': { type: 'cape' }, - '/sys/bus/i2c/drivers/at24/2-0056/eeprom': { type: 'cape' }, - '/sys/bus/i2c/drivers/at24/2-0057/eeprom': { type: 'cape' } + '/sys/bus/i2c/drivers/at24/0-0050/eeprom': { + type: 'bone' + }, + '/sys/bus/i2c/drivers/at24/2-0054/eeprom': { + type: 'cape' + }, + '/sys/bus/i2c/drivers/at24/2-0055/eeprom': { + type: 'cape' + }, + '/sys/bus/i2c/drivers/at24/2-0056/eeprom': { + type: 'cape' + }, + '/sys/bus/i2c/drivers/at24/2-0057/eeprom': { + type: 'cape' + } }; eeproms = eeprom.readEeproms(EepromFiles); - return(eeproms); + return (eeproms); }; -exports.readPlatform = function(platform) { +var readPlatform = function (platform) { var eeproms = eeprom.readEeproms({ - '/sys/bus/i2c/drivers/at24/0-0050/eeprom': { type: 'bone' } + '/sys/bus/i2c/drivers/at24/0-0050/eeprom': { + type: 'bone' + } }); var x = eeproms['/sys/bus/i2c/drivers/at24/0-0050/eeprom']; - if(x.boardName == 'A335BONE') platform.name = 'BeagleBone'; - if(x.boardName == 'A335BNLT') platform.name = 'BeagleBone Black'; + if (x.boardName == 'A335BONE') platform.name = 'BeagleBone'; + if (x.boardName == 'A335BNLT') platform.name = 'BeagleBone Black'; platform.version = x.version; - if(!platform.version.match(/^[\040-\176]*$/)) delete platform.version; + if (!platform.version.match(/^[\040-\176]*$/)) delete platform.version; platform.serialNumber = x.serialNumber; - if(!platform.serialNumber.match(/^[\040-\176]*$/)) delete platform.serialNumber; + if (!platform.serialNumber.match(/^[\040-\176]*$/)) delete platform.serialNumber; try { platform.dogtag = fs.readFileSync('/etc/dogtag', 'ascii'); - } catch(ex) { - } - return(platform); + } catch (ex) {} + return (platform); }; + +module.exports = { + logfile: logfile, + readPWMFreqAndValue: readPWMFreqAndValue, + readGPIODirection: readGPIODirection, + readPinMux: readPinMux, + setPinMode: setPinMode, + setLEDPinToGPIO: setLEDPinToGPIO, + exportGPIOControls: exportGPIOControls, + writeGPIOValue: writeGPIOValue, + readGPIOValue: readGPIOValue, + enableAIN: enableAIN, + readAIN: readAIN, + writeGPIOEdge: writeGPIOEdge, + writePWMFreqAndValue: writePWMFreqAndValue, + readEeproms: readEeproms, + readPlatform: readPlatform +} \ No newline at end of file diff --git a/src/iic.js b/src/iic.js index 560906cc..94c21007 100644 --- a/src/iic.js +++ b/src/iic.js @@ -10,19 +10,21 @@ m.events = { 'data': ['data'] }; m.openPorts = {}; -m.doOpen = function(args) { +m.doOpen = function (args) { var path = args.port[0]; - if(m.ports[args.port[0]].path) path = m.ports[args.port[0]].path; - if(typeof args.options !== typeof {}) args.options = {}; + if (m.ports[args.port[0]].path) path = m.ports[args.port[0]].path; + if (typeof args.options !== typeof {}) args.options = {}; args.options.device = path; var openPort = new m.module(args.port[1], args.options); - return(openPort); + return (openPort); }; -exports.i2cOpen = my.wrapOpen(m, ['options']); -exports.i2cScan = my.wrapCall(m, 'scan', [], ['err', 'data']); -exports.i2cWriteByte = my.wrapCall(m, 'writeByte', ['byte'], ['err']); -exports.i2cWriteBytes = my.wrapCall(m, 'writeBytes', ['command', 'bytes'], ['err']); -exports.i2cReadByte = my.wrapCall(m, 'readByte', [], ['err', 'res']); -exports.i2cReadBytes = my.wrapCall(m, 'readBytes', ['command', 'length'], ['err', 'res']); -exports.i2cStream = my.wrapCall(m, 'stream', ['command', 'length', 'delay'], []); +module.exports = { + i2cOpen: my.wrapOpen(m, ['options']), + i2cScan: my.wrapCall(m, 'scan', [], ['err', 'data']), + i2cWriteByte: my.wrapCall(m, 'writeByte', ['byte'], ['err']), + i2cWriteBytes: my.wrapCall(m, 'writeBytes', ['command', 'bytes'], ['err']), + i2cReadByte: my.wrapCall(m, 'readByte', [], ['err', 'res']), + i2cReadBytes: my.wrapCall(m, 'readBytes', ['command', 'length'], ['err', 'res']), + i2cStream: my.wrapCall(m, 'stream', ['command', 'length', 'delay'], []) +} \ No newline at end of file diff --git a/src/index.d.ts b/src/index.d.ts new file mode 100644 index 00000000..9d1400ca --- /dev/null +++ b/src/index.d.ts @@ -0,0 +1,274 @@ +// Type definitions for bonescript 0.6 +// Project: https://github.com/jadonk/bonescript +// Definitions by: Troy W. +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +import * as SerialPort from 'serialport'; +import * as VError from 'verror'; + +// OBJECTS +export const bone: BoneObj; + +// FUNCTIONS - TODO obliterate all "any" types where possible! --- TWW +// https://github.com/jadonk/bonescript#system + +export function getPlatform(callback?: (error: ErrorType, platform: PlatformObj) => void): any; + +export function echo(data: string, callback?: (error: ErrorType, data: string) => void): any; + +export function readTextFile(filename: string, callback?: (error: ErrorType, data: string) => void): string; + +export function writeTextFile(filename: string, data: any, callback?: (error: ErrorType) => void): any; + +export function writeCModule(filename: string, data: any, callback?: (error: ErrorType) => void): any; + +export function setDate(date: string, callback?: (error: ErrorType) => void): any; + +export function analogRead(pin: string, callback?: (err: ErrorType, value: number) => void): any; + +export function analogWrite(pin: string, value: number, freq?: number, callback?: ErrorCb): any; + +export function attachInterrupt( + pin: string, + handler: InterruptFn, + mode: InterruptType, + callback?: AttachIntCb +): any; + +export function detachInterrupt(pin: string, callback?: DetachIntCb): any; + +export function digitalRead(pin: string, callback?: (err: ErrorType, value: number) => void): any; + +export function digitalWrite(pin: string, value: PinStateType, callback?: DigitalWriteCb): any; + +export function pinMode( + pin: string, + direction: 'in' | 'out' | 'analog_out' | 'in_pullup', + mux?: string, + pullup?: 'disabled' | 'pullup' | 'pulldown', + slew?: 'fast' | 'slow', + callback?: PinModeCb +): any; + +export function getPinMode(pin: string, callback?: (err: ErrorType, mode: PinModeObj) => void): any; + +export function shiftOut(dataPin: string, clockPin: string, bitOrder: BitOrderType, val: number, callback?: ErrorCb): any; + +// https://github.com/jadonk/bonescript#serial +export function serialOpen(port: any, options: any, callback?: ErrorCb): any; + +export function serialWrite(port: any, data: any, callback?: ErrorCb): any; + +export const serialParsers: typeof SerialPort.parsers; + +export function i2cOpen(port: any, address: any, options: any, callback?: ErrorCb): any; + +export function i2cScan(port: any, callback?: ErrorCb): any; + +export function i2cWriteByte(port: any, byte: any, callback?: ErrorCb): any; + +export function i2cWriteBytes(port: any, command: any, bytes: any, callback?: ErrorCb): any; + +export function i2cReadByte(port: any, callback?: ErrorCb): any; + +export function i2cReadBytes(port: any, command: any, length: any, callback?: ErrorCb): any; + +export function i2cStream(port: any, command: any, length: any, callback?: ErrorCb): any; +// ffi +export function loadCModule(filename: string, data: any, isMRAA?: boolean): any; + +export function lowByte(value: number): number; + +export function highByte(value: number): number; + +export function bitRead(value: number, bitnum: number): number; + +export function bitWrite(value: number, bitnum: number, bitdata: any): number; + +export function bitSet(value: number, bitnum: number): number; + +export function bitClear(value: number, bitnum: number): number; + +export function bit(bitnum: number): number; + +export function min(x: number, y: number): number; + +export function max(x: number, y: number): number; + +export function abs(x: number): number; + +export function constrain(x: number, a: number, b: number): number; + +export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number; + +export function pow(x: number, y: number): number; + +export function sqrt(x: number): number; + +export function sin(radians: number): number; + +export function cos(radians: number): number; + +export function tan(radians: number): number; + +export function randomSeed(x: number): void; + +export function random(min: number, max?: number): number; + +export function delay(...args: any[]): any; + +export function autorun(...args: any[]): any; + +export function serverStart(...args: any[]): any; + +export function socketJSReqHandler(...args: any[]): any; + +export function addSocketListeners(...args: any[]): any; + +export function setGlobals(...args: any[]): any; + +// CONSTANTS +export const OUTPUT: 'out'; +export const INPUT: 'in'; +export const INPUT_PULLUP: 'in_pullup'; +export const ANALOG_OUTPUT: 'analog_out'; +export const HIGH: 1; +export const LOW: 0; +export const LSBFIRST: 1; +export const MSBFIRST: 0; +export const CHANGE: 'both'; +export const RISING: 'rising'; +export const FALLING: 'falling'; + +// INTERFACES - adjusted based on observation / testing +interface PlatformObj { + name: string; + platform: BoneObj; + bonescript: string; + serialNumber?: string; + dogtag?: string; + os: { + hostname: string, + type: string, + arch: string, + release: string, + uptime: number, + loadavg: number[], + totalmem: number, + freemem: number, + networkInterfaces?: any + }; +} + +export interface PinModeObj { + gpio?: { + active: boolean, + direction: 'in' | 'out', + allocated: boolean, + }; + modes: string[]; + mux?: number; + name: string; + pin: string; + pinState: string; + pullup?: 'disabled' | 'pullup' | 'pulldown'; + pwm?: { + freq: number, + value: number, + }; + rx?: 'enabled' | 'disabled'; + slew?: 'fast' | 'slow'; +} + +interface BoneObj { + i2c: i2cObj; + uarts: UartsObj; + getPinKeys(): string[]; + getPinObjects(): any; + naturalCompare(): any; +} + +interface PinsObj { + [i: string]: PinInfo; +} + +interface UartsObj { + [i: string]: UartInfo; +} + +interface i2cObj { + [i: string]: i2cInfo; +} + +export interface PinInfo { + // Analog In + ain?: number; + // GPIO / LEDs / Analog In + eeprom?: number; + // GPIO / LEDs + gpio?: number; + key: string; + // LEDs + led?: string; + mux?: string; + muxRegOffset?: string; + // All + name: string; + options?: string[]; + // PWM + pwm?: PwmInfo; + scale?: number; + universalName?: string; +} + +interface PwmInfo { + addr: string; + chip: string; + index: number; + module: string; + muxmode: number; + name: string; + path: string; + sysfs: number; +} + +interface UartInfo { + devicetree?: string; + rx?: string; + tx?: string; +} + +interface i2cInfo { + devicetree?: string; + path?: string; + scl?: string; + sda?: string; +} + +// TYPES - adjusted based on observation / testing +type PinStateType = typeof HIGH | typeof LOW; +type PinModeType = typeof ANALOG_OUTPUT | typeof INPUT | typeof INPUT_PULLUP | typeof OUTPUT; +type InterruptType = typeof RISING | typeof FALLING | typeof CHANGE; +type BitOrderType = typeof LSBFIRST | typeof MSBFIRST; +type ErrorCb = (err: ErrorType) => void; +type InterruptFn = (resp: { + pin: PinInfo, + value: number +}) => void; +type AttachIntCb = (resp: { + pin: PinInfo, + attached: boolean +}) => void; +type DetachIntCb = (resp: { + pin: PinInfo, + detached: boolean +}) => void; +type PinModeCb = (resp: { + value: number, + err: VError +}) => void; +type DigitalWriteCb = (resp: { + data: any, + err: VError +}) => void; +type ErrorType = VError; diff --git a/src/index.js b/src/index.js index 94180daa..baf7b301 100644 --- a/src/index.js +++ b/src/index.js @@ -5,8 +5,8 @@ var fs = require('fs'); var child_process = require('child_process'); var winston = require('winston'); var os = require('os'); -var bone = require('./bone'); // Database of pins -var functions = require('./functions'); // functions.js defines several math/bit functions that are handy +var bone = require('./bone'); // Database of pins +var functions = require('./functions'); // functions.js defines several math/bit functions that are handy var serial = require('./serial'); var iic = require('./iic'); var my = require('./my'); @@ -17,41 +17,42 @@ var epoll = my.require('epoll'); var autorun = require('./autorun'); var server = require('./server'); var socketHandlers = require('./socket_handlers'); +var ffi = require('./ffiimp'); var rc = require('./rc'); var debug = process.env.DEBUG ? true : false; // Detect if we are on a Beagle var hw; -if(os.type() == 'Linux' && os.arch() == 'arm') { +if (os.type() == 'Linux' && os.arch() == 'arm') { var osVer = ("" + os.release()).split('.'); - console.log(osVer.join(":")); - if(my.is_new_capemgr() || osVer[0] > 4 || - (osVer[0] == 4 && osVer[1] >= 4)) { + if (debug) console.log(osVer.join(":")); + if (my.is_new_capemgr() || osVer[0] > 4 || + (osVer[0] == 4 && osVer[1] >= 4)) { // Used for 4.4+ kernels using capemgr and universal helpers hw = require('./hw_mainline'); - if(debug) console.log('Using Mainline interface'); - } else if(my.is_cape_universal()) { + if (debug) console.log('Using Mainline interface'); + } else if (my.is_cape_universal()) { // Used for 3.8 kernels using a single universal overlay with pinmux helpers // located in debugfs at /sys/kernel/debug/pinctrl/44e10800.pinmux/pins hw = require('./hw_universal'); - if(debug) console.log('Using Universal Cape interface'); - } else if(my.is_capemgr()) { + if (debug) console.log('Using Universal Cape interface'); + } else if (my.is_capemgr()) { // Used for 3.8 kernels using an older out-of-tree version of CapeMgr hw = require('./hw_capemgr'); - if(debug) console.log('Using CapeMgr interface'); + if (debug) console.log('Using CapeMgr interface'); } else { // Used for 3.2 kernels using /sys/kernel/debug/omap_mux/ hw = require('./hw_oldkernel'); - if(debug) console.log('Using 3.2 kernel interface'); + if (debug) console.log('Using 3.2 kernel interface'); } } else { // Incomplete implementation of a set of hardware stubs to run on non BeagleBone targets hw = require('./hw_simulator'); - if(debug) winston.debug('Using simulator mode'); + if (debug) winston.debug('Using simulator mode'); } -if(debug) { +if (debug) { winston.add(winston.transports.File, { filename: hw.logfile, level: 'debug' @@ -61,7 +62,7 @@ if(debug) { winston.setLevels(winston.config.syslog.levels); } -if(debug) winston.debug('index.js loaded'); +if (debug) winston.debug('index.js loaded'); var f = {}; @@ -86,26 +87,31 @@ var ain = false; // active: GPIO is enabled by the kernel // allocated: boolean for if it is allocated by this application // direction: 'in' or 'out' (allocated might be false) -f.getPinMode = function(pin, callback) { +f.getPinMode = function (pin, callback) { pin = my.getpin(pin); - if(debug) winston.debug('getPinMode(' + pin.key + ');'); - var mode = {'pin': pin.key, 'name': pin.name}; - if(pin.options) mode.options = pin.options; + if (debug) winston.debug('getPinMode(' + pin.key + ');'); + var mode = { + 'pin': pin.key, + 'name': pin.name + }; + if (pin.options) mode.options = pin.options; // Get PWM settings if applicable - if( - (typeof pin.pwm != 'undefined') // pin has PWM capabilities - && (typeof pwm[pin.pwm.name] != 'undefined') // PWM used for this pin is enabled - && (pin.key == pwm[pin.pwm.name].key) // PWM is allocated for this pin + if ( + (typeof pin.pwm != 'undefined') // pin has PWM capabilities + && + (typeof pwm[pin.pwm.name] != 'undefined') // PWM used for this pin is enabled + && + (pin.key == pwm[pin.pwm.name].key) // PWM is allocated for this pin ) { mode.pwm = hw.readPWMFreqAndValue(pin, pwm[pin.pwm.name]); } // Get GPIO settings if applicable - if((typeof pin.gpio != 'undefined')) { + if ((typeof pin.gpio != 'undefined')) { var n = pin.gpio; mode.gpio = hw.readGPIODirection(n, gpio); - if(typeof gpio[n] == 'undefined') { + if (typeof gpio[n] == 'undefined') { mode.gpio.allocated = false; } else { mode.gpio.allocated = true; @@ -114,62 +120,82 @@ f.getPinMode = function(pin, callback) { // Get pinmux settings mode = hw.readPinMux(pin, mode, callback); - return(mode); + return (mode); }; f.getPinMode.args = ['pin', 'callback']; -f.pinMode = function(pin, direction, mux, pullup, slew, callback) { +f.pinMode = function (pin, direction, mux, pullup, slew, callback) { pin = my.getpin(pin); - if(debug) winston.debug('pinMode(' + [pin.key, direction, mux, pullup, slew] + ');'); - if(direction == g.INPUT_PULLUP) pullup = 'pullup'; + if (debug) winston.debug('pinMode(' + [pin.key, direction, mux, pullup, slew] + ');'); + if (direction == g.INPUT_PULLUP) pullup = 'pullup'; pullup = pullup || ((direction == g.INPUT) ? 'pulldown' : 'disabled'); slew = slew || 'fast'; mux = (typeof mux != 'undefined') ? mux : 7; // default to GPIO mode - var resp = {value: true}; + var resp = { + value: true + }; var template = 'bspm'; var n = pin.gpio; - - if( - direction == g.ANALOG_OUTPUT - || mux == g.ANALOG_OUTPUT - || (typeof pin.pwm != 'undefined' && mux == pin.pwm.muxmode) + + if ( + direction == g.ANALOG_OUTPUT || + mux == g.ANALOG_OUTPUT || + (typeof pin.pwm != 'undefined' && mux == pin.pwm.muxmode) ) { - if( - (typeof pin.pwm == 'undefined') || // pin does not have PWM capability - (typeof pin.pwm.muxmode == 'undefined') // required muxmode is not provided + if ( + (typeof pin.pwm == 'undefined') || // pin does not have PWM capability + (typeof pin.pwm.muxmode == 'undefined') // required muxmode is not provided ) { var err = 'pinMode only supports ANALOG_OUTPUT for PWM pins: ' + pin.key; winston.info(err); - if(callback) callback({value:false, err:err}); - return(false); + if (callback) { //support both nodestyle and oldstyle callbacks based on arguments length + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback({ + value: false, + err: err + }); + } else + callback(err, false); + } + return (false); } direction = g.OUTPUT; mux = pin.pwm.muxmode; template = 'bspwm'; - pwm[pin.pwm.name] = {'key': pin.key, 'freq': 0}; + pwm[pin.pwm.name] = { + 'key': pin.key, + 'freq': 0 + }; } - - if(!pin.mux) { - if(debug) winston.debug('Invalid pin object for pinMode: ' + pin); - throw('Invalid pin object for pinMode: ' + pin); + + if (!pin.mux) { + winston.info('pinMode: Missing mux name for pin object: ' + JSON.stringify(pin)); } // Handle case where pin is allocated as a gpio-led - if(pin.led) { - if((direction != g.OUTPUT) || (mux != 7)) { + if (debug) winston.debug('pinMode: pin.led = ' + pin.led); + if (pin.led) { + if ((direction != g.OUTPUT) || (mux != 7)) { resp.err = 'pinMode only supports GPIO output for LEDs: ' + pin.key; winston.info(resp.err); resp.value = false; - if(callback) callback(resp); - return(false); + if (callback) callback(resp); + return (false); } resp = hw.setLEDPinToGPIO(pin, resp); - if(typeof resp.err == 'undefined') { + if (typeof resp.err == 'undefined') { gpio[n] = true; } - if(callback) callback(resp); - return(resp.value); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(resp); + } else + callback(resp.err, resp.value); + } + return (resp.value); } // Figure out the desired value @@ -178,25 +204,31 @@ f.pinMode = function(pin, direction, mux, pullup, slew, callback) { // May be required: mount -t debugfs none /sys/kernel/debug resp = hw.setPinMode(pin, pinData, template, resp); - if(typeof resp.err != 'undefined') { - if(debug) winston.debug('Unable to configure mux for pin ' + pin + ': ' + resp.err); + if (typeof resp.err != 'undefined') { + if (debug) winston.debug('Unable to configure mux for pin ' + pin + ': ' + resp.err); // It might work if the pin is already muxed to desired mode var currentMode = f.getPinMode(pin); - if(currentMode.mux != mux) { + if (currentMode.mux != mux) { resp.value = false; winston.info(resp.err); delete gpio[n]; - if(callback) callback(resp); - return(resp.value); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(resp); + } else + callback(resp.err, resp.value); + } + return (resp.value); } } - + // Enable GPIO and set direction - if(mux == 7) { + if (mux == 7) { // Export the GPIO controls - resp = hw.exportGPIOControls(pin, direction, resp); - if(typeof resp.err != 'undefined') { - if(typeof gpio[n] == 'undefined') { + resp = hw.exportGPIOControls(pin, direction, resp); + if (typeof resp.err != 'undefined') { + if (typeof gpio[n] == 'undefined') { delete gpio[n]; } } else { @@ -206,37 +238,54 @@ f.pinMode = function(pin, direction, mux, pullup, slew, callback) { delete gpio[n]; } - if(callback) callback(resp); - return(resp.value); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(resp); + } else + callback(resp.err, resp.value); + } + return (resp.value); }; f.pinMode.args = ['pin', 'direction', 'mux', 'pullup', 'slew', 'callback']; -f.digitalWrite = function(pin, value, callback) { +f.digitalWrite = function (pin, value, callback) { var myCallback = false; - if(callback) myCallback = function(resp) { - if(!resp || (typeof resp != 'object')) resp = {'data': resp}; + if (callback) myCallback = function (resp) { + if (!resp || (typeof resp != 'object')) resp = { + 'data': resp + }; callback(resp); } pin = my.getpin(pin); - if(debug) winston.debug('digitalWrite(' + [pin.key, value] + ');'); + if (debug) winston.debug('digitalWrite(' + [pin.key, value] + ');'); value = parseInt(Number(value), 2) ? 1 : 0; + //handle case digitalWrite() on Analog_Out + if (typeof pin.pwm != 'undefined') { + var gpioEnabled = (7 == f.getPinMode(pin).mux); //check whether pin set as gpio + if (!gpioEnabled) { + winston.debug([pin.key, value] + ' set as ANALOG_OUTPUT modifying duty cycle according to value'); + f.analogWrite(pin, value, 2000, myCallback); //write duty cycle as per value + return (true); + } + } hw.writeGPIOValue(pin, value, myCallback); - - return(true); + + return (true); }; f.digitalWrite.args = ['pin', 'value', 'callback']; -f.digitalRead = function(pin, callback) { +f.digitalRead = function (pin, callback) { pin = my.getpin(pin); - if(debug) winston.debug('digitalRead(' + [pin.key] + ');'); + if (debug) winston.debug('digitalRead(' + [pin.key] + ');'); var resp = {}; - if(typeof pin.ain != 'undefined') { - if(callback) { + if (typeof pin.ain != 'undefined') { + if (callback) { f.analogRead(pin, analogCallback); } else { resp.value = f.analogRead(pin); - if(resp.value >= 0.5) { + if (resp.value >= 0.5) { resp.value = g.HIGH; } else { resp.value = g.LOW; @@ -247,88 +296,94 @@ f.digitalRead = function(pin, callback) { } function analogCallback(x) { - x = analogValue(x); - callback(x); + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(analogValue(x)); + } else + callback(x.err, analogValue(x).value); } function analogValue(x) { - if(typeof x.value == 'undefined') return; - if(x.value >= 0.5) { + if (typeof x.value == 'undefined') return; + if (x.value >= 0.5) { x.value = g.HIGH; } else { x.value = g.LOW; } + return x; } - - return(resp.value); + + return (resp.value); }; f.digitalRead.args = ['pin', 'callback']; -f.analogRead = function(pin, callback) { +f.analogRead = function (pin, callback) { pin = my.getpin(pin); - if(debug) winston.debug('analogRead(' + [pin.key] + ');'); + if (debug) winston.debug('analogRead(' + [pin.key] + ');'); var resp = {}; - if(!ain) { + if (!ain) { ain = hw.enableAIN(); } - if(typeof pin.ain == 'undefined') { + if (typeof pin.ain == 'undefined') { resp.value = f.digitalRead(pin, callback); } else { resp = hw.readAIN(pin, resp, callback); } - - return(resp.value); -}; + + return (resp.value); +}; f.analogRead.args = ['pin', 'callback']; -f.shiftOut = function(dataPin, clockPin, bitOrder, val, callback) { +f.shiftOut = function (dataPin, clockPin, bitOrder, val, callback) { dataPin = my.getpin(dataPin); clockPin = my.getpin(clockPin); - if(debug) winston.debug('shiftOut(' + [dataPin.key, clockPin.key, bitOrder, val] + ');'); + if (debug) winston.debug('shiftOut(' + [dataPin.key, clockPin.key, bitOrder, val] + ');'); var i = 0; var bit; var clock = 0; function next(err) { - if(debug) winston.debug('i = ' + i); - if(debug) winston.debug('clock = ' + clock); - if(err || i == 8) { - callback({'err': err}); + if (debug) winston.debug('i = ' + i); + if (debug) winston.debug('clock = ' + clock); + if (err || i == 8) { + callback({ + 'err': err + }); return; } - if(bitOrder == g.LSBFIRST) { + if (bitOrder == g.LSBFIRST) { bit = val & (1 << i); } else { bit = val & (1 << (7 - i)); } - if(clock === 0) { + if (clock === 0) { clock = 1; - if(bit) { + if (bit) { f.digitalWrite(dataPin, g.HIGH, next); } else { f.digitalWrite(dataPin, g.LOW, next); } - } else if(clock == 1) { + } else if (clock == 1) { clock = 2; f.digitalWrite(clockPin, g.HIGH, next); - } else if(clock == 2) { + } else if (clock == 2) { i++; clock = 0; f.digitalWrite(clockPin, g.LOW, next); } } - - if(callback) { + + if (callback) { next(); } else { - for(i = 0; i < 8; i++) { - if(bitOrder == b.LSBFIRST) { + for (i = 0; i < 8; i++) { + if (bitOrder == g.LSBFIRST) { bit = val & (1 << i); } else { bit = val & (1 << (7 - i)); } - - if(bit) { + + if (bit) { f.digitalWrite(dataPin, g.HIGH); } else { f.digitalWrite(dataPin, g.LOW); @@ -340,53 +395,94 @@ f.shiftOut = function(dataPin, clockPin, bitOrder, val, callback) { }; f.shiftOut.args = ['dataPin', 'clockPin', 'bitOrder', 'val', 'callback']; -f.attachInterrupt = function(pin, handler, mode, callback) { +f.attachInterrupt = function (pin, handler, mode, callback) { pin = my.getpin(pin); - if(debug) winston.debug('attachInterrupt(' + [pin.key, handler, mode] + ');'); + if (debug) winston.debug('attachInterrupt(' + [pin.key, handler, mode] + ');'); var n = pin.gpio; - var resp = {'pin':pin, 'attached': false}; + var resp = { + 'pin': pin, + 'attached': false + }; // Check if we don't have the required Epoll module - if(!epoll.exists) { + if (!epoll.exists) { resp.err = 'attachInterrupt: requires Epoll module'; - if(debug) winston.debug(resp.err); - if(callback) callback(resp); - return(resp.attached); + if (debug) winston.debug(resp.err); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(resp); + } else { + var err = resp.err; + delete resp.err; + callback(err, resp); + } + } + return (resp.attached); } // Check if pin isn't already configured as GPIO - if(typeof gpio[n] == 'undefined') { + if (typeof gpio[n] == 'undefined') { resp.err = 'attachInterrupt: pin ' + pin.key + ' not already configured as GPIO'; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); resp.attached = false; resp.configured = false; - if(callback) callback(resp); - return(resp); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(resp); + } else { + var err = resp.err; + delete resp.err; + callback(err, resp); + } + } + return (resp); } // Check if someone already has a handler configured - if(typeof gpioInt[n] != 'undefined') { + if (typeof gpioInt[n] != 'undefined') { resp.err = 'attachInterrupt: pin ' + pin.key + ' already has an interrupt handler assigned'; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); resp.attached = false; resp.configured = true; - if(callback) callback(resp); - return(resp.attached); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(resp); + } else { + var err = resp.err; + delete resp.err; + callback(err, resp); + } + } + return (resp.attached); } handler = (typeof handler === "string") ? my.myeval('(' + handler + ')') : handler; - var intHandler = function(err, fd, events) { + var intHandler = function (err, fd, events) { var m = {}; - if(err) { + if (err) { m.err = err; } fs.readSync(gpioInt[n].valuefd, gpioInt[n].value, 0, 1, 0); m.pin = pin; - m.value = parseInt(Number(gpioInt[n].value), 2); - if(typeof handler =='function') m.output = handler(m); - else m.output = {handler:handler}; - if(m.output && (typeof callback == 'function')) callback(m); + m.value = parseInt(gpioInt[n].value.toString(), 2); + if (typeof handler == 'function') m.output = handler(m); + else m.output = { + handler: handler + }; + if (m.output && (typeof callback == 'function')) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(m); + } else { + var err = m.err; + delete m.err; + callback(err, m); + } + } }; try { @@ -395,60 +491,110 @@ f.attachInterrupt = function(pin, handler, mode, callback) { fs.readSync(gpioInt[n].valuefd, gpioInt[n].value, 0, 1, 0); gpioInt[n].epoll.add(gpioInt[n].valuefd, epoll.Epoll.EPOLLPRI); resp.attached = true; - } catch(ex) { + } catch (ex) { resp.err = 'attachInterrupt: GPIO input file not opened: ' + ex; - if(debug) winston.debug(resp.err); + if (debug) winston.debug(resp.err); } - if(callback) callback(resp); - return(resp.attached); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(resp); + } else { + var err = resp.err; + delete resp.err; + callback(err, resp); + } + } + return (resp.attached); }; f.attachInterrupt.args = ['pin', 'handler', 'mode', 'callback']; -f.detachInterrupt = function(pin, callback) { +f.detachInterrupt = function (pin, callback) { pin = my.getpin(pin); - if(debug) winston.debug('detachInterrupt(' + [pin.key] + ');'); + if (debug) winston.debug('detachInterrupt(' + [pin.key] + ');'); var n = pin.gpio; - if(typeof gpio[n] == 'undefined' || typeof gpioInt[n] == 'undefined') { - if(callback) callback({'pin':pin, 'detached':false}); - return(false); + if (typeof gpio[n] == 'undefined' || typeof gpioInt[n] == 'undefined') { + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback({ + 'pin': pin, + 'detached': false + }); + } else + callback(true, { + 'pin': pin, + 'detached': false + }); + } + return (false); } gpioInt[n].epoll.remove(gpioInt[n].valuefd); delete gpioInt[n]; - if(callback) callback({'pin':pin, 'detached':true}); - return(true); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback({ + 'pin': pin, + 'detached': true + }); + } else + callback(null, { + 'pin': pin, + 'detached': true + }); + } + return (true); }; f.detachInterrupt.args = ['pin', 'callback']; // See http://processors.wiki.ti.com/index.php/AM335x_PWM_Driver's_Guide // That guide isn't useful for the new pwm_test interface -f.analogWrite = function(pin, value, freq, callback) { +f.analogWrite = function (pin, value, freq, callback) { pin = my.getpin(pin); - if(debug) winston.debug('analogWrite(' + [pin.key,value,freq] + ');'); + if (debug) winston.debug('analogWrite(' + [pin.key, value, freq] + ');'); freq = freq || 2000.0; var resp = {}; // Make sure the pin has a PWM associated - if(typeof pin.pwm == 'undefined') { + if (typeof pin.pwm == 'undefined') { + //handle analogWrite() on digital OUTPUT + if (typeof pin.gpio != 'undefined') { + if (value >= 0.5) { + if (callback) + f.digitalWrite(pin, g.HIGH, callback); + else + f.digitalWrite(pin, g.HIGH); + return (true); + } else { + if (callback) + f.digitalWrite(pin, g.LOW, callback); + else + f.digitalWrite(pin, g.LOW); + return (true); + } + } resp.err = 'analogWrite: ' + pin.key + ' does not support analogWrite()'; winston.error(resp.err); - if(callback) callback(resp); - return(false); + if (callback) callback(resp); + return (false); } // Make sure there is no one else who has the PWM - if( - (typeof pwm[pin.pwm.name] != 'undefined') // PWM needed by this pin is already allocated - && (pin.key != pwm[pin.pwm.name].key) // allocation is not by this pin + if ( + (typeof pwm[pin.pwm.name] != 'undefined') // PWM needed by this pin is already allocated + && + (pin.key != pwm[pin.pwm.name].key) // allocation is not by this pin ) { resp.err = 'analogWrite: ' + pin.key + ' requires pwm ' + pin.pwm.name + ' but it is already in use by ' + pwm[pin.pwm.name].key; winston.error(resp.err); - if(callback) callback(resp); - return(false); + if (callback) callback(resp); + return (false); } // Enable PWM controls if not already done - if(typeof pwm[pin.pwm.name] == 'undefined') { + if (typeof pwm[pin.pwm.name] == 'undefined') { var pinMode = f.getPinMode(pin.key); var slew = pinMode.slew || 'fast'; var pullup = pinMode.pullup || 'disabled'; @@ -463,52 +609,67 @@ f.analogWrite = function(pin, value, freq, callback) { pwm[pin.pwm.name].value = value; // All done - if(callback) callback(resp); - return(true); + if (callback) callback(resp); + return (true); }; f.analogWrite.args = ['pin', 'value', 'freq', 'callback']; -f.getEeproms = function(callback) { +f.getEeproms = function (callback) { var eeproms = {}; eeproms = hw.readEeproms(eeproms); - if(eeproms == {}) { - if(debug) winston.debug('No valid EEPROM contents found'); + if (eeproms == {}) { + if (debug) winston.debug('No valid EEPROM contents found'); + } + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(eeproms); + } else + callback(eeproms == {} ? 'No valid EEPROM contents found' : null, eeproms); } - if(callback) callback(eeproms); - return(eeproms); + return (eeproms); }; f.getEeproms.args = ['callback']; -f.readTextFile = function(filename, callback) { - if(typeof callback == 'function') { - var cb = function(err, data) { - callback({'err': err, 'data':data}); +f.readTextFile = function (filename, callback) { + if (typeof callback == 'function') { + var cb = function (err, data) { + callback({ + 'err': err, + 'data': data + }); }; - fs.readFile(filename, 'ascii', cb); + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + fs.readFile(filename, 'ascii', cb); + } else + fs.readFile(filename, 'ascii', callback); } else { return fs.readFileSync(filename, 'ascii'); - } + } }; f.readTextFile.args = ['filename', 'callback']; -f.writeTextFile = function(filename, data, callback) { - if(typeof callback == 'function') { - var cb = function(err) { - callback({'err':err}); +f.writeTextFile = function (filename, data, callback) { + if (typeof callback == 'function') { + var cb = function (err) { + callback({ + 'err': err + }); }; fs.writeFile(filename, data, 'ascii', cb); } else { try { return fs.writeFileSync(filename, data, 'ascii'); - } catch(ex) { + } catch (ex) { winston.error("writeTextFile error: " + ex); - return(false); + return (false); } } }; f.writeTextFile.args = ['filename', 'data', 'callback']; -f.getPlatform = function(callback) { +f.getPlatform = function (callback) { var platform = { 'platform': bone, 'name': "BeagleBone", @@ -525,85 +686,114 @@ f.getPlatform = function(callback) { platform.os.freemem = os.freemem(); platform.os.networkInterfaces = os.networkInterfaces(); platform = hw.readPlatform(platform); - if(callback) callback(platform); - return(platform); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback(platform); + } else + callback(null, platform); + } + return (platform); }; f.getPlatform.args = ['callback']; -f.echo = function(data, callback) { +f.echo = function (data, callback) { winston.info(data); - if(callback) callback({'data': data}); - return(data); + if (callback) { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback({ + 'data': data + }); + } else + callback(null, data); + } + return (data); }; f.echo.args = ['data', 'callback']; -f.setDate = function(date, callback) { +f.setDate = function (date, callback) { child_process.exec('date -s "' + date + '"', dateResponse); - + function dateResponse(error, stdout, stderr) { - if(typeof callback != 'function') return; - else callback({'error': error, 'stdout':stdout, 'stderr':stderr}); + if (typeof callback != 'function') return; + else { + if (callback.length == 1) { + winston.warning("single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)"); + callback({ + 'error': error, + 'stdout': stdout, + 'stderr': stderr + }); + } else + callback({ + 'error': error, + 'stderr': stderr + }, stdout); + } } }; f.setDate.args = ['date', 'callback']; -f.delay = function(ms) { +f.delay = function (ms) { var fiber = fibers.current; - if(typeof fiber == 'undefined') { + if (typeof fiber == 'undefined') { winston.error('sleep may only be called within the setup or run functions'); return; } - setTimeout(function() { + setTimeout(function () { fiber.run(); }, ms); fibers.yield(); }; // Exported variables -exports.bone = bone; // this likely needs to be platform and be detected -for(var x in f) { - exports[x] = f[x]; +f.bone = bone; // this likely needs to be platform and be detected +for (var x in functions) { + f[x] = functions[x]; } -for(var x in functions) { - exports[x] = functions[x]; +for (var x in serial) { + f[x] = serial[x]; } -for(var x in serial) { - exports[x] = serial[x]; +for (var x in iic) { + f[x] = iic[x]; } -for(var x in iic) { - exports[x] = iic[x]; +for (var x in g) { + f[x] = g[x]; } -for(var x in g) { - exports[x] = g[x]; +for (var x in autorun) { + f[x] = autorun[x]; } -for(var x in autorun) { - exports[x] = autorun[x]; +for (var x in server) { + f[x] = server[x]; } -for(var x in server) { - exports[x] = server[x]; +for (var x in socketHandlers) { + f[x] = socketHandlers[x]; } -for(var x in socketHandlers) { - exports[x] = socketHandlers[x]; +for (var x in ffi) { + f[x] = ffi[x]; } -for(var x in rc) { - exports[x] = rc[x]; +for (var x in rc) { + f[x] = rc[x]; } + var alreadyRan = false; + function run() { - if(debug) winston.debug('Calling run()'); - if(alreadyRan) return(false); + if (debug) winston.debug('Calling run()'); + if (alreadyRan) return (false); alreadyRan = true; // 'setup' and 'loop' are globals that may or may not be defined - if(typeof global.setup == 'function' || typeof global.loop == 'function') { - fibers(function() { - if(typeof global.setup == 'function') { + if (typeof global.setup == 'function' || typeof global.loop == 'function') { + fibers(function () { + if (typeof global.setup == 'function') { winston.debug('Running setup()'); global.setup(); } - if(typeof global.loop == 'function') { - if(debug) winston.debug('Starting loop()'); - while(1) { + if (typeof global.loop == 'function') { + if (debug) winston.debug('Starting loop()'); + while (1) { global.loop(); } } @@ -614,10 +804,10 @@ process.nextTick(run); // Global variable assignments // This section is broken out because it will eventually be deprecated -function setGlobals() { - for(var x in exports) { - global[x] = exports[x]; +f.setGlobals = function () { + for (var x in f) { + global[x] = f[x]; } global.run = run; -} -exports.setGlobals = setGlobals; +}; +module.exports = f; \ No newline at end of file diff --git a/src/my.js b/src/my.js index 34a5cd8a..4139cd5c 100644 --- a/src/my.js +++ b/src/my.js @@ -7,124 +7,131 @@ var winston = require('winston'); var child_process = require('child_process'); var bone = require('./bone'); var g = require('./constants'); -var ffi = require("ffi"); var debug = process.env.DEBUG ? true : false; var sysfsFiles = {}; -var libc = new ffi.Library(null, { - "system": ["int32", ["string"]] -}); -var system = libc.system; - -exports.require = function(packageName, onfail) { +var myRequire = function (packageName, onfail) { var y = {}; try { y = require(packageName); y.exists = true; - } catch(ex) { + } catch (ex) { y.exists = false; - if(debug) winston.debug("Optional package '" + packageName + "' not loaded"); - if(onfail) onfail(); + if (debug) winston.debug("Optional package '" + packageName + "' not loaded"); + if (onfail) onfail(); } - return(y); + return (y); }; -var fibers = exports.require('fibers'); +var fibers = myRequire('fibers'); -exports.is_new_capemgr = function(callback) { - var exists = exports.file_existsSync('/sys/devices/platform/bone_capemgr/slots'); - if(callback) callback(exists); - return(exists); +var is_new_capemgr = function (callback) { + var exists = file_existsSync('/sys/devices/platform/bone_capemgr/slots'); + if (callback) callback(exists); + return (exists); }; -exports.is_capemgr = function(callback) { - return(exports.find_sysfsFile('capemgr', '/sys/devices', 'bone_capemgr.', callback)); +var is_capemgr = function (callback) { + return (find_sysfsFile('capemgr', '/sys/devices', 'bone_capemgr.', callback)); }; -exports.is_ocp = function(callback) { - var found = exports.find_sysfsFile('ocp', '/sys/devices', 'ocp.', callback); - if(debug) winston.debug("is_ocp, found = " + found); - if(typeof found == 'undefined') { - found = exports.find_sysfsFile('ocp', '/sys/devices/platform', 'ocp', callback); - if(debug) winston.debug("is_ocp, found2 = " + found); +var is_ocp = function (callback) { + var found = find_sysfsFile('ocp', '/sys/devices', 'ocp.', callback); + if (debug) winston.debug("is_ocp, found = " + found); + if (typeof found == 'undefined') { + found = find_sysfsFile('ocp', '/sys/devices/platform', 'ocp', callback); + if (debug) winston.debug("is_ocp, found2 = " + found); } - return(found); + return (found); }; -exports.is_cape_universal = function(callback) { - var ocp = exports.is_ocp(); - if(debug) winston.debug('is_ocp() = ' + ocp); - var cape_universal = exports.find_sysfsFile('cape-universal', ocp, 'cape-universal.', callback); - if(debug) winston.debug('is_cape_universal() = ' + cape_universal); - return(cape_universal); +var is_cape_universal = function (callback) { + var ocp = is_ocp(); + if (debug) winston.debug('is_ocp() = ' + ocp); + var cape_universal = find_sysfsFile('cape-universal', ocp, 'cape-universal.', callback); + if (debug) winston.debug('is_cape_universal() = ' + cape_universal); + return (cape_universal); }; -exports.find_sysfsFile = function(name, path, prefix, callback) { - if(typeof sysfsFiles[name] == 'undefined') { - if(callback) { - sysfsFiles[name] = exports.file_find(path, prefix, 1, onFindCapeMgr); +var find_sysfsFile = function (name, path, prefix, callback) { + if (debug) winston.debug('find_sysfsFile(' + name + ',' + path + ',' + prefix + ')'); + if (typeof sysfsFiles[name] == 'undefined') { + if (callback) { + sysfsFiles[name] = file_find(path, prefix, 1, onFindCapeMgr); } else { - sysfsFiles[name] = exports.file_find(path, prefix, 1); + sysfsFiles[name] = file_find(path, prefix, 1); } } else { - if(callback) callback({path: sysfsFiles[name]}); + if (callback) callback({ + path: sysfsFiles[name] + }); } - + function onFindCapeMgr(resp) { - if(typeof resp.path == 'undefined') sysfsFiles[name] = false; + if (typeof resp.path == 'undefined') sysfsFiles[name] = false; else sysfsFiles[name] = resp.path; callback(resp); } - - return(sysfsFiles[name]); + + return (sysfsFiles[name]); }; -exports.file_exists = fs.exists; -exports.file_existsSync = fs.existsSync; -if(typeof exports.file_exists == 'undefined') { +file_exists = fs.exists; +file_existsSync = fs.existsSync; +if (typeof file_exists == 'undefined') { var path = require('path'); - exports.file_exists = path.exists; - exports.file_existsSync = path.existsSync; + file_exists = path.exists; + file_existsSync = path.existsSync; } -exports.file_find = function(path, prefix, attempts, callback) { +var file_find = function (path, prefix, attempts, callback) { var resp = {}; resp.attempts = 0; - if(typeof attempts == 'undefined') attempts = 1; - - if(callback) { + if (typeof attempts == 'undefined') attempts = 1; + + if (callback) { fs.readdir(path, onReadDir); } else { - while(resp.attempts < attempts) { + while (resp.attempts < attempts) { try { var files = fs.readdirSync(path); onReadDir(null, files); - } catch(ex) { - if(debug) winston.debug('Error reading ' + path); - return(resp.path); + } catch (ex) { + if (debug) winston.debug('Error reading ' + path); + return (resp.path); } - if(resp.path) return(resp.path); + if (resp.path) return (resp.path); } - return(resp.path); + return (resp.path); } - + function onReadDir(err, files) { resp.attempts++; - if(err) { + if (err) { resp.err = 'Error listing directory ' + path + ': ' + err; - if(callback) callback(resp); + if (callback) callback(resp); return; } - for(var j in files) { - if(files[j].indexOf(prefix) === 0) { - resp.path = path + '/' + files[j]; - if(callback) callback(resp); - return; + for (var j in files) { + if (Array.isArray(prefix)) { + for (var k = 0; k < prefix.length; k++) { + if (files[j].search(prefix[k]) == 0) { + resp.path = path + '/' + files[j]; + if (callback) callback(resp); + return; + } + } + } else { + if (files[j].search(prefix) === 0) { + resp.path = path + '/' + files[j]; + if (callback) callback(resp); + return; + } } } - if(callback) { - if(resp.attempts >= attempts) { + if (callback) { + if (resp.attempts >= attempts) { resp.err = 'Did not find ' + prefix + ' in ' + path; callback(resp); } else { @@ -132,63 +139,65 @@ exports.file_find = function(path, prefix, attempts, callback) { } } } - - return(resp.path); + + return (resp.path); }; // Note, this just makes sure there was an attempt to load the // devicetree fragment, not if it was successful -exports.load_dt = function(name, pin, resp, callback) { - if(debug) winston.debug('load_dt(' + [name, pin ? pin.key : null, JSON.stringify(resp)] + ')'); +var load_dt = function (name, pin, resp, callback) { + if (debug) winston.debug('load_dt(' + [name, pin ? pin.key : null, JSON.stringify(resp)] + ')'); resp = resp || {}; var slotsFile; var lastSlots; var writeAttempts = 0; var readAttempts = 0; - if(pin) { + if (pin) { var slotRegex = new RegExp('\\d+(?=\\s*:.*,bs.*' + pin.key + ')', 'gm'); } - var capemgr = exports.is_capemgr(); - onFindCapeMgr({path:capemgr}); - + var capemgr = is_capemgr(); + onFindCapeMgr({ + path: capemgr + }); + function onFindCapeMgr(x) { - if(debug) winston.debug('onFindCapeMgr: path = ' + x.path); - if(typeof x.path == 'undefined') { + if (debug) winston.debug('onFindCapeMgr: path = ' + x.path); + if (typeof x.path == 'undefined') { resp.err = "CapeMgr not found: " + x.err; winston.error(resp.err); - if(callback) callback(resp); - return(false); + if (callback) callback(resp); + return (false); } slotsFile = x.path + '/slots'; var slots; try { slots = fs.readFileSync(slotsFile, 'ascii'); - } catch(ex) { + } catch (ex) { resp.err = ex; } onReadSlots(resp.err, slots); } - + function onReadSlots(err, slots) { readAttempts++; - if(err) { + if (err) { resp.err = 'Unable to read from CapeMgr slots: ' + err; winston.error(resp.err); - if(callback) callback(resp); - return(false); + if (callback) callback(resp); + return (false); } lastSlots = slots; var index = slots.indexOf(name); - if(debug) winston.debug('onReadSlots: index = ' + index + ', readAttempts = ' + readAttempts); - if(index >= 0) { + if (debug) winston.debug('onReadSlots: index = ' + index + ', readAttempts = ' + readAttempts); + if (index >= 0) { // Fragment is already loaded - if(callback) callback(resp); + if (callback) callback(resp); } else if (readAttempts <= 1) { // Attempt to load fragment try { - if(debug) winston.debug('Writing ' + name + ' to ' + slotsFile); + if (debug) winston.debug('Writing ' + name + ' to ' + slotsFile); fs.writeFileSync(slotsFile, name, 'ascii'); - } catch(ex) { + } catch (ex) { resp.err = ex; } onWriteSlots(resp.err); @@ -197,80 +206,80 @@ exports.load_dt = function(name, pin, resp, callback) { callback(resp); } } - + function onWriteSlots(err) { writeAttempts++; - if(err) { + if (err) { resp.err = 'Write to CapeMgr slots failed: ' + err; - if(pin && writeAttempts <= 1) unloadSlot(); + if (pin && writeAttempts <= 1) unloadSlot(); else { - if(callback) callback(resp); - return(false); + if (callback) callback(resp); + return (false); } } var slots; try { slots = fs.readFileSync(slotsFile, 'ascii'); - } catch(ex) { + } catch (ex) { resp.err = ex; } onReadSlots(resp.err, slots); } - + function unloadSlot() { var slot = lastSlots.match(slotRegex); - if(slot && slot[0]) { - if(debug) winston.debug('Attempting to unload conflicting slot ' + + if (slot && slot[0]) { + if (debug) winston.debug('Attempting to unload conflicting slot ' + slot[0] + ' for ' + name); try { - fs.writeFileSync(slotsFile, '-'+slot[0], 'ascii'); - } catch(ex) { + fs.writeFileSync(slotsFile, '-' + slot[0], 'ascii'); + } catch (ex) { resp.err = ex; } onUnloadSlot(resp.err); } else { - if(callback) callback(resp); - return(false); + if (callback) callback(resp); + return (false); } } function onUnloadSlot(err) { - if(err) { + if (err) { resp.err = "Unable to unload conflicting slot: " + err; callback(resp); return; } try { fs.writeFileSync(slotsFile, name, 'ascii'); - } catch(ex) { + } catch (ex) { resp.err = ex; } onWriteSlots(resp.err); } - - if(debug) winston.debug('load_dt resp: ' + JSON.stringify(resp)); - if(debug) winston.debug('load_dt return: ' + (typeof resp.err == 'undefined')); - return(typeof resp.err == 'undefined'); + + if (debug) winston.debug('load_dt resp: ' + JSON.stringify(resp)); + if (debug) winston.debug('load_dt return: ' + (typeof resp.err == 'undefined')); + return (typeof resp.err == 'undefined'); }; -exports.create_dt = function(pin, data, template, load, force_create, resp, callback) { - if(debug) winston.debug('create_dt(' + [pin.key, data, template, load, force_create, JSON.stringify(resp)] + ')'); +var create_dt = function (pin, data, template, load, force_create, resp, callback) { + if (debug) winston.debug('create_dt(' + [pin.key, data, template, load, force_create, JSON.stringify(resp)] + ')'); resp = resp || {}; template = template || 'bspm'; load = (typeof load === 'undefined') ? true : load; var fragment = template + '_' + pin.key + '_' + data.toString(16); var dtsFilename = '/lib/firmware/' + fragment + '-00A0.dts'; var dtboFilename = '/lib/firmware/' + fragment + '-00A0.dtbo'; - - if(force_create) { + + if (force_create) { createDTS(); } else { - var exists = exports.file_existsSync(dtboFilename); + var exists = file_existsSync(dtboFilename); onDTBOExistsTest(exists); } - + function onDTBOExistsTest(exists) { - if(exists) { + if (exists) { onDTBOExists(); } else { createDTS(); @@ -280,96 +289,104 @@ exports.create_dt = function(pin, data, template, load, force_create, resp, call function createDTS() { var templateFilename = require.resolve('bonescript').replace('main.js', 'dts/' + template + '_template.dts'); - if(debug) winston.debug('Creating template: ' + templateFilename); + if (debug) winston.debug('Creating template: ' + templateFilename); var dts = fs.readFileSync(templateFilename, 'utf8'); dts = dts.replace(/!PIN_KEY!/g, pin.key); dts = dts.replace(/!PIN_DOT_KEY!/g, pin.key.replace(/_/, '.')); - dts = dts.replace(/!PIN_FUNCTION!/g, pin.options[data&7]); + dts = dts.replace(/!PIN_FUNCTION!/g, pin.options[data & 7]); dts = dts.replace(/!PIN_OFFSET!/g, pin.muxRegOffset); dts = dts.replace(/!DATA!/g, '0x' + data.toString(16)); - if(pin.pwm) { + if (pin.pwm) { dts = dts.replace(/!PWM_MODULE!/g, pin.pwm.module); dts = dts.replace(/!PWM_INDEX!/g, pin.pwm.index); dts = dts.replace(/!DUTY_CYCLE!/g, 500000); } try { fs.writeFileSync(dtsFilename, dts, 'ascii'); - } catch(ex) { + } catch (ex) { resp.err = ex; } onDTSWrite(resp.err); } - + function onDTSWrite(err) { - if(err) { + if (err) { resp.err = 'Error writing ' + dtsFilename + ': ' + err; - if(debug) winston.debug(resp.err); - if(callback) callback(resp); - return(resp); + if (debug) winston.debug(resp.err); + if (callback) callback(resp); + return (resp); } var command = 'dtc -O dtb -o ' + dtboFilename + ' -b 0 -@ ' + dtsFilename; try { - system(command); - } catch(ex) { + child_process.execSync(command); + } catch (ex) { resp.err = ex; } dtcHandler(resp.err); } - + function dtcHandler(error, stdout, stderr) { - if(debug) winston.debug('dtcHandler: ' + - JSON.stringify({error:error, stdout:stdout, stderr:stderr})); - if(!error) onDTBOExists(); + if (debug) winston.debug('dtcHandler: ' + + JSON.stringify({ + error: error, + stdout: stdout, + stderr: stderr + })); + if (!error) onDTBOExists(); } - + function onDTBOExists() { - if(debug) winston.debug('onDTBOExists()'); - if(load) exports.load_dt(fragment, pin, resp); + if (debug) winston.debug('onDTBOExists()'); + if (load) load_dt(fragment, pin, resp); } - if(callback) callback(resp); - return(typeof resp.err == 'undefined'); + if (callback) callback(resp); + return (typeof resp.err == 'undefined'); }; -exports.myeval = function(x) { +var myeval = function (x) { winston.debug('myeval("' + x + '");'); var y; try { y = eval(x); - } catch(ex) { + } catch (ex) { y = undefined; winston.error('myeval error: ' + ex); - throw('myeval error: ' + ex); + throw ('myeval error: ' + ex); } winston.debug('result = ' + y); - return(y); + return (y); }; -exports.getpin = function(pin) { - if(typeof pin == 'object') return(pin); - else if(typeof pin == 'string') return(bone.pins[pin]); - else if(typeof pin == 'number') return(bone.pinIndex[pin]); - else throw("Invalid pin: " + pin); +var getpin = function (pin) { + if (typeof pin == 'object') return (pin); + else { + var pinObject = bone.getPinObject(pin); + if (typeof pinObject != 'object') { + throw ("Invalid pin: " + pin); + } + return (pinObject); + } }; -exports.wrapCall = function(m, func, funcArgs, cbArgs) { - if(!m.module.exists) { - if(debug) winston.debug(m.name + ' support module not loaded.'); - return(function(){}); +var wrapCall = function (m, func, funcArgs, cbArgs) { + if (!m.module.exists) { + if (debug) winston.debug(m.name + ' support module not loaded.'); + return (function () {}); } funcArgs.unshift('port'); funcArgs.push('callback'); - var newFunction = function() { + var newFunction = function () { var args = []; var port = arguments[0]; var callback = false; - for(var i = 1; i < arguments.length; i++) { + for (var i = 1; i < arguments.length; i++) { winston.debug('Adding argument ' + funcArgs[i] + ' to wrapper'); - if(funcArgs[i] == 'callback') { + if (funcArgs[i] == 'callback') { callback = arguments[i]; - var wrappedCallback = function() { + var wrappedCallback = function () { var cbData = {}; - for(var j = 0; j < cbArgs.length; j++) { + for (var j = 0; j < cbArgs.length; j++) { cbData[cbArgs[j]] = arguments[j]; } cbData.event = 'callback'; @@ -381,58 +398,69 @@ exports.wrapCall = function(m, func, funcArgs, cbArgs) { args.push(arguments[i]); } } - if(!m.openPorts[port]) { - if(callback) callback({'err': m.name + ' ' + port + ' not opened'}); - return(false); + if (!m.openPorts[port]) { + if (callback) callback({ + 'err': m.name + ' ' + port + ' not opened' + }); + return (false); } winston.debug('Calling ' + m.name + '[' + port + '].' + func + '(' + args + ')'); var x = m.openPorts[port][func].apply( - m.openPorts[port], args); - if(callback) callback({'event': 'return', 'return': x}); - return(x); + m.openPorts[port], args); + if (callback) callback({ + 'event': 'return', + 'return': x + }); + return (x); }; newFunction.args = funcArgs; - return(newFunction); + return (newFunction); }; -exports.wrapOpen = function(m, openArgs) { - if(!m.module.exists) { - if(debug) winston.debug(m.name + ' support module not loaded.'); - return(function(){}); +var wrapOpen = function (m, openArgs) { + if (!m.module.exists) { + if (debug) winston.debug(m.name + ' support module not loaded.'); + return (function () {}); } openArgs.unshift('port'); openArgs.push('callback'); - var newFunction = function() { + var newFunction = function () { var args = {}; - for(var i = 0; i < openArgs.length; i++) { + for (var i = 0; i < openArgs.length; i++) { args[openArgs[i]] = arguments[i]; } var port = args.port; var callback = args.callback; winston.debug(m.name + ' opened with ' + JSON.stringify(arguments)); - if(m.ports[port] && m.ports[port].devicetree) { + if (m.ports[port] && m.ports[port].devicetree) { var fragment = m.ports[port].devicetree; - if(!exports.is_capemgr()) { - if(callback) callback({err:'Kernel does not include CapeMgr module'}); - return(false); + if (!is_capemgr()) { + if (callback) callback({ + err: 'Kernel does not include CapeMgr module' + }); + return (false); } - if(!exports.load_dt(fragment)) { - if(callback) callback({'err': 'Devicetree overlay fragment ' + - fragment + ' not loaded'}); - return(false); + if (!load_dt(fragment)) { + if (callback) callback({ + 'err': 'Devicetree overlay fragment ' + + fragment + ' not loaded' + }); + return (false); } } m.openPorts[port] = m.doOpen(args); - if(!m.openPorts[port]) { - if(callback) callback({'err': 'Unable to ' + m.name}); - return(false); + if (!m.openPorts[port]) { + if (callback) callback({ + 'err': 'Unable to ' + m.name + }); + return (false); } - for(var e in m.events) { - var addHandler = function(m, port, e) { - var handler = function() { + for (var e in m.events) { + var addHandler = function (m, port, e) { + var handler = function () { var myargs = arguments; myargs.event = e; - for(var i = 0; i < arguments.length; i++) { + for (var i = 0; i < arguments.length; i++) { myargs[m.events[e][i]] = arguments[i]; } callback(myargs); @@ -441,18 +469,21 @@ exports.wrapOpen = function(m, openArgs) { }; addHandler(m, port, e); } - if(callback) callback({'event':'return', 'value':true}); - return(true); + if (callback) callback({ + 'event': 'return', + 'value': true + }); + return (true); }; newFunction.args = openArgs; - return(newFunction); + return (newFunction); }; -exports.pin_data = function(slew, direction, pullup, mux) { +var pin_data = function (slew, direction, pullup, mux) { var pinData = 0; - if(slew == 'slow') pinData |= 0x40; - if(direction != g.OUTPUT) pinData |= 0x20; - switch(pullup) { + if (slew == 'slow') pinData |= 0x40; + if (direction != g.OUTPUT) pinData |= 0x20; + switch (pullup) { case 'disabled': pinData |= 0x08; break; @@ -463,28 +494,28 @@ exports.pin_data = function(slew, direction, pullup, mux) { break; } pinData |= (mux & 0x07); - return(pinData); + return (pinData); }; // Inspired by // https://github.com/luciotato/waitfor/blob/master/waitfor.js // https://github.com/0ctave/node-sync/blob/master/lib/sync.js -exports.wait_for = function(fn, myargs, result_name, no_error) { - var fiber = fibers.current; +var wait_for = function (fn, myargs, result_name, no_error) { + var fiber = fibers.current; var yielded = false; var args = []; var result; - for(var i in fn.args) { - if(fn.args[i] == 'callback') { + for (var i in fn.args) { + if (fn.args[i] == 'callback') { args.push(myCallback); } else { args.push(myargs[i]); } } - if(typeof fiber == 'undefined') { - if(no_error) { + if (typeof fiber == 'undefined') { + if (no_error) { // No callback required (fire and forget) fn.apply(this, args); } else { @@ -492,33 +523,53 @@ exports.wait_for = function(fn, myargs, result_name, no_error) { var err = 'As of BoneScript 0.2.5, synchronous calls must be made\n' + 'within a fiber such as within loop() or setup():\n' + stack; winston.error(err); - throw(err); + throw (err); } } else { fn.apply(this, args); - if(!myCallback.called) { + if (!myCallback.called) { yielded = true; fibers.yield(); - } + } } - + function myCallback(x) { - if(debug) winston.debug('Callback: ' + fn.name + ' ' + x.err); - if(myCallback.called) return; - if(typeof result_name == 'undefined') { + if (debug) winston.debug('Callback: ' + fn.name + ' ' + x.err); + if (myCallback.called) return; + if (typeof result_name == 'undefined') { result = x; - } else if(typeof x[result_name] != 'undefined') { + } else if (typeof x[result_name] != 'undefined') { result = x[result_name]; } - if(typeof x.err != 'undefined' && x.err) { + if (typeof x.err != 'undefined' && x.err) { //var fn_name = fn.toString().substr('function '.length); //fn_name = fn_name.substr(0, fn_name.indexOf('(')); - if(debug) winston.debug(fn.name + ' ' + x.err); + if (debug) winston.debug(fn.name + ' ' + x.err); } myCallback.called = true; - if(typeof fiber == 'undefined' && no_error) return; - if(yielded) fiber.run(); + if (typeof fiber == 'undefined' && no_error) return; + if (yielded) fiber.run(); } - - return(result); + + return (result); }; + +module.exports = { + require: myRequire, + is_new_capemgr: is_new_capemgr, + is_capemgr: is_capemgr, + is_ocp: is_ocp, + is_cape_universal: is_cape_universal, + find_sysfsFile: find_sysfsFile, + file_exists: file_exists, + file_existsSync: file_existsSync, + file_find: file_find, + load_dt: load_dt, + create_dt: create_dt, + myeval: myeval, + getpin: getpin, + wrapCall: wrapCall, + wrapOpen: wrapOpen, + pin_data: pin_data, + wait_for: wait_for +} \ No newline at end of file diff --git a/src/parse.js b/src/parse.js index 3731b2b4..148a6183 100644 --- a/src/parse.js +++ b/src/parse.js @@ -3,13 +3,13 @@ var winston = require('winston'); var debug = process.env.PARSE_DEBUG ? true : false; // This parses pinmux data from the register value -var modeFromStatus = function(pinData, mode) { +var modeFromStatus = function (pinData, mode) { mode = mode || {}; mode.mux = (pinData & 0x07); mode.slew = (pinData & 0x40) ? 'slow' : 'fast'; mode.rx = (pinData & 0x20) ? 'enabled' : 'disabled'; var pullup = (pinData & 0x18) >> 3; - switch(pullup) { + switch (pullup) { case 1: mode.pullup = 'disabled'; break; @@ -20,13 +20,13 @@ var modeFromStatus = function(pinData, mode) { mode.pullup = 'pulldown'; break; default: - winston.error('Unknown pullup value: '+pullup); + winston.error('Unknown pullup value: ' + pullup); } - return(mode); + return (mode); }; -var modeFromOmapMux = function(readout, mode) { - if(debug) winston.debug('' + readout); +var modeFromOmapMux = function (readout, mode) { + if (debug) winston.debug('' + readout); mode = mode || {}; // The format read from debugfs looks like this: // name: mcasp0_axr0.spi1_d1 (0x44e10998/0x998 = 0x0023), b NA, t NA @@ -35,40 +35,40 @@ var modeFromOmapMux = function(readout, mode) { var breakdown = ''; try { breakdown = readout.split('\n'); - } catch(ex) { + } catch (ex) { winston.info('Unable to parse mux readout "' + readout + '": ' + ex); - return(mode); + return (mode); } - try { + try { // Parse the muxmode number, '3' in the above example mode.mux = breakdown[1].split('|')[1].substr(-1); // Parse the mux register value, '0x0023' in the above example - var pinData = parseInt(breakdown[0].split('=')[1].substr(1,6), 16); - if(debug) winston.debug('pinData = ' + pinData); + var pinData = parseInt(breakdown[0].split('=')[1].substr(1, 6), 16); + if (debug) winston.debug('pinData = ' + pinData); mode = modeFromStatus(pinData, mode); - } catch(ex2) { + } catch (ex2) { winston.info('Unable to parse mux mode "' + breakdown + '": ' + ex2); } try { mode.options = breakdown[2].split('|'); - for(var option in mode.options) { - var x = ''+mode.options[option]; + for (var option in mode.options) { + var x = '' + mode.options[option]; try { mode.options[option] = x.replace(/ /g, '').replace('signals:', ''); - } catch(ex) { + } catch (ex) { winston.info('Unable to parse option "' + x + '": ' + ex); mode.options[option] = 'NA'; } } - } catch(ex3) { + } catch (ex3) { winston.info('Unable to parse options "' + breakdown + '": ' + ex3); mode.options = null; } - return(mode); + return (mode); }; -var modeFromPinctrl = function(pins, muxRegOffset, muxBase, mode) { - if(debug) winston.debug('' + pins); +var modeFromPinctrl = function (pins, muxRegOffset, muxBase, mode) { + if (debug) winston.debug('' + pins); muxBase = muxBase || 0x44e10800; mode = mode || {}; // The format read from debugfs looks like this: @@ -76,26 +76,35 @@ var modeFromPinctrl = function(pins, muxRegOffset, muxBase, mode) { // ... // pin 108 (44e109b0) 00000027 pinctrl-single // ... + // + // new format is: + // registered pins: 142 + // ... + // pin 0 (PIN0) 44e10800 00000027 pinctrl-single + // ... + // var pinLines = pins.split('\n'); var numRegistered = pinLines[0].replace(/registered pins: (\d+)/, "$1"); - var pattern = new RegExp('pin ([0-9]+) .([0-9a-f\.]+). ([0-9a-f]+) pinctrl-single'); + var pattern = /pin (\d+) (\(PIN\d+\))? \(?([0-9a-f\.]+)\(? ([0-9a-f]+) pinctrl-single/; var muxAddress = muxBase + muxRegOffset; - for(var i = 0; i < numRegistered; i++) { - if(debug) winston.debug('pinLine = ' + pinLines[i + 1]); + for (var i = 0; i < numRegistered; i++) { + if (debug) winston.debug('pinLine = ' + pinLines[i + 1]); var parsedFields = pattern.exec(pinLines[i + 1]); - if(debug) winston.debug('parsedFields = ' + parsedFields); + if (debug) winston.debug('parsedFields = ' + parsedFields); //var index = parseInt(parsedFields[1], 10); - var address = parseInt(parsedFields[2], 16); - var status = parseInt(parsedFields[3], 16); - if(address == muxAddress) { + var address = parseInt(parsedFields[3], 16); + var status = parseInt(parsedFields[4], 16); + if (address == muxAddress) { mode = modeFromStatus(status, mode); - return(mode); + return (mode); } } //winston.error('Did not find status at ' + muxAddress); - return(mode); + return (mode); }; -exports.modeFromStatus = modeFromStatus; -exports.modeFromOmapMux = modeFromOmapMux; -exports.modeFromPinctrl = modeFromPinctrl; +module.exports = { + modeFromStatus: modeFromStatus, + modeFromOmapMux: modeFromOmapMux, + modeFromPinctrl: modeFromPinctrl +} \ No newline at end of file diff --git a/src/rc.js b/src/rc.js index f46d3994..8233e952 100644 --- a/src/rc.js +++ b/src/rc.js @@ -2,68 +2,113 @@ var my = require('./my'); var rc = my.require('roboticscape'); -if(!rc.exists) return; +if (rc.exists) { -exports.rcInitialize = function(callback) { - var i = rc.initialize(); - var x = {}; - if(i) { - x.error = i; - } - if(callback) callback(x); - return(i); -}; -exports.rcInitialize.args = ['callback']; + var rcInitialize = function (callback) { + var i = rc.initialize(); + var x = {}; + if (i) { + x.error = i; + } + if (callback) callback(x); + return (i); + }; + rcInitialize.args = ['callback']; -exports.rcState = function(state, callback) { - var x = {}; - if(state) { - rc.state(state); - } else { - state = rc.state(); - } - x.state = state; - if(callback) callback(x); - return(state); -}; -exports.rcState.args = ['state', 'callback']; + var rcState = function (state, callback) { + var x = {}; + if (state) { + rc.state(state); + } else { + state = rc.state(); + } + x.state = state; + if (callback) callback(x); + return (state); + }; + rcState.args = ['state', 'callback']; -exports.rcLED = function(led, value, callback) { - if(typeof value !== 'undefined') { - rc.led(led, value); - } - if(callback) callback(); -}; -exports.rcLED.args = ['led', 'value', 'callback']; + var rcLED = function (led, value, callback) { + if (typeof value !== 'undefined') { + rc.led(led, value); + } + if (callback) callback(); + }; + rcLED.args = ['led', 'value', 'callback']; -exports.rcOn = function(event, callback) { - function myCallback() { - callback({'event': event}); - } - rc.on(event, myCallback); -}; -exports.rcOn.args = ['event', 'callback']; + var rcOn = function (event, callback) { + function myCallback() { + callback({ + 'event': event + }); + } + rc.on(event, myCallback); + }; + rcOn.args = ['event', 'callback']; -exports.rcMotor = function(motor, value, callback) { - if(typeof motor !== 'undefined') { - rc.motor(motor, value); - } else { - rc.motor(value); - } - if(callback) callback(); -}; -exports.rcMotor.args = ['motor', 'value', 'callback']; + var rcMotor = function (motor, value, callback) { + if (typeof value !== 'undefined') { + rc.motor(motor, value); + } else { + rc.motor(motor); + } + if (callback) callback(); + }; + rcMotor.args = ['motor', 'value', 'callback']; -exports.rcEncoder = function(encoder, value, callback) { - var x = {}; - x.encoder = encoder; - var i; - if(typeof value !== 'undefined') { - i = rc.encoder(encoder, value); - } else { - i = rc.encoder(encoder); - x.value = i; - } - if(callback) callback(x); -}; -exports.rcEncoder.args = ['encoder', 'value', 'callback']; + var rcServo = function (option, value, callback) { + if (typeof value !== 'undefined') { + rc.servo(option, value); + } else { + rc.servo(option); + } + if (callback) callback(); + }; + rcServo.args = ['option', 'value', 'callback']; + + var rcBMP = function (option, callback) { + var value + if (typeof option !== 'undefined') { + value = rc.bmp(option); + } + if (callback) callback(null, value); + else return value; + }; + rcBMP.args = ['option', 'callback']; + + var rcIMU = function (option, callback) { + var value + if (typeof option !== 'undefined') { + value = rc.imu(option); + } + if (callback) callback(null, value); + else return value; + }; + rcIMU.args = ['option', 'callback']; + + var rcEncoder = function (encoder, value, callback) { + var x = {}; + x.encoder = encoder; + var i; + if (typeof value !== 'undefined') { + i = rc.encoder(encoder, value); + } else { + i = rc.encoder(encoder); + x.value = i; + } + if (callback) callback(x); + }; + rcEncoder.args = ['encoder', 'value', 'callback']; + + module.exports = { + rcInitialize: rcInitialize, + rcState: rcState, + rcLED: rcLED, + rcOn: rcOn, + rcMotor: rcMotor, + rcServo: rcServo, + rcBMP: rcBMP, + rcIMU: rcIMU, + rcEncoder: rcEncoder + }; +} \ No newline at end of file diff --git a/src/rewrite_bone.js b/src/rewrite_bone.js deleted file mode 100644 index eef25d67..00000000 --- a/src/rewrite_bone.js +++ /dev/null @@ -1,13 +0,0 @@ -// This script needs a complete rewrite itself!!! - -var b = require('bonescript'); - -for(var pin in b.bone.pins) { - var mode = b.getPinMode(b.bone.pins[pin]); - //console.log('getPinMode(' + bone[pin].key + ') = ' + JSON.stringify(mode)); - b.bone.pins[pin].options = mode.options; -} - -console.log("if(typeof exports === 'undefined') exports = {};"); -console.log(""); -console.log("exports.bone = " + JSON.stringify(b.bone.pins,null,4) + ";"); diff --git a/src/serial.js b/src/serial.js index 51a66187..7720f0c6 100644 --- a/src/serial.js +++ b/src/serial.js @@ -11,14 +11,15 @@ m.events = { 'data': ['data'] }; m.openPorts = {}; -m.doOpen = function(args) { +m.doOpen = function (args) { var path = args.port; - if(m.ports[args.port].path) path = m.ports[args.port].path; + if (m.ports[args.port].path) path = m.ports[args.port].path; var openPort = new m.module.SerialPort(path, args.options); - return(openPort); + return (openPort); }; +module.exports = { + serialOpen: my.wrapOpen(m, ['options']), + serialWrite: my.wrapCall(m, 'write', ['data'], ['err', 'results']), -exports.serialOpen = my.wrapOpen(m, ['options']); -exports.serialWrite = my.wrapCall(m, 'write', ['data'], ['err', 'results']); - -exports.serialParsers = m.module.exists ? m.module.parsers : {}; + serialParsers: m.module.exists ? m.module.parsers : {} +} \ No newline at end of file diff --git a/src/server.js b/src/server.js index f7a27610..04c71123 100644 --- a/src/server.js +++ b/src/server.js @@ -6,50 +6,65 @@ var http = require('http'); var winston = require('winston'); var express = require('express'); var events = require('events'); +var crypto = require('crypto'); var socketHandlers = require('./socket_handlers'); var serverEmitter = new events.EventEmitter(); var debug = process.env.DEBUG ? true : false; -myrequire('systemd', function() { - if(debug) winston.debug("Startup as socket-activated service under systemd not enabled"); +myrequire('systemd', function () { + if (debug) winston.debug("Startup as socket-activated service under systemd not enabled"); }); -exports.serverStart = function(port, directory, callback) { - if(port === undefined) { +var serverStart = function (port, directory, passphrase, callback) { + if (port === undefined) { port = (process.env.LISTEN_PID > 0) ? 'systemd' : ((process.env.PORT) ? process.env.PORT : 80); } - if(directory === undefined) { + if (directory === undefined) { directory = (process.env.SERVER_DIR) ? process.env.SERVER_DIR : '/usr/share/bone101'; } - var server = mylisten(port, directory); + var passphrase_hash; + if (passphrase) { + if (passphrase.hash) //whether passphrase supplied as hash/text + passphrase_hash = passphrase.data; + else + passphrase_hash = crypto.createHash('sha256').update(passphrase.data).digest("hex"); //generate hash + } + var server = mylisten(port, directory, passphrase_hash); serverEmitter.on('newListner', addServerListener); function addServerListener(event, listener) { console.log('got here'); //TODO: not getting here - if(debug) winston.debug('Got request to add listener to ' + event); + if (debug) winston.debug('Got request to add listener to ' + event); var serverEvent = event.replace(/^server\$/, ''); - if(serverEvent) { - if(debug) winston.debug('Adding listener to server$' + serverEvent); - server.on(serverEvent, listener); + if (serverEvent) { + if (debug) winston.debug('Adding listener to server$' + serverEvent); + server.on(serverEvent, listener); } } - return(serverEmitter); + if (callback) { + callback({ + server: server, + serverEmitter: serverEmitter + }); + } + + return (serverEmitter); }; -function mylisten(port, directory) { +function mylisten(port, directory, passphrase_hash) { winston.info("Opening port " + port + " to serve up " + directory); var app = express(); app.get('/bonescript.js', socketHandlers.socketJSReqHandler); app.use('/bone101', express.static(directory)); - app.use('/bone101/static', express.static(directory+"/static")); + app.use('/bone101/static', express.static(directory + "/static")); app.use(express.static(directory)); var server = http.createServer(app); - socketHandlers.addSocketListeners(server, serverEmitter); + socketHandlers.addSocketListeners(server, serverEmitter, passphrase_hash); server.listen(port); - return(server); + return (server); } function myrequire(packageName, onfail) { @@ -57,10 +72,14 @@ function myrequire(packageName, onfail) { try { y = require(packageName); y.exists = true; - } catch(ex) { + } catch (ex) { y.exists = false; - if(debug) winston.debug("Optional package '" + packageName + "' not loaded"); - if(onfail) onfail(); + if (debug) winston.debug("Optional package '" + packageName + "' not loaded"); + if (onfail) onfail(); } - return(y); + return (y); } + +module.exports = { + serverStart: serverStart +} \ No newline at end of file diff --git a/src/socket_handlers.js b/src/socket_handlers.js index 12c0a48a..e4a45591 100644 --- a/src/socket_handlers.js +++ b/src/socket_handlers.js @@ -7,13 +7,14 @@ var url = require('url'); var child_process = require('child_process'); var winston = require('winston'); var socketio = require('socket.io'); - var debug = process.env.DEBUG ? true : false; -exports.socketJSReqHandler = function(req, res) { +var socketJSReqHandler = function (req, res) { function sendFile(err, file) { - if(err) { - res.writeHead(500, {"Content-Type": "text/plain"}); + if (err) { + res.writeHead(500, { + "Content-Type": "text/plain" + }); res.end(err + '\n'); return; } @@ -24,25 +25,44 @@ exports.socketJSReqHandler = function(req, res) { var parsedUrl = url.parse(req.url); var uri = parsedUrl.pathname; var host = 'http://' + req.headers.host; - if(uri == '/bonescript.js') { + if (uri == '/bonescript.js') { var filename = __dirname + '/bonescript.js'; - if(debug) winston.debug('filename = ' + filename) + if (debug) winston.debug('filename = ' + filename) fs.readFile(filename, 'utf8', sendFile); } } -exports.addSocketListeners = function(server, serverEmitter) { +var addSocketListeners = function (server, serverEmitter, passphrase_hash) { var io = socketio(server); - if(debug) winston.debug('Listening for new socket.io clients'); - io.on('connection', onconnect); + if (passphrase_hash) { //attach middleware to handle authentication + io.use(function (socket, next) { + socket.auth = false; //consider the all sockets initially as unauthorized + if (socket.handshake.headers.authorization) { + if (socket.handshake.headers.authorization == passphrase_hash) { + socket.auth = true; //authorize the socket + next(); + } else + next(new Error("Authentication Failed : incorrect passphrase !!")); + } else { + next(new Error("Authentication data not send !!")); + } + }); + } + if (debug) winston.debug('Listening for new socket.io clients'); + io.on('connection', function (socket) { + if (socket.auth || !passphrase_hash) + onconnect(socket); + else + socket.disconnect('unauthorized'); + }); + function onconnect(socket) { winston.debug('Client connected'); - serverEmitter.emit('socket$connect', socket); // on disconnect - socket.on('disconnect', function() { - if(debug) winston.debug('Client disconnected'); + socket.on('disconnect', function () { + if (debug) winston.debug('Client disconnected'); serverEmitter.emit('socket$disconnect'); }); @@ -54,48 +74,65 @@ exports.addSocketListeners = function(server, serverEmitter) { modmsg.module = 'bonescript'; modmsg.data = {}; - var callMyFunc = function(name, m) { - var myCallback = function(resp) { - if(debug) winston.debug(name + ' replied to ' + JSON.stringify(m) + ' with ' + JSON.stringify(resp)); - if(typeof m.seq == 'undefined') return; - if(!resp || (typeof resp != 'object')) resp = {'data': resp}; + var callMyFunc = function (name, m) { + var myCallback = function (resp) { + if (debug) winston.debug(name + ' replied to ' + JSON.stringify(m) + ' with ' + JSON.stringify(resp)); + if (typeof m.seq == 'undefined') return; + if (!resp || (typeof resp != 'object')) resp = { + 'data': resp + }; resp.seq = m.seq; // TODO: consider setting 'oneshot' - if(debug) winston.debug('Sending message "bonescript": ' + JSON.stringify(resp)); + if (debug) winston.debug('Sending message "bonescript": ' + JSON.stringify(resp)); socket.emit('bonescript', resp); }; + var myCallback_nodestyle = function (err, resp) { + if (debug) winston.debug(name + ' replied to ' + JSON.stringify(m) + ' with ' + JSON.stringify(resp)); + if (typeof m.seq == 'undefined') return; + // TODO: consider setting 'oneshot' + if (debug) winston.debug('Sending message "bonescript": ' + JSON.stringify(resp)); + socket.emit('bonescript', { + err: err, + resp: resp, + seq: m.seq + }); + }; try { var callargs = []; - for(var arg in b[name].args) { + for (var arg in b[name].args) { var argname = b[name].args[arg]; - if(argname == 'callback') { - if(typeof m.seq == 'number') callargs.push(myCallback); - else callargs.push(null); - } else if(typeof m[argname] != 'undefined') { + if (argname == 'callback') { + if (typeof m.seq == 'number') { + if (m.length == 1) + callargs.push(myCallback); + else + callargs.push(myCallback_nodestyle); + } else callargs.push(null); + } else if (typeof m[argname] != 'undefined') { callargs.push(m[argname]); } else { callargs.push(undefined); } } - if(debug) winston.debug('Calling ' + name + '(' + callargs.join(',') + ')'); + if (debug) winston.debug('Calling ' + name + '(' + callargs.join(',') + ')'); b[name].apply(this, callargs); - } catch(ex) { - if(debug) winston.debug('Error handing ' + name + ' message: ' + ex); - if(debug) winston.debug('m = ' + JSON.stringify(m)); + } catch (ex) { + if (debug) winston.debug('Error handing ' + name + ' message: ' + ex); + if (debug) winston.debug('m = ' + JSON.stringify(m)); } }; - var addSocketX = function(message, name) { - var onFuncMessage = function(m) { + var addSocketX = function (message, name) { + var onFuncMessage = function (m) { callMyFunc(name, m); }; socket.on(message, onFuncMessage); }; var b = require('../main'); - for(var i in b) { - if(typeof b[i] == 'function') { - if(typeof b[i].args != 'undefined') { + for (var i in b) { + if (typeof b[i] == 'function') { + if (typeof b[i].args != 'undefined') { modmsg.data[i] = {}; modmsg.data[i].name = i; modmsg.data[i].type = 'function'; @@ -116,10 +153,9 @@ exports.addSocketListeners = function(server, serverEmitter) { function serverMessage(message) { serverEmitter.emit('message', message); } - - return(io); -} + return (io); +} // most heavily borrowed from https://github.com/itchyny/browsershell function spawn(socket) { var stream = ''; @@ -128,31 +164,33 @@ function spawn(socket) { var c; socket.on('shell', receive); - return(receive); + return (receive); function receive(msg) { - if(!c) { + if (!c) { try { - if(debug) winston.debug('Spawning bash'); - c = child_process.spawn('/bin/bash', ['-i'], {customFds: [-1, -1, -1]}); + if (debug) winston.debug('Spawning bash'); + c = child_process.spawn('/bin/bash', ['-i'], { + customFds: [-1, -1, -1] + }); c.stdout.on('data', send); c.stderr.on('data', send); - c.on('exit', function() { + c.on('exit', function () { socket.emit('shell', send('\nexited\n')); c = undefined; }); socket.on('disconnect', function () { - if(debug) winston.debug('Killing bash'); + if (debug) winston.debug('Killing bash'); c.kill('SIGHUP'); }); - } catch(ex) { + } catch (ex) { c = undefined; send('Error invoking bash'); winston.error('Error invoking bash'); } } - if(c) { - if(msg) { + if (c) { + if (msg) { c.stdin.write(msg + '\n', 'utf-8'); } } else { @@ -161,27 +199,31 @@ function spawn(socket) { } function send(data) { - // add data to the stream - stream += data.toString(); - ++len; - - // clear any existing timeout if it exists - if(timer) clearTimeout(timer); - - // set new timeout - timer = setTimeout(function () { - socket.emit('shell', stream); - stream = ''; - len = 0; - }, 100); - - // send data if over threshold - if(len > 1000) - { - clearTimeout(timer); - socket.emit('shell', stream); - stream = ''; - len = 0; - } + // add data to the stream + stream += data.toString(); + ++len; + + // clear any existing timeout if it exists + if (timer) clearTimeout(timer); + + // set new timeout + timer = setTimeout(function () { + socket.emit('shell', stream); + stream = ''; + len = 0; + }, 100); + + // send data if over threshold + if (len > 1000) { + clearTimeout(timer); + socket.emit('shell', stream); + stream = ''; + len = 0; + } } } + +module.exports = { + socketJSReqHandler: socketJSReqHandler, + addSocketListeners: addSocketListeners +} \ No newline at end of file diff --git a/test/TODO/test-pocketbeagle.js b/test/TODO/test-pocketbeagle.js new file mode 100644 index 00000000..156ee468 --- /dev/null +++ b/test/TODO/test-pocketbeagle.js @@ -0,0 +1,38 @@ +var b = require('bonescript'); + +var gpios = [ + 'p1.2', + 'p1.04', + 'P1.6', + 'P1_20', + 'P1_29', + 'P1_30', + 'P1_31', + 'P1_33', + 'P1_35', + 'P1.36', + 'P1.37', + 'P1_38', + 'p2.1', + 59, + 23, + 'p2_06', + 60, + 52, + 65, + 47, + 27, + 46, + 'P2_26', + 'P2_28', + 'p2_30', + 'p2.32', + 'p2_33', + 'p2_34', + 'P2_35', + 'P2_36', +]; + +for(i in gpios) { + b.setMode(gpios[i], b.OUTPUT); +} diff --git a/test/test-analogread.js b/test/test-analogread.js new file mode 100644 index 00000000..04f6a16f --- /dev/null +++ b/test/test-analogread.js @@ -0,0 +1,39 @@ +var b = require('bonescript'); + +var pinKeys = []; +for (var i = 1; i <= 36; i++) { + pinKeys.push("P1_" + i); + pinKeys.push("P2_" + i); +} +for (var i = 1; i <= 46; i++) { + pinKeys.push("P8_" + i); + pinKeys.push("P9_" + i); +} +exports.testanalogread1 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + var y = b.analogRead(pinKeys[x]); + test.ok(typeof y == 'number'); + } + test.done(); +} +exports.testanalogread2 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + b.analogRead(pinKeys[x], function (x) { + test.ok(typeof x.value == 'number' && !x.err); + }); + if (x == pinKeys.length - 1) + test.done(); + } +} +exports.testanalogread3 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + b.analogRead(pinKeys[x], function (err, value) { + test.ok(typeof value == 'number' && !err); + }); + if (x == pinKeys.length - 1) + test.done(); + } +} \ No newline at end of file diff --git a/test/test-analogwrite.js b/test/test-analogwrite.js new file mode 100644 index 00000000..568fec5b --- /dev/null +++ b/test/test-analogwrite.js @@ -0,0 +1,30 @@ +var b = require('bonescript'); + +var pinKeys = []; +for (var i = 1; i <= 36; i++) { + pinKeys.push("P1_" + i); + pinKeys.push("P2_" + i); +} +for (var i = 1; i <= 46; i++) { + pinKeys.push("P8_" + i); + pinKeys.push("P9_" + i); +} +exports.testanalogwrite1 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + test.doesNotThrow(function () { + b.analogWrite(pinKeys[x], Math.random()); + }); + } + test.done(); +} +exports.testanalogwrite2 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + b.analogWrite(pinKeys[x], Math.random(), 2000, function (x) { + test.ok(true); + }); + if (x == pinKeys.length - 1) + test.done(); + } +} \ No newline at end of file diff --git a/test/test-autorun.js b/test/test-autorun.js new file mode 100644 index 00000000..28c72535 --- /dev/null +++ b/test/test-autorun.js @@ -0,0 +1,63 @@ +var autorun = require('bonescript').autorun; +var fs = require('fs'); +var testDir = '/tmp/autorun-test'; +var file0 = testDir + '/autorun-test0.js'; +var file1 = testDir + '/autorun-test1.js'; + +exports.testAutorun = function (test) { + test.expect(3); + setTimeout(onTimeout1, 100); + setTimeout(onTimeout2, 1000); + + if (!fs.existsSync(testDir)) { + fs.mkdirSync(testDir); + } + try { + fs.unlinkSync(file0); + } catch (ex) { + console.log('Unable to delete ' + file0); + } + try { + fs.unlinkSync(file1); + } catch (ex) { + console.log('Unable to delete ' + file1); + } + fs.writeFileSync(file0, 'console.log("got here in ' + file0 + '");'); + console.log('Wrote ' + file0); + + var ar = autorun(testDir); + var apps = ar.getApps(); + var emitter = ar.getEmitter(); + + emitter.on('start', function (file) { + console.log('Started ' + file); + if (file == file1) { + setTimeout(function () { + fs.unlink(file1, onUnlink); + }, 500); + test.ok(true); + } + }); + + emitter.on('closed', function (file) { + if (file == file1) { + ar.stop(); + test.ok(true); + } + }); + + function onTimeout1() { + fs.writeFileSync(file1, 'console.log("got here in ' + file1 + '"); setTimeout(function(){console.log("timeout")}, 3000);'); + console.log('Wrote ' + file1); + test.ok(true); + } + + function onTimeout2() { + console.log('Done'); + test.done(); + } + + function onUnlink() { + console.log('Deleted ' + file1); + } +}; \ No newline at end of file diff --git a/test/test-bone.js b/test/test-bone.js new file mode 100644 index 00000000..c8975f84 --- /dev/null +++ b/test/test-bone.js @@ -0,0 +1,137 @@ +//process.env.DEBUG = true; +var bone = require('bonescript').bone; + +var expectedResults = []; + +expectedResults.push({ + "name": "LEDs", + "search": /^USR/, + "keys": ["USR0", "USR1", "USR2", "USR3"] +}); + +var pbKeys = []; +for (var i = 1; i <= 36; i++) { + pbKeys.push("P1_" + i); + pbKeys.push("P2_" + i); +} +expectedResults.push({ + "name": "PocketBeagleHeaders", + "search": /^P[12]/, + "keys": pbKeys +}); + +var boneKeys = []; +for (var i = 1; i <= 46; i++) { + boneKeys.push("P8_" + i); + boneKeys.push("P9_" + i); +} +boneKeys.push("P9_15B"); +boneKeys.push("P9_41B"); +boneKeys.push("P9_42B"); +expectedResults.push({ + "name": "BeagleBoneHeaders", + "search": /^P[89]/, + "keys": boneKeys +}); + +var ainKeys = []; +for (var i = 0; i <= 7; i++) { + ainKeys.push("A" + i); +} +expectedResults.push({ + "name": "AnalogInPins", + "search": /^A[0-7]/, + "keys": ainKeys +}); + +var gpioKeys = []; +for (var i = 0; i <= 117; i++) { + gpioKeys.push("GPIO_" + i); +} +expectedResults.push({ + "name": "GPIOPins", + "search": /^GPIO_/, + "keys": gpioKeys +}); +// removes must be done high-to-low to keep indexes valid +gpioKeys.splice(108, 1); // remove GPIO3_12 +gpioKeys.splice(107, 1); // remove GPIO3_11 +gpioKeys.splice(25, 1); // remove GPIO0_25 +gpioKeys.splice(24, 1); // remove GPIO0_24 + +var eepromKeys = []; +for (var i = 0; i < 74; i++) { + eepromKeys.push("EEPROM_" + i); +} +expectedResults.push({ + "name": "EEPROM", + "search": /^EEPROM_/, + "keys": eepromKeys +}); + +var blueKeys = []; +for (var i = 1; i <= 6; i++) { + blueKeys.push("GP0_" + i); + blueKeys.push("GP1_" + i); + blueKeys.push("S1_1_" + i); + blueKeys.push("S1_2_" + i); + blueKeys.push("ADC_" + i); +} +for (var i = 2; i <= 6; i++) { + blueKeys.push("GPS_" + i); +} +for (var i = 1; i <= 4; i++) { + for (var j = 1; j <= 4; j++) { + blueKeys.push("E" + j + "_" + i); + } + blueKeys.push("I2C_" + i); + blueKeys.push("UT0_" + i); + blueKeys.push("UT1_" + i); + blueKeys.push("UT5_" + i); +} +for (var i = 1; i <= 3; i++) { + blueKeys.push("DSM2_" + i); +} +blueKeys.push("RED"); +blueKeys.push("GREEN"); +blueKeys.push("WIFI"); +blueKeys.push("BAT25"); +blueKeys.push("BAT50"); +blueKeys.push("BAT75"); +blueKeys.push("BAT100"); +blueKeys.push("PAUSE"); +blueKeys.push("MODE"); +expectedResults.push({ + "name": "BeagleBoneBlue", + "search": /^((E[1234]|GP[01]|GPS|S1_[12]|I2C|UT[015]|ADC|DSM2)_|RED|GREEN|WIFI|BAT|PAUSE|MODE)/, + "keys": blueKeys +}); + +var results = {}; + +for (var i = 0; i < expectedResults.length; i++) { + var er = expectedResults[i]; + exports['testBoneGetPinKeys' + er.name] = makeTest(i); +} + +function makeTest(i) { + var search = expectedResults[i].search; + var expected = expectedResults[i].keys.sort(bone.naturalCompare); + return (function (test) { + test.expect(2); + test.doesNotThrow(function () { + results = bone.getPinKeys(search).sort(bone.naturalCompare); + }); + test.ok(compareResults(results, expected)); + test.done(); + }); +} + +function compareResults(results, expected) { + console.log("results = " + JSON.stringify(results)); + console.log("expectedResults = " + JSON.stringify(expected)); + for (i in expected) { + if (results[i] != expected[i]) return (false); + } + return (true); +} \ No newline at end of file diff --git a/test/test-digitalread.js b/test/test-digitalread.js new file mode 100644 index 00000000..2986407c --- /dev/null +++ b/test/test-digitalread.js @@ -0,0 +1,39 @@ +var b = require('bonescript'); + +var pinKeys = []; +for (var i = 1; i <= 36; i++) { + pinKeys.push("P1_" + i); + pinKeys.push("P2_" + i); +} +for (var i = 1; i <= 46; i++) { + pinKeys.push("P8_" + i); + pinKeys.push("P9_" + i); +} +exports.testdigitalRead1 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + var y = b.digitalRead(pinKeys[x]); + test.ok(typeof y == 'number'); + } + test.done(); +} +exports.testdigitalRead2 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + b.digitalRead(pinKeys[x], function (x) { + test.ok(typeof x.value == 'number' && !x.err); + }); + if (x == pinKeys.length - 1) + test.done(); + } +} +exports.testdigitalRead3 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + b.digitalRead(pinKeys[x], function (err, value) { + test.ok(typeof value == 'number' && !err); + }); + if (x == pinKeys.length - 1) + test.done(); + } +} \ No newline at end of file diff --git a/test/test-digitalwrite.js b/test/test-digitalwrite.js new file mode 100644 index 00000000..28c4e795 --- /dev/null +++ b/test/test-digitalwrite.js @@ -0,0 +1,31 @@ +var b = require('bonescript'); + +var pinKeys = []; +for (var i = 1; i <= 36; i++) { + pinKeys.push("P1_" + i); + pinKeys.push("P2_" + i); +} +for (var i = 1; i <= 46; i++) { + pinKeys.push("P8_" + i); + pinKeys.push("P9_" + i); +} +pinKeys = pinKeys.concat(['USR0', 'USR1', 'USR2', 'USR3']); +exports.testdigitalwrite1 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + test.doesNotThrow(function () { + b.digitalWrite(pinKeys[x], b.HIGH); + }); + } + test.done(); +} +exports.testdigitalwrite2 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + b.digitalWrite(pinKeys[x], b.LOW, function () { + test.ok(true); + }); + if (x == pinKeys.length - 1) + test.done(); + } +} \ No newline at end of file diff --git a/test/test-ffi.js b/test/test-ffi.js new file mode 100644 index 00000000..df7b997d --- /dev/null +++ b/test/test-ffi.js @@ -0,0 +1,81 @@ +var b = require('bonescript'); +var fs = require('fs'); +var testDir = '/tmp/ffi-test'; +var Cfile = testDir + '/ffi-test'; +var Cfile1 = testDir + '/ffi-test1'; +var txtFile = testDir + '/txt-test.txt' +var txtFile1 = testDir + '/txt-test1.txt' +var args = { + 'dummy': ['int', ['void']] +}; +var text = "HELLO"; +var cCode = ` +#include +int dummy() +{ + printf("Hello, World!"); + return 0; +} +` +module.exports.testFFI = function (test) { + + test.expect(8); + if (!fs.existsSync(testDir)) { + fs.mkdirSync(testDir); + } + //test writetxtFile + b.writeTextFile(txtFile, text); + if (fs.existsSync(txtFile)) { + console.log("Write Text File Successful"); + test.ok(true); + } + //test readtxtFile + if (b.readTextFile(txtFile) == text) { + console.log("Read Text File Successful"); + test.ok(true); + } + //test mraaGPIO() + var mraaGPIO = b.mraaGPIO('P9_12'); + if (mraaGPIO === '0x3a') { + console.log("MRAA Library Load Successful"); + test.ok(true); + } + //test writeCModule + b.writeCModule(Cfile, cCode); + if (fs.existsSync(Cfile + '.c')) { + console.log("Write C Module Successful"); + test.ok(true); + } + //test loadCModule + var Cmodule = b.loadCModule(Cfile, args); + if (Cmodule == "ffi not loaded") { + console.log("Load C Module Unsuccesful(ffi not loaded)"); + test.ok(true); + } else { + var moduleRetVal = Cmodule.dummy(0); + //returns 0 + console.log("Load C Module Succesful, returned: " + moduleRetVal); + test.ok(moduleRetVal == 0); + } //test writetxtFile with callback + b.writeTextFile(txtFile1, text, function (x) { + if (!x.err) + test.ok(true); + onWriteTextFile(); + }); + //test readtxtFile with callback + function onWriteTextFile() { + b.readTextFile(txtFile1, function (err, data) { + if (!err && data == text) + test.ok(true); + onReadTextFile() + }) + } + //test writeCModule with callback + function onReadTextFile() { + b.writeCModule(Cfile1, cCode, function (x) { + if (!x.err) + test.ok(true); + test.done(); + }); + } +} \ No newline at end of file diff --git a/test/test-getpinmode.js b/test/test-getpinmode.js index 5b7daaa1..cb2189f9 100644 --- a/test/test-getpinmode.js +++ b/test/test-getpinmode.js @@ -1,108 +1,407 @@ //process.env.DEBUG = true; var b = require('bonescript'); -var expectedResults = [ - {"pin":"USR0","name":"USR0"}, - {"pin":"USR1","name":"USR1"}, - {"pin":"USR2","name":"USR2"}, - {"pin":"USR3","name":"USR3"}, - {"pin":"P8_1","name":"DGND"}, - {"pin":"P8_2","name":"DGND"}, - {"pin":"P8_3","name":"GPIO1_6"}, - {"pin":"P8_4","name":"GPIO1_7"}, - {"pin":"P8_5","name":"GPIO1_2"}, - {"pin":"P8_6","name":"GPIO1_3"}, - {"pin":"P8_7","name":"TIMER4"}, - {"pin":"P8_8","name":"TIMER7"}, - {"pin":"P8_9","name":"TIMER5"}, - {"pin":"P8_10","name":"TIMER6"}, - {"pin":"P8_11","name":"GPIO1_13"}, - {"pin":"P8_12","name":"GPIO1_12"}, - {"pin":"P8_13","name":"EHRPWM2B"}, - {"pin":"P8_14","name":"GPIO0_26"}, - {"pin":"P8_15","name":"GPIO1_15"}, - {"pin":"P8_16","name":"GPIO1_14"}, - {"pin":"P8_17","name":"GPIO0_27"}, - {"pin":"P8_18","name":"GPIO2_1"}, - {"pin":"P8_19","name":"EHRPWM2A"}, - {"pin":"P8_20","name":"GPIO1_31"}, - {"pin":"P8_21","name":"GPIO1_30"}, - {"pin":"P8_22","name":"GPIO1_5"}, - {"pin":"P8_23","name":"GPIO1_4"}, - {"pin":"P8_24","name":"GPIO1_1"}, - {"pin":"P8_25","name":"GPIO1_0"}, - {"pin":"P8_26","name":"GPIO1_29"}, - {"pin":"P8_27","name":"GPIO2_22"}, - {"pin":"P8_28","name":"GPIO2_24"}, - {"pin":"P8_29","name":"GPIO2_23"}, - {"pin":"P8_30","name":"GPIO2_25"}, - {"pin":"P8_31","name":"UART5_CTSN"}, - {"pin":"P8_32","name":"UART5_RTSN"}, - {"pin":"P8_33","name":"UART4_RTSN"}, - {"pin":"P8_34","name":"UART3_RTSN"}, - {"pin":"P8_35","name":"UART4_CTSN"}, - {"pin":"P8_36","name":"UART3_CTSN"}, - {"pin":"P8_37","name":"UART5_TXD"}, - {"pin":"P8_38","name":"UART5_RXD"}, - {"pin":"P8_39","name":"GPIO2_12"}, - {"pin":"P8_40","name":"GPIO2_13"}, - {"pin":"P8_41","name":"GPIO2_10"}, - {"pin":"P8_42","name":"GPIO2_11"}, - {"pin":"P8_43","name":"GPIO2_8"}, - {"pin":"P8_44","name":"GPIO2_9"}, - {"pin":"P8_45","name":"GPIO2_6"}, - {"pin":"P8_46","name":"GPIO2_7"}, - {"pin":"P9_1","name":"DGND"}, - {"pin":"P9_2","name":"DGND"}, - {"pin":"P9_3","name":"VDD_3V3"}, - {"pin":"P9_4","name":"VDD_3V3"}, - {"pin":"P9_5","name":"VDD_5V"}, - {"pin":"P9_6","name":"VDD_5V"}, - {"pin":"P9_7","name":"SYS_5V"}, - {"pin":"P9_8","name":"SYS_5V"}, - {"pin":"P9_9","name":"PWR_BUT"}, - {"pin":"P9_10","name":"SYS_RESETn"}, - {"pin":"P9_11","name":"UART4_RXD"}, - {"pin":"P9_12","name":"GPIO1_28"}, - {"pin":"P9_13","name":"UART4_TXD"}, - {"pin":"P9_14","name":"EHRPWM1A"}, - {"pin":"P9_15","name":"GPIO1_16"}, - {"pin":"P9_16","name":"EHRPWM1B"}, - {"pin":"P9_17","name":"I2C1_SCL"}, - {"pin":"P9_18","name":"I2C1_SDA"}, - {"pin":"P9_19","name":"I2C2_SCL"}, - {"pin":"P9_20","name":"I2C2_SDA"}, - {"pin":"P9_21","name":"UART2_TXD"}, - {"pin":"P9_22","name":"UART2_RXD"}, - {"pin":"P9_23","name":"GPIO1_17"}, - {"pin":"P9_24","name":"UART1_TXD"}, - {"pin":"P9_25","name":"GPIO3_21"}, - {"pin":"P9_26","name":"UART1_RXD"}, - {"pin":"P9_27","name":"GPIO3_19"}, - {"pin":"P9_28","name":"SPI1_CS0"}, - {"pin":"P9_29","name":"SPI1_D0"}, - {"pin":"P9_30","name":"SPI1_D1"}, - {"pin":"P9_31","name":"SPI1_SCLK"}, - {"pin":"P9_32","name":"VDD_ADC"}, - {"pin":"P9_33","name":"AIN4"}, - {"pin":"P9_34","name":"GNDA_ADC"}, - {"pin":"P9_35","name":"AIN6"}, - {"pin":"P9_36","name":"AIN5"}, - {"pin":"P9_37","name":"AIN2"}, - {"pin":"P9_38","name":"AIN3"}, - {"pin":"P9_39","name":"AIN0"}, - {"pin":"P9_40","name":"AIN1"}, - {"pin":"P9_41","name":"CLKOUT2"}, - {"pin":"P9_42","name":"GPIO0_7"}, - {"pin":"P9_43","name":"DGND"}, - {"pin":"P9_44","name":"DGND"}, - {"pin":"P9_45","name":"DGND"}, - {"pin":"P9_46","name":"DGND"}, +var expectedResults = [{ + "pin": "USR0", + "name": "USR0" + }, + { + "pin": "USR1", + "name": "USR1" + }, + { + "pin": "USR2", + "name": "USR2" + }, + { + "pin": "USR3", + "name": "USR3" + }, + { + "pin": "P8_1", + "name": "DGND" + }, + { + "pin": "P8_2", + "name": "DGND" + }, + { + "pin": "P8_3", + "name": "GPIO1_6" + }, + { + "pin": "P8_4", + "name": "GPIO1_7" + }, + { + "pin": "P8_5", + "name": "GPIO1_2" + }, + { + "pin": "P8_6", + "name": "GPIO1_3" + }, + { + "pin": "P8_7", + "name": "TIMER4" + }, + { + "pin": "P8_8", + "name": "TIMER7" + }, + { + "pin": "P8_9", + "name": "TIMER5" + }, + { + "pin": "P8_10", + "name": "TIMER6" + }, + { + "pin": "P8_11", + "name": "GPIO1_13" + }, + { + "pin": "P8_12", + "name": "GPIO1_12" + }, + { + "pin": "P8_13", + "name": "EHRPWM2B" + }, + { + "pin": "P8_14", + "name": "GPIO0_26" + }, + { + "pin": "P8_15", + "name": "GPIO1_15" + }, + { + "pin": "P8_16", + "name": "GPIO1_14" + }, + { + "pin": "P8_17", + "name": "GPIO0_27" + }, + { + "pin": "P8_18", + "name": "GPIO2_1" + }, + { + "pin": "P8_19", + "name": "EHRPWM2A" + }, + { + "pin": "P8_20", + "name": "GPIO1_31" + }, + { + "pin": "P8_21", + "name": "GPIO1_30" + }, + { + "pin": "P8_22", + "name": "GPIO1_5" + }, + { + "pin": "P8_23", + "name": "GPIO1_4" + }, + { + "pin": "P8_24", + "name": "GPIO1_1" + }, + { + "pin": "P8_25", + "name": "GPIO1_0" + }, + { + "pin": "P8_26", + "name": "GPIO1_29" + }, + { + "pin": "P8_27", + "name": "GPIO2_22" + }, + { + "pin": "P8_28", + "name": "GPIO2_24" + }, + { + "pin": "P8_29", + "name": "GPIO2_23" + }, + { + "pin": "P8_30", + "name": "GPIO2_25" + }, + { + "pin": "P8_31", + "name": "UART5_CTSN" + }, + { + "pin": "P8_32", + "name": "UART5_RTSN" + }, + { + "pin": "P8_33", + "name": "UART4_RTSN" + }, + { + "pin": "P8_34", + "name": "UART3_RTSN" + }, + { + "pin": "P8_35", + "name": "UART4_CTSN" + }, + { + "pin": "P8_36", + "name": "UART3_CTSN" + }, + { + "pin": "P8_37", + "name": "UART5_TXD" + }, + { + "pin": "P8_38", + "name": "UART5_RXD" + }, + { + "pin": "P8_39", + "name": "GPIO2_12" + }, + { + "pin": "P8_40", + "name": "GPIO2_13" + }, + { + "pin": "P8_41", + "name": "GPIO2_10" + }, + { + "pin": "P8_42", + "name": "GPIO2_11" + }, + { + "pin": "P8_43", + "name": "GPIO2_8" + }, + { + "pin": "P8_44", + "name": "GPIO2_9" + }, + { + "pin": "P8_45", + "name": "GPIO2_6" + }, + { + "pin": "P8_46", + "name": "GPIO2_7" + }, + { + "pin": "P9_1", + "name": "DGND" + }, + { + "pin": "P9_2", + "name": "DGND" + }, + { + "pin": "P9_3", + "name": "VDD_3V3" + }, + { + "pin": "P9_4", + "name": "VDD_3V3" + }, + { + "pin": "P9_5", + "name": "VDD_5V" + }, + { + "pin": "P9_6", + "name": "VDD_5V" + }, + { + "pin": "P9_7", + "name": "SYS_5V" + }, + { + "pin": "P9_8", + "name": "SYS_5V" + }, + { + "pin": "P9_9", + "name": "PWR_BUT" + }, + { + "pin": "P9_10", + "name": "SYS_RESETn" + }, + { + "pin": "P9_11", + "name": "UART4_RXD" + }, + { + "pin": "P9_12", + "name": "GPIO1_28" + }, + { + "pin": "P9_13", + "name": "UART4_TXD" + }, + { + "pin": "P9_14", + "name": "EHRPWM1A" + }, + { + "pin": "P9_15", + "name": "GPIO1_16" + }, + { + "pin": "P9_15B", + "name": "GPIO1_16" + }, + { + "pin": "P9_16", + "name": "EHRPWM1B" + }, + { + "pin": "P9_17", + "name": "I2C1_SCL" + }, + { + "pin": "P9_18", + "name": "I2C1_SDA" + }, + { + "pin": "P9_19", + "name": "I2C2_SCL" + }, + { + "pin": "P9_20", + "name": "I2C2_SDA" + }, + { + "pin": "P9_21", + "name": "UART2_TXD" + }, + { + "pin": "P9_22", + "name": "UART2_RXD" + }, + { + "pin": "P9_23", + "name": "GPIO1_17" + }, + { + "pin": "P9_24", + "name": "UART1_TXD" + }, + { + "pin": "P9_25", + "name": "GPIO3_21" + }, + { + "pin": "P9_26", + "name": "UART1_RXD" + }, + { + "pin": "P9_27", + "name": "GPIO3_19" + }, + { + "pin": "P9_28", + "name": "SPI1_CS0" + }, + { + "pin": "P9_29", + "name": "SPI1_D0" + }, + { + "pin": "P9_30", + "name": "SPI1_D1" + }, + { + "pin": "P9_31", + "name": "SPI1_SCLK" + }, + { + "pin": "P9_32", + "name": "VDD_ADC" + }, + { + "pin": "P9_33", + "name": "AIN4" + }, + { + "pin": "P9_34", + "name": "GNDA_ADC" + }, + { + "pin": "P9_35", + "name": "AIN6" + }, + { + "pin": "P9_36", + "name": "AIN5" + }, + { + "pin": "P9_37", + "name": "AIN2" + }, + { + "pin": "P9_38", + "name": "AIN3" + }, + { + "pin": "P9_39", + "name": "AIN0" + }, + { + "pin": "P9_40", + "name": "AIN1" + }, + { + "pin": "P9_41", + "name": "CLKOUT2" + }, + { + "pin": "P9_41B", + "name": "CLKOUT2" + }, + { + "pin": "P9_42", + "name": "GPIO0_7" + }, + { + "pin": "P9_42B", + "name": "GPIO0_7" + }, + { + "pin": "P9_43", + "name": "DGND" + }, + { + "pin": "P9_44", + "name": "DGND" + }, + { + "pin": "P9_45", + "name": "DGND" + }, + { + "pin": "P9_46", + "name": "DGND" + }, ]; var results = {}; -for(var i=0; i < expectedResults.length; i++) { +for (var i = 0; i < expectedResults.length; i++) { var er = expectedResults[i]; exports['testGetPinMode' + er.pin] = makeTest(i); } @@ -110,10 +409,15 @@ for(var i=0; i < expectedResults.length; i++) { function makeTest(i) { var pin = expectedResults[i].pin; var expected = expectedResults[i]; - return(function(test) { + return (function (test) { test.expect(2); - test.doesNotThrow(function() { + test.doesNotThrow(function () { results = b.getPinMode(pin); + // Only compare name to work on travis-ci + results = { + "pin": results.pin, + "name": results.name + }; }); test.ok(compareResults(results, expected)); test.done(); @@ -123,8 +427,8 @@ function makeTest(i) { function compareResults(results, expected) { console.log("results = " + JSON.stringify(results)); console.log("expectedResults = " + JSON.stringify(expected)); - for(i in expected) { - if(results[i] != expected[i]) return(false); + for (i in expected) { + if (results[i] != expected[i]) return (false); } - return(true); -} + return (true); +} \ No newline at end of file diff --git a/test/test-lint.js b/test/test-lint.js new file mode 100644 index 00000000..0da923e1 --- /dev/null +++ b/test/test-lint.js @@ -0,0 +1,39 @@ +module.exports = {}; +var beautify = require('../node_modules/js-beautify'); +var fs = require('fs'); +var path = require('path'); + +var config = JSON.parse(fs.readFileSync('./lint-config.json')); +var index = 0; + +testDir("./"); +testDir("./src/"); +testDir("./test/"); + +function testDir(dir) { + var files = fs.readdirSync(dir); + files.forEach(function (file, index) { + testFile(dir + file); + }); +} + +function testFile(fileToTest) { + var stat = fs.statSync(fileToTest); + if (stat.isFile() && fileToTest.match(/js$/)) { + //console.log("Adding lint test for " + fileToTest); + index++; + module.exports["testLint" + index] = function (test) { + var inFile = "a"; + var outFile = "b"; + test.expect(2); + test.doesNotThrow(function () { + console.log("Running lint on " + fileToTest); + inFile = fs.readFileSync(fileToTest, 'utf8'); + outFile = beautify.js(inFile, config); + //fs.writeFileSync(fileToTest + ".lint", outFile); + }); + test.equal(inFile, outFile); + test.done(); + }; + } +} \ No newline at end of file diff --git a/test/test-math.js b/test/test-math.js new file mode 100644 index 00000000..582fa280 --- /dev/null +++ b/test/test-math.js @@ -0,0 +1,20 @@ +var math = require('../src/functions'); +var b = require('bonescript'); + +var mathFns = Object.getOwnPropertyNames(math); +for (var x in mathFns) + mathFns[x] = b[mathFns[x]]; + +function getRandomInt() { + return Math.floor(Math.random() * 100); +} + +exports.testMathFunctions = function (test) { + test.expect(mathFns.length - 1); //randomseed does not return anything + for (var x in mathFns) { + var result = mathFns[x].call(null, getRandomInt(), getRandomInt(), getRandomInt(), getRandomInt(), getRandomInt()); + if (typeof result == 'number') //assuming every math function returns a number + test.ok(true); + } + test.done(); +} \ No newline at end of file diff --git a/test/test-pinMode.js b/test/test-pinMode.js new file mode 100644 index 00000000..09ef1c16 --- /dev/null +++ b/test/test-pinMode.js @@ -0,0 +1,47 @@ +var b = require('bonescript'); + +var pinKeys = []; +for (var i = 1; i <= 36; i++) { + pinKeys.push("P1_" + i); + pinKeys.push("P2_" + i); +} +for (var i = 1; i <= 46; i++) { + pinKeys.push("P8_" + i); + pinKeys.push("P9_" + i); +} +for (var i = 0; i <= 7; i++) { + pinKeys.push("A" + i); +} +pinKeys = pinKeys.concat(['USR0', 'USR1', 'USR2', 'USR3']); +exports.testpinMode1 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + test.doesNotThrow(function () { + b.pinMode(pinKeys[x], b.OUTPUT); + b.pinMode(pinKeys[x], b.INPUT); + b.pinMode(pinKeys[x], b.INPUT_PULLUP); + b.pinMode(pinKeys[x], b.ANALOG_OUTPUT); + }); + } + test.done(); +} +exports.testpinMode2 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + b.pinMode(pinKeys[x], b.OUTPUT, 7, 'pullup', 'fast', function (x) { + test.ok(x.value && !x.err); + }); + if (x == pinKeys.length - 1) + test.done(); + } +} +exports.testpinMode3 = function (test) { + test.expect(pinKeys.length); + for (var x in pinKeys) { + b.pinMode(pinKeys[x], b.OUTPUT, 7, 'pullup', 'fast', function (err, value) { + test.ok(value && !err); + }); + if (x == pinKeys.length - 1) + test.done(); + } +} \ No newline at end of file diff --git a/test/test-rpc.js b/test/test-rpc.js new file mode 100644 index 00000000..0bf90792 --- /dev/null +++ b/test/test-rpc.js @@ -0,0 +1,232 @@ +var server = require('bonescript'); +var bonescript = require('../src/bonescript'); +var myserver = null; + +exports.setUp = function (callback) { + server.serverStart(8000, process.cwd(), null, mycb); + + function mycb(serverObj) { + myserver = serverObj.server; + callback(); + } +}; + +exports.testRPC_callbacks = function (test) { + test.expect(15); + + bonescript.startClient({ + address: '127.0.0.1', + port: 8000 + }, getPlatformTest_oldstyle); + + function getPlatformTest_oldstyle() { + var b = bonescript.require('bonescript'); + b.getPlatform(function (platform) { + console.log("***getPlatformTest_oldstyle***"); + console.log(platform); + console.log('Name: ' + platform.name); + console.log('Version: ' + platform.bonescript); + getPlatformTest_nodestyle(platform); + }); + } + + function getPlatformTest_nodestyle(platform_) { + console.log('here'); + var b = bonescript.require('bonescript'); + b.getPlatform(function (err, platform) { + console.log("***getPlatformTest_nodestyle***"); + console.log(platform); + console.log('Name: ' + platform.name); + console.log('Version: ' + platform.bonescript); + test.equals(platform.name, platform_.name); + test.equals(platform.bonescript, platform_.bonescript); + pinModeTest_oldstyle(); + }); + } + + function pinModeTest_oldstyle() { + var b = bonescript.require('bonescript'); + b.pinMode("P8_13", b.OUTPUT, 7, 'pullup', 'fast', printStatus); + + function printStatus(x) { + console.log("***pinModeTest_oldstyle***"); + console.log('value = ' + x.value); + console.log('err = ' + x.err); + pinModeTest_nodestyle(x); + } + } + + function pinModeTest_nodestyle(x) { + var b = bonescript.require('bonescript'); + b.pinMode("P8_13", b.OUTPUT, 7, 'pullup', 'fast', printStatus); + + function printStatus(err, value) { + console.log("***pinModeTest_nodestyle***"); + console.log('value = ' + value); + console.log('err = ' + err); + test.equals(x.err, err); + test.equals(x.value, value); + getPinModeTest_oldstyle(); + } + } + + function getPinModeTest_oldstyle() { + var b = bonescript.require('bonescript'); + b.getPinMode("P8_13", printPinMux); + + function printPinMux(x) { + console.log("***getPinModeTest_oldstyle***"); + console.log('mux = ' + x.mux); + console.log('pullup = ' + x.pullup); + console.log('slew = ' + x.slew); + console.log('options = ' + x.options.join(',')); + console.log('err = ' + x.err); + getPinModeTest_nodestyle(x) + } + } + + function getPinModeTest_nodestyle(x) { + var b = bonescript.require('bonescript'); + b.getPinMode("P8_13", printPinMux); + + function printPinMux(err, resp) { + console.log("***getPinModeTest_nodestyle***"); + console.log('mux = ' + resp.mux); + console.log('pullup = ' + resp.pullup); + console.log('slew = ' + resp.slew); + console.log('options = ' + resp.options.join(',')); + console.log('err = ' + resp.err); + test.equals(x.mux, resp.mux); + test.equals(x.pullup, resp.pullup); + test.equals(x.slew, resp.slew); + test.equals(x.options.join(','), resp.options.join(',')); + digitalWriteTest(); + } + } + + function digitalWriteTest() { + var b = bonescript.require('bonescript'); + b.digitalWrite('USR0', b.HIGH, printErr); + + function printErr(x) { + console.log("***digitalWriteTest***"); + console.log('err = ' + x.err); + test.ok(true); + digitalReadTest_oldstyle(); + } + } + + function digitalReadTest_oldstyle() { + var b = bonescript.require('bonescript'); + b.digitalRead('P8_19', printStatus); + + function printStatus(x) { + console.log("***digitalReadTest_oldstyle***"); + console.log('x.value = ' + x.value); + console.log('x.err = ' + x.err); + digitalReadTest_nodestyle(x) + } + } + + function digitalReadTest_nodestyle(x) { + var b = bonescript.require('bonescript'); + b.digitalRead('P8_19', printStatus); + + function printStatus(err, value) { + console.log("***digitalReadTest_nodestyle***"); + console.log('x.value = ' + value); + console.log('x.err = ' + err); + test.equals(x.value, value); + analogWriteTest() + } + } + + + function analogWriteTest() { + var b = bonescript.require('bonescript'); + b.analogWrite('P9_14', 0.7, 2000, printJSON); + + function printJSON(x) { + console.log("***analogWriteTest***"); + console.log(JSON.stringify(x)); + test.ok(true); + analogReadTest_oldstyle(); + + } + } + + function analogReadTest_oldstyle() { + var b = bonescript.require('bonescript'); + b.analogRead('P9_36', printStatus); + + function printStatus(x) { + console.log("***analogReadTest_oldstyle***"); + console.log('x.value = ' + x.value); + console.log('x.err = ' + x.err); + analogReadTest_nodestyle(x); + } + } + + function analogReadTest_nodestyle(x) { + var b = bonescript.require('bonescript'); + b.analogRead('P9_36', printStatus); + + function printStatus(err, value) { + console.log("***analogReadTest_nodestyle***"); + console.log('x.value = ' + value); + console.log('x.err = ' + err); + test.equals(x.value, value); + attachInterruptTest_oldstyle() + } + } + + function attachInterruptTest_oldstyle() { + var b = bonescript.require('bonescript'); + b.attachInterrupt('P8_19', true, b.CHANGE, interruptCallback); + + function interruptCallback(x) { + console.log("***attachInterruptTest_oldstyle***"); + console.log(JSON.stringify(x)); + attachInterruptTest_nodestyle(x) + } + } + + function attachInterruptTest_nodestyle(x) { + var b = bonescript.require('bonescript'); + b.attachInterrupt('P8_19', true, b.CHANGE, interruptCallback); + + function interruptCallback(err, resp) { + console.log("***attachInterruptTest_nodestyle***"); + console.log(JSON.stringify(resp)); + test.equals(x.pin.name, resp.pin.name); + readTextFileTest_oldstyle(); + } + } + + function readTextFileTest_oldstyle() { + var b = bonescript.require('bonescript'); + b.readTextFile('/etc/fstab', printStatus); + + function printStatus(x) { + console.log("***readTextFileTest_oldstyle***"); + console.log('x.data = ' + x.data); + console.log('x.err = ' + x.err); + readTextFileTest_nodestyle(x); + } + } + + function readTextFileTest_nodestyle(x) { + var b = bonescript.require('bonescript'); + b.readTextFile('/etc/fstab', printStatus); + + function printStatus(err, data) { + console.log("***readTextFileTest_nodestyle***"); + console.log('x.data = ' + data); + console.log('x.err = ' + err); + test.equals(x.data, data); + test.equals(x.err, err); + myserver.close(); + test.done(); + } + } +} \ No newline at end of file diff --git a/test/test-rpc_secure.js b/test/test-rpc_secure.js new file mode 100644 index 00000000..2e17ebc6 --- /dev/null +++ b/test/test-rpc_secure.js @@ -0,0 +1,48 @@ +var server = require('bonescript'); +var bonescript = require('../src/bonescript'); +var myserver = null; + +exports.setUp = function (callback) { + server.serverStart(8000, process.cwd(), { // create a secure server by supplying credentials + data: 'testpass', + hash: false + }, mycb); + + function mycb(serverobj) { + myserver = serverobj.server; + callback(); + } +}; + +exports.testRPC_secure1 = function (test) { + test.expect(1); + bonescript.startClient({ // this should throw an authentication error + address: '127.0.0.1', + port: 8000, + password: 'tdestpass' + }, function () {}); + process.on('uncaughtException', function (err) { + console.log(err.toString()); + test.equals(err.toString(), 'Error: Authentication Failed : incorrect passphrase !!'); + myserver.close(); + test.done(); + }); +} + +exports.testRPC_secure2 = function (test) { + test.expect(1); + bonescript.startClient({ + address: '127.0.0.1', + port: 8000, + password: 'testpass' // will not throw any error + }, function () { + var b = bonescript.require('bonescript'); + b.getPlatform(function (platform) { + console.log('Name: ' + platform.name); + console.log('Version: ' + platform.bonescript); + test.ok(platform != 'undefined'); + myserver.close(); + test.done(); + }); + }); +} \ No newline at end of file diff --git a/test/test-sanity.js b/test/test-sanity.js index 08695c50..20b053e1 100644 --- a/test/test-sanity.js +++ b/test/test-sanity.js @@ -1,12 +1,12 @@ //process.env.DEBUG = true; -exports.testSanity1 = function(test) { +exports.testSanity1 = function (test) { test.expect(1); - test.doesNotThrow(function() { + test.doesNotThrow(function () { var b = require('bonescript'); console.log('Name: ' + b.getPlatform().name); console.log('Version: ' + b.getPlatform().bonescript); - }); - test.done(); -} + }); + test.done(); +} \ No newline at end of file