array-gpio
Advanced tools
+165
-168
@@ -115,3 +115,3 @@ /*! | ||
| function startTime(){ | ||
| d1 = new Date(); | ||
| d1 = new Date(); | ||
| } | ||
@@ -142,8 +142,8 @@ | ||
| if(debugStateAdvanced){ | ||
| dmsg(1, pinCheck + ' ] *** Fail ***'); | ||
| return false | ||
| dmsg(1, pinCheck + ' ] *** Fail ***'); | ||
| return false | ||
| } | ||
| else{ | ||
| console.log('** warning **'); | ||
| duplicatePinError(arr1[x]); | ||
| console.log('** warning **'); | ||
| duplicatePinError(arr1[x]); | ||
| } | ||
@@ -158,7 +158,7 @@ } | ||
| /**************************************** | ||
| * * * | ||
| * array-gpio class module * | ||
| * * * | ||
| ****************************************/ | ||
| /****************************** | ||
| * | ||
| * array-gpio class module | ||
| * | ||
| ******************************/ | ||
| class ArrayGpio { | ||
@@ -178,3 +178,3 @@ | ||
| { | ||
| rpi.lib_close(); | ||
| rpi.lib_close(); | ||
| } | ||
@@ -184,11 +184,10 @@ | ||
| watchInput (edge, cb, td){ | ||
| if(typeof edge === 'function' && typeof cb === 'number'){ | ||
| td = cb; | ||
| cb = edge; | ||
| edge = null; | ||
| td = cb; | ||
| cb = edge; | ||
| edge = null; | ||
| } | ||
| else if(typeof edge === 'function' && cb === undefined){ | ||
| cb = edge; | ||
| edge = null; | ||
| cb = edge; | ||
| edge = null; | ||
| } | ||
@@ -199,9 +198,8 @@ else if(typeof edge !== 'string' && typeof edge !== 'number' && edge !== null){ | ||
| else if ((typeof edge === 'string' || typeof edge === 'number') && typeof cb !== 'function'){ | ||
| throw new Error('invalid callback argument'); | ||
| throw new Error('invalid callback argument'); | ||
| } | ||
| for (var x = 0; x < eventPin.length; x++) { | ||
| watchPin(edge, cb, eventPin[x], td); | ||
| watchPin(edge, cb, eventPin[x], td); | ||
| } | ||
| } | ||
@@ -225,3 +223,2 @@ | ||
| setInput () { | ||
| startTime(); | ||
@@ -231,9 +228,9 @@ var input = [], options = {}, inputPin = [], pinCheck = true, config, arraySetup; | ||
| if(arguments[0] === undefined || arguments[0] === null ){ | ||
| console.log('\nsetInput() - empty argument!'); | ||
| invalidPinError(arguments[0]); | ||
| console.log('\nsetInput() - empty argument!'); | ||
| invalidPinError(arguments[0]); | ||
| } | ||
| if(typeof arguments[0] === 'string' || typeof arguments[0] === 'function' ){ | ||
| console.log('\nsetInput() - invalid argument!'); | ||
| invalidPinError(arguments[0]); | ||
| console.log('\nsetInput() - invalid argument!'); | ||
| invalidPinError(arguments[0]); | ||
| } | ||
@@ -243,4 +240,4 @@ | ||
| if(typeof arguments[0] === 'object' && (arguments[0].pin === undefined || arguments[0].pin[0] == undefined)){ | ||
| console.log('\nsetInput({pin:[]}) - array pin property is empty!'); | ||
| invalidPinError(arguments[0]); | ||
| console.log('\nsetInput({pin:[]}) - array pin property is empty!'); | ||
| invalidPinError(arguments[0]); | ||
| } | ||
@@ -274,21 +271,21 @@ | ||
| for (var x = 0; x < arguments[0].pin.length; x++) { | ||
| // check if pins are from numbers 1 ~ 40 and validate for input use | ||
| if(Number.isInteger(arguments[0].pin[x]) && arguments[0].pin[x] > 0 && arguments[0].pin[x] < 41){ | ||
| try{ | ||
| rpi.gpio_open(arguments[0].pin[x], 0); | ||
| } | ||
| catch(e){ | ||
| inputPin.push(' *' + arguments[0].pin[x]); | ||
| console.log('input pins [ ' + inputPin + ' ]'); | ||
| invalidPinError(arguments[0].pin[x]); | ||
| } | ||
| inputPin.push(arguments[0].pin[x]); | ||
| arrayPinCheck.push(arguments[0].pin[x]); | ||
| } | ||
| // invalid pin number | ||
| else{ | ||
| invalidPinError(arguments[0].pin[x]); | ||
| } | ||
| } | ||
| options = arguments[0]; | ||
| // check if pins are from numbers 1 ~ 40 and validate for input use | ||
| if(Number.isInteger(arguments[0].pin[x]) && arguments[0].pin[x] > 0 && arguments[0].pin[x] < 41){ | ||
| try{ | ||
| rpi.gpio_open(arguments[0].pin[x], 0); | ||
| } | ||
| catch(e){ | ||
| inputPin.push(' *' + arguments[0].pin[x]); | ||
| console.log('input pins [ ' + inputPin + ' ]'); | ||
| invalidPinError(arguments[0].pin[x]); | ||
| } | ||
| inputPin.push(arguments[0].pin[x]); | ||
| arrayPinCheck.push(arguments[0].pin[x]); | ||
| } | ||
| // invalid pin number | ||
| else{ | ||
| invalidPinError(arguments[0].pin[x]); | ||
| } | ||
| } | ||
| options = arguments[0]; | ||
| } | ||
@@ -300,17 +297,17 @@ | ||
| */ | ||
| if (Number.isInteger(arguments[0]) && arguments.length >= 1) { | ||
| if(Number.isInteger(arguments[0]) && arguments.length >= 1) { | ||
| for (var x = 0; x < arguments.length; x++) { | ||
| // check if pins are from numbers 1 ~ 40 and validate for input use | ||
| if(Number.isInteger(arguments[x]) && arguments[x] > 0 && arguments[x] < 41){ | ||
| try{ | ||
| rpi.gpio_open(arguments[x], 0); | ||
| } | ||
| catch(e){ | ||
| inputPin.push(' *' + arguments[x]); | ||
| console.log('input pins [ ' + inputPin + ' ]'); | ||
| invalidPinError(arguments[x]); | ||
| } | ||
| inputPin.push(arguments[x]); | ||
| arrayPinCheck.push(inputPin[x]); | ||
| } | ||
| // check if pins are from numbers 1 ~ 40 and validate for input use | ||
| if(Number.isInteger(arguments[x]) && arguments[x] > 0 && arguments[x] < 41){ | ||
| try{ | ||
| rpi.gpio_open(arguments[x], 0); | ||
| } | ||
| catch(e){ | ||
| inputPin.push(' *' + arguments[x]); | ||
| console.log('input pins [ ' + inputPin + ' ]'); | ||
| invalidPinError(arguments[x]); | ||
| } | ||
| inputPin.push(arguments[x]); | ||
| arrayPinCheck.push(inputPin[x]); | ||
| } | ||
| // invalid pin number | ||
@@ -337,8 +334,8 @@ else if(Number.isInteger(arguments[x]) && arguments[x] <= 0 || arguments[x] > 40){ | ||
| else if(arguments[x] instanceof Object ){ | ||
| options = arguments[x]; | ||
| } | ||
| else { | ||
| console.log('Invalid arguments', arguments[x]); | ||
| } | ||
| } // for | ||
| options = arguments[x]; | ||
| } | ||
| else { | ||
| console.log('Invalid arguments', arguments[x]); | ||
| } | ||
| } // for | ||
| } | ||
@@ -353,14 +350,14 @@ | ||
| for (var i = 0; i < inputPin.length; i++) { | ||
| var index = i, pin = inputPin[i]; | ||
| if(options){ | ||
| if(options.pinCheck === 'NoPinCheck' || options.pinCheck === false){ | ||
| var index = i, pin = inputPin[i]; | ||
| if(options){ | ||
| if(options.pinCheck === 'NoPinCheck' || options.pinCheck === false){ | ||
| pinCheck = false; | ||
| } | ||
| if(options.index === 'PinAsIndex' || options.index === 'pin'){ | ||
| } | ||
| if(options.index === 'PinAsIndex' || options.index === 'pin'){ | ||
| index = inputPin[i]; | ||
| } | ||
| eventPin.push(pin); | ||
| input[index] = new GpioInput(index, pin, options); | ||
| } | ||
| } | ||
| } | ||
| eventPin.push(pin); | ||
| input[index] = new GpioInput(index, pin, options); | ||
| } | ||
| } | ||
| } | ||
@@ -379,6 +376,6 @@ createObject(inputPin, options, GpioInput); | ||
| arraySetup = options.index; | ||
| config = '{ pin:[' + inputPin + ']' + ', index:' + options.index + ' } ' + endTime(1); | ||
| if(options.array){ | ||
| config = '{ pin:[' + inputPin + ']' + ', array:true, index:' + options.index + ' } ' + endTime(1); | ||
| } | ||
| config = '{ pin:[' + inputPin + ']' + ', index:' + options.index + ' } ' + endTime(1); | ||
| if(options.array){ | ||
| config = '{ pin:[' + inputPin + ']' + ', array:true, index:' + options.index + ' } ' + endTime(1); | ||
| } | ||
| } | ||
@@ -415,8 +412,8 @@ else if(inputPin.length < 2 && options.array === true && (options.index === 'PinAsIndex' || options.index === 'pin')){ | ||
| console.log('\nsetOutput() - empty argument!'); | ||
| invalidPinError(arguments[0]); | ||
| invalidPinError(arguments[0]); | ||
| } | ||
| if(typeof arguments[0] === 'string' || typeof arguments[0] === 'function' ){ | ||
| console.log('\nsetOutput() - invalid argument!'); | ||
| invalidPinError(arguments[0]); | ||
| console.log('\nsetOutput() - invalid argument!'); | ||
| invalidPinError(arguments[0]); | ||
| } | ||
@@ -426,4 +423,4 @@ | ||
| if(typeof arguments[0] === 'object' && (arguments[0].pin === undefined || arguments[0].pin[0] == undefined)){ | ||
| console.log('\nsetOutput({pin:[]}) - array pin property is empty!'); | ||
| invalidPinError(arguments[0]); | ||
| console.log('\nsetOutput({pin:[]}) - array pin property is empty!'); | ||
| invalidPinError(arguments[0]); | ||
| } | ||
@@ -457,20 +454,20 @@ | ||
| // check if pins are from numbers 1 ~ 40 and validate for output use | ||
| if(Number.isInteger(arguments[0].pin[x]) && arguments[0].pin[x] > 0 && arguments[0].pin[x] < 41){ | ||
| try{ | ||
| rpi.gpio_open(arguments[0].pin[x] , 1); | ||
| } | ||
| catch(e){ | ||
| if(Number.isInteger(arguments[0].pin[x]) && arguments[0].pin[x] > 0 && arguments[0].pin[x] < 41){ | ||
| try{ | ||
| rpi.gpio_open(arguments[0].pin[x], 1); | ||
| } | ||
| catch(e){ | ||
| outputPin.push(' *' + arguments[0].pin[x]); | ||
| console.log('output pins [ ' + outputPin + ' ]'); | ||
| invalidPinError(arguments[0].pin[x]); | ||
| } | ||
| outputPin.push(arguments[0].pin[x]); | ||
| arrayPinCheck.push(arguments[0].pin[x]); | ||
| } | ||
| } | ||
| outputPin.push(arguments[0].pin[x]); | ||
| arrayPinCheck.push(arguments[0].pin[x]); | ||
| } | ||
| // invalid pin number | ||
| else{ | ||
| invalidPinError(arguments[0].pin[x]); | ||
| } | ||
| } | ||
| options = arguments[0]; | ||
| else{ | ||
| invalidPinError(arguments[0].pin[x]); | ||
| } | ||
| } | ||
| options = arguments[0]; | ||
| } | ||
@@ -521,3 +518,3 @@ | ||
| } | ||
| } | ||
| } | ||
| } | ||
@@ -543,28 +540,28 @@ | ||
| if(debugState || debugStateAdvanced){ | ||
| arrayPinCheck = []; | ||
| arrayPinCheck = []; | ||
| } | ||
| else if(pinCheck) { | ||
| checkPinOnArray(arrayPinCheck); | ||
| checkPinOnArray(arrayPinCheck); | ||
| } | ||
| if(outputPin.length > 1) { | ||
| if(options === undefined || !options.index){ | ||
| arraySetup = 'index:0~n'; | ||
| } | ||
| else if(options.index && !options.array) { | ||
| arraySetup = 'index:pin'; | ||
| } | ||
| else if(options.array && !options.index) { | ||
| arraySetup = 'array:true, index:0~n'; | ||
| } | ||
| else if(options.array && options.index){ | ||
| if(options === undefined || !options.index){ | ||
| arraySetup = 'index:0~n'; | ||
| } | ||
| else if(options.index && !options.array) { | ||
| arraySetup = 'index:pin'; | ||
| } | ||
| else if(options.array && !options.index) { | ||
| arraySetup = 'array:true, index:0~n'; | ||
| } | ||
| else if(options.array && options.index){ | ||
| arraySetup = 'array:true, index:pin'; | ||
| } | ||
| config = '{ pin:[' + outputPin + '], ' + arraySetup + ' } ' + endTime(1); | ||
| } | ||
| config = '{ pin:[' + outputPin + '], ' + arraySetup + ' } ' + endTime(1); | ||
| } | ||
| else if(outputPin.length < 2 && options && options.array == true && (options.index === 'pin' || options === 'PinAsIndex')){ | ||
| config = '{ pin:[' + outputPin + '], array:true, index:pin } ' + endTime(1); | ||
| config = '{ pin:[' + outputPin + '], array:true, index:pin } ' + endTime(1); | ||
| } | ||
| else if(outputPin.length < 2 && options && options.array){ | ||
| config = '{ pin:[' + outputPin + '], array:true, index:0~n } ' + endTime(1); | ||
| config = '{ pin:[' + outputPin + '], array:true, index:0~n } ' + endTime(1); | ||
| } | ||
@@ -603,6 +600,6 @@ else{ | ||
| if(x === 1){ | ||
| debugState = true; | ||
| debugStateAdvanced = true; | ||
| } | ||
| return debugState; | ||
| debugState = true; | ||
| debugStateAdvanced = true; | ||
| } | ||
| return debugState; | ||
| } | ||
@@ -617,25 +614,25 @@ | ||
| if(arguments.length > 4 || arguments.length < 1){ | ||
| throw new Error('invalid PWM(pin, freq, T, pw) arguments'); | ||
| throw new Error('invalid PWM(pin, freq, T, pw) arguments'); | ||
| } | ||
| /* arguments validation */ | ||
| if(arguments[0] === 33 || arguments[0] === 35 || arguments[0] === 12 || arguments[0] === 32){ | ||
| var validPin = pin; | ||
| /* store validated pin in array */ | ||
| if(validPin === 12 || validPin === 32){ | ||
| pwmPin.c1.push(validPin); | ||
| } | ||
| var validPin = pin; | ||
| /* store validated pin in array */ | ||
| if(validPin === 12 || validPin === 32){ | ||
| pwmPin.c1.push(validPin); | ||
| } | ||
| else{ | ||
| pwmPin.c2.push(validPin); | ||
| } | ||
| /* check duplicate pins */ | ||
| if(pwmPin.c1.length > 1 ){ | ||
| if(validPin === pwmPin.c1[0]){ | ||
| throw new Error('\nsetPWM() error: pin ' + validPin + ' is already in use.\n'); | ||
| } | ||
| } | ||
| if(pwmPin.c2.length > 1){ | ||
| if(validPin === pwmPin.c2[0]){ | ||
| throw new Error('\nsetPWM() error: pin ' + validPin + ' is already in use.\n'); | ||
| } | ||
| } | ||
| pwmPin.c2.push(validPin); | ||
| } | ||
| /* check duplicate pins */ | ||
| if(pwmPin.c1.length > 1 ){ | ||
| if(validPin === pwmPin.c1[0]){ | ||
| throw new Error('\nsetPWM() error: pin ' + validPin + ' is already in use.\n'); | ||
| } | ||
| } | ||
| if(pwmPin.c2.length > 1){ | ||
| if(validPin === pwmPin.c2[0]){ | ||
| throw new Error('\nsetPWM() error: pin ' + validPin + ' is already in use.\n'); | ||
| } | ||
| } | ||
| } | ||
@@ -647,9 +644,9 @@ else{ | ||
| if(arguments[1] === 10 || arguments[1] === 100 || arguments[1] === 1000 ){ | ||
| var validFreq = freq; | ||
| var validFreq = freq; | ||
| } | ||
| else if(arguments[1] === undefined){ | ||
| var validFreq = 1; | ||
| var validFreq = 1; | ||
| } | ||
| else{ | ||
| throw new Error('invalid setPulse() freq argument'); | ||
| throw new Error('invalid setPulse() freq argument'); | ||
| } | ||
@@ -659,19 +656,19 @@ | ||
| if(arguments[2] > 0 || arguments[2] < 1000000 ){ | ||
| var validT = T; | ||
| var validT = T; | ||
| } | ||
| else if(arguments[2] === undefined){ | ||
| var validT = 0; | ||
| var validT = 0; | ||
| } | ||
| else{ | ||
| throw new Error('invalid setPulse() period T argument'); | ||
| throw new Error('invalid setPulse() period T argument'); | ||
| } | ||
| /* pw or data */ | ||
| if(arguments[3] > 0 || arguments[3] < 1000000 ){ | ||
| var validPW = pw; | ||
| var validPW = pw; | ||
| } | ||
| else if( arguments[3] === undefined){ | ||
| var validPW = 0; | ||
| var validPW = 0; | ||
| } | ||
| else{ | ||
| throw new Error('invalid setPulse() pw argument'); | ||
| throw new Error('invalid setPulse() pw argument'); | ||
| } | ||
@@ -687,17 +684,17 @@ | ||
| if(Freq === 10){ | ||
| var res = '0.1 ms'; | ||
| var res = '0.1 ms'; | ||
| } | ||
| else if(Freq === 100){ | ||
| var res = '0.01 ms'; | ||
| var res = '0.01 ms'; | ||
| } | ||
| else if(Freq === 1000){ | ||
| var res = '0.001 ms'; | ||
| var res = '0.001 ms'; | ||
| } | ||
| if(validFreq === 1){ | ||
| console.log('PWM setup: (pin ' + validPin + ')'); | ||
| console.log('PWM setup: (pin ' + validPin + ')'); | ||
| } | ||
| else{ | ||
| /* Freq is global, not validFreq - one freq only for all */ | ||
| console.log('PWM setup: pin ' + validPin + ', Freq ' + Freq + ' KHz (' + res + '), T ' + validT + ', pw ' + validPW); | ||
| /* Freq is global, not validFreq - one freq only for all */ | ||
| console.log('PWM setup: pin ' + validPin + ', Freq ' + Freq + ' KHz (' + res + '), T ' + validT + ', pw ' + validPW); | ||
| } | ||
@@ -709,3 +706,3 @@ | ||
| setImmediate(function(){ | ||
| pwmObjectTotal += 1; | ||
| pwmObjectTotal += 1; | ||
| if(pwmObject === pwmObjectTotal && pwmObject > 1){ | ||
@@ -716,3 +713,3 @@ console.log("\nArray-gpio has detected you are using more than 1 PWM peripheral." | ||
| /* pwm pin channel check */ | ||
| setImmediate(function(){ | ||
| setImmediate(function(){ | ||
| /* channel 1 */ | ||
@@ -732,3 +729,3 @@ if(pwmPin.c1.length > 1 && pwmObject > 1){ | ||
| } | ||
| }); | ||
| }); | ||
| }); | ||
@@ -752,3 +749,3 @@ return pwm; | ||
| I2C(pin) { | ||
| return new I2C(pin); | ||
| return new I2C(pin); | ||
| } | ||
@@ -761,3 +758,3 @@ | ||
| startI2C(pinSet) { | ||
| return new I2C(pinSet); | ||
| return new I2C(pinSet); | ||
| } | ||
@@ -801,17 +798,17 @@ | ||
| { | ||
| rpi.uswait(us); | ||
| rpi.uswait(us); | ||
| } | ||
| pinout(){ | ||
| console.log('** common pins for rpi zero, rpi3 and rpi4 **'); | ||
| console.log('(based on the physical pinout numbering from the board header)\n'); | ||
| console.log('** common pins for rpi zero, rpi3 and rpi4 **'); | ||
| console.log('(based on the physical pinout numbering from the board header)\n'); | ||
| console.log('5v', pwr5); | ||
| console.log('3.3v', pwr3); | ||
| console.log('ground', ground); | ||
| console.log('eeprom id',eprom); | ||
| console.log('uart', uart); | ||
| console.log('i2c', i2c); | ||
| console.log('spi', spi); | ||
| console.log('pwm', pwm); | ||
| console.log('gpio (ALT0)', gpio, '\n'); | ||
| console.log('eeprom id',eprom); | ||
| console.log('uart', uart); | ||
| console.log('i2c', i2c); | ||
| console.log('spi', spi); | ||
| console.log('pwm', pwm); | ||
| console.log('gpio (ALT0)', gpio, '\n'); | ||
| } | ||
@@ -818,0 +815,0 @@ |
+2
-5
| { | ||
| "name": "array-gpio", | ||
| "version": "1.7.2", | ||
| "description": "array-gpio is low-level javascript library for Raspberry Pi using direct register control.", | ||
| "version": "1.7.3", | ||
| "description": "array-gpio is low-level javascript library for Raspberry Pi using direct register access.", | ||
| "main": "index.js", | ||
@@ -32,6 +32,3 @@ "cpu" : ["arm","arm64"], | ||
| "pi", | ||
| "raspberry", | ||
| "raspberrypi", | ||
| "raspberry pi", | ||
| "raspberry pi 3", | ||
| "rpi", | ||
@@ -38,0 +35,0 @@ "rpio", |
+4
-1402
@@ -6,3 +6,3 @@ [](https://www.npmjs.com/package/array-gpio) | ||
| **array-gpio** is a low-level javascript library for Raspberry Pi using a direct register control. | ||
| **array-gpio** is a low-level javascript library for Raspberry Pi using direct register access. | ||
@@ -23,7 +23,7 @@ It maps the ARM peripheral registers in memory using */dev/mem* for PWM, I2C, SPI | ||
| ### GPIO pin numbers | ||
| All pin numbering used on this module are based on the RPI board's pinout diagram *numbers 1~40*. | ||
| All pin numbering used on this module are based on the RPI's board pinout diagram *numbers 1~40*. | ||
| <br> | ||
| For IoT or machine-to-machine applications, please check [m2m](https://www.npmjs.com/package/m2m) using array-gpio. | ||
| <!--For IoT or machine-to-machine applications, please check [m2m](https://www.npmjs.com/package/m2m) using array-gpio.--> | ||
@@ -53,3 +53,3 @@ # Table of contents | ||
| ### Supported Raspberry Pi Devices | ||
| * Model: Pi Zero & Zero W, Pi 3 Model B+, Pi 4 Model B, Compute Module 3 & 4 (Generally most of the 40-pin models) | ||
| * Model: Pi Zero & Zero W, Pi 3 Model B+, Pi 4, Compute Module 3 & 4 (Generally most of the 40-pin models) | ||
@@ -75,1399 +75,1 @@ <br> | ||
| # Quick Tour | ||
| ## Example 1 | ||
| ### Create a GPIO input and output object | ||
| Connect a momentary *switch button* on pin **11** and an *led* on pin **33**. | ||
|  | ||
| Using **in** and **out** method from *array-gpio* object module | ||
| ```js | ||
| // create a raspberry pi (r) object | ||
| const r = require('array-gpio'); | ||
| // set pin 11 as input | ||
| let input = r.in(11); | ||
| // set pin 33 as output | ||
| let output = r.out(33); | ||
| ``` | ||
| Alternatively using the object destructuring assignment pattern, you can use the **setInput** and **setOutput** methods to create your input/output objects | ||
| ```js | ||
| const {setInput, setOutput} = require('array-gpio'); | ||
| // set pin 11 as input | ||
| let sw = setInput(11); | ||
| // set pin 33 as output | ||
| let led = setOutput(33); | ||
| ``` | ||
| ## Example 2 | ||
| ### Monitor the state of an input object | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw = r.in(11); | ||
| let led = r.out(33); | ||
| // Pressing the switch sw button, the led will turn on | ||
| // Releasing the switch sw button, the led will turn off | ||
| sw.watch((state) => { | ||
| if(state){ | ||
| led.on(); | ||
| } | ||
| else{ | ||
| led.off(); | ||
| } | ||
| }); | ||
| ``` | ||
| ## Example 3 | ||
| ### Using *isOn* and *isOff* properties to get the current state of an input/output object | ||
| The **isOn** and **isOff** properties are built-in own properties of input/output objects when they are created. | ||
|  | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw = r.in(11); | ||
| let led = r.out(33); | ||
| // Check the current state of sw and led object | ||
| console.log(sw1.isOn); // false | ||
| console.log(led.isOn); // false | ||
| console.log(sw1.isOff); // true | ||
| console.log(led.isOff); // true | ||
| ``` | ||
| ## Example 4 | ||
| ### Monitor multiple input objects | ||
| To monitor multiple input objects, you can use the **watchInput()** method. | ||
| Connect a momentary *switch button* on pin **11, 13, 15** and **19** and an *led* on pin **33** and **35**. | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw1 = r.in(11), sw2 = r.in(13), sw3 = r.in(15), sw4 = r.in(19); | ||
| let led1 = r.out(33), led2 = r.out(35); | ||
| // Press sw1 to turn on led1, press sw2 to turn off led1 | ||
| // Press sw3 to turn on led2, press sw4 to turn off led2 | ||
| // The callback argument will be invoked | ||
| // if you press any of the input switches | ||
| r.watchInput(() => { | ||
| if(sw1.isOn){ | ||
| led1.on(); | ||
| } | ||
| else if(sw2.isOn){ | ||
| led1.off(); | ||
| } | ||
| else if(sw3.isOn){ | ||
| led2.on(); | ||
| } | ||
| else if(sw4.isOn){ | ||
| led2.off(); | ||
| } | ||
| }); | ||
| ``` | ||
| ## Example 5 | ||
| ### Turning *on* and *off* a GPIO output with a *delay* | ||
| Connect a momentary *switch button* on pin **11** and **13** and an *led* on pin **33**. | ||
| ```js | ||
| const {setInput, setOutput, watchInput} = require('array-gpio'); | ||
| let sw1 = setInput(11); | ||
| let sw2 = setInput(13); | ||
| let led = setOutput(33); | ||
| watchInput(() => { | ||
| if(sw1.isOn){ | ||
| // pressing sw1, the led will turn on after 1000 ms or 1 sec delay | ||
| led.on(1000); | ||
| } | ||
| else if(sw2.isOn){ | ||
| // pressing sw2, the led will turn off after 500 ms or 0.5 sec delay | ||
| led.off(500); | ||
| } | ||
| }); | ||
| ``` | ||
| ## Example 6 | ||
| ### Create an input/output array object | ||
| Connect a momentary *switch button* for each input pin and an *led* for each output pin. | ||
|  | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| const sw = r.in({pin:[11, 13], index:'pin'}); | ||
| const led = r.out({pin:[33, 35, 37, 36, 38, 40], index:'pin'}); | ||
| // turn on all led outputs sequentially | ||
| let LedOn = () => { | ||
| let t = 0; // initial on time delay in ms | ||
| for(let x in led){ | ||
| t += 50; | ||
| led[x].on(t); | ||
| } | ||
| } | ||
| // turn off all led outputs sequentially | ||
| let LedOff = () => { | ||
| let t = 0; // initial off time delay in ms | ||
| for(let x in led){ | ||
| t += 50; | ||
| led[x].off(t); | ||
| } | ||
| } | ||
| r.watchInput(() => { | ||
| if(sw[11].isOn){ | ||
| LedOn(); | ||
| } | ||
| else if(sw[13].isOn){ | ||
| LedOff(); | ||
| } | ||
| }); | ||
| ``` | ||
| ### Using forEach to iterate over the array objects | ||
| ```js | ||
| const {setInput, setOutput, watchInput} = require('array-gpio'); | ||
| const sw = setInput({pin:[11, 13], index:'pin'}); | ||
| const led = setOutput({pin:[33, 35, 37, 36, 38, 40], index:'pin'}); | ||
| let LedOn = () => { | ||
| let t = 0; | ||
| led.forEach((output) => { | ||
| t += 50; | ||
| output.on(t); | ||
| }) | ||
| } | ||
| let LedOff = () => { | ||
| let t = 0; | ||
| led.forEach((output) => { | ||
| t += 50; | ||
| output.off(t); | ||
| }) | ||
| } | ||
| watchInput(() => { | ||
| sw.forEach((input) => { | ||
| if(input.pin === 11 && input.isOn){ | ||
| ledOn(); | ||
| } | ||
| else if(input.pin === 13 && input.isOn){ | ||
| ledOff(); | ||
| } | ||
| }) | ||
| }); | ||
| ``` | ||
| ## Example 7 | ||
| ### Create a simple GPIO single one-shot pulse | ||
| Connect a momentary *switch button* on pin **11, 13, 15** and an *led* on pin **33**. | ||
| ```js | ||
| const {setInput, setOutput, watchInput} = require('array-gpio'); | ||
| let sw1 = setInput(11); | ||
| let sw2 = setInput(13); | ||
| let sw3 = setInput(15); | ||
| let led = setOutput(33); | ||
| watchInput(() => { | ||
| // press sw1 to create a pulse with a duration of 50 ms | ||
| if(sw1.isOn){ | ||
| led.pulse(50); | ||
| } | ||
| // press sw2 to create a pulse with a duration of 200 ms | ||
| else if(sw2.isOn){ | ||
| led.pulse(200); | ||
| } | ||
| // press sw3 to create a pulse with a duration of 1000 ms or 1 sec | ||
| else if(sw3.isOn){ | ||
| led.pulse(1000); | ||
| } | ||
| }); | ||
| ``` | ||
| # API | ||
| All pin numbering used on this module are based on the RPI board's pinout diagram *numbers 1~40*. | ||
| If you are using a *Raspberry Pi OS*, you can check your board's pinout by entering *pinout* from a terminal. | ||
| ```console | ||
| $ pinout | ||
| ``` | ||
| All numbers in parenthesis are the pin numbers used on this module. | ||
| <br> | ||
| ## GPIO | ||
| ### state | ||
| `input/output property` | ||
| Shows the current digital logical state of an input/output object during runtime. It is a getter only property. | ||
| Returns *true* if the object logical state is *high* or *ON*. | ||
| Returns *false* if the object logical state is *low* or *OFF*. | ||
| ##### Example 1 | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sensor = r.in(11); | ||
| // returns the current state of the sensor | ||
| console.log(sensor.state); // false | ||
| ``` | ||
| ##### Example 2 | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw = r.in(11); | ||
| let led = r.out(33); | ||
| sw.watch(function(){ | ||
| if(sw.state && !led.state){ | ||
| console.log(sw.state); // true | ||
| console.log(led.state); // false | ||
| led.on(); | ||
| console.log(sw.state); // true | ||
| console.log(led.state); // true | ||
| } | ||
| }); | ||
| ``` | ||
| ### isOn and isOff | ||
| `input/output property` | ||
| Similar with the *state* property, it will return the current digital logical state of an input/output object with explicit context. | ||
| **isOn** - returns *true* if the object logical state is *high* or *ON*, otherwise it returns *false*. | ||
| **isOff** - returns *true* if the object logical state is *low* or *OFF*, otherwise it returns *false*. | ||
| ##### Example | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw1 = r.in(11); | ||
| let sw2 = r.in(13); | ||
| let led = r.out(33); | ||
| r.watchInput(() => { | ||
| // turns on led if sw1 is on and if led is off | ||
| if(sw1.isOn && led.isOff){ | ||
| led.on(); | ||
| } | ||
| // turns off led if sw2 is on and if led is on | ||
| else if(sw2.isOn && led.isOn){ | ||
| led.off(); | ||
| } | ||
| }); | ||
| ``` | ||
| ### pin | ||
| `input/output property` | ||
| Returns the GPIO pin used from any input/output objects. | ||
| ##### Example | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw = r.setInput(11); | ||
| let led = r.setOutput(33); | ||
| console.log(sw.pin); // 11 | ||
| console.log(led.pin); // 33 | ||
| ``` | ||
| ### close() | ||
| `input/output method` | ||
| Closes an input/output object. Removes any events (pin watching) from the object and resets the pin to GPIO input. | ||
| ##### Example 1 | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw = r.setInput(11); | ||
| let led = r.setOutput(33); | ||
| sw.close(); | ||
| led.close(); | ||
| ``` | ||
| ##### Example 2 | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let input = r.setInput({pin:[11, 13]}); | ||
| let output = r.setOutput({pin:[33, 35]}); | ||
| function appExitProcess(){ | ||
| console.log('closing all I/O objects'); | ||
| for(let x in input){ | ||
| input[x].close(); | ||
| } | ||
| for(let x in output){ | ||
| output[x].close(); | ||
| } | ||
| } | ||
| // using Ctrl-C for app exit | ||
| process.on('SIGINT', function (){ | ||
| appExitProcess(); | ||
| process.exit(0); | ||
| }); | ||
| ``` | ||
| ### read([callback]) | ||
| `input/output method` | ||
| The conventional way of getting the current logical state condition of an input/output object. | ||
| Returns logical **1** value if the object state is in *high* or *ON* state condition and **0** for *low* or *OFF* state condition. | ||
| The optional **callback** parameter will be invoked asynchronously after returning the object state condition. | ||
| This method is similar to **state** property but as a method property, you can use a | ||
| callback argument to execute any additional application logic based on the object state condition. | ||
| ##### Example | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw = r.setInput(11); | ||
| let solenoid = r.setOutput(35); | ||
| sw.read((state) => { | ||
| if(state === 1) | ||
| solenoid.on(); | ||
| else | ||
| solenoid.off(); | ||
| }); | ||
| ``` | ||
| ## Input Properties | ||
| ### in(arg) | ||
| or | ||
| ### setInput(arg) | ||
| Sets a GPIO pin or group of GPIO pins as input object. | ||
| **arg** | ||
| Any valid GPIO pin number or an input option argument. | ||
| #### Single Object | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let input = r.setInput(11); | ||
| // or | ||
| let input = r.in(11); | ||
| ``` | ||
| #### Array Object | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let inputOption = {pin: [11, 13, 15]}; | ||
| const input = r.setInput(inputOption); | ||
| // or | ||
| const input = r.in(inputOption); | ||
| // By default, the array object created is indexed using zero-based indexing | ||
| // (indexed from 0 to n-1, where n is the array.length). | ||
| /* Get the current logical state of each input element */ | ||
| console.log(input[0].state); | ||
| console.log(input[1].state); | ||
| console.log(input[2].state); | ||
| ``` | ||
| To use the pin as index, add an *index* property to the object argument and set the value to `'pin'`. | ||
| ```js | ||
| let inputOption = {pin:[11, 13, 15], index: 'pin'}; | ||
| const input = r.setInput(inputOption); | ||
| /* Get the current logical state of each input element using pin as index */ | ||
| console.log(input[11].state); | ||
| console.log(input[13].state); | ||
| console.log(input[15].state); | ||
| /* Iterate over the array object in both cases to access each input element */ | ||
| for(let x in input){ | ||
| console.log(input[x].isOn); | ||
| } | ||
| // or | ||
| input.forEach(function(inputObject){ | ||
| console.log(inputObject.isOn); | ||
| }); | ||
| ``` | ||
| ### watch (edge, callback, [s]) | ||
| `input method` | ||
| Watches the logical state of an input object for changes or state transitions. | ||
| **edge** | ||
| `1` - watch state changes from *low* to *high* (*false* to *true*) or rising edge transition | ||
| `0` - watch state changes from *high* to *low* (*true* to *false*) or falling edge transition | ||
| `'both'` - watches both state transitions | ||
| If edge argument is not provided, it will watch both transitions same as `'both'`. | ||
| **callback** | ||
| The callback argument will be called asynchronously everytime a state transition is detected based on the above conditions. | ||
| You can passed an optional parameters *state* and *pin* respectively to the callback argument for any fine-grained application logic execution. | ||
| **s** | ||
| This is an an optional scan rate argument in ms (milliseconds). If not provided, scan rate will default to *100* ms, minimum is *1* ms. | ||
| A lower value will make your input more responsive but contact bounce will increase. A higher value will make it less responsive but with a lower contact bounce. | ||
| ##### Example1 | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw = r.in(11); | ||
| function pinEvent(){ | ||
| console.log('pinEvent invoked'); | ||
| } | ||
| // pinEvent will be invoked if sw state changes from false to true | ||
| sw.watch(1, pinEvent); | ||
| // pinEvent will be invoked if sw state changes from true to false | ||
| sw.watch(0, pinEvent); | ||
| // edge argument is not provided, | ||
| // pinEvent will be invoked if sw state changes from true to false and vice versa | ||
| sw.watch(pinEvent); | ||
| // using a scan rate of 10 ms | ||
| sw.watch(pinEvent, 10); | ||
| ``` | ||
| ##### Example 2 | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw1 = r.in(11); | ||
| let led = r.out(33); | ||
| // pressing the sw1 button will turn on the led then turns off after 1000 ms delay | ||
| // releasing the sw1 button will do nothing | ||
| sw1.watch(1, (state) => { | ||
| if(state){ | ||
| led.on(); | ||
| led.off(1000); | ||
| } | ||
| }); | ||
| ``` | ||
| ### unwatch() | ||
| `input method` | ||
| Stops monitoring an input object from the .watch() method. | ||
| ### setR(value) | ||
| `input method` | ||
| Sets the internal resistor of an input pin using either *pull up* or *pull down* resistor. | ||
| **value** | ||
| `'pu'` or `1` - Enable internal *pull up* resistor. | ||
| `'pd'` or `0` - Enable internal *pull down* resistor. | ||
| If argument is not provided, no internal resistor will be used. | ||
| ##### Example | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw = r.setInput({pin:[11,13,15]}); | ||
| // using pull up resistor | ||
| sw[0].setR('pu'); | ||
| // using pull down resistor | ||
| sw[1].setR(0); | ||
| // no internal resistor is used | ||
| sw[2].setR(); | ||
| ``` | ||
| ### watchInput(callback, [s]) | ||
| `main module method` | ||
| Monitor multiple input objects all at once from the main module using **.watchInput()** method. | ||
| It will watch both state transistions from *low* to *high* and vice versa for all inputs. | ||
| The **callback** argument is shared by all input objects. It will be invoked asynchronously if any of the input objects changes state. | ||
| You can passed an optional parameters - *state* and *pin* respectively to the callback argument for any fine-grained application logic execution. | ||
| **s** is an optional scan rate argument in ms (milliseconds). If not provided, scan rate will default to *100* ms, minimum is *1* ms. A lower value will make your input more responsive but contact bounce will increase. A higher value will make it less responsive but with a lower contact bounce. | ||
| To capture which input object state has changed, you can use each object's **state** or **isOn** property. Or use the *pin* argument from the callback when it is invoked for any state transitions. | ||
| ##### Example 1 | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw = r.in({pin:[11, 13, 15], index:'pin'}); | ||
| let led = r.out({pin:[33, 35], index:'pin'}); | ||
| r.watchInput(() => { | ||
| // if sw[11] is on, led[33] will turn on | ||
| if(sw[11].isOn){ | ||
| led[33].on(); | ||
| } | ||
| // if sw[13] is on, led[35] will turn on | ||
| else if(sw[13].isOn){ | ||
| led[35].on(); | ||
| } | ||
| // if sw[15] is on, both led[33] and led[35] will turn off | ||
| else if(sw[15].isOn){ | ||
| led[33].off(); | ||
| led[35].off(); | ||
| } | ||
| }); | ||
| ``` | ||
| ##### Example 2 | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw1 = r.in(11); | ||
| let sw2 = r.in(13); | ||
| let led = r.out(35); | ||
| r.watchInput((state, pin) => { | ||
| if(state && sw1.pin === pin){ | ||
| led.on(); | ||
| } | ||
| else if(state && sw2.pin === pin){ | ||
| led.off(); | ||
| } | ||
| }); | ||
| ``` | ||
| ### unwatchInput() | ||
| `main module method` | ||
| Stop monitoring all the input objects from **.watchInput()** method. | ||
| It will stop invoking the shared callback argument for any input state changes. | ||
| ##### Example | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw1 = r.in(11); | ||
| let sw2 = r.in(13); | ||
| let sw3 = r.in(15); | ||
| let led1 = r.out(33); | ||
| let led2 = r.out(35); | ||
| r.watchInput(() => { | ||
| if(sw1.state){ | ||
| return led1.on(); | ||
| } | ||
| if(sw2.state){ | ||
| return led2.on(); | ||
| } | ||
| if(sw3.state){ | ||
| led1.off(); | ||
| led2.off(); | ||
| } | ||
| }); | ||
| // stops all input pin monitoring after 15 secs | ||
| setTimeout(() => r.unwatchInput(), 15000); | ||
| ``` | ||
| ### Output Properties | ||
| ### setOutput(arg) | ||
| or | ||
| ### out(arg) | ||
| `main module method` | ||
| Sets a GPIO pin or group of GPIO pins as output object. | ||
| **arg** | ||
| Any valid GPIO pin number or an output option argument. | ||
| #### Single Object | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| /* creates a single output object */ | ||
| let led = r.setOutput(33); | ||
| // or | ||
| let led = r.out(33); | ||
| /* turn on the led */ | ||
| led.on(); | ||
| ``` | ||
| #### Array Object | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| /* creates an array output object */ | ||
| let outputOption = {pin:[33, 35, 36]}; | ||
| const output = r.setOutput(outputOption); | ||
| // or | ||
| const output = r.out(outputOption); | ||
| // Similar with input, the array object created is indexed using zero-based indexing | ||
| // (indexed from 0 to n-1, where n is the array.length). | ||
| /* Get the current logical state of each output element */ | ||
| console.log(output[0].state); | ||
| console.log(output[1].state); | ||
| console.log(output[2].state); | ||
| ``` | ||
| To use the pin as index, add an *index* property to the object argument and set the value to `'pin'`. | ||
| ```js | ||
| let outputOption = {pin:[33, 35, 36], index:'pin'}; | ||
| const output = r.setOutput(outputOption); | ||
| /* Get the current logical state of each output element using pin as index */ | ||
| console.log(output[33].state); | ||
| console.log(output[35].state); | ||
| console.log(output[36].state); | ||
| // iterate over the array object in both cases to access each output element | ||
| for(let x in output){ | ||
| output[x].on(); | ||
| } | ||
| // or | ||
| output.forEach(function(outputObject){ | ||
| outputObject.on(); | ||
| }); | ||
| ``` | ||
| ### on([t],[callback]) and off([t],[callback]) | ||
| `output method` | ||
| Sets the state of an output object to logical *high* state condition (*true*) or *low* state condition (*false*). | ||
| **t** is an optional time delay in milliseconds. | ||
| The state will change after the duration of time delay *t*. | ||
| **callback** | ||
| The optional callback argument will be invoked asynchronously after the output state has changed. | ||
| You can passed an optional parameter *state* for any fine-grained application logic execution. | ||
| ##### Example | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw1 = r.in(11); | ||
| let sw2 = r.in(13); | ||
| let actuator1 = r.out(33); | ||
| let actuator2 = r.out(35); | ||
| r.watchInput(() => { | ||
| if(sw1.isOn && actuator1.isOff){ | ||
| actuator1.on(200); // turns on after 200 ms delay | ||
| actuator2.on((state) => { | ||
| if(state){ | ||
| console.log('actuator2 is on'); | ||
| } | ||
| }); | ||
| } | ||
| else if(sw2.isOn && actuator2.isOn){ | ||
| actuator1.off(50); // turns off after 50 ms delay | ||
| actuator2.off((state) => { | ||
| if(!state){ | ||
| console.log('actuator2 is off'); | ||
| } | ||
| }); | ||
| } | ||
| }); | ||
| ``` | ||
| ### write(bit [,callback]) | ||
| `output method` | ||
| This is the conventional way of setting the ouput state to *high* or *low* state condition. | ||
| **bit** - control bit value. | ||
| `1` or `true` - high or ON state | ||
| `0` or `false` - low or OFF state | ||
| **callback** | ||
| The optional callback argument will be invoked asynchronously after the output state has changed. | ||
| You can passed an optional parameter *state* for any fine-grained application logic execution. | ||
| ##### Example | ||
| ```js | ||
| const {setInput, setOutput, watchInput} = require('array-gpio'); | ||
| const sw = setInput(11,13); | ||
| const motor = setOutput(33,35); | ||
| let sw1 = sw[0]; | ||
| let sw2 = sw[1]; | ||
| let motorA = motor[0]; | ||
| let motorB = motor[1]; | ||
| watchInput((state) => { | ||
| if(sw1.read()){ | ||
| motorA.write(state, () => motorB.write(!state)); | ||
| } | ||
| if(sw2.read()){ | ||
| motorB.write(state, () => motorA.write(!state)); | ||
| } | ||
| }); | ||
| ``` | ||
| ### pulse(pw [,callback]) | ||
| `output method` | ||
| Generates a single square wave pulse with a duration of *pw*. | ||
| **pw** | ||
| This is the pulse width in milliseconds or the time duration of the pulse. | ||
| **callback** | ||
| The optional callback argument will be invoked asynchronously when *pw* time duration expires. | ||
| ##### Example | ||
| ```js | ||
| const r = require('array-gpio'); | ||
| let sw1 = r.in(11); | ||
| let sw2 = r.in(13); | ||
| let actuator = r.out({pin:[33, 35]}); | ||
| r.watchInput(() => { | ||
| // starts a single pulse w/ a duration of 1 sec | ||
| if(sw1.isOn && actuator[0].isOff){ | ||
| actuator[0].pulse(1000); | ||
| } | ||
| // starts a single pulse w/ a duration of 2 secs | ||
| else if(sw2.isOn && actuator[1].isOff){ | ||
| console.log('start of actuator[1] pulse'); | ||
| actuator[1].pulse(3000, () => { | ||
| console.log('end of actuator[1] pulse'); | ||
| }); | ||
| } | ||
| }); | ||
| ``` | ||
| *** | ||
| ## PWM | ||
| ### startPWM(pin) | ||
| Creates a pwm object from the provided GPIO pin and starts the PWM operations. | ||
| Sets GPIO pins *12* and *33* to alternate function 0 (ALT0) and sets pins *12* and *35* to alternate function 5 (ALT5). | ||
| This operation requires root access. | ||
| **pin** | ||
| Channel 1 - pins *12* and *32*. | ||
| Channel 2 - pins *33* and *35*. | ||
| You can only control 2 peripherals independently, one from channel 1 and one from channel 2. If both peripherals are from the same channel, you can control both channels using only | ||
| the control values (setRange and setData) from one of the peripherals. | ||
| ### setClockFreq(div) | ||
| **div** | ||
| The divisor value to calculate the desired clock frequency from a fixed oscillator freq of 19.2 MHz. | ||
| (0 to 4095) | ||
| freq = 19200000/div | ||
| ### setRange(range) | ||
| Sets the period **T** of the pwm pulse. | ||
| **range** The period T of the pulse | ||
| ### setData(data) | ||
| Sets the **pw** (pulse width) of the pwm pulse. | ||
| **data** The pulse width of the pulse | ||
| ### stop() | ||
| Stops temporarily the pulse generation from the system 19.2 MHz clock oscillator. | ||
| You can restart the pulse generation at anytime by calling the **.pulse()** or **.setData()** method. | ||
| ### close() | ||
| Stops PWM operations on the GPIO pin. Resets the pin to GPIO input. | ||
| ##### Example 1 | ||
|  | ||
| ```js | ||
| /* Connect an led to pin 12. */ | ||
| /* r for raspberry pi */ | ||
| const r = require('array-gpio'); | ||
| /* create a pwm object using pin 12 */ | ||
| var pwm = r.startPWM(12); | ||
| /* set the pwm clock frequency using a div value of 1920 */ | ||
| pwm.setClockFreq(1920); // sets clock freq to 10kHz or 0.1 ms time resolution for T and pw | ||
| /* set period (T) of the pulse */ | ||
| pwm.setRange(1000); // 1000 x 0.1 ms = 100 ms (actual period T) | ||
| /* | ||
| * set pw (pulse width) of the pulse and start the pulse generation for 2 seconds | ||
| * | ||
| * The led attached to pin 12 should blink for 2 seconds | ||
| */ | ||
| pwm.setData(100); // 100 x 0.1 ms = 10 ms (actual pw) | ||
| /* stop the pwm operation and reset pin 12 to GPIO input after 2 secs */ | ||
| setTimeout(function(){ | ||
| pwm.stop(); | ||
| pwm.close(); | ||
| }, 2000); | ||
| ``` | ||
| ### startPWM(pin, freq, T, pw) | ||
| Creates a pwm object from a predefined clock frequencies of `10`, `100`, or `1000` kHz that will provide different time resolutions | ||
| for the **T** (period) and **pw** (pulse width) of your desired pwm pulse. | ||
| **pin** | ||
| Choose from channel 1 (12, 32) or channel 2 (33, 35). | ||
| **freq** (kHz) | ||
| Choose a predefined clock oscillator frequency of `10`, `100`, or `1000` kHz | ||
| `10` kHz provides *0.1* ms resolution | ||
| `100` kHz provides *0.01* ms resolution | ||
| `1000` kHz provides *0.001* ms or *1* uS (microsecond) resolution | ||
| **T** (ms) | ||
| The initial cycle period of the pulse. | ||
| **pw** (ms) | ||
| The initial pulse width of the pulse. | ||
| The ratio of **pw** over **T** is the pulse **duty cycle** (pw/T) x 100%. | ||
| ### pulse([pw]) | ||
| Start the pulse generation or generates a new pulse using the **pw** argument provided. | ||
| If **pw** argument is not provided, it will use the initial *pw* argument used in **.setPWM()** constructor and start the pulse generation. | ||
| **pw** (ms) is the pulse width that will be used to generate a new pulse. | ||
| You can change the period *T* of the pulse using the **.setRange()** and the pulse width *pw* using **.setData()** or **.pulse()** method at anytime in your application. | ||
| However in servo motor applications, the period *T* is usually fixed while changes in pulse width *pw* controls the rotational position of your servo motors. | ||
| ##### Example 2 | ||
|  | ||
| ```js | ||
| /* Using a generic micro servo motor (~4.8 to 6.0 V) | ||
| * | ||
| * T = 20 ms (pulse period) | ||
| * | ||
| * pw (pulse width) needed for various servo positions | ||
| * | ||
| * pw 1.0 ms - pos 1, home position | ||
| * pw 1.5 ms - pos 2, rotates 40 degrees cw (clockwise) from pos 1 | ||
| * pw 2.0 ms - pos 3, rotates 80 degress cw from pos 1 | ||
| * pw 2.5 ms - pos 4, rotates 120 degress cw from pos 1 | ||
| * | ||
| */ | ||
| const r = require('array-gpio'); | ||
| var pin = 33; /* pin from channel 2 */ | ||
| var freq = 10; /* using 10 kHz clock frequency that will provide a 0.1 ms time resolution */ | ||
| var T = 200; /* Use 200 to get the 20 ms period (200 x 0.1 ms = 20 ms) */ | ||
| var pw = 10; /* Use 10 to get an initial pulse width of 1.0 ms (10 x 0.1 ms = 1.0 ms), home position */ | ||
| /* initialize PWM using with above pin, freq, T and pw details */ | ||
| var pwm = r.startPWM(pin, freq, T, pw); | ||
| /* create four push buttons sw[0], sw[1], sw[2] and sw[4] */ | ||
| const sw = r.setInput({pin:[11, 13, 15, 19]}); | ||
| r.watchInput(() => { | ||
| /* Press sw[0] button to rotate the servo motor to pos 1 or home position */ | ||
| if(sw[0].isOn){ | ||
| pwm.pulse(10); // 1.0 ms pw | ||
| } | ||
| /* Press sw[1] button to rotate to pos 2 */ | ||
| else if(sw[1].isOn){ | ||
| pwm.pulse(15); // 1.5 ms pw | ||
| } | ||
| /* Press sw[2] button to rotate to pos 3 */ | ||
| else if(sw[2].isOn){ | ||
| pwm.pulse(20); // 2.0 ms pw | ||
| } | ||
| /* Press sw[3] button to rotate to pos 4 */ | ||
| else if(sw[3].isOn){ | ||
| pwm.pulse(25); // 2.5 ms pw | ||
| } | ||
| }); | ||
| const appExitProcess = () => { | ||
| console.log('closing all sw and pwm objects'); | ||
| for(let x in sw){ | ||
| sw[x].close(); | ||
| } | ||
| pwm.close(); | ||
| process.exit(0); | ||
| } | ||
| process.on('SIGINT', () => { | ||
| console.log('\napp terminated using Ctrl-C'); | ||
| appExitProcess(); | ||
| }); | ||
| ``` | ||
| *** | ||
| ## I2C | ||
| ### startI2C() | ||
| Sets i2c pins 03 (SDA) and 05 (SCL) to its alternate function (ALT0) for i2c operation. | ||
| Returns an i2c object with properties to configure the I2C interface to start the i2c data transfer operation. | ||
| This operation requires root access. | ||
| ### begin() | ||
| Starts i2c operation in your application. | ||
| This operation is integrated in setI2C() method, so there is no need to call it explicitly to start the i2c operation. | ||
| ### end() | ||
| Stops i2c operation and resets i2c pins 03 (SDA) and 05 (SCL) to GPIO input pins. | ||
| ### setClockFreq(div) | ||
| Sets the i2c clock speed based on the **div** divisor value. Check the various *div* values below and the possible clock speeds that will be generated. | ||
| ```code | ||
| div 2500 => 10us => 100 kHz | ||
| div 626 => 2.504us => 399.3610 kHz | ||
| div 150 => 60ns => 1.666 MHz (default at reset) | ||
| div 148 => 59ns => 1.689 MHz | ||
| ``` | ||
| ### setTransferSpeed(baud) | ||
| Directly set the the i2c clock speed using a baud argument instead of using a div value. Either use the setClockFreq above or this method. | ||
| Sets the i2c clock frequency by converting the **baud** argument to the equivalent i2c clock divider value. | ||
| ### selectSlave(addr) | ||
| Sets the i2c address of the slave device. | ||
| **addr** | ||
| The i2c address of the slave device. | ||
| ### write(wbuf, n) | ||
| Write a number of bytes to the currently selected i2c slave device. | ||
| **wbuf** The buffer containing the actual data bytes to send/write to the selected i2c slave device. | ||
| **n** The number of bytes to send/write to the selected i2c slave device. | ||
| ### read(rbuf, n) | ||
| Read a number of bytes from the currently selected i2c slave device. | ||
| **rbuf** The buffer containing the actual data bytes to read/receive from the selected i2c slave device. | ||
| **n** The number of bytes to read/receive from the selected i2c slave device. | ||
| ##### Example | ||
|  | ||
| ```js | ||
| /* Using MCP9808 Temperature Sensor | ||
| * | ||
| * Please read the MCP9808 datasheet on how to configure the chip for more details. | ||
| */ | ||
| const r = require('array-gpio'); | ||
| let i2c = r.startI2C(); // using SDA1 and SCL1 (pin 3 & 5) pins | ||
| /* Set data transfer speed to 200 kHz */ | ||
| i2c.setTransferSpeed(200000); | ||
| /* MCP9808 hardware device address */ | ||
| let addr = 0x18; | ||
| /* Select the MCP9808 device for data trasfer */ | ||
| i2c.selectSlave(addr); | ||
| /* Setup the application read and write data buffer */ | ||
| const wbuf = Buffer.alloc(16); // write buffer | ||
| const rbuf = Buffer.alloc(16); // read buffer | ||
| /* Accessing the internal 16-bit manufacturer ID register within MCP9808 */ | ||
| wbuf[0] = 0x06; // from the MCP9808 datasheet, set the address of the manufacturer ID register to the write buffer | ||
| i2c.write(wbuf, 1); // writes 1 data byte to the slave device selecting the MCP9808 manufacturer ID register for data access | ||
| /* Master (rpi) device will now read the content of the 16-bit manufacturer ID register (should be 0x54 as per datasheet) */ | ||
| /* Reading 2 data bytes - the upper byte (rbuf[0]) and lower byte (rbuf[1]) from the manufacturer ID register, ID value is on the lower byte from the datasheet */ | ||
| i2c.read(rbuf, 2); | ||
| console.log('MCP9808 ID: ', rbuf[1].toString(16)); // convert the ID value to hex value | ||
| /* Based on MCP9808 datasheet, compute the temperature data as follows */ | ||
| function getTemp(){ | ||
| let Temp = null; | ||
| let UpperByte = rbuf[0]; // MSB | ||
| let LowerByte = rbuf[1]; // LSB | ||
| UpperByte = UpperByte & 0x1F; // Clear flag bits | ||
| /* Temp < 0 C */ | ||
| if ((UpperByte & 0x10) == 0x10){ | ||
| UpperByte = UpperByte & 0x0F; // Clear SIGN | ||
| Temp = 256 - ((UpperByte * 16) + (LowerByte / 16)); | ||
| /* Temp > 0 C */ | ||
| } | ||
| else { | ||
| Temp = ((UpperByte * 16) + (LowerByte / 16)); | ||
| } | ||
| /* Print out temperature data */ | ||
| console.log('Temp: ', Temp); | ||
| return Temp; | ||
| } | ||
| /* Get temperature readings every 2 seconds */ | ||
| setInterval( function(){ | ||
| /* Accessing the internal 16-bit configuration register within MCP9808. | ||
| You can skip accessing this register using default settings */ | ||
| wbuf[0] = 0x01; // address of the configuration register | ||
| /* Change content of configuration register */ | ||
| wbuf[1] = 0x02; // register upper byte, THYST set with +1.5 C | ||
| wbuf[2] = 0x00; // register lower byte (power up defaults) | ||
| i2c.write(wbuf, 3); | ||
| /* Accessing the internal 16-bit ambient temp register within MCP9808 */ | ||
| wbuf[0] = 0x05; // address of ambient temperature register | ||
| i2c.write(wbuf, 1); | ||
| /* Read the content of ambient temp register */ | ||
| i2c.read(rbuf, 2); // read the UpperByte and LowerByte data | ||
| /* Get temperature data and print out the results */ | ||
| getTemp(); | ||
| }, 2000); | ||
| process.on('SIGINT', function (){ | ||
| console.log('\napp terminated using Ctrl-C'); | ||
| i2c.end(); | ||
| process.exit(0); | ||
| }); | ||
| ``` | ||
| *** | ||
| ## SPI | ||
| ### startSPI() | ||
| Sets SPI0 bus pins 19 (MOSI), 21 (MISO), 23 (CLK), 24 (CE0) and 26 (CE1) to its alternate function (ALT0) for spi operation. | ||
| Returns an spi object with properties to configure the SPI interface. | ||
| This operation requires root access. | ||
| ### begin() | ||
| Initializes the SPI0 bus pins for spi operation. | ||
| This process is integrated in setSPI() method, so there is no need to call it explicitly to start the spi operation. | ||
| ### setClockFreq(div) | ||
| Sets the SPI clock frequency using a divisor value. | ||
| Clock is based on the nominal core clock rate of 250MHz on RPi1 and RPi2, and 400MHz on RPi3. | ||
| **div** | ||
| The SPI divisor to generate the SPI clock frequency. | ||
| The information below shows the various *div* value and the *clock frequency* in kHz that will be generated. | ||
| ```code | ||
| SPI div 2048 = 122.0703125kHz on Rpi2, 195.3125kHz on RPI3 | ||
| SPI div 1024 = 244.140625kHz on Rpi2, 390.625kHz on RPI3 | ||
| SPI div 512 = 488.28125kHz on Rpi2, 781.25kHz on RPI3 | ||
| SPI div 256 = 976.5625kHz on Rpi2, 1.5625MHz on RPI3 | ||
| SPI div 128 = 1.953125MHz on Rpi2, 3.125MHz on RPI3 (default) | ||
| SPI div 64 = 3.90625MHz on Rpi2, 6.250MHz on RPI3 | ||
| SPI div 32 = 7.8125MHz on Rpi2, 12.5MHz on RPI3 | ||
| SPI div 16 = 15.625MHz on Rpi2, 25MHz on RPI3 | ||
| SPI div 8 = 31.25MHz on Rpi2, 50MHz on RPI3 | ||
| ``` | ||
| ### chipSelect(cs) | ||
| Sets the chip select pin(s). | ||
| When data transfer starts, the selected pin(s) will be asserted or held in active state (usually active **low**) during data transfer. | ||
| **cs** | ||
| Choose from one of cs values below. | ||
| ```code | ||
| cs = 0, Chip Select 0 | ||
| cs = 1, Chip Select 1 | ||
| cs = 2, Chip Select 2 | ||
| cs = 3, No Chip Select | ||
| ``` | ||
| ### setCSPolarity(cs, active) | ||
| Change the active state of the chip select pin. | ||
| **cs** | ||
| The chip select pin you want to change the active state. | ||
| **active** | ||
| Select `0` for active low or `1` for active high state. | ||
| ### setDataMode(mode) | ||
| Sets the SPI data mode, the clock polariy (CPOL) and phase (CPHA). | ||
| **mode** | ||
| Choose from one of SPI mode below. | ||
| ```code | ||
| mode = 0, CPOL = 0, CPHA = 0 | ||
| mode = 1, CPOL = 0, CPHA = 1 | ||
| mode = 2, CPOL = 1, CPHA = 0 | ||
| mode = 3, CPOL = 1, CPHA = 1 | ||
| ``` | ||
| ### transfer(wbuf, rbuf, n) | ||
| Transfers any number of bytes to and from the currently selected spi slave device. | ||
| This method makes it possible to perform simultaneous write and read operations for date transfer. | ||
| Selected CS pins (as previously set by chipSelect) will be held in active state during the data transfer. | ||
| **wbuf** The buffer containing the actual data bytes to send/write to the selected spi slave device. | ||
| **rbuf** The buffer containing the actual data bytes to read/receive from the selected spi slave device. | ||
| **n** The number of bytes to send/receive from/to the selected spi device. | ||
| ### write(wbuf, n) | ||
| Write a number of bytes to the currently selected spi slave chip. | ||
| Asserts the currently selected CS pins (as previously set by chipSelect) during the data transfer operations. | ||
| **wbuf** The buffer containing the actual data bytes to write/send to the selected spi slave device. | ||
| **n** The number of bytes to write/send to the selected spi slave device. | ||
| ### read(rbuf, n) | ||
| Read a number of bytes from the currently selected spi slave device. | ||
| **rbuf** The buffer containing the actual data bytes to read/receive from the selected spi slave device. | ||
| **n** The number of bytes to read/receive from the spi slave device. | ||
| ### end() | ||
| Stops the SPI data transfer operations. SPI0 pins 19 (MOSI), 21 (MISO), 23 (CLK), 24 (CE0) and 26 (CE1) are reset to GPIO input pins. | ||
| ##### Example | ||
|  | ||
| ```js | ||
| /* Using MCP3008 10-bit A/D Converter Chip | ||
| * | ||
| * In this example, we will connect the Vdd and Vref pins to the Raspberry Pi's 3.3 V. | ||
| * Channel 0 (pin 1) will be used for analog input voltage using single-ended mode. | ||
| * | ||
| * Please read the MCP3008 datasheet on how to configure the chip for more details. | ||
| */ | ||
| const r = require('array-gpio'); | ||
| var spi = r.startSPI(); | ||
| spi.setDataMode(0); | ||
| spi.setClockFreq(128); | ||
| spi.setCSPolarity(0, 0); | ||
| spi.chipSelect(0); | ||
| /* Setup write and read data buffer */ | ||
| const wbuf = Buffer.alloc(16); // write buffer | ||
| const rbuf = Buffer.alloc(16); // read buffer | ||
| /* Configure the chip to use CH0 in single-ended mode. | ||
| * The device will begin to sample the analog input on the fourth rising edge of the clock after | ||
| * the start bit has been received */ | ||
| wbuf[0] = 0x01; // start bit | ||
| wbuf[1] = 0x80; // using channel 0, single ended | ||
| wbuf[2] = 0x00; // don't care data byte as per datasheet | ||
| spi.write(wbuf, 3); | ||
| /* Alternative way to write and read to a slave at the same time */ | ||
| //spi.transfer(wbuf, rbuf, 3); // write 3 bytes and receive 3 bytes afterwards | ||
| /* Read the conversion result */ | ||
| spi.read(rbuf, 3); | ||
| /* Read A/D conversion result | ||
| * The 1st byte received through rbuf[0] will be discarded as per datasheet */ | ||
| var data1 = rbuf[1] << 8; // MSB, using only 2 bits data | ||
| var data2 = rbuf[2]; // LSB, 8 bits data | ||
| var adc = data1 + data2; // combine both data to create a 10-bit digital output code | ||
| console.log("* A/D digital output code: ", adc); | ||
| /* Compute the output voltage */ | ||
| var vout = (adc/1023) * 3.3; | ||
| console.log("* A/D voltage output: ", vout); | ||
| spi.end(); | ||
| ``` |
+120
-118
@@ -1,2 +0,4 @@ | ||
| /* | ||
| /** | ||
| * node_rpi.cc | ||
| * | ||
| * Copyright (c) 2017 Ed Alegrid <ealegrid@gmail.com> | ||
@@ -12,3 +14,3 @@ */ | ||
| #define BCM_EVENT_LOW 0x1 | ||
| #define BCM_EVENT_HIGH 0x2 | ||
| #define BCM_EVENT_HIGH 0x2 | ||
@@ -26,3 +28,3 @@ using namespace Nan; | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -41,3 +43,3 @@ rpi_init(arg); | ||
| info.GetReturnValue().Set(rval); | ||
| info.GetReturnValue().Set(rval); | ||
| } | ||
@@ -51,6 +53,6 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint64_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint64_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -63,6 +65,6 @@ nswait(arg); | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint32_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint32_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -75,8 +77,8 @@ uswait(arg); | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint32_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| mswait(arg); | ||
| mswait(arg); | ||
| } | ||
@@ -90,9 +92,9 @@ | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| gpio_config(arg1, arg2); | ||
| gpio_config(arg1, arg2); | ||
| } | ||
@@ -103,8 +105,8 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| gpio_input(arg); | ||
| gpio_input(arg); | ||
| } | ||
@@ -115,8 +117,8 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| gpio_output(arg); | ||
| gpio_output(arg); | ||
| } | ||
@@ -129,8 +131,8 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| rval = gpio_read(arg); | ||
| rval = gpio_read(arg); | ||
@@ -143,9 +145,9 @@ info.GetReturnValue().Set(rval); | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| gpio_enable_async_rising_event(arg1, arg2); | ||
| gpio_enable_async_rising_event(arg1, arg2); | ||
| } | ||
@@ -158,8 +160,8 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| rval = gpio_detect_input_event(arg); | ||
| rval = gpio_detect_input_event(arg); | ||
@@ -172,8 +174,8 @@ info.GetReturnValue().Set(rval); | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| gpio_reset_all_events(arg); | ||
| gpio_reset_all_events(arg); | ||
| } | ||
@@ -184,8 +186,8 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| gpio_reset_event(arg); | ||
| gpio_reset_event(arg); | ||
| } | ||
@@ -198,9 +200,9 @@ | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| rval = gpio_write(arg1, arg2); | ||
| rval = gpio_write(arg1, arg2); | ||
@@ -213,9 +215,9 @@ info.GetReturnValue().Set(rval); | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| gpio_enable_pud(arg1, arg2); | ||
| gpio_enable_pud(arg1, arg2); | ||
| } | ||
@@ -229,4 +231,4 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -241,4 +243,4 @@ uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -260,6 +262,6 @@ uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint32_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint32_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -283,7 +285,7 @@ rval = pwm_set_clock_freq(arg); | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -296,7 +298,7 @@ pwm_enable(arg1, arg2); | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -309,9 +311,9 @@ pwm_set_mode(arg1, arg2); | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| pwm_set_pola(arg1, arg2); | ||
| pwm_set_pola(arg1, arg2); | ||
| } | ||
@@ -322,7 +324,7 @@ | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint32_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint32_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -335,9 +337,9 @@ pwm_set_data(arg1, arg2); | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint32_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint32_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| pwm_set_range(arg1, arg2); | ||
| pwm_set_range(arg1, arg2); | ||
| } | ||
@@ -362,8 +364,8 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber() )){ | ||
| return ThrowTypeError("Incorrect argument"); | ||
| } | ||
| return ThrowTypeError("Incorrect argument"); | ||
| } | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| rval = i2c_init(arg); | ||
| rval = i2c_init(arg); | ||
@@ -382,7 +384,7 @@ info.GetReturnValue().Set(rval); | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| } | ||
| uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| i2c_select_slave(arg); | ||
| i2c_select_slave(arg); | ||
| } | ||
@@ -394,3 +396,3 @@ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| } | ||
| uint16_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -404,4 +406,4 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -418,4 +420,4 @@ uint32_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| if((info.Length() != 2) || (!info[0]->IsObject()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -425,3 +427,3 @@ v8::Local<v8::Object> wbuf = info[0]->ToObject(Nan::GetCurrentContext()).FromMaybe(v8::Local<v8::Object>()); | ||
| rval = i2c_write(node::Buffer::Data(wbuf), arg); | ||
| rval = i2c_write(node::Buffer::Data(wbuf), arg); | ||
@@ -433,9 +435,9 @@ info.GetReturnValue().Set(rval); | ||
| { | ||
| uint8_t rval; | ||
| uint8_t rval; | ||
| if((info.Length() != 2) || (!info[0]->IsObject()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| v8::Local<v8::Object> rbuf = info[0]->ToObject(Nan::GetCurrentContext()).FromMaybe(v8::Local<v8::Object>()); | ||
| v8::Local<v8::Object> rbuf = info[0]->ToObject(Nan::GetCurrentContext()).FromMaybe(v8::Local<v8::Object>()); | ||
| uint8_t arg = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -477,4 +479,4 @@ | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -489,4 +491,4 @@ uint16_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -501,7 +503,7 @@ uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| if((info.Length() != 2) || (!info[0]->IsNumber()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| uint8_t arg1 = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| uint8_t arg2 = info[1]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
@@ -514,4 +516,4 @@ spi_set_chip_select_polarity(arg1, arg2); | ||
| if((info.Length() != 1) || (!info[0]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -526,4 +528,4 @@ uint8_t arg = info[0]->IntegerValue(Nan::GetCurrentContext()).ToChecked(); | ||
| if((info.Length() != 3) || (!info[0]->IsObject()) || (!info[1]->IsObject()) || (!info[2]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -541,4 +543,4 @@ v8::Local<v8::Object> wbuf = info[0]->ToObject(Nan::GetCurrentContext()).FromMaybe(v8::Local<v8::Object>()); | ||
| if((info.Length() != 2) || (!info[0]->IsObject()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -554,4 +556,4 @@ v8::Local<v8::Object> wbuf = info[0]->ToObject(Nan::GetCurrentContext()).FromMaybe(v8::Local<v8::Object>()); | ||
| if((info.Length() != 2) || (!info[0]->IsObject()) || (!info[1]->IsNumber())){ | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
| return ThrowTypeError("Incorrect arguments"); | ||
| } | ||
@@ -572,7 +574,7 @@ v8::Local<v8::Object> rbuf = info[0]->ToObject(Nan::GetCurrentContext()).FromMaybe(v8::Local<v8::Object>()); | ||
| /* gpio */ | ||
| /* gpio */ | ||
| NAN_EXPORT(target, gpio_config); | ||
| NAN_EXPORT(target, gpio_input); | ||
| NAN_EXPORT(target, gpio_output); | ||
| NAN_EXPORT(target, gpio_read); | ||
| NAN_EXPORT(target, gpio_read); | ||
| NAN_EXPORT(target, gpio_enable_async_rising_event); | ||
@@ -586,3 +588,3 @@ NAN_EXPORT(target, gpio_detect_input_event); | ||
| /* pwm */ | ||
| NAN_EXPORT(target, pwm_set_pin); | ||
| NAN_EXPORT(target, pwm_set_pin); | ||
| NAN_EXPORT(target, pwm_reset_pin); | ||
@@ -592,3 +594,3 @@ NAN_EXPORT(target, pwm_reset_all_pins); | ||
| NAN_EXPORT(target, pwm_clk_status); | ||
| NAN_EXPORT(target, pwm_enable); | ||
| NAN_EXPORT(target, pwm_enable); | ||
| NAN_EXPORT(target, pwm_set_mode); | ||
@@ -599,4 +601,4 @@ NAN_EXPORT(target, pwm_set_pola); | ||
| /* i2c */ | ||
| NAN_EXPORT(target, i2c_start); | ||
| /* i2c */ | ||
| NAN_EXPORT(target, i2c_start); | ||
| NAN_EXPORT(target, i2c_init); | ||
@@ -608,3 +610,3 @@ NAN_EXPORT(target, i2c_stop); | ||
| NAN_EXPORT(target, i2c_write); | ||
| NAN_EXPORT(target, i2c_read); | ||
| NAN_EXPORT(target, i2c_read); | ||
| NAN_EXPORT(target, i2c_byte_read); | ||
@@ -615,7 +617,7 @@ | ||
| NAN_EXPORT(target, spi_stop); | ||
| NAN_EXPORT(target, spi_set_clock_freq); | ||
| NAN_EXPORT(target, spi_set_clock_freq); | ||
| NAN_EXPORT(target, spi_set_data_mode); | ||
| NAN_EXPORT(target, spi_set_chip_select_polarity); | ||
| NAN_EXPORT(target, spi_set_chip_select_polarity); | ||
| NAN_EXPORT(target, spi_chip_select); | ||
| NAN_EXPORT(target, spi_data_transfer); | ||
| NAN_EXPORT(target, spi_data_transfer); | ||
| NAN_EXPORT(target, spi_write); | ||
@@ -622,0 +624,0 @@ NAN_EXPORT(target, spi_read); |
+285
-253
@@ -48,12 +48,12 @@ /** | ||
| #define ST_BASE (peri_base + 0x003000) // 0x7E003000 | ||
| #define GPIO_PADS (peri_base + 0x100000) // 0x7E100000 unused | ||
| #define CLK_BASE (peri_base + 0x101000) // 0x7E101000 | ||
| #define GPIO_BASE (peri_base + 0x200000) // 0x7E200000 | ||
| #define GPIO_PADS (peri_base + 0x100000) // 0x7E100000 unused | ||
| #define CLK_BASE (peri_base + 0x101000) // 0x7E101000 | ||
| #define GPIO_BASE (peri_base + 0x200000) // 0x7E200000 | ||
| #define SPI0_BASE (peri_base + 0x204000) // 0x7E204000 SPI0 | ||
| #define BSC0_BASE (peri_base + 0x205000) // 0x7E205000 BSC0 // GPIO 00 & 01/pin 27 & 28 | ||
| #define PWM_BASE (peri_base + 0x20C000) // 0x7E20C000 PWM0 | ||
| #define PWM_BASE (peri_base + 0x20C000) // 0x7E20C000 PWM0 | ||
| #define AUX_BASE (peri_base + 0x215000) // 0x7E215000 unused | ||
| #define SPI1_BASE (peri_base + 0x215080) // 0x7E215080 unused | ||
| #define SPI2_BASE (peri_base + 0x2150C0) // 0x7E2150C0 unused | ||
| #define BSC1_BASE (peri_base + 0x804000) // 0x7E804000 BSC1 // GPIO 02 & 03/pin 03 & 05 | ||
| #define BSC1_BASE (peri_base + 0x804000) // 0x7E804000 BSC1 // GPIO 02 & 03/pin 03 & 05 | ||
@@ -67,10 +67,10 @@ /* Size of memory block or length of bytes to be used during mmap() */ | ||
| /* System timer registers */ | ||
| #define ST_PERI_BASE base_pointer[0] // ST_BASE | ||
| #define ST_CS (ST_PERI_BASE + 0x00/4) | ||
| #define ST_CLO (ST_PERI_BASE + 0x04/4) | ||
| #define ST_PERI_ BASE base_pointer[0] // ST_BASE | ||
| #define ST_CS (ST_PERI_BASE + 0x00/4) | ||
| #define ST_CLO (ST_PERI_BASE + 0x04/4) | ||
| #define ST_CHI_CLO (ST_PERI_BASE + 0x08/4) | ||
| #define ST_C0 (ST_PERI_BASE + 0x0C/4) | ||
| #define ST_C1 (ST_PERI_BASE + 0x10/4) | ||
| #define ST_C2 (ST_PERI_BASE + 0x14/4) | ||
| #define ST_C3 (ST_PERI_BASE + 0x18/4) | ||
| #define ST_C0 (ST_PERI_BASE + 0x0C/4) | ||
| #define ST_C1 (ST_PERI_BASE + 0x10/4) | ||
| #define ST_C2 (ST_PERI_BASE + 0x14/4) | ||
| #define ST_C3 (ST_PERI_BASE + 0x18/4) | ||
@@ -89,8 +89,8 @@ /* PWM control manager clocks control registers | ||
| #define GPIO_PERI_BASE base_pointer[2] // GPIO_BASE | ||
| #define GPIO_GPFSEL0 (GPIO_PERI_BASE + 0x00/4) | ||
| #define GPIO_GPFSEL1 (GPIO_PERI_BASE + 0x04/4) | ||
| #define GPIO_GPFSEL2 (GPIO_PERI_BASE + 0x08/4) | ||
| #define GPIO_GPFSEL3 (GPIO_PERI_BASE + 0x0C/4) | ||
| #define GPIO_GPFSEL4 (GPIO_PERI_BASE + 0x10/4) | ||
| #define GPIO_GPFSEL5 (GPIO_PERI_BASE + 0x14/4) | ||
| #define GPIO_GPFSEL0 (GPIO_PERI_BASE + 0x00/4) | ||
| #define GPIO_GPFSEL1 (GPIO_PERI_BASE + 0x04/4) | ||
| #define GPIO_GPFSEL2 (GPIO_PERI_BASE + 0x08/4) | ||
| #define GPIO_GPFSEL3 (GPIO_PERI_BASE + 0x0C/4) | ||
| #define GPIO_GPFSEL4 (GPIO_PERI_BASE + 0x10/4) | ||
| #define GPIO_GPFSEL5 (GPIO_PERI_BASE + 0x14/4) | ||
| #define GPIO_GPSET0 (GPIO_PERI_BASE + 0x1C/4) | ||
@@ -111,6 +111,6 @@ #define GPIO_GPSET1 (GPIO_PERI_BASE + 0x20/4) | ||
| #define GPIO_GPLEN0 (GPIO_PERI_BASE + 0x70/4) | ||
| #define GPIO_GPAREN0 (GPIO_PERI_BASE + 0x7C/4) | ||
| #define GPIO_GPAREN1 (GPIO_PERI_BASE + 0x80/4) | ||
| #define GPIO_GPAFEN0 (GPIO_PERI_BASE + 0x88/4) | ||
| #define GPIO_GPAFEN1 (GPIO_PERI_BASE + 0x8C/4) | ||
| #define GPIO_GPAREN0 (GPIO_PERI_BASE + 0x7C/4) | ||
| #define GPIO_GPAREN1 (GPIO_PERI_BASE + 0x80/4) | ||
| #define GPIO_GPAFEN0 (GPIO_PERI_BASE + 0x88/4) | ||
| #define GPIO_GPAFEN1 (GPIO_PERI_BASE + 0x8C/4) | ||
| #define GPIO_GPPUD (GPIO_PERI_BASE + 0x94/4) | ||
@@ -136,3 +136,3 @@ #define GPIO_GPPUDCLK0 (GPIO_PERI_BASE + 0x98/4) | ||
| #define PWM_FIF1 (PWM_PERI_BASE + 0x18/4) | ||
| #define PWM_RNG2 (PWM_PERI_BASE + 0x20/4) | ||
| #define PWM_RNG2 (PWM_PERI_BASE + 0x20/4) | ||
| #define PWM_DAT2 (PWM_PERI_BASE + 0x24/4) | ||
@@ -142,6 +142,6 @@ | ||
| #define I2C_PERI_BASE base_pointer[5] // BSC1_BASE | ||
| #define I2C_C (I2C_PERI_BASE + 0x00/4) | ||
| #define I2C_S (I2C_PERI_BASE + 0x04/4) | ||
| #define I2C_C (I2C_PERI_BASE + 0x00/4) | ||
| #define I2C_S (I2C_PERI_BASE + 0x04/4) | ||
| #define I2C_DLEN (I2C_PERI_BASE + 0x08/4) | ||
| #define I2C_A (I2C_PERI_BASE + 0x0C/4) | ||
| #define I2C_A (I2C_PERI_BASE + 0x0C/4) | ||
| #define I2C_FIFO (I2C_PERI_BASE + 0x10/4) | ||
@@ -170,3 +170,3 @@ #define I2C_DIV (I2C_PERI_BASE + 0x14/4) | ||
| /* Temporary dynamic core_clock frequency container (RPi 1 & 2 = 250 MHz, RPi 3 & 4 = 400 MHz) */ | ||
| uint32_t core_clock_freq = 250000000; // initial value is 250 MHz | ||
| uint32_t core_clock_freq = 250000000; // Initial value is 250 MHz | ||
@@ -193,35 +193,35 @@ /********************************** | ||
| if (strncmp (info, "Model", 5) == 0) | ||
| break; | ||
| break; | ||
| } | ||
| //printf("%s", info); | ||
| if(strstr(info, "Pi Zero")||strstr(info, "Pi 1")){ | ||
| if(strstr(info, "Pi Zero")||strstr(info, "Pi 1")){ | ||
| //puts("Pi zero/Pi 1"); | ||
| peri_base = PERI_BASE_RPI1; | ||
| } | ||
| peri_base = PERI_BASE_RPI1; | ||
| } | ||
| else if(strstr(info, "Pi Zero 2")||strstr(info, "Pi 3")){ | ||
| //puts("Pi Zero 2/Pi 3"); | ||
| peri_base = PERI_BASE_RPI23; | ||
| core_clock_freq = CORE_CLOCK_FREQ_RPI23; | ||
| } | ||
| peri_base = PERI_BASE_RPI23; | ||
| core_clock_freq = CORE_CLOCK_FREQ_RPI23; | ||
| } | ||
| else if(strstr(info, "Pi Compute Module 3")){ | ||
| //puts("Pi Compute Module 3 Model"); | ||
| peri_base = PERI_BASE_RPI23; | ||
| peri_base = PERI_BASE_RPI23; | ||
| core_clock_freq = CORE_CLOCK_FREQ_RPI23; | ||
| } | ||
| } | ||
| else if(strstr(info, "Pi 4")||strstr(info, "Pi Compute Module 4")){ | ||
| //puts("Pi 4 Model B/Pi Compute Module 4"); | ||
| peri_base = PERI_BASE_RPI4; | ||
| core_clock_freq = CORE_CLOCK_FREQ_RPI4; | ||
| } | ||
| peri_base = PERI_BASE_RPI4; | ||
| core_clock_freq = CORE_CLOCK_FREQ_RPI4; | ||
| } | ||
| else if(strstr(info, "Pi 400")){ | ||
| //puts("Pi 400 Model"); | ||
| peri_base = PERI_BASE_RPI4; | ||
| core_clock_freq = CORE_CLOCK_FREQ_RPI4; | ||
| } | ||
| peri_base = PERI_BASE_RPI4; | ||
| core_clock_freq = CORE_CLOCK_FREQ_RPI4; | ||
| } | ||
| else{ | ||
| //puts("Other Rpi Model"); | ||
| peri_base = PERI_BASE_RPI4; | ||
| core_clock_freq = CORE_CLOCK_FREQ_RPI4; | ||
| } | ||
| core_clock_freq = CORE_CLOCK_FREQ_RPI4; | ||
| } | ||
@@ -237,3 +237,3 @@ /* Verify ST_BASE, its new value should be other than 0x3000 | ||
| exit(1); | ||
| } | ||
| } | ||
@@ -243,20 +243,20 @@ /* | ||
| // Get 'Hardware' info | ||
| rewind (fp); | ||
| while (fgets (info, INFO_SIZE, fp) != NULL){ | ||
| if (strncmp (info, "Hardware", 8) == 0) | ||
| break ; | ||
| } | ||
| printf("%s", info); // show Hardware line info | ||
| rewind (fp); | ||
| while (fgets (info, INFO_SIZE, fp) != NULL){ | ||
| if (strncmp (info, "Hardware", 8) == 0) | ||
| break ; | ||
| } | ||
| printf("%s", info); // show Hardware line info | ||
| / Get 'Revision' info | ||
| // Get 'Revision' info | ||
| rewind (fp); | ||
| while (fgets (info, INFO_SIZE, fp) != NULL){ | ||
| if (strncmp (info, "Revision", 8) == 0) | ||
| break ; | ||
| } | ||
| printf("%s", info); // show Revision line info | ||
| while (fgets (info, INFO_SIZE, fp) != NULL){ | ||
| if (strncmp (info, "Revision", 8) == 0) | ||
| break ; | ||
| } | ||
| printf("%s", info); // show Revision line info | ||
| */ | ||
| /* Set each peripheral base address | ||
| * consecutively for each base array element | ||
| * consecutively for each base array element | ||
| */ | ||
@@ -273,3 +273,3 @@ base_add[0] = ST_BASE; | ||
| base_add[4] = PWM_BASE; | ||
| } | ||
| } | ||
@@ -283,3 +283,3 @@ if(i2c_option == 0){ | ||
| fclose(fp); | ||
| fclose(fp); | ||
| } | ||
@@ -290,3 +290,4 @@ | ||
| /*page_size = (size_t)sysconf(_SC_PAGESIZE); | ||
| /* | ||
| page_size = (size_t)sysconf(_SC_PAGESIZE); | ||
| //printf("init page_size: %i\n", page_size); | ||
@@ -297,3 +298,4 @@ | ||
| exit(1); | ||
| }*/ | ||
| } | ||
| */ | ||
@@ -306,4 +308,4 @@ // access = 0, non-root | ||
| exit(1); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| // access = 1, root | ||
@@ -316,30 +318,29 @@ else if(access) { | ||
| exit(1); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| /* Start mmap() process for each peripheral base address | ||
| /* Start mmap() process for each peripheral base address | ||
| * and capture the corresponding peripheral memory base pointers | ||
| */ | ||
| for(i = 0; i < BASE_INDEX; i++){ | ||
| base_pointer[i] = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, base_add[i]); | ||
| for(i = 0; i < BASE_INDEX; i++){ | ||
| base_pointer[i] = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, base_add[i]); | ||
| if (base_pointer[i] == MAP_FAILED) { | ||
| perror("mmap() error"); | ||
| perror("mmap() error"); | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid peripheral register base address."); | ||
| if(close(fd) < 0){ | ||
| perror("fd close"); | ||
| } | ||
| if(close(fd) < 0) | ||
| perror("fd close"); | ||
| exit(1); | ||
| } | ||
| } | ||
| /* Reset peripheral base register pointers back to 0 */ | ||
| // Note: Disable this for SocketCan operation | ||
| *base_pointer[i] = 0; | ||
| *base_pointer[i] = 0; | ||
| } | ||
| /* Close fd after memory-mapped operation */ | ||
| if(close(fd) < 0){ | ||
| /* Close fd after memory-mapped operation */ | ||
| if(close(fd) < 0) | ||
| perror("fd close"); | ||
| } | ||
| } | ||
@@ -354,3 +355,4 @@ | ||
| void rpi_init(int access) { | ||
| set_peri_base_address(0, 0, 1); | ||
| set_peri_base_address(0, 0, 1); | ||
| start_mmap(access); | ||
@@ -379,3 +381,3 @@ } | ||
| { | ||
| int i; | ||
| int i; | ||
| //page_size = (size_t)sysconf(_SC_PAGESIZE); | ||
@@ -385,12 +387,12 @@ //printf("close page_size: %i\n", page_size); | ||
| for(i = 0; i < BASE_INDEX; i++){ | ||
| if (munmap((uint32_t *) base_pointer[i] , BLOCK_SIZE) < 0){ | ||
| perror("munmap() error"); | ||
| if (munmap((uint32_t *) base_pointer[i] , BLOCK_SIZE) < 0){ | ||
| perror("munmap() error"); | ||
| printf("%s() error: ", __func__); | ||
| puts("munmap() operation fail"); | ||
| return -1; | ||
| } | ||
| } | ||
| } | ||
| /* munmap() success */ | ||
| return 0; | ||
| return 0; | ||
| } | ||
@@ -413,7 +415,7 @@ | ||
| void nswait(uint64_t ns) { | ||
| struct timespec req = { ns / 1000000, ns % 1000000 }; | ||
| struct timespec rem; | ||
| struct timespec req = { ns / 1000000, ns % 1000000 }; | ||
| struct timespec rem; | ||
| while ( nanosleep(&req,&rem) == -1 ) | ||
| req.tv_nsec = rem.tv_nsec; | ||
| while ( nanosleep(&req,&rem) == -1 ) | ||
| req.tv_nsec = rem.tv_nsec; | ||
| } | ||
@@ -427,3 +429,3 @@ | ||
| while ( nanosleep(&req,&rem) == -1 ) | ||
| req.tv_nsec = rem.tv_nsec; | ||
| req.tv_nsec = rem.tv_nsec; | ||
| } | ||
@@ -437,3 +439,3 @@ | ||
| while ( nanosleep(&req, &rem) == -1 ) | ||
| req.tv_nsec = rem.tv_nsec; | ||
| req.tv_nsec = rem.tv_nsec; | ||
| } | ||
@@ -514,7 +516,7 @@ | ||
| volatile uint32_t *gpsel = (uint32_t *)(GPIO_GPFSEL0 + (pin/10)); // get the GPFSEL0 pointer (GPFSEL0 ~ GPFSEL5) based on the pin number selected | ||
| uint32_t mask = ~ (7 << (pin % 10)*3); // mask to reset fsel to 0 first | ||
| *gpsel &= mask; // reset gpsel value to 0 | ||
| mask = (fsel << ((pin) % 10)*3); // mask for new fsel value | ||
| uint32_t mask = ~ (7 << (pin % 10)*3); // mask to reset fsel to 0 first | ||
| *gpsel &= mask; // reset gpsel value to 0 | ||
| mask = (fsel << ((pin) % 10)*3); // mask for new fsel value | ||
| __sync_synchronize(); | ||
| *gpsel |= mask; // write new fsel value to gpselect pointer | ||
| *gpsel |= mask; // write new fsel value to gpselect pointer | ||
| __sync_synchronize(); | ||
@@ -534,3 +536,3 @@ } | ||
| void gpio_output(uint8_t pin){ | ||
| set_gpio(pin, 1); | ||
| set_gpio(pin, 1); | ||
| } | ||
@@ -560,19 +562,19 @@ | ||
| else if(mode == 5){ | ||
| set_gpio(pin, 5); // alt-func 1 | ||
| } | ||
| set_gpio(pin, 5); // alt-func 1 | ||
| } | ||
| else if(mode == 6){ | ||
| set_gpio(pin, 6); // alt-func 2 | ||
| } | ||
| } | ||
| else if(mode == 7){ | ||
| set_gpio(pin, 7); // alt-func 3 | ||
| } | ||
| set_gpio(pin, 7); // alt-func 3 | ||
| } | ||
| else if(mode == 3){ | ||
| set_gpio(pin, 3); // alt-func 4 | ||
| } | ||
| else if(mode == 2){ | ||
| set_gpio(pin, 2); // alt-func 5 | ||
| } | ||
| else if(mode == 2){ | ||
| set_gpio(pin, 2); // alt-func 5 | ||
| } | ||
| else{ | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid mode parameter."); | ||
| puts("Invalid mode parameter."); | ||
| } | ||
@@ -608,2 +610,24 @@ } | ||
| /* Turn ON a GPIO pin | ||
| */ | ||
| void gpio_on(uint8_t pin){ | ||
| gpio_write(pin, 1); | ||
| } | ||
| /* Turn OFF a GPIO pin | ||
| */ | ||
| void gpio_off(uint8_t pin){ | ||
| gpio_write(pin, 0); | ||
| } | ||
| /* Create a simple sing-shot pulse | ||
| * | ||
| * td as time duration or period of the pulse | ||
| */ | ||
| void gpio_pulse(uint8_t pin, int td){ | ||
| gpio_on(pin); | ||
| mswait(td); | ||
| gpio_off(pin); | ||
| } | ||
| /* Read the current state of a GPIO pin (input/output) | ||
@@ -649,10 +673,10 @@ * | ||
| if(bit == 1){ | ||
| setBit(GPIO_GPHEN0, pin); | ||
| setBit(GPIO_GPHEN0, pin); | ||
| } | ||
| else if(bit == 0){ | ||
| clearBit(GPIO_GPHEN0, pin); | ||
| clearBit(GPIO_GPHEN0, pin); | ||
| } | ||
| else { | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid bit parameter."); | ||
| puts("Invalid bit parameter."); | ||
| } | ||
@@ -668,10 +692,10 @@ } | ||
| if(bit == 1){ | ||
| setBit(GPIO_GPLEN0, pin); | ||
| setBit(GPIO_GPLEN0, pin); | ||
| } | ||
| else if(bit == 0){ | ||
| clearBit(GPIO_GPLEN0, pin); | ||
| clearBit(GPIO_GPLEN0, pin); | ||
| } | ||
| else { | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid bit parameter."); | ||
| puts("Invalid bit parameter."); | ||
| } | ||
@@ -710,10 +734,10 @@ } | ||
| if(bit == 1){ | ||
| setBit(GPIO_GPFEN0, pin); | ||
| setBit(GPIO_GPFEN0, pin); | ||
| } | ||
| else if(bit == 0){ | ||
| clearBit(GPIO_GPFEN0, pin); | ||
| clearBit(GPIO_GPFEN0, pin); | ||
| } | ||
| else { | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid bit parameter."); | ||
| puts("Invalid bit parameter."); | ||
| } | ||
@@ -729,10 +753,10 @@ } | ||
| if(bit == 1){ | ||
| setBit(GPIO_GPAREN0, pin); | ||
| setBit(GPIO_GPAREN0, pin); | ||
| } | ||
| else if(bit == 0){ | ||
| clearBit(GPIO_GPAREN0, pin); | ||
| clearBit(GPIO_GPAREN0, pin); | ||
| } | ||
| else { | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid bit parameter."); | ||
| puts("Invalid bit parameter."); | ||
| } | ||
@@ -748,10 +772,10 @@ } | ||
| if(bit == 1){ | ||
| setBit(GPIO_GPAFEN0, pin); | ||
| setBit(GPIO_GPAFEN0, pin); | ||
| } | ||
| else if(bit == 0){ | ||
| clearBit(GPIO_GPAFEN0, pin); | ||
| clearBit(GPIO_GPAFEN0, pin); | ||
| } | ||
| else { | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid bit parameter."); | ||
| puts("Invalid bit parameter."); | ||
| } | ||
@@ -773,3 +797,3 @@ } | ||
| void gpio_reset_event(uint8_t pin) { | ||
| setBit(GPIO_GPEDS0, pin); | ||
| setBit(GPIO_GPEDS0, pin); | ||
| } | ||
@@ -785,14 +809,14 @@ | ||
| if(value == 0){ | ||
| *GPIO_GPPUD = 0x0; // Disable PUD/Pull-UP/Down | ||
| } | ||
| *GPIO_GPPUD = 0x0; // Disable PUD/Pull-UP/Down | ||
| } | ||
| else if(value == 1){ | ||
| *GPIO_GPPUD = 0x1; // Enable PD/Pull-Down | ||
| *GPIO_GPPUD = 0x1; // Enable PD/Pull-Down | ||
| } | ||
| else if(value == 2){ | ||
| *GPIO_GPPUD = 0x2; // Enable PU/Pull-Up | ||
| *GPIO_GPPUD = 0x2; // Enable PU/Pull-Up | ||
| } | ||
| else{ | ||
| printf("%s() error: ", __func__); | ||
| else{ | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid pud value."); | ||
| } | ||
| } | ||
@@ -824,14 +848,14 @@ uswait(150); /* required wait times based on bcm2835 manual */ | ||
| void pwm_set_pin(uint8_t pin){ | ||
| if(pin == 12||pin ==13) { // alt 100b, PHY pin 33, GPIO 13, alt 0 | ||
| set_gpio(pin, 4); // alt 100b, PHY pin 32, GPIO 12, alt 0 | ||
| } | ||
| else if(pin == 18||pin == 19) { // alt 10b, PHY pin 35, GPIO 19, alt 5 | ||
| set_gpio(pin, 2); // alt 10b, PHY pin 12, GPIO 18, alt 5 | ||
| if(pin == 12||pin ==13) { // alt 100b, PHY pin 33, GPIO 13, alt 0 | ||
| set_gpio(pin, 4); // alt 100b, PHY pin 32, GPIO 12, alt 0 | ||
| } | ||
| else if(pin == 18||pin == 19) { // alt 10b, PHY pin 35, GPIO 19, alt 5 | ||
| set_gpio(pin, 2); // alt 10b, PHY pin 12, GPIO 18, alt 5 | ||
| } | ||
| else { | ||
| printf("%s() error: ", __func__); | ||
| else { | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid pin number for PWM."); | ||
| puts("Choose only from board header layout pins 12, 32, 33 and 35."); | ||
| exit(1); | ||
| } | ||
| } | ||
| } | ||
@@ -842,9 +866,9 @@ | ||
| if(pin == 18||pin ==12||pin==13||pin==19) { | ||
| gpio_input(pin); // GPIO18/PHY12, GPIO12/PHY32, GPIO13/PHY33, GPIO19/PHY35 | ||
| } | ||
| else { | ||
| printf("%s() error: ", __func__); | ||
| gpio_input(pin); // GPIO18/PHY12, GPIO12/PHY32, GPIO13/PHY33, GPIO19/PHY35 | ||
| } | ||
| else { | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid pin."); | ||
| exit(1); | ||
| } | ||
| exit(1); | ||
| } | ||
| } | ||
@@ -876,7 +900,7 @@ | ||
| if(isBitSet(CM_PWMCTL, 7)){ | ||
| return 1; // clk is running | ||
| } | ||
| return 1; // clk is running | ||
| } | ||
| else{ | ||
| return 0; // clk is not running | ||
| } | ||
| return 0; // clk is not running | ||
| } | ||
| } | ||
@@ -910,4 +934,6 @@ | ||
| /* set DIVF (bit num 11-0) divisor from clock manager | ||
| general purpose register (CM_GP2DIV) while clk is not running */ | ||
| /* | ||
| set DIVF (bit num 11-0) divisor from clock manager | ||
| general purpose register (CM_GP2DIV) while clk is not running | ||
| */ | ||
| if(!isBitSet(CM_PWMCTL, 7)){ | ||
@@ -939,4 +965,4 @@ *CM_PWMDIV = 0x5A000000 | ( div << 12 ); | ||
| else{ | ||
| return -1; | ||
| } | ||
| return -1; | ||
| } | ||
| } | ||
@@ -962,21 +988,21 @@ | ||
| bool WERR1 = isBitSet(PWM_STA, 2); | ||
| uswait(10); | ||
| uswait(10); | ||
| if (!STA1) { | ||
| if (RERR1) | ||
| setBit(PWM_STA, 3); // reset RERR1 | ||
| if (WERR1) | ||
| if(!STA1) { | ||
| if(RERR1) | ||
| setBit(PWM_STA, 3); // reset RERR1 | ||
| if(WERR1) | ||
| setBit(PWM_STA, 2); // reset WERR1 | ||
| if (BERR) | ||
| setBit(PWM_STA, 8); // reset BERR | ||
| if(BERR) | ||
| setBit(PWM_STA, 8); // reset BERR | ||
| } | ||
| if(!STA2){ | ||
| if (RERR1) | ||
| setBit(PWM_STA, 3); // reset RERR1 | ||
| if (WERR1) | ||
| setBit(PWM_STA, 2); // reset WERR1 | ||
| if (BERR) | ||
| setBit(PWM_STA, 8); // reset BERR | ||
| if(RERR1) | ||
| setBit(PWM_STA, 3); // reset RERR1 | ||
| if(WERR1) | ||
| setBit(PWM_STA, 2); // reset WERR1 | ||
| if(BERR) | ||
| setBit(PWM_STA, 8); // reset BERR | ||
| } | ||
| uswait(10); | ||
| uswait(10); | ||
| } | ||
@@ -989,11 +1015,11 @@ | ||
| if(n == 1){ | ||
| setBit(PWM_CTL, position); | ||
| } | ||
| else if(n == 0) { | ||
| clearBit(PWM_CTL, position); | ||
| } | ||
| else{ | ||
| puts("Invalid n control parameter. Choose 1 or 0 only."); | ||
| } | ||
| uswait(10); | ||
| setBit(PWM_CTL, position); | ||
| } | ||
| else if(n == 0) { | ||
| clearBit(PWM_CTL, position); | ||
| } | ||
| else{ | ||
| puts("Invalid n control parameter. Choose 1 or 0 only."); | ||
| } | ||
| uswait(10); | ||
| } | ||
@@ -1008,4 +1034,4 @@ | ||
| // Channel 1 | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| pwm_reg_ctrl(n, 0); | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| pwm_reg_ctrl(n, 0); | ||
| } | ||
@@ -1029,4 +1055,4 @@ // Channel 2 | ||
| // Channel 1 | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| pwm_reg_ctrl(n, 7); | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| pwm_reg_ctrl(n, 7); | ||
| } | ||
@@ -1050,3 +1076,3 @@ // Channel 2 | ||
| // Channel 1 | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| pwm_reg_ctrl(n, 4); | ||
@@ -1067,3 +1093,3 @@ } | ||
| // Channel 1 | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| *PWM_RNG1 = range; | ||
@@ -1085,16 +1111,16 @@ reset_status_reg(); | ||
| void pwm_set_data(uint8_t pin, uint32_t data){ | ||
| // Channel 1 | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| *PWM_DAT1 = data; | ||
| // Channel 1 | ||
| if( pin == 18 || pin == 12) { // GPIO 18/12, PHY 12/32 | ||
| *PWM_DAT1 = data; | ||
| reset_status_reg(); | ||
| } | ||
| // Channel 2 | ||
| else if(pin == 13 || pin == 19) { // GPIO 13/19, PHY 33/35 | ||
| *PWM_DAT2 = data; | ||
| reset_status_reg(); | ||
| } | ||
| else{ | ||
| // Channel 2 | ||
| else if(pin == 13 || pin == 19) { // GPIO 13/19, PHY 33/35 | ||
| *PWM_DAT2 = data; | ||
| reset_status_reg(); | ||
| } | ||
| else{ | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid pin."); | ||
| } | ||
| } | ||
| } | ||
@@ -1211,3 +1237,3 @@ | ||
| return 1; // i2c initialization success is successful | ||
| return 1; // i2c initialization is successful | ||
| } | ||
@@ -1236,3 +1262,3 @@ | ||
| // set a new msb and lsb values to data delay register | ||
| // set a new msb and lsb values to data delay register | ||
| volatile uint32_t value = (volatile uint32_t)(msb << 16 | lsb); | ||
@@ -1251,3 +1277,4 @@ | ||
| /*volatile uint32_t delay_reg = *I2C_DEL; | ||
| /* | ||
| volatile uint32_t delay_reg = *I2C_DEL; | ||
@@ -1260,3 +1287,4 @@ // Extract the msb and lsb values from a pointer | ||
| printf("lsb1:%x\n", lsb1); | ||
| printf("delay_reg:%x\n", delay_reg);*/ | ||
| printf("delay_reg:%x\n", delay_reg); | ||
| */ | ||
@@ -1273,8 +1301,10 @@ return *I2C_DEL; | ||
| /*printf("cdiv msb:%x\n", msb); | ||
| /* | ||
| printf("cdiv msb:%x\n", msb); | ||
| printf("cdiv lsb:%x\n", lsb); | ||
| printf("cdiv_reg:%x\n", div_reg);*/ | ||
| printf("cdiv_reg:%x\n", div_reg); | ||
| */ | ||
| volatile uint32_t *div = I2C_DIV; | ||
| lsb = 0x05DC; | ||
| lsb = 0x05DC; | ||
| // reset | ||
@@ -1299,3 +1329,3 @@ *div = (volatile uint32_t)(msb << 16 | lsb); | ||
| /* get the divisor value from the 250 MHz system clock source */ | ||
| //uint32_t divider = (core_clock_freq / baud); // using a dynamic core clock freq | ||
| //uint32_t divider = (core_clock_freq / baud); // using a dynamic core clock freq | ||
@@ -1311,8 +1341,10 @@ uint32_t divider = (CORE_CLK_FREQ/baud); // using a fixed core clock freq | ||
| /*volatile uint32_t *clkt = I2C_CLKT; | ||
| printf("clkt:%i\n", *clkt); | ||
| /* | ||
| volatile uint32_t *clkt = I2C_CLKT; | ||
| printf("clkt:%i\n", *clkt); | ||
| if(i == buf_len){ | ||
| puts("Data tansfer is complete."); | ||
| }*/ | ||
| } | ||
| */ | ||
@@ -1323,3 +1355,3 @@ if(i < buf_len) | ||
| printf("%s(): ", __func__); | ||
| puts("Data tansfer is incomplete."); | ||
| puts("Data tansfer is incomplete."); | ||
| } | ||
@@ -1330,3 +1362,3 @@ else if(i > buf_len) | ||
| printf("%s(): ", __func__); | ||
| puts("Data tansfer error."); | ||
| puts("Data tansfer error."); | ||
| } | ||
@@ -1339,3 +1371,3 @@ | ||
| printf("%s(): ", __func__); | ||
| puts("Slave address is not acknowledged."); | ||
| puts("Slave address is not acknowledged."); | ||
| } | ||
@@ -1348,3 +1380,3 @@ | ||
| printf("%s(): ", __func__); | ||
| puts("Clock stretch timeout."); | ||
| puts("Clock stretch timeout."); | ||
| } | ||
@@ -1361,3 +1393,2 @@ /* write error | ||
| puts("Not all data were sent to the slave device."); | ||
| } | ||
@@ -1373,3 +1404,3 @@ /* read error | ||
| printf("%s(): ", __func__); | ||
| puts("Not all data were received from the slave device."); | ||
| puts("Not all data were received from the slave device."); | ||
| } | ||
@@ -1388,4 +1419,4 @@ | ||
| result = 4; | ||
| printf("%s(): ", __func__); | ||
| puts("Data transfer is incomplete."); | ||
| printf("%s(): ", __func__); | ||
| puts("Data transfer is incomplete."); | ||
| } | ||
@@ -1505,6 +1536,6 @@ | ||
| //while(isBitSet(I2C_S, 5) && (i <= rbuf_len)) | ||
| while(isBitSet(I2C_S, 5) && (rbuf_len >= i )) // check RXD field (RXD = 0 FIFO is empty, RXD = 1 FIFO contains at least 1 byte of data) | ||
| while(isBitSet(I2C_S, 5) && (rbuf_len >= i )) // check RXD field (RXD = 0 FIFO is empty, RXD = 1 FIFO contains at least 1 byte of data) | ||
| { | ||
| rbuf[i] = *fifo; | ||
| i++; | ||
| rbuf[i] = *fifo; | ||
| i++; | ||
| } | ||
@@ -1564,3 +1595,3 @@ } | ||
| if(i2c_pin_set == 0){ | ||
| //puts("reset SDA0/SCL0 pins to GPIO input"); | ||
| //puts("reset SDA0/SCL0 pins to GPIO input"); | ||
| set_gpio(0, 0); /* alt 00b, PHY 27, GPIO 00, alt 0 SDA */ | ||
@@ -1573,3 +1604,3 @@ set_gpio(1, 0); /* alt 00b, PHY 28, GPIO 01, alt 0 SCL */ | ||
| set_gpio(3, 0); /* alt 00b, PHY 5, GPIO 03, alt 0 SCL */ | ||
| } | ||
| } | ||
| } | ||
@@ -1585,3 +1616,3 @@ | ||
| { | ||
| //rpi_init(1); | ||
| //rpi_init(1); | ||
| //mswait(25); | ||
@@ -1592,4 +1623,4 @@ | ||
| printf("%s() error: ", __func__); | ||
| puts("Invalid SPI registers addresses."); | ||
| return 0; | ||
| puts("Invalid SPI registers addresses."); | ||
| return 0; | ||
| } | ||
@@ -1606,3 +1637,3 @@ | ||
| clearBit(SPI_CS, 13); // set SPI to SPI Master (Standard SPI) | ||
| clear_fifo(SPI_CS); // Clear SPI TX and RX FIFO | ||
| clear_fifo(SPI_CS); // Clear SPI TX and RX FIFO | ||
@@ -1628,3 +1659,3 @@ return 1; | ||
| volatile uint32_t *div = SPI_CLK; | ||
| *div = divider; | ||
| *div = divider; | ||
| } | ||
@@ -1643,11 +1674,11 @@ | ||
| clearBit(SPI_CS, 2); //CPHA 0 | ||
| clearBit(SPI_CS, 3); //CPOL 0 | ||
| clearBit(SPI_CS, 3); //CPOL 0 | ||
| } | ||
| else if(mode == 1){ | ||
| setBit(SPI_CS, 2); //CPHA 1 | ||
| clearBit(SPI_CS, 3); //CPOL 0 | ||
| setBit(SPI_CS, 2); //CPHA 1 | ||
| clearBit(SPI_CS, 3); //CPOL 0 | ||
| } | ||
| else if(mode == 2){ | ||
| clearBit(SPI_CS, 2); //CPHA 0 | ||
| setBit(SPI_CS, 3); //CPOL 1 | ||
| setBit(SPI_CS, 3); //CPOL 1 | ||
| } | ||
@@ -1658,15 +1689,15 @@ else if(mode == 3){ | ||
| } | ||
| else{ | ||
| printf("%s() error: ", __func__); | ||
| puts("invalid mode"); | ||
| } | ||
| else{ | ||
| printf("%s() error: ", __func__); | ||
| puts("invalid mode"); | ||
| } | ||
| // alternate code | ||
| /* | ||
| volatile uint32_t *cs = SPI_CS; | ||
| uint32_t mask = ~ (3 << 2); // clear bit position 2 and 3 first | ||
| *cs &= mask; // set mask to 0 | ||
| mask = (mode << 2); // write mode value to set SPI data mode | ||
| *cs |= mask; // set data mode | ||
| */ | ||
| // alternate code | ||
| /* | ||
| volatile uint32_t *cs = SPI_CS; | ||
| uint32_t mask = ~ (3 << 2); // clear bit position 2 and 3 first | ||
| *cs &= mask; // set mask to 0 | ||
| mask = (mode << 2); // write mode value to set SPI data mode | ||
| *cs |= mask; // set data mode | ||
| */ | ||
| } | ||
@@ -1686,3 +1717,3 @@ | ||
| uint32_t mask = ~ (3 << 0); // clear bit 0 and 1 first | ||
| *cs_addr &= mask; // set mask to value 0 | ||
| *cs_addr &= mask; // set mask to value 0 | ||
| mask = (cs << 0); // write cs value to set SPI data mode | ||
@@ -1704,3 +1735,3 @@ *cs_addr |= mask; // set cs value | ||
| else if(cs == 0 && active == 1){ | ||
| setBit(SPI_CS, 21); | ||
| setBit(SPI_CS, 21); | ||
| } | ||
@@ -1738,8 +1769,8 @@ else if(cs == 1 && active == 0){ | ||
| { | ||
| // TX fifo is not full, add/write more bytes | ||
| while(isBitSet(SPI_CS, 18) && (w < len)) | ||
| { | ||
| *fifo = wbuf[w]; | ||
| w++; | ||
| } | ||
| // TX fifo is not full, add/write more bytes | ||
| while(isBitSet(SPI_CS, 18) && (w < len)) | ||
| { | ||
| *fifo = wbuf[w]; | ||
| w++; | ||
| } | ||
| } | ||
@@ -1750,8 +1781,8 @@ | ||
| { | ||
| // RX fifo is not empty, read more received bytes | ||
| // RX fifo is not empty, read more received bytes | ||
| while(isBitSet(SPI_CS, 17) && (r < len )) | ||
| { | ||
| rbuf[r] = *fifo; | ||
| r++; | ||
| } | ||
| { | ||
| rbuf[r] = *fifo; | ||
| r++; | ||
| } | ||
| } | ||
@@ -1764,4 +1795,4 @@ | ||
| if(isBitSet(SPI_CS, 16)){ | ||
| printf("%s() error: ", __func__); | ||
| puts("data transfer error"); | ||
| printf("%s() error: ", __func__); | ||
| puts("data transfer error"); | ||
| } | ||
@@ -1788,4 +1819,4 @@ } | ||
| { | ||
| *fifo = wbuf[i]; | ||
| i++; | ||
| *fifo = wbuf[i]; | ||
| i++; | ||
| } | ||
@@ -1816,4 +1847,4 @@ } | ||
| { | ||
| rbuf[i] = *fifo; | ||
| i++; | ||
| rbuf[i] = *fifo; | ||
| i++; | ||
| } | ||
@@ -1826,1 +1857,2 @@ } | ||
+6
-1
@@ -48,2 +48,8 @@ /** | ||
| void gpio_on(uint8_t pin); | ||
| void gpio_off(uint8_t pin); | ||
| void gpio_pulse(uint8_t pin, int td); | ||
| void gpio_reset_all_events(uint8_t pin); | ||
@@ -134,3 +140,2 @@ | ||
| #ifdef __cplusplus | ||
@@ -137,0 +142,0 @@ } |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
163043
-18.25%72
-95.1%