├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples └── i2c_multiple_adafruitled7Segs.js ├── index.js ├── lib ├── analog.js ├── bone.js ├── constants.json ├── digital.js ├── eeprom.js ├── hw_simulator.js ├── hw_universal.js ├── i2c.js ├── pinmap.json ├── pwm.js ├── serial.js └── watchdog.js ├── package.json └── test ├── analog.js ├── digital.js ├── i2c.js ├── interrupt.js ├── pinmodesync.js ├── serial.js └── watchdog.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ChangeLog 2 | --------- 3 | 4 | __Check https://github.com/theoctal/octalbonescript/releases for changelog.__ 5 | 6 | ### 0.4.9 7 | * This version and all pervious versions were bug fixes 8 | 9 | ### 0.4.4 10 | * Bug fixes in analogWrite function. ```startAnalog(pin, callback)``` function added 11 | 12 | ### 0.4.3 13 | * All the express, socket.io and cloud9 dependencies removed. The library now focuses only on providing better I/O functionality for BeagleBone rather than serving to cloud9 IDE 14 | * Removed usage of FFI and moved to 'shelljs' to compile universal device tree 15 | 16 | ### 0.4.2 17 | * ```stopAnalog(pin, callback)``` function added to ust stop the analog output on given pin. Call ```analogWrite``` again on that pin to start analog output (see v0.4.4 for update) 18 | 19 | ### 0.4.1 20 | * Better warning in pinMode 21 | 22 | ### 0.4.0 (Major update. Introduces BC break) 23 | 24 | * Support for 3.2 kernel has been dropped 25 | * Individual pin based "hw_capemgr" is no longer supported. Universal cape manager handles all the tasks of pin muxing 26 | * Required nodejs version is now >= 0.10.24. Effecively, the octalbonescript won't install on Angstrom distribution 27 | * __BC Break__ ```pinMode``` function now takes only 3 arguments -> (pin, direction, callback). This function now asserts mode automatically and sets slew rate as fast. Additional direction variable ```INPUT_PULLDOWN``` is also added. 28 | * __BC Break__ ```pinMode``` function is now fully async unlike original bonescript. Please use callback to know the status. 29 | * Support for WatchDog timer added. It can be accessed via ```startWatchdog()``` and ```stopWatchdog()``` functions 30 | 31 | ### 0.3.1 32 | 33 | * Small bug fixes 34 | 35 | ### 0.3.0 36 | 37 | * Universal and HDMI cape loaded as per compatibility 38 | * 2 new dts overlays bs_univ_template and bs_hdmi_template added 39 | * Changed name of bone.js to pinmap.js to better reflect its content 40 | * Pins P8_7, P8_8, P8_9 should now be used as P8_07, P8_08, P8_09 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Jason Kridner , Aditya Patadia 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OctalBoneScript 2 | =============== 3 | 4 | __This package is abandoned and no longer maintained. Please use https://www.npmjs.com/package/beaglebone-io to interact with BeagleBone and its variants.__ 5 | 6 | [![npm version](https://badge.fury.io/js/octalbonescript.svg)](https://badge.fury.io/js/octalbonescript) 7 | 8 | A more stable, continuously tested and better node.js library for scripting BeagleBone. This is alternative to [bonescript](https://github.com/jadonk/bonescript) library. 9 | 10 | __v1.0.0 introduces major BC breaks. Please refer to [releases](https://github.com/theoctal/octalbonescript/releases) to see the changes made in latest version.__ 11 | 12 | Installation 13 | ------------ 14 | Recommended method to install OctalBoneScript is to add following line in your project ```package.json``` file. 15 | 16 | ```json 17 | 18 | "octalbonescript" : "1.3.x" 19 | 20 | ``` 21 | 22 | If you are running nodejs v0.10.x, you should use 1.1.x branch. 23 | 24 | ```json 25 | 26 | "octalbonescript" : "1.1.x" 27 | 28 | ``` 29 | 30 | If you are running kernel 3.8 i.e. Debian 7.9 or below, you should use 1.0.x branch. 31 | 32 | ```json 33 | 34 | "octalbonescript" : "1.0.x" 35 | 36 | ``` 37 | 38 | After adding this line, you should run ``` npm install ``` command from that project directory to install OBS. Another method is to directly ```cd``` to project directory and run ```npm install octalbonescript``` command. 39 | 40 | If you must install OBS globally, you must run following command as root. 41 | 42 | ```sh 43 | 44 | npm install -g --unsafe-perm octalbonescript 45 | 46 | ``` 47 | 48 | Please note that OBS does not recommend Linux Angstrom. We strongly recommend that you upgrade your BeagleBone to Debian by following link given below: 49 | 50 | [http://beagleboard.org/getting-started#update](http://beagleboard.org/getting-started#update) 51 | 52 | Examples 53 | -------- 54 | Latest code docs, examples and **migration guide** from original bonescript are available at following link: 55 | 56 | [https://github.com/theoctal/octalbonescript/wiki](https://github.com/theoctal/octalbonescript/wiki) 57 | 58 | Fork 59 | ---- 60 | This is a fork of [bonescript](https://github.com/jadonk/bonescript). Some APIs are changed in v1.0.0, and we have changed many things under the hood leading to a much better, more functional and faster version of the original library. 61 | 62 | This fork is created to make bonescript more feature rich, faster, fix bugs and make it work in 63 | simulator mode under Mac OSX and Linux. 64 | 65 | We encourage you to report issues rightaway if you face any. We will try our best to be of help. 66 | 67 | Contributors 68 | ------------ 69 | This [fork](https://github.com/ruth0000/octalbonescript_capemgr4_1) of OBS was very helpful in making OBS compatible with 4.1 kernel. 70 | 71 | I also thank [psiphi75](https://github.com/psiphi75) who funded OBS transition to 4.1 kernel. 72 | 73 | Donate 74 | ------ 75 | I have kept OBS updated and working since May 2014 and I will continue to do so. This ongoing development takes lot of my personal time. 76 | 77 | If you use OBS in commercial projects, please consider donating some money as it supports ongoing development. 78 | 79 | Bitcoin address: **15v6b7AP7TVc8PASGxqddYPeNW1kA7ydFh** 80 | -------------------------------------------------------------------------------- /examples/i2c_multiple_adafruitled7Segs.js: -------------------------------------------------------------------------------- 1 | // Created by Andrew DeVries, Digital Example LLC move to test path + address to allow multiple i2c slaves Issue #68 2 | 3 | 4 | //Sugested this be run with Debug enabled so can view Bone debug 5 | //sudo DEBUG=bone node testBone.js 6 | // Test coded to use Qty 2 adafruit LED 7 Segment displays https://www.adafruit.com/products/879 7 | // on the second LED 7 Segment display solder pads A1 so its i2c address is moved from default 0x70 to 0x71 8 | 9 | var boneScript; 10 | 11 | try { 12 | //diable autoload of cape in octalbone until issue #67 13 | // if running the command 'cat /sys/devices/platform/bone_capemgr/slots' output is 14 | //0: PF---- -1 15 | //1: PF---- -1 16 | //2: PF---- -1 17 | //3: PF---- -1 18 | // with no 4th or greater option of the universal cap being set then removing this line may resolve 19 | // This does npt work on the BeagleBoneGreen the current AUTO_LOAD_CAPE logic doesn't load the correct overlay for the BBG so it errors. 20 | process.env['AUTO_LOAD_CAPE'] = '0'; 21 | //boneScript = require('bonescript'); 22 | boneScript = require('octalbonescript'); 23 | boneScript.getPlatform(function (err, x) { 24 | console.log('bonescript getPlatform'); 25 | // console.log('version = ' + x.version); 26 | console.log('serialNumber = ' + x.serialNumber); 27 | console.log('dogtag = ' + x.dogtag); 28 | }); 29 | 30 | //Adafruit LED Backpack 7 Segment Registers 31 | var HT16K33_BLINK_CMD = 0x80; 32 | var HT16K33_BLINK_DISPLAYON = 0x01; 33 | var HT16K33_BLINK_OFF = 0; 34 | var HT16K33_BLINK_2HZ = 1; 35 | var HT16K33_BLINK_1HZ = 2; 36 | var HT16K33_BLINK_HALFHZ = 3; 37 | var HT16K33_CMD_BRIGHTNESS = 0xE0; 38 | var HT16K33_CMD_SYSTEM = 0x20; 39 | var buffer = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 40 | var digits = [ 41 | 0x3F, //0 42 | 0x06, //1 43 | 0x5B, //2 44 | 0x4F, //3 45 | 0x66, //4 46 | 0x6D, //5 47 | 0x7D, //6 48 | 0x07, //7 49 | 0x7F, //8 50 | 0x6F, //9 51 | 0x77, //A 52 | 0x7C, //B 53 | 0x39, //C 54 | 0x5E, //D 55 | 0x79, //E 56 | 0x71, //F 57 | 0x00 //blank 58 | ]; 59 | 60 | 61 | 62 | //Method to open i2c backpacks and write 00:00 to the diplays so you know they are connected correctly 63 | var testI2cOpen = function (i2cDevice, i2cAddress, Callback) { 64 | 65 | boneScript.i2c.open(i2cDevice, i2cAddress, 66 | function () { 67 | //Not realy used not sure why it is needed 68 | console.log('bonescript i2c.open handler'); 69 | }, 70 | function (err, port) { 71 | 72 | if (err) { 73 | debug('bonescript i2c.open error %', err); 74 | console.log('bonescript i2c.open Error'); 75 | console.dir(err, { depth: null }); 76 | debug('bonescript i2c.open error %s', err); 77 | if (Callback) { 78 | Callback(err, null); 79 | } 80 | } else { 81 | //i2cdevice = port; 82 | console.log('bonescript i2c.open success ', port); 83 | // Turn on the LED Ocillator 84 | //port.setAddress(objOptions.I2CAddress); 85 | port.writeBytes(HT16K33_CMD_SYSTEM | HT16K33_BLINK_DISPLAYON, [0x00], 86 | function (err) { 87 | if (err) { 88 | console.log('Error in init DisplayOn %s', err); 89 | if (Callback) { 90 | Callback(err, null); 91 | } 92 | } else { 93 | console.log('ocillator enabled ' + i2cAddress + " device " + i2cDevice); 94 | //i2cdevice.setAddress(objOptions.I2CAddress); 95 | port.writeBytes(HT16K33_BLINK_CMD | 0x01, [0x00], function (err) { 96 | if (err) { 97 | console.log('Error in init setBlinkRate %s', err); 98 | if (Callback) { 99 | Callback(err, null); 100 | } 101 | } else { 102 | console.log('display enabled ' + i2cAddress + " device " + i2cDevice); 103 | //i2cdevice.setAddress(objOptions.I2CAddress); 104 | port.writeBytes(HT16K33_CMD_BRIGHTNESS | 15, [0x00], function (err) { 105 | if (err) { 106 | console.log('Error in init setBrightness %s', err); 107 | } else { 108 | console.log('Brightness set to high ' + i2cAddress + " device " + i2cDevice); 109 | //i2cdevice.setAddress(objOptions.I2CAddress); 110 | port.writeBytes([0x00], [digits[0], 0x00, digits[0], 0x00, 0x00, 0x00, digits[0], 0x00, digits[0], 0x00], function (err) { 111 | if (err) { 112 | console.log('Error in write zeros ' + i2cAddress + " device " + i2cDevice, err); 113 | } else { 114 | console.log('wrote zeros ' + i2cAddress + " device " + i2cDevice); 115 | } 116 | }); 117 | if (Callback) { 118 | Callback(err, port); 119 | } 120 | } 121 | }); // setBrightness 122 | } 123 | }); // setBlinkRate 124 | } 125 | }); //WriteData // oscillator on 126 | 127 | } 128 | }, 129 | function (err, port) { 130 | console.log('bonescript adafruitLedBackpack i2c.open'); 131 | 132 | } 133 | ); // boneScript i2c Open 134 | } 135 | 136 | 137 | 138 | //Now Test multiple i2c devices same port using 2 adafruit i2c LED 7 segment displays via the adafruit LEDBacpack HT16K33 139 | //https://www.adafruit.com/products/879 140 | // 141 | var LedI2cDevicePath = '/dev/i2c-1'; 142 | var LedI2cAddress1 = '0x70'; 143 | var LedI2cAddress2 = '0x71'; 144 | 145 | 146 | 147 | // Open and write 1234 to LED Backpack 1 148 | var LedI2cBackpack1; 149 | testI2cOpen(LedI2cDevicePath, LedI2cAddress1, function (err, i2cPort) { 150 | if (err) { 151 | console.log(' LedI2cBackpack1 errored ' + err); 152 | } else { 153 | console.log(' LedI2cBackpack1 success '); 154 | LedI2cBackpack1 = i2cPort; 155 | LedI2cBackpack1.writeBytes([0x00], [digits[1], 0x00, digits[1], 0x00, 0x02, 0x00, digits[1], 0x00, digits[1], 0x00], function (err) { 156 | if (err) { 157 | console.log('LedI2cBackpack1 Error in write 11:11', err); 158 | } else { 159 | console.log('LedI2cBackpack1 wrote 11:11 ', LedI2cBackpack1); 160 | } 161 | }); 162 | } 163 | 164 | }); 165 | 166 | // Open and write 1234 to LED Backpack 1 167 | var LedI2cBackpack2; 168 | testI2cOpen(LedI2cDevicePath, LedI2cAddress2, function (err, i2cPort) { 169 | if (err) { 170 | console.log(' LedI2cBackpack2 errored ' + err); 171 | } else { 172 | console.log(' LedI2cBackpack2 success '); 173 | LedI2cBackpack2 = i2cPort; 174 | LedI2cBackpack2.writeBytes([0x00], [digits[2], 0x00, digits[2], 0x00, 0x02, 0x00, digits[2], 0x00, digits[2], 0x00], function (err) { 175 | if (err) { 176 | console.log('LedI2cBackpack2 Error in write 22:22', err); 177 | } else { 178 | console.log('LedI2cBackpack2 wrote 22:22 ', LedI2cBackpack2); 179 | } 180 | // Another way to reuse the device but change address on the return but this will causes issues 181 | // LedI2cBackpack2.address = LedI2cAddress1; 182 | //LedI2cBackpack2.writeBytes([0x00], [digits[5], 0x00, digits[6], 0x00, 0x02, 0x00, digits[7], 0x00, digits[8], 0x00], function (err) { 183 | // if (err) { 184 | // console.log('LedI2cBackpack2 Error in write 12:34', err); 185 | // } else { 186 | // console.log('LedI2cBackpack2 wrote 12:34 ', LedI2cBackpack2); 187 | // } 188 | //}); 189 | }); 190 | 191 | } 192 | 193 | }); 194 | 195 | 196 | } catch (e) { 197 | console.log(e); 198 | } 199 | 200 | 201 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2011 - Texas Instruments, Jason Kridner 2 | // 3 | // Modified by Aditya Patadia, Octal Consulting LLP 4 | var fs = require('fs'); 5 | var child_process = require('child_process'); 6 | var debug = require('debug')('bone'); 7 | var os = require('os'); 8 | var epoll = require('epoll'); 9 | var verror = require('verror'); 10 | var pinmap = require('./lib/pinmap'); 11 | var serial = require('./lib/serial'); 12 | var i2c = require('./lib/i2c'); 13 | var bone = require('./lib/bone'); 14 | var package_json = require('./package.json'); 15 | var g = require('./lib/constants'); 16 | 17 | var f = {}; 18 | 19 | // Keep track of allocated resources 20 | var gpio = {}; 21 | var gpioInt = {}; 22 | var pwm = {}; 23 | 24 | // Detect if we are on a Beagle 25 | var hw = null; 26 | 27 | if (os.type() === 'Linux' && os.arch() === 'arm') { 28 | 29 | debug('Using Universal Cape interface'); 30 | hw = require('./lib/hw_universal'); 31 | 32 | // AUTO_LOAD_CAPE can be used to turn off the autoloading of capes. 33 | if (typeof process.env.AUTO_LOAD_CAPE === 'undefined' || process.env.AUTO_LOAD_CAPE === '1') { 34 | debug('Checking for Universal Cape interface... prevent with AUTO_LOAD_CAPE=0'); 35 | if (bone.is_cape_universal_loaded() == false) { 36 | debug('No Universal Cape interface found will attempt to load...'); 37 | bone.load_universal_cape(); 38 | } else { 39 | debug('Universal Cape interface already loaded ...'); 40 | } 41 | 42 | } 43 | 44 | } else { 45 | hw = require('./lib/hw_simulator'); 46 | debug('Using simulator mode'); 47 | } 48 | 49 | 50 | f.loadCape = function(name) { 51 | var result = bone.load_dt_sync(name); 52 | if (name.indexOf('cape-universal') >= 0) { 53 | enableAnalogInputs(); 54 | } 55 | return result; 56 | 57 | function enableAnalogInputs() { 58 | debug('Enabling analog inputs'); 59 | hw.analog.enable(); 60 | } 61 | 62 | }; 63 | 64 | 65 | f.unloadCape = function(name) { 66 | return bone.unload_dt_sync(name); 67 | }; 68 | 69 | 70 | 71 | // returned object has: 72 | // mux: index of mux mode 73 | // options: array of mode names 74 | // slew: 'fast' or 'slow' 75 | // rx: 'enabled' or 'disabled' 76 | // pullup: 'diabled', 'pullup' or 'pulldown' 77 | // pin: key string for pin 78 | // name: pin name 79 | // pwm: object if pwm enabled, undefind otherwise 80 | // freq: frequency of PWM 81 | // value: duty cycle of PWM as number between 0 and 1 82 | // gpio: object if GPIO enabled, undefined otherwise 83 | // active: GPIO is enabled by the kernel 84 | // allocated: boolean for if it is allocated by this application 85 | // direction: 'in' or 'out' (allocated might be false) 86 | f.getPinMode = function(pin, callback) { 87 | if (typeof callback != 'function') { 88 | throw new verror("getPinMode() requires callback function"); 89 | } 90 | if (pin) { 91 | pin = bone.getpin(pin); 92 | } else { 93 | throw new verror("Please provide valid pin as first argument"); 94 | } 95 | debug('getPinMode(' + pin.key + ')'); 96 | var mode = { 97 | 'pin': pin.key, 98 | 'name': pin.name 99 | }; 100 | if (pin.modes) mode.modes = pin.modes; 101 | 102 | // Get PWM settings if applicable 103 | if ( 104 | (typeof pin.pwm != 'undefined') && // pin has PWM capabilities 105 | (typeof pwm[pin.pwm.name] != 'undefined') && // PWM used for this pin is enabled 106 | (pin.key == pwm[pin.pwm.name].key) // PWM is allocated for this pin 107 | ) { 108 | hw.pwm.readFreqAndValue(pin, pwm[pin.pwm.name], onReadPWM); 109 | } else { 110 | onReadPWM(null); 111 | } 112 | 113 | function onReadPWM(err, pwm) { 114 | if (err) { 115 | console.error(err.message); 116 | if(typeof callback == 'function') callback(err, null); 117 | return; 118 | } 119 | if (pwm) { 120 | mode.pwm = pwm; 121 | } 122 | // Get GPIO settings if applicable 123 | if ((typeof pin.gpio != 'undefined')) { 124 | var n = pin.gpio; 125 | hw.digital.readDirection(n, onReadGPIODirection); 126 | } else { 127 | hw.readPinState(pin, onReadPinState); 128 | } 129 | } 130 | 131 | function onReadGPIODirection(err, direction) { 132 | if (err) { 133 | console.error(error.message); 134 | if(typeof callback == 'function') callback(err, null); 135 | return; 136 | } 137 | mode.gpio = direction; 138 | var n = pin.gpio; 139 | if (typeof gpio[n] == 'undefined') { 140 | mode.gpio.allocated = false; 141 | } else { 142 | mode.gpio.allocated = true; 143 | } 144 | hw.readPinState(pin, onReadPinState); 145 | } 146 | 147 | function onReadPinState(err, state) { 148 | if (err) { 149 | console.error(err.message); 150 | if(typeof callback == 'function') callback(err, null); 151 | return; 152 | } 153 | mode.pinState = state; 154 | if(typeof callback == 'function') callback(null, mode); 155 | } 156 | }; 157 | 158 | f.pinMode = function(givenPin, mode, callback) { 159 | if (!callback) { 160 | console.warn("As of version 0.4.0, pinMode function is fully async and we recommend passing " + 161 | "a callback function as third argument to know completion of pinMode function." + 162 | "v1.0.0 introduced 'pinModeSync' function. You can use it synchronously perform pinMode."); 163 | } 164 | 165 | if (arguments.length > 3 || (callback && typeof callback != 'function')) { 166 | console.error("As of version 0.4.0, pinMode function takes only 3 arguments (pin, mode, callback). " + 167 | "This function is now fully async so we recommend using callback to know completion of this funciton."); 168 | throw new verror("pinMode arguments are not valid."); 169 | } 170 | 171 | var pin = bone.getpin(givenPin); 172 | var n = pin.gpio; 173 | var direction; 174 | var err; 175 | 176 | debug('pinMode(' + [pin.key, mode] + ');'); 177 | 178 | if (mode == g.INPUT_PULLUP) { 179 | direction = g.INPUT; 180 | } else if (mode == g.INPUT_PULLDOWN) { 181 | direction = g.INPUT; 182 | } else if (mode == g.INPUT || mode == g.OUTPUT) { 183 | direction = mode; 184 | mode = "gpio"; 185 | } else if (mode == g.ANALOG_OUTPUT) { 186 | if (typeof pin.pwm == 'undefined') { 187 | err = new verror('BeagleBone does not allow ANALOG_OUTPUT for pin: ' + pin.key); 188 | console.error(err.message); 189 | if (typeof callback == 'function') callback(err, null); 190 | return; 191 | } 192 | pwm[pin.pwm.name] = { 193 | 'key': pin.key, 194 | 'freq': 0 195 | }; 196 | direction = g.OUTPUT; 197 | } else { 198 | err = new verror("Invalid mode supplied for pin: " + givenPin + ". Only following modes are supported: " + pin.modes); 199 | console.error(err.message); 200 | if (typeof callback == 'function') callback(err, null); 201 | return; 202 | } 203 | 204 | // Handle case where pin is allocated as a gpio-led 205 | if (pin.led) { 206 | if (direction != g.OUTPUT) { 207 | err = new verror('pinMode only supports GPIO output for LED pin: ' + pin.key); 208 | console.error(err.message); 209 | if (typeof callback == 'function') callback(err, null); 210 | return; 211 | } 212 | 213 | hw.digital.setLEDPinToGPIO(pin, onSetLEDPin); 214 | 215 | return; // since nothing to do more for LED pins 216 | } 217 | 218 | function onSetLEDPin(err) { 219 | if (err) { 220 | console.error(err.message); 221 | if (typeof callback == 'function') callback(err, null); 222 | } else { 223 | gpio[n] = true; 224 | if (typeof callback == 'function') callback(null, givenPin); 225 | } 226 | } 227 | 228 | // May be required: mount -t debugfs none /sys/kernel/debug 229 | hw.setPinMode(pin, mode, onSetPinMode); 230 | 231 | function onSetPinMode(err) { 232 | debug('returned from setPinMode'); 233 | if (err) { 234 | err = new verror(err, 'Unable to configure mux for pin ' + pin); 235 | console.error(err.message); 236 | // It might work if the pin is already muxed to desired mode 237 | if(typeof callback == 'function') callback(err, null); 238 | } else { 239 | pinModeTestGPIO(); 240 | } 241 | } 242 | 243 | function pinModeTestGPIO() { 244 | // Enable GPIO 245 | if (mode == "gpio" || mode == "gpio_pu" || mode == "gpio_pd") { 246 | // Export the GPIO controls 247 | resp = hw.digital.exportControls(pin, direction, onExport); 248 | } else { 249 | delete gpio[n]; 250 | if(typeof callback == 'function') callback(null, givenPin); 251 | } 252 | } 253 | 254 | function onExport(err) { 255 | if (err) { 256 | console.error(err.message); 257 | delete gpio[n]; 258 | if(typeof callback == 'function') callback(err, null); 259 | } else { 260 | gpio[n] = true; 261 | if(typeof callback == 'function') callback(null, givenPin); 262 | } 263 | } 264 | }; 265 | 266 | f.pinModeSync = function(pin, mode) { 267 | 268 | pin = bone.getpin(pin); 269 | var n = pin.gpio; 270 | var direction; 271 | var err; 272 | var resp; 273 | 274 | debug('pinModeSync(' + [pin.key, mode] + ');'); 275 | 276 | if (mode == g.INPUT_PULLUP) { 277 | direction = g.INPUT; 278 | } else if (mode == g.INPUT_PULLDOWN) { 279 | direction = g.INPUT; 280 | } else if (mode == g.INPUT || mode == g.OUTPUT) { 281 | direction = mode; 282 | mode = "gpio"; 283 | } else if (mode == g.ANALOG_OUTPUT) { 284 | if (typeof pin.pwm == 'undefined') { 285 | err = new verror('BeagleBone does not allow ANALOG_OUTPUT for pin: ' + pin.key); 286 | console.error(err.message); 287 | return; 288 | } 289 | pwm[pin.pwm.name] = { 290 | 'key': pin.key, 291 | 'freq': 0 292 | }; 293 | direction = g.OUTPUT; 294 | } else { 295 | throw new verror("Invalid mode supplied for pin: " + givenPin + ". Only following modes are supported: " + pin.modes); 296 | } 297 | 298 | // Handle case where pin is allocated as a gpio-led 299 | if (pin.led) { 300 | if (direction != g.OUTPUT) { 301 | err = new verror('pinMode only supports GPIO output for LED pin: ' + pin.key); 302 | console.error(err.message); 303 | if (typeof callback == 'function') callback(err, null); 304 | return; 305 | } 306 | 307 | resp = hw.digital.setLEDPinToGPIOSync(pin); 308 | if (resp === true) { 309 | gpio[n] = true; 310 | return true; 311 | } else { 312 | console.error(resp.message); 313 | } 314 | 315 | return false; // since nothing to do more for LED pins 316 | } 317 | 318 | // May be required: mount -t debugfs none /sys/kernel/debug 319 | resp = hw.setPinModeSync(pin, mode); 320 | 321 | debug('done from setPinModeSync'); 322 | 323 | if (resp === true) { 324 | return pinModeTestGPIO(); 325 | } else { 326 | console.error(resp.message); 327 | return false; 328 | } 329 | 330 | function pinModeTestGPIO() { 331 | // Enable GPIO 332 | if (mode == "gpio" || mode == "gpio_pu" || mode == "gpio_pd") { 333 | // Export the GPIO controls 334 | resp = hw.digital.exportControlsSync(pin, direction); 335 | gpio[n] = true; 336 | } else { 337 | delete gpio[n]; 338 | } 339 | return true; 340 | } 341 | }; 342 | 343 | f.digitalWrite = function(pin, value, callback) { 344 | if (pin) { 345 | pin = bone.getpin(pin); 346 | } else { 347 | throw new verror("Provide pin as first argument to digitalWrite"); 348 | } 349 | debug('digitalWrite(' + [pin.key, value] + ');'); 350 | value = parseInt(Number(value), 2) ? 1 : 0; 351 | 352 | hw.digital.write(pin, value, callback); 353 | }; 354 | 355 | f.digitalWriteSync = function(pin, value) { 356 | if (pin) { 357 | pin = bone.getpin(pin); 358 | } else { 359 | throw new verror("Provide pin as first argument to digitalWrite"); 360 | } 361 | debug('digitalWriteSync(' + [pin.key, value] + ');'); 362 | value = parseInt(Number(value), 2) ? 1 : 0; 363 | 364 | hw.digital.writeSync(pin, value); 365 | }; 366 | 367 | 368 | f.digitalRead = function(pin, callback) { 369 | if (typeof callback != 'function') { 370 | throw new verror("digitalRead() requires callback function"); 371 | } 372 | pin = bone.getpin(pin); 373 | debug('digitalRead(' + [pin.key] + ');'); 374 | 375 | if (typeof pin.ain != 'undefined') { 376 | f.analogRead(pin, analogCallback); 377 | } else { 378 | hw.digital.read(pin, callback); 379 | } 380 | 381 | function analogCallback(err, value) { 382 | if (err) { 383 | console.error(err.message); 384 | callback(err, null); 385 | } else { 386 | value = analogValue(value); 387 | callback(null, value); 388 | } 389 | } 390 | 391 | function analogValue(value) { 392 | if (value > 0.5) { 393 | value = g.HIGH; 394 | } else { 395 | value = g.LOW; 396 | } 397 | return value; 398 | } 399 | }; 400 | 401 | 402 | f.analogRead = function(pin, callback) { 403 | if (typeof callback != 'function') { 404 | throw new verror("analogRead() requires callback function"); 405 | } 406 | pin = bone.getpin(pin); 407 | debug('analogRead(' + [pin.key] + ');'); 408 | 409 | if (typeof pin.ain == 'undefined') { 410 | f.digitalRead(pin, callback); 411 | } else { 412 | hw.analog.read(pin, callback); 413 | } 414 | }; 415 | 416 | 417 | f.stopAnalog = function(pin, callback) { 418 | pin = bone.getpin(pin); 419 | if (typeof pin.pwm == 'undefined') { 420 | throw new verror(pin.key + ' does not support stopAnalog()'); 421 | } 422 | // Enable PWM controls if not already done 423 | if (typeof pwm[pin.pwm.name] == 'undefined') { 424 | f.pinMode(pin, g.ANALOG_OUTPUT, onPinMode); 425 | } else { 426 | onPinMode(); 427 | } 428 | 429 | function onPinMode() { 430 | hw.pwm.stop(pin, pwm[pin.pwm.name], callback); 431 | } 432 | }; 433 | 434 | 435 | f.startAnalog = function(pin, callback) { 436 | pin = bone.getpin(pin); 437 | if (typeof pin.pwm == 'undefined') { 438 | throw new verror(pin.key + ' does not support startAnalog()'); 439 | } 440 | // Enable PWM controls if not already done 441 | if (typeof pwm[pin.pwm.name] == 'undefined') { 442 | f.pinMode(pin, g.ANALOG_OUTPUT, onPinMode); 443 | } else { 444 | onPinMode(); 445 | } 446 | 447 | function onPinMode() { 448 | hw.pwm.start(pin, pwm[pin.pwm.name], callback); 449 | } 450 | }; 451 | 452 | 453 | // See http://processors.wiki.ti.com/index.php/AM335x_PWM_Driver's_Guide 454 | // That guide isn't useful for the new pwm_test interface 455 | f.analogWrite = function(pin, value, freq, callback) { 456 | pin = bone.getpin(pin); 457 | debug('analogWrite(' + [pin.key, value, freq] + ');'); 458 | freq = freq || 2000.0; 459 | var resp = {}; 460 | 461 | // Make sure the pin has a PWM associated 462 | if (typeof pin.pwm == 'undefined') { 463 | throw new verror(pin.key + ' does not support analogWrite()'); 464 | } 465 | 466 | // Make sure there is no one else who has the PWM 467 | if ( 468 | (typeof pwm[pin.pwm.name] != 'undefined') && // PWM needed by this pin is already allocated 469 | (pin.key != pwm[pin.pwm.name].key) // allocation is not by this pin 470 | ) { 471 | var err = 'analogWrite: ' + pin.key + ' requires pwm ' + pin.pwm.name + 472 | ' but it is already in use by ' + pwm[pin.pwm.name].key; 473 | err = new verror(err); 474 | console.error(err.message); 475 | if (typeof callback == 'function') callback(err); 476 | return; 477 | } 478 | 479 | // Enable PWM controls if not already done 480 | if (typeof pwm[pin.pwm.name] == 'undefined') { 481 | f.pinMode(pin, g.ANALOG_OUTPUT, onPinMode); 482 | } else { 483 | onPinMode(); 484 | } 485 | 486 | function onPinMode() { 487 | // Perform update 488 | hw.pwm.writeFreqAndValue(pin, pwm[pin.pwm.name], freq, value, onWritePWM); 489 | } 490 | 491 | function onWritePWM(err) { 492 | // Save off the freq, value and PWM assignment 493 | if (err) { 494 | err = new verror(err, "There was an error writing analog value"); 495 | if(typeof callback == 'function') callback(err); 496 | } else { 497 | pwm[pin.pwm.name].freq = freq; 498 | pwm[pin.pwm.name].value = value; 499 | 500 | // All done 501 | if(typeof callback == 'function') callback(null); 502 | } 503 | } 504 | }; 505 | 506 | 507 | f.shiftOut = function(dataPin, clockPin, bitOrder, val, callback) { 508 | dataPin = bone.getpin(dataPin); 509 | clockPin = bone.getpin(clockPin); 510 | debug('shiftOut(' + [dataPin.key, clockPin.key, bitOrder, val] + ');'); 511 | var i = 0; 512 | var bit; 513 | var clock = 0; 514 | next(); 515 | 516 | function next(err) { 517 | debug('i = ' + i); 518 | debug('clock = ' + clock); 519 | if (err || i == 8) { 520 | if(typeof callback == 'function') callback({ 521 | 'err': err 522 | }); 523 | return; 524 | } 525 | if (bitOrder == g.LSBFIRST) { 526 | bit = val & (1 << i); 527 | } else { 528 | bit = val & (1 << (7 - i)); 529 | } 530 | if (clock === 0) { 531 | clock = 1; 532 | if (bit) { 533 | f.digitalWrite(dataPin, g.HIGH, next); 534 | } else { 535 | f.digitalWrite(dataPin, g.LOW, next); 536 | } 537 | } else if (clock == 1) { 538 | clock = 2; 539 | f.digitalWrite(clockPin, g.HIGH, next); 540 | } else if (clock == 2) { 541 | i++; 542 | clock = 0; 543 | f.digitalWrite(clockPin, g.LOW, next); 544 | } 545 | } 546 | }; 547 | 548 | 549 | f.attachInterrupt = function(pin, mode, handler, callback) { 550 | pin = bone.getpin(pin); 551 | debug('attachInterrupt(' + [pin.key, handler, mode] + ');'); 552 | var n = pin.gpio; 553 | var err; 554 | 555 | /* Check if we don't have the required Epoll module 556 | if(!epoll.exists) { 557 | resp.err = 'attachInterrupt: requires Epoll module'; 558 | console.error(resp.err); 559 | if(callback) callback(resp); 560 | return; 561 | } 562 | */ 563 | 564 | // Check if pin isn't already configured as GPIO 565 | if (typeof gpio[n] == 'undefined') { 566 | debug( 'pin ' + pin.key + ' not already configured as GPIO. Configuring..'); 567 | f.pinModeSync(pin, g.INPUT); 568 | } 569 | 570 | if (typeof handler != 'function') { 571 | err = new verror('attachInterrupt: handler argument must be supplied and it should be a function'); 572 | console.error(err.message); 573 | if(typeof callback == 'function') callback(err, null); 574 | return; 575 | } 576 | 577 | if (mode != g.RISING && mode != g.FALLING && mode != g.CHANGE) { 578 | err = new verror('attachInterrupt: mode must be "rising", "falling" or "both". Invalid mode argument'); 579 | console.error(err.message); 580 | if(typeof callback == 'function') callback(err, null); 581 | return; 582 | } 583 | 584 | // Check if someone already has a handler configured 585 | if (typeof gpioInt[n] != 'undefined') { 586 | err = new verror('attachInterrupt: pin ' + pin.key + ' already has an interrupt handler assigned'); 587 | console.error(err.message); 588 | if(typeof callback == 'function') callback(err); 589 | return; 590 | } 591 | 592 | var intHandler = function(err, fd, events) { 593 | if (err) { 594 | err = new verror(err, "Error during interrupt handler execution"); 595 | handler(err, null); 596 | return; 597 | } 598 | var m = {}; 599 | fs.readSync(gpioInt[n].valuefd, gpioInt[n].value, 0, 1, 0); 600 | m.pin = pin; 601 | m.value = parseInt(Number(gpioInt[n].value), 2); 602 | if (typeof handler == 'function') handler(null, m); 603 | }; 604 | 605 | try { 606 | gpioInt[n] = hw.digital.writeEdge(pin, mode); 607 | gpioInt[n].epoll = new epoll.Epoll(intHandler); 608 | fs.readSync(gpioInt[n].valuefd, gpioInt[n].value, 0, 1, 0); 609 | gpioInt[n].epoll.add(gpioInt[n].valuefd, epoll.Epoll.EPOLLPRI); 610 | if(typeof callback == 'function') callback(null); 611 | } catch (ex) { 612 | err = new verror(ex, 'attachInterrupt: GPIO input file not opened'); 613 | console.error(err.message); 614 | if(typeof callback == 'function') callback(err); 615 | } 616 | }; 617 | 618 | 619 | f.detachInterrupt = function(pin, callback) { 620 | pin = bone.getpin(pin); 621 | debug('detachInterrupt(' + [pin.key] + ');'); 622 | var n = pin.gpio; 623 | var err; 624 | if (typeof gpio[n] == 'undefined' || typeof gpioInt[n] == 'undefined') { 625 | err = new verror("Interrupt not attached with the pin. Nothing detached"); 626 | if (typeof callback == 'function') callback(err); 627 | return; 628 | } 629 | gpioInt[n].epoll.remove(gpioInt[n].valuefd).close(); 630 | delete gpioInt[n]; 631 | if (typeof callback == 'function') callback(null); 632 | }; 633 | 634 | 635 | f.getEeproms = function(callback) { 636 | if (typeof callback != 'function') { 637 | console.error("getEeproms requires callback function"); 638 | return; 639 | } 640 | var eeproms = {}; 641 | eeproms = hw.readEeproms(eeproms); 642 | if (eeproms == {}) { 643 | debug('No valid EEPROM contents found'); 644 | } 645 | if(typeof callback == 'function') callback(null, eeproms); 646 | }; 647 | 648 | 649 | f.getPlatform = function(callback) { 650 | if (typeof callback != 'function') { 651 | throw new verror("getPlatform requires callback function"); 652 | } 653 | var platform = { 654 | 'platform': pinmap, 655 | 'name': "BeagleBone", 656 | 'bonescript': package_json.version, 657 | 'os': {} 658 | }; 659 | platform.os.hostname = os.hostname(); 660 | platform.os.type = os.type(); 661 | platform.os.arch = os.arch(); 662 | platform.os.release = os.release(); 663 | platform.os.uptime = os.uptime(); 664 | platform.os.loadavg = os.loadavg(); 665 | platform.os.totalmem = os.totalmem(); 666 | platform.os.freemem = os.freemem(); 667 | platform.os.networkInterfaces = os.networkInterfaces(); 668 | platform = hw.readPlatform(platform); 669 | if(typeof callback == 'function') callback(null, platform); 670 | }; 671 | 672 | 673 | f.setDate = function(date, callback) { 674 | child_process.exec('date -s "' + date + '"', dateResponse); 675 | 676 | function dateResponse(err, stdout, stderr) { 677 | if (err) { 678 | err = new verror(err); 679 | if(typeof callback == 'function') callback(err); 680 | } else { 681 | if(typeof callback == 'function') callback(null, { 682 | 'stdout': stdout, 683 | 'stderr': stderr 684 | }); 685 | } 686 | } 687 | }; 688 | 689 | 690 | f.watchdog = hw.watchdog; 691 | 692 | // Exported variables 693 | f.pinmap = pinmap; 694 | 695 | f.serial = serial; 696 | 697 | f.serialOpen = function() { 698 | console.error("serialOpen and all related functions are removed as of v1.0.0. Please use serial.open and refer " + 699 | "to README of OctalBoneScript for more information"); 700 | }; 701 | 702 | f.i2c = i2c; 703 | 704 | f.i2cOpen = function() { 705 | console.error("i2cOpen and all related functions are removed as of v1.0.0. Please use i2c.open and refer " + 706 | "to README of OctalBoneScript for more information"); 707 | }; 708 | 709 | for (var x in g) { 710 | f[x] = g[x]; 711 | } 712 | 713 | module.exports = f; 714 | 715 | debug('index.js loaded'); 716 | -------------------------------------------------------------------------------- /lib/analog.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var debug = require('debug')('bone'); 3 | var bone = require('./bone'); 4 | var verror = require("verror"); 5 | 6 | var ainPrefix = ""; 7 | 8 | module.exports = { 9 | 10 | enable: function(callback) { 11 | bone.load_dt_sync('BB-ADC'); 12 | var helper = bone.find_sysfsFile('helper', '/sys/devices/platform/ocp', '44e0d000.tscadc'); 13 | if (helper) { 14 | ainPrefix = helper + '/TI-am335x-adc/iio:device0/in_voltage'; 15 | debug('analog enable. Path = ' + ainPrefix); 16 | } 17 | if (typeof callback == 'function') callback(null, { 18 | 'path': helper 19 | }); 20 | 21 | }, 22 | 23 | read: function(pin, callback) { 24 | debug('read Analog input ' + pin.key); 25 | if(!ainPrefix){ 26 | module.exports.enable(); 27 | } 28 | var ainFile = ainPrefix + pin.ain.toString() + '_raw'; 29 | fs.readFile(ainFile, onReadAIN); 30 | 31 | function onReadAIN(err, data) { 32 | if (err) { 33 | err = new verror(err, 'analogRead error'); 34 | callback(err, null); 35 | } else { 36 | callback(null, parseInt(data, 10) / 4096); 37 | } 38 | } 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /lib/bone.js: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 - Texas Instruments, Jason Kridner 2 | // 3 | // This is meant to hold some private functions 4 | // Modified by Aditya Patadia, Octal Consulting LLP 5 | var fs = require('fs'); 6 | var debug = require('debug')('bone'); 7 | var pinmap = require('./pinmap'); 8 | var verror = require("verror"); 9 | 10 | var sysfsFiles = {}; 11 | 12 | function boneRequire(packageName, onfail) { 13 | var y = {}; 14 | try { 15 | y = require(packageName); 16 | y.exists = true; 17 | } catch (ex) { 18 | y.exists = false; 19 | var err = new verror("Optional package '%s' not loaded", packageName); 20 | console.error(err.message); 21 | if (onfail) onfail(); 22 | } 23 | return (y); 24 | } 25 | 26 | module.exports = { 27 | 28 | require: boneRequire, 29 | 30 | getpin: function(pin) { 31 | debug('getpin('+[pin]+')'); 32 | if (typeof pin == 'object') return (pin); 33 | else if (typeof pin == 'string' && pinmap[pin]) { 34 | if (pinmap[pin].exists) { 35 | return (pinmap[pin]); 36 | } else { 37 | var p = "ocp:" + pinmap[pin].key + "_pinmux"; 38 | var path = module.exports.find_sysfsFile(p, module.exports.is_ocp(), p); 39 | debug("Pin Path :" + path); 40 | if (fs.existsSync(path + "/state") || 41 | typeof pinmap[pin].ain != 'undefined' || 42 | typeof pinmap[pin].led != 'undefined') { 43 | pinmap[pin].exists = true; 44 | return pinmap[pin]; 45 | } else { 46 | throw new verror("The pin " + pinmap[pin].key + " is not availble to write. " + 47 | "Please make sure it is not used by another cape."); 48 | } 49 | } 50 | } else throw new verror("Invalid pin: " + pin); 51 | }, 52 | 53 | is_capemgr: function(callback) { 54 | if(typeof callback == 'function') callback({path: "/sys/devices/platform/bone_capemgr"}); 55 | return "/sys/devices/platform/bone_capemgr"; 56 | }, 57 | 58 | is_ocp: function(callback) { 59 | if(typeof callback == 'function') callback({path: "/sys/devices/platform/ocp"}); 60 | return "/sys/devices/platform/ocp"; 61 | }, 62 | 63 | is_cape_universal: function(callback) { 64 | var ocp = module.exports.is_ocp(); 65 | debug('is_ocp() = ' + ocp); 66 | var cape_universal = module.exports.find_sysfsFile('cape-universal', ocp, 'ocp:cape-universal', callback); 67 | debug('is_cape_universal() = ' + cape_universal); 68 | return (cape_universal); 69 | }, 70 | 71 | is_cape_universal_loaded: function () { 72 | 73 | // the universal capes start with cape-univ and or univ- so we try to find them using those two names 74 | var capemgr = module.exports.is_capemgr(); 75 | var slotsFile = capemgr + '/slots'; 76 | var slots = fs.readFileSync(slotsFile, 'ascii'); 77 | var slotRegex = new RegExp('\\d+(?=\\s*:.*,(cape-univ|univ-))', 'gm'); 78 | var foundUniv = slots.match(slotRegex); 79 | debug('Slots returned ' + slots); 80 | debug('found Universial at slot ' + foundUniv); 81 | if (foundUniv) { 82 | debug('Found Universial using ",cape-univ" or ",univ-" as filter'); 83 | return true; 84 | } else { 85 | debug('No Universial Cape Found'); 86 | return false; 87 | } 88 | 89 | 90 | 91 | }, 92 | load_universal_cape: function (callback) { 93 | // 06/02/2016 Andrew DeVries Logic based on dogtag BeagleBoard.org Debian Image 2016-05-13 94 | // need to determine which universal cape to load based on board type ie BeagleBone Green has no HDMI etc. 95 | //this logic was taken from https://github.com/RobertCNelson/boot-scripts/blob/master/boot/am335x_evm.sh#L321-L407 96 | //the am335x_evm.sh script executes at boot and should autoload universal 97 | // script is located at /opt/scripts/boot/am335x_evm.sh 98 | // 99 | // Note known issue on console image (lqxn image works correctly) BeagleBoard.org Debian Image 2016-05-13 where config-pin missing 100 | // so universial is not loaded automaticaly at boot. 101 | // Fix so script runs at boot is to add config-pin link 102 | // 103 | // cd /opt/source/ 104 | // sudo git clone https://github.com/cdsteinkuehler/beaglebone-universal-io.git 105 | // sudo chmod a+ rwx / opt / source / beaglebone - universal - io / config - pin 106 | // cd / usr / local / bin / 107 | // sudo ln - s / opt / source / beaglebone - universal - io / config - pin config- pin 108 | 109 | // 110 | //overlays can be found here https://github.com/RobertCNelson/bb.org-overlays/tree/master/src/arm 111 | // view loaded overlays 'cat /sys/devices/platform/bone_capemgr/slots' 112 | // manual load of overlay 'sudo sh -c "echo 'univ-emmc' > /sys/devices/platform/bone_capemgr/slots"' 113 | // manual unload of overlay 'sudo sh -c "echo '-4' > /sys/devices/platform/bone_capemgr/slots"' 114 | 115 | 116 | // Check /proc/device-tree/model for the model 117 | var overlay = 'cape-universaln'; 118 | try { 119 | var machine = fs.readFileSync('/proc/device-tree/model', 'ascii'); 120 | if (machine) { 121 | machine = machine.replace(/ /g, "_"); 122 | } 123 | switch (machine) { 124 | case 'TI_AM335x_BeagleBone': 125 | overlay = "univ-all"; 126 | break; 127 | case 'TI_AM335x_BeagleBone_Black_Wireless': 128 | overlay = "cape-universaln" 129 | break; 130 | case 'TI_AM335x_BeagleBone_Black': 131 | overlay = "cape-universaln"; 132 | break; 133 | case 'TI_AM335x_BeagleBone_Green': 134 | overlay = "univ-emmc"; 135 | break; 136 | case 'TI_AM335x_BeagleBone_Green_Wireless': 137 | overlay= "univ-bbgw"; 138 | break; 139 | } 140 | debug('Detected machine ' + machine + ' using Overlay ' + overlay ); 141 | } catch(err){ 142 | debug('Error detecting machine'); 143 | } 144 | module.exports.load_dt_sync(overlay); 145 | // if (!bone.is_audio_enable()) { 146 | // debug('Loading AUDIO Cape...'); 147 | // bone.load_dt_sync("cape-univ-audio"); 148 | // } 149 | 150 | //if (!bone.is_hdmi_enable()) { 151 | // debug('Loading HDMI Cape...'); 152 | // bone.load_dt_sync('cape-univ-hdmi'); 153 | //} 154 | }, 155 | is_hdmi_enable: function() { 156 | var capemgr = module.exports.is_capemgr(); 157 | var slotsFile = capemgr + '/slots'; 158 | var slots = fs.readFileSync(slotsFile, 'ascii'); 159 | 160 | var slotRegex = new RegExp('\\d+(?=\\s*:.*,' + 'cape-univ-hdmi' + ')', 'gm'); 161 | return slots.match(slotRegex); 162 | }, 163 | 164 | is_audio_enable: function() { 165 | var capemgr = module.exports.is_capemgr(); 166 | var slotsFile = capemgr + '/slots'; 167 | var slots = fs.readFileSync(slotsFile, 'ascii'); 168 | 169 | var slotRegex = new RegExp('\\d+(?=\\s*:.*,' + 'cape-univ-audio' + ')', 'gm'); 170 | return slots.match(slotRegex); 171 | }, 172 | 173 | find_sysfsFile: function(name, path, prefix, callback) { 174 | debug("find_sysfsFile("+ [name,path,prefix] + ")"); 175 | if (typeof sysfsFiles[name] == 'undefined') { 176 | if (callback) { 177 | module.exports.file_find(path, prefix, onFindFile); 178 | } else { 179 | sysfsFiles[name] = module.exports.file_find(path, prefix); 180 | } 181 | } else if(typeof callback == 'function') { 182 | callback(null, { 183 | path: sysfsFiles[name] 184 | }); 185 | } 186 | 187 | function onFindFile(err, resp) { 188 | if (err) { 189 | if(typeof callback == 'function') callback(err, null); 190 | } else { 191 | sysfsFiles[name] = resp.path; 192 | if(typeof callback == 'function') callback(null, resp); 193 | } 194 | } 195 | 196 | return (sysfsFiles[name]); 197 | }, 198 | 199 | file_find: function(path, prefix, callback) { 200 | var resp = { 201 | path: null 202 | }; 203 | 204 | if (callback) { 205 | fs.readdir(path, onReadDir); 206 | } else { 207 | try { 208 | var files = fs.readdirSync(path); 209 | onReadDir(null, files); 210 | } catch (ex) { 211 | console.error('Error reading directory ' + path); 212 | } 213 | return (resp.path); 214 | } 215 | 216 | function onReadDir(err, fileList) { 217 | if (err) { 218 | err = verror(err, 'Error listing directory %s', path); 219 | if(typeof callback == 'function') callback(err, null); 220 | return; 221 | } 222 | for (var j in fileList) { 223 | if (fileList[j].indexOf(prefix) === 0) { 224 | resp.path = path + '/' + fileList[j]; 225 | if(typeof callback == 'function') callback(null, resp); 226 | return; 227 | } 228 | } 229 | if (resp.path === null && callback) { 230 | callback(null, resp); 231 | } 232 | } 233 | }, 234 | 235 | // Note, this just makes sure there was an attempt to load the 236 | // devicetree fragment, not if it was successful 237 | 238 | load_dt_sync: function(name) { 239 | debug('load_dt_sync(' + [name] + ')'); 240 | var slotsFile; 241 | var err; 242 | var readAttempts = 0; 243 | 244 | var capemgr = module.exports.is_capemgr(); 245 | debug('onFindCapeMgr: path = ' + capemgr); 246 | if (!capemgr) { 247 | throw new verror("CapeMgr not found "); 248 | } 249 | 250 | slotsFile = capemgr + '/slots'; 251 | readSlots(); 252 | 253 | function readSlots() { 254 | var slots; 255 | try { 256 | slots = fs.readFileSync(slotsFile, 'ascii'); 257 | } catch (ex) { 258 | err = ex; 259 | } 260 | onReadSlots(err, slots); 261 | } 262 | 263 | function onReadSlots(err2, slots) { 264 | readAttempts++; 265 | if (err2) { 266 | throw new verror(err2, 'Unable to read from CapeMgr slots'); 267 | } 268 | var index = slots.indexOf(name); 269 | debug('onReadSlots: index = ' + index + ', readAttempts = ' + readAttempts); 270 | if (index >= 0) { 271 | debug(name + " is successfully loaded"); // do nothing... 272 | } else if (readAttempts <= 1) { 273 | // Attempt to load fragment 274 | try { 275 | debug('Writing ' + name + ' to ' + slotsFile); 276 | fs.writeFileSync(slotsFile, name, 'ascii'); 277 | } catch (ex) { 278 | err2 = ex; 279 | } 280 | onWriteSlots(err2); 281 | } else { 282 | err2 = 'Error waiting for CapeMgr slot to load'; 283 | throw new verror(err2); 284 | } 285 | } 286 | 287 | function onWriteSlots(err2) { 288 | if (err2) { 289 | throw new verror(err2, 'Write to CapeMgr slots failed'); 290 | } 291 | readSlots(); 292 | } 293 | 294 | debug('load_dt_sync return'); 295 | return true; 296 | }, 297 | 298 | unload_dt_sync : function(name) { 299 | debug('unload_dt_sync('+ [name] + ')'); 300 | var capemgr = module.exports.is_capemgr(); 301 | var slotsFile = capemgr + '/slots'; 302 | var slots = fs.readFileSync(slotsFile, 'ascii'); 303 | 304 | var slotRegex = new RegExp('\\d+(?=\\s*:.*,' + name + ')', 'gm'); 305 | var slot = slots.match(slotRegex); 306 | debug("Found slot : " + slot); 307 | if (slot && slot[0]) { 308 | debug('Attempting to unload conflicting slot ' + 309 | slot[0] + ' for ' + name); 310 | fs.writeFileSync(slotsFile, '-'+slot[0], 'ascii'); 311 | debug('slot unload successful'); 312 | return true; 313 | } else { 314 | return false; 315 | } 316 | } 317 | 318 | }; 319 | -------------------------------------------------------------------------------- /lib/constants.json: -------------------------------------------------------------------------------- 1 | { 2 | "OUTPUT": "out", 3 | "INPUT": "in", 4 | "INPUT_PULLUP": "gpio_pu", 5 | "INPUT_PULLDOWN": "gpio_pd", 6 | "HIGH": 1, 7 | "LOW": 0, 8 | "LSBFIRST": 1, 9 | "MSBFIRST": 0, 10 | "RISING": "rising", 11 | "FALLING": "falling", 12 | "CHANGE": "both", 13 | "ANALOG_OUTPUT": "pwm" 14 | } -------------------------------------------------------------------------------- /lib/digital.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var debug = require('debug')('bone'); 3 | var bone = require('./bone'); 4 | var verror = require("verror"); 5 | 6 | var gpioFile = {}; 7 | 8 | module.exports = { 9 | 10 | setPinMode: function(pin, mode, callback) { 11 | debug('digital.setPinMode(' + [pin.key, mode] + ');'); 12 | var p = "ocp:" + pin.key + "_pinmux"; 13 | bone.find_sysfsFile(p, bone.is_ocp(), p , onFindPinmux); 14 | 15 | function onFindPinmux(err, data) { 16 | if (err) { 17 | if(typeof callback == 'function') callback(err); 18 | } else if (!data.path) { 19 | err = new verror("Pinmux file for " + p + " could not be found"); 20 | if(typeof callback == 'function') callback(err); 21 | } else { 22 | gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; 23 | 24 | fs.writeFile(data.path + "/state", mode, onModeComplete); 25 | } 26 | } 27 | 28 | function onModeComplete(err) { 29 | if (err) { 30 | err = new verror(err, "onComplete problem"); 31 | if (typeof callback == 'function') callback(err); 32 | return; 33 | } 34 | if (typeof callback == 'function') callback(null); 35 | } 36 | }, 37 | 38 | setPinModeSync: function(pin, mode) { 39 | debug('digital.setPinModeSync(' + [pin.key, mode] + ');'); 40 | var p = "ocp:" + pin.key + "_pinmux"; 41 | var path = bone.find_sysfsFile(p, bone.is_ocp(), p ); 42 | 43 | gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; 44 | 45 | fs.writeFileSync(path + "/state", mode); 46 | return true; 47 | }, 48 | 49 | readDirection: function(n, callback) { 50 | debug("readGPIODirection(" + [n] + ")"); 51 | var resp = {}; 52 | var directionFile = "/sys/class/gpio/gpio" + n + "/direction"; 53 | fs.exists(directionFile, function(exists) { 54 | if (exists) { 55 | fs.readFile(directionFile, 'utf8', onReadDirection); 56 | } else { 57 | var err = new verror("Direction file" + directionFile + " deos not exist"); 58 | callback(err, null); 59 | } 60 | }); 61 | 62 | function onReadDirection(err, direction) { 63 | resp.active = true; 64 | resp.direction = direction.trim(); 65 | callback(null, resp); 66 | } 67 | }, 68 | 69 | 70 | setLEDPinToGPIO: function(pin, callback) { 71 | var path = "/sys/class/leds/beaglebone:green:" + pin.led + "/trigger"; 72 | fs.exists(path, function(exists) { 73 | if (exists) { 74 | fs.writeFile(path, "gpio", onWriteMode); 75 | } else { 76 | var err = new verror("Unable to find LED " + pin.led); 77 | if(typeof callback == 'function') callback(err); 78 | } 79 | }); 80 | 81 | function onWriteMode(err) { 82 | if (err) { 83 | err = new verror("Unable to write file %s", path); 84 | if(typeof callback == 'function') callback(err); 85 | } else { 86 | if(typeof callback == 'function') callback(null); 87 | } 88 | } 89 | }, 90 | 91 | setLEDPinToGPIOSync: function(pin) { 92 | var path = "/sys/class/leds/beaglebone:green:" + pin.led + "/trigger"; 93 | var exists = fs.existsSync(path); 94 | 95 | if (exists) { 96 | fs.writeFileSync(path, "gpio"); 97 | return true; 98 | } else { 99 | return new verror("Unable to find LED " + pin.led); 100 | } 101 | }, 102 | 103 | 104 | exportControls: function(pin, direction, callback) { 105 | debug('hw.exportGPIOControls(' + [pin.key, direction] + ');'); 106 | var n = pin.gpio; 107 | fs.exists(gpioFile[pin.key], onFileExists); 108 | 109 | function onFileExists(exists) { 110 | if (exists) { 111 | debug("gpio: " + n + " already exported."); 112 | fs.writeFile("/sys/class/gpio/gpio" + n + "/direction", direction, onGPIODirectionSet); 113 | } else { 114 | debug("exporting gpio: " + n); 115 | fs.writeFile("/sys/class/gpio/export", String(n), onGPIOExport); 116 | } 117 | } 118 | 119 | function onGPIOExport(err) { 120 | if (err) { 121 | err = new verror(err, "Unable to export GPIO-" + n); 122 | if(typeof callback == 'function') callback(err); 123 | } else { 124 | debug("setting gpio " + n + " direction to " + direction); 125 | fs.writeFile("/sys/class/gpio/gpio" + n + "/direction", direction, onGPIODirectionSet); 126 | } 127 | } 128 | 129 | function onGPIODirectionSet(err) { 130 | if (err) { 131 | err = new verror(err, "Unable to set direction of GPIO-" + n); 132 | if(typeof callback == 'function') callback(err); 133 | } else { 134 | if(typeof callback == 'function') callback(null); 135 | } 136 | } 137 | }, 138 | 139 | exportControlsSync: function(pin, direction) { 140 | debug('hw.exportGPIOControls(' + [pin.key, direction] + ');'); 141 | var n = pin.gpio; 142 | 143 | var exists = fs.existsSync(gpioFile[pin.key]); 144 | 145 | if (exists) { 146 | debug("gpio: " + n + " already exported."); 147 | fs.writeFileSync("/sys/class/gpio/gpio" + n + "/direction", direction); 148 | } else { 149 | debug("exporting gpio: " + n); 150 | fs.writeFileSync("/sys/class/gpio/export", String(n)); 151 | fs.writeFileSync("/sys/class/gpio/gpio" + n + "/direction", direction); 152 | } 153 | return true; 154 | }, 155 | 156 | write: function(pin, value, callback) { 157 | if (typeof gpioFile[pin.key] == 'undefined') { 158 | gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; 159 | if (pin.led) { 160 | gpioFile[pin.key] = "/sys/class/leds/beaglebone:"; 161 | gpioFile[pin.key] += "green:" + pin.led + "/brightness"; 162 | } 163 | fs.exists(gpioFile[pin.key], function(exists) { 164 | if (!exists) { 165 | var err = new verror("Unable to find gpio: " + gpioFile[pin.key]); 166 | if(typeof callback == 'function') callback(err); 167 | } else { 168 | writeGPIO(); 169 | } 170 | }); 171 | } else { 172 | writeGPIO(); 173 | } 174 | 175 | function writeGPIO() { 176 | debug("writeGPIO gpioFile = " + gpioFile[pin.key]); 177 | fs.writeFile(gpioFile[pin.key], String(value), onWriteGPIO); 178 | } 179 | 180 | function onWriteGPIO(err) { 181 | if (err) { 182 | err = new verror(err, "Writing to GPIO failed"); 183 | console.error(err.message); 184 | if (typeof callback == 'function') callback(err); 185 | } else { 186 | if (typeof callback == 'function') callback(null); 187 | } 188 | } 189 | }, 190 | 191 | 192 | writeSync: function(pin, value) { 193 | if (typeof gpioFile[pin.key] == 'undefined') { 194 | gpioFile[pin.key] = '/sys/class/gpio/gpio' + pin.gpio + '/value'; 195 | if (pin.led) { 196 | gpioFile[pin.key] = "/sys/class/leds/beaglebone:"; 197 | gpioFile[pin.key] += "green:" + pin.led + "/brightness"; 198 | } 199 | if (!fs.existsSync(gpioFile[pin.key])) { 200 | throw new verror("Unable to find gpio: " + gpioFile[pin.key]); 201 | } 202 | } 203 | debug("writeGPIOValueSync gpioFile = " + gpioFile[pin.key]); 204 | try { 205 | fs.writeFileSync(gpioFile[pin.key], String(value)); 206 | } catch (err) { 207 | throw new verror(err, "Writing to GPIO failed"); 208 | } 209 | }, 210 | 211 | read: function(pin, callback) { 212 | var gpioFile = '/sys/class/gpio/gpio' + pin.gpio + '/value'; 213 | fs.readFile(gpioFile, onGPIORead); 214 | 215 | function onGPIORead(err, data) { 216 | if (err) { 217 | err = new verror(err, 'digitalRead error'); 218 | callback(err, null); 219 | } else { 220 | callback(null, parseInt(data, 2)); 221 | } 222 | } 223 | }, 224 | 225 | writeEdge: function(pin, mode) { 226 | fs.writeFileSync('/sys/class/gpio/gpio' + pin.gpio + '/edge', mode); 227 | var resp = {}; 228 | resp.gpioFile = '/sys/class/gpio/gpio' + pin.gpio + '/value'; 229 | resp.valuefd = fs.openSync(resp.gpioFile, 'r'); 230 | resp.value = new Buffer(1); 231 | 232 | return (resp); 233 | } 234 | }; 235 | -------------------------------------------------------------------------------- /lib/eeprom.js: -------------------------------------------------------------------------------- 1 | // Functions derived from https://github.com/joyent/node/blob/master/lib/buffer.js are: 2 | // 3 | // Copyright Joyent, Inc. and other Node contributors. All rights reserved. 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to 6 | // deal in the Software without restriction, including without limitation the 7 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | // sell copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | // IN THE SOFTWARE. 21 | 22 | // Modified by Aditya Patadia, Octal Consulting LLP 23 | 24 | var fs = require('fs'); 25 | var buffer = require('buffer'); 26 | var util = require('util'); 27 | var debug = require('debug')('bone'); 28 | var pinmap = require('./pinmap').pins; 29 | 30 | // Function derived from https://github.com/joyent/node/blob/master/lib/buffer.js 31 | if (!buffer.Buffer.prototype.readUint16BE) { 32 | buffer.Buffer.prototype.readUint16BE = function(offset) { 33 | var val = 0; 34 | val = this[offset] << 8; 35 | val |= this[offset + 1]; 36 | return (val); 37 | }; 38 | } 39 | 40 | // Function derived from https://github.com/joyent/node/blob/master/lib/buffer.js 41 | if (!buffer.Buffer.prototype.hexSlice) { 42 | var toHex = function(n) { 43 | if (n < 16) return '0' + n.toString(16); 44 | return n.toString(16); 45 | }; 46 | buffer.Buffer.prototype.hexSlice = function(start, end) { 47 | var len = this.length; 48 | if (!start || start < 0) start = 0; 49 | if (!end || end < 0 || end > len) end = len; 50 | 51 | var out = ''; 52 | for (var i = start; i < end; i++) { 53 | out += toHex(this[i]); 54 | } 55 | return (out); 56 | }; 57 | } 58 | 59 | // Function derived from https://github.com/joyent/node/blob/master/lib/buffer.js 60 | if (!buffer.Buffer.prototype.writeUint16BE) { 61 | buffer.Buffer.prototype.writeUint16BE = function(value, offset) { 62 | this[offset] = (value & 0xff00) >>> 8; 63 | this[offset + 1] = value & 0x00ff; 64 | }; 65 | } 66 | 67 | // Function derived from https://github.com/joyent/node/blob/master/lib/buffer.js 68 | // fill(value, start=0, end=buffer.length) 69 | if (!buffer.Buffer.prototype.fill) { 70 | buffer.Buffer.prototype.fill = function(value, start, end) { 71 | value || (value = 0); 72 | start || (start = 0); 73 | end || (end = this.length); 74 | 75 | for (var i = start; i < end; i++) { 76 | this[i] = value; 77 | } 78 | }; 79 | } 80 | 81 | // Function derived from https://github.com/joyent/node/blob/master/lib/buffer.js 82 | if (!buffer.Buffer.prototype.hexWrite) { 83 | buffer.Buffer.prototype.hexWrite = function(string, offset, length) { 84 | offset = +offset || 0; 85 | var remaining = this.length - offset; 86 | if (!length) { 87 | length = remaining; 88 | } else { 89 | length = +length; 90 | if (length > remaining) { 91 | length = remaining; 92 | } 93 | } 94 | 95 | // must be an even number of digits 96 | var strLen = string.length; 97 | if (strLen % 2) { 98 | throw new Error('Invalid hex string'); 99 | } 100 | if (length > strLen / 2) { 101 | length = strLen / 2; 102 | } 103 | 104 | for (var i = 0; i < length; i++) { 105 | var byte = parseInt(string.substr(i * 2, 2), 16); 106 | if (isNaN(byte)) throw new Error('Invalid hex string'); 107 | this[offset + i] = byte; 108 | } 109 | return i; 110 | }; 111 | } 112 | 113 | var eepromData = new buffer.Buffer(244); 114 | 115 | var readEeproms = exports.readEeproms = function(files) { 116 | var data = {}; 117 | for (var file in files) { 118 | var raw = fetchEepromData(file); 119 | var parsed = null; 120 | if (raw) { 121 | if (files[file].type == 'bone') { 122 | parsed = parseMainEeprom(raw); 123 | if (parsed) parsed.type = 'bone'; 124 | } else { 125 | parsed = parseCapeEeprom(raw); 126 | if (parsed) parsed.type = 'cape'; 127 | } 128 | if (parsed) { 129 | data[file] = parsed; 130 | } 131 | } 132 | } 133 | return (data); 134 | }; 135 | 136 | var fetchEepromData = function(address) { 137 | try { 138 | debug('Reading EEPROM at ' + address); 139 | var eepromFile = 140 | fs.openSync( 141 | address, 142 | 'r' 143 | ); 144 | fs.readSync(eepromFile, eepromData, 0, 244, 0); 145 | return (eepromData); 146 | } catch (ex) { 147 | debug('Unable to open EEPROM at ' + address + ': ' + ex); 148 | return (null); 149 | } 150 | }; 151 | 152 | var parseMainEeprom = function(x) { 153 | var data = {}; 154 | data.header = x.hexSlice(0, 4); 155 | if (data.header != 'aa5533ee') { 156 | console.error('Unknown EEPROM format: ' + data.header); 157 | return (null); 158 | } 159 | data.boardName = x.toString('ascii', 4, 12).trim().replace(/^\x00+|\x00+$/g, ''); 160 | data.version = x.toString('ascii', 12, 16).trim().replace(/^\x00+|\x00+$/g, ''); 161 | data.serialNumber = x.toString('ascii', 16, 28).trim().replace(/^\x00+|\x00+$/g, ''); 162 | data.configOption = x.hexSlice(28, 60); 163 | return (data); 164 | }; 165 | 166 | var parseCapeEeprom = function(x) { 167 | var data = {}; 168 | data.header = x.hexSlice(0, 4); 169 | if (data.header != 'aa5533ee') { 170 | console.error('Unknown EEPROM format: ' + data.header); 171 | return (null); 172 | } 173 | data.formatRev = x.toString('ascii', 4, 6); 174 | if (data.formatRev != 'A0') { 175 | console.error('Unknown EEPROM format revision: ' + data.formatRev); 176 | return (null); 177 | } 178 | data.boardName = x.toString('ascii', 6, 38).trim().replace(/^\x00+|\x00+$/g, ''); 179 | data.version = x.toString('ascii', 38, 42).trim().replace(/^\x00+|\x00+$/g, ''); 180 | data.manufacturer = x.toString('ascii', 42, 58).trim().replace(/^\x00+|\x00+$/g, ''); 181 | data.partNumber = x.toString('ascii', 58, 74).trim().replace(/^\x00+|\x00+$/g, ''); 182 | data.numPins = x.readUint16BE(74); 183 | data.serialNumber = x.toString('ascii', 76, 88).trim().replace(/^\x00+|\x00+$/g, ''); 184 | data.currentVDD_3V3EXP = x.readUint16BE(236); 185 | data.currentVDD_5V = x.readUint16BE(238); 186 | data.currentSYS_5V = x.readUint16BE(240); 187 | data.DCSupplied = x.readUint16BE(242); 188 | data.mux = {}; 189 | for (var pin in pinmap) { 190 | if (typeof pinmap[pin].eeprom != 'undefined') { 191 | var pinOffset = pinmap[pin].eeprom * 2 + 88; 192 | var pinData = x.readUint16BE(pinOffset); 193 | var pinObject = {}; 194 | var used = (pinData & 0x8000) >> 15; 195 | if (used || debug) { 196 | pinObject.used = used ? 'used' : 'available'; 197 | pinObject.data = x.hexSlice(pinOffset, pinOffset + 2); 198 | var direction = (pinData & 0x6000) >> 13; 199 | switch (direction) { 200 | case 1: 201 | pinObject.direction = 'in'; 202 | break; 203 | case 2: 204 | pinObject.direction = 'out'; 205 | break; 206 | case 3: 207 | pinObject.direction = 'bidir'; 208 | break; 209 | default: 210 | console.error('Unknown direction value: ' + direction); 211 | } 212 | pinObject.slew = (pinData & 0x40) ? 'slow' : 'fast'; 213 | pinObject.rx = (pinData & 0x20) ? 'enabled' : 'disabled'; 214 | var pullup = (pinData & 0x18) >> 3; 215 | switch (pullup) { 216 | case 1: 217 | pinObject.pullup = 'disabled'; 218 | break; 219 | case 2: 220 | pinObject.pullup = 'pullup'; 221 | break; 222 | case 0: 223 | pinObject.pullup = 'pulldown'; 224 | break; 225 | default: 226 | console.error('Unknown pullup value: ' + pullup); 227 | } 228 | pinObject.mode = (pinData & 0x0007); 229 | try { 230 | // read mux from debugfs 231 | var muxReadout = fs.readFileSync('/sys/kernel/debug/omap_mux/' + pinmap[pin].mux, 'ascii'); 232 | pinObject.function = muxReadout.split("\n")[2].split("|")[pinObject.mode].replace('signals:', '').trim(); 233 | } catch (ex) { 234 | debug('Unable to read pin mux function name: ' + pinmap[pin].mux); 235 | } 236 | data.mux[pin] = pinObject; 237 | } 238 | } 239 | } 240 | return (data); 241 | }; 242 | 243 | var fillCapeEepromData = exports.fillCapeEepromData = function(data) { 244 | eepromData.fill(); 245 | eepromData.hexWrite('aa5533ee', 0, 4); 246 | eepromData.write('A0', 4, 2, 'ascii'); 247 | if (data.boardName.length > 32) { 248 | data.boardName.length = 32; 249 | } 250 | eepromData.write(data.boardName, 6, 32, 'ascii'); 251 | if (data.version.length > 4) { 252 | data.version.length = 4; 253 | } 254 | eepromData.write(data.version, 38, 4, 'ascii'); 255 | if (data.manufacturer.length > 16) { 256 | data.manufacturer.length = 16; 257 | } 258 | eepromData.write(data.manufacturer, 42, 16, 'ascii'); 259 | if (data.partNumber.length > 16) { 260 | data.partNumber.length = 16; 261 | } 262 | eepromData.write(data.partNumber, 58, 16, 'ascii'); 263 | eepromData.writeUint16BE(data.numPins, 74, 'ascii'); 264 | if (data.serialNumber.length > 12) { 265 | data.serialNumber.length = 12; 266 | } 267 | eepromData.write(data.serialNumber, 76, 12, 'ascii'); 268 | eepromData.writeUint16BE(data.currentVDD_3V3EXP, 236); 269 | eepromData.writeUint16BE(data.currentVDD_5V, 238); 270 | eepromData.writeUint16BE(data.currentSYS_5V, 240); 271 | eepromData.writeUint16BE(data.DCSupplied, 242); 272 | for (var pin in data.mux) { 273 | if (typeof pinmap[pin].eeprom != 'undefined') { 274 | var pinOffset = pinmap[pin].eeprom * 2 + 88; 275 | var pinObject = data.mux[pin]; 276 | var pinData = 0; 277 | if (pinObject.used == 'used') pinData |= 0x8000; 278 | switch (pinObject.direction) { 279 | case 'in': 280 | pinData |= 0x2000; 281 | break; 282 | case 'out': 283 | pinData |= 0x4000; 284 | break; 285 | case 'bidir': 286 | pinData |= 0x6000; 287 | break; 288 | default: 289 | console.error('Unknown direction value: ' + pinObject.direction); 290 | pinData |= 0x2000; 291 | } 292 | if (pinObject.slew == 'slow') pinData |= 0x40; 293 | if (pinObject.rx == 'enabled') pinData |= 0x20; 294 | var pullup = (pinData & 0x18) >> 3; 295 | switch (pinObject.pullup) { 296 | case 'disabled': 297 | pinData |= 0x08; 298 | break; 299 | case 'pullup': 300 | pinData |= 0x10; 301 | break; 302 | case 'pulldown': 303 | break; 304 | default: 305 | console.error('Unknown pullup value: ' + pullup); 306 | } 307 | pinData |= (pinObject.mode & 0x0007); 308 | eepromData.writeUint16BE(pinData, pinOffset); 309 | } 310 | } 311 | return (eepromData); 312 | }; 313 | 314 | var defaultEepromFiles = { 315 | '/sys/bus/i2c/drivers/at24/1-0050/eeprom': { 316 | type: 'bone' 317 | }, 318 | '/sys/bus/i2c/drivers/at24/1-0051/eeprom': { 319 | type: 'bone' 320 | }, 321 | '/sys/bus/i2c/drivers/at24/3-0054/eeprom': { 322 | type: 'cape' 323 | }, 324 | '/sys/bus/i2c/drivers/at24/3-0055/eeprom': { 325 | type: 'cape' 326 | }, 327 | '/sys/bus/i2c/drivers/at24/3-0056/eeprom': { 328 | type: 'cape' 329 | }, 330 | '/sys/bus/i2c/drivers/at24/3-0057/eeprom': { 331 | type: 'cape' 332 | }, 333 | 'test-bone.eeprom': { 334 | type: 'bone' 335 | }, 336 | 'test-cape.eeprom': { 337 | type: 'cape' 338 | }, 339 | }; -------------------------------------------------------------------------------- /lib/hw_simulator.js: -------------------------------------------------------------------------------- 1 | // Modified by Aditya Patadia, Octal Consulting LLP 2 | var fs = require('fs'); 3 | var debug = require('debug')('bone'); 4 | 5 | var gpioFile = {}; 6 | 7 | module.exports = { 8 | 9 | watchdog: { 10 | start: function() { 11 | return true; 12 | }, 13 | 14 | stop: function() { 15 | return true; 16 | } 17 | }, 18 | 19 | pwm: { 20 | readFreqAndValue: function(pin, pwm) { 21 | debug('pwm.readFreqAndValue(' + [pin.key, pwm.key] + ')'); 22 | var mode = {}; 23 | mode.freq = pwm.freq; 24 | mode.value = pwm.value; 25 | return (mode); 26 | }, 27 | 28 | enable: function(callback) { 29 | debug('enableAIN()'); 30 | if (typeof callback == 'function') { 31 | var resp = {}; 32 | resp.err = false; 33 | callback(resp); 34 | } 35 | return (true); 36 | }, 37 | 38 | readInput: function(pin, resp, callback) { 39 | debug('readAIN(' + [pin.key] + ')'); 40 | resp.value = 0; 41 | if (callback) { 42 | setTimeout(callback, 20, resp); 43 | } 44 | return (resp); 45 | }, 46 | 47 | writeFreqAndValue: function(pin, pwm, freq, value, resp) { 48 | debug('writePWMFreqAndValue(' + [pin.key, pwm.name, freq, value] + ')'); 49 | return (resp); 50 | }, 51 | }, 52 | 53 | digital: { 54 | readDirection: function(n, gpio) { 55 | debug('readGPIODirection(' + [n] + ')'); 56 | var mode = {}; 57 | if (typeof gpio[n] != 'undefined') { 58 | if (gpio[n].active) { 59 | mode.active = true; 60 | } else { 61 | mode.active = false; 62 | } 63 | mode.direction = gpio[n].direction; 64 | } 65 | return (mode); 66 | }, 67 | 68 | setLEDPinToGPIO: function(pin, resp) { 69 | debug('setLEDPinToGPIO(' + [pin.key] + ')'); 70 | return (resp); 71 | }, 72 | 73 | exportControls: function(pin, direction, resp, callback) { 74 | debug('expertGPIOControls(' + [pin.key, direction] + ')'); 75 | if (typeof callback == 'function') { 76 | callback({}); 77 | } 78 | return (resp); 79 | }, 80 | 81 | write: function(pin, value, callback) { 82 | debug('writeGPIOValue(' + [pin.key, value] + ')'); 83 | if (callback) { 84 | setTimeout(callback, 20); 85 | } 86 | }, 87 | 88 | writeSync: function(pin, value) { 89 | debug('writeGPIOValueSync(' + [pin.key, value] + ')'); 90 | }, 91 | 92 | read: function(pin, resp, callback) { 93 | debug('readGPIOValue(' + [pin.key] + ')'); 94 | if (callback) { 95 | setTimeout(callback, 20, 0); 96 | return (true); 97 | } 98 | resp.value = 0; 99 | return (resp); 100 | }, 101 | 102 | writeEdge: function(pin, mode) { 103 | debug('writeGPIOEdge(' + [pin.key, mode] + ')'); 104 | var resp = {}; 105 | return (resp); 106 | }, 107 | }, 108 | 109 | 110 | 111 | setPinMode: function(pin, pinData, template, resp, callback) { 112 | debug('setPinMode(' + [pin.key, pinData, template] + ')'); 113 | gpioFile[pin.key] = true; 114 | if (typeof callback == 'function') { 115 | callback({}); 116 | } 117 | return (resp); 118 | }, 119 | 120 | readEeproms: function(eeproms) { 121 | debug('readEeproms()'); 122 | var boardName = 'A335BNLT'; 123 | var version = ''; 124 | var serialNumber = ''; 125 | eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'] = {}; 126 | eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'].boardName = boardName; 127 | eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'].version = version; 128 | eeproms['/sys/bus/i2c/drivers/at24/1-0050/eeprom'].serialNumber = serialNumber; 129 | return (eeproms); 130 | }, 131 | 132 | readPlatform: function(platform) { 133 | debug('readPlatform()'); 134 | platform.name = 'BeagleBone Simulator'; 135 | return (platform); 136 | } 137 | }; -------------------------------------------------------------------------------- /lib/hw_universal.js: -------------------------------------------------------------------------------- 1 | // Copyright Aditya Patadia, Octal Consulting LLP 2 | var fs = require('fs'); 3 | var debug = require('debug')('bone'); 4 | var bone = require('./bone'); 5 | var verror = require("verror"); 6 | var eeprom = require('./eeprom'); 7 | 8 | module.exports = { 9 | 10 | watchdog: require("./watchdog"), 11 | 12 | pwm: require("./pwm"), 13 | 14 | digital: require("./digital"), 15 | 16 | analog: require("./analog"), 17 | 18 | readPinState: function(pin, callback) { 19 | debug("readPinState(" + pin.key + ")"); 20 | var p = "ocp:" + pin.key + "_pinmux"; 21 | bone.find_sysfsFile(p, bone.is_ocp(), p , onFindPinmux); 22 | 23 | function onFindPinmux(err, data) { 24 | if (err) { 25 | callback(err, null); 26 | } else if (!data.path) { 27 | err = new verror("Pinmux file for " + p + " could not be found"); 28 | callback(err, null); 29 | } else { 30 | fs.readFile(data.path + "/state", 'utf8', function(err, state) { 31 | callback(null, state.trim()); 32 | }); 33 | } 34 | } 35 | }, 36 | 37 | setPinMode: function(pin, mode, callback) { 38 | if (mode == "gpio" || mode == "gpio_pu" || mode == "gpio_pd") { 39 | 40 | module.exports.digital.setPinMode(pin, mode, callback); 41 | 42 | } else if (mode == "pwm") { 43 | 44 | module.exports.pwm.setPinMode(pin, mode, callback); 45 | 46 | } else { 47 | 48 | err = new verror('This mode is currently not supported by octalbonescript'); 49 | if(typeof callback == 'function') callback(err); 50 | 51 | } 52 | }, 53 | 54 | setPinModeSync: function(pin, mode) { 55 | if (mode == "gpio" || mode == "gpio_pu" || mode == "gpio_pd") { 56 | 57 | return module.exports.digital.setPinModeSync(pin, mode); 58 | 59 | } else if (mode == "pwm") { 60 | 61 | return module.exports.pwm.setPinModeSync(pin, mode); 62 | 63 | } else { 64 | 65 | return new verror('This mode is currently not supported by octalbonescript'); 66 | 67 | } 68 | }, 69 | 70 | readEeproms: function(eeproms) { 71 | var EepromFiles = { 72 | '/sys/bus/i2c/drivers/at24/0-0050/eeprom': { 73 | type: 'bone' 74 | }, 75 | '/sys/bus/i2c/drivers/at24/2-0054/eeprom': { 76 | type: 'cape' 77 | }, 78 | '/sys/bus/i2c/drivers/at24/2-0055/eeprom': { 79 | type: 'cape' 80 | }, 81 | '/sys/bus/i2c/drivers/at24/2-0056/eeprom': { 82 | type: 'cape' 83 | }, 84 | '/sys/bus/i2c/drivers/at24/2-0057/eeprom': { 85 | type: 'cape' 86 | } 87 | }; 88 | eeproms = eeprom.readEeproms(EepromFiles); 89 | return (eeproms); 90 | }, 91 | 92 | readPlatform: function(platform) { 93 | var eeproms = eeprom.readEeproms({ 94 | '/sys/bus/i2c/drivers/at24/0-0050/eeprom': { 95 | type: 'bone' 96 | } 97 | }); 98 | var x = eeproms['/sys/bus/i2c/drivers/at24/0-0050/eeprom']; 99 | if (x.boardName == 'A335BONE') platform.name = 'BeagleBone'; 100 | if (x.boardName == 'A335BNLT') platform.name = 'BeagleBone Black'; 101 | platform.version = x.version; 102 | if (!platform.version.match(/^[\040-\176]*$/)) delete platform.version; 103 | platform.serialNumber = x.serialNumber; 104 | if (!platform.serialNumber.match(/^[\040-\176]*$/)) delete platform.serialNumber; 105 | try { 106 | platform.dogtag = fs.readFileSync('/etc/dogtag', 'ascii'); 107 | } catch (ex) {} 108 | return (platform); 109 | } 110 | }; 111 | -------------------------------------------------------------------------------- /lib/i2c.js: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 - Texas Instruments, Jason Kridner 2 | // Modified by Aditya Patadia, Octal Consulting LLP 3 | // Modified by Andrew DeVries, Digital Example LLC move to path + address to allow multiple i2c slaves 4 | var fs = require('fs'); 5 | var verror = require("verror"); 6 | var bone = require('./bone'); 7 | var i2cPort = bone.require("i2c"); 8 | var pinmap = require('./pinmap'); 9 | var debug = require('debug')('bone'); 10 | 11 | var i2c = { 12 | ports: pinmap.i2c, 13 | openPorts: {} 14 | }; 15 | 16 | module.exports = { 17 | enable: function (path, callback) { 18 | debug("i2c.enable(" + path + ")"); 19 | if (!i2c.ports[path]) { 20 | throw new verror("Supplied path:" + path + " is not a vaild i2c port path."); 21 | } 22 | var sclPin = i2c.ports[path].scl; 23 | var sdaPin = i2c.ports[path].sda; 24 | var setSclPinState = false; 25 | 26 | bone.find_sysfsFile("ocp:" + sclPin + "_pinmux", bone.is_ocp(),"ocp:" + sclPin + "_pinmux", onFindPinmux); 27 | 28 | function onFindPinmux(err, data) { 29 | if (err) { 30 | err = new verror(err, "Error finding pinmux for: " + txPin); 31 | console.error(err.message); 32 | if (callback) callback(err); 33 | return; 34 | } 35 | fs.writeFile(data.path + "/state", "i2c", onWriteState); 36 | } 37 | 38 | function onWriteState(err) { 39 | if (err) { 40 | err = new verror(err, "Error setting pin state to I2C. Please unload I2C cape if already loaded."); 41 | console.error(err.message); 42 | if (callback) callback(err); 43 | return; 44 | } 45 | if (setSclPinState) { 46 | if (callback) callback(null); 47 | } else { 48 | setSclPinState = true; 49 | bone.find_sysfsFile("ocp:" + sdaPin + "_pinmux", bone.is_ocp(),"ocp:" + sdaPin + "_pinmux", onFindPinmux); 50 | } 51 | } 52 | }, 53 | 54 | open: function(path, address, handler, callback) { 55 | debug("i2c.open(" + path + ", " + address + ")"); 56 | if (!i2c.ports[path]) { 57 | throw new verror("Supplied path:" + path + " is not a vaild i2c port path."); 58 | } 59 | 60 | if (typeof handler != "function" || typeof callback != 'function') { 61 | throw new verror("handler and callback must be provided to i2c.open and both should be functions"); 62 | } 63 | 64 | module.exports.enable(path, onI2CEnable); 65 | 66 | function onI2CEnable(err) { 67 | if (err) { 68 | throw new verror(err); 69 | } 70 | 71 | if (!i2c.openPorts[path + ':' + address]) { 72 | var port = new i2cPort(address, { 73 | device: i2c.ports[path].path 74 | }); 75 | debug('opened i2c port: ' + path + ':' + address); 76 | port.on('data', handler); 77 | i2c.openPorts[path + ':' + address] = port; 78 | if (callback) callback(null, i2c.openPorts[path + ':' + address]); 79 | } else { 80 | if (callback) callback(null, i2c.openPorts[path + ':' + address]); 81 | } 82 | } 83 | }, 84 | 85 | writeByte: function(path, address, byte, callback) { 86 | debug("i2c.writeByte(" + path + ':' + address + ", " + byte + ")"); 87 | if (!i2c.openPorts[path + ':' + address]) { 88 | throw new verror("I2C port " + path + ':' + address + " is not open. Please call i2c.open function to open it."); 89 | } 90 | var port = i2c.openPorts[path + ':' + address]; 91 | port.writeByte(byte, callback); 92 | }, 93 | 94 | writeBytes: function (path, address, command, byteArray, callback) { 95 | debug("i2c.writeBytes(" + path + ", " + command + ", " + byteArray + ")"); 96 | if (!i2c.openPorts[path + ':' + address]) { 97 | throw new verror("I2C port " + path + ':' + address + " is not open. Please call i2c.open function to open it."); 98 | } 99 | var port = i2c.openPorts[path + ':' + address]; 100 | port.writeBytes(command, byteArray, callback); 101 | }, 102 | 103 | readByte: function(path, address, callback) { 104 | debug("i2c.readByte(" + path + ':' + address + ")"); 105 | if (!i2c.openPorts[path + ':' + address]) { 106 | throw new verror("I2C port " + path + ':' + address + " is not open. Please call i2c.open function to open it."); 107 | } 108 | var port = i2c.openPorts[path + ':' + address]; 109 | port.readByte(callback); 110 | }, 111 | 112 | readBytes: function(path, address, command, length, callback) { 113 | debug("i2c.readBytes(" + path + ':' + address + ", " + command + ", " + length + ")"); 114 | if (!i2c.openPorts[path + ':' + address]) { 115 | throw new verror("I2C port " + path + ':' + address + " is not open. Please call i2c.open function to open it."); 116 | } 117 | var port = i2c.openPorts[path + ':' + address]; 118 | port.readBytes(command, length, callback); 119 | }, 120 | 121 | stream: function(path, address, command, length, delay) { 122 | debug("i2c.readBytes(" + path + ':' + address + ", " + command + ", " + length + ", " + delay + ")"); 123 | if (!i2c.openPorts[path + ':' + address]) { 124 | throw new verror("I2C port " + path + ':' + address + " is not open. Please call i2c.open function to open it."); 125 | } 126 | var port = i2c.openPorts[path + ':' + address]; 127 | port.stream(command, length, delay); 128 | }, 129 | 130 | write: function (path, address, byteArray, callback) { 131 | debug("i2c.readBytes(" + path + ':' + address + ", " + byteArray + ")"); 132 | if (!i2c.openPorts[path]) { 133 | throw new verror("I2C port " + path + ':' + address + " is not open. Please call i2c.open function to open it."); 134 | } 135 | var port = i2c.openPorts[path + ':' + address]; 136 | port.write(byteArray, callback); 137 | }, 138 | 139 | read: function(path, length, callback) { 140 | debug("i2c.readBytes(" + path + ':' + address + ", " + length + ")"); 141 | if (!i2c.openPorts[path + ':' + address]) { 142 | throw new verror("I2C port " + path + ':' + address + " is not open. Please call i2c.open function to open it."); 143 | } 144 | var port = i2c.openPorts[path + ':' + address]; 145 | port.read(length, callback); 146 | }, 147 | 148 | }; 149 | -------------------------------------------------------------------------------- /lib/pinmap.json: -------------------------------------------------------------------------------- 1 | { 2 | "USR0": { 3 | "name": "USR0", 4 | "gpio": 53, 5 | "led": "usr0", 6 | "mux": "gpmc_a5", 7 | "key": "USR0", 8 | "muxRegOffset": "0x054", 9 | "modes": [ 10 | "gpmc_a5", 11 | "gmii2_txd0", 12 | "rgmii2_td0", 13 | "rmii2_txd0", 14 | "gpmc_a21", 15 | "pr1_mii1_rxd3", 16 | "eqep1b_in", 17 | "gpio1_21" 18 | ] 19 | }, 20 | "USR1": { 21 | "name": "USR1", 22 | "gpio": 54, 23 | "led": "usr1", 24 | "mux": "gpmc_a6", 25 | "key": "USR1", 26 | "muxRegOffset": "0x058", 27 | "modes": [ 28 | "gpmc_a6", 29 | "gmii2_txclk", 30 | "rgmii2_tclk", 31 | "mmc2_dat4", 32 | "gpmc_a22", 33 | "pr1_mii1_rxd2", 34 | "eqep1_index", 35 | "gpio1_22" 36 | ] 37 | }, 38 | "USR2": { 39 | "name": "USR2", 40 | "gpio": 55, 41 | "led": "usr2", 42 | "mux": "gpmc_a7", 43 | "key": "USR2", 44 | "muxRegOffset": "0x05c", 45 | "modes": [ 46 | "gpmc_a7", 47 | "gmii2_rxclk", 48 | "rgmii2_rclk", 49 | "mmc2_dat5", 50 | "gpmc_a23", 51 | "pr1_mii1_rxd1", 52 | "eqep1_strobe", 53 | "gpio1_23" 54 | ] 55 | }, 56 | "USR3": { 57 | "name": "USR3", 58 | "gpio": 56, 59 | "led": "usr3", 60 | "mux": "gpmc_a8", 61 | "key": "USR3", 62 | "muxRegOffset": "0x060", 63 | "modes": [ 64 | "gpmc_a8", 65 | "gmii2_rxd3", 66 | "rgmii2_rd3", 67 | "mmc2_dat6", 68 | "gpmc_a24", 69 | "pr1_mii1_rxd0", 70 | "mcasp0_aclkx", 71 | "gpio1_24" 72 | ] 73 | }, 74 | "P8_01": { 75 | "name": "DGND", 76 | "key": "P8_01" 77 | }, 78 | "P8_02": { 79 | "name": "DGND", 80 | "key": "P8_02" 81 | }, 82 | "P8_03": { 83 | "name": "GPIO1_6", 84 | "gpio": 38, 85 | "mux": "gpmc_ad6", 86 | "eeprom": 26, 87 | "key": "P8_03", 88 | "muxRegOffset": "0x018", 89 | "modes": [ 90 | "gpmc_ad6", 91 | "mmc1_dat6", 92 | "NA", 93 | "NA", 94 | "NA", 95 | "NA", 96 | "NA", 97 | "gpio1_6" 98 | ] 99 | }, 100 | "P8_04": { 101 | "name": "GPIO1_7", 102 | "gpio": 39, 103 | "mux": "gpmc_ad7", 104 | "eeprom": 27, 105 | "key": "P8_04", 106 | "muxRegOffset": "0x01c", 107 | "modes": [ 108 | "gpmc_ad7", 109 | "mmc1_dat7", 110 | "NA", 111 | "NA", 112 | "NA", 113 | "NA", 114 | "NA", 115 | "gpio1_7" 116 | ] 117 | }, 118 | "P8_05": { 119 | "name": "GPIO1_2", 120 | "gpio": 34, 121 | "mux": "gpmc_ad2", 122 | "eeprom": 22, 123 | "key": "P8_05", 124 | "muxRegOffset": "0x008", 125 | "modes": [ 126 | "gpmc_ad2", 127 | "mmc1_dat2", 128 | "NA", 129 | "NA", 130 | "NA", 131 | "NA", 132 | "NA", 133 | "gpio1_2" 134 | ] 135 | }, 136 | "P8_06": { 137 | "name": "GPIO1_3", 138 | "gpio": 35, 139 | "mux": "gpmc_ad3", 140 | "eeprom": 23, 141 | "key": "P8_06", 142 | "muxRegOffset": "0x00c", 143 | "modes": [ 144 | "gpmc_ad3", 145 | "mmc1_dat3", 146 | "NA", 147 | "NA", 148 | "NA", 149 | "NA", 150 | "NA", 151 | "gpio1_3" 152 | ] 153 | }, 154 | "P8_07": { 155 | "name": "TIMER4", 156 | "gpio": 66, 157 | "mux": "gpmc_advn_ale", 158 | "eeprom": 41, 159 | "key": "P8_07", 160 | "muxRegOffset": "0x090", 161 | "modes": ["gpio", "gpio_pu", "gpio_pd", "timer"] 162 | }, 163 | "P8_08": { 164 | "name": "TIMER7", 165 | "gpio": 67, 166 | "mux": "gpmc_oen_ren", 167 | "eeprom": 44, 168 | "key": "P8_08", 169 | "muxRegOffset": "0x094", 170 | "modes": ["gpio", "gpio_pu", "gpio_pd", "timer"] 171 | }, 172 | "P8_09": { 173 | "name": "TIMER5", 174 | "gpio": 69, 175 | "mux": "gpmc_ben0_cle", 176 | "eeprom": 42, 177 | "key": "P8_09", 178 | "muxRegOffset": "0x09c", 179 | "modes": ["gpio", "gpio_pu", "gpio_pd", "timer"] 180 | }, 181 | "P8_10": { 182 | "name": "TIMER6", 183 | "gpio": 68, 184 | "mux": "gpmc_wen", 185 | "eeprom": 43, 186 | "key": "P8_10", 187 | "muxRegOffset": "0x098", 188 | "modes": ["gpio", "gpio_pu", "gpio_pd", "timer"] 189 | }, 190 | "P8_11": { 191 | "name": "GPIO1_13", 192 | "gpio": 45, 193 | "mux": "gpmc_ad13", 194 | "eeprom": 29, 195 | "key": "P8_11", 196 | "muxRegOffset": "0x034", 197 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "qep"] 198 | }, 199 | "P8_12": { 200 | "name": "GPIO1_12", 201 | "gpio": 44, 202 | "mux": "gpmc_ad12", 203 | "eeprom": 28, 204 | "key": "P8_12", 205 | "muxRegOffset": "0x030", 206 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "qep"] 207 | }, 208 | "P8_13": { 209 | "name": "EHRPWM2B", 210 | "gpio": 23, 211 | "mux": "gpmc_ad9", 212 | "eeprom": 15, 213 | "pwm": { 214 | "module": "ehrpwm2", 215 | "chipAddress": "48304000", 216 | "featAddress": "48304200.ehrpwm", 217 | "sysfs": 6, 218 | "index": 1, 219 | "muxmode": 4, 220 | "path": "ehrpwm.2:1", 221 | "name": "EHRPWM2B" 222 | }, 223 | "key": "P8_13", 224 | "muxRegOffset": "0x024", 225 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 226 | }, 227 | "P8_14": { 228 | "name": "GPIO0_26", 229 | "gpio": 26, 230 | "mux": "gpmc_ad10", 231 | "eeprom": 16, 232 | "key": "P8_14", 233 | "muxRegOffset": "0x028", 234 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 235 | }, 236 | "P8_15": { 237 | "name": "GPIO1_15", 238 | "gpio": 47, 239 | "mux": "gpmc_ad15", 240 | "eeprom": 31, 241 | "key": "P8_15", 242 | "muxRegOffset": "0x03c", 243 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruin", "qep"] 244 | }, 245 | "P8_16": { 246 | "name": "GPIO1_14", 247 | "gpio": 46, 248 | "mux": "gpmc_ad14", 249 | "eeprom": 30, 250 | "key": "P8_16", 251 | "muxRegOffset": "0x038", 252 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruin", "qep"] 253 | }, 254 | "P8_17": { 255 | "name": "GPIO0_27", 256 | "gpio": 27, 257 | "mux": "gpmc_ad11", 258 | "eeprom": 17, 259 | "key": "P8_17", 260 | "muxRegOffset": "0x02c", 261 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 262 | }, 263 | "P8_18": { 264 | "name": "GPIO2_1", 265 | "gpio": 65, 266 | "mux": "gpmc_clk", 267 | "eeprom": 40, 268 | "key": "P8_18", 269 | "muxRegOffset": "0x08c", 270 | "modes": ["gpio", "gpio_pu", "gpio_pd"] 271 | }, 272 | "P8_19": { 273 | "name": "EHRPWM2A", 274 | "gpio": 22, 275 | "mux": "gpmc_ad8", 276 | "eeprom": 14, 277 | "pwm": { 278 | "module": "ehrpwm2", 279 | "chipAddress": "48304000", 280 | "featAddress": "48304200.ehrpwm", 281 | "sysfs": 5, 282 | "index": 0, 283 | "muxmode": 4, 284 | "path": "ehrpwm.2:0", 285 | "name": "EHRPWM2A" 286 | }, 287 | "key": "P8_19", 288 | "muxRegOffset": "0x020", 289 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 290 | }, 291 | "P8_20": { 292 | "name": "GPIO1_31", 293 | "gpio": 63, 294 | "mux": "gpmc_csn2", 295 | "eeprom": 39, 296 | "key": "P8_20", 297 | "muxRegOffset": "0x084", 298 | "modes": [ 299 | "gpmc_csn2", 300 | "gpmc_be1n", 301 | "mmc1_cmd", 302 | "pr1_edio_data_in7", 303 | "pr1_edio_data_out7", 304 | "pr1_pru1_pru_r30_13", 305 | "pr1_pru1_pru_r31_13", 306 | "gpio1_31" 307 | ] 308 | }, 309 | "P8_21": { 310 | "name": "GPIO1_30", 311 | "gpio": 62, 312 | "mux": "gpmc_csn1", 313 | "eeprom": 38, 314 | "key": "P8_21", 315 | "muxRegOffset": "0x080", 316 | "modes": [ 317 | "gpmc_csn1", 318 | "gpmc_clk", 319 | "mmc1_clk", 320 | "pr1_edio_data_in6", 321 | "pr1_edio_data_out6", 322 | "pr1_pru1_pru_r30_12", 323 | "pr1_pru1_pru_r31_12", 324 | "gpio1_30" 325 | ] 326 | }, 327 | "P8_22": { 328 | "name": "GPIO1_5", 329 | "gpio": 37, 330 | "mux": "gpmc_ad5", 331 | "eeprom": 25, 332 | "key": "P8_22", 333 | "muxRegOffset": "0x014", 334 | "modes": [ 335 | "gpmc_ad5", 336 | "mmc1_dat5", 337 | "NA", 338 | "NA", 339 | "NA", 340 | "NA", 341 | "NA", 342 | "gpio1_5" 343 | ] 344 | }, 345 | "P8_23": { 346 | "name": "GPIO1_4", 347 | "gpio": 36, 348 | "mux": "gpmc_ad4", 349 | "eeprom": 24, 350 | "key": "P8_23", 351 | "muxRegOffset": "0x010", 352 | "modes": [ 353 | "gpmc_ad4", 354 | "mmc1_dat4", 355 | "NA", 356 | "NA", 357 | "NA", 358 | "NA", 359 | "NA", 360 | "gpio1_4" 361 | ] 362 | }, 363 | "P8_24": { 364 | "name": "GPIO1_1", 365 | "gpio": 33, 366 | "mux": "gpmc_ad1", 367 | "eeprom": 21, 368 | "key": "P8_24", 369 | "muxRegOffset": "0x004", 370 | "modes": [ 371 | "gpmc_ad1", 372 | "mmc1_dat1", 373 | "NA", 374 | "NA", 375 | "NA", 376 | "NA", 377 | "NA", 378 | "gpio1_1" 379 | ] 380 | }, 381 | "P8_25": { 382 | "name": "GPIO1_0", 383 | "gpio": 32, 384 | "mux": "gpmc_ad0", 385 | "eeprom": 20, 386 | "key": "P8_25", 387 | "muxRegOffset": "0x000", 388 | "modes": [ 389 | "gpmc_ad0", 390 | "mmc1_dat0", 391 | "NA", 392 | "NA", 393 | "NA", 394 | "NA", 395 | "NA", 396 | "gpio1_0" 397 | ] 398 | }, 399 | "P8_26": { 400 | "name": "GPIO1_29", 401 | "gpio": 61, 402 | "mux": "gpmc_csn0", 403 | "eeprom": 37, 404 | "key": "P8_26", 405 | "muxRegOffset": "0x07c", 406 | "modes": ["gpio", "gpio_pu", "gpio_pd"] 407 | }, 408 | "P8_27": { 409 | "name": "GPIO2_22", 410 | "gpio": 86, 411 | "mux": "lcd_vsync", 412 | "eeprom": 57, 413 | "key": "P8_27", 414 | "muxRegOffset": "0x0e0", 415 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin"] 416 | }, 417 | "P8_28": { 418 | "name": "GPIO2_24", 419 | "gpio": 88, 420 | "mux": "lcd_pclk", 421 | "eeprom": 59, 422 | "key": "P8_28", 423 | "muxRegOffset": "0x0e8", 424 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin"] 425 | }, 426 | "P8_29": { 427 | "name": "GPIO2_23", 428 | "gpio": 87, 429 | "mux": "lcd_hsync", 430 | "eeprom": 58, 431 | "key": "P8_29", 432 | "muxRegOffset": "0x0e4", 433 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin"] 434 | }, 435 | "P8_30": { 436 | "name": "GPIO2_25", 437 | "gpio": 89, 438 | "mux": "lcd_ac_bias_en", 439 | "eeprom": 60, 440 | "key": "P8_30", 441 | "muxRegOffset": "0x0ec", 442 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin"] 443 | }, 444 | "P8_31": { 445 | "name": "UART5_CTSN", 446 | "gpio": 10, 447 | "mux": "lcd_data14", 448 | "eeprom": 7, 449 | "key": "P8_31", 450 | "muxRegOffset": "0x0d8", 451 | "modes": ["gpio", "gpio_pu", "gpio_pd", "uart"] 452 | }, 453 | "P8_32": { 454 | "name": "UART5_RTSN", 455 | "gpio": 11, 456 | "mux": "lcd_data15", 457 | "eeprom": 8, 458 | "key": "P8_32", 459 | "muxRegOffset": "0x0dc", 460 | "modes": ["gpio", "gpio_pu", "gpio_pd"] 461 | }, 462 | "P8_33": { 463 | "name": "UART4_RTSN", 464 | "gpio": 9, 465 | "mux": "lcd_data13", 466 | "eeprom": 6, 467 | "key": "P8_33", 468 | "muxRegOffset": "0x0d4", 469 | "modes": ["gpio", "gpio_pu", "gpio_pd"] 470 | }, 471 | "P8_34": { 472 | "name": "UART3_RTSN", 473 | "gpio": 81, 474 | "mux": "lcd_data11", 475 | "eeprom": 56, 476 | "pwm": { 477 | "module": "ehrpwm1", 478 | "chipAddress": "48302000", 479 | "featAddress": "48302200.ehrpwm", 480 | "sysfs": 4, 481 | "index": 1, 482 | "muxmode": 2, 483 | "path": "ehrpwm.1:1", 484 | "name": "EHRPWM1B" 485 | }, 486 | "key": "P8_34", 487 | "muxRegOffset": "0x0cc", 488 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 489 | }, 490 | "P8_35": { 491 | "name": "UART4_CTSN", 492 | "gpio": 8, 493 | "mux": "lcd_data12", 494 | "eeprom": 5, 495 | "key": "P8_35", 496 | "muxRegOffset": "0x0d0", 497 | "modes": ["gpio", "gpio_pu", "gpio_pd"] 498 | }, 499 | "P8_36": { 500 | "name": "UART3_CTSN", 501 | "gpio": 80, 502 | "mux": "lcd_data10", 503 | "eeprom": 55, 504 | "pwm": { 505 | "module": "ehrpwm1", 506 | "chipAddress": "48302000", 507 | "featAddress": "48302200.ehrpwm", 508 | "sysfs": 3, 509 | "index": 0, 510 | "muxmode": 2, 511 | "path": "ehrpwm.1:0", 512 | "name": "EHRPWM1A" 513 | }, 514 | "key": "P8_36", 515 | "muxRegOffset": "0x0c8", 516 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 517 | }, 518 | "P8_37": { 519 | "name": "UART5_TXD", 520 | "gpio": 78, 521 | "mux": "lcd_data8", 522 | "eeprom": 53, 523 | "key": "P8_37", 524 | "muxRegOffset": "0x0c0", 525 | "modes": ["gpio", "gpio_pu", "gpio_pd", "uart", "pwm"] 526 | }, 527 | "P8_38": { 528 | "name": "UART5_RXD", 529 | "gpio": 79, 530 | "mux": "lcd_data9", 531 | "eeprom": 54, 532 | "key": "P8_38", 533 | "muxRegOffset": "0x0c4", 534 | "modes": ["gpio", "gpio_pu", "gpio_pd", "uart", "pwm"] 535 | }, 536 | "P8_39": { 537 | "name": "GPIO2_12", 538 | "gpio": 76, 539 | "mux": "lcd_data6", 540 | "eeprom": 51, 541 | "key": "P8_39", 542 | "muxRegOffset": "0x0b8", 543 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin"] 544 | }, 545 | "P8_40": { 546 | "name": "GPIO2_13", 547 | "gpio": 77, 548 | "mux": "lcd_data7", 549 | "eeprom": 52, 550 | "key": "P8_40", 551 | "muxRegOffset": "0x0bc", 552 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin"] 553 | }, 554 | "P8_41": { 555 | "name": "GPIO2_10", 556 | "gpio": 74, 557 | "mux": "lcd_data4", 558 | "eeprom": 49, 559 | "key": "P8_41", 560 | "muxRegOffset": "0x0b0", 561 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin"] 562 | }, 563 | "P8_42": { 564 | "name": "GPIO2_11", 565 | "gpio": 75, 566 | "mux": "lcd_data5", 567 | "eeprom": 50, 568 | "key": "P8_42", 569 | "muxRegOffset": "0x0b4", 570 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin"] 571 | }, 572 | "P8_43": { 573 | "name": "GPIO2_8", 574 | "gpio": 72, 575 | "mux": "lcd_data2", 576 | "eeprom": 47, 577 | "key": "P8_43", 578 | "muxRegOffset": "0x0a8", 579 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "pwm"] 580 | }, 581 | "P8_44": { 582 | "name": "GPIO2_9", 583 | "gpio": 73, 584 | "mux": "lcd_data3", 585 | "eeprom": 48, 586 | "key": "P8_44", 587 | "muxRegOffset": "0x0ac", 588 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "pwm"] 589 | }, 590 | "P8_45": { 591 | "name": "GPIO2_6", 592 | "gpio": 70, 593 | "mux": "lcd_data0", 594 | "eeprom": 45, 595 | "pwm": { 596 | "module": "ehrpwm2", 597 | "chipAddress": "48304000", 598 | "featAddress": "48304200.ehrpwm", 599 | "sysfs": 5, 600 | "index": 0, 601 | "muxmode": 3, 602 | "path": "ehrpwm.2:0", 603 | "name": "EHRPWM2A" 604 | }, 605 | "key": "P8_45", 606 | "muxRegOffset": "0x0a0", 607 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "pwm"] 608 | }, 609 | "P8_46": { 610 | "name": "GPIO2_7", 611 | "gpio": 71, 612 | "mux": "lcd_data1", 613 | "eeprom": 46, 614 | "pwm": { 615 | "module": "ehrpwm2", 616 | "chipAddress": "48304000", 617 | "featAddress": "48304200.ehrpwm", 618 | "sysfs": 6, 619 | "index": 1, 620 | "muxmode": 3, 621 | "path": "ehrpwm.2:1", 622 | "name": "EHRPWM2B" 623 | }, 624 | "key": "P8_46", 625 | "muxRegOffset": "0x0a4", 626 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "pwm"] 627 | }, 628 | "P9_01": { 629 | "name": "DGND", 630 | "key": "P9_01" 631 | }, 632 | "P9_02": { 633 | "name": "DGND", 634 | "key": "P9_02" 635 | }, 636 | "P9_03": { 637 | "name": "VDD_3V3", 638 | "key": "P9_03" 639 | }, 640 | "P9_04": { 641 | "name": "VDD_3V3", 642 | "key": "P9_4" 643 | }, 644 | "P9_05": { 645 | "name": "VDD_5V", 646 | "key": "P9_05" 647 | }, 648 | "P9_06": { 649 | "name": "VDD_5V", 650 | "key": "P9_06" 651 | }, 652 | "P9_07": { 653 | "name": "SYS_5V", 654 | "key": "P9_07" 655 | }, 656 | "P9_08": { 657 | "name": "SYS_5V", 658 | "key": "P9_08" 659 | }, 660 | "P9_09": { 661 | "name": "PWR_BUT", 662 | "key": "P9_09" 663 | }, 664 | "P9_10": { 665 | "name": "SYS_RESETn", 666 | "key": "P9_10" 667 | }, 668 | "P9_11": { 669 | "name": "UART4_RXD", 670 | "gpio": 30, 671 | "mux": "gpmc_wait0", 672 | "eeprom": 18, 673 | "key": "P9_11", 674 | "muxRegOffset": "0x070", 675 | "modes": ["gpio", "gpio_pu", "gpio_pd", "uart"] 676 | }, 677 | "P9_12": { 678 | "name": "GPIO1_28", 679 | "gpio": 60, 680 | "mux": "gpmc_ben1", 681 | "eeprom": 36, 682 | "key": "P9_12", 683 | "muxRegOffset": "0x078", 684 | "modes": ["gpio", "gpio_pu", "gpio_pd"] 685 | }, 686 | "P9_13": { 687 | "name": "UART4_TXD", 688 | "gpio": 31, 689 | "mux": "gpmc_wpn", 690 | "eeprom": 19, 691 | "key": "P9_13", 692 | "muxRegOffset": "0x074", 693 | "modes": ["gpio", "gpio_pu", "gpio_pd", "uart"] 694 | }, 695 | "P9_14": { 696 | "name": "EHRPWM1A", 697 | "gpio": 50, 698 | "mux": "gpmc_a2", 699 | "eeprom": 34, 700 | "pwm": { 701 | "module": "ehrpwm1", 702 | "chipAddress": "48302000", 703 | "featAddress": "48302200.ehrpwm", 704 | "sysfs": 3, 705 | "index": 0, 706 | "muxmode": 6, 707 | "path": "ehrpwm.1:0", 708 | "name": "EHRPWM1A" 709 | }, 710 | "key": "P9_14", 711 | "muxRegOffset": "0x048", 712 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 713 | }, 714 | "P9_15": { 715 | "name": "GPIO1_16", 716 | "gpio": 48, 717 | "mux": "mii1_rxd3", 718 | "eeprom": 32, 719 | "key": "P9_15", 720 | "muxRegOffset": "0x040", 721 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 722 | }, 723 | "P9_16": { 724 | "name": "EHRPWM1B", 725 | "gpio": 51, 726 | "mux": "gpmc_a3", 727 | "eeprom": 35, 728 | "pwm": { 729 | "module": "ehrpwm1", 730 | "chipAddress": "48302000", 731 | "featAddress": "48302200.ehrpwm", 732 | "sysfs": 4, 733 | "index": 1, 734 | "muxmode": 6, 735 | "path": "ehrpwm.1:1", 736 | "name": "EHRPWM1B" 737 | }, 738 | "key": "P9_16", 739 | "muxRegOffset": "0x04c", 740 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 741 | }, 742 | "P9_17": { 743 | "name": "I2C1_SCL", 744 | "gpio": 5, 745 | "mux": "spi0_cs0", 746 | "eeprom": 3, 747 | "key": "P9_17", 748 | "muxRegOffset": "0x15c", 749 | "modes": ["gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm"] 750 | }, 751 | "P9_18": { 752 | "name": "I2C1_SDA", 753 | "gpio": 4, 754 | "mux": "spi0_d1", 755 | "eeprom": 2, 756 | "key": "P9_18", 757 | "muxRegOffset": "0x158", 758 | "modes": ["gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm"] 759 | }, 760 | "P9_19": { 761 | "name": "I2C2_SCL", 762 | "gpio": 13, 763 | "mux": "uart1_rtsn", 764 | "eeprom": 9, 765 | "key": "P9_19", 766 | "muxRegOffset": "0x17c", 767 | "modes": [ 768 | "uart1_rtsn", 769 | "NA", 770 | "d_can0_rx", 771 | "i2c2_scl", 772 | "spi1_cs1", 773 | "NA", 774 | "NA", 775 | "gpio0_13" 776 | ] 777 | }, 778 | "P9_20": { 779 | "name": "I2C2_SDA", 780 | "gpio": 12, 781 | "mux": "uart1_ctsn", 782 | "eeprom": 10, 783 | "key": "P9_20", 784 | "muxRegOffset": "0x178", 785 | "modes": [ 786 | "uart1_ctsn", 787 | "NA", 788 | "d_can0_tx", 789 | "i2c2_sda", 790 | "spi1_cs0", 791 | "NA", 792 | "NA", 793 | "gpio0_12" 794 | ] 795 | }, 796 | "P9_21": { 797 | "name": "UART2_TXD", 798 | "gpio": 3, 799 | "mux": "spi0_d0", 800 | "eeprom": 1, 801 | "pwm": { 802 | "module": "ehrpwm0", 803 | "chipAddress": "48300000", 804 | "featAddress": "48300200.ehrpwm", 805 | "sysfs": 1, 806 | "index": 1, 807 | "muxmode": 3, 808 | "path": "ehrpwm.0:1", 809 | "name": "EHRPWM0B" 810 | }, 811 | "key": "P9_21", 812 | "muxRegOffset": "0x154", 813 | "modes": ["gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm"] 814 | }, 815 | "P9_22": { 816 | "name": "UART2_RXD", 817 | "gpio": 2, 818 | "mux": "spi0_sclk", 819 | "eeprom": 0, 820 | "pwm": { 821 | "module": "ehrpwm0", 822 | "chipAddress": "48300000", 823 | "featAddress": "48300200.ehrpwm", 824 | "sysfs": 0, 825 | "index": 0, 826 | "muxmode": 3, 827 | "path": "ehrpwm.0:0", 828 | "name": "EHRPWM0A" 829 | }, 830 | "key": "P9_22", 831 | "muxRegOffset": "0x150", 832 | "modes": ["gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm"] 833 | }, 834 | "P9_23": { 835 | "name": "GPIO1_17", 836 | "gpio": 49, 837 | "mux": "gpmc_a1", 838 | "eeprom": 33, 839 | "key": "P9_23", 840 | "muxRegOffset": "0x044", 841 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm"] 842 | }, 843 | "P9_24": { 844 | "name": "UART1_TXD", 845 | "gpio": 15, 846 | "mux": "uart1_txd", 847 | "eeprom": 12, 848 | "key": "P9_24", 849 | "muxRegOffset": "0x184", 850 | "modes": ["gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pruin"] 851 | }, 852 | "P9_25": { 853 | "name": "GPIO3_21", 854 | "gpio": 117, 855 | "mux": "mcasp0_ahclkx", 856 | "eeprom": 66, 857 | "key": "P9_25", 858 | "muxRegOffset": "0x1ac", 859 | "modes": ["gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"] 860 | }, 861 | "P9_26": { 862 | "name": "UART1_RXD", 863 | "gpio": 14, 864 | "mux": "uart1_rxd", 865 | "eeprom": 11, 866 | "key": "P9_26", 867 | "muxRegOffset": "0x180", 868 | "modes": ["gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pruin"] 869 | }, 870 | "P9_27": { 871 | "name": "GPIO3_19", 872 | "gpio": 115, 873 | "mux": "mcasp0_fsr", 874 | "eeprom": 64, 875 | "key": "P9_27", 876 | "muxRegOffset": "0x1a4", 877 | "modes": ["gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"] 878 | }, 879 | "P9_28": { 880 | "name": "SPI1_CS0", 881 | "gpio": 113, 882 | "mux": "mcasp0_ahclkr", 883 | "eeprom": 63, 884 | "pwm": { 885 | "module": "ecap2", 886 | "chipAddress": "48304000", 887 | "featAddress": "48304100.ecap", 888 | "sysfs": 7, 889 | "index": 2, 890 | "muxmode": 4, 891 | "path": "ecap.2", 892 | "name": "ECAPPWM2" 893 | }, 894 | "key": "P9_28", 895 | "muxRegOffset": "0x19c", 896 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pwm2", "pruout", "pruin"] 897 | }, 898 | "P9_29": { 899 | "name": "SPI1_D0", 900 | "gpio": 111, 901 | "mux": "mcasp0_fsx", 902 | "eeprom": 61, 903 | "pwm": { 904 | "module": "ehrpwm0", 905 | "chipAddress": "48300000", 906 | "featAddress": "48300200.ehrpwm", 907 | "sysfs": 1, 908 | "index": 1, 909 | "muxmode": 1, 910 | "path": "ehrpwm.0:1", 911 | "name": "EHRPWM0B" 912 | }, 913 | "key": "P9_29", 914 | "muxRegOffset": "0x194", 915 | "modes": ["gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"] 916 | }, 917 | "P9_30": { 918 | "name": "SPI1_D1", 919 | "gpio": 112, 920 | "mux": "mcasp0_axr0", 921 | "eeprom": 62, 922 | "key": "P9_30", 923 | "muxRegOffset": "0x198", 924 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"] 925 | }, 926 | "P9_31": { 927 | "name": "SPI1_SCLK", 928 | "gpio": 110, 929 | "mux": "mcasp0_aclkx", 930 | "eeprom": 65, 931 | "pwm": { 932 | "module": "ehrpwm0", 933 | "chipAddress": "48300000", 934 | "featAddress": "48300200.ehrpwm", 935 | "sysfs": 0, 936 | "index": 0, 937 | "muxmode": 1, 938 | "path": "ehrpwm.0:0", 939 | "name": "EHRPWM0A" 940 | }, 941 | "key": "P9_31", 942 | "muxRegOffset": "0x190", 943 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"] 944 | }, 945 | "P9_32": { 946 | "name": "VDD_ADC", 947 | "key": "P9_32" 948 | }, 949 | "P9_33": { 950 | "name": "AIN4", 951 | "ain": 4, 952 | "eeprom": 71, 953 | "scale": 4096, 954 | "key": "P9_33" 955 | }, 956 | "P9_34": { 957 | "name": "GNDA_ADC", 958 | "key": "P9_34" 959 | }, 960 | "P9_35": { 961 | "name": "AIN6", 962 | "ain": 6, 963 | "eeprom": 73, 964 | "scale": 4096, 965 | "key": "P9_35" 966 | }, 967 | "P9_36": { 968 | "name": "AIN5", 969 | "ain": 5, 970 | "eeprom": 72, 971 | "scale": 4096, 972 | "key": "P9_36" 973 | }, 974 | "P9_37": { 975 | "name": "AIN2", 976 | "ain": 2, 977 | "eeprom": 69, 978 | "scale": 4096, 979 | "key": "P9_37" 980 | }, 981 | "P9_38": { 982 | "name": "AIN3", 983 | "ain": 3, 984 | "eeprom": 70, 985 | "scale": 4096, 986 | "key": "P9_38" 987 | }, 988 | "P9_39": { 989 | "name": "AIN0", 990 | "ain": 0, 991 | "eeprom": 67, 992 | "scale": 4096, 993 | "key": "P9_39" 994 | }, 995 | "P9_40": { 996 | "name": "AIN1", 997 | "ain": 1, 998 | "eeprom": 68, 999 | "scale": 4096, 1000 | "key": "P9_40" 1001 | }, 1002 | "P9_41": { 1003 | "name": "CLKOUT2", 1004 | "gpio": 20, 1005 | "mux": "xdma_event_intr1", 1006 | "eeprom": 13, 1007 | "key": "P9_41", 1008 | "muxRegOffset": "0x1b4", 1009 | "modes": ["gpio", "gpio_pu", "gpio_pd", "timer", "pruin"] 1010 | }, 1011 | "P9_42": { 1012 | "name": "GPIO0_7", 1013 | "gpio": 7, 1014 | "mux": "ecap0_in_pwm0_out", 1015 | "eeprom": 4, 1016 | "pwm": { 1017 | "module": "ecap0", 1018 | "chipAddress": "48300000", 1019 | "featAddress": "48300100.ecap", 1020 | "sysfs": 2, 1021 | "index": 0, 1022 | "muxmode": 0, 1023 | "path": "ecap.0", 1024 | "name": "ECAPPWM0" 1025 | }, 1026 | "key": "P9_42", 1027 | "muxRegOffset": "0x164", 1028 | "modes": ["gpio", "gpio_pu", "gpio_pd", "pwm", "uart", "spics", "spiclk"] 1029 | }, 1030 | "P9_43": { 1031 | "name": "DGND", 1032 | "key": "P9_43" 1033 | }, 1034 | "P9_44": { 1035 | "name": "DGND", 1036 | "key": "P9_44" 1037 | }, 1038 | "P9_45": { 1039 | "name": "DGND", 1040 | "key": "P9_45" 1041 | }, 1042 | "P9_46": { 1043 | "name": "DGND", 1044 | "key": "P9_46" 1045 | }, 1046 | "uarts": { 1047 | "/dev/ttyO0": {}, 1048 | "/dev/ttyO1": { 1049 | "rx": "P9_26", 1050 | "tx": "P9_24" 1051 | }, 1052 | "/dev/ttyO2": { 1053 | "rx": "P9_22", 1054 | "tx": "P9_21" 1055 | }, 1056 | "/dev/ttyO3": {}, 1057 | "/dev/ttyO4": { 1058 | "rx": "P9_11", 1059 | "tx": "P9_13" 1060 | }, 1061 | "/dev/ttyO5": { 1062 | "rx": "P8_38", 1063 | "tx": "P8_37" 1064 | } 1065 | }, 1066 | "i2c": { 1067 | "/dev/i2c-0": {}, 1068 | "/dev/i2c-1": { 1069 | "devicetree": "BB-I2C1", 1070 | "path": "/dev/i2c-2", 1071 | "sda": "P9_18", 1072 | "scl": "P9_17" 1073 | }, 1074 | "/dev/i2c-1a": { 1075 | "devicetree": "BB-I2C1A", 1076 | "path": "/dev/i2c-2", 1077 | "sda": "P9_26", 1078 | "scl": "P9_24" 1079 | }, 1080 | "/dev/i2c-2": { 1081 | "path": "/dev/i2c-1", 1082 | "sda": "P9_20", 1083 | "scl": "P9_19" 1084 | } 1085 | } 1086 | } 1087 | -------------------------------------------------------------------------------- /lib/pwm.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var debug = require('debug')('bone'); 3 | var bone = require('./bone'); 4 | var verror = require("verror"); 5 | 6 | var pwmPrefix = {}; 7 | 8 | module.exports = { 9 | 10 | 11 | setPinMode: function(pin, mode, callback) { 12 | debug('pwm.setPinMode(' + [pin.key, mode] + ');'); 13 | var p = "ocp:" + pin.key + "_pinmux"; 14 | bone.find_sysfsFile(p, bone.is_ocp(), p, onFindPinmux); 15 | 16 | function onFindPinmux(err, data) { 17 | debug("onFindPinmux: " + data.path); 18 | if (err) { 19 | if(typeof callback == 'function') callback(err); 20 | } else if (!data.path) { 21 | err = new verror("Pinmux file for " + p + " could not be found"); 22 | if(typeof callback == 'function') callback(err); 23 | } else { 24 | fs.writeFile(data.path + "/state", mode, onWriteState); //write mode to the state file... 25 | } 26 | } 27 | 28 | function onWriteState(err) { 29 | if (err) { 30 | err = new verror(err, "writeState problem"); 31 | if (typeof callback == 'function') callback(err); 32 | return; 33 | } 34 | pwmPrefix[pin.pwm.name] = '/sys/devices/platform/ocp/' + pin.pwm.chipAddress + '.epwmss/' + pin.pwm.featAddress + '/pwm'; 35 | fs.readdir(pwmPrefix[pin.pwm.name], function(err, files) { 36 | if (err) { 37 | err = new verror(err, "onFindPwmChip readdir problem"); 38 | if (typeof callback == 'function') callback(err); 39 | return; 40 | } 41 | pin.pwm.sysfs = files[0].slice(-1); 42 | pwmPrefix[pin.pwm.name] = '/sys/class/pwm/pwmchip' + pin.pwm.sysfs + '/pwm' + pin.pwm.index; 43 | debug(pin.pwm.module + ' belongs to pwmchip' + pin.pwm.sysfs); 44 | onFindPwmChip(err); 45 | }); 46 | } 47 | 48 | function onFindPwmChip(err) { 49 | if (err) { 50 | err = new verror(err, "onFindPwmChip problem"); 51 | if (typeof callback == 'function') callback(err); 52 | return; 53 | } 54 | pwmPrefix[pin.pwm.name] = '/sys/class/pwm/pwmchip' + pin.pwm.sysfs + '/pwm' + pin.pwm.index; 55 | fs.exists(pwmPrefix[pin.pwm.name], function(exists) { 56 | if (!exists) { 57 | fs.appendFile('/sys/class/pwm/pwmchip' + pin.pwm.sysfs + '/export', pin.pwm.index, onExport); // now export if not exported 58 | } else { 59 | fs.writeFile(pwmPrefix[pin.pwm.name] + '/enable', 1, onModeComplete); // now start PWM 60 | } 61 | }); 62 | } 63 | 64 | function onExport(err) { 65 | if (err) { 66 | err = new verror(err, "onExport problem"); 67 | if (typeof callback == 'function') callback(err); 68 | return; 69 | } 70 | fs.writeFile(pwmPrefix[pin.pwm.name] + '/enable', 1, onModeComplete); // now start PWM 71 | } 72 | 73 | function onModeComplete(err) { 74 | if (err) { 75 | err = new verror(err, "onModeComplete problem"); 76 | if (typeof callback == 'function') callback(err); 77 | return; 78 | } 79 | if (typeof callback == 'function') callback(null); 80 | } 81 | }, 82 | 83 | setPinModeSync: function(pin, mode) { 84 | debug('pwm.setPinMode(' + [pin.key, mode] + ');'); 85 | var p = "ocp:" + pin.key + "_pinmux"; 86 | var path = bone.find_sysfsFile(p, bone.is_ocp(), p); 87 | 88 | fs.writeFileSync(path + "/state", mode); 89 | pwmPrefix[pin.pwm.name] = '/sys/devices/platform/ocp/' + pin.pwm.chipAddress + '.epwmss/' + pin.pwm.featAddress + '/pwm'; 90 | 91 | try { 92 | var files = fs.readdirSync(pwmPrefix[pin.pwm.name]); 93 | pin.pwm.sysfs = files[0].slice(-1); 94 | } catch (ex) { 95 | console.error('Error reading directory ' + pwmPrefix[pin.pwm.name]); 96 | return; 97 | } 98 | 99 | pwmPrefix[pin.pwm.name] = '/sys/class/pwm/pwmchip' + pin.pwm.sysfs + '/pwm' + pin.pwm.index; 100 | 101 | var exists = fs.existsSync(pwmPrefix[pin.pwm.name]); 102 | 103 | if (exists) { 104 | fs.writeFileSync(pwmPrefix[pin.pwm.name] + '/enable', 1); // now start PWM 105 | } else { 106 | fs.appendFileSync('/sys/class/pwm/pwmchip' + pin.pwm.sysfs + '/export', pin.pwm.index); // now export if not exported 107 | fs.writeFileSync(pwmPrefix[pin.pwm.name] + '/enable', 1); // now start PWM 108 | } 109 | return true; 110 | }, 111 | 112 | stop: function(pin, pwm, callback) { 113 | var resp = {}; 114 | var path = pwmPrefix[pin.pwm.name]; 115 | debug('Stopping PWM'); 116 | fs.writeFile(path + '/enable', 0, onStopPWM); 117 | 118 | function onStopPWM(err) { 119 | if (err) { 120 | err = new verror(err, "Failed to stop PWM"); 121 | if (typeof callback == 'function') callback(err); 122 | } else { 123 | if (typeof callback == 'function') callback(null); 124 | } 125 | } 126 | }, 127 | 128 | start: function(pin, pwm, callback) { 129 | var resp = {}; 130 | var path = pwmPrefix[pin.pwm.name]; 131 | debug('Starting PWM'); 132 | fs.writeFile(path + '/enable', 1, onStartPWM); 133 | 134 | function onStartPWM(err) { 135 | if (err) { 136 | err = new verror(err, "Failed to start PWM"); 137 | if (typeof callback == 'function') callback(err); 138 | } else { 139 | if (typeof callback == 'function') callback(null); 140 | } 141 | } 142 | }, 143 | 144 | readFreqAndValue: function(pin, pwm, callback) { 145 | debug("pwm.readFreqAndValue(" + pin.key + ")"); 146 | var resp = {}; 147 | var error; 148 | var period = null; 149 | fs.readFile(pwmPrefix[pin.pwm.name] + '/period', "utf8", onReadPeriod); 150 | 151 | function onReadPeriod(err, data) { 152 | if (err) { 153 | error = new verror(err + ': Unable to read period from ' + pwmPrefix[pin.pwm.name] + '/period'); 154 | } 155 | period = data; 156 | fs.readFile(pwmPrefix[pin.pwm.name] + '/duty_cycle', "utf8", onReadDuty); 157 | } 158 | 159 | function onReadDuty(err, duty) { 160 | if (err) { 161 | error = new verror(error, err + ': Unable to read duty from ' + pwmPrefix[pin.pwm.name] + '/duty_cycle'); 162 | callback(error, null); 163 | } else { 164 | resp.freq = 1.0e9 / period; 165 | resp.value = duty / period; 166 | callback(null, resp); 167 | } 168 | } 169 | }, 170 | 171 | writeFreqAndValue: function(pin, pwm, freq, value, callback) { 172 | debug('pwm.writeFreqAndValue(' + [pin.key, pwm, freq, value] + ');'); 173 | var path = pwmPrefix[pin.pwm.name]; 174 | var period = Math.round(1.0e9 / freq); // period in ns 175 | var duty = Math.round(period * value); 176 | 177 | var currentDuty; 178 | 179 | fs.readFile(path + '/duty_cycle', onReadDuty); 180 | 181 | function onReadDuty(err, readDuty) { 182 | if (err && !path) { 183 | err = new verror("Please call pinMode function on this pin before running analogWrite."); 184 | if (typeof callback == 'function') callback(err); 185 | return; 186 | } 187 | currentDuty = readDuty; 188 | if (period >= currentDuty) { 189 | fs.writeFile(path + '/period', period, onWritePeriod); 190 | } else { 191 | fs.writeFile(path + '/duty_cycle', duty, onWriteDuty); 192 | } 193 | } 194 | 195 | function onWritePeriod(err) { 196 | if (err) { 197 | err = new verror(err, "Fail to update PWM period"); 198 | if (typeof callback == 'function') callback(err); 199 | return; 200 | } 201 | if (period >= currentDuty) { 202 | fs.writeFile(path + '/duty_cycle', duty, onWriteDuty); 203 | } else { 204 | module.exports.start(pin, pwm, callback); 205 | } 206 | 207 | } 208 | 209 | function onWriteDuty(err) { 210 | if (err) { 211 | err = new verror(err, "Fail to update PWM duty"); 212 | if (typeof callback == 'function') callback(err); 213 | return; 214 | } 215 | if (period >= currentDuty) { 216 | module.exports.start(pin, pwm, callback); 217 | } else { 218 | fs.writeFile(path + '/period', period, onWritePeriod); 219 | } 220 | } 221 | } 222 | }; 223 | -------------------------------------------------------------------------------- /lib/serial.js: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 - Texas Instruments, Jason Kridner 2 | // Modified by Aditya Patadia, Octal Consulting LLP 3 | var fs = require('fs'); 4 | var verror = require("verror"); 5 | var pinmap = require('./pinmap'); 6 | var bone = require('./bone'); 7 | var SerialPort = bone.require('serialport'); 8 | var debug = require('debug')('bone'); 9 | 10 | var serial = { 11 | ports: pinmap.uarts, 12 | openPorts: {} 13 | }; 14 | 15 | module.exports = { 16 | 17 | enable: function(path, callback) { 18 | debug("serial.enable(" + path + ")"); 19 | if (!serial.ports[path]) { 20 | throw new verror("Supplied path:" + path + " is not a vaild serial port path."); 21 | } 22 | var txPin = serial.ports[path].tx; 23 | var rxPin = serial.ports[path].rx; 24 | var setTxPinState = false; 25 | 26 | bone.find_sysfsFile("ocp:" + txPin + "_pinmux", bone.is_ocp(), "ocp:" + txPin + "_pinmux", onFindPinmux); 27 | 28 | function onFindPinmux(err, data) { 29 | if (err) { 30 | err = new verror(err, "Error finding pinmux for: " + txPin); 31 | console.error(err.message); 32 | if (callback) callback(err); 33 | return; 34 | } 35 | fs.writeFile(data.path + "/state", "uart", onWriteState); 36 | } 37 | 38 | function onWriteState(err) { 39 | if (err) { 40 | err = new verror(err, "Error setting pin state to UART. Please unload UART cape if already loaded."); 41 | console.error(err.message); 42 | if (callback) callback(err); 43 | return; 44 | } 45 | if (setTxPinState) { 46 | if (callback) callback(null); 47 | } else { 48 | setTxPinState = true; 49 | bone.find_sysfsFile("ocp:" + rxPin + "_pinmux", bone.is_ocp(),"ocp:" + rxPin + "_pinmux", onFindPinmux); 50 | } 51 | } 52 | }, 53 | 54 | open: function(path, options, handler, callback) { 55 | debug("serial.open(" + path + ", " + options + ")"); 56 | 57 | if (!serial.ports[path]) { 58 | throw new verror("Supplied path:" + path + " is not a vaild serial port path."); 59 | } 60 | 61 | if (typeof handler != "function" || typeof callback != 'function') { 62 | throw new verror("handler and callback must be provided to serial.open and both should be functions"); 63 | } 64 | 65 | module.exports.enable(path, onSerialEnable); 66 | 67 | function onSerialEnable() { 68 | if (!serial.openPorts[path]) { 69 | var port = new SerialPort(path, options); 70 | port.on("open", function(err) { 71 | if (err) { 72 | err = new verror(err, "Can't open port : " + path); 73 | console.error(err.message); 74 | if (callback) callback(err, null); 75 | return; 76 | } 77 | debug('opened serial port: ' + path); 78 | port.on('data', handler); 79 | serial.openPorts[path] = port; 80 | if (callback) callback(null, serial.openPorts[path]); 81 | }); 82 | } else { 83 | if (callback) callback(null, serial.openPorts[path]); 84 | } 85 | } 86 | 87 | }, 88 | 89 | write: function(path, data, callback) { 90 | debug("serial.write(" + path + ", " + data + ")"); 91 | if (!serial.openPorts[path]) { 92 | throw new verror("Serial port " + path + " is not open. Please call serial.open function to open it."); 93 | } 94 | var port = serial.openPorts[path]; 95 | port.write(data, callback); 96 | }, 97 | 98 | parsers: SerialPort.exists ? SerialPort.parsers : {} 99 | }; 100 | -------------------------------------------------------------------------------- /lib/watchdog.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | 3 | var watchdogFile = null; 4 | var watchdogTimer = null; 5 | 6 | module.exports = { 7 | start: function() { 8 | if (watchdogFile !== null) { 9 | console.warn("Watchdog timer is already running"); 10 | return false; 11 | } 12 | fs.open("/dev/watchdog", "w+", function(err, fd) { 13 | watchdogFile = fd; 14 | watchdogTimer = setInterval(function() { 15 | fs.write(watchdogFile, "\n"); 16 | }, 10000); 17 | }); 18 | }, 19 | 20 | stop: function() { 21 | if (watchdogFile === null) { 22 | console.warn("Watchdog timer is not running"); 23 | return false; 24 | } 25 | clearInterval(watchdogTimer); 26 | fs.close(watchdogFile); 27 | } 28 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": { 3 | "name": "Aditya Patadia", 4 | "url": "http://aditya.patadia.org" 5 | }, 6 | "name": "octalbonescript", 7 | "description": "Physical computing library for embedded Linux and BeagleBone", 8 | "keywords": [ 9 | "embedded", 10 | "linux", 11 | "beagleboard", 12 | "beaglebone", 13 | "gpio", 14 | "bonescript", 15 | "octalbonescript" 16 | ], 17 | "version": "1.3.1", 18 | "homepage": "", 19 | "repository": { 20 | "type": "git", 21 | "url": "git://github.com/theoctal/octalbonescript" 22 | }, 23 | "main": "index.js", 24 | "engines": { 25 | "node": ">= 0.10.24" 26 | }, 27 | "dependencies": { 28 | "debug": "2.6.x", 29 | "verror": "1.8.x", 30 | "serialport": "4.0.x" 31 | }, 32 | "devDependencies": { 33 | "chai": "^2.0.0", 34 | "mocha": "^2.1.0" 35 | }, 36 | "scripts": {}, 37 | "optionalDependencies": { 38 | "i2c": "0.2.*", 39 | "epoll": "0.1.*" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/analog.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect, 2 | b = require('../index'); 3 | 4 | describe('#analog', function() { 5 | before("setting P8_13 to analog output pin",function(done){ 6 | b.pinMode("P8_13", b.ANALOG_OUTPUT, done); 7 | }); 8 | 9 | it('reads analog input pin P9_40', function(done) { 10 | b.analogRead("P9_40", function(err, value) { 11 | expect(value).to.be.within(0,1); 12 | done(err); 13 | }); 14 | }); 15 | 16 | it('writes analog value to pin P8_13', function(done) { 17 | b.analogWrite("P8_13", 0.5, 2000, done); 18 | }); 19 | 20 | it('stops analog output on pin P8_13', function(done) { 21 | b.stopAnalog("P8_13", done); 22 | }); 23 | 24 | it('starts analog output on pin P8_13', function(done) { 25 | b.startAnalog("P8_13", done); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/digital.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect, 2 | b = require('../index'); 3 | 4 | describe('#digitalRead', function() { 5 | before("setting P9_42 to digital input pin",function(done){ 6 | b.pinMode("P9_42", b.INPUT,done); 7 | }); 8 | 9 | it('reads digital input pin P9_42 ', function(done) { 10 | b.digitalRead("P9_42", function(err, value) { 11 | expect(value).to.be.within(0,1); 12 | done(err); 13 | }); 14 | }); 15 | }); 16 | 17 | describe('#digitalWrite', function() { 18 | before("setting P9_42 and USR0 to digital output pin",function(done){ 19 | b.pinMode("P9_42", b.OUTPUT, function(){ 20 | b.pinMode("USR0", b.OUTPUT, done); 21 | }); 22 | }); 23 | 24 | it('writes digital pin P9_42 and USR0 ', function(done) { 25 | b.digitalWrite("P9_42", b.HIGH, function(err) { 26 | b.digitalWrite("USR0", b.HIGH, done); 27 | }); 28 | }); 29 | 30 | it('writes digital pin P9_42 sync', function() { 31 | b.digitalWriteSync("P9_42", b.LOW); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /test/i2c.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect, 2 | b = require('../index'); 3 | 4 | describe('#i2c', function() { 5 | 6 | it('opens i2c port', function(done) { 7 | b.i2c.open("/dev/i2c-1", 0x18 , function(){ 8 | 9 | }, function(err){ 10 | done(err); 11 | }); 12 | }); 13 | }); -------------------------------------------------------------------------------- /test/interrupt.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect, 2 | b = require('../index'); 3 | 4 | describe('#interrupt', function() { 5 | before("attaches interrupt to pin P8_07",function(done){ 6 | b.attachInterrupt("P8_07", b.RISING, function(data){ 7 | 8 | }, function(err){ 9 | done(err); 10 | }); 11 | }); 12 | 13 | it('detatches interrupt from pin P8_07', function(done) { 14 | b.detachInterrupt("P8_07", function(err){ 15 | done(err); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/pinmodesync.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect, 2 | b = require('../index'); 3 | 4 | describe('#pinModeSync', function() { 5 | 6 | it('tests sync version of pinmode', function() { 7 | b.pinModeSync("P8_13", b.ANALOG_OUTPUT); 8 | b.pinModeSync("P8_13", b.OUTPUT); 9 | }); 10 | }); -------------------------------------------------------------------------------- /test/serial.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect, 2 | b = require('../index'); 3 | 4 | describe('#serial', function() { 5 | 6 | it('opens serial port', function(done) { 7 | b.serial.open("/dev/ttyO1",{}, function(){ 8 | 9 | }, function(err){ 10 | done(err); 11 | }); 12 | }); 13 | }); -------------------------------------------------------------------------------- /test/watchdog.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect, 2 | b = require('../index'); 3 | 4 | describe('#watchdog', function() { 5 | before("starts watchdog timer",function(){ 6 | b.watchdog.start(); 7 | }); 8 | 9 | it('stops watchdog timer', function() { 10 | b.watchdog.stop(); 11 | }); 12 | }); --------------------------------------------------------------------------------