From fe02d1d4f9813f08a27ec1221ee16d6fdfa82371 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 2 Jul 2014 14:11:47 +0200 Subject: [PATCH 01/64] Preparing wiring-pi 2.0.0 - Split the source code (based on libWiringPi source code hierarchy) - ADD: Implement I2C functions - ADD: Aliasing serialPrintf to serialPuts - FIX: missing constants in pinMode check - ADD: missing constant PI_MODEL_COMPUTE - ADD: wiringPiISR support (experimental) - UPD: Exports constants from C++ (ReadOnly | DontDelete) - UPD: Exports setup function from C++ - UPD: setup function no longer accepts calling without mode defined (breaks backward compatibility) - ADD: Better types and allowed values check - ADD: Better error messages - UPD: wiringPiSPIDataRW now takes two parameters, a node buffer as second parameter (instead of a string as second and length as third) - UPD: README.md (move documentation to DOCUMENTATION.md) - UPD: Documentation - UPD: Package.json version and contributors section - ADD: version history file (CHANGELOG.md) - DEL: Backward compatibility constants --- .gitignore | 2 + CHANGELOG.md | 0 DOCUMENTATION.md | 347 ++++++ README.md | 259 +---- binding.gyp | 24 +- lib/exports.js | 138 +-- package.json | 5 +- src/addon.h | 150 +++ src/bindings.cc | 2501 ------------------------------------------- src/softPwm.cc | 87 ++ src/softPwm.h | 8 + src/softServo.cc | 73 ++ src/softServo.h | 8 + src/softTone.cc | 77 ++ src/softTone.h | 8 + src/wiringPi.cc | 709 ++++++++++++ src/wiringPi.h | 8 + src/wiringPiI2C.cc | 197 ++++ src/wiringPiI2C.h | 8 + src/wiringPiISR.cc | 227 ++++ src/wiringPiISR.h | 8 + src/wiringPiSPI.cc | 80 ++ src/wiringPiSPI.h | 8 + src/wiringSerial.cc | 167 +++ src/wiringSerial.h | 8 + src/wiringShift.cc | 76 ++ src/wiringShift.h | 8 + src/wpi.cc | 15 + src/wpi.h | 14 + 29 files changed, 2331 insertions(+), 2889 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 DOCUMENTATION.md create mode 100644 src/addon.h delete mode 100644 src/bindings.cc create mode 100644 src/softPwm.cc create mode 100644 src/softPwm.h create mode 100644 src/softServo.cc create mode 100644 src/softServo.h create mode 100644 src/softTone.cc create mode 100644 src/softTone.h create mode 100644 src/wiringPi.cc create mode 100644 src/wiringPi.h create mode 100644 src/wiringPiI2C.cc create mode 100644 src/wiringPiI2C.h create mode 100644 src/wiringPiISR.cc create mode 100644 src/wiringPiISR.h create mode 100644 src/wiringPiSPI.cc create mode 100644 src/wiringPiSPI.h create mode 100644 src/wiringSerial.cc create mode 100644 src/wiringSerial.h create mode 100644 src/wiringShift.cc create mode 100644 src/wiringShift.h create mode 100644 src/wpi.cc create mode 100644 src/wpi.h diff --git a/.gitignore b/.gitignore index 378eac2..72bd1fa 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ build +npm-debug.log +wiringpi/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e69de29 diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md new file mode 100644 index 0000000..9b9aa85 --- /dev/null +++ b/DOCUMENTATION.md @@ -0,0 +1,347 @@ + + +# Index + +* [Install](#install) +* [Usage](#usage) +* [APIs](#apis) + * [Setup](#setup) + * [wiringPiSetup](#wiringpisetup) + * [wiringPiSetupGpio](#wiringpisetupgpio) + * [Shift](#shift) + +# Install + +```bash +npm install wiring-pi +``` + +# Usage + +```javascript +var wpi = require('wiring-pi'); +``` + +# APIs + +## Setup + +### `wiringPiSetup()` + +Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. +This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. +see the pins page (http://wiringpi.com/pins/) for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. +This function needs to be called with root privileges. + +### `wiringPiSetupGpio()` + +This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards. + +### `wiringPiSetupPhys()` + >= 1.0.0 + +Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. As above, this function needs to be called with root priviliges. + +### `wiringPiSetupSys()` + +This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed). + +### `setup(mode)` + +An handy function to setup wiringPi + +`mode` can be one of the following values: + +* `wpi`: sets up pin numbering with wiringPiSetup +* `gpio`: sets up pin numbering with wiringPiSetupGpio +* `sys`: sets up pin numbering with wiringPiSetupSys +* `phys`: sets up pin numbering with wiringPiSetupPhys + +More info about pin numbering systems at [wiringpi.com/pins/](http://wiringpi.com/pins/) + +**NOTE: wiring-pi >= 2.0.0 no longer accept calling setup without mode specified. (defaulting to `wpi` in wiring-pi < 2.0.0)** + +--- + +## Core functions + +### `pinModeAlt(pin, mode)` + >= 1.0.0 + +This is an un-documented special to let you set any pin to any mode. + +`mode` can be one of the following values: + +* `WPI_MODE_PINS` +* `WPI_MODE_PHYS` +* `WPI_MODE_GPIO` + +### `pinMode(pin, mode)` + +This sets the mode of a pin. Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program. + +`mode` can be one of the following values: + +* `modes.INPUT` **wiring-pi < 1.0.0** +* `modes.OUTPUT` **wiring-pi < 1.0.0** +* `modes.PWM_OUTPUT` **wiring-pi < 1.0.0** +* `modes.GPIO_CLOCK` **wiring-pi < 1.0.0** +* `INPUT` +* `OUTPUT` +* `PWM_OUTPUT` +* `GPIO_CLOCK` +* `SOFT_PWM_OUTPUT` **wiring-pi >= 1.1.0** +* `SOFT_TONE_OUTPUT` **wiring-pi >= 1.1.0** + +### `pullUpDnControl(pin, pud)` + >= 0.2.0 + +This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. + +`pud` can be one of the following values: + +* `PUD_OFF` *no pull up/down* +* `PUD_DOWN` *pull to ground* +* `PUD_UP` *pull to 3.3v* + +### `digitalRead(pin)` + +This function returns the value read at the given pin. It will be `HIGH` (1) or `LOW` (0) depending on the logic level at the pin. + +### `digitalWrite(pin, state)` + +Write the value `HIGH` (1) or `LOW` (0) to the given pin which must have been previously set as an output. WiringPi treats any non-zero number as `HIGH`, however 0 is the only representation of `LOW`. + +`state` can be one of the following value: + +* `HIGH` +* `LOW` + +### `pwmWrite(pin, value)` + +Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024]. Other PWM devices may have other PWM ranges. This function is not able to control the Pi's on-board PWM when in Sys mode. + +`value` must be in range of [0, 1024] + +### `analogRead(pin)` + >= 1.0.0 + +This returns the value read on the supplied analog input pin. You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc. + +### `analogWrite(pin, value)` + >= 1.0.0 + +This writes the given value to the supplied analog pin. You will need to register additional analog modules to enable this function for devices such as the Gertboard. + +### `pulseIn(pin, state)` + >= 1.1.0 + +`state` can be one of the following values: + +* `HIGH` +* `LOW` + +### `delay(milliseconds)` + >= 1.1.0 + +### `delayMicroseconds(microseconds)` + >= 1.1.0 + +### `millis()` + >= 1.1.0 + +### `micros()` + >= 1.1.0 + +--- + +## Raspberry Pi hardware specific functions + +### `piBoardRev()` + +This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. + +### `piBoardId()` + >= 1.1.0 + +### `wpiPinToGpio(pin)` + >= 1.0.0 + +This returns the BCM_GPIO pin number of the supplied wiringPi pin. It takes the board revision into account. + +### `physPinToGpio(pin)` + >= 1.0.0 + +This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector. + +### `setPadDrive(group, value)` + >= 1.0.0 + +This sets the "strength" of the pad drivers for a particular group of pins. There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you know what you are doing. + +### `getAlt(pin)` + >= 1.0.0 + +Returns the ALT bits for a given port. + +### `digitalWriteByte(byte)` + >= 1.0.0 + +This writes the 8-bit byte supplied to the first 8 GPIO pins. It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware. + +### `pwmSetMode(mode)` + >= 1.0.0 + +The PWM generator can run in 2 modes – “balanced” and “mark:space”. The mark:space mode is traditional, however the default mode in the Pi is “balanced”. + +`mode` can be one of the following values: + +* `PWM_MODE_BAL` *balanced* +* `PWM_MODE_MS` *mark:space* + +### `pwmSetRange(range)` + +This sets the range register in the PWM generator. The default is 1024. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. + +### `pwmSetClock(divisor)` + +This sets the divisor for the PWM clock. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. + +### `gpioClockSet(pin, frequency)` + >= 1.0.0 + +Set the frequency on a GPIO clock pin + +--- + +## I2C + +### `wiringPiI2CSetup(devId)` + >= 2.0.0 + +### `wiringPiI2CSetupInterface(device, devId)` + >= 2.0.0 + +### `wiringPiI2CRead(fd)` + >= 2.0.0 + +### `wiringPiI2CReadReg8(fd, reg)` + >= 2.0.0 + +### `wiringPiI2CReadReg16(fd, red)` + >= 2.0.0 + +### `wiringPiI2CWrite(fd, data)` + >= 2.0.0 + +### `wiringPiI2CWriteReg8(fd, reg, data)` + >= 2.0.0 + +### `wiringPiI2CWriteReg16(fd, reg, data)` + >= 2.0.0 + +--- + +## SPI + +### `wiringPiSPIGetFd(channel)` + >= 1.0.0 + +### `wiringPiSPIDataRW(channel, data)` + >= 1.0.0 + +### `wiringPiSPISetup(channel, speed)` + >= 1.0.0 + +--- + +## Serial + +### `serialOpen(device, baudrate)` + >= 1.0.0 + +### `serialClose(fd)` + >= 1.0.0 + +### `serialFlush(fd)` + >= 1.0.0 + +### `serialPutchar(fd, character)` + >= 1.0.0 + +### `serialPuts(fd, string)` + >= 1.0.0 + +### `serialPrintf(fd, string)` + + Alias: serialPuts + >= 2.0.0 + + +### `serialDataAvail(fd)` + >= 1.0.0 + +### `serialGetchar(fd)` + >= 1.0.0 + +--- + +## Shift + +### `shiftIn(dPin, cPin, order)` + >= 1.0.0 + +### `shiftOut(dPin, cPin, order, value)` + >= 1.0.0 + +--- + +## Soft PWM + +### `softPwmCreate(pin, value, range)` + >= 1.0.0 + +### `softPwmWrite(pin, value)` + >= 1.0.0 + +### `softPwmStop(pin)` + >= 1.1.0 + +--- + +## Soft Servo + +### `softServoWrite(pin, value)` + >= 1.0.0 + +### `softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7)` + >= 1.0.0 + +--- + +## Soft Tone + +### `softToneCreate(pin);` + >= 1.0.0 + +### `softToneWrite(pin, frequency);` + >= 1.0.0 + +### `softToneStop(pin);` + >= 1.1.0 + +--- + +## Extensions \ No newline at end of file diff --git a/README.md b/README.md index 2572085..0b563e9 100644 --- a/README.md +++ b/README.md @@ -1,258 +1,21 @@ -Node.js bindings to [wiringPi](https://projects.drogon.net/raspberry-pi/wiringpi/) +Node.js bindings to [wiringPi](http://www.wiringpi.com) Based on the awesome work of [Soarez](https://github.com/Soarez/node-wiring-pi) ## Install - > npm install wiring-pi - -## Use - -```javascript -var wpi = require('wiring-pi'); -``` -## Setup - -### `wpi.setup([mode])` - -An handy function to setup wiringPi - -```javascript -wpi.setup(); -``` - -```javascript -wpi.setup('gpio'); -``` - -Valid Modes: - -- `wpi`: sets up pin numbering with `wiringPiSetup` -- `gpio`: sets up pin numbers with `wiringPiSetupGpio` -- `sys`: sets up pin numbers with `wiringPiSetupSys` -- `phys`: sets up pin numbers with `wiringPiSetupPhys` - -See [wiringPi Pins](http://wiringpi.com/pins/) for the differences in Pin numbering; - -### `wpi.wiringPiSetup()` - -Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. -This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. -see the pins page (https://projects.drogon.net/raspberry-pi/wiringpi/pins/) for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. -This function needs to be called with root privileges. - -```javascript -wpi.wiringPisetup(); -``` - -### `wpi.wiringPiSetupGpio()` - -This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. -As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards. - -```javascript -wpi.wiringPisetupGpio(); -``` - -### `wpi.wiringPiSetupPhys()` - -Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. -As above, this function needs to be called with root priviliges. - -```javascript -wpi.wiringPisetupPhys(); ``` - -### `wpi.wiringPiSetupSys()` - -This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. -Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. -You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. -Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed). - -```javascript -wpi.wiringPisetupSys(); -``` - -## Core functions - -### `wpi.pinModeAlt(pin, mode)` - -This is an un-documented special to let you set any pin to any mode. - -- `pin`: pin number -- `mode`: `wpi.WPI_MODE_PINS`, `wpi.WPI_MODE_PHYS` or `wpi.WPI_MODE_GPIO` - -### `wpi.pinMode(pin, mode)` - -This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. -Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. -This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program. - -```javascript -wpi.pinMode(0, wpi.modes.OUTPUT); -``` - -- `pin`: pin number -- `mode`: `wpi.modes.INPUT`, `wpi.modes.OUTPUT`, `wpi.modes.PWM_OUTPUT` or `wpi.modes.GPIO_CLOCK` - -### `wpi.pullUpDnControl(pin, pud)` - -This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. -The parameter pud should be; PUD_OFF (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP (pull to 3.3v). -The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. - -```javascript -wpi.pullUpDnControl(0, wpi.PUD_DOWN); +npm install wiring-pi ``` -- `pin`: pin number -- `pud`: `wpi.PUD_OFF`, `wpi.PUD_DOWN`, `wpi.PUD_UP` - -### `wpi.digitalRead(pin)` - -This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) depending on the logic level at the pin. - -```javascript -wpi.digitalRead(0); -//=> 1 -``` - -- `pin`: pin number - -### `wpi.digitalWrite(pin, value)` - -Write the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as an output. -WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW. - -```javascript -wpi.digitalWrite(0, wpi.HIGH); -``` +## Usage ```javascript -wpi.digitalWrite(0, wpi.LOW); -``` - -- `pin`: pin number -- `value`: 0 (`wpi.LOW`) or 1 (`wpi.HIGH`) - -### `wpi.pwmWrite(pin, value)` - -Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is 0-1024. -Other PWM devices may have other PWM ranges. -This function is not able to control the Pi's on-board PWM when in Sys mode. - -```javascript -wpi.pwmWrite(0, 512); -``` - -- `pin`: pin number -- `value`: value in PWM ranges - -### `wpi.analogRead(pin)` - -This returns the value read on the supplied analog input pin. You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc. - -```javascript -wpi.analogRead(0); -//=> 512 -``` - -- `pin`: pin number - -### `wpi.analogWrite(pin, value)` - -This writes the given value to the supplied analog pin. You will need to register additional analog modules to enable this function for devices such as the Gertboard. - -```javascript -wpi.analogWrite(0, 512); -``` - -- `pin`: pin number -- `value`: value - -## Raspberry Pi specifics - -### `wpi.piBoardRev()` - -This returns the board revision of the Raspberry Pi. It will be either 1 or 2. -Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. - -```javascript -wpi.piBoardRev(); -//=>2 -``` - -### `wpi.wpiPinToGpio(pin)` - -This returns the BCM_GPIO pin number of the supplied wiringPi pin. -It takes the board revision into account. - -```javascript -wpi.wpiPinToGpio(7); -//=>4 -``` - -- `pin`: pin number in WiringPi scheme - -### `wpi.physPinToGpio(pin)` - -This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector. - -```javascript -wpi.wpiPinToGpio(23); -//=>11 -``` - -- `pin`: pin number in physical scheme - -### `wpi.setPadDrive(group, value)` - -This sets the "strength" of the pad drivers for a particular group of pins. -There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you know what you are doing. - -### `wpi.getAlt(pin)` - -Returns the ALT bits for a given port. Only really of-use for the gpio readall command (I think). - -### `wpi.digitalWriteByte(value)` - -This writes the 8-bit byte supplied to the first 8 GPIO pins. -It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware. - -```javascript -wpi.digitalWriteByte(0xFF); //set the first 8 GPIO pins to HIGH -``` - -- `value`: the byte to write to the first 8 GPIO pins - -### `wpi.pwmSetMode(mode)` - -The PWM generator can run in 2 modes – “balanced” and “mark:space”. -The mark:space mode is traditional, however the default mode in the Pi is “balanced”. -You can switch modes by supplying the parameter: PWM_MODE_BAL or PWM_MODE_MS. - -```javascript -wpi.pwmSetMode(wpi.PWM_MODE_BAL); +var wpi = require('wiring-pi'); ``` +## Documentation -- `mode`: `wpi.PWM_MODE_BAL` or `wpi.PWM_MODE_MS` - -### `wpi.pwmSetRange(range)` - -This sets the range register in the PWM generator. The default is 1024. -Note: The PWM control functions can not be used when in Sys mode. -To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. - -### `wpi.pwmSetClock(divisor)` - -This sets the divisor for the PWM clock. -Note: The PWM control functions can not be used when in Sys mode. -To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. - -### `wpi.gpioClockSet(pin, freq)` - -Set the frequency on a GPIO clock pin +See the [DOCUMENTATION.md](https://github.com/eugeneware/wiring-pi/blob/master/DOCUMENTATION.md) file for more detailed documentation. ## Contributing @@ -266,8 +29,8 @@ See the [CONTRIBUTING.md](https://github.com/eugeneware/wiring-pi/blob/master/CO wiring-pi is only possible due to the excellent work of the following contributors: - - - - -
Igor Soarez (Creator)GitHub/SoarezTwitter/@igorsoarez
Gohy LeandreGitHub/nekuz0rTwitter/@LeandreGohy
Eugene WareGitHub/eugenewareTwitter/@eugeneware
+Contributor | GitHub profile | Twitter profile | +--- | --- | --- +Igor Soarez (Creator) | [Soarez](https://github.com/Soarez) | [@igorsoarez](https://twitter.com/igorsoarez) +Leandre Gohy | [nekuz0r](https://github.com/nekuz0r) | [@LeandreGohy](http://twitter.com/LeandreGohy) +Eugene Ware | [eugeneware](https://github.com/eugeneware) | [@eugeneware](http://twitter.com/eugeneware) diff --git a/binding.gyp b/binding.gyp index 8b110d9..b22d142 100644 --- a/binding.gyp +++ b/binding.gyp @@ -3,7 +3,16 @@ { 'target_name': 'wiringPi', 'sources': [ - 'src/bindings.cc' + 'src/wiringPi.cc', + 'src/softPwm.cc', + 'src/softServo.cc', + 'src/softTone.cc', + 'src/wiringPiI2C.cc', + 'src/wiringPiSPI.cc', + 'src/wiringSerial.cc', + 'src/wiringShift.cc', + 'src/wiringPiISR.cc', + 'src/wpi.cc' ], 'include_dirs': [ 'wiringpi/wiringPi' @@ -12,7 +21,18 @@ '", "contributors": [ - "Leandre Gohy " + "Leandre Gohy ", + "Eugene Ware " ], "license": "BSD" } diff --git a/src/addon.h b/src/addon.h new file mode 100644 index 0000000..fb326d2 --- /dev/null +++ b/src/addon.h @@ -0,0 +1,150 @@ +#ifndef _ADDON_H_ +#define _ADDON_H_ + + #include + #include + #include + #include + #include + #include + #include + + using namespace v8; + + template + struct type_of_size { typedef char type[N]; }; + + template + char (&sizeof_array_helper(T(&)[size]))[size]; + + #define sizeof_array(array) sizeof(sizeof_array_helper(array)) + + template + void ThrowError(T func, const char* format, ...) { + char buffer[256]; + va_list args; + va_start(args, format); + vsnprintf(buffer, 156, format, args); + va_end(args); + + ThrowException(func(String::New(buffer))); + } + + template + bool isInList(T value, std::initializer_list values) { + return !(std::find(values.begin(), values.end(), value) == values.end()); + } + + #define DECLARE(name) \ + namespace nodemodule { \ + static Handle name(const Arguments& args); \ + } + + #define IMPLEMENT(name) \ + Handle nodemodule::name(const Arguments& args) + + #define EXPORT_FUNCTION(name) \ + target->Set(String::NewSymbol(#name), \ + FunctionTemplate::New(nodemodule::name)->GetFunction()) + + #define EXPORT_CONSTANT_INT(name) \ + target->Set(String::NewSymbol(#name), \ + Int32::New(name), static_cast(ReadOnly | DontDelete)); + + #define EXPORT_CONSTANT_STRING(name) \ + target->Set(String::NewSymbol(#name), \ + String::New(name), static_cast(ReadOnly | DontDelete)); + + #define EXPORT_CONSTANT_INT_ARRAY(name, array, length) \ + { \ + Local arr = Array::New(); \ + for (int i = 0; i < length; i++) { \ + arr->Set(i, INT32(array[i])); \ + } \ + target->Set(String::NewSymbol(#name), arr, static_cast(ReadOnly | DontDelete)); \ + } + + #define EXPORT_CONSTANT_STRING_ARRAY(name, array, length) \ + { \ + Local arr = Array::New(); \ + for (int i = 0; i < length; i++) { \ + arr->Set(i, STRING(array[i])); \ + } \ + target->Set(String::NewSymbol(#name), arr, static_cast(ReadOnly | DontDelete)); \ + } + + #define NODE_MODULE_INIT() \ + namespace nodemodule { \ + void init(Handle target); \ + } \ + void nodemodule::init(Handle target) + #define NODE_MODULE_DECLARE(name) NODE_MODULE(name, nodemodule::init) + #define IMPLEMENT_EXPORT_INIT(name) void nodemodule::init##name(Handle target) + #define DECLARE_EXPORT_INIT(name) \ + namespace nodemodule { \ + void init##name(Handle target); \ + } + + #define INIT(name) nodemodule::init##name(target); + + #define SCOPE_OPEN() HandleScope scope + #define SCOPE_CLOSE(obj) return scope.Close(obj) + + #define UNDEFINED() Undefined() + #define INT32(v) Int32::New(v) + #define UINT32(v) Uint32::New(v) + #define STRING(v) String::New(v) + + #define THROW_ERROR(fmt, ...) \ + ThrowError(Exception::Error, fmt, __VA_ARGS__); \ + SCOPE_CLOSE(UNDEFINED()) + + #define THROW_TYPE_ERROR(fmt, ...) \ + ThrowError(Exception::TypeError, fmt, __VA_ARGS__); \ + SCOPE_CLOSE(UNDEFINED()) + + #define SET_ARGUMENT_NAME(id, name) static const char* arg##id = #name + #define GET_ARGUMENT_NAME(id) arg##id + + #define CHECK_ARGUMENTS_LENGTH_EQUAL(length) \ + if (args.Length() != length) { \ + THROW_ERROR("%s: arguments.length => (%i === %i) === false", __func__, args.Length(), length); \ + } + + #define CHECK_ARGUMENT_TYPE(id, istype) \ + if (!args[id]->istype()) { \ + THROW_ERROR("%s: %s(%s) === false", __func__, #istype, GET_ARGUMENT_NAME(id)); \ + } + + #define CHECK_ARGUMENT_TYPE_INT32(id) CHECK_ARGUMENT_TYPE(id, IsInt32) + #define CHECK_ARGUMENT_TYPE_UINT32(id) CHECK_ARGUMENT_TYPE(id, IsUint32) + #define CHECK_ARGUMENT_TYPE_NUMBER(id) CHECK_ARGUMENT_TYPE(id, IsNumber) + #define CHECK_ARGUMENT_TYPE_STRING(id) CHECK_ARGUMENT_TYPE(id, IsString) + #define CHECK_ARGUMENT_TYPE_FUNCTION(id) CHECK_ARGUMENT_TYPE(id, IsFunction) + #define CHECK_ARGUMENT_TYPE_OBJECT(id) CHECK_ARGUMENT_TYPE(id, IsObject) + #define CHECK_ARGUMENT_TYPE_NODE_BUFFER(id) \ + if (!(args[id]->IsObject() && node::Buffer::HasInstance(args[id]))) { \ + THROW_ERROR("%s: %s(%s) === false", __func__, "isBuffer", GET_ARGUMENT_NAME(id)); \ + } + + #define GET_ARGUMENT_AS_TYPE(id, type) args[id]->type() + + #define GET_ARGUMENT_AS_INT32(id) GET_ARGUMENT_AS_TYPE(id, Int32Value) + #define GET_ARGUMENT_AS_UINT32(id) GET_ARGUMENT_AS_TYPE(id, Uint32Value) + #define GET_ARGUMENT_AS_NUMBER(id) GET_ARGUMENT_AS_TYPE(id, NumberValue) + #define GET_ARGUMENT_AS_STRING(id) GET_ARGUMENT_AS_TYPE(id, ToString) + #define GET_ARGUMENT_AS_LOCAL_FUNCTION(id) Local::Cast(args[id]) + #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) + + #define LIST(...) { __VA_ARGS__ } + #define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ + if (!isInList(std::string(*value), LIST T)) { \ + THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ + } + + #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ + if (!isInList(value, LIST T)) { \ + THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ + } + +#endif \ No newline at end of file diff --git a/src/bindings.cc b/src/bindings.cc deleted file mode 100644 index 73d725b..0000000 --- a/src/bindings.cc +++ /dev/null @@ -1,2501 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace v8; - -#define DECLARE(name) \ - static Handle name(const Arguments& args) -#define IMPLEMENT(name) \ - Handle wpi::name(const Arguments& args) -#define EXPORT(name) \ - target->Set(String::NewSymbol(#name), \ - FunctionTemplate::New(wpi::name)->GetFunction()) - -namespace wpi { - // Setup - DECLARE(wiringPiSetup); - DECLARE(wiringPiSetupGpio); - DECLARE(wiringPiSetupSys); - DECLARE(wiringPiSetupPhys); - - // Core wiringPi functions - DECLARE(pinModeAlt); - DECLARE(pinMode); - DECLARE(pullUpDnControl); - DECLARE(digitalRead); - DECLARE(digitalWrite); - DECLARE(pwmWrite); - DECLARE(analogRead); - DECLARE(analogWrite); - DECLARE(pulseIn); - - DECLARE(delay); - DECLARE(delayMicroseconds); - DECLARE(millis); - DECLARE(micros); - - // PiFace specifics (Deprecated) - //DECLARE(wiringPiSetupPiFace); - //DECLARE(wiringPiSetupPiFaceForGpioProg); // Don't use this - for gpio program only - - // On-Board Rasberry Pi hardware specific stuff - DECLARE(piBoardRev); - DECLARE(piBoardId); - DECLARE(wpiPinToGpio); - DECLARE(physPinToGpio); - DECLARE(setPadDrive); - DECLARE(getAlt); - DECLARE(digitalWriteByte); - DECLARE(pwmSetMode); - DECLARE(pwmSetRange); - DECLARE(pwmSetClock); - DECLARE(gpioClockSet); - - // Extensions - DECLARE(drcSetupSerial); - DECLARE(max5322Setup); - DECLARE(max31855Setup); - DECLARE(mcp23s08Setup); - DECLARE(mcp23s17Setup); - DECLARE(mcp3002Setup); - DECLARE(mcp3004Setup); - DECLARE(mcp3422Setup); - DECLARE(mcp4802Setup); - DECLARE(mcp23008Setup); - DECLARE(mcp23016Setup); - DECLARE(mcp23017Setup); - DECLARE(pcf8574Setup); - DECLARE(pcf8591Setup); - DECLARE(sn3218Setup); - DECLARE(sr595Setup); - DECLARE(pca9685Setup); - - // Soft PWM - DECLARE(softPwmCreate); - DECLARE(softPwmWrite); - DECLARE(softPwmStop); - - // Soft Servo - DECLARE(softServoWrite); - DECLARE(softServoSetup); - - // Soft Tone - DECLARE(softToneCreate); - DECLARE(softToneWrite); - DECLARE(softToneStop); - - // WiringPI I2C - DECLARE(wiringPiI2CRead); - DECLARE(wiringPiI2CReadReg8); - DECLARE(wiringPiI2CReadReg16); - DECLARE(wiringPiI2CWrite); - DECLARE(wiringPiI2CWriteReg8); - DECLARE(wiringPiI2CWriteReg16); - DECLARE(wiringPiI2CSetupInterface); - DECLARE(wiringPiI2CSetup); - - // WiringPI SPI - DECLARE(wiringPiSPIGetFd); - DECLARE(wiringPiSPIDataRW); - DECLARE(wiringPiSPISetup); - - // WiringPi Serial - DECLARE(serialOpen); - DECLARE(serialClose); - DECLARE(serialFlush); - DECLARE(serialPutchar); - DECLARE(serialPuts); - DECLARE(serialPrintf); - DECLARE(serialDataAvail); - DECLARE(serialGetchar); - - // WiringPi Shift - DECLARE(shiftIn); - DECLARE(shiftOut); -} - -// === Setup === - -// Func : int wiringPiSetup(void) -// Returns : error code if v1 mode otherwise always returns 0 -// Description : Initialises wiringPi and assumes that the calling program is going -// to be using the wiringPi pin numbering scheme. -// This is a simplified numbering scheme which provides a mapping from virtual -// pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. -// see the pins page (https://projects.drogon.net/raspberry-pi/wiringpi/pins/) for a table -// which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location -// on the edge connector. -// This function needs to be called with root privileges. - -IMPLEMENT(wiringPiSetup) { - HandleScope scope; - int res; - - // CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSetup(); - - return scope.Close(Int32::New(res)); -} - -// Func : int wiringPiSetupGpio(void) -// Returns : error code if v1 mode otherwise always returns 0 -// Description : This is indential to above, however it allows the calling programs to use -// the Broadcom GPIO pin numbers directly with no re-mapping. -// As above, this function needs to be called with root privileges, and note that some pins -// are different from revision 1 to revision 2 boards. - -IMPLEMENT(wiringPiSetupGpio) { - HandleScope scope; - int res; - - // CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSetupGpio(); - - return scope.Close(Int32::New(res)); -} - -// Func : int wiringPiSetupPhys(void) -// Returns : error code if v1 mode otherwise always returns 0 -// Description : Identical to above, however it allows the calling programs to use -// the physical pin numbers on the P1 connector only. -// As above, this function needs to be called with root priviliges. - -IMPLEMENT(wiringPiSetupPhys) { - HandleScope scope; - int res; - - // CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSetupPhys(); - - return scope.Close(Int32::New(res)); -} - -// Func : int wiringPiSetupSys(void) -// Returns : error code if v1 mode otherwise always returns 0 -// Description : This initialises wiringPi but uses the /sys/class/gpio interface rather than -// accessing the hardware directly. This can be called as a non-root user provided the GPIO pins -// have been exported before-hand using gpio program. Pin numbering in this mode is the native -// Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences -// between Rev 1 and Rev 2 boards. -// Note: In this mode you can only use the pins which have been exported via the -// /sys/class/gpio interface before you run your program. You can do this in a seperate -// shell script, or by using the system() function from inside your program to call the gpio program. -// Also note that some functions have no effect when using this mode as they're not currently -// possible to action unless called with root privileges. (although you can use system() to call -// gpio to set/change modes if needed). - -IMPLEMENT(wiringPiSetupSys) { - HandleScope scope; - int res; - - // CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSetupSys(); - - return scope.Close(Int32::New(res)); -} - -// === Core functions === - -// Func : void pinModeAlt(int pin, int mode) -// Description : This is an un-documented special to let you set any pin to any mode. -// Modes are WPI_MODE_PINS, WPI_MODE_PHYS, WPI_MODE_GPIO. - -IMPLEMENT(pinModeAlt) { - HandleScope scope; - int pin; - int mode; - - // CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - mode = args[1]->NumberValue(); - - // CHECK: Allowed values - if (mode != WPI_MODE_PINS && mode != WPI_MODE_PHYS && mode != WPI_MODE_GPIO) { - ThrowException(Exception::TypeError( - String::New("Incorrect mode value. WPI_MODE_PINS, WPI_MODE_PHYS or WPI_MODE_GPIO expected."))); - return scope.Close(Undefined()); - } - - ::pinModeAlt(pin, mode); - - return scope.Close(Undefined()); -} - -// Func : void pinMode(int pin, int mode) -// Description : This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. -// Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) -// supports CLOCK output modes. -// This function has no effect when in Sys mode. If you need to change the pin mode, the you can -// do it with the gpio program in a script before you start your program. - -IMPLEMENT(pinMode) { - HandleScope scope; - int mode; - int pin; - - // CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - mode = args[1]->NumberValue(); - - // CHECK: Allowed values - if (mode != INPUT && mode != OUTPUT && mode != PWM_OUTPUT && mode != GPIO_CLOCK) { - ThrowException(Exception::TypeError( - String::New("Incorrect mode value. INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK expected."))); - return scope.Close(Undefined()); - } - - ::pinMode(pin, mode); - - return scope.Close(Undefined()); -} - -// Func : void pullUpDnControl(int pin, int pud) -// Description : This sets the pull-up or pull-down resistor mode on the given pin, which should be set -// as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. -// The parameter pud should be; PUD_OFF (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP (pull to 3.3v). -// The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. - -IMPLEMENT(pullUpDnControl) { - HandleScope scope; - int pin; - int pud; - - // CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - pud = args[1]->NumberValue(); - - // CHECK: Allowed values - if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP) { - ThrowException(Exception::TypeError( - String::New("Incorrect mode value. PUD_OFF, PUD_DOWN or PUD_UP expected."))); - return scope.Close(Undefined()); - } - - ::pullUpDnControl(pin, pud); - - return scope.Close(Undefined()); -} - -// Func : int digitalRead(int pin) -// Description : This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) -// depending on the logic level at the pin. - -IMPLEMENT(digitalRead) { - HandleScope scope; - int pin; - int res; - - // CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - res = ::digitalRead(pin); - - // Make sure the function returns strictly 1 or 0 - // §4.7/4 from the C++ Standard says (Integral Conversion) - // If the source type is bool, the value false is converted to zero and the value true is converted to one. - res = (res != 0); - - return scope.Close(Int32::New(res)); -} - -// Func : void digitalWrite(int pin, int value) -// Description : Write the value HIGH or LOW (1 or 0) to the given pin which must have been -// previously set as an output. -// WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW. - -IMPLEMENT(digitalWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - value = args[1]->NumberValue(); - - // Make sure value is strictly 1 or 0 - // §4.7/4 from the C++ Standard says (Integral Conversion) - // If the source type is bool, the value false is converted to zero and the value true is converted to one. - value = (value != 0); - - ::digitalWrite(pin, value); - - return scope.Close(Undefined()); -} - -// Func : void pwmWrite(int pin, int value) -// Description : Writes the value to the PWM register for the given pin. The Raspberry Pi has -// one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is 0-1024. Other PWM -// devices may have other PWM ranges. -// This function is not able to control the Pi's on-board PWM when in Sys mode. - -IMPLEMENT(pwmWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - value = args[1]->NumberValue(); - - ::pwmWrite(pin, value); - - return scope.Close(Undefined()); -} - -// Func : int analogRead(int pin) -// Description : This returns the value read on the supplied analog input pin. You will need to -// register additional analog modules to enable this function for device such as the Gertboard, -// quick2Wire analog board, etc. - -IMPLEMENT(analogRead) { - HandleScope scope; - int pin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - res = ::analogRead(pin); - - return scope.Close(Int32::New(res)); -} - -// Func : void analogWrite(int pin, int value) -// Description : This writes the given value to the supplied analog pin. You will need to register -// additional analog modules to enable this function for devices such as the Gertboard. - -IMPLEMENT(analogWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - value = args[1]->NumberValue(); - - ::analogWrite(pin, value); - - return scope.Close(Undefined()); -} - -IMPLEMENT(pulseIn) { - HandleScope scope; - int pin; - int state; - int microseconds; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - state = args[1]->NumberValue(); - - microseconds = ::pulseIn(pin, state); - - return scope.Close(Int32::New(microseconds)); -} - -IMPLEMENT(delay) { - HandleScope scope; - unsigned int howLong; - - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - howLong = args[0]->Uint32Value(); - - ::delay(howLong); - - return scope.Close(Undefined()); -} - -IMPLEMENT(delayMicroseconds) { - HandleScope scope; - unsigned int howLong; - - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - howLong = args[0]->Uint32Value(); - - ::delay(howLong); - - return scope.Close(Undefined()); -} - -IMPLEMENT(millis) { - HandleScope scope; - - unsigned int ms = ::millis(); - - return scope.Close(Uint32::New(ms)); -} - -IMPLEMENT(micros) { - HandleScope scope; - - unsigned int us = ::micros(); - - return scope.Close(Uint32::New(us)); -} - -// === Raspberry Pi specific === - -// Func : int piBoardRev(void) -// Description : This returns the board revision of the Raspberry Pi. It will be either 1 or 2. -// Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, -// so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. - -IMPLEMENT(piBoardRev) { - HandleScope scope; - int res; - - //CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::piBoardRev(); - - return scope.Close(Int32::New(res)); -} - -IMPLEMENT(piBoardId) { - HandleScope scope; - int model; - int rev; - int mem; - char* marker; - - //CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - ::piBoardId(&model, &rev, &mem, &marker); - - Local obj = Object::New(); - obj->Set(String::NewSymbol("model"), Int32::New(model)); - obj->Set(String::NewSymbol("rev"), Int32::New(rev)); - obj->Set(String::NewSymbol("mem"), Int32::New(mem)); - obj->Set(String::NewSymbol("marker"), String::New(marker)); - - return scope.Close(obj); -} - -// Func : int wpiPinToGpio(int wpiPin) -// Description : This returns the BCM_GPIO pin number of the supplied wiringPi pin. -// It takes the board revision into account. - -IMPLEMENT(wpiPinToGpio) { - HandleScope scope; - int wpiPin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - wpiPin = args[0]->NumberValue(); - res = ::wpiPinToGpio(wpiPin); - - return scope.Close(Int32::New(res)); -} - -// Func : int physPinToGpio (int physPin) -// Description : This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector. - -IMPLEMENT(physPinToGpio) { - HandleScope scope; - int physPin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - physPin = args[0]->NumberValue(); - res = ::physPinToGpio(physPin); - - return scope.Close(Int32::New(res)); -} - -// Func : void setPadDrive(int group, int value) -// Description : This sets the "strength" of the pad drivers for a particular group of pins. -// There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you -// know what you are doing. - -IMPLEMENT(setPadDrive) { - HandleScope scope; - int group; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - group = args[0]->NumberValue(); - value = args[1]->NumberValue(); - ::setPadDrive(group, value); - - return scope.Close(Undefined()); -} - -// Func : int getAlt(int pin) -// Description : Returns the ALT bits for a given port. Only really of-use -// for the gpio readall command (I think). - -IMPLEMENT(getAlt) { - HandleScope scope; - int pin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - res = ::getAlt(pin); - - return scope.Close(Int32::New(res)); -} - -// Func : void digitalWriteByte(int value) -// Description : This writes the 8-bit byte supplied to the first 8 GPIO pins. -// It’s the fastest way to set all 8 bits at once to a particular value, although it still takes -// two write operations to the Pi’s GPIO hardware. - -IMPLEMENT(digitalWriteByte) { - HandleScope scope; - int value; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - value = args[0]->NumberValue(); - ::digitalWriteByte(value); - - return scope.Close(Undefined()); -} - -// Func : void pwmSetMode(int mode) -// Description : The PWM generator can run in 2 modes – “balanced” and “mark:space”. -// The mark:space mode is traditional, however the default mode in the Pi is “balanced”. -// You can switch modes by supplying the parameter: PWM_MODE_BAL or PWM_MODE_MS. - -IMPLEMENT(pwmSetMode) { - HandleScope scope; - int mode; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - mode = args[0]->NumberValue(); - - //CHECK: Allowed values - if (mode != PWM_MODE_BAL && mode != PWM_MODE_MS) { - ThrowException(Exception::TypeError( - String::New("Incorrect mode value. PWM_MODE_BAL or PWM_MODE_MS expected."))); - return scope.Close(Undefined()); - } - - ::pwmSetMode(mode); - - return scope.Close(Undefined()); -} - -// Func : void pwmSetRange(unsigned int range) -// Description : This sets the range register in the PWM generator. The default is 1024. -// Note: The PWM control functions can not be used when in Sys mode. To understand more about -// the PWM system, you’ll need to read the Broadcom ARM peripherals manual. - -IMPLEMENT(pwmSetRange) { - HandleScope scope; - unsigned int range; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - range = args[0]->Uint32Value(); - ::pwmSetRange(range); - - return scope.Close(Undefined()); -} - -// Func : void pwmSetClock(int divisor) -// Description : This sets the divisor for the PWM clock. -// Note: The PWM control functions can not be used when in Sys mode. To understand more about -// the PWM system, you’ll need to read the Broadcom ARM peripherals manual. - -IMPLEMENT(pwmSetClock) { - HandleScope scope; - int divisor; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - divisor = args[0]->NumberValue(); - ::pwmSetClock(divisor); - - return scope.Close(Undefined()); -} - -// Func : void gpioClockSet(int pin, int freq) -// Description : Set the frequency on a GPIO clock pin - -IMPLEMENT(gpioClockSet) { - HandleScope scope; - int pin; - int freq; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - freq = args[1]->NumberValue(); - ::gpioClockSet(pin, freq); - - return scope.Close(Undefined()); -} - -// === Extensions === - -// Func : int drcSetupSerial(const int pinBase, const int numPins, const char* device, const int baud) -// Description : https://projects.drogon.net/drogon-remote-control/drc-protocol-arduino/ - -IMPLEMENT(drcSetupSerial) { - HandleScope scope; - int pinBase; - int numPins; - const char* device; - int baud; - int res; - - //CHECK: Number of argument - if (args.Length() != 4) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsString() || !args[3]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - numPins = args[1]->Int32Value(); - v8::String::AsciiValue deviceString(args[2]->ToString()); - device = *deviceString; - baud = args[3]->Int32Value(); - - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::drcSetupSerial(pinBase, numPins, device, baud); - - return scope.Close(Int32::New(res)); -} - -// Func : int max5233Setup(int pinBase, int spiChannel) - -IMPLEMENT(max5322Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::max5322Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func : int max31855Setup(int pinBase, int spiChannel) - -IMPLEMENT(max31855Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::max31855Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func int mcp23s08Setup(const int pinBase, const int spiPort, const int devId) - -IMPLEMENT(mcp23s08Setup) { - HandleScope scope; - int pinBase; - int spiPort; - int devId; - int res; - - //CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->NumberValue(); - spiPort = args[1]->NumberValue(); - devId = args[2]->NumberValue(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiPort != 0 && spiPort != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiPort value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - //MCP23S08 3bits addressing - if (devId < 0 || devId > 7) { - ThrowException(Exception::TypeError( - String::New("Incorrect devId value. Value from 0 to 7 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23s08Setup(pinBase, spiPort, devId); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp23s17Setup(int pinBase, int spiPort, int devId) -// Description : Initialise libWiringPi to be used with MCP23S17 -// pinBase is any number above 64 that doesn’t clash with any other wiringPi expansion module, -// spiPort is 0 or 1 for one of the two SPI ports on the Pi and devId is the ID of that MCP23s17 on the SPI port. - -IMPLEMENT(mcp23s17Setup) { - HandleScope scope; - int pinBase; - int spiPort; - int devId; - int res; - - //CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->NumberValue(); - spiPort = args[1]->NumberValue(); - devId = args[2]->NumberValue(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiPort != 0 && spiPort != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiPort value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - //MCP23S17 3bits addressing - if (devId < 0 || devId > 7) { - ThrowException(Exception::TypeError( - String::New("Incorrect devId value. Value from 0 to 7 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23s17Setup(pinBase, spiPort, devId); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp3002Setup(int pinBase, int spiChannel) - -IMPLEMENT(mcp3002Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp3002Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp3004Setup(int pinBase, int spiChannel) - -IMPLEMENT(mcp3004Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp3004Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp3422Setup(int pinBase, int i2cAddress, int sampleRate, int gain) - -IMPLEMENT(mcp3422Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int sampleRate; - int gain; - int res; - - //CHECK: Number of argument - if (args.Length() != 4) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - sampleRate = args[2]->Int32Value(); - gain = args[3]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (sampleRate < 0 || sampleRate > 3) { - ThrowException(Exception::TypeError( - String::New("Incorrect sampleRate value. MCP3422_SR_3_75, MCP3422_SR_15, MCP3422_SR_60 or MCP3422_SR_240 expected."))); - return scope.Close(Undefined()); - } - - if (gain < 0 || gain > 3) { - ThrowException(Exception::TypeError( - String::New("Incorrect gain value. MCP3422_GAIN_1, MCP3422_GAIN_2, MCP3422_GAIN_3 or MCP3422_GAIN_4 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp3422Setup(pinBase, i2cAddress, sampleRate, gain); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp4802Setup(int pinBase, int spiChannel) - -IMPLEMENT(mcp4802Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp4802Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp23008Setup(int pinBase, int i2cAddress) - -IMPLEMENT(mcp23008Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23008Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp23016Setup(const int pinBase, const int i2cAddress) - -IMPLEMENT(mcp23016Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23016Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp23017Setup(const int pinBase, const int i2cAddress) - -IMPLEMENT(mcp23017Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23017Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int pcf8574Setup(const int pinBase, const int i2cAddress) - -IMPLEMENT(pcf8574Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::pcf8574Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int pcf8591Setup(const int pinBase, const int i2cAddress) - -IMPLEMENT(pcf8591Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::pcf8591Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int sn3128Setup(int pinBase) - -IMPLEMENT(sn3218Setup) { - HandleScope scope; - int pinBase; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::sn3218Setup(pinBase); - - return scope.Close(Int32::New(res)); -} - -// Func : int sr595Setup(const int pinBase, const int numPins, const int dataPin, const int clockPin, const int latchPin) - -IMPLEMENT(sr595Setup) { - HandleScope scope; - int pinBase; - int numPins; - int dataPin; - int clockPin; - int latchPin; - int res; - - //CHECK: Number of argument - if (args.Length() != 5) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - numPins = args[1]->Int32Value(); - dataPin = args[2]->Int32Value(); - clockPin = args[3]->Int32Value(); - latchPin = args[4]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin); - - return scope.Close(Int32::New(res)); -} - -IMPLEMENT(pca9685Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int freq; - int res; - - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect arguments type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - freq = args[2]->Int32Value(); - - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected"))); - return scope.Close(Undefined()); - } - - res = ::pca9685Setup(pinBase, i2cAddress, freq); - - return scope.Close(Int32::New(res)); -} - -// === Soft PWM === - -// Func : int softPwmCreate(int pin, int value, int range) -// Description : This creates a software controlled PWM pin. -// You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. -// Use 100 for the pwmRange, then the value can be anything from 0 (off) to 100 (fully on) for the given pin. -// The return value is 0 for success. Anything else and you should check the global errno variable to see what went wrong. -// NOTE : You must initialise wiringPi with one of wiringPiSetup(), wiringPiSetupGpio() or wiringPiSetupPhys() functions. -// wiringPiSetupSys() is not fast enough, so you must run your programs with sudo. -// NOTE2 : Each “cycle” of PWM output takes 10mS with the default range value of 100, -// so trying to change the PWM value more than 100 times a second will be futile. -// NOTE3 : Each pin activated in softPWM mode uses approximately 0.5% of the CPU. -// NOTE4 : There is currently no way to disable softPWM on a pin while the program in running. -// NOTE5 : You need to keep your program running to maintain the PWM output! - -IMPLEMENT(softPwmCreate) { - HandleScope scope; - int pin; - int value; - int range; - int res; - - //CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - value = args[1]->Int32Value(); - range = args[2]->Int32Value(); - - res = ::softPwmCreate(pin, value, range); - - return scope.Close(Int32::New(res)); -} - -// Func void softPwmWrite(int pin, int value) -// Description : This updates the PWM value on the given pin. -// The value is checked to be in-range and pins that haven’t previously been initialised via softPwmCreate will be silently ignored. - -IMPLEMENT(softPwmWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - value = args[1]->Int32Value(); - - ::softPwmWrite(pin, value); - - return scope.Close(Undefined()); -} - -IMPLEMENT(softPwmStop) { - HandleScope scope; - int pin; - - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - - ::softPwmStop(pin); - - return scope.Close(Undefined()); -} - -// === Soft Servo === - -// Func : void softServoWrite(int pin, int value) -// Description : Write a Servo value to the given pin - -IMPLEMENT(softServoWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - value = args[1]->Int32Value(); - - ::softServoWrite(pin, value); - - return scope.Close(Undefined()); -} - -// Func : int softServoSetup(int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) -// Description : Setup the software servo system - -IMPLEMENT(softServoSetup) { - HandleScope scope; - int p0; - int p1; - int p2; - int p3; - int p4; - int p5; - int p6; - int p7; - int res; - - //CHECK: Number of argument - if (args.Length() != 8) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() - || !args[4]->IsNumber() || !args[5]->IsNumber() || !args[6]->IsNumber() || !args[7]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - p0 = args[0]->Int32Value(); - p1 = args[1]->Int32Value(); - p2 = args[2]->Int32Value(); - p3 = args[3]->Int32Value(); - p4 = args[4]->Int32Value(); - p5 = args[5]->Int32Value(); - p6 = args[6]->Int32Value(); - p7 = args[7]->Int32Value(); - - res = ::softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7); - - return scope.Close(Int32::New(res)); -} - -// === Soft Tone === - -// Func : int softToneCreate(int pin); -// Description : This creates a software controlled tone pin. -// You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. -// The return value is 0 for success. -// Anything else and you should check the global errno variable to see what went wrong. -// NOTE : You must initialise wiringPi with one of wiringPiSetup(), wiringPiSetupGpio() or wiringPiSetupPhys() functions. -// wiringPiSetupSys() is not fast enough, so you must run your programs with sudo. -// NOTE2 : Each pin activated in softTone mode uses approximately 0.5% of the CPU. -// NOTE3 : You need to keep your program running to maintain the sound output! - -IMPLEMENT(softToneCreate) { - HandleScope scope; - int pin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - - res = ::softToneCreate(pin); - - return scope.Close(Int32::New(res)); -} - -// Func : void softToneWrite(int pin, int freq); -// Description : This updates the tone frequency value on the given pin. The tone will be played until you set the frequency to 0. - -IMPLEMENT(softToneWrite) { - HandleScope scope; - int pin; - int freq; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - freq = args[1]->Int32Value(); - - ::softToneWrite(pin, freq); - - return scope.Close(Undefined()); -} - -IMPLEMENT(softToneStop) { - HandleScope scope; - int pin; - - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - - ::softToneStop(pin); - - return scope.Close(Undefined()); -} - -// === WiringPI I2C === - -IMPLEMENT(wiringPiI2CRead) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CReadReg8) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CReadReg16) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CWrite) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CWriteReg8) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CWriteReg16) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CSetupInterface) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CSetup) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -// === WiringPI SPI === - -// Func : int wiringPiSPIGetFd(int channel) - -IMPLEMENT(wiringPiSPIGetFd) { - HandleScope scope; - int channel; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - channel = args[0]->Int32Value(); - - // CHECK: Allowed values - if (channel != 0 || channel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect channel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSPIGetFd(channel); - - return scope.Close(Int32::New(res)); -} - -// Func : wiringPiSPIDataRW(int channel, unsigned char* data, int len) - -IMPLEMENT(wiringPiSPIDataRW) { - HandleScope scope; - int channel; - unsigned char* data; - int len; - int res; - - //CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsString() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type."))); - return scope.Close(Undefined()); - } - - channel = args[0]->Int32Value(); - v8::String::AsciiValue dataString(args[1]->ToString()); - data = (unsigned char*)*dataString; - len = args[2]->Int32Value(); - - // CHECK: Allowed values - if (channel != 0 || channel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect channel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSPIDataRW(channel, data, len); - - return scope.Close(Int32::New(res)); -} - -// Func : int wiringPiSPISetup(int channel, int speed) - -IMPLEMENT(wiringPiSPISetup) { - HandleScope scope; - int channel; - int speed; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - channel = args[0]->Int32Value(); - speed = args[1]->Int32Value(); - - // CHECK: Allowed values - if (channel != 0 || channel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect channel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSPISetup(channel, speed); - - return scope.Close(Int32::New(res)); -} - -// === WiringPi Serial === - -// Func : int serialOpen(const char* device, const int baud) - -IMPLEMENT(serialOpen) { - HandleScope scope; - const char* device; - int baud; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsString()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type."))); - return scope.Close(Undefined()); - } - - v8::String::AsciiValue deviceString(args[0]->ToString()); - device = *deviceString; - baud = args[1]->Int32Value(); - - res = ::serialOpen(device, baud); - - return scope.Close(Int32::New(res)); -} - -// Func : void serialClose(const int fd) - -IMPLEMENT(serialClose) { - HandleScope scope; - int fd; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - - ::serialClose(fd); - - return scope.Close(Undefined()); -} - -// Func : void serialFlush(const int fd); - -IMPLEMENT(serialFlush) { - HandleScope scope; - int fd; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - - ::serialFlush(fd); - - return scope.Close(Undefined()); -} - -// Func : void serialPutchar(const int fd, const unsigned char c) - -IMPLEMENT(serialPutchar) { - HandleScope scope; - int fd; - unsigned char c; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - c = (args[0]->Uint32Value() & 0xFF); - - ::serialPutchar(fd, c); - - return scope.Close(Undefined()); -} - -// Func : void serialPuts(const int fd, const char* s) - -IMPLEMENT(serialPuts) { - HandleScope scope; - int fd; - const char* s; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsString()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - v8::String::AsciiValue sString(args[0]->ToString()); - s = *sString; - - ::serialPuts(fd, s); - - return scope.Close(Undefined()); -} - -// Func : void serialPrintf(const int fd, const char* message, ...) - -IMPLEMENT(serialPrintf) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -// Func : int serialDataAvail(const int fd) - -IMPLEMENT(serialDataAvail) { - HandleScope scope; - int fd; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - - res = ::serialDataAvail(fd); - - return scope.Close(Int32::New(res)); -} - -// Func : int serialGetchar(const int fd) -// NOTE TO MYSELF : I don't understand why serialPutchar takes a unsigned char and on the other side -// serialGetchar returns a int ... serialGetchar should returns a unsigned char too. - -IMPLEMENT(serialGetchar) { - HandleScope scope; - int fd; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - - res = ::serialGetchar(fd); - - return scope.Close(Int32::New(res)); -} - -// === WiringPi Shift === - -// Func : uint8_t shiftIn(uint8_t dPin, uint8_t cPin, uint8_t order) -// Description : This shifts an 8-bit data value in with the data appearing on the dPin and the clock being sent out on the cPin. -// Order is either LSBFIRST or MSBFIRST. -// The data is sampled after the cPin goes high. -// (So cPin high, sample data, cPin low, repeat for 8 bits) The 8-bit value is returned by the function. - -IMPLEMENT(shiftIn) { - HandleScope scope; - uint8_t dPin; - uint8_t cPin; - uint8_t order; - uint8_t res; - - // CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - dPin = args[0]->Uint32Value(); - cPin = args[1]->Uint32Value(); - order = args[2]->Uint32Value(); - - // CHECK : Allowed values - if (order != LSBFIRST || order != MSBFIRST) { - ThrowException(Exception::TypeError( - String::New("Incorrect order value. LSBFIRT or MSBFIRST expected."))); - return scope.Close(Undefined()); - } - - res = ::shiftIn(dPin, cPin, order); - - return scope.Close(Uint32::New(res)); -} - -// Func : void shiftOut(uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; -// Description : The shifts an 8-bit data value val out with the data being sent out on dPin and the clock being sent out on the cPin. -// order is as above. -// Data is clocked out on the rising or falling edge – ie. dPin is set, then cPin is taken high then low – repeated for the 8 bits. - -IMPLEMENT(shiftOut) { - HandleScope scope; - uint8_t dPin; - uint8_t cPin; - uint8_t order; - uint8_t val; - - // CHECK: Number of argument - if (args.Length() != 4) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - dPin = args[0]->Uint32Value(); - cPin = args[1]->Uint32Value(); - order = args[2]->Uint32Value(); - val = args[3]->Uint32Value(); - - // CHECK : Allowed values - if (order != LSBFIRST || order != MSBFIRST) { - ThrowException(Exception::TypeError( - String::New("Incorrect order value. LSBFIRT or MSBFIRST expected."))); - return scope.Close(Undefined()); - } - - ::shiftOut(dPin, cPin, order, val); - - return scope.Close(Undefined()); -} - -void init(Handle target) { - // Setup - EXPORT(wiringPiSetup); - EXPORT(wiringPiSetupGpio); - EXPORT(wiringPiSetupSys); - EXPORT(wiringPiSetupPhys); - - // Core wiringPi functions - EXPORT(pinModeAlt); - EXPORT(pinMode); - EXPORT(pullUpDnControl); - EXPORT(digitalRead); - EXPORT(digitalWrite); - EXPORT(pwmWrite); - EXPORT(analogRead); - EXPORT(analogWrite); - EXPORT(pulseIn); - - EXPORT(delay); - EXPORT(delayMicroseconds); - EXPORT(millis); - EXPORT(micros); - - // PiFace specifics (Deprecated) - //EXPORT(wiringPiSetupPiFace); - //EXPORT(wiringPiSetupPiFaceForGpioProg); // Don't use this - for gpio program only - - // On-Board Rasberry Pi hardware specific stuff - EXPORT(piBoardRev); - EXPORT(piBoardId); - EXPORT(wpiPinToGpio); - EXPORT(physPinToGpio); - EXPORT(setPadDrive); - EXPORT(getAlt); - EXPORT(digitalWriteByte); - EXPORT(pwmSetMode); - EXPORT(pwmSetRange); - EXPORT(pwmSetClock); - EXPORT(gpioClockSet); - - // Extensions - EXPORT(drcSetupSerial); - EXPORT(max5322Setup); - EXPORT(max31855Setup); - EXPORT(mcp23s08Setup); - EXPORT(mcp23s17Setup); - EXPORT(mcp3002Setup); - EXPORT(mcp3004Setup); - EXPORT(mcp3422Setup); - EXPORT(mcp4802Setup); - EXPORT(mcp23008Setup); - EXPORT(mcp23016Setup); - EXPORT(mcp23017Setup); - EXPORT(pcf8574Setup); - EXPORT(pcf8591Setup); - EXPORT(sn3218Setup); - EXPORT(sr595Setup); - EXPORT(pca9685Setup); - - // Soft PWM - EXPORT(softPwmCreate); - EXPORT(softPwmWrite); - EXPORT(softPwmStop); - - // Soft Servo - EXPORT(softServoWrite); - EXPORT(softServoSetup); - - // Soft Tone - EXPORT(softToneCreate); - EXPORT(softToneWrite); - EXPORT(softToneStop); - - // WiringPI I2C - EXPORT(wiringPiI2CRead); - EXPORT(wiringPiI2CReadReg8); - EXPORT(wiringPiI2CReadReg16); - EXPORT(wiringPiI2CWrite); - EXPORT(wiringPiI2CWriteReg8); - EXPORT(wiringPiI2CWriteReg16); - EXPORT(wiringPiI2CSetupInterface); - EXPORT(wiringPiI2CSetup); - - // WiringPI SPI - EXPORT(wiringPiSPIGetFd); - EXPORT(wiringPiSPIDataRW); - EXPORT(wiringPiSPISetup); - - // WiringPi Serial - EXPORT(serialOpen); - EXPORT(serialClose); - EXPORT(serialFlush); - EXPORT(serialPutchar); - EXPORT(serialPuts); - EXPORT(serialPrintf); - EXPORT(serialDataAvail); - EXPORT(serialGetchar); - - // WiringPi Shift - EXPORT(shiftIn); - EXPORT(shiftOut); -} - -NODE_MODULE(wiringPi, init) \ No newline at end of file diff --git a/src/softPwm.cc b/src/softPwm.cc new file mode 100644 index 0000000..c602caf --- /dev/null +++ b/src/softPwm.cc @@ -0,0 +1,87 @@ +#include "softPwm.h" +#include +#include + +DECLARE(softPwmCreate); +DECLARE(softPwmWrite); +DECLARE(softPwmStop); + +// Func : int softPwmCreate(int pin, int value, int range) +// Description : This creates a software controlled PWM pin. +// You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. +// Use 100 for the pwmRange, then the value can be anything from 0 (off) to 100 (fully on) for the given pin. +// The return value is 0 for success. Anything else and you should check the global errno variable to see what went wrong. +// NOTE : You must initialise wiringPi with one of wiringPiSetup(), wiringPiSetupGpio() or wiringPiSetupPhys() functions. +// wiringPiSetupSys() is not fast enough, so you must run your programs with sudo. +// NOTE2 : Each “cycle” of PWM output takes 10mS with the default range value of 100, +// so trying to change the PWM value more than 100 times a second will be futile. +// NOTE3 : Each pin activated in softPWM mode uses approximately 0.5% of the CPU. +// NOTE4 : There is currently no way to disable softPWM on a pin while the program in running. +// NOTE5 : You need to keep your program running to maintain the PWM output! + +IMPLEMENT(softPwmCreate) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + SET_ARGUMENT_NAME(2, range); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + int range = GET_ARGUMENT_AS_INT32(2); + + int res = ::softPwmCreate(pin, value, range); + + SCOPE_CLOSE(INT32(res)); +} + +// Func void softPwmWrite(int pin, int value) +// Description : This updates the PWM value on the given pin. +// The value is checked to be in-range and pins that haven’t previously been initialised via softPwmCreate will be silently ignored. + +IMPLEMENT(softPwmWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::softPwmWrite(pin, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(softPwmStop) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + + ::softPwmStop(pin); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(softPwm) { + EXPORT_FUNCTION(softPwmCreate); + EXPORT_FUNCTION(softPwmWrite); + EXPORT_FUNCTION(softPwmStop); +} \ No newline at end of file diff --git a/src/softPwm.h b/src/softPwm.h new file mode 100644 index 0000000..33db755 --- /dev/null +++ b/src/softPwm.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SOFT_PWM_H_ +#define _WPI_SOFT_PWM_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(softPwm); + +#endif \ No newline at end of file diff --git a/src/softServo.cc b/src/softServo.cc new file mode 100644 index 0000000..60bdc5a --- /dev/null +++ b/src/softServo.cc @@ -0,0 +1,73 @@ +#include "softServo.h" +#include +#include + +DECLARE(softServoWrite); +DECLARE(softServoSetup); + +// Func : void softServoWrite(int pin, int value) +// Description : Write a Servo value to the given pin + +IMPLEMENT(softServoWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::softServoWrite(pin, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : int softServoSetup(int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) +// Description : Setup the software servo system + +IMPLEMENT(softServoSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, p0); + SET_ARGUMENT_NAME(1, p1); + SET_ARGUMENT_NAME(2, p2); + SET_ARGUMENT_NAME(3, p3); + SET_ARGUMENT_NAME(4, p4); + SET_ARGUMENT_NAME(5, p5); + SET_ARGUMENT_NAME(6, p6); + SET_ARGUMENT_NAME(7, p7); + + CHECK_ARGUMENTS_LENGTH_EQUAL(8); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + CHECK_ARGUMENT_TYPE_INT32(5); + CHECK_ARGUMENT_TYPE_INT32(6); + CHECK_ARGUMENT_TYPE_INT32(7); + + int p0 = GET_ARGUMENT_AS_INT32(0); + int p1 = GET_ARGUMENT_AS_INT32(1); + int p2 = GET_ARGUMENT_AS_INT32(2); + int p3 = GET_ARGUMENT_AS_INT32(3); + int p4 = GET_ARGUMENT_AS_INT32(4); + int p5 = GET_ARGUMENT_AS_INT32(5); + int p6 = GET_ARGUMENT_AS_INT32(6); + int p7 = GET_ARGUMENT_AS_INT32(7); + + int res = ::softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(softServo) { + EXPORT_FUNCTION(softServoWrite); + EXPORT_FUNCTION(softServoSetup); +} \ No newline at end of file diff --git a/src/softServo.h b/src/softServo.h new file mode 100644 index 0000000..f079730 --- /dev/null +++ b/src/softServo.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SOFT_SERVO_H_ +#define _WPI_SOFT_SERVO_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(softServo); + +#endif \ No newline at end of file diff --git a/src/softTone.cc b/src/softTone.cc new file mode 100644 index 0000000..48ab5b9 --- /dev/null +++ b/src/softTone.cc @@ -0,0 +1,77 @@ +#include "softTone.h" +#include +#include + +DECLARE(softToneCreate); +DECLARE(softToneWrite); +DECLARE(softToneStop); + +// Func : int softToneCreate(int pin); +// Description : This creates a software controlled tone pin. +// You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. +// The return value is 0 for success. +// Anything else and you should check the global errno variable to see what went wrong. +// NOTE : You must initialise wiringPi with one of wiringPiSetup(), wiringPiSetupGpio() or wiringPiSetupPhys() functions. +// wiringPiSetupSys() is not fast enough, so you must run your programs with sudo. +// NOTE2 : Each pin activated in softTone mode uses approximately 0.5% of the CPU. +// NOTE3 : You need to keep your program running to maintain the sound output! + +IMPLEMENT(softToneCreate) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + + int res = ::softToneCreate(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void softToneWrite(int pin, int freq); +// Description : This updates the tone frequency value on the given pin. The tone will be played until you set the frequency to 0. + +IMPLEMENT(softToneWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, frequency); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int frequency = GET_ARGUMENT_AS_INT32(1); + + ::softToneWrite(pin, frequency); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(softToneStop) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + + ::softToneStop(pin); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(softTone) { + EXPORT_FUNCTION(softToneCreate); + EXPORT_FUNCTION(softToneWrite); + EXPORT_FUNCTION(softToneStop); +} \ No newline at end of file diff --git a/src/softTone.h b/src/softTone.h new file mode 100644 index 0000000..a96682f --- /dev/null +++ b/src/softTone.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SOFT_TONE_H_ +#define _WPI_SOFT_TONE_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(softTone); + +#endif \ No newline at end of file diff --git a/src/wiringPi.cc b/src/wiringPi.cc new file mode 100644 index 0000000..2860d54 --- /dev/null +++ b/src/wiringPi.cc @@ -0,0 +1,709 @@ +#include "wiringPi.h" +#include + +// Setup +DECLARE(setup); +DECLARE(wiringPiSetup); +DECLARE(wiringPiSetupGpio); +DECLARE(wiringPiSetupSys); +DECLARE(wiringPiSetupPhys); + +// Core functions +DECLARE(pinModeAlt); +DECLARE(pinMode); +DECLARE(pullUpDnControl); +DECLARE(digitalRead); +DECLARE(digitalWrite); +DECLARE(pwmWrite); +DECLARE(analogRead); +DECLARE(analogWrite); +DECLARE(pulseIn); + +DECLARE(delay); +DECLARE(delayMicroseconds); +DECLARE(millis); +DECLARE(micros); + +// On-Board Rasberry Pi hardware specific stuff +DECLARE(piBoardRev); +DECLARE(piBoardId); +DECLARE(wpiPinToGpio); +DECLARE(physPinToGpio); +DECLARE(setPadDrive); +DECLARE(getAlt); +DECLARE(digitalWriteByte); +DECLARE(pwmSetMode); +DECLARE(pwmSetRange); +DECLARE(pwmSetClock); +DECLARE(gpioClockSet); + +IMPLEMENT(setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, mode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_STRING(0); + + String::AsciiValue mode(GET_ARGUMENT_AS_STRING(0)); + + CHECK_ARGUMENT_IN_STRINGS(0, mode, ("wpi", "gpio", "sys", "phys")); + + int res = 0; + if (!strcasecmp(*mode, "wpi")) { + res = ::wiringPiSetup(); + } + else if (!strcasecmp(*mode, "gpio")) { + res = ::wiringPiSetupGpio(); + } + else if (!strcasecmp(*mode, "sys")) { + res = ::wiringPiSetupSys(); + } + else if (!strcasecmp(*mode, "phys")) { + res = ::wiringPiSetupPhys(); + } + + // libWiringPi v2 setup functions always returns 0, so this check is kind of useless, unless v1 behaviour is restored + // NOTE: If you want to restore the v1 behaviour, then you need to set the + // environment variable: WIRINGPI_CODES (to any value, it just needs to exist) + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSetup(void) +// Returns : error code if v1 mode otherwise always returns 0 +// Description : Initialises wiringPi and assumes that the calling program is going +// to be using the wiringPi pin numbering scheme. +// This is a simplified numbering scheme which provides a mapping from virtual +// pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. +// see the pins page (https://projects.drogon.net/raspberry-pi/wiringpi/pins/) for a table +// which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location +// on the edge connector. +// This function needs to be called with root privileges. + +IMPLEMENT(wiringPiSetup) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::wiringPiSetup(); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSetupGpio(void) +// Returns : error code if v1 mode otherwise always returns 0 +// Description : This is indential to above, however it allows the calling programs to use +// the Broadcom GPIO pin numbers directly with no re-mapping. +// As above, this function needs to be called with root privileges, and note that some pins +// are different from revision 1 to revision 2 boards. + +IMPLEMENT(wiringPiSetupGpio) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::wiringPiSetupGpio(); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSetupSys(void) +// Returns : error code if v1 mode otherwise always returns 0 +// Description : This initialises wiringPi but uses the /sys/class/gpio interface rather than +// accessing the hardware directly. This can be called as a non-root user provided the GPIO pins +// have been exported before-hand using gpio program. Pin numbering in this mode is the native +// Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences +// between Rev 1 and Rev 2 boards. +// Note: In this mode you can only use the pins which have been exported via the +// /sys/class/gpio interface before you run your program. You can do this in a seperate +// shell script, or by using the system() function from inside your program to call the gpio program. +// Also note that some functions have no effect when using this mode as they're not currently +// possible to action unless called with root privileges. (although you can use system() to call +// gpio to set/change modes if needed). + +IMPLEMENT(wiringPiSetupSys) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::wiringPiSetupSys(); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSetupPhys(void) +// Returns : error code if v1 mode otherwise always returns 0 +// Description : Identical to above, however it allows the calling programs to use +// the physical pin numbers on the P1 connector only. +// As above, this function needs to be called with root priviliges. + +IMPLEMENT(wiringPiSetupPhys) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::wiringPiSetupPhys(); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void pinModeAlt(int pin, int mode) +// Description : This is an un-documented special to let you set any pin to any mode. +// Modes are WPI_MODE_PINS, WPI_MODE_PHYS, WPI_MODE_GPIO. + +IMPLEMENT(pinModeAlt) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, mode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int mode = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, mode, (WPI_MODE_PINS, WPI_MODE_PHYS, WPI_MODE_GPIO)); + + ::pinModeAlt(pin, mode); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pinMode(int pin, int mode) +// Description : This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. +// Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) +// supports CLOCK output modes. +// This function has no effect when in Sys mode. If you need to change the pin mode, the you can +// do it with the gpio program in a script before you start your program. + +IMPLEMENT(pinMode) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, mode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int mode = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, mode, (INPUT, OUTPUT, PWM_OUTPUT, GPIO_CLOCK, SOFT_PWM_OUTPUT, SOFT_TONE_OUTPUT)); + + ::pinMode(pin, mode); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pullUpDnControl(int pin, int pud) +// Description : This sets the pull-up or pull-down resistor mode on the given pin, which should be set +// as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. +// The parameter pud should be; PUD_OFF (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP (pull to 3.3v). +// The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. + +IMPLEMENT(pullUpDnControl) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, pud); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int pud = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, pud, (PUD_OFF, PUD_DOWN, PUD_UP)); + + ::pullUpDnControl(pin, pud); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : int digitalRead(int pin) +// Description : This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) +// depending on the logic level at the pin. + +IMPLEMENT(digitalRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::digitalRead(pin); + + // Make sure the function returns strictly 1 or 0 + // §4.7/4 from the C++ Standard says (Integral Conversion) + // If the source type is bool, the value false is converted to zero and the value true is converted to one. + res = (res != 0); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void digitalWrite(int pin, int value) +// Description : Write the value HIGH or LOW (1 or 0) to the given pin which must have been +// previously set as an output. +// WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW. + +IMPLEMENT(digitalWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, state, (HIGH, LOW)); + + ::digitalWrite(pin, state); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pwmWrite(int pin, int value) +// Description : Writes the value to the PWM register for the given pin. The Raspberry Pi has +// one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is 0-1024. Other PWM +// devices may have other PWM ranges. +// This function is not able to control the Pi's on-board PWM when in Sys mode. + +IMPLEMENT(pwmWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::pwmWrite(pin, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(analogRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::analogRead(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void analogWrite(int pin, int value) +// Description : This writes the given value to the supplied analog pin. You will need to register +// additional analog modules to enable this function for devices such as the Gertboard. + +IMPLEMENT(analogWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::analogWrite(pin, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(pulseIn) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, state, (HIGH, LOW)); + + int us = ::pulseIn(pin, state); + + SCOPE_CLOSE(INT32(us)); +} + +IMPLEMENT(delay) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, ms); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int ms = GET_ARGUMENT_AS_INT32(0); + + ::delay(ms); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(delayMicroseconds) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, us); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int us = GET_ARGUMENT_AS_INT32(0); + + ::delayMicroseconds(us); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(millis) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + unsigned int ms = ::millis(); + + SCOPE_CLOSE(UINT32(ms)); +} + +IMPLEMENT(micros) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + unsigned int us = ::micros(); + + SCOPE_CLOSE(UINT32(us)); +} + +// === Raspberry Pi specific === + +// Func : int piBoardRev(void) +// Description : This returns the board revision of the Raspberry Pi. It will be either 1 or 2. +// Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, +// so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. + +IMPLEMENT(piBoardRev) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::piBoardRev(); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT(piBoardId) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int model, rev, mem; + char* marker; + + ::piBoardId(&model, &rev, &mem, &marker); + + Local obj = Object::New(); + obj->Set(String::NewSymbol("model"), INT32(model)); + obj->Set(String::NewSymbol("rev"), INT32(rev)); + obj->Set(String::NewSymbol("mem"), INT32(mem)); + obj->Set(String::NewSymbol("marker"), String::New(marker)); + + SCOPE_CLOSE(obj); +} + +// Func : int wpiPinToGpio(int wpiPin) +// Description : This returns the BCM_GPIO pin number of the supplied wiringPi pin. +// It takes the board revision into account. + +IMPLEMENT(wpiPinToGpio) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::wpiPinToGpio(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int physPinToGpio (int physPin) +// Description : This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector. + +IMPLEMENT(physPinToGpio) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::physPinToGpio(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void setPadDrive(int group, int value) +// Description : This sets the "strength" of the pad drivers for a particular group of pins. +// There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you +// know what you are doing. + +IMPLEMENT(setPadDrive) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, group); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int group = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::setPadDrive(group, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : int getAlt(int pin) +// Description : Returns the ALT bits for a given port. Only really of-use +// for the gpio readall command (I think). + +IMPLEMENT(getAlt) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::getAlt(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void digitalWriteByte(int value) +// Description : This writes the 8-bit byte supplied to the first 8 GPIO pins. +// It’s the fastest way to set all 8 bits at once to a particular value, although it still takes +// two write operations to the Pi’s GPIO hardware. + +IMPLEMENT(digitalWriteByte) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, byte); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int byte = GET_ARGUMENT_AS_INT32(0); + ::digitalWriteByte(byte); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pwmSetMode(int mode) +// Description : The PWM generator can run in 2 modes – “balanced” and “mark:space”. +// The mark:space mode is traditional, however the default mode in the Pi is “balanced”. +// You can switch modes by supplying the parameter: PWM_MODE_BAL or PWM_MODE_MS. + +IMPLEMENT(pwmSetMode) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, mode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int mode = GET_ARGUMENT_AS_INT32(0); + + CHECK_ARGUMENT_IN_INTS(0, mode, (PWM_MODE_BAL, PWM_MODE_MS)); + + ::pwmSetMode(mode); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pwmSetRange(unsigned int range) +// Description : This sets the range register in the PWM generator. The default is 1024. +// Note: The PWM control functions can not be used when in Sys mode. To understand more about +// the PWM system, you’ll need to read the Broadcom ARM peripherals manual. + +IMPLEMENT(pwmSetRange) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, range); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_UINT32(0); + + unsigned int range = GET_ARGUMENT_AS_UINT32(0); + ::pwmSetRange(range); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pwmSetClock(int divisor) +// Description : This sets the divisor for the PWM clock. +// Note: The PWM control functions can not be used when in Sys mode. To understand more about +// the PWM system, you’ll need to read the Broadcom ARM peripherals manual. + +IMPLEMENT(pwmSetClock) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, divisor); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int divisor = GET_ARGUMENT_AS_INT32(0); + ::pwmSetClock(divisor); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void gpioClockSet(int pin, int freq) +// Description : Set the frequency on a GPIO clock pin + +IMPLEMENT(gpioClockSet) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, frequency); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int frequency = GET_ARGUMENT_AS_INT32(1); + + ::gpioClockSet(pin, frequency); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(wiringPi) { + // Setup + EXPORT_FUNCTION(setup); + EXPORT_FUNCTION(wiringPiSetup); + EXPORT_FUNCTION(wiringPiSetupGpio); + EXPORT_FUNCTION(wiringPiSetupSys); + EXPORT_FUNCTION(wiringPiSetupPhys); + + // Core functions + EXPORT_FUNCTION(pinModeAlt); + EXPORT_FUNCTION(pinMode); + EXPORT_FUNCTION(pullUpDnControl); + EXPORT_FUNCTION(digitalRead); + EXPORT_FUNCTION(digitalWrite); + EXPORT_FUNCTION(pwmWrite); + EXPORT_FUNCTION(analogRead); + EXPORT_FUNCTION(analogWrite); + EXPORT_FUNCTION(pulseIn); + + EXPORT_FUNCTION(delay); + EXPORT_FUNCTION(delayMicroseconds); + EXPORT_FUNCTION(millis); + EXPORT_FUNCTION(micros); + + // On-Board Rasberry Pi hardware specific stuff + EXPORT_FUNCTION(piBoardRev); + EXPORT_FUNCTION(piBoardId); + EXPORT_FUNCTION(wpiPinToGpio); + EXPORT_FUNCTION(physPinToGpio); + EXPORT_FUNCTION(setPadDrive); + EXPORT_FUNCTION(getAlt); + EXPORT_FUNCTION(digitalWriteByte); + EXPORT_FUNCTION(pwmSetMode); + EXPORT_FUNCTION(pwmSetRange); + EXPORT_FUNCTION(pwmSetClock); + EXPORT_FUNCTION(gpioClockSet); + + // pinModeAlt + EXPORT_CONSTANT_INT(WPI_MODE_PINS); + EXPORT_CONSTANT_INT(WPI_MODE_PHYS); + EXPORT_CONSTANT_INT(WPI_MODE_GPIO); + + // pinMode + EXPORT_CONSTANT_INT(INPUT); + EXPORT_CONSTANT_INT(OUTPUT); + EXPORT_CONSTANT_INT(PWM_OUTPUT); + EXPORT_CONSTANT_INT(GPIO_CLOCK); + EXPORT_CONSTANT_INT(SOFT_PWM_OUTPUT); + EXPORT_CONSTANT_INT(SOFT_TONE_OUTPUT); + + // pullUpDnControl + EXPORT_CONSTANT_INT(PUD_OFF); + EXPORT_CONSTANT_INT(PUD_DOWN); + EXPORT_CONSTANT_INT(PUD_UP); + + // digitalRead/Write + EXPORT_CONSTANT_INT(HIGH); + EXPORT_CONSTANT_INT(LOW); + + // pwmSetMode + EXPORT_CONSTANT_INT(PWM_MODE_BAL); + EXPORT_CONSTANT_INT(PWM_MODE_MS); + + EXPORT_CONSTANT_INT(PI_MODEL_A); + EXPORT_CONSTANT_INT(PI_MODEL_B); + EXPORT_CONSTANT_INT(PI_MODEL_CM); + + /*EXPORT_CONSTANT_STRING_ARRAY(PI_MODEL_NAMES, piModelNames, 3); + EXPORT_CONSTANT_STRING_ARRAY(PI_REVISION_NAMES, piRevisionNames, 3); + EXPORT_CONSTANT_STRING_ARRAY(PI_COMPUTE_REVISION_NAMES, piComputeRevisionNames, 0);*/ +} + diff --git a/src/wiringPi.h b/src/wiringPi.h new file mode 100644 index 0000000..f6cde55 --- /dev/null +++ b/src/wiringPi.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_PI_H_ +#define _WPI_WIRING_PI_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringPi); + +#endif \ No newline at end of file diff --git a/src/wiringPiI2C.cc b/src/wiringPiI2C.cc new file mode 100644 index 0000000..e5e5481 --- /dev/null +++ b/src/wiringPiI2C.cc @@ -0,0 +1,197 @@ +#include "wiringPiI2C.h" +#include +#include + +DECLARE(wiringPiI2CRead); +DECLARE(wiringPiI2CReadReg8); +DECLARE(wiringPiI2CReadReg16); +DECLARE(wiringPiI2CWrite); +DECLARE(wiringPiI2CWriteReg8); +DECLARE(wiringPiI2CWriteReg16); +DECLARE(wiringPiI2CSetupInterface); +DECLARE(wiringPiI2CSetup); + +// Func : int wiringPiI2CRead (int fd); +// Simple device read. Some devices present data when you read them without having to do any register transactions. + +IMPLEMENT(wiringPiI2CRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + int res = ::wiringPiI2CRead(fd); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CRead (int fd, int reg); +// read an 8-bits value from the device register indicated. + +IMPLEMENT(wiringPiI2CReadReg8) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, reg); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int reg = GET_ARGUMENT_AS_INT32(1); + + int res = ::wiringPiI2CReadReg8(fd, reg); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CRead (int fd, int reg) +// read a 16-bits value from the device register indicated. + +IMPLEMENT(wiringPiI2CReadReg16) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, reg); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int reg = GET_ARGUMENT_AS_INT32(1); + + int res = ::wiringPiI2CReadReg16(fd, reg); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CWrite (int fd, int data) +// Simple device write. Some devices accept data this way without needing to access any internal registers. + +IMPLEMENT(wiringPiI2CWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int data = GET_ARGUMENT_AS_INT32(1); + data = data & 0xFF; + + int res = ::wiringPiI2CWrite(fd, data); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CWriteReg8 (int fd, int reg, int data) +// write an 8-bit data value into the device register indicated. + +IMPLEMENT(wiringPiI2CWriteReg8) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, reg); + SET_ARGUMENT_NAME(2, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int fd = GET_ARGUMENT_AS_INT32(0); + int reg = GET_ARGUMENT_AS_INT32(1); + int data = GET_ARGUMENT_AS_INT32(2); + data = data & 0xFF; + + int res = ::wiringPiI2CWriteReg8(fd, reg, data); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT(wiringPiI2CWriteReg16) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, reg); + SET_ARGUMENT_NAME(2, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int fd = GET_ARGUMENT_AS_INT32(0); + int reg = GET_ARGUMENT_AS_INT32(1); + int data = GET_ARGUMENT_AS_INT32(2); + data = data & 0xFFFF; + + int res = ::wiringPiI2CWriteReg16(fd, reg, data); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CSetupInterface (const char *device, int devId) + +IMPLEMENT(wiringPiI2CSetupInterface) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, device); + SET_ARGUMENT_NAME(1, devId); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_STRING(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + String::AsciiValue device(GET_ARGUMENT_AS_STRING(0)); + int devId = GET_ARGUMENT_AS_INT32(1); + + int res = ::wiringPiI2CSetupInterface(*device, devId); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wirintPiI2CSetup (int devId) + +IMPLEMENT(wiringPiI2CSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, devId); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int devId = GET_ARGUMENT_AS_INT32(0); + + int res = ::wiringPiI2CSetup(devId); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(wiringPiI2C) { + EXPORT_FUNCTION(wiringPiI2CRead); + EXPORT_FUNCTION(wiringPiI2CReadReg8); + EXPORT_FUNCTION(wiringPiI2CReadReg16); + EXPORT_FUNCTION(wiringPiI2CWrite); + EXPORT_FUNCTION(wiringPiI2CWriteReg8); + EXPORT_FUNCTION(wiringPiI2CWriteReg16); + EXPORT_FUNCTION(wiringPiI2CSetupInterface); + EXPORT_FUNCTION(wiringPiI2CSetup); +} diff --git a/src/wiringPiI2C.h b/src/wiringPiI2C.h new file mode 100644 index 0000000..27fbe9d --- /dev/null +++ b/src/wiringPiI2C.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_PI_I2C_H_ +#define _WPI_WIRING_PI_I2C_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringPiI2C); + +#endif \ No newline at end of file diff --git a/src/wiringPiISR.cc b/src/wiringPiISR.cc new file mode 100644 index 0000000..12bad63 --- /dev/null +++ b/src/wiringPiISR.cc @@ -0,0 +1,227 @@ +#include "wiringPiISR.h" +#include +#include +#include + +using namespace v8; + +typedef struct js_work_t { + uv_work_t req; + int pin; + unsigned int delta; +} js_work_t; + +typedef void (*NATIVE_INTERRUPT_HANDLER_T)(void); + +static NATIVE_INTERRUPT_HANDLER_T nativeInterruptHandlers[64]; +static unsigned long int lastInterruptMicroseconds[64]; +static std::map > interruptCallbackMapping; + +#define DEFINE_NATIVE_INTERRUPT_HANDLER(pin) \ + static void nativeInterruptHandler##pin(void) { \ + processNativeInterrupt(pin); \ + } + +#define REGISTER_NATIVE_INTERRUPT_HANDLER(pin) nativeInterruptHandlers[pin] = &nativeInterruptHandler##pin + +#define GET_NATIVE_INTERRUPT_HANDLER(pin) nativeInterruptHandlers[pin] + +static void processInterrupt(uv_work_t* req, int status) { + js_work_t* work = static_cast(req->data); + + Persistent callback = interruptCallbackMapping[work->pin]; + + Local argv[] = { + Local::New(Int32::New(work->pin)), + Local::New(Uint32::New(work->delta)) + }; + + callback->Call(Context::GetCurrent()->Global(), 2, argv); + + delete work; +} + +static void UV_NOP(uv_work_t*) {} + +void processNativeInterrupt(int pin) { + unsigned int now = ::micros(); + + js_work_t* work = new js_work_t; + work->req.data = work; + work->pin = pin; + work->delta = now - lastInterruptMicroseconds[pin]; + + int r = uv_queue_work(uv_default_loop(), &work->req, &UV_NOP, &processInterrupt); + if (r != 0) { + delete work; + } + + lastInterruptMicroseconds[pin] = now; +} + +DEFINE_NATIVE_INTERRUPT_HANDLER(0); +DEFINE_NATIVE_INTERRUPT_HANDLER(1); +DEFINE_NATIVE_INTERRUPT_HANDLER(2); +DEFINE_NATIVE_INTERRUPT_HANDLER(3); +DEFINE_NATIVE_INTERRUPT_HANDLER(4); +DEFINE_NATIVE_INTERRUPT_HANDLER(5); +DEFINE_NATIVE_INTERRUPT_HANDLER(6); +DEFINE_NATIVE_INTERRUPT_HANDLER(7); +DEFINE_NATIVE_INTERRUPT_HANDLER(8); +DEFINE_NATIVE_INTERRUPT_HANDLER(9); +DEFINE_NATIVE_INTERRUPT_HANDLER(10); +DEFINE_NATIVE_INTERRUPT_HANDLER(11); +DEFINE_NATIVE_INTERRUPT_HANDLER(12); +DEFINE_NATIVE_INTERRUPT_HANDLER(13); +DEFINE_NATIVE_INTERRUPT_HANDLER(14); +DEFINE_NATIVE_INTERRUPT_HANDLER(15); +DEFINE_NATIVE_INTERRUPT_HANDLER(16); +DEFINE_NATIVE_INTERRUPT_HANDLER(17); +DEFINE_NATIVE_INTERRUPT_HANDLER(18); +DEFINE_NATIVE_INTERRUPT_HANDLER(19); +DEFINE_NATIVE_INTERRUPT_HANDLER(20); +DEFINE_NATIVE_INTERRUPT_HANDLER(21); +DEFINE_NATIVE_INTERRUPT_HANDLER(22); +DEFINE_NATIVE_INTERRUPT_HANDLER(23); +DEFINE_NATIVE_INTERRUPT_HANDLER(24); +DEFINE_NATIVE_INTERRUPT_HANDLER(25); +DEFINE_NATIVE_INTERRUPT_HANDLER(26); +DEFINE_NATIVE_INTERRUPT_HANDLER(27); +DEFINE_NATIVE_INTERRUPT_HANDLER(28); +DEFINE_NATIVE_INTERRUPT_HANDLER(29); +DEFINE_NATIVE_INTERRUPT_HANDLER(30); +DEFINE_NATIVE_INTERRUPT_HANDLER(31); +DEFINE_NATIVE_INTERRUPT_HANDLER(32); +DEFINE_NATIVE_INTERRUPT_HANDLER(33); +DEFINE_NATIVE_INTERRUPT_HANDLER(34); +DEFINE_NATIVE_INTERRUPT_HANDLER(35); +DEFINE_NATIVE_INTERRUPT_HANDLER(36); +DEFINE_NATIVE_INTERRUPT_HANDLER(37); +DEFINE_NATIVE_INTERRUPT_HANDLER(38); +DEFINE_NATIVE_INTERRUPT_HANDLER(39); +DEFINE_NATIVE_INTERRUPT_HANDLER(40); +DEFINE_NATIVE_INTERRUPT_HANDLER(41); +DEFINE_NATIVE_INTERRUPT_HANDLER(42); +DEFINE_NATIVE_INTERRUPT_HANDLER(43); +DEFINE_NATIVE_INTERRUPT_HANDLER(44); +DEFINE_NATIVE_INTERRUPT_HANDLER(45); +DEFINE_NATIVE_INTERRUPT_HANDLER(46); +DEFINE_NATIVE_INTERRUPT_HANDLER(47); +DEFINE_NATIVE_INTERRUPT_HANDLER(48); +DEFINE_NATIVE_INTERRUPT_HANDLER(49); +DEFINE_NATIVE_INTERRUPT_HANDLER(50); +DEFINE_NATIVE_INTERRUPT_HANDLER(51); +DEFINE_NATIVE_INTERRUPT_HANDLER(52); +DEFINE_NATIVE_INTERRUPT_HANDLER(53); +DEFINE_NATIVE_INTERRUPT_HANDLER(54); +DEFINE_NATIVE_INTERRUPT_HANDLER(55); +DEFINE_NATIVE_INTERRUPT_HANDLER(56); +DEFINE_NATIVE_INTERRUPT_HANDLER(57); +DEFINE_NATIVE_INTERRUPT_HANDLER(58); +DEFINE_NATIVE_INTERRUPT_HANDLER(59); +DEFINE_NATIVE_INTERRUPT_HANDLER(60); +DEFINE_NATIVE_INTERRUPT_HANDLER(61); +DEFINE_NATIVE_INTERRUPT_HANDLER(62); +DEFINE_NATIVE_INTERRUPT_HANDLER(63); + +DECLARE(wiringPiISR); +IMPLEMENT(wiringPiISR) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, edgeType); + SET_ARGUMENT_NAME(2, callback); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_FUNCTION(2); + + int pin = GET_ARGUMENT_AS_INT32(0); + int edgeType = GET_ARGUMENT_AS_INT32(1); + Persistent callback = GET_ARGUMENT_AS_PERSISTENT_FUNCTION(2); + + CHECK_ARGUMENT_IN_INTS(1, edgeType, (INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH, INT_EDGE_SETUP)); + + interruptCallbackMapping.insert(std::pair >(pin, callback)); + lastInterruptMicroseconds[pin] = ::micros(); + + ::wiringPiISR(pin, edgeType, GET_NATIVE_INTERRUPT_HANDLER(pin)); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(wiringPiISR) { + REGISTER_NATIVE_INTERRUPT_HANDLER(0); + REGISTER_NATIVE_INTERRUPT_HANDLER(1); + REGISTER_NATIVE_INTERRUPT_HANDLER(2); + REGISTER_NATIVE_INTERRUPT_HANDLER(3); + REGISTER_NATIVE_INTERRUPT_HANDLER(4); + REGISTER_NATIVE_INTERRUPT_HANDLER(5); + REGISTER_NATIVE_INTERRUPT_HANDLER(6); + REGISTER_NATIVE_INTERRUPT_HANDLER(7); + REGISTER_NATIVE_INTERRUPT_HANDLER(8); + REGISTER_NATIVE_INTERRUPT_HANDLER(9); + REGISTER_NATIVE_INTERRUPT_HANDLER(10); + REGISTER_NATIVE_INTERRUPT_HANDLER(11); + REGISTER_NATIVE_INTERRUPT_HANDLER(12); + REGISTER_NATIVE_INTERRUPT_HANDLER(13); + REGISTER_NATIVE_INTERRUPT_HANDLER(14); + REGISTER_NATIVE_INTERRUPT_HANDLER(15); + REGISTER_NATIVE_INTERRUPT_HANDLER(16); + REGISTER_NATIVE_INTERRUPT_HANDLER(17); + REGISTER_NATIVE_INTERRUPT_HANDLER(18); + REGISTER_NATIVE_INTERRUPT_HANDLER(19); + REGISTER_NATIVE_INTERRUPT_HANDLER(20); + REGISTER_NATIVE_INTERRUPT_HANDLER(21); + REGISTER_NATIVE_INTERRUPT_HANDLER(22); + REGISTER_NATIVE_INTERRUPT_HANDLER(23); + REGISTER_NATIVE_INTERRUPT_HANDLER(24); + REGISTER_NATIVE_INTERRUPT_HANDLER(25); + REGISTER_NATIVE_INTERRUPT_HANDLER(26); + REGISTER_NATIVE_INTERRUPT_HANDLER(27); + REGISTER_NATIVE_INTERRUPT_HANDLER(28); + REGISTER_NATIVE_INTERRUPT_HANDLER(29); + REGISTER_NATIVE_INTERRUPT_HANDLER(30); + REGISTER_NATIVE_INTERRUPT_HANDLER(31); + REGISTER_NATIVE_INTERRUPT_HANDLER(32); + REGISTER_NATIVE_INTERRUPT_HANDLER(33); + REGISTER_NATIVE_INTERRUPT_HANDLER(34); + REGISTER_NATIVE_INTERRUPT_HANDLER(35); + REGISTER_NATIVE_INTERRUPT_HANDLER(36); + REGISTER_NATIVE_INTERRUPT_HANDLER(37); + REGISTER_NATIVE_INTERRUPT_HANDLER(38); + REGISTER_NATIVE_INTERRUPT_HANDLER(39); + REGISTER_NATIVE_INTERRUPT_HANDLER(40); + REGISTER_NATIVE_INTERRUPT_HANDLER(41); + REGISTER_NATIVE_INTERRUPT_HANDLER(42); + REGISTER_NATIVE_INTERRUPT_HANDLER(43); + REGISTER_NATIVE_INTERRUPT_HANDLER(44); + REGISTER_NATIVE_INTERRUPT_HANDLER(45); + REGISTER_NATIVE_INTERRUPT_HANDLER(46); + REGISTER_NATIVE_INTERRUPT_HANDLER(47); + REGISTER_NATIVE_INTERRUPT_HANDLER(48); + REGISTER_NATIVE_INTERRUPT_HANDLER(49); + REGISTER_NATIVE_INTERRUPT_HANDLER(50); + REGISTER_NATIVE_INTERRUPT_HANDLER(51); + REGISTER_NATIVE_INTERRUPT_HANDLER(52); + REGISTER_NATIVE_INTERRUPT_HANDLER(53); + REGISTER_NATIVE_INTERRUPT_HANDLER(54); + REGISTER_NATIVE_INTERRUPT_HANDLER(55); + REGISTER_NATIVE_INTERRUPT_HANDLER(56); + REGISTER_NATIVE_INTERRUPT_HANDLER(57); + REGISTER_NATIVE_INTERRUPT_HANDLER(58); + REGISTER_NATIVE_INTERRUPT_HANDLER(59); + REGISTER_NATIVE_INTERRUPT_HANDLER(60); + REGISTER_NATIVE_INTERRUPT_HANDLER(61); + REGISTER_NATIVE_INTERRUPT_HANDLER(62); + REGISTER_NATIVE_INTERRUPT_HANDLER(63); + + EXPORT_FUNCTION(wiringPiISR); + + EXPORT_CONSTANT_INT(INT_EDGE_FALLING); + EXPORT_CONSTANT_INT(INT_EDGE_RISING); + EXPORT_CONSTANT_INT(INT_EDGE_BOTH); + EXPORT_CONSTANT_INT(INT_EDGE_SETUP); +} \ No newline at end of file diff --git a/src/wiringPiISR.h b/src/wiringPiISR.h new file mode 100644 index 0000000..c08ff1e --- /dev/null +++ b/src/wiringPiISR.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_PI_ISR_H_ +#define _WPI_WIRING_PI_ISR_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringPiISR); + +#endif \ No newline at end of file diff --git a/src/wiringPiSPI.cc b/src/wiringPiSPI.cc new file mode 100644 index 0000000..fcde1c0 --- /dev/null +++ b/src/wiringPiSPI.cc @@ -0,0 +1,80 @@ +#include "wiringPiSPI.h" +#include +#include + +DECLARE(wiringPiSPIGetFd); +DECLARE(wiringPiSPIDataRW); +DECLARE(wiringPiSPISetup); + +// Func : int wiringPiSPIGetFd(int channel) + +IMPLEMENT(wiringPiSPIGetFd) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, channel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int channel = GET_ARGUMENT_AS_INT32(0); + + CHECK_ARGUMENT_IN_INTS(0, channel, (0, 1)); + + int res = ::wiringPiSPIGetFd(channel); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : wiringPiSPIDataRW(int channel, unsigned char* data, int len) + +IMPLEMENT(wiringPiSPIDataRW) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, channel); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_NODE_BUFFER(1); + + int channel = GET_ARGUMENT_AS_INT32(0); + char* data = node::Buffer::Data(args[1]->ToObject()); + int length = node::Buffer::Length(args[1]->ToObject()); + + CHECK_ARGUMENT_IN_INTS(0, channel, (0, 1)); + + int res = ::wiringPiSPIDataRW(channel, reinterpret_cast(data), length); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSPISetup(int channel, int speed) + +IMPLEMENT(wiringPiSPISetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, channel); + SET_ARGUMENT_NAME(1, speed); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int channel = GET_ARGUMENT_AS_INT32(0); + int speed = GET_ARGUMENT_AS_INT32(0); + + CHECK_ARGUMENT_IN_INTS(0, channel, (0, 1)); + + int res = ::wiringPiSPISetup(channel, speed); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(wiringPiSPI) { + EXPORT_FUNCTION(wiringPiSPIGetFd); + EXPORT_FUNCTION(wiringPiSPIDataRW); + EXPORT_FUNCTION(wiringPiSPISetup); +} \ No newline at end of file diff --git a/src/wiringPiSPI.h b/src/wiringPiSPI.h new file mode 100644 index 0000000..4ff13a5 --- /dev/null +++ b/src/wiringPiSPI.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_PI_SPI_H_ +#define _WPI_WIRING_PI_SPI_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringPiSPI); + +#endif \ No newline at end of file diff --git a/src/wiringSerial.cc b/src/wiringSerial.cc new file mode 100644 index 0000000..51b8af1 --- /dev/null +++ b/src/wiringSerial.cc @@ -0,0 +1,167 @@ +#include "wiringSerial.h" +#include +#include + +DECLARE(serialOpen); +DECLARE(serialClose); +DECLARE(serialFlush); +DECLARE(serialPutchar); +DECLARE(serialPuts); +DECLARE(serialPrintf); +DECLARE(serialDataAvail); +DECLARE(serialGetchar); + +// Func : int serialOpen(const char* device, const int baud) + +IMPLEMENT(serialOpen) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, device); + SET_ARGUMENT_NAME(1, baudrate); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_STRING(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + String::AsciiValue device(GET_ARGUMENT_AS_STRING(0)); + int baudrate = GET_ARGUMENT_AS_INT32(1); + + int res = ::serialOpen(*device, baudrate); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void serialClose(const int fd) + +IMPLEMENT(serialClose) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + ::serialClose(fd); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void serialFlush(const int fd); + +IMPLEMENT(serialFlush) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + ::serialFlush(fd); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void serialPutchar(const int fd, const unsigned char c) + +IMPLEMENT(serialPutchar) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, character); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + unsigned char character = GET_ARGUMENT_AS_UINT32(1); + + ::serialPutchar(fd, character); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void serialPuts(const int fd, const char* s) + +IMPLEMENT(serialPuts) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, string); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_STRING(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + String::AsciiValue string(GET_ARGUMENT_AS_STRING(1)); + + ::serialPuts(fd, *string); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void serialPrintf(const int fd, const char* message, ...) + +IMPLEMENT(serialPrintf) { + // Make serialPrintf a alias to serialPuts + return serialPuts(args); +} + +// Func : int serialDataAvail(const int fd) + +IMPLEMENT(serialDataAvail) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + int res = ::serialDataAvail(fd); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int serialGetchar(const int fd) +// NOTE TO MYSELF : I don't understand why serialPutchar takes a unsigned char and on the other side +// serialGetchar returns a int ... serialGetchar should returns a unsigned char too. + +IMPLEMENT(serialGetchar) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + int res = ::serialGetchar(fd); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(wiringSerial) { + EXPORT_FUNCTION(serialOpen); + EXPORT_FUNCTION(serialClose); + EXPORT_FUNCTION(serialFlush); + EXPORT_FUNCTION(serialPutchar); + EXPORT_FUNCTION(serialPuts); + EXPORT_FUNCTION(serialPrintf); + EXPORT_FUNCTION(serialDataAvail); + EXPORT_FUNCTION(serialGetchar); +} \ No newline at end of file diff --git a/src/wiringSerial.h b/src/wiringSerial.h new file mode 100644 index 0000000..2da6c1f --- /dev/null +++ b/src/wiringSerial.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_SERIAL_H_ +#define _WPI_WIRING_SERIAL_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringSerial); + +#endif \ No newline at end of file diff --git a/src/wiringShift.cc b/src/wiringShift.cc new file mode 100644 index 0000000..4d54780 --- /dev/null +++ b/src/wiringShift.cc @@ -0,0 +1,76 @@ +#include "wiringShift.h" +#include +#include + +DECLARE(shiftIn); +DECLARE(shiftOut); + +// Func : uint8_t shiftIn(uint8_t dPin, uint8_t cPin, uint8_t order) +// Description : This shifts an 8-bit data value in with the data appearing on the dPin and the clock being sent out on the cPin. +// Order is either LSBFIRST or MSBFIRST. +// The data is sampled after the cPin goes high. +// (So cPin high, sample data, cPin low, repeat for 8 bits) The 8-bit value is returned by the function. + +IMPLEMENT(shiftIn) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, dPin); + SET_ARGUMENT_NAME(1, cPin); + SET_ARGUMENT_NAME(2, order); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_UINT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + CHECK_ARGUMENT_TYPE_UINT32(2); + + uint8_t dPin = GET_ARGUMENT_AS_UINT32(0); + uint8_t cPin = GET_ARGUMENT_AS_UINT32(1); + uint8_t order = GET_ARGUMENT_AS_UINT32(2); + + CHECK_ARGUMENT_IN_INTS(2, order, (LSBFIRST, MSBFIRST)); + + uint8_t res = ::shiftIn(dPin, cPin, order); + + SCOPE_CLOSE(UINT32(res)); +} + +// Func : void shiftOut(uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; +// Description : The shifts an 8-bit data value val out with the data being sent out on dPin and the clock being sent out on the cPin. +// order is as above. +// Data is clocked out on the rising or falling edge – ie. dPin is set, then cPin is taken high then low – repeated for the 8 bits. + +IMPLEMENT(shiftOut) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, dPin); + SET_ARGUMENT_NAME(1, cPin); + SET_ARGUMENT_NAME(2, order); + SET_ARGUMENT_NAME(3, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(4); + + CHECK_ARGUMENT_TYPE_UINT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + CHECK_ARGUMENT_TYPE_UINT32(2); + CHECK_ARGUMENT_TYPE_UINT32(3); + + uint8_t dPin = GET_ARGUMENT_AS_UINT32(0); + uint8_t cPin = GET_ARGUMENT_AS_UINT32(1); + uint8_t order = GET_ARGUMENT_AS_UINT32(2); + uint8_t value = GET_ARGUMENT_AS_UINT32(3); + + CHECK_ARGUMENT_IN_INTS(2, order, (LSBFIRST, MSBFIRST)); + + ::shiftOut(dPin, cPin, order, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(wiringShift) { + EXPORT_FUNCTION(shiftIn); + EXPORT_FUNCTION(shiftOut); + + EXPORT_CONSTANT_INT(LSBFIRST); + EXPORT_CONSTANT_INT(MSBFIRST); +} \ No newline at end of file diff --git a/src/wiringShift.h b/src/wiringShift.h new file mode 100644 index 0000000..98ca11b --- /dev/null +++ b/src/wiringShift.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_SHIFT_H_ +#define _WPI_WIRING_SHIFT_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringShift); + +#endif \ No newline at end of file diff --git a/src/wpi.cc b/src/wpi.cc new file mode 100644 index 0000000..991eec4 --- /dev/null +++ b/src/wpi.cc @@ -0,0 +1,15 @@ +#include "wpi.h" + +NODE_MODULE_INIT() { + INIT(wiringPi); + INIT(softPwm); + INIT(softServo); + INIT(softTone); + INIT(wiringPiI2C); + INIT(wiringPiSPI); + INIT(wiringSerial); + INIT(wiringShift); + INIT(wiringPiISR); +} + +NODE_MODULE_DECLARE(wiringPi); \ No newline at end of file diff --git a/src/wpi.h b/src/wpi.h new file mode 100644 index 0000000..301c9cf --- /dev/null +++ b/src/wpi.h @@ -0,0 +1,14 @@ +#ifndef _WPI_H_ +#define _WPI_H_ + + #include "wiringPi.h" + #include "softPwm.h" + #include "softServo.h" + #include "softTone.h" + #include "wiringPiI2C.h" + #include "wiringPiSPI.h" + #include "wiringSerial.h" + #include "wiringShift.h" + #include "wiringPiISR.h" + +#endif \ No newline at end of file From 347287e45a6397e50eca4561b7ad00e86cc37f51 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 2 Jul 2014 19:50:27 +0200 Subject: [PATCH 02/64] update documentation --- DOCUMENTATION.md | 85 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 9b9aa85..a1efb00 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -1,16 +1,30 @@ + + # Index @@ -39,6 +53,7 @@ var wpi = require('wiring-pi'); ## Setup ### `wiringPiSetup()` + >= 0.1.0 Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. @@ -46,6 +61,7 @@ see the pins page (http://wiringpi.com/pins/) for a table which maps the wiringP This function needs to be called with root privileges. ### `wiringPiSetupGpio()` + >= 0.1.1 This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards. @@ -55,23 +71,29 @@ This is indential to above, however it allows the calling programs to use the Br Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. As above, this function needs to be called with root priviliges. ### `wiringPiSetupSys()` + >= 0.1.1 This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed). ### `setup(mode)` + >= 0.1.1 An handy function to setup wiringPi `mode` can be one of the following values: * `wpi`: sets up pin numbering with wiringPiSetup + >= 0.1.1 * `gpio`: sets up pin numbering with wiringPiSetupGpio + >= 0.1.1 * `sys`: sets up pin numbering with wiringPiSetupSys + >= 0.1.1 * `phys`: sets up pin numbering with wiringPiSetupPhys + >= 1.0.0 More info about pin numbering systems at [wiringpi.com/pins/](http://wiringpi.com/pins/) -**NOTE: wiring-pi >= 2.0.0 no longer accept calling setup without mode specified. (defaulting to `wpi` in wiring-pi < 2.0.0)** +**NOTE: `>= 2.0.0` no longer accept calling setup without mode specified. (defaulting to `wpi` in `< 2.0.0`)** --- @@ -85,25 +107,39 @@ This is an un-documented special to let you set any pin to any mode. `mode` can be one of the following values: * `WPI_MODE_PINS` + >= 1.0.0 * `WPI_MODE_PHYS` + >= 1.0.0 * `WPI_MODE_GPIO` + >= 1.0.0 ### `pinMode(pin, mode)` + >= 0.1.0 This sets the mode of a pin. Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program. `mode` can be one of the following values: -* `modes.INPUT` **wiring-pi < 1.0.0** -* `modes.OUTPUT` **wiring-pi < 1.0.0** -* `modes.PWM_OUTPUT` **wiring-pi < 1.0.0** -* `modes.GPIO_CLOCK` **wiring-pi < 1.0.0** +* `modes.INPUT` + >= 0.1.1 < 2.0.0 removed +* `modes.OUTPUT` + >= 0.1.1 < 2.0.0 removed +* `modes.PWM_OUTPUT` + >= 0.1.1 < 2.0.0 removed +* `modes.GPIO_CLOCK` + >= 0.1.1 < 2.0.0 removed * `INPUT` + >= 1.0.0 * `OUTPUT` + >= 1.0.0 * `PWM_OUTPUT` + >= 1.0.0 * `GPIO_CLOCK` -* `SOFT_PWM_OUTPUT` **wiring-pi >= 1.1.0** -* `SOFT_TONE_OUTPUT` **wiring-pi >= 1.1.0** + >= 1.0.0 +* `SOFT_PWM_OUTPUT` + >= 1.1.0 +* `SOFT_TONE_OUTPUT` + >= 1.1.0 ### `pullUpDnControl(pin, pud)` >= 0.2.0 @@ -113,23 +149,31 @@ This sets the pull-up or pull-down resistor mode on the given pin, which should `pud` can be one of the following values: * `PUD_OFF` *no pull up/down* + >= 0.2.0 * `PUD_DOWN` *pull to ground* + >= 0.2.0 * `PUD_UP` *pull to 3.3v* + >= 0.2.0 ### `digitalRead(pin)` + >= 0.1.1 This function returns the value read at the given pin. It will be `HIGH` (1) or `LOW` (0) depending on the logic level at the pin. ### `digitalWrite(pin, state)` + >= 0.1.0 Write the value `HIGH` (1) or `LOW` (0) to the given pin which must have been previously set as an output. WiringPi treats any non-zero number as `HIGH`, however 0 is the only representation of `LOW`. `state` can be one of the following value: * `HIGH` + >= 0.1.2 * `LOW` + >= 0.1.2 ### `pwmWrite(pin, value)` + >= 0.1.1 Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024]. Other PWM devices may have other PWM ranges. This function is not able to control the Pi's on-board PWM when in Sys mode. @@ -151,7 +195,9 @@ This writes the given value to the supplied analog pin. You will need to registe `state` can be one of the following values: * `HIGH` + >= 0.1.2 * `LOW` + >= 0.1.2 ### `delay(milliseconds)` >= 1.1.0 @@ -170,6 +216,7 @@ This writes the given value to the supplied analog pin. You will need to registe ## Raspberry Pi hardware specific functions ### `piBoardRev()` + >= 0.1.1 This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. @@ -212,10 +259,12 @@ The PWM generator can run in 2 modes – “balanced” and “mark:space”. Th * `PWM_MODE_MS` *mark:space* ### `pwmSetRange(range)` + >= 0.1.1 This sets the range register in the PWM generator. The default is 1024. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. ### `pwmSetClock(divisor)` + >= 0.1.1 This sets the divisor for the PWM clock. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. From eaff0e32400f073fa2d98022d771737e78e3b192 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 12:48:56 +0200 Subject: [PATCH 03/64] update documentation --- DOCUMENTATION.html | 266 +++++++++++++++++++ README.md | 2 +- DOCUMENTATION.md => docs/DOCUMENTATION.md | 40 +-- docs/pandoc.css | 301 ++++++++++++++++++++++ 4 files changed, 569 insertions(+), 40 deletions(-) create mode 100644 DOCUMENTATION.html rename DOCUMENTATION.md => docs/DOCUMENTATION.md (95%) create mode 100644 docs/pandoc.css diff --git a/DOCUMENTATION.html b/DOCUMENTATION.html new file mode 100644 index 0000000..c795b0e --- /dev/null +++ b/DOCUMENTATION.html @@ -0,0 +1,266 @@ + + + + + + + + + + + + + +

Install

+
npm install wiring-pi
+

Usage

+
var wpi = require('wiring-pi');
+

APIs

+

Setup

+

wiringPiSetup()

+

>= 0.1.0

+

Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. see the pins page (http://wiringpi.com/pins/) for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. This function needs to be called with root privileges.

+

wiringPiSetupGpio()

+

>= 0.1.1

+

This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards.

+

wiringPiSetupPhys()

+

>= 1.0.0

+

Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. As above, this function needs to be called with root priviliges.

+

wiringPiSetupSys()

+

>= 0.1.1

+

This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed).

+

setup(mode)

+

>= 0.1.1

+

An handy function to setup wiringPi

+

mode can be one of the following values:

+
    +
  • wpi: sets up pin numbering with wiringPiSetup >= 0.1.1
  • +
  • gpio: sets up pin numbering with wiringPiSetupGpio >= 0.1.1
  • +
  • sys: sets up pin numbering with wiringPiSetupSys >= 0.1.1
  • +
  • phys: sets up pin numbering with wiringPiSetupPhys >= 1.0.0
  • +
+

More info about pin numbering systems at wiringpi.com/pins/

+

NOTE: >= 2.0.0 no longer accept calling setup without mode specified. (defaulting to wpi in < 2.0.0)

+
+

Core functions

+

pinModeAlt(pin, mode)

+

>= 1.0.0

+

This is an un-documented special to let you set any pin to any mode.

+

mode can be one of the following values:

+
    +
  • WPI_MODE_PINS >= 1.0.0
  • +
  • WPI_MODE_PHYS >= 1.0.0
  • +
  • WPI_MODE_GPIO >= 1.0.0
  • +
+

pinMode(pin, mode)

+

>= 0.1.0

+

This sets the mode of a pin. Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program.

+

mode can be one of the following values:

+
    +
  • modes.INPUT >= 0.1.1 < 2.0.0 removed
  • +
  • modes.OUTPUT >= 0.1.1 < 2.0.0 removed
  • +
  • modes.PWM_OUTPUT >= 0.1.1 < 2.0.0 removed
  • +
  • modes.GPIO_CLOCK >= 0.1.1 < 2.0.0 removed
  • +
  • INPUT >= 1.0.0
  • +
  • OUTPUT >= 1.0.0
  • +
  • PWM_OUTPUT >= 1.0.0
  • +
  • GPIO_CLOCK >= 1.0.0
  • +
  • SOFT_PWM_OUTPUT >= 1.1.0
  • +
  • SOFT_TONE_OUTPUT >= 1.1.0
  • +
+

pullUpDnControl(pin, pud)

+

>= 0.2.0

+

This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi.

+

pud can be one of the following values:

+
    +
  • PUD_OFF no pull up/down >= 0.2.0
  • +
  • PUD_DOWN pull to ground >= 0.2.0
  • +
  • PUD_UP pull to 3.3v >= 0.2.0
  • +
+

digitalRead(pin)

+

>= 0.1.1

+

This function returns the value read at the given pin. It will be HIGH (1) or LOW (0) depending on the logic level at the pin.

+

digitalWrite(pin, state)

+

>= 0.1.0

+

Write the value HIGH (1) or LOW (0) to the given pin which must have been previously set as an output. WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW.

+

state can be one of the following value:

+
    +
  • HIGH >= 0.1.2
  • +
  • LOW >= 0.1.2
  • +
+

pwmWrite(pin, value)

+

>= 0.1.1

+

Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024]. Other PWM devices may have other PWM ranges. This function is not able to control the Pi's on-board PWM when in Sys mode.

+

value must be in range of [0, 1024]

+

analogRead(pin)

+

>= 1.0.0

+

This returns the value read on the supplied analog input pin. You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc.

+

analogWrite(pin, value)

+

>= 1.0.0

+

This writes the given value to the supplied analog pin. You will need to register additional analog modules to enable this function for devices such as the Gertboard.

+

pulseIn(pin, state)

+

>= 1.1.0

+

state can be one of the following values:

+
    +
  • HIGH >= 0.1.2
  • +
  • LOW >= 0.1.2
  • +
+

delay(milliseconds)

+

>= 1.1.0

+

delayMicroseconds(microseconds)

+

>= 1.1.0

+

millis()

+

>= 1.1.0

+

micros()

+

>= 1.1.0

+
+

Raspberry Pi hardware specific functions

+

piBoardRev()

+

>= 0.1.1

+

This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences.

+

piBoardId()

+

>= 1.1.0

+

wpiPinToGpio(pin)

+

>= 1.0.0

+

This returns the BCM_GPIO pin number of the supplied wiringPi pin. It takes the board revision into account.

+

physPinToGpio(pin)

+

>= 1.0.0

+

This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector.

+

setPadDrive(group, value)

+

>= 1.0.0

+

This sets the "strength" of the pad drivers for a particular group of pins. There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you know what you are doing.

+

getAlt(pin)

+

>= 1.0.0

+

Returns the ALT bits for a given port.

+

digitalWriteByte(byte)

+

>= 1.0.0

+

This writes the 8-bit byte supplied to the first 8 GPIO pins. It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware.

+

pwmSetMode(mode)

+

>= 1.0.0

+

The PWM generator can run in 2 modes – “balanced” and “mark:space”. The mark:space mode is traditional, however the default mode in the Pi is “balanced”.

+

mode can be one of the following values:

+
    +
  • PWM_MODE_BAL balanced
  • +
  • PWM_MODE_MS mark:space
  • +
+

pwmSetRange(range)

+

>= 0.1.1

+

This sets the range register in the PWM generator. The default is 1024. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

+

pwmSetClock(divisor)

+

>= 0.1.1

+

This sets the divisor for the PWM clock. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

+

gpioClockSet(pin, frequency)

+

>= 1.0.0

+

Set the frequency on a GPIO clock pin

+
+

I2C

+

wiringPiI2CSetup(devId)

+

>= 2.0.0

+

wiringPiI2CSetupInterface(device, devId)

+

>= 2.0.0

+

wiringPiI2CRead(fd)

+

>= 2.0.0

+

wiringPiI2CReadReg8(fd, reg)

+

>= 2.0.0

+

wiringPiI2CReadReg16(fd, red)

+

>= 2.0.0

+

wiringPiI2CWrite(fd, data)

+

>= 2.0.0

+

wiringPiI2CWriteReg8(fd, reg, data)

+

>= 2.0.0

+

wiringPiI2CWriteReg16(fd, reg, data)

+

>= 2.0.0

+
+

SPI

+

wiringPiSPIGetFd(channel)

+

>= 1.0.0

+

wiringPiSPIDataRW(channel, data)

+

>= 1.0.0

+

wiringPiSPISetup(channel, speed)

+

>= 1.0.0

+
+

Serial

+

serialOpen(device, baudrate)

+

>= 1.0.0

+

serialClose(fd)

+

>= 1.0.0

+

serialFlush(fd)

+

>= 1.0.0

+

serialPutchar(fd, character)

+

>= 1.0.0

+

serialPuts(fd, string)

+

>= 1.0.0

+

serialPrintf(fd, string)

+

Alias: serialPuts >= 2.0.0

+

serialDataAvail(fd)

+

>= 1.0.0

+

serialGetchar(fd)

+

>= 1.0.0

+
+

Shift

+

shiftIn(dPin, cPin, order)

+

>= 1.0.0

+

shiftOut(dPin, cPin, order, value)

+

>= 1.0.0

+
+

Soft PWM

+

softPwmCreate(pin, value, range)

+

>= 1.0.0

+

softPwmWrite(pin, value)

+

>= 1.0.0

+

softPwmStop(pin)

+

>= 1.1.0

+
+

Soft Servo

+

softServoWrite(pin, value)

+

>= 1.0.0

+

softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7)

+

>= 1.0.0

+
+

Soft Tone

+

softToneCreate(pin);

+

>= 1.0.0

+

softToneWrite(pin, frequency);

+

>= 1.0.0

+

softToneStop(pin);

+

>= 1.1.0

+
+

Extensions

+ + diff --git a/README.md b/README.md index 0b563e9..f1e3d26 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ var wpi = require('wiring-pi'); ``` ## Documentation -See the [DOCUMENTATION.md](https://github.com/eugeneware/wiring-pi/blob/master/DOCUMENTATION.md) file for more detailed documentation. +See the [DOCUMENTATION.html](https://github.com/eugeneware/wiring-pi/blob/master/DOCUMENTATION.html) file for more detailed documentation. ## Contributing diff --git a/DOCUMENTATION.md b/docs/DOCUMENTATION.md similarity index 95% rename from DOCUMENTATION.md rename to docs/DOCUMENTATION.md index a1efb00..c6e98ad 100644 --- a/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -1,44 +1,6 @@ - - - - -# Index - -* [Install](#install) -* [Usage](#usage) -* [APIs](#apis) - * [Setup](#setup) - * [wiringPiSetup](#wiringpisetup) - * [wiringPiSetupGpio](#wiringpisetupgpio) - * [Shift](#shift) - # Install -```bash +``` npm install wiring-pi ``` diff --git a/docs/pandoc.css b/docs/pandoc.css new file mode 100644 index 0000000..dc4daf5 --- /dev/null +++ b/docs/pandoc.css @@ -0,0 +1,301 @@ +body { + font-family: Helvetica, arial, sans-serif; + font-size: 14px; + line-height: 1.6; + padding-top: 10px; + padding-bottom: 10px; + background-color: white; + padding: 30px; } + +body > *:first-child { + margin-top: 0 !important; } +body > *:last-child { + margin-bottom: 0 !important; } + +a { + color: #4183C4; } +a.absent { + color: #cc0000; } +a.anchor { + display: block; + padding-left: 30px; + margin-left: -30px; + cursor: pointer; + position: absolute; + top: 0; + left: 0; + bottom: 0; } + +h1, h2, h3, h4, h5, h6 { + margin: 20px 0 10px; + padding: 0; + font-weight: bold; + -webkit-font-smoothing: antialiased; + cursor: text; + position: relative; } + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { + background: url("../../images/modules/styleguide/para.png") no-repeat 10px center; + text-decoration: none; } + +h1 tt, h1 code { + font-size: inherit; } + +h2 tt, h2 code { + font-size: inherit; } + +h3 tt, h3 code { + font-size: inherit; } + +h4 tt, h4 code { + font-size: inherit; } + +h5 tt, h5 code { + font-size: inherit; } + +h6 tt, h6 code { + font-size: inherit; } + +h1 { + font-size: 28px; + color: black; } + +h2 { + font-size: 24px; + border-bottom: 1px solid #cccccc; + color: black; } + +h3 { + font-size: 18px; } + +h4 { + font-size: 16px; } + +h5 { + font-size: 14px; } + +h6 { + color: #777777; + font-size: 14px; } + +p, blockquote, ul, ol, dl, li, table, pre { + margin: 15px 0; } + +hr { + background: transparent url("../../images/modules/pulls/dirty-shade.png") repeat-x 0 0; + border: 0 none; + color: #cccccc; + height: 4px; + padding: 0; } + +body > h2:first-child { + margin-top: 0; + padding-top: 0; } +body > h1:first-child { + margin-top: 0; + padding-top: 0; } + body > h1:first-child + h2 { + margin-top: 0; + padding-top: 0; } +body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child { + margin-top: 0; + padding-top: 0; } + +a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { + margin-top: 0; + padding-top: 0; } + +h1 p, h2 p, h3 p, h4 p, h5 p, h6 p { + margin-top: 0; } + +li p.first { + display: inline-block; } + +ul, ol { + padding-left: 30px; } + +ul :first-child, ol :first-child { + margin-top: 0; } + +ul :last-child, ol :last-child { + margin-bottom: 0; } + +dl { + padding: 0; } + dl dt { + font-size: 14px; + font-weight: bold; + font-style: italic; + padding: 0; + margin: 15px 0 5px; } + dl dt:first-child { + padding: 0; } + dl dt > :first-child { + margin-top: 0; } + dl dt > :last-child { + margin-bottom: 0; } + dl dd { + margin: 0 0 15px; + padding: 0 15px; } + dl dd > :first-child { + margin-top: 0; } + dl dd > :last-child { + margin-bottom: 0; } + +blockquote { + border-left: 4px solid #dddddd; + padding: 0 15px; + color: #777777; } + blockquote > :first-child { + margin-top: 0; } + blockquote > :last-child { + margin-bottom: 0; } + +table { + padding: 0; } + table tr { + border-top: 1px solid #cccccc; + background-color: white; + margin: 0; + padding: 0; } + table tr:nth-child(2n) { + background-color: #f8f8f8; } + table tr th { + font-weight: bold; + border: 1px solid #cccccc; + text-align: left; + margin: 0; + padding: 6px 13px; } + table tr td { + border: 1px solid #cccccc; + text-align: left; + margin: 0; + padding: 6px 13px; } + table tr th :first-child, table tr td :first-child { + margin-top: 0; } + table tr th :last-child, table tr td :last-child { + margin-bottom: 0; } + +img { + max-width: 100%; } + +span.frame { + display: block; + overflow: hidden; } + span.frame > span { + border: 1px solid #dddddd; + display: block; + float: left; + overflow: hidden; + margin: 13px 0 0; + padding: 7px; + width: auto; } + span.frame span img { + display: block; + float: left; } + span.frame span span { + clear: both; + color: #333333; + display: block; + padding: 5px 0 0; } +span.align-center { + display: block; + overflow: hidden; + clear: both; } + span.align-center > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: center; } + span.align-center span img { + margin: 0 auto; + text-align: center; } +span.align-right { + display: block; + overflow: hidden; + clear: both; } + span.align-right > span { + display: block; + overflow: hidden; + margin: 13px 0 0; + text-align: right; } + span.align-right span img { + margin: 0; + text-align: right; } +span.float-left { + display: block; + margin-right: 13px; + overflow: hidden; + float: left; } + span.float-left span { + margin: 13px 0 0; } +span.float-right { + display: block; + margin-left: 13px; + overflow: hidden; + float: right; } + span.float-right > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: right; } + +code, tt { + margin: 0 2px; + padding: 0 5px; + white-space: nowrap; + border: 1px solid #eaeaea; + background-color: #f8f8f8; + border-radius: 3px; } + +pre code { + margin: 0; + padding: 0; + white-space: pre; + border: none; + background: transparent; } + +.highlight pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; } + +pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; } + pre code, pre tt { + background-color: transparent; + border: none; } + +.api-info { + display: block; + text-align: right; + margin-top: -40px; + font-style: italic; +} + +.api-info-list { + display: inline; + float:right; +} + +.api-info-deprecated { + background-color: #F90 !important; + color: #FFF !important; + text-transform: uppercase; +} + +.api-info-removed { + background-color: #D33 !important; + color: #FFF !important; + text-transform: uppercase; +} From 71f29f0426c77e6981a4d90f3dbd5b2b6b6f7fc7 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 15:35:08 +0200 Subject: [PATCH 04/64] Preparing wiring-pi 2.0.0 - UPD: documentation - UPD: install script (add gpio utility installation, make check, fix update) - ADD: drcSerial extension - UPD: examples --- binding.gyp | 3 +++ docs/dirty-shade.png | Bin 0 -> 939 bytes docs/gendoc.sh | 3 +++ docs/pandoc.css | 4 ++-- docs/para.png | Bin 0 -> 1048 bytes examples/blink.js | 2 +- examples/pwm.js | 2 +- install.sh | 30 +++++++++++++++++++++++++++++ src/extensions/drcSerial.cc | 37 ++++++++++++++++++++++++++++++++++++ src/extensions/drcSerial.h | 8 ++++++++ src/wpi.cc | 2 ++ src/wpi.h | 2 ++ 12 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 docs/dirty-shade.png create mode 100644 docs/gendoc.sh create mode 100644 docs/para.png create mode 100644 src/extensions/drcSerial.cc create mode 100644 src/extensions/drcSerial.h diff --git a/binding.gyp b/binding.gyp index b22d142..f4f8f55 100644 --- a/binding.gyp +++ b/binding.gyp @@ -12,6 +12,9 @@ 'src/wiringSerial.cc', 'src/wiringShift.cc', 'src/wiringPiISR.cc', + + 'src/extensions/drcSerial.cc', + 'src/wpi.cc' ], 'include_dirs': [ diff --git a/docs/dirty-shade.png b/docs/dirty-shade.png new file mode 100644 index 0000000000000000000000000000000000000000..3e0e9c90bdf0469caf1afc7f7b8e35dc41aa99ad GIT binary patch literal 939 zcmaJ=&yLbS9Bu?RX5%J%)r*sIm3CVGv`naLX~At`2>}v0I68E`#B(wv*x$VPM%sc<5`*!CP28u*qoIUzjFg2jXA466 zB8#!NBn(W+JctbO_ovSy2z*0))^MR4TVxSjZWA)v_Q&3K>9u_E;t^-VUUGa zQHnA{-032I&aY(=>>zAuh}S_)+ySs?LO?@;RSz~HXeyFYt81F}5U5arGE`+nttuL- zsR%-_|3vOB@n>jg_x8THWrz#LVkFD!^;%ljB$~`+rPXTX8me05h-$it7|yCuS}7E4 zl6pxHvw%h*SHx4gVur{gy-p#F53*6ZFB31AoZ(njB$%gE0A2V0&@eopQ#K?w@%~dd z9dBYH4@pW_iN_l^tK_a?WF-VMnv5yEDyleGP)5@Qje#|402g~fl-oPJ>mnyg8IC;S z*oMdzq#*E-ZdtvWshQ12(^Ql$>}Z|3sn>K(wbWLxt`}UJdaIB`tl;`L+|E&MJ_=#X zJ=-J+UJ}2T&=BlWM#1q|^rL!vu75n1)={p^gOT&b{?+K>ice2|Jd7-TSeeBn>xfn%HF?B~>feETarsWeTXe}C6gl9dganLhU$?bv4U>&^lNpMnERjTwcI_K$pnbJ{xI#Ff zH$r0c;=!Aq3I6~G(Qx5t;>i2#A6R>(50lDh68CTHRb0wr5tMH-4GwOBT` z){L~t&fWzxflLK#M060?>y9r68Mdh_({*^vv!DqfYZ>-DsTFkzzP>A!84k;!iWl@sj)1dXRG@55tWlbrzV$ofOtr6nNJYTQZxq5=b-YPGo z)9Fwn9*g4fyse-h-|#G#Sl9ufqF%upB*W57&#z#+9a+b3*+dQF1Ks5X z4u)5116B3^P}}aHeWIa@eE%uzmp5I+YskkNo+FsbT><%Ha+rnsugCC4YaW1y0f zVQDzdvP?Ohm!x!lE}lxkq97E6l$c5@sf41$b43y6l5MVnjSU+)q|G%ixQVXZux@OZ zMplq#y+CHs!!~I8BU{~bfnD`lT(f&FLRT(Nli|ZE_^T?~N3_(!Wv9mJrqdX-UbIgYT8!jmB(bV&|JMRl8 Td-L}vXeg#sSX2(?p1t}5UOquV literal 0 HcmV?d00001 diff --git a/examples/blink.js b/examples/blink.js index 66aa537..d3a0fb0 100644 --- a/examples/blink.js +++ b/examples/blink.js @@ -1,6 +1,6 @@ var wpi = require('wiring-pi'); -wpi.setup(); +wpi.setup('wpi'); var pin = 0; diff --git a/examples/pwm.js b/examples/pwm.js index ffdb0fe..f7f3ad4 100644 --- a/examples/pwm.js +++ b/examples/pwm.js @@ -2,7 +2,7 @@ var wpi = require('wiring-pi'); var async = require('async'); -wpi.setup(); +wpi.setup('wpi'); var pin = 1; wpi.pinMode(pin, wpi.PWM_OUTPUT); diff --git a/install.sh b/install.sh index ce9fd49..38d7c46 100644 --- a/install.sh +++ b/install.sh @@ -1,7 +1,37 @@ #!/bin/bash +check_make_ok() { + echo "" + echo "================================================================================" + if [ $2 == 1 ]; then + echo "FATAL: Making $1 failed." + else + echo "Making $1 failed." + fi + echo "Please check the messages and fix any problems. If you're still stuck," + echo "then please open a new issue then post all the output and as many details as you can to" + echo " https://github.com/eugeneware/wiring-pi/issues" + echo "================================================================================" + echo "" + if [ $2 == 1 ]; then + exit 1 + fi +} + git clone https://github.com/nekuz0r/wiringpi.git + cd ./wiringpi/wiringPi/ +make clean make static +check_make_ok "libWiringPi" 1 cd ../../ + +cd ./wiringpi/gpio/ +sudo make uninstall +make clean +make +check_make_ok "gpio utility" +sudo make install +check_make_ok "gpio utility" + node-gyp rebuild \ No newline at end of file diff --git a/src/extensions/drcSerial.cc b/src/extensions/drcSerial.cc new file mode 100644 index 0000000..02eb38b --- /dev/null +++ b/src/extensions/drcSerial.cc @@ -0,0 +1,37 @@ +#include "drcSerial.h" +#include +#include + +DECLARE(drcSetupSerial); + +// Func : int drcSetupSerial(const int pinBase, const int numPins, const char* device, const int baud) +// Description : https://projects.drogon.net/drogon-remote-control/drc-protocol-arduino/ + +IMPLEMENT(drcSetupSerial) { + SCOPE_START(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, numPins); + SET_ARGUMENT_NAME(2, device); + SET_ARGUMENT_NAME(3, baudrate); + + CHECK_ARGUMENTS_LENGTH_EQUAL(4); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_STRING(2); + CHECK_ARGUMENT_TYPE_INT32(3); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int numPins = GET_ARGUMENT_AS_INT32(1); + String::AsciiValue device(GET_ARGUMENT_AS_STRING(2)); + int baudrate = GET_ARGUMENT_AS_INT32(3); + + int res = ::drcSetupSerial(pinBase, numPins, device, baudrate); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(drcSerial) { + EXPORT_FUNCTION(drcSetupSerial); +} \ No newline at end of file diff --git a/src/extensions/drcSerial.h b/src/extensions/drcSerial.h new file mode 100644 index 0000000..76e3417 --- /dev/null +++ b/src/extensions/drcSerial.h @@ -0,0 +1,8 @@ +#ifndef _WPI_DRC_SERIAL_H_ +#define _WPI_DRC_SERIAL_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(drcSerial); + +#endif \ No newline at end of file diff --git a/src/wpi.cc b/src/wpi.cc index 991eec4..7b51d86 100644 --- a/src/wpi.cc +++ b/src/wpi.cc @@ -10,6 +10,8 @@ NODE_MODULE_INIT() { INIT(wiringSerial); INIT(wiringShift); INIT(wiringPiISR); + + INIT(drcSerial); } NODE_MODULE_DECLARE(wiringPi); \ No newline at end of file diff --git a/src/wpi.h b/src/wpi.h index 301c9cf..43bad4e 100644 --- a/src/wpi.h +++ b/src/wpi.h @@ -10,5 +10,7 @@ #include "wiringSerial.h" #include "wiringShift.h" #include "wiringPiISR.h" + + #include "extensions/drcSerial.h" #endif \ No newline at end of file From 51189646439055545efbf21bc00a179530f83c82 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 15:57:50 +0200 Subject: [PATCH 05/64] update install script --- .gitignore | 3 +- install.sh | 80 ++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 72bd1fa..1ad15a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build npm-debug.log -wiringpi/ \ No newline at end of file +wiringpi/ +install.log \ No newline at end of file diff --git a/install.sh b/install.sh index 38d7c46..d75b0b2 100644 --- a/install.sh +++ b/install.sh @@ -1,37 +1,77 @@ #!/bin/bash check_make_ok() { - echo "" - echo "================================================================================" - if [ $2 == 1 ]; then - echo "FATAL: Making $1 failed." - else - echo "Making $1 failed." + if [ $? != 0 ]; then + echo "failed." + echo "" + echo "================================================================================" + if [ $2 == 1 ]; then + echo "FATAL: Making $1 failed." + else + echo "Making $1 failed." + fi + echo "Please check install.log and fix any problems. If you're still stuck," + echo "then please open a new issue then post all the output and as many details as you can to" + echo " https://github.com/eugeneware/wiring-pi/issues" + echo "================================================================================" + echo "" + if [ $2 == 1 ]; then + exit 1 + fi fi - echo "Please check the messages and fix any problems. If you're still stuck," - echo "then please open a new issue then post all the output and as many details as you can to" - echo " https://github.com/eugeneware/wiring-pi/issues" - echo "================================================================================" - echo "" - if [ $2 == 1 ]; then +} + +check_git_clone() { + if [ $? != 0 ]; then + echo "failed." + echo "" + echo "================================================================================" + echo "FATAL: Cloning libWiringPi failed." + echo "Please check install.log and fix any problems. If you're still stuck," + echo "then please open a new issue then post all the output and as many details as you can to" + echo " https://github.com/eugeneware/wiring-pi/issues" + echo "================================================================================" + echo "" exit 1 fi } -git clone https://github.com/nekuz0r/wiringpi.git +rm ./install.log 2>/dev/null 1>&2 +echo -n "Cloning libWiringPi ... " +rm -Rf ./wiringpi 2>/dev/null 1>&2 +git clone https://github.com/nekuz0r/wiringpi.git 2>./install.log 1>&2 +check_git_clone +echo "done." + +echo -n "Making libWiringPi ... " cd ./wiringpi/wiringPi/ -make clean -make static +make clean 2>../../install.log 1>&2 +make static 2>../../install.log 1>&2 check_make_ok "libWiringPi" 1 cd ../../ +echo "done." cd ./wiringpi/gpio/ -sudo make uninstall -make clean -make +echo -n "Unistalling gpio utility ... " +sudo make uninstall 2>../../install.log 1>&2 +echo "done." + +echo -n "Making gpio utility ... " +make clean 2>../../install.log 1>&2 +make 2>../../install.log 1>&2 check_make_ok "gpio utility" -sudo make install +echo "done." + +echo -n "Installing gpio utility ... " +sudo make install 2>../../install.log 1>&2 check_make_ok "gpio utility" +cd ../../ +echo "done." + +echo -n "Making wiring-pi ... " +node-gyp rebuild 2>./install.log 1>&2 +check_make_ok "wiring-pi" 1 +echo "done." -node-gyp rebuild \ No newline at end of file +echo "Enjoy !" \ No newline at end of file From 409588be4913404c08691f49e34577e34aa08663 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 19:27:07 +0200 Subject: [PATCH 06/64] Remove c++11 requirement --- binding.gyp | 13 +------------ src/addon.h | 28 ++++++++++++++++++++++------ src/extensions/drcSerial.cc | 4 ++-- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/binding.gyp b/binding.gyp index f4f8f55..658f512 100644 --- a/binding.gyp +++ b/binding.gyp @@ -24,18 +24,7 @@ ' #include #include - #include + //#include using namespace v8; @@ -30,10 +30,10 @@ ThrowException(func(String::New(buffer))); } - template + /*template bool isInList(T value, std::initializer_list values) { return !(std::find(values.begin(), values.end(), value) == values.end()); - } + }*/ #define DECLARE(name) \ namespace nodemodule { \ @@ -113,7 +113,7 @@ #define CHECK_ARGUMENT_TYPE(id, istype) \ if (!args[id]->istype()) { \ - THROW_ERROR("%s: %s(%s) === false", __func__, #istype, GET_ARGUMENT_NAME(id)); \ + THROW_ERROR("%s: %s(arguments['%s']) === false", __func__, #istype, GET_ARGUMENT_NAME(id)); \ } #define CHECK_ARGUMENT_TYPE_INT32(id) CHECK_ARGUMENT_TYPE(id, IsInt32) @@ -124,7 +124,7 @@ #define CHECK_ARGUMENT_TYPE_OBJECT(id) CHECK_ARGUMENT_TYPE(id, IsObject) #define CHECK_ARGUMENT_TYPE_NODE_BUFFER(id) \ if (!(args[id]->IsObject() && node::Buffer::HasInstance(args[id]))) { \ - THROW_ERROR("%s: %s(%s) === false", __func__, "isBuffer", GET_ARGUMENT_NAME(id)); \ + THROW_ERROR("%s: %s(arguments['%s']) === false", __func__, "isBuffer", GET_ARGUMENT_NAME(id)); \ } #define GET_ARGUMENT_AS_TYPE(id, type) args[id]->type() @@ -137,7 +137,7 @@ #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) #define LIST(...) { __VA_ARGS__ } - #define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ + /*#define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ if (!isInList(std::string(*value), LIST T)) { \ THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ } @@ -145,6 +145,22 @@ #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ if (!isInList(value, LIST T)) { \ THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ + }*/ + + #define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ + { \ + std::string strings[] = LIST T; \ + if (std::find(strings, strings + sizeof_array(strings), std::string(*value)) == strings + sizeof_array(strings)) { \ + THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ + } \ + } + + #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ + { \ + int ints[] = LIST T; \ + if (std::find(ints, ints + sizeof_array(ints), value) == ints + sizeof_array(ints)) { \ + THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ + } \ } #endif \ No newline at end of file diff --git a/src/extensions/drcSerial.cc b/src/extensions/drcSerial.cc index 02eb38b..1a7bf1a 100644 --- a/src/extensions/drcSerial.cc +++ b/src/extensions/drcSerial.cc @@ -8,7 +8,7 @@ DECLARE(drcSetupSerial); // Description : https://projects.drogon.net/drogon-remote-control/drc-protocol-arduino/ IMPLEMENT(drcSetupSerial) { - SCOPE_START(); + SCOPE_OPEN(); SET_ARGUMENT_NAME(0, pinBase); SET_ARGUMENT_NAME(1, numPins); @@ -27,7 +27,7 @@ IMPLEMENT(drcSetupSerial) { String::AsciiValue device(GET_ARGUMENT_AS_STRING(2)); int baudrate = GET_ARGUMENT_AS_INT32(3); - int res = ::drcSetupSerial(pinBase, numPins, device, baudrate); + int res = ::drcSetupSerial(pinBase, numPins, *device, baudrate); SCOPE_CLOSE(INT32(res)); } From a42d1ae2ab6905b08c1809a9ed7008cfab71cfe1 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 21:43:39 +0200 Subject: [PATCH 07/64] Add all remaining extensions :) --- binding.gyp | 20 +++++++++++++-- src/addon.h | 8 ++++-- src/extensions/extensions.cc | 38 ++++++++++++++++++++++++++++ src/extensions/extensions.h | 8 ++++++ src/extensions/max31855.cc | 31 +++++++++++++++++++++++ src/extensions/max31855.h | 8 ++++++ src/extensions/max5322.cc | 32 ++++++++++++++++++++++++ src/extensions/max5322.h | 8 ++++++ src/extensions/mcp23008.cc | 29 ++++++++++++++++++++++ src/extensions/mcp23008.h | 8 ++++++ src/extensions/mcp23016.cc | 29 ++++++++++++++++++++++ src/extensions/mcp23016.h | 8 ++++++ src/extensions/mcp23017.cc | 29 ++++++++++++++++++++++ src/extensions/mcp23017.h | 8 ++++++ src/extensions/mcp23s08.cc | 37 +++++++++++++++++++++++++++ src/extensions/mcp23s08.h | 8 ++++++ src/extensions/mcp23s17.cc | 40 ++++++++++++++++++++++++++++++ src/extensions/mcp23s17.h | 8 ++++++ src/extensions/mcp3002.cc | 31 +++++++++++++++++++++++ src/extensions/mcp3002.h | 8 ++++++ src/extensions/mcp3004.cc | 31 +++++++++++++++++++++++ src/extensions/mcp3004.h | 8 ++++++ src/extensions/mcp3422.cc | 48 ++++++++++++++++++++++++++++++++++++ src/extensions/mcp3422.h | 8 ++++++ src/extensions/mcp4802.cc | 31 +++++++++++++++++++++++ src/extensions/mcp4802.h | 8 ++++++ src/extensions/pca9685.cc | 30 ++++++++++++++++++++++ src/extensions/pca9685.h | 8 ++++++ src/extensions/pcf8574.cc | 29 ++++++++++++++++++++++ src/extensions/pcf8574.h | 8 ++++++ src/extensions/pcf8591.cc | 29 ++++++++++++++++++++++ src/extensions/pcf8591.h | 8 ++++++ src/extensions/sn3218.cc | 26 +++++++++++++++++++ src/extensions/sn3218.h | 8 ++++++ src/extensions/sr595.cc | 38 ++++++++++++++++++++++++++++ src/extensions/sr595.h | 8 ++++++ src/softPwm.cc | 1 - src/softServo.cc | 1 - src/softTone.cc | 1 - src/wiringPiI2C.cc | 1 - src/wiringPiISR.cc | 2 +- src/wiringPiSPI.cc | 1 - src/wiringSerial.cc | 1 - src/wiringShift.cc | 1 - src/wpi.cc | 2 +- src/wpi.h | 2 +- 46 files changed, 721 insertions(+), 14 deletions(-) create mode 100644 src/extensions/extensions.cc create mode 100644 src/extensions/extensions.h create mode 100644 src/extensions/max31855.cc create mode 100644 src/extensions/max31855.h create mode 100644 src/extensions/max5322.cc create mode 100644 src/extensions/max5322.h create mode 100644 src/extensions/mcp23008.cc create mode 100644 src/extensions/mcp23008.h create mode 100644 src/extensions/mcp23016.cc create mode 100644 src/extensions/mcp23016.h create mode 100644 src/extensions/mcp23017.cc create mode 100644 src/extensions/mcp23017.h create mode 100644 src/extensions/mcp23s08.cc create mode 100644 src/extensions/mcp23s08.h create mode 100644 src/extensions/mcp23s17.cc create mode 100644 src/extensions/mcp23s17.h create mode 100644 src/extensions/mcp3002.cc create mode 100644 src/extensions/mcp3002.h create mode 100644 src/extensions/mcp3004.cc create mode 100644 src/extensions/mcp3004.h create mode 100644 src/extensions/mcp3422.cc create mode 100644 src/extensions/mcp3422.h create mode 100644 src/extensions/mcp4802.cc create mode 100644 src/extensions/mcp4802.h create mode 100644 src/extensions/pca9685.cc create mode 100644 src/extensions/pca9685.h create mode 100644 src/extensions/pcf8574.cc create mode 100644 src/extensions/pcf8574.h create mode 100644 src/extensions/pcf8591.cc create mode 100644 src/extensions/pcf8591.h create mode 100644 src/extensions/sn3218.cc create mode 100644 src/extensions/sn3218.h create mode 100644 src/extensions/sr595.cc create mode 100644 src/extensions/sr595.h diff --git a/binding.gyp b/binding.gyp index 658f512..9e3f67e 100644 --- a/binding.gyp +++ b/binding.gyp @@ -12,10 +12,26 @@ 'src/wiringSerial.cc', 'src/wiringShift.cc', 'src/wiringPiISR.cc', + 'src/wpi.cc', + 'src/extensions/extensions.cc', 'src/extensions/drcSerial.cc', - - 'src/wpi.cc' + 'src/extensions/max5322.cc', + 'src/extensions/max31855.cc', + 'src/extensions/mcp23s08.cc', + 'src/extensions/mcp23s17.cc', + 'src/extensions/mcp3002.cc', + 'src/extensions/mcp3004.cc', + 'src/extensions/mcp3422.cc', + 'src/extensions/mcp4802.cc', + 'src/extensions/mcp23008.cc', + 'src/extensions/mcp23016.cc', + 'src/extensions/mcp23017.cc', + 'src/extensions/pcf8574.cc', + 'src/extensions/pcf8591.cc', + 'src/extensions/sn3218.cc', + 'src/extensions/sr595.cc', + 'src/extensions/pca9685.cc' ], 'include_dirs': [ 'wiringpi/wiringPi' diff --git a/src/addon.h b/src/addon.h index 5fac119..414a4cf 100644 --- a/src/addon.h +++ b/src/addon.h @@ -4,8 +4,7 @@ #include #include #include - #include - #include + #include #include //#include @@ -162,5 +161,10 @@ THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ } \ } + + #define CHECK_ARGUMENT_IN_RANGE(id, value, min, max) \ + if (value < min || value > max) { \ + THROW_ERROR("%s: arguments['%s'] => inRange(%i, [%i, %i]) === false", __func__, GET_ARGUMENT_NAME(id), value, min, max); \ + } #endif \ No newline at end of file diff --git a/src/extensions/extensions.cc b/src/extensions/extensions.cc new file mode 100644 index 0000000..2f3002e --- /dev/null +++ b/src/extensions/extensions.cc @@ -0,0 +1,38 @@ +#include "extensions.h" + +#include "drcSerial.h" +#include "max5322.h" +#include "max31855.h" +#include "mcp23s08.h" +#include "mcp23s17.h" +#include "mcp3002.h" +#include "mcp3004.h" +#include "mcp3422.h" +#include "mcp4802.h" +#include "mcp23008.h" +#include "mcp23016.h" +#include "mcp23017.h" +#include "pcf8574.h" +#include "pcf8591.h" +#include "sn3218.h" +#include "sr595.h" +#include "pca9685.h" + +IMPLEMENT_EXPORT_INIT(extensions) { + INIT(drcSerial); + INIT(max5322); + INIT(max31855); + INIT(mcp23s08); + INIT(mcp23s17); + INIT(mcp3002); + INIT(mcp3004); + INIT(mcp3422); + INIT(mcp4802); + INIT(mcp23008); + INIT(mcp23016); + INIT(mcp23017); + INIT(pcf8574); + INIT(pcf8591); + INIT(sr595); + INIT(pca9685); +} \ No newline at end of file diff --git a/src/extensions/extensions.h b/src/extensions/extensions.h new file mode 100644 index 0000000..c2a90a4 --- /dev/null +++ b/src/extensions/extensions.h @@ -0,0 +1,8 @@ +#ifndef _WPI_EXTENSIONS_H_ +#define _WPI_EXTENSIONS_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(extensions); + +#endif \ No newline at end of file diff --git a/src/extensions/max31855.cc b/src/extensions/max31855.cc new file mode 100644 index 0000000..65a3f8c --- /dev/null +++ b/src/extensions/max31855.cc @@ -0,0 +1,31 @@ +#include "max31855.h" +#include + +DECLARE(max31855Setup); + +// Func : int max31855Setup(int pinBase, int spiChannel) + +IMPLEMENT(max31855Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::max31855Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(max31855) { + EXPORT_FUNCTION(max31855Setup); +} \ No newline at end of file diff --git a/src/extensions/max31855.h b/src/extensions/max31855.h new file mode 100644 index 0000000..caebaeb --- /dev/null +++ b/src/extensions/max31855.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MAX31855_H_ +#define _WPI_MAX31855_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(max31855); + +#endif \ No newline at end of file diff --git a/src/extensions/max5322.cc b/src/extensions/max5322.cc new file mode 100644 index 0000000..9b945b4 --- /dev/null +++ b/src/extensions/max5322.cc @@ -0,0 +1,32 @@ +#include "max5322.h" +#include + +DECLARE(max5322Setup); + +// Func : int max5233Setup(int pinBase, int spiChannel) + +IMPLEMENT(max5322Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::max5322Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + + +IMPLEMENT_EXPORT_INIT(max5322) { + EXPORT_FUNCTION(max5322Setup); +} \ No newline at end of file diff --git a/src/extensions/max5322.h b/src/extensions/max5322.h new file mode 100644 index 0000000..912d267 --- /dev/null +++ b/src/extensions/max5322.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MAX5322_H_ +#define _WPI_MAX5322_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(max5322); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23008.cc b/src/extensions/mcp23008.cc new file mode 100644 index 0000000..f254d34 --- /dev/null +++ b/src/extensions/mcp23008.cc @@ -0,0 +1,29 @@ +#include "mcp23008.h" +#include + +DECLARE(mcp23008Setup); + +// Func : int mcp23008Setup(int pinBase, int i2cAddress) + +IMPLEMENT(mcp23008Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::mcp23008Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23008) { + EXPORT_FUNCTION(mcp23008Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23008.h b/src/extensions/mcp23008.h new file mode 100644 index 0000000..5297854 --- /dev/null +++ b/src/extensions/mcp23008.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23008_H_ +#define _WPI_MCP23008_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23008); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23016.cc b/src/extensions/mcp23016.cc new file mode 100644 index 0000000..46f2751 --- /dev/null +++ b/src/extensions/mcp23016.cc @@ -0,0 +1,29 @@ +#include "mcp23016.h" +#include + +DECLARE(mcp23016Setup); + +// Func : int mcp23016Setup(int pinBase, int i2cAddress) + +IMPLEMENT(mcp23016Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::mcp23016Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23016) { + EXPORT_FUNCTION(mcp23016Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23016.h b/src/extensions/mcp23016.h new file mode 100644 index 0000000..64a6761 --- /dev/null +++ b/src/extensions/mcp23016.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23016_H_ +#define _WPI_MCP23016_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23016); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23017.cc b/src/extensions/mcp23017.cc new file mode 100644 index 0000000..aebdc8b --- /dev/null +++ b/src/extensions/mcp23017.cc @@ -0,0 +1,29 @@ +#include "mcp23017.h" +#include + +DECLARE(mcp23017Setup); + +// Func : int mcp23017Setup(int pinBase, int i2cAddress) + +IMPLEMENT(mcp23017Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::mcp23017Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23017) { + EXPORT_FUNCTION(mcp23017Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23017.h b/src/extensions/mcp23017.h new file mode 100644 index 0000000..4ca67ff --- /dev/null +++ b/src/extensions/mcp23017.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23017_H_ +#define _WPI_MCP23017_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23017); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23s08.cc b/src/extensions/mcp23s08.cc new file mode 100644 index 0000000..94bd38f --- /dev/null +++ b/src/extensions/mcp23s08.cc @@ -0,0 +1,37 @@ +#include "mcp23s08.h" +#include + +DECLARE(mcp23s08Setup); + +// Func int mcp23s08Setup(const int pinBase, const int spiChannel, const int devId) + +IMPLEMENT(mcp23s08Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + SET_ARGUMENT_NAME(2, devId); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + int devId = GET_ARGUMENT_AS_INT32(2); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + //MCP23S08 3bits addressing + CHECK_ARGUMENT_IN_RANGE(2, devId, 0, 7); + + int res = ::mcp23s08Setup(pinBase, spiChannel, devId); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23s08) { + EXPORT_FUNCTION(mcp23s08Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23s08.h b/src/extensions/mcp23s08.h new file mode 100644 index 0000000..2eabae4 --- /dev/null +++ b/src/extensions/mcp23s08.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23S08_H_ +#define _WPI_MCP23S08_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23s08); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23s17.cc b/src/extensions/mcp23s17.cc new file mode 100644 index 0000000..3352812 --- /dev/null +++ b/src/extensions/mcp23s17.cc @@ -0,0 +1,40 @@ +#include "mcp23s17.h" +#include + +DECLARE(mcp23s17Setup); + +// Func : int mcp23s17Setup(int pinBase, int spiPort, int devId) +// Description : Initialise libWiringPi to be used with MCP23S17 +// pinBase is any number above 64 that doesn’t clash with any other wiringPi expansion module, +// spiPort is 0 or 1 for one of the two SPI ports on the Pi and devId is the ID of that MCP23s17 on the SPI port. + +IMPLEMENT(mcp23s17Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + SET_ARGUMENT_NAME(2, devId); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + int devId = GET_ARGUMENT_AS_INT32(2); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + //MCP23S17 3bits addressing + CHECK_ARGUMENT_IN_RANGE(2, devId, 0, 7); + + int res = ::mcp23s17Setup(pinBase, spiChannel, devId); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23s17) { + EXPORT_FUNCTION(mcp23s17Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23s17.h b/src/extensions/mcp23s17.h new file mode 100644 index 0000000..9e71198 --- /dev/null +++ b/src/extensions/mcp23s17.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23S17_H_ +#define _WPI_MCP23S17_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23s17); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp3002.cc b/src/extensions/mcp3002.cc new file mode 100644 index 0000000..1332690 --- /dev/null +++ b/src/extensions/mcp3002.cc @@ -0,0 +1,31 @@ +#include "mcp3002.h" +#include + +DECLARE(mcp3002Setup); + +// Func : int mcp3002Setup(int pinBase, int spiChannel) + +IMPLEMENT(mcp3002Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::mcp3002Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp3002) { + EXPORT_FUNCTION(mcp3002Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp3002.h b/src/extensions/mcp3002.h new file mode 100644 index 0000000..242c3b7 --- /dev/null +++ b/src/extensions/mcp3002.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP3002_H_ +#define _WPI_MCP3002_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp3002); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp3004.cc b/src/extensions/mcp3004.cc new file mode 100644 index 0000000..78bbc60 --- /dev/null +++ b/src/extensions/mcp3004.cc @@ -0,0 +1,31 @@ +#include "mcp3004.h" +#include + +DECLARE(mcp3004Setup); + +// Func : int mcp3004Setup(int pinBase, int spiChannel) + +IMPLEMENT(mcp3004Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::mcp3004Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp3004) { + EXPORT_FUNCTION(mcp3004Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp3004.h b/src/extensions/mcp3004.h new file mode 100644 index 0000000..176ca0b --- /dev/null +++ b/src/extensions/mcp3004.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP3004_H_ +#define _WPI_MCP3004_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp3004); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp3422.cc b/src/extensions/mcp3422.cc new file mode 100644 index 0000000..30211a0 --- /dev/null +++ b/src/extensions/mcp3422.cc @@ -0,0 +1,48 @@ +#include "mcp3422.h" +#include + +DECLARE(mcp3422Setup); + +// Func : int mcp3422Setup(int pinBase, int i2cAddress, int sampleRate, int gain) + +IMPLEMENT(mcp3422Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + SET_ARGUMENT_NAME(2, sampleRate); + SET_ARGUMENT_NAME(3, gain); + + CHECK_ARGUMENTS_LENGTH_EQUAL(4); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + int sampleRate = GET_ARGUMENT_AS_INT32(2); + int gain = GET_ARGUMENT_AS_INT32(3); + + CHECK_ARGUMENT_IN_INTS(2, sampleRate, (MCP3422_SR_3_75, MCP3422_SR_15, MCP3422_SR_60, MCP3422_SR_240)); + CHECK_ARGUMENT_IN_INTS(3, gain, (MCP3422_GAIN_1, MCP3422_GAIN_2, MCP3422_GAIN_4, MCP3422_GAIN_8)); + + int res = ::mcp3422Setup(pinBase, i2cAddress, sampleRate, gain); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp3422) { + EXPORT_FUNCTION(mcp3422Setup); + + EXPORT_CONSTANT_INT(MCP3422_SR_3_75); + EXPORT_CONSTANT_INT(MCP3422_SR_15); + EXPORT_CONSTANT_INT(MCP3422_SR_60); + EXPORT_CONSTANT_INT(MCP3422_SR_240); + + EXPORT_CONSTANT_INT(MCP3422_GAIN_1); + EXPORT_CONSTANT_INT(MCP3422_GAIN_2); + EXPORT_CONSTANT_INT(MCP3422_GAIN_4); + EXPORT_CONSTANT_INT(MCP3422_GAIN_8); +} \ No newline at end of file diff --git a/src/extensions/mcp3422.h b/src/extensions/mcp3422.h new file mode 100644 index 0000000..57bfe74 --- /dev/null +++ b/src/extensions/mcp3422.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP3422_H_ +#define _WPI_MCP3422_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp3422); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp4802.cc b/src/extensions/mcp4802.cc new file mode 100644 index 0000000..f12732e --- /dev/null +++ b/src/extensions/mcp4802.cc @@ -0,0 +1,31 @@ +#include "mcp4802.h" +#include + +DECLARE(mcp4802Setup); + +// Func : int mcp4802Setup(int pinBase, int spiChannel) + +IMPLEMENT(mcp4802Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::mcp4802Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp4802) { + EXPORT_FUNCTION(mcp4802Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp4802.h b/src/extensions/mcp4802.h new file mode 100644 index 0000000..a8d887f --- /dev/null +++ b/src/extensions/mcp4802.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP4802_H_ +#define _WPI_MCP4802_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp4802); + +#endif \ No newline at end of file diff --git a/src/extensions/pca9685.cc b/src/extensions/pca9685.cc new file mode 100644 index 0000000..309347c --- /dev/null +++ b/src/extensions/pca9685.cc @@ -0,0 +1,30 @@ +#include "pca9685.h" +#include + +DECLARE(pca9685Setup); + +IMPLEMENT(pca9685Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + SET_ARGUMENT_NAME(2, frequency); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + int freq = GET_ARGUMENT_AS_INT32(2); + + int res = ::pca9685Setup(pinBase, i2cAddress, freq); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(pca9685) { + EXPORT_FUNCTION(pca9685Setup); +} \ No newline at end of file diff --git a/src/extensions/pca9685.h b/src/extensions/pca9685.h new file mode 100644 index 0000000..bbf4dc3 --- /dev/null +++ b/src/extensions/pca9685.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PCA9685_H_ +#define _WPI_PCA9685_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(pca9685); + +#endif \ No newline at end of file diff --git a/src/extensions/pcf8574.cc b/src/extensions/pcf8574.cc new file mode 100644 index 0000000..7e10b5b --- /dev/null +++ b/src/extensions/pcf8574.cc @@ -0,0 +1,29 @@ +#include "pcf8574.h" +#include + +DECLARE(pcf8574Setup); + +// Func : int pcf8574Setup(const int pinBase, const int i2cAddress) + +IMPLEMENT(pcf8574Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::pcf8574Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(pcf8574) { + EXPORT_FUNCTION(pcf8574Setup); +} \ No newline at end of file diff --git a/src/extensions/pcf8574.h b/src/extensions/pcf8574.h new file mode 100644 index 0000000..53d42a2 --- /dev/null +++ b/src/extensions/pcf8574.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PCF8574_H_ +#define _WPI_PCF8574_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(pcf8574); + +#endif \ No newline at end of file diff --git a/src/extensions/pcf8591.cc b/src/extensions/pcf8591.cc new file mode 100644 index 0000000..fd9744a --- /dev/null +++ b/src/extensions/pcf8591.cc @@ -0,0 +1,29 @@ +#include "pcf8591.h" +#include + +DECLARE(pcf8591Setup); + +// Func : int pcf8591Setup(const int pinBase, const int i2cAddress) + +IMPLEMENT(pcf8591Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::pcf8591Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(pcf8591) { + EXPORT_FUNCTION(pcf8591Setup); +} \ No newline at end of file diff --git a/src/extensions/pcf8591.h b/src/extensions/pcf8591.h new file mode 100644 index 0000000..2cfa1d9 --- /dev/null +++ b/src/extensions/pcf8591.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PCF8591_H_ +#define _WPI_PCF8591_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(pcf8591); + +#endif \ No newline at end of file diff --git a/src/extensions/sn3218.cc b/src/extensions/sn3218.cc new file mode 100644 index 0000000..d125cc4 --- /dev/null +++ b/src/extensions/sn3218.cc @@ -0,0 +1,26 @@ +#include "sn3218.h" +#include + +DECLARE(sn3218Setup); + +// Func : int sn3128Setup(int pinBase) + +IMPLEMENT(sn3218Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + + int res = ::sn3218Setup(pinBase); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(sn3218) { + EXPORT_FUNCTION(sn3218Setup); +} \ No newline at end of file diff --git a/src/extensions/sn3218.h b/src/extensions/sn3218.h new file mode 100644 index 0000000..a1ce2f4 --- /dev/null +++ b/src/extensions/sn3218.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SN3218_H_ +#define _WPI_SN3218_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(sn3218); + +#endif \ No newline at end of file diff --git a/src/extensions/sr595.cc b/src/extensions/sr595.cc new file mode 100644 index 0000000..0db70fd --- /dev/null +++ b/src/extensions/sr595.cc @@ -0,0 +1,38 @@ +#include "sr595.h" +#include + +DECLARE(sr595Setup); + +// Func : int sr595Setup(const int pinBase, const int numPins, const int dataPin, const int clockPin, const int latchPin) + +IMPLEMENT(sr595Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, numPins); + SET_ARGUMENT_NAME(2, dataPin); + SET_ARGUMENT_NAME(3, clockPin); + SET_ARGUMENT_NAME(4, latchPin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(5); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int numPins = GET_ARGUMENT_AS_INT32(1); + int dataPin = GET_ARGUMENT_AS_INT32(2); + int clockPin = GET_ARGUMENT_AS_INT32(3); + int latchPin = GET_ARGUMENT_AS_INT32(4); + + int res = ::sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(sr595) { + EXPORT_FUNCTION(sr595Setup); +} \ No newline at end of file diff --git a/src/extensions/sr595.h b/src/extensions/sr595.h new file mode 100644 index 0000000..e25bfb6 --- /dev/null +++ b/src/extensions/sr595.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SR595_H_ +#define _WPI_SR595_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(sr595); + +#endif \ No newline at end of file diff --git a/src/softPwm.cc b/src/softPwm.cc index c602caf..a9cdd04 100644 --- a/src/softPwm.cc +++ b/src/softPwm.cc @@ -1,5 +1,4 @@ #include "softPwm.h" -#include #include DECLARE(softPwmCreate); diff --git a/src/softServo.cc b/src/softServo.cc index 60bdc5a..f082efb 100644 --- a/src/softServo.cc +++ b/src/softServo.cc @@ -1,5 +1,4 @@ #include "softServo.h" -#include #include DECLARE(softServoWrite); diff --git a/src/softTone.cc b/src/softTone.cc index 48ab5b9..61999e3 100644 --- a/src/softTone.cc +++ b/src/softTone.cc @@ -1,5 +1,4 @@ #include "softTone.h" -#include #include DECLARE(softToneCreate); diff --git a/src/wiringPiI2C.cc b/src/wiringPiI2C.cc index e5e5481..38203be 100644 --- a/src/wiringPiI2C.cc +++ b/src/wiringPiI2C.cc @@ -1,5 +1,4 @@ #include "wiringPiI2C.h" -#include #include DECLARE(wiringPiI2CRead); diff --git a/src/wiringPiISR.cc b/src/wiringPiISR.cc index 12bad63..101c43d 100644 --- a/src/wiringPiISR.cc +++ b/src/wiringPiISR.cc @@ -1,6 +1,6 @@ #include "wiringPiISR.h" -#include #include +#include #include using namespace v8; diff --git a/src/wiringPiSPI.cc b/src/wiringPiSPI.cc index fcde1c0..a8210f6 100644 --- a/src/wiringPiSPI.cc +++ b/src/wiringPiSPI.cc @@ -1,5 +1,4 @@ #include "wiringPiSPI.h" -#include #include DECLARE(wiringPiSPIGetFd); diff --git a/src/wiringSerial.cc b/src/wiringSerial.cc index 51b8af1..55360f6 100644 --- a/src/wiringSerial.cc +++ b/src/wiringSerial.cc @@ -1,5 +1,4 @@ #include "wiringSerial.h" -#include #include DECLARE(serialOpen); diff --git a/src/wiringShift.cc b/src/wiringShift.cc index 4d54780..4e34978 100644 --- a/src/wiringShift.cc +++ b/src/wiringShift.cc @@ -1,5 +1,4 @@ #include "wiringShift.h" -#include #include DECLARE(shiftIn); diff --git a/src/wpi.cc b/src/wpi.cc index 7b51d86..306d9c1 100644 --- a/src/wpi.cc +++ b/src/wpi.cc @@ -11,7 +11,7 @@ NODE_MODULE_INIT() { INIT(wiringShift); INIT(wiringPiISR); - INIT(drcSerial); + INIT(extensions); } NODE_MODULE_DECLARE(wiringPi); \ No newline at end of file diff --git a/src/wpi.h b/src/wpi.h index 43bad4e..a61262b 100644 --- a/src/wpi.h +++ b/src/wpi.h @@ -11,6 +11,6 @@ #include "wiringShift.h" #include "wiringPiISR.h" - #include "extensions/drcSerial.h" + #include "extensions/extensions.h" #endif \ No newline at end of file From 73ef6100413d2920676a2270a4dcb5276a8e6753 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 3 Jul 2014 23:29:42 +0200 Subject: [PATCH 08/64] fix some bugs --- install.sh | 22 +++++++++++----------- src/addon.h | 3 ++- src/wiringPi.cc | 1 + 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/install.sh b/install.sh index d75b0b2..8985f38 100644 --- a/install.sh +++ b/install.sh @@ -40,38 +40,38 @@ rm ./install.log 2>/dev/null 1>&2 echo -n "Cloning libWiringPi ... " rm -Rf ./wiringpi 2>/dev/null 1>&2 -git clone https://github.com/nekuz0r/wiringpi.git 2>./install.log 1>&2 +git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 check_git_clone echo "done." echo -n "Making libWiringPi ... " cd ./wiringpi/wiringPi/ -make clean 2>../../install.log 1>&2 -make static 2>../../install.log 1>&2 +make clean >> ../../install.log 2>&1 +make static >> ../../install.log 2>&1 check_make_ok "libWiringPi" 1 cd ../../ echo "done." cd ./wiringpi/gpio/ echo -n "Unistalling gpio utility ... " -sudo make uninstall 2>../../install.log 1>&2 +sudo make uninstall >> ../../install.log 2>&1 echo "done." echo -n "Making gpio utility ... " -make clean 2>../../install.log 1>&2 -make 2>../../install.log 1>&2 -check_make_ok "gpio utility" +make clean >> ../../install.log 2>&1 +make >> ../../install.log 2>&1 +check_make_ok "gpio utility" 0 echo "done." echo -n "Installing gpio utility ... " -sudo make install 2>../../install.log 1>&2 -check_make_ok "gpio utility" +sudo make install >> ../../install.log 2>&1 +check_make_ok "gpio utility" 0 cd ../../ echo "done." echo -n "Making wiring-pi ... " -node-gyp rebuild 2>./install.log 1>&2 +node-gyp rebuild 2>&1 | tee -a ./install.log check_make_ok "wiring-pi" 1 echo "done." -echo "Enjoy !" \ No newline at end of file +echo "Enjoy !" diff --git a/src/addon.h b/src/addon.h index 414a4cf..97e0ec7 100644 --- a/src/addon.h +++ b/src/addon.h @@ -6,6 +6,7 @@ #include #include #include + #include //#include using namespace v8; @@ -167,4 +168,4 @@ THROW_ERROR("%s: arguments['%s'] => inRange(%i, [%i, %i]) === false", __func__, GET_ARGUMENT_NAME(id), value, min, max); \ } -#endif \ No newline at end of file +#endif diff --git a/src/wiringPi.cc b/src/wiringPi.cc index 2860d54..16c2506 100644 --- a/src/wiringPi.cc +++ b/src/wiringPi.cc @@ -1,5 +1,6 @@ #include "wiringPi.h" #include +#include // Setup DECLARE(setup); From a23114861cce91b79b3295b70a5233847172b816 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 09:48:04 +0200 Subject: [PATCH 09/64] Optimizing compilation time --- binding.gyp | 2 + src/addon.cc | 31 ++++++++++++ src/addon.h | 120 +++++++++++++++++---------------------------- src/wiringPiISR.cc | 1 + src/wpi.cc | 1 + 5 files changed, 81 insertions(+), 74 deletions(-) create mode 100644 src/addon.cc diff --git a/binding.gyp b/binding.gyp index 9e3f67e..43d8d9a 100644 --- a/binding.gyp +++ b/binding.gyp @@ -3,6 +3,8 @@ { 'target_name': 'wiringPi', 'sources': [ + 'src/addon.cc', + 'src/wiringPi.cc', 'src/softPwm.cc', 'src/softServo.cc', diff --git a/src/addon.cc b/src/addon.cc new file mode 100644 index 0000000..ab1dec3 --- /dev/null +++ b/src/addon.cc @@ -0,0 +1,31 @@ +#include "addon.h" +#include +#include + +bool find_string(const char* string, const char* array[], size_t s) { + for (size_t i = 0; i < s; i++) { + if (!strcasecmp(string, array[i])) { + return true; + } + } + return false; +} + +bool find_int(const int value, const int array[], size_t s) { + for (size_t i = 0; i < s; i++) { + if (value == array[i]) { + return true; + } + } + return false; +} + +void throw_error(const char* format, ...) { + char buffer[256]; + va_list args; + va_start(args, format); + vsnprintf(buffer, 156, format, args); + va_end(args); + + v8::ThrowException(v8::Exception::Error(v8::String::New(buffer))); +} \ No newline at end of file diff --git a/src/addon.h b/src/addon.h index 97e0ec7..ce3ed9e 100644 --- a/src/addon.h +++ b/src/addon.h @@ -1,106 +1,88 @@ #ifndef _ADDON_H_ #define _ADDON_H_ - - #include - #include + #include - #include - #include - #include - //#include using namespace v8; - template - struct type_of_size { typedef char type[N]; }; - - template - char (&sizeof_array_helper(T(&)[size]))[size]; - - #define sizeof_array(array) sizeof(sizeof_array_helper(array)) - - template - void ThrowError(T func, const char* format, ...) { - char buffer[256]; - va_list args; - va_start(args, format); - vsnprintf(buffer, 156, format, args); - va_end(args); - - ThrowException(func(String::New(buffer))); + // We don't want to include the whole node headers :) + namespace node { + namespace Buffer { + bool HasInstance(v8::Handle val); + bool HasInstance(v8::Handle val); + char* Data(v8::Handle val); + char* Data(v8::Handle val); + size_t Length(v8::Handle val); + size_t Length(v8::Handle val); + } } - - /*template - bool isInList(T value, std::initializer_list values) { - return !(std::find(values.begin(), values.end(), value) == values.end()); - }*/ + + bool find_string(const char* string, const char* array[], size_t s); + bool find_int(const int value, const int array[], size_t s); + void throw_error(const char* fmt, ...); #define DECLARE(name) \ namespace nodemodule { \ - static Handle name(const Arguments& args); \ + static v8::Handle name(const v8::Arguments& args); \ } #define IMPLEMENT(name) \ - Handle nodemodule::name(const Arguments& args) + v8::Handle nodemodule::name(const v8::Arguments& args) #define EXPORT_FUNCTION(name) \ - target->Set(String::NewSymbol(#name), \ - FunctionTemplate::New(nodemodule::name)->GetFunction()) + target->Set(v8::String::NewSymbol(#name), \ + v8::FunctionTemplate::New(nodemodule::name)->GetFunction()) #define EXPORT_CONSTANT_INT(name) \ - target->Set(String::NewSymbol(#name), \ - Int32::New(name), static_cast(ReadOnly | DontDelete)); + target->Set(v8::String::NewSymbol(#name), \ + v8::Int32::New(name), static_cast(v8::ReadOnly | v8::DontDelete)); #define EXPORT_CONSTANT_STRING(name) \ - target->Set(String::NewSymbol(#name), \ - String::New(name), static_cast(ReadOnly | DontDelete)); + target->Set(v8::String::NewSymbol(#name), \ + v8::String::New(name), static_cast(v8::ReadOnly | v8::DontDelete)); #define EXPORT_CONSTANT_INT_ARRAY(name, array, length) \ { \ - Local arr = Array::New(); \ + v8::Local arr = v8::Array::New(); \ for (int i = 0; i < length; i++) { \ - arr->Set(i, INT32(array[i])); \ + arr->Set(i, v8::Int32::New(array[i])); \ } \ - target->Set(String::NewSymbol(#name), arr, static_cast(ReadOnly | DontDelete)); \ + target->Set(v8::String::NewSymbol(#name), arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ } #define EXPORT_CONSTANT_STRING_ARRAY(name, array, length) \ { \ - Local arr = Array::New(); \ + v8::Local arr = v8::Array::New(); \ for (int i = 0; i < length; i++) { \ - arr->Set(i, STRING(array[i])); \ + arr->Set(i, v8::Int32::New(array[i])); \ } \ - target->Set(String::NewSymbol(#name), arr, static_cast(ReadOnly | DontDelete)); \ + target->Set(v8::String::NewSymbol(#name), arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ } #define NODE_MODULE_INIT() \ namespace nodemodule { \ - void init(Handle target); \ + void init(v8::Handle target); \ } \ - void nodemodule::init(Handle target) + void nodemodule::init(v8::Handle target) #define NODE_MODULE_DECLARE(name) NODE_MODULE(name, nodemodule::init) - #define IMPLEMENT_EXPORT_INIT(name) void nodemodule::init##name(Handle target) + #define IMPLEMENT_EXPORT_INIT(name) void nodemodule::init##name(v8::Handle target) #define DECLARE_EXPORT_INIT(name) \ namespace nodemodule { \ - void init##name(Handle target); \ + void init##name(v8::Handle target); \ } #define INIT(name) nodemodule::init##name(target); - #define SCOPE_OPEN() HandleScope scope + #define SCOPE_OPEN() v8::HandleScope scope #define SCOPE_CLOSE(obj) return scope.Close(obj) - #define UNDEFINED() Undefined() - #define INT32(v) Int32::New(v) - #define UINT32(v) Uint32::New(v) - #define STRING(v) String::New(v) + #define UNDEFINED() v8::Undefined() + #define INT32(v) v8::Int32::New(v) + #define UINT32(v) v8::Uint32::New(v) + #define STRING(v) v8::String::New(v) #define THROW_ERROR(fmt, ...) \ - ThrowError(Exception::Error, fmt, __VA_ARGS__); \ - SCOPE_CLOSE(UNDEFINED()) - - #define THROW_TYPE_ERROR(fmt, ...) \ - ThrowError(Exception::TypeError, fmt, __VA_ARGS__); \ + throw_error(fmt, __VA_ARGS__); \ SCOPE_CLOSE(UNDEFINED()) #define SET_ARGUMENT_NAME(id, name) static const char* arg##id = #name @@ -133,32 +115,22 @@ #define GET_ARGUMENT_AS_UINT32(id) GET_ARGUMENT_AS_TYPE(id, Uint32Value) #define GET_ARGUMENT_AS_NUMBER(id) GET_ARGUMENT_AS_TYPE(id, NumberValue) #define GET_ARGUMENT_AS_STRING(id) GET_ARGUMENT_AS_TYPE(id, ToString) - #define GET_ARGUMENT_AS_LOCAL_FUNCTION(id) Local::Cast(args[id]) - #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) + #define GET_ARGUMENT_AS_LOCAL_FUNCTION(id) v8::Local::Cast(args[id]) + #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) v8::Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) #define LIST(...) { __VA_ARGS__ } - /*#define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ - if (!isInList(std::string(*value), LIST T)) { \ - THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ - } - - #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ - if (!isInList(value, LIST T)) { \ - THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ - }*/ - #define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ { \ - std::string strings[] = LIST T; \ - if (std::find(strings, strings + sizeof_array(strings), std::string(*value)) == strings + sizeof_array(strings)) { \ - THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ + static const char* strings[] = LIST T; \ + if (!find_string(*value, strings, sizeof(strings) / sizeof(char*))) { \ + THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), *value, #T); \ } \ } #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ { \ - int ints[] = LIST T; \ - if (std::find(ints, ints + sizeof_array(ints), value) == ints + sizeof_array(ints)) { \ + static const int ints[] = LIST T; \ + if (!find_int(value, ints, sizeof(ints) / sizeof(int))) { \ THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ } \ } diff --git a/src/wiringPiISR.cc b/src/wiringPiISR.cc index 101c43d..0a43e01 100644 --- a/src/wiringPiISR.cc +++ b/src/wiringPiISR.cc @@ -2,6 +2,7 @@ #include #include #include +#include using namespace v8; diff --git a/src/wpi.cc b/src/wpi.cc index 306d9c1..491f874 100644 --- a/src/wpi.cc +++ b/src/wpi.cc @@ -1,4 +1,5 @@ #include "wpi.h" +#include NODE_MODULE_INIT() { INIT(wiringPi); From 4967b4e9ca52f36b915fe125d0b4c0b2c0cb7032 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 10:22:31 +0200 Subject: [PATCH 10/64] fix gpio compilation and installation --- install.sh | 11 +++++++++++ patchs/devLib_Makefile.patch | 19 +++++++++++++++++++ patchs/gpio_Makefile.patch | 20 ++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 patchs/devLib_Makefile.patch create mode 100644 patchs/gpio_Makefile.patch diff --git a/install.sh b/install.sh index 8985f38..df4ab18 100644 --- a/install.sh +++ b/install.sh @@ -44,6 +44,9 @@ git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 check_git_clone echo "done." +patch ./wiringpi/devLib/Makefile < ./patchs/devLib-Makefile.patch +patch ./wiringpi/gpio/Makefile < ./patchs/gpio-Makefile.patch + echo -n "Making libWiringPi ... " cd ./wiringpi/wiringPi/ make clean >> ../../install.log 2>&1 @@ -52,6 +55,14 @@ check_make_ok "libWiringPi" 1 cd ../../ echo "done." +cd ./wiringpi/devLib/ +echo -n "Making devLib ..." +make clean >> ../../install.log 2>&1 +make statis >> ../../install.log 2>&1 +check_make_ok "devLib" 0 +cd ../../ +echo "done." + cd ./wiringpi/gpio/ echo -n "Unistalling gpio utility ... " sudo make uninstall >> ../../install.log 2>&1 diff --git a/patchs/devLib_Makefile.patch b/patchs/devLib_Makefile.patch new file mode 100644 index 0000000..a4080ac --- /dev/null +++ b/patchs/devLib_Makefile.patch @@ -0,0 +1,19 @@ +--- Makefile_org 2014-07-04 09:48:18.000000000 +0200 ++++ Makefile 2014-07-04 10:12:15.000000000 +0200 +@@ -26,6 +26,7 @@ + VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) + DESTDIR=/usr + PREFIX=/local ++PWD=`PWD` + + STATIC=libwiringPiDev.a + DYNAMIC=libwiringPiDev.so.$(VERSION) +@@ -33,7 +34,7 @@ + #DEBUG = -g -O0 + DEBUG = -O2 + CC = gcc +-INCLUDE = -I. ++INCLUDE = -I. -I$(PWD)/../wiringPi + CFLAGS = $(DEBUG) -Wformat=2 -Wall $(INCLUDE) -Winline -pipe -fPIC + + LIBS = diff --git a/patchs/gpio_Makefile.patch b/patchs/gpio_Makefile.patch new file mode 100644 index 0000000..73cec63 --- /dev/null +++ b/patchs/gpio_Makefile.patch @@ -0,0 +1,20 @@ +--- Makefile_org 2014-07-04 09:58:05.000000000 +0200 ++++ Makefile 2014-07-04 10:13:01.000000000 +0200 +@@ -25,14 +25,15 @@ + + DESTDIR=/usr + PREFIX=/local ++PWD=`pwd` + + #DEBUG = -g -O0 + DEBUG = -O2 + CC = gcc +-INCLUDE = -I$(DESTDIR)$(PREFIX)/include ++INCLUDE = -I$(PWD)/../wiringPi -I($PWD)/../devLib + CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +-LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib ++LDFLAGS = -L$(PWD)/../wiringPi -L$(PWD)/../devLib + LIBS = -lwiringPi -lwiringPiDev -lpthread -lm + + # May not need to alter anything below this line From 2e5028ed7ceb5742649bc8bee99d0c5ba9542803 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 10:25:54 +0200 Subject: [PATCH 11/64] fix typos :/ --- install.sh | 6 +++--- patchs/gpio_Makefile.patch | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/install.sh b/install.sh index df4ab18..5d0e3bc 100644 --- a/install.sh +++ b/install.sh @@ -44,8 +44,8 @@ git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 check_git_clone echo "done." -patch ./wiringpi/devLib/Makefile < ./patchs/devLib-Makefile.patch -patch ./wiringpi/gpio/Makefile < ./patchs/gpio-Makefile.patch +patch ./wiringpi/devLib/Makefile < ./patchs/devLib_Makefile.patch +patch ./wiringpi/gpio/Makefile < ./patchs/gpio_Makefile.patch echo -n "Making libWiringPi ... " cd ./wiringpi/wiringPi/ @@ -58,7 +58,7 @@ echo "done." cd ./wiringpi/devLib/ echo -n "Making devLib ..." make clean >> ../../install.log 2>&1 -make statis >> ../../install.log 2>&1 +make static >> ../../install.log 2>&1 check_make_ok "devLib" 0 cd ../../ echo "done." diff --git a/patchs/gpio_Makefile.patch b/patchs/gpio_Makefile.patch index 73cec63..e50bfe0 100644 --- a/patchs/gpio_Makefile.patch +++ b/patchs/gpio_Makefile.patch @@ -10,7 +10,7 @@ DEBUG = -O2 CC = gcc -INCLUDE = -I$(DESTDIR)$(PREFIX)/include -+INCLUDE = -I$(PWD)/../wiringPi -I($PWD)/../devLib ++INCLUDE = -I$(PWD)/../wiringPi -I$(PWD)/../devLib CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib From b7ab4f5449b8ee3b2737d311881c56928515aae9 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 10:28:14 +0200 Subject: [PATCH 12/64] typo again ... --- patchs/devLib_Makefile.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patchs/devLib_Makefile.patch b/patchs/devLib_Makefile.patch index a4080ac..8ae4125 100644 --- a/patchs/devLib_Makefile.patch +++ b/patchs/devLib_Makefile.patch @@ -4,7 +4,7 @@ VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) DESTDIR=/usr PREFIX=/local -+PWD=`PWD` ++PWD=`pwd` STATIC=libwiringPiDev.a DYNAMIC=libwiringPiDev.so.$(VERSION) From 947b1b23449c9032f109f32eded68245d8523594 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 12:09:09 +0200 Subject: [PATCH 13/64] wiringPiISR callback remove pin Useless since callback is associated with interrupt on a given pin --- src/wiringPiISR.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wiringPiISR.cc b/src/wiringPiISR.cc index 0a43e01..710bee2 100644 --- a/src/wiringPiISR.cc +++ b/src/wiringPiISR.cc @@ -33,11 +33,10 @@ static void processInterrupt(uv_work_t* req, int status) { Persistent callback = interruptCallbackMapping[work->pin]; Local argv[] = { - Local::New(Int32::New(work->pin)), Local::New(Uint32::New(work->delta)) }; - callback->Call(Context::GetCurrent()->Global(), 2, argv); + callback->Call(Context::GetCurrent()->Global(), 1, argv); delete work; } From e7f58aaf354c6bcfe1f35e2b71458ef0b73af5fc Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 13:30:31 +0200 Subject: [PATCH 14/64] update changelog --- CHANGELOG.md | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29..02d809a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,119 @@ +# CHANGELOG + +## v2.0.0 *[not released yet]* + * **Update:** split source code (based on libWiringPi hierarchy) `nekuz0r` + * **Update:** better types check `nekuz0r` + * **Update:** better allowed values check `nekuz0r` + * **Update:** better error messages `nekuz0r` + * **Update:** documentation `nekuz0r` + * **Update:** constants are exported from c++ (ReadOnly | DontDelete) `nekuz0r` + * **Update:** setup() is exported from c++ `nekuz0r` + * NOTE: it no longer accepts empty parameter 'mode' (breaks backward compatibility) + * **Update:** wiringPiSPIDataRW now takes a buffer as second parameter (no thrid anymore) `nekuz0r` + * **Remove:** backward compatibility constants `nekuz0r` + * **Add:** wiringPiISR `nekuz0r` + * **Add:** CHANGELOG.md `nekuz0r` + * **Add:** wiringPiI2C support `nekuz0r` + * **Add:** wiring-pi install gpio utilty (required for interrupts) `nekuz0r` + +## v1.1.1 *[not released yet]* + * **Fix:** missing constant in pinModeCheck `nekuz0r` + * **Fix:** missing constant PI_MODEL_CM `nekuz0r` + * **Add:** serialPrintf (alias to serialPuts) `nekuz0r` + +## v1.1.0 *[Jun 30 2014]* + * **Update:** libWiringPi to [custom](nekuz0r-libWiringPi) v2.15 `nekuz0r` + * **Fix:** mcp3422 constants again `nekuz0r` + * **Remove:** precompiled dependencies `nekuz0r` + * **Add:** install script + * **Add:** pca9685 support `nekuz0r` + * **Add:** pulseIn `nekuz0r` + * **Add:** piBoardId `nekuz0r` + * **Add:** softPwmStop `nekuz0r` + * **Add:** softToneStop `nekuz0r` + * **Add:** SOFT_PWM_OUTPUT, SOFT_TONE_OUTPUT `nekuz0r` + * **Add:** PI_MODEL_A, PI_MODEL_B, PI_MODEL_CM `nekuz0r` + * **Add:** PI_MODEL_NAMES, PI_REVISION_NAMES, PI_COMPUTE_REVISION_NAMES `nekuz0r` + * **Add:** delay `nekuz0r` + * **Add:** delayMicroseconds `nekuz0r` + * **Add:** millis `nekuz0r` + * **Add:** micros `nekuz0r` + +## v1.0.2 *[Mar 18 2014]* + * Releasing as Open Open Source `eugeneware` + +## v1.0.1 *[Mar 18 2014]* + * **Fix:** mcp3422 constants `nekuz0r` + +## v1.0.0 *[Nov 29 2013]* + * **Update:** libWiringPi to v2.13 `nekuz0r` + * **Update:** examples (blink, pwm) `nekuz0r` + * **Update:** documentation `nekuz0r` + * **Add:** physical numbering scheme support (setup) `nekuz0r` + * **Add:** drcSerial support `nekuz0r` + * **Add:** max5322 support `nekuz0r` + * **Add:** mcp23s08 support `nekuz0r` + * **Add:** mcp3002 support `nekuz0r` + * **Add:** mcp3004 support `nekuz0r` + * **Add:** mcp3422 support `nekuz0r` + * **Add:** mcp4802 support `nekuz0r` + * **Add:** mcp23008 support `nekuz0r` + * **Add:** mcp23016 support `nekuz0r` + * **Add:** mcp23017 support `nekuz0r` + * **Add:** pcf8574 support `nekuz0r` + * **Add:** pcf8591 support `nekuz0r` + * **Add:** softPWM support `nekuz0r` + * **Add:** softServo support `nekuz0r` + * **Add:** softTone support `nekuz0r` + * **Add:** sr595 support `nekuz0r` + * **Add:** wiringPiSPI support `nekuz0r` + * **Add:** wiringPiSerial support (serialPrintf not implemented yet) `nekuz0r` + * **Add:** wiringPiShift support `nekuz0r` + * **Add:** pinModeAlt `nekuz0r` + * **Add:** analogRead `nekuz0r` + * **Add:** analogWrite `nekuz0r` + * **Add:** wpiPinToGpio `nekuz0r` + * **Add:** physPinToGpio `nekuz0r` + * **Add:** setPadDrive `nekuz0r` + * **Add:** getAlt `nekuz0r` + * **Add:** digitalWriteByte `nekuz0r` + * **Add:** pwmSetMode `nekuz0r` + * **Add:** gpioClockSet `nekuz0r` + * **Add:** LSBFIRST, MSBFIRST `nekuz0r` + * **Add:** MCP3422_SR_3_75, MCP3422_SR_15, MCP3422_SR_60, MCP3422_SR_240 `nekuz0r` + * **Add:** MCP3422_GAIN_1, MCP3422_GAIN_2, MCP3422_GAIN_4, MCP3422_GAIN_8 `nekuz0r` + * **Add:** WPI_MODE_PINS, WPI_MODE_GPIO, WPI_MODE_GPIO_SYS, WPI_MODE_GPIO_PHYS, WPI_MODE_PIFACE, WPI_MODE_UNINITIALIZED `nekuz0r` + * **Add:** INPUT, OUTPUT, PWM_OUTPUT, GPIO_CLOCK `nekuz0r` + * **Add:** PUD_OFF, PUD_UP, PUD_DOWN `nekuz0r` + * **Add:** PWM_MODE_MS, PWM_MODE, BAL `nekuz0r` + * **Add:** INT_EDGE_SETUP, INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH `nekuz0r` + +## v0.2.0 *[Nov 5 2013]* + * **Add:** pullUpDnControl `nekuz0r` + * **Add:** pull.PUD_OFF, pull.PUD_UP, pull.PUD_DOWN `nekuz0r` + +## v0.1.2 *[Aug 2 2013]* + * **Add:** HIGH, LOW `csquared` + * **Fix:** typo in exports.js `csquared` + * **Update:** README.md `csquared` + +## v0.1.1 *[Jun 11 2013]* + * **Add:** PWM example `eugeneware` + * **Fix:** pwmWrite export `eugeneware` + +## v0.1.0 *[Dec 20 2013]* + * Initial version `soarez` + * wiringPiSetup + * wiringPiSetupGpio + * wiringPiSetupSys + * piBoardRev + * pinMode + * digitalWrite + * digitalRead + * pwmSetRange + * pwmSetClock + * pwmWrite + * setup + * blink example + +[nekuz0r-libWiringPi]: https://github.com/nekuz0r/wiringpi/ \ No newline at end of file From 80ad177ecfaa8edb0d89286846d1f023d47024ab Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 13:31:39 +0200 Subject: [PATCH 15/64] fix typo in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02d809a..78996d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ * **Add:** serialPrintf (alias to serialPuts) `nekuz0r` ## v1.1.0 *[Jun 30 2014]* - * **Update:** libWiringPi to [custom](nekuz0r-libWiringPi) v2.15 `nekuz0r` + * **Update:** libWiringPi to [custom][nekuz0r-libWiringPi] v2.15 `nekuz0r` * **Fix:** mcp3422 constants again `nekuz0r` * **Remove:** precompiled dependencies `nekuz0r` * **Add:** install script From e60820633227d3882e44b28a3395b61bca829d80 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 15:27:05 +0200 Subject: [PATCH 16/64] devLib support --- CHANGELOG.md | 9 ++ binding.gyp | 13 +- src/devlib/devlib.cc | 21 +++ src/devlib/devlib.h | 8 ++ src/devlib/ds1302.cc | 176 +++++++++++++++++++++++++ src/devlib/ds1302.h | 8 ++ src/devlib/gertboard.cc | 24 ++++ src/devlib/gertboard.h | 8 ++ src/devlib/lcd.cc | 284 ++++++++++++++++++++++++++++++++++++++++ src/devlib/lcd.h | 8 ++ src/devlib/lcd128x64.cc | 0 src/devlib/lcd128x64.h | 0 src/devlib/maxdetect.cc | 58 ++++++++ src/devlib/maxdetect.h | 8 ++ src/devlib/piFace.cc | 24 ++++ src/devlib/piFace.h | 8 ++ src/devlib/piGlow.cc | 97 ++++++++++++++ src/devlib/piGlow.h | 8 ++ src/devlib/piNes.cc | 58 ++++++++ src/devlib/piNes.h | 8 ++ src/wpi.cc | 1 + src/wpi.h | 1 + 22 files changed, 829 insertions(+), 1 deletion(-) create mode 100644 src/devlib/devlib.cc create mode 100644 src/devlib/devlib.h create mode 100644 src/devlib/ds1302.cc create mode 100644 src/devlib/ds1302.h create mode 100644 src/devlib/gertboard.cc create mode 100644 src/devlib/gertboard.h create mode 100644 src/devlib/lcd.cc create mode 100644 src/devlib/lcd.h create mode 100644 src/devlib/lcd128x64.cc create mode 100644 src/devlib/lcd128x64.h create mode 100644 src/devlib/maxdetect.cc create mode 100644 src/devlib/maxdetect.h create mode 100644 src/devlib/piFace.cc create mode 100644 src/devlib/piFace.h create mode 100644 src/devlib/piGlow.cc create mode 100644 src/devlib/piGlow.h create mode 100644 src/devlib/piNes.cc create mode 100644 src/devlib/piNes.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 78996d4..b2eae93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,15 @@ * **Add:** CHANGELOG.md `nekuz0r` * **Add:** wiringPiI2C support `nekuz0r` * **Add:** wiring-pi install gpio utilty (required for interrupts) `nekuz0r` + * **Add:** ds1302 support `nekuz0r` + * **Add:** gertboard support `nekuz0r` + * **Add:** lcd support `nekuz0r` + * **Add:** lcd128x64 support `nekuz0r` + * **Add:** maxdetect support `nekuz0r` + * **Add:** piFace support `nekuz0r` + * **Add:** piGlow support `nekuz0r` + * **Add:** piNes support `nekuz0r` + * **Fictitious:** this release eats Pi(e)s :) ## v1.1.1 *[not released yet]* * **Fix:** missing constant in pinModeCheck `nekuz0r` diff --git a/binding.gyp b/binding.gyp index 43d8d9a..3541dfe 100644 --- a/binding.gyp +++ b/binding.gyp @@ -34,12 +34,23 @@ 'src/extensions/sn3218.cc', 'src/extensions/sr595.cc', 'src/extensions/pca9685.cc' + + 'src/devlib/devlib.cc', + 'src/devlib/ds1302.cc', + 'src/devlib/gertboard.cc', + 'src/devlib/lcd.cc', + 'src/devlib/lcd128x64.cc', + 'src/devlib/maxdetect.cc', + 'src/devlib/piFace.cc', + 'src/devlib/piGlow.cc', + 'src/devlib/piNes.cc', ], 'include_dirs': [ 'wiringpi/wiringPi' ], 'libraries': [ - ' + +DECLARE(ds1302rtcRead); +DECLARE(ds1302rtcWrite); +DECLARE(ds1302ramRead); +DECLARE(ds1302ramWrite); +DECLARE(ds1302clockRead); +DECLARE(ds1302clockWrite); +DECLARE(ds1302trickleCharge); +DECLARE(ds1302setup); + +// Func: unsigned int ds1302rtcRead (const int reg) +// Description: Reads the data to/from the RTC register + +IMPLEMENT(ds1302rtcRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, reg); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int reg = GET_ARGUMENT_AS_INT32(0); + + unsigned int res = ::ds1302rtcRead(reg); + + SCOPE_CLOSE(UINT32(res)); +} + +// Func: void ds1302rtcWrite (int reg, unsigned int data) +// Description: Writes the data to/from the RTC register + +IMPLEMENT(ds1302rtcWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, reg); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int reg = GET_ARGUMENT_AS_INT32(0); + unsigned int data = GET_ARGUMENT_AS_UINT32(1); + + ::ds1302rtcWrite(reg, data); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(ds1302ramRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, address); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int address = GET_ARGUMENT_AS_INT32(0); + + unsigned int res = ::ds1302ramRead(address); + + SCOPE_CLOSE(UINT32(res)); +} + +IMPLEMENT(ds1302ramWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, address); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + + int address = GET_ARGUMENT_AS_INT32(0); + unsigned int data = GET_ARGUMENT_AS_UINT32(1); + + ::ds1302ramWrite(address, data); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(ds1302clockRead) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int clockData[8]; + ::ds1302clockRead(clockData); + + v8::Local res = v8::Array::New(8); + for (int i = 0; i < 8; i++) { + res->Set(i, v8::Int32::New(clockData[i])); + } + + SCOPE_CLOSE(res); +} + +IMPLEMENT(ds1302clockWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, clockData); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_ARRAY(0); + CHECK_ARGUMENT_ARRAY_LENGTH(0, 8); + + v8::Local clockData = v8::Local::Cast(args[0]); + + int ar[8]; + for (int i = 0; i < 8; i++) { + ar[i] = clockData->Get(i)->Int32Value(); + } + + ::ds1302clockWrite(ar); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(ds1302trickleCharge) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, diodes); + SET_ARGUMENT_NAME(1, resistors); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int diodes = GET_ARGUMENT_AS_INT32(0); + int resistors = GET_ARGUMENT_AS_INT32(1); + + ::ds1302trickleCharge(diodes, resistors); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(ds1302setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, clockPin); + SET_ARGUMENT_NAME(1, dataPin); + SET_ARGUMENT_NAME(2, csPin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int clockPin = GET_ARGUMENT_AS_INT32(0); + int dataPin = GET_ARGUMENT_AS_INT32(1); + int csPin = GET_ARGUMENT_AS_INT32(2); + + ::ds1302setup(clockPin, dataPin, csPin); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(ds1302) { + EXPORT_FUNCTION(ds1302rtcRead); + EXPORT_FUNCTION(ds1302rtcWrite); + EXPORT_FUNCTION(ds1302ramRead); + EXPORT_FUNCTION(ds1302ramWrite); + EXPORT_FUNCTION(ds1302clockRead); + EXPORT_FUNCTION(ds1302clockWrite); + EXPORT_FUNCTION(ds1302trickleCharge); + EXPORT_FUNCTION(ds1302setup); +} \ No newline at end of file diff --git a/src/devlib/ds1302.h b/src/devlib/ds1302.h new file mode 100644 index 0000000..349d2e5 --- /dev/null +++ b/src/devlib/ds1302.h @@ -0,0 +1,8 @@ +#ifndef _WPI_DS1302_H_ +#define _WPI_DS1302_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(ds1302); + +#endif \ No newline at end of file diff --git a/src/devlib/gertboard.cc b/src/devlib/gertboard.cc new file mode 100644 index 0000000..17387b3 --- /dev/null +++ b/src/devlib/gertboard.cc @@ -0,0 +1,24 @@ +#include "gertboard.h" +#include + +DECLARE(gertboardAnalogSetup); + +IMPLEMENT(gertboardAnalogSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + + int res = ::getboardAnalogSetup(pinBase); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(gertboard) { + EXPORT_FUNCTION(gertboardAnalogSetup); +} \ No newline at end of file diff --git a/src/devlib/gertboard.h b/src/devlib/gertboard.h new file mode 100644 index 0000000..f9d1ea1 --- /dev/null +++ b/src/devlib/gertboard.h @@ -0,0 +1,8 @@ +#ifndef _WPI_GERTBOARD_H_ +#define _WPI_GERTBOARD_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(gertboard); + +#endif \ No newline at end of file diff --git a/src/devlib/lcd.cc b/src/devlib/lcd.cc new file mode 100644 index 0000000..8866800 --- /dev/null +++ b/src/devlib/lcd.cc @@ -0,0 +1,284 @@ +#include "lcd.h" +#include + +DECLARE(lcdHome); +DECLARE(lcdClear); +DECLARE(lcdDisplay); +DECLARE(lcdCursor); +DECLARE(lcdCursorBlink); +DECLARE(lcdSendCommand); +DECLARE(lcdPosition); +DECLARE(lcdCharDef); +DECLARE(lcdPutchar); +DECLARE(lcdPuts); +DECLARE(lcdPrintf); +DECLARE(lcdInit); + +IMPLEMENT(lcdHome) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + ::lcdHome(fd); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdClear) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + ::lcdClear(fd); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdDisplay) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + ::lcdDisplay(fd, state); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdCursor) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + ::lcdCursor(fd, state); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdCursorBlink) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + ::lcdCursorBlink(fd, state); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdSendCommand) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, command); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int command = GET_ARGUMENT_AS_UINT32(1); + + ::lcdSendCommand(fd, command); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdPosition) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, x); + SET_ARGUMENT_NAME(2, y); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int fd = GET_ARGUMENT_AS_INT32(0); + int x = GET_ARGUMENT_AS_INT32(1); + int y = GET_ARGUMENT_AS_INT32(2); + + ::lcdPosition(fd, x, y); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdCharDef) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, index); + SET_ARGUMENT_NAME(2, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_ARRAY(2); + CHECK_ARGUMENT_ARRAY_LENGTH(8); + + int fd = GET_ARGUMENT_AS_INT32(0); + int index = GET_ARGUMENT_AS_INT32(1); + v8::Local data = v8::Local::Cast(args[2]); + + unsigned int ar[8]; + for (int i = 0; i < 8; i++) { + ar[i] = data->Get(i)->Uint32Value(); + } + + ::lcdCharDef(fd, index, ar); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdPutchar) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + unsigned int data = GET_ARGUMENT_AS_UINT32(1); + + ::lcdPutchar(fd, data); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdPuts) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, string); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_STRING(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + v8::String::AsciiValue data(GET_ARGUMENT_AS_STRING(1)); + + ::lcdPuts(fd, *data); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdPrintf) { + return lcdPuts(args); +} + +IMPLEMENT(lcdInit) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, rows); + SET_ARGUMENT_NAME(1, cols); + SET_ARGUMENT_NAME(2, bits); + SET_ARGUMENT_NAME(3, rs); + SET_ARGUMENT_NAME(4, strb); + SET_ARGUMENT_NAME(5, d0); + SET_ARGUMENT_NAME(6, d1); + SET_ARGUMENT_NAME(7, d2); + SET_ARGUMENT_NAME(8, d3); + SET_ARGUMENT_NAME(9, d4); + SET_ARGUMENT_NAME(10, d5); + SET_ARGUMENT_NAME(11, d6); + SET_ARGUMENT_NAME(12, d7); + + CHECK_ARGUMENTS_LENGTH_EQUAL(13); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + CHECK_ARGUMENT_TYPE_INT32(5); + CHECK_ARGUMENT_TYPE_INT32(6); + CHECK_ARGUMENT_TYPE_INT32(7); + CHECK_ARGUMENT_TYPE_INT32(8); + CHECK_ARGUMENT_TYPE_INT32(9); + CHECK_ARGUMENT_TYPE_INT32(10); + CHECK_ARGUMENT_TYPE_INT32(11); + CHECK_ARGUMENT_TYPE_INT32(12); + + int rows = GET_ARGUMENT_AS_INT32(0); + int cols = GET_ARGUMENT_AS_INT32(1); + int bits = GET_ARGUMENT_AS_INT32(2); + int rs = GET_ARGUMENT_AS_INT32(3); + int strb = GET_ARGUMENT_AS_INT32(4); + int d0 = GET_ARGUMENT_AS_INT32(5); + int d1 = GET_ARGUMENT_AS_INT32(6); + int d2 = GET_ARGUMENT_AS_INT32(7); + int d3 = GET_ARGUMENT_AS_INT32(8); + int d4 = GET_ARGUMENT_AS_INT32(9); + int d5 = GET_ARGUMENT_AS_INT32(10); + int d6 = GET_ARGUMENT_AS_INT32(11); + int d7 = GET_ARGUMENT_AS_INT32(12); + + int res = ::lcdInit(rows, cols, bits, rs, strb, d0, d1, d2, d3, d4, d5, d6, d7); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(lcd) { + EXPORT_FUNCTION(lcdHome); + EXPORT_FUNCTION(lcdClear); + EXPORT_FUNCTION(lcdDisplay); + EXPORT_FUNCTION(lcdCursor); + EXPORT_FUNCTION(lcdCursorBlink); + EXPORT_FUNCTION(lcdSendCommand); + EXPORT_FUNCTION(lcdPosition); + EXPORT_FUNCTION(lcdCharDef); + EXPORT_FUNCTION(lcdPutchar); + EXPORT_FUNCTION(lcdPuts); + EXPORT_FUNCTION(lcdPrintf); + EXPORT_FUNCTION(lcdInit); + + EXPORT_CONSTANT_INT(MAX_LCDS); +} \ No newline at end of file diff --git a/src/devlib/lcd.h b/src/devlib/lcd.h new file mode 100644 index 0000000..1b66119 --- /dev/null +++ b/src/devlib/lcd.h @@ -0,0 +1,8 @@ +#ifndef _WPI_LCD_H_ +#define _WPI_LCD_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(lcd); + +#endif \ No newline at end of file diff --git a/src/devlib/lcd128x64.cc b/src/devlib/lcd128x64.cc new file mode 100644 index 0000000..e69de29 diff --git a/src/devlib/lcd128x64.h b/src/devlib/lcd128x64.h new file mode 100644 index 0000000..e69de29 diff --git a/src/devlib/maxdetect.cc b/src/devlib/maxdetect.cc new file mode 100644 index 0000000..3163dc3 --- /dev/null +++ b/src/devlib/maxdetect.cc @@ -0,0 +1,58 @@ +#include "maxdetect.h" +#include + +DECLARE(maxDetectRead); +DECLARE(readRHT03); + +IMPLEMENT(maxDetectRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + + unsigned char buffer[4]; + int res = ::maxDetectRead(pin, buffer); + + v8::Local data = v8::Array::New(4); + for (int i = 0; i < 4; i++) { + data->Set(i, Int32::New(buffer[i])); + } + + v8::Local ret = v8::Array::New(2); + ret->Set(0, Int32::New(res)); + ret->Set(1, data); + + SCOPE_CLOSE(ret); +} + +IMPLEMENT(readRHT03) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32; + + int temp, int rh; + int res = ::readRHT03(pin, &temp, &rh); + + v8::Local ret = v8::Array::New(3); + ret->Set(0, v8::Int32::New(res)); + ret->Set(1, v8::Int32::New(temp)); + ret->Set(2, v8::Int32::New(rh)); + + SCOPE_CLOSE(ret); +} + +IMPLEMENT_EXPORT_INIT(maxdetect) { + EXPORT_FUNCTION(maxDetectRead); + EXPORT_FUNCTION(readRHT03); +} \ No newline at end of file diff --git a/src/devlib/maxdetect.h b/src/devlib/maxdetect.h new file mode 100644 index 0000000..d9e7d38 --- /dev/null +++ b/src/devlib/maxdetect.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MAXDETECT_H_ +#define _WPI_MAXDETECT_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(maxdetect); + +#endif \ No newline at end of file diff --git a/src/devlib/piFace.cc b/src/devlib/piFace.cc new file mode 100644 index 0000000..1efba8b --- /dev/null +++ b/src/devlib/piFace.cc @@ -0,0 +1,24 @@ +#include "piFace.h" +#include + +DECLARE(piFaceSetup); + +IMPLEMENT(piFaceSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + + int res = ::piFaceSetup(pinBase); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(piFace) { + EXPORT_FUNCTION(piFaceSetup); +} \ No newline at end of file diff --git a/src/devlib/piFace.h b/src/devlib/piFace.h new file mode 100644 index 0000000..63bf848 --- /dev/null +++ b/src/devlib/piFace.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PI_FACE_H_ +#define _WPI_PI_FACE_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(piFace); + +#endif \ No newline at end of file diff --git a/src/devlib/piGlow.cc b/src/devlib/piGlow.cc new file mode 100644 index 0000000..ea66211 --- /dev/null +++ b/src/devlib/piGlow.cc @@ -0,0 +1,97 @@ +#include "piGlow.h" +#include + +DECLARE(piGlow1); +DECLARE(piGlowLeg); +DECLARE(piGlowRing); +DECLARE(piGlowSetup); + +IMPLEMENT(piGlow1) { + OPEN_SCOPE(); + + SET_ARGUMENT_NAME(0, leg); + SET_ARGUMENT_NAME(1, ring); + SET_ARGUMENT_NAME(2, intensity); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int leg = GET_ARGUMENT_AS_INT32(0); + int ring = GET_ARGUMENT_AS_INT32(1); + int intensity = GET_ARGUMENT_AS_INT32(2); + + ::piGlow1(leg, ring, intensity); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(piGlowLeg) { + OPEN_SCOPE(); + + SET_ARGUMENT_NAME(0, leg); + SET_ARGUMENT_NAME(1, intensity); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int leg = GET_ARGUMENT_AS_INT32(0); + int intensity = GET_ARGUMENT_AS_INT32(1); + + ::piGlowLeg(leg, intensity); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(piGlowRing) { + OPEN_SCOPE(); + + SET_ARGUMENT_NAME(0, ring); + SET_ARGUMENT_NAME(1, intensity); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int ring = GET_ARGUMENT_AS_INT32(0); + int intensity = GET_ARGUMENT_AS_INT32(1); + + ::piGlowRing(ring, intensity); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(piGlowSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, clear); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int clear = GET_ARGUMENT_AS_INT32(0); + + ::piGlowSetup(clear); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(piGlow) { + EXPORT_FUNCTION(piGlow1); + EXPORT_FUNCTION(piGlowLeg); + EXPORT_FUNCTION(piGlowRing); + EXPORT_FUNCTION(piGlowSetup); + + EXPORT_CONSTANT_INT(PIGLOW_RED); + EXPORT_CONSTANT_INT(PIGLOW_YELLOW); + EXPORT_CONSTANT_INT(PIGLOW_ORANGE); + EXPORT_CONSTANT_INT(PIGLOW_GREEN); + EXPORT_CONSTANT_INT(PIGLOW_BLUE); + EXPORT_CONSTANT_INT(PIGLOW_WHITE); +} \ No newline at end of file diff --git a/src/devlib/piGlow.h b/src/devlib/piGlow.h new file mode 100644 index 0000000..b1dd98c --- /dev/null +++ b/src/devlib/piGlow.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PI_GLOW_H_ +#define _WPI_PI_GLOW_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(piGlow); + +#endif \ No newline at end of file diff --git a/src/devlib/piNes.cc b/src/devlib/piNes.cc new file mode 100644 index 0000000..f94d988 --- /dev/null +++ b/src/devlib/piNes.cc @@ -0,0 +1,58 @@ +#include "piNes.h" +#include + +DECLARE(setupNesJoystick); +DECLARE(readNesJoystick); + +IMPLEMENT(setupNesJoystick) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, dPin); + SET_ARGUMENT_NAME(1, cPin); + SET_ARGUMENT_NAME(2, lPin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int dPin = GET_ARGUMENT_AS_INT32(0); + int cPin = GET_ARGUMENT_AS_INT32(1); + int lPin = GET_ARGUMENT_AS_INT32(2); + + int res = ::setupNesJoystick(dPin, cPin, lPin); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT(readNesJoystick) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, joystick); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int joystick = GET_ARGUMENT_AS_INT32(0); + + unsigned int res = ::readNesJoystick(joystick); + + SCOPE_CLOSE(UINT32(res)); +} + +IMPLEMENT_EXPORT_INIT(piNes) { + EXPORT_FUNCTION(setupNesJoystick); + EXPORT_FUNCTION(readNesJoystick); + + EXPORT_CONSTANT_INT(MAX_NES_JOYSTICKS); + EXPORT_CONSTANT_INT(NES_RIGHT); + EXPORT_CONSTANT_INT(NES_LEFT); + EXPORT_CONSTANT_INT(NES_DOWN); + EXPORT_CONSTANT_INT(NES_UP); + EXPORT_CONSTANT_INT(NES_START); + EXPORT_CONSTANT_INT(NES_SELECT); + EXPORT_CONSTANT_INT(NES_A); + EXPORT_CONSTANT_INT(NES_B); +} \ No newline at end of file diff --git a/src/devlib/piNes.h b/src/devlib/piNes.h new file mode 100644 index 0000000..f7125a8 --- /dev/null +++ b/src/devlib/piNes.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PI_NES_H_ +#define _WPI_PI_NES_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(piNes); + +#endif \ No newline at end of file diff --git a/src/wpi.cc b/src/wpi.cc index 491f874..f04c705 100644 --- a/src/wpi.cc +++ b/src/wpi.cc @@ -13,6 +13,7 @@ NODE_MODULE_INIT() { INIT(wiringPiISR); INIT(extensions); + INIT(devlib); } NODE_MODULE_DECLARE(wiringPi); \ No newline at end of file diff --git a/src/wpi.h b/src/wpi.h index a61262b..a9c60df 100644 --- a/src/wpi.h +++ b/src/wpi.h @@ -12,5 +12,6 @@ #include "wiringPiISR.h" #include "extensions/extensions.h" + #include "devlib/devlib.h" #endif \ No newline at end of file From 07f2dc241b06c04c77dd0b3c8eb99e4e10db8e4f Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 16:30:51 +0200 Subject: [PATCH 17/64] update changeling --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2eae93..00f3075 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ * **Add:** piNes support `nekuz0r` * **Fictitious:** this release eats Pi(e)s :) -## v1.1.1 *[not released yet]* +## v1.1.1 *[Jul 4 2014]* * **Fix:** missing constant in pinModeCheck `nekuz0r` * **Fix:** missing constant PI_MODEL_CM `nekuz0r` * **Add:** serialPrintf (alias to serialPuts) `nekuz0r` From de351d2541bbba12f9fc272a58fdfc6b661da842 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 2 Jul 2014 14:11:47 +0200 Subject: [PATCH 18/64] Preparing wiring-pi 2.0.0 - Split the source code (based on libWiringPi source code hierarchy) - ADD: Implement I2C functions - ADD: Aliasing serialPrintf to serialPuts - FIX: missing constants in pinMode check - ADD: missing constant PI_MODEL_COMPUTE - ADD: wiringPiISR support (experimental) - UPD: Exports constants from C++ (ReadOnly | DontDelete) - UPD: Exports setup function from C++ - UPD: setup function no longer accepts calling without mode defined (breaks backward compatibility) - ADD: Better types and allowed values check - ADD: Better error messages - UPD: wiringPiSPIDataRW now takes two parameters, a node buffer as second parameter (instead of a string as second and length as third) - UPD: README.md (move documentation to DOCUMENTATION.md) - UPD: Documentation - UPD: Package.json version and contributors section - ADD: version history file (CHANGELOG.md) - DEL: Backward compatibility constants --- .gitignore | 2 + CHANGELOG.md | 0 DOCUMENTATION.md | 347 ++++++ README.md | 259 +---- binding.gyp | 24 +- lib/exports.js | 139 +-- package.json | 5 +- src/addon.h | 150 +++ src/bindings.cc | 2498 ------------------------------------------- src/softPwm.cc | 87 ++ src/softPwm.h | 8 + src/softServo.cc | 73 ++ src/softServo.h | 8 + src/softTone.cc | 77 ++ src/softTone.h | 8 + src/wiringPi.cc | 709 ++++++++++++ src/wiringPi.h | 8 + src/wiringPiI2C.cc | 197 ++++ src/wiringPiI2C.h | 8 + src/wiringPiISR.cc | 227 ++++ src/wiringPiISR.h | 8 + src/wiringPiSPI.cc | 80 ++ src/wiringPiSPI.h | 8 + src/wiringSerial.cc | 167 +++ src/wiringSerial.h | 8 + src/wiringShift.cc | 76 ++ src/wiringShift.h | 8 + src/wpi.cc | 15 + src/wpi.h | 14 + 29 files changed, 2331 insertions(+), 2887 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 DOCUMENTATION.md create mode 100644 src/addon.h delete mode 100644 src/bindings.cc create mode 100644 src/softPwm.cc create mode 100644 src/softPwm.h create mode 100644 src/softServo.cc create mode 100644 src/softServo.h create mode 100644 src/softTone.cc create mode 100644 src/softTone.h create mode 100644 src/wiringPi.cc create mode 100644 src/wiringPi.h create mode 100644 src/wiringPiI2C.cc create mode 100644 src/wiringPiI2C.h create mode 100644 src/wiringPiISR.cc create mode 100644 src/wiringPiISR.h create mode 100644 src/wiringPiSPI.cc create mode 100644 src/wiringPiSPI.h create mode 100644 src/wiringSerial.cc create mode 100644 src/wiringSerial.h create mode 100644 src/wiringShift.cc create mode 100644 src/wiringShift.h create mode 100644 src/wpi.cc create mode 100644 src/wpi.h diff --git a/.gitignore b/.gitignore index 378eac2..72bd1fa 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ build +npm-debug.log +wiringpi/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e69de29 diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md new file mode 100644 index 0000000..9b9aa85 --- /dev/null +++ b/DOCUMENTATION.md @@ -0,0 +1,347 @@ + + +# Index + +* [Install](#install) +* [Usage](#usage) +* [APIs](#apis) + * [Setup](#setup) + * [wiringPiSetup](#wiringpisetup) + * [wiringPiSetupGpio](#wiringpisetupgpio) + * [Shift](#shift) + +# Install + +```bash +npm install wiring-pi +``` + +# Usage + +```javascript +var wpi = require('wiring-pi'); +``` + +# APIs + +## Setup + +### `wiringPiSetup()` + +Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. +This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. +see the pins page (http://wiringpi.com/pins/) for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. +This function needs to be called with root privileges. + +### `wiringPiSetupGpio()` + +This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards. + +### `wiringPiSetupPhys()` + >= 1.0.0 + +Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. As above, this function needs to be called with root priviliges. + +### `wiringPiSetupSys()` + +This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed). + +### `setup(mode)` + +An handy function to setup wiringPi + +`mode` can be one of the following values: + +* `wpi`: sets up pin numbering with wiringPiSetup +* `gpio`: sets up pin numbering with wiringPiSetupGpio +* `sys`: sets up pin numbering with wiringPiSetupSys +* `phys`: sets up pin numbering with wiringPiSetupPhys + +More info about pin numbering systems at [wiringpi.com/pins/](http://wiringpi.com/pins/) + +**NOTE: wiring-pi >= 2.0.0 no longer accept calling setup without mode specified. (defaulting to `wpi` in wiring-pi < 2.0.0)** + +--- + +## Core functions + +### `pinModeAlt(pin, mode)` + >= 1.0.0 + +This is an un-documented special to let you set any pin to any mode. + +`mode` can be one of the following values: + +* `WPI_MODE_PINS` +* `WPI_MODE_PHYS` +* `WPI_MODE_GPIO` + +### `pinMode(pin, mode)` + +This sets the mode of a pin. Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program. + +`mode` can be one of the following values: + +* `modes.INPUT` **wiring-pi < 1.0.0** +* `modes.OUTPUT` **wiring-pi < 1.0.0** +* `modes.PWM_OUTPUT` **wiring-pi < 1.0.0** +* `modes.GPIO_CLOCK` **wiring-pi < 1.0.0** +* `INPUT` +* `OUTPUT` +* `PWM_OUTPUT` +* `GPIO_CLOCK` +* `SOFT_PWM_OUTPUT` **wiring-pi >= 1.1.0** +* `SOFT_TONE_OUTPUT` **wiring-pi >= 1.1.0** + +### `pullUpDnControl(pin, pud)` + >= 0.2.0 + +This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. + +`pud` can be one of the following values: + +* `PUD_OFF` *no pull up/down* +* `PUD_DOWN` *pull to ground* +* `PUD_UP` *pull to 3.3v* + +### `digitalRead(pin)` + +This function returns the value read at the given pin. It will be `HIGH` (1) or `LOW` (0) depending on the logic level at the pin. + +### `digitalWrite(pin, state)` + +Write the value `HIGH` (1) or `LOW` (0) to the given pin which must have been previously set as an output. WiringPi treats any non-zero number as `HIGH`, however 0 is the only representation of `LOW`. + +`state` can be one of the following value: + +* `HIGH` +* `LOW` + +### `pwmWrite(pin, value)` + +Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024]. Other PWM devices may have other PWM ranges. This function is not able to control the Pi's on-board PWM when in Sys mode. + +`value` must be in range of [0, 1024] + +### `analogRead(pin)` + >= 1.0.0 + +This returns the value read on the supplied analog input pin. You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc. + +### `analogWrite(pin, value)` + >= 1.0.0 + +This writes the given value to the supplied analog pin. You will need to register additional analog modules to enable this function for devices such as the Gertboard. + +### `pulseIn(pin, state)` + >= 1.1.0 + +`state` can be one of the following values: + +* `HIGH` +* `LOW` + +### `delay(milliseconds)` + >= 1.1.0 + +### `delayMicroseconds(microseconds)` + >= 1.1.0 + +### `millis()` + >= 1.1.0 + +### `micros()` + >= 1.1.0 + +--- + +## Raspberry Pi hardware specific functions + +### `piBoardRev()` + +This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. + +### `piBoardId()` + >= 1.1.0 + +### `wpiPinToGpio(pin)` + >= 1.0.0 + +This returns the BCM_GPIO pin number of the supplied wiringPi pin. It takes the board revision into account. + +### `physPinToGpio(pin)` + >= 1.0.0 + +This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector. + +### `setPadDrive(group, value)` + >= 1.0.0 + +This sets the "strength" of the pad drivers for a particular group of pins. There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you know what you are doing. + +### `getAlt(pin)` + >= 1.0.0 + +Returns the ALT bits for a given port. + +### `digitalWriteByte(byte)` + >= 1.0.0 + +This writes the 8-bit byte supplied to the first 8 GPIO pins. It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware. + +### `pwmSetMode(mode)` + >= 1.0.0 + +The PWM generator can run in 2 modes – “balanced” and “mark:space”. The mark:space mode is traditional, however the default mode in the Pi is “balanced”. + +`mode` can be one of the following values: + +* `PWM_MODE_BAL` *balanced* +* `PWM_MODE_MS` *mark:space* + +### `pwmSetRange(range)` + +This sets the range register in the PWM generator. The default is 1024. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. + +### `pwmSetClock(divisor)` + +This sets the divisor for the PWM clock. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. + +### `gpioClockSet(pin, frequency)` + >= 1.0.0 + +Set the frequency on a GPIO clock pin + +--- + +## I2C + +### `wiringPiI2CSetup(devId)` + >= 2.0.0 + +### `wiringPiI2CSetupInterface(device, devId)` + >= 2.0.0 + +### `wiringPiI2CRead(fd)` + >= 2.0.0 + +### `wiringPiI2CReadReg8(fd, reg)` + >= 2.0.0 + +### `wiringPiI2CReadReg16(fd, red)` + >= 2.0.0 + +### `wiringPiI2CWrite(fd, data)` + >= 2.0.0 + +### `wiringPiI2CWriteReg8(fd, reg, data)` + >= 2.0.0 + +### `wiringPiI2CWriteReg16(fd, reg, data)` + >= 2.0.0 + +--- + +## SPI + +### `wiringPiSPIGetFd(channel)` + >= 1.0.0 + +### `wiringPiSPIDataRW(channel, data)` + >= 1.0.0 + +### `wiringPiSPISetup(channel, speed)` + >= 1.0.0 + +--- + +## Serial + +### `serialOpen(device, baudrate)` + >= 1.0.0 + +### `serialClose(fd)` + >= 1.0.0 + +### `serialFlush(fd)` + >= 1.0.0 + +### `serialPutchar(fd, character)` + >= 1.0.0 + +### `serialPuts(fd, string)` + >= 1.0.0 + +### `serialPrintf(fd, string)` + + Alias: serialPuts + >= 2.0.0 + + +### `serialDataAvail(fd)` + >= 1.0.0 + +### `serialGetchar(fd)` + >= 1.0.0 + +--- + +## Shift + +### `shiftIn(dPin, cPin, order)` + >= 1.0.0 + +### `shiftOut(dPin, cPin, order, value)` + >= 1.0.0 + +--- + +## Soft PWM + +### `softPwmCreate(pin, value, range)` + >= 1.0.0 + +### `softPwmWrite(pin, value)` + >= 1.0.0 + +### `softPwmStop(pin)` + >= 1.1.0 + +--- + +## Soft Servo + +### `softServoWrite(pin, value)` + >= 1.0.0 + +### `softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7)` + >= 1.0.0 + +--- + +## Soft Tone + +### `softToneCreate(pin);` + >= 1.0.0 + +### `softToneWrite(pin, frequency);` + >= 1.0.0 + +### `softToneStop(pin);` + >= 1.1.0 + +--- + +## Extensions \ No newline at end of file diff --git a/README.md b/README.md index 2572085..0b563e9 100644 --- a/README.md +++ b/README.md @@ -1,258 +1,21 @@ -Node.js bindings to [wiringPi](https://projects.drogon.net/raspberry-pi/wiringpi/) +Node.js bindings to [wiringPi](http://www.wiringpi.com) Based on the awesome work of [Soarez](https://github.com/Soarez/node-wiring-pi) ## Install - > npm install wiring-pi - -## Use - -```javascript -var wpi = require('wiring-pi'); -``` -## Setup - -### `wpi.setup([mode])` - -An handy function to setup wiringPi - -```javascript -wpi.setup(); -``` - -```javascript -wpi.setup('gpio'); -``` - -Valid Modes: - -- `wpi`: sets up pin numbering with `wiringPiSetup` -- `gpio`: sets up pin numbers with `wiringPiSetupGpio` -- `sys`: sets up pin numbers with `wiringPiSetupSys` -- `phys`: sets up pin numbers with `wiringPiSetupPhys` - -See [wiringPi Pins](http://wiringpi.com/pins/) for the differences in Pin numbering; - -### `wpi.wiringPiSetup()` - -Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. -This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. -see the pins page (https://projects.drogon.net/raspberry-pi/wiringpi/pins/) for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. -This function needs to be called with root privileges. - -```javascript -wpi.wiringPisetup(); -``` - -### `wpi.wiringPiSetupGpio()` - -This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. -As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards. - -```javascript -wpi.wiringPisetupGpio(); -``` - -### `wpi.wiringPiSetupPhys()` - -Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. -As above, this function needs to be called with root priviliges. - -```javascript -wpi.wiringPisetupPhys(); ``` - -### `wpi.wiringPiSetupSys()` - -This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. -Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. -You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. -Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed). - -```javascript -wpi.wiringPisetupSys(); -``` - -## Core functions - -### `wpi.pinModeAlt(pin, mode)` - -This is an un-documented special to let you set any pin to any mode. - -- `pin`: pin number -- `mode`: `wpi.WPI_MODE_PINS`, `wpi.WPI_MODE_PHYS` or `wpi.WPI_MODE_GPIO` - -### `wpi.pinMode(pin, mode)` - -This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. -Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. -This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program. - -```javascript -wpi.pinMode(0, wpi.modes.OUTPUT); -``` - -- `pin`: pin number -- `mode`: `wpi.modes.INPUT`, `wpi.modes.OUTPUT`, `wpi.modes.PWM_OUTPUT` or `wpi.modes.GPIO_CLOCK` - -### `wpi.pullUpDnControl(pin, pud)` - -This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. -The parameter pud should be; PUD_OFF (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP (pull to 3.3v). -The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. - -```javascript -wpi.pullUpDnControl(0, wpi.PUD_DOWN); +npm install wiring-pi ``` -- `pin`: pin number -- `pud`: `wpi.PUD_OFF`, `wpi.PUD_DOWN`, `wpi.PUD_UP` - -### `wpi.digitalRead(pin)` - -This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) depending on the logic level at the pin. - -```javascript -wpi.digitalRead(0); -//=> 1 -``` - -- `pin`: pin number - -### `wpi.digitalWrite(pin, value)` - -Write the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as an output. -WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW. - -```javascript -wpi.digitalWrite(0, wpi.HIGH); -``` +## Usage ```javascript -wpi.digitalWrite(0, wpi.LOW); -``` - -- `pin`: pin number -- `value`: 0 (`wpi.LOW`) or 1 (`wpi.HIGH`) - -### `wpi.pwmWrite(pin, value)` - -Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is 0-1024. -Other PWM devices may have other PWM ranges. -This function is not able to control the Pi's on-board PWM when in Sys mode. - -```javascript -wpi.pwmWrite(0, 512); -``` - -- `pin`: pin number -- `value`: value in PWM ranges - -### `wpi.analogRead(pin)` - -This returns the value read on the supplied analog input pin. You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc. - -```javascript -wpi.analogRead(0); -//=> 512 -``` - -- `pin`: pin number - -### `wpi.analogWrite(pin, value)` - -This writes the given value to the supplied analog pin. You will need to register additional analog modules to enable this function for devices such as the Gertboard. - -```javascript -wpi.analogWrite(0, 512); -``` - -- `pin`: pin number -- `value`: value - -## Raspberry Pi specifics - -### `wpi.piBoardRev()` - -This returns the board revision of the Raspberry Pi. It will be either 1 or 2. -Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. - -```javascript -wpi.piBoardRev(); -//=>2 -``` - -### `wpi.wpiPinToGpio(pin)` - -This returns the BCM_GPIO pin number of the supplied wiringPi pin. -It takes the board revision into account. - -```javascript -wpi.wpiPinToGpio(7); -//=>4 -``` - -- `pin`: pin number in WiringPi scheme - -### `wpi.physPinToGpio(pin)` - -This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector. - -```javascript -wpi.wpiPinToGpio(23); -//=>11 -``` - -- `pin`: pin number in physical scheme - -### `wpi.setPadDrive(group, value)` - -This sets the "strength" of the pad drivers for a particular group of pins. -There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you know what you are doing. - -### `wpi.getAlt(pin)` - -Returns the ALT bits for a given port. Only really of-use for the gpio readall command (I think). - -### `wpi.digitalWriteByte(value)` - -This writes the 8-bit byte supplied to the first 8 GPIO pins. -It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware. - -```javascript -wpi.digitalWriteByte(0xFF); //set the first 8 GPIO pins to HIGH -``` - -- `value`: the byte to write to the first 8 GPIO pins - -### `wpi.pwmSetMode(mode)` - -The PWM generator can run in 2 modes – “balanced” and “mark:space”. -The mark:space mode is traditional, however the default mode in the Pi is “balanced”. -You can switch modes by supplying the parameter: PWM_MODE_BAL or PWM_MODE_MS. - -```javascript -wpi.pwmSetMode(wpi.PWM_MODE_BAL); +var wpi = require('wiring-pi'); ``` +## Documentation -- `mode`: `wpi.PWM_MODE_BAL` or `wpi.PWM_MODE_MS` - -### `wpi.pwmSetRange(range)` - -This sets the range register in the PWM generator. The default is 1024. -Note: The PWM control functions can not be used when in Sys mode. -To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. - -### `wpi.pwmSetClock(divisor)` - -This sets the divisor for the PWM clock. -Note: The PWM control functions can not be used when in Sys mode. -To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. - -### `wpi.gpioClockSet(pin, freq)` - -Set the frequency on a GPIO clock pin +See the [DOCUMENTATION.md](https://github.com/eugeneware/wiring-pi/blob/master/DOCUMENTATION.md) file for more detailed documentation. ## Contributing @@ -266,8 +29,8 @@ See the [CONTRIBUTING.md](https://github.com/eugeneware/wiring-pi/blob/master/CO wiring-pi is only possible due to the excellent work of the following contributors: - - - - -
Igor Soarez (Creator)GitHub/SoarezTwitter/@igorsoarez
Gohy LeandreGitHub/nekuz0rTwitter/@LeandreGohy
Eugene WareGitHub/eugenewareTwitter/@eugeneware
+Contributor | GitHub profile | Twitter profile | +--- | --- | --- +Igor Soarez (Creator) | [Soarez](https://github.com/Soarez) | [@igorsoarez](https://twitter.com/igorsoarez) +Leandre Gohy | [nekuz0r](https://github.com/nekuz0r) | [@LeandreGohy](http://twitter.com/LeandreGohy) +Eugene Ware | [eugeneware](https://github.com/eugeneware) | [@eugeneware](http://twitter.com/eugeneware) diff --git a/binding.gyp b/binding.gyp index 8b110d9..b22d142 100644 --- a/binding.gyp +++ b/binding.gyp @@ -3,7 +3,16 @@ { 'target_name': 'wiringPi', 'sources': [ - 'src/bindings.cc' + 'src/wiringPi.cc', + 'src/softPwm.cc', + 'src/softServo.cc', + 'src/softTone.cc', + 'src/wiringPiI2C.cc', + 'src/wiringPiSPI.cc', + 'src/wiringSerial.cc', + 'src/wiringShift.cc', + 'src/wiringPiISR.cc', + 'src/wpi.cc' ], 'include_dirs': [ 'wiringpi/wiringPi' @@ -12,7 +21,18 @@ '", "contributors": [ - "Leandre Gohy " + "Leandre Gohy ", + "Eugene Ware " ], "license": "BSD" } diff --git a/src/addon.h b/src/addon.h new file mode 100644 index 0000000..fb326d2 --- /dev/null +++ b/src/addon.h @@ -0,0 +1,150 @@ +#ifndef _ADDON_H_ +#define _ADDON_H_ + + #include + #include + #include + #include + #include + #include + #include + + using namespace v8; + + template + struct type_of_size { typedef char type[N]; }; + + template + char (&sizeof_array_helper(T(&)[size]))[size]; + + #define sizeof_array(array) sizeof(sizeof_array_helper(array)) + + template + void ThrowError(T func, const char* format, ...) { + char buffer[256]; + va_list args; + va_start(args, format); + vsnprintf(buffer, 156, format, args); + va_end(args); + + ThrowException(func(String::New(buffer))); + } + + template + bool isInList(T value, std::initializer_list values) { + return !(std::find(values.begin(), values.end(), value) == values.end()); + } + + #define DECLARE(name) \ + namespace nodemodule { \ + static Handle name(const Arguments& args); \ + } + + #define IMPLEMENT(name) \ + Handle nodemodule::name(const Arguments& args) + + #define EXPORT_FUNCTION(name) \ + target->Set(String::NewSymbol(#name), \ + FunctionTemplate::New(nodemodule::name)->GetFunction()) + + #define EXPORT_CONSTANT_INT(name) \ + target->Set(String::NewSymbol(#name), \ + Int32::New(name), static_cast(ReadOnly | DontDelete)); + + #define EXPORT_CONSTANT_STRING(name) \ + target->Set(String::NewSymbol(#name), \ + String::New(name), static_cast(ReadOnly | DontDelete)); + + #define EXPORT_CONSTANT_INT_ARRAY(name, array, length) \ + { \ + Local arr = Array::New(); \ + for (int i = 0; i < length; i++) { \ + arr->Set(i, INT32(array[i])); \ + } \ + target->Set(String::NewSymbol(#name), arr, static_cast(ReadOnly | DontDelete)); \ + } + + #define EXPORT_CONSTANT_STRING_ARRAY(name, array, length) \ + { \ + Local arr = Array::New(); \ + for (int i = 0; i < length; i++) { \ + arr->Set(i, STRING(array[i])); \ + } \ + target->Set(String::NewSymbol(#name), arr, static_cast(ReadOnly | DontDelete)); \ + } + + #define NODE_MODULE_INIT() \ + namespace nodemodule { \ + void init(Handle target); \ + } \ + void nodemodule::init(Handle target) + #define NODE_MODULE_DECLARE(name) NODE_MODULE(name, nodemodule::init) + #define IMPLEMENT_EXPORT_INIT(name) void nodemodule::init##name(Handle target) + #define DECLARE_EXPORT_INIT(name) \ + namespace nodemodule { \ + void init##name(Handle target); \ + } + + #define INIT(name) nodemodule::init##name(target); + + #define SCOPE_OPEN() HandleScope scope + #define SCOPE_CLOSE(obj) return scope.Close(obj) + + #define UNDEFINED() Undefined() + #define INT32(v) Int32::New(v) + #define UINT32(v) Uint32::New(v) + #define STRING(v) String::New(v) + + #define THROW_ERROR(fmt, ...) \ + ThrowError(Exception::Error, fmt, __VA_ARGS__); \ + SCOPE_CLOSE(UNDEFINED()) + + #define THROW_TYPE_ERROR(fmt, ...) \ + ThrowError(Exception::TypeError, fmt, __VA_ARGS__); \ + SCOPE_CLOSE(UNDEFINED()) + + #define SET_ARGUMENT_NAME(id, name) static const char* arg##id = #name + #define GET_ARGUMENT_NAME(id) arg##id + + #define CHECK_ARGUMENTS_LENGTH_EQUAL(length) \ + if (args.Length() != length) { \ + THROW_ERROR("%s: arguments.length => (%i === %i) === false", __func__, args.Length(), length); \ + } + + #define CHECK_ARGUMENT_TYPE(id, istype) \ + if (!args[id]->istype()) { \ + THROW_ERROR("%s: %s(%s) === false", __func__, #istype, GET_ARGUMENT_NAME(id)); \ + } + + #define CHECK_ARGUMENT_TYPE_INT32(id) CHECK_ARGUMENT_TYPE(id, IsInt32) + #define CHECK_ARGUMENT_TYPE_UINT32(id) CHECK_ARGUMENT_TYPE(id, IsUint32) + #define CHECK_ARGUMENT_TYPE_NUMBER(id) CHECK_ARGUMENT_TYPE(id, IsNumber) + #define CHECK_ARGUMENT_TYPE_STRING(id) CHECK_ARGUMENT_TYPE(id, IsString) + #define CHECK_ARGUMENT_TYPE_FUNCTION(id) CHECK_ARGUMENT_TYPE(id, IsFunction) + #define CHECK_ARGUMENT_TYPE_OBJECT(id) CHECK_ARGUMENT_TYPE(id, IsObject) + #define CHECK_ARGUMENT_TYPE_NODE_BUFFER(id) \ + if (!(args[id]->IsObject() && node::Buffer::HasInstance(args[id]))) { \ + THROW_ERROR("%s: %s(%s) === false", __func__, "isBuffer", GET_ARGUMENT_NAME(id)); \ + } + + #define GET_ARGUMENT_AS_TYPE(id, type) args[id]->type() + + #define GET_ARGUMENT_AS_INT32(id) GET_ARGUMENT_AS_TYPE(id, Int32Value) + #define GET_ARGUMENT_AS_UINT32(id) GET_ARGUMENT_AS_TYPE(id, Uint32Value) + #define GET_ARGUMENT_AS_NUMBER(id) GET_ARGUMENT_AS_TYPE(id, NumberValue) + #define GET_ARGUMENT_AS_STRING(id) GET_ARGUMENT_AS_TYPE(id, ToString) + #define GET_ARGUMENT_AS_LOCAL_FUNCTION(id) Local::Cast(args[id]) + #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) + + #define LIST(...) { __VA_ARGS__ } + #define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ + if (!isInList(std::string(*value), LIST T)) { \ + THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ + } + + #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ + if (!isInList(value, LIST T)) { \ + THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ + } + +#endif \ No newline at end of file diff --git a/src/bindings.cc b/src/bindings.cc deleted file mode 100644 index 7bfe32c..0000000 --- a/src/bindings.cc +++ /dev/null @@ -1,2498 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace v8; - -#define DECLARE(name) \ - static Handle name(const Arguments& args) -#define IMPLEMENT(name) \ - Handle wpi::name(const Arguments& args) -#define EXPORT(name) \ - target->Set(String::NewSymbol(#name), \ - FunctionTemplate::New(wpi::name)->GetFunction()) - -namespace wpi { - // Setup - DECLARE(wiringPiSetup); - DECLARE(wiringPiSetupGpio); - DECLARE(wiringPiSetupSys); - DECLARE(wiringPiSetupPhys); - - // Core wiringPi functions - DECLARE(pinModeAlt); - DECLARE(pinMode); - DECLARE(pullUpDnControl); - DECLARE(digitalRead); - DECLARE(digitalWrite); - DECLARE(pwmWrite); - DECLARE(analogRead); - DECLARE(analogWrite); - DECLARE(pulseIn); - - DECLARE(delay); - DECLARE(delayMicroseconds); - DECLARE(millis); - DECLARE(micros); - - // PiFace specifics (Deprecated) - //DECLARE(wiringPiSetupPiFace); - //DECLARE(wiringPiSetupPiFaceForGpioProg); // Don't use this - for gpio program only - - // On-Board Rasberry Pi hardware specific stuff - DECLARE(piBoardRev); - DECLARE(piBoardId); - DECLARE(wpiPinToGpio); - DECLARE(physPinToGpio); - DECLARE(setPadDrive); - DECLARE(getAlt); - DECLARE(digitalWriteByte); - DECLARE(pwmSetMode); - DECLARE(pwmSetRange); - DECLARE(pwmSetClock); - DECLARE(gpioClockSet); - - // Extensions - DECLARE(drcSetupSerial); - DECLARE(max5322Setup); - DECLARE(max31855Setup); - DECLARE(mcp23s08Setup); - DECLARE(mcp23s17Setup); - DECLARE(mcp3002Setup); - DECLARE(mcp3004Setup); - DECLARE(mcp3422Setup); - DECLARE(mcp4802Setup); - DECLARE(mcp23008Setup); - DECLARE(mcp23016Setup); - DECLARE(mcp23017Setup); - DECLARE(pcf8574Setup); - DECLARE(pcf8591Setup); - DECLARE(sn3218Setup); - DECLARE(sr595Setup); - DECLARE(pca9685Setup); - - // Soft PWM - DECLARE(softPwmCreate); - DECLARE(softPwmWrite); - DECLARE(softPwmStop); - - // Soft Servo - DECLARE(softServoWrite); - DECLARE(softServoSetup); - - // Soft Tone - DECLARE(softToneCreate); - DECLARE(softToneWrite); - DECLARE(softToneStop); - - // WiringPI I2C - DECLARE(wiringPiI2CRead); - DECLARE(wiringPiI2CReadReg8); - DECLARE(wiringPiI2CReadReg16); - DECLARE(wiringPiI2CWrite); - DECLARE(wiringPiI2CWriteReg8); - DECLARE(wiringPiI2CWriteReg16); - DECLARE(wiringPiI2CSetupInterface); - DECLARE(wiringPiI2CSetup); - - // WiringPI SPI - DECLARE(wiringPiSPIGetFd); - DECLARE(wiringPiSPIDataRW); - DECLARE(wiringPiSPISetup); - - // WiringPi Serial - DECLARE(serialOpen); - DECLARE(serialClose); - DECLARE(serialFlush); - DECLARE(serialPutchar); - DECLARE(serialPuts); - DECLARE(serialPrintf); - DECLARE(serialDataAvail); - DECLARE(serialGetchar); - - // WiringPi Shift - DECLARE(shiftIn); - DECLARE(shiftOut); -} - -// === Setup === - -// Func : int wiringPiSetup(void) -// Returns : error code if v1 mode otherwise always returns 0 -// Description : Initialises wiringPi and assumes that the calling program is going -// to be using the wiringPi pin numbering scheme. -// This is a simplified numbering scheme which provides a mapping from virtual -// pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. -// see the pins page (https://projects.drogon.net/raspberry-pi/wiringpi/pins/) for a table -// which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location -// on the edge connector. -// This function needs to be called with root privileges. - -IMPLEMENT(wiringPiSetup) { - HandleScope scope; - int res; - - // CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSetup(); - - return scope.Close(Int32::New(res)); -} - -// Func : int wiringPiSetupGpio(void) -// Returns : error code if v1 mode otherwise always returns 0 -// Description : This is indential to above, however it allows the calling programs to use -// the Broadcom GPIO pin numbers directly with no re-mapping. -// As above, this function needs to be called with root privileges, and note that some pins -// are different from revision 1 to revision 2 boards. - -IMPLEMENT(wiringPiSetupGpio) { - HandleScope scope; - int res; - - // CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSetupGpio(); - - return scope.Close(Int32::New(res)); -} - -// Func : int wiringPiSetupPhys(void) -// Returns : error code if v1 mode otherwise always returns 0 -// Description : Identical to above, however it allows the calling programs to use -// the physical pin numbers on the P1 connector only. -// As above, this function needs to be called with root priviliges. - -IMPLEMENT(wiringPiSetupPhys) { - HandleScope scope; - int res; - - // CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSetupPhys(); - - return scope.Close(Int32::New(res)); -} - -// Func : int wiringPiSetupSys(void) -// Returns : error code if v1 mode otherwise always returns 0 -// Description : This initialises wiringPi but uses the /sys/class/gpio interface rather than -// accessing the hardware directly. This can be called as a non-root user provided the GPIO pins -// have been exported before-hand using gpio program. Pin numbering in this mode is the native -// Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences -// between Rev 1 and Rev 2 boards. -// Note: In this mode you can only use the pins which have been exported via the -// /sys/class/gpio interface before you run your program. You can do this in a seperate -// shell script, or by using the system() function from inside your program to call the gpio program. -// Also note that some functions have no effect when using this mode as they're not currently -// possible to action unless called with root privileges. (although you can use system() to call -// gpio to set/change modes if needed). - -IMPLEMENT(wiringPiSetupSys) { - HandleScope scope; - int res; - - // CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSetupSys(); - - return scope.Close(Int32::New(res)); -} - -// === Core functions === - -// Func : void pinModeAlt(int pin, int mode) -// Description : This is an un-documented special to let you set any pin to any mode. -// Modes are WPI_MODE_PINS, WPI_MODE_PHYS, WPI_MODE_GPIO. - -IMPLEMENT(pinModeAlt) { - HandleScope scope; - int pin; - int mode; - - // CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - mode = args[1]->NumberValue(); - - // CHECK: Allowed values - if (mode != WPI_MODE_PINS && mode != WPI_MODE_PHYS && mode != WPI_MODE_GPIO) { - ThrowException(Exception::TypeError( - String::New("Incorrect mode value. WPI_MODE_PINS, WPI_MODE_PHYS or WPI_MODE_GPIO expected."))); - return scope.Close(Undefined()); - } - - ::pinModeAlt(pin, mode); - - return scope.Close(Undefined()); -} - -// Func : void pinMode(int pin, int mode) -// Description : This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. -// Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) -// supports CLOCK output modes. -// This function has no effect when in Sys mode. If you need to change the pin mode, the you can -// do it with the gpio program in a script before you start your program. - -IMPLEMENT(pinMode) { - HandleScope scope; - int mode; - int pin; - - // CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - mode = args[1]->NumberValue(); - - // CHECK: Allowed values - if (mode != INPUT && mode != OUTPUT && mode != PWM_OUTPUT && mode != GPIO_CLOCK && mode != SOFT_PWM_OUTPUT && mode != SOFT_TONE_OUTPUT) { - ThrowException(Exception::TypeError( - String::New("Incorrect mode value. INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK expected."))); - return scope.Close(Undefined()); - } - - ::pinMode(pin, mode); - - return scope.Close(Undefined()); -} - -// Func : void pullUpDnControl(int pin, int pud) -// Description : This sets the pull-up or pull-down resistor mode on the given pin, which should be set -// as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. -// The parameter pud should be; PUD_OFF (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP (pull to 3.3v). -// The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. - -IMPLEMENT(pullUpDnControl) { - HandleScope scope; - int pin; - int pud; - - // CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - pud = args[1]->NumberValue(); - - // CHECK: Allowed values - if (pud != PUD_OFF && pud != PUD_DOWN && pud != PUD_UP) { - ThrowException(Exception::TypeError( - String::New("Incorrect mode value. PUD_OFF, PUD_DOWN or PUD_UP expected."))); - return scope.Close(Undefined()); - } - - ::pullUpDnControl(pin, pud); - - return scope.Close(Undefined()); -} - -// Func : int digitalRead(int pin) -// Description : This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) -// depending on the logic level at the pin. - -IMPLEMENT(digitalRead) { - HandleScope scope; - int pin; - int res; - - // CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - res = ::digitalRead(pin); - - // Make sure the function returns strictly 1 or 0 - // §4.7/4 from the C++ Standard says (Integral Conversion) - // If the source type is bool, the value false is converted to zero and the value true is converted to one. - res = (res != 0); - - return scope.Close(Int32::New(res)); -} - -// Func : void digitalWrite(int pin, int value) -// Description : Write the value HIGH or LOW (1 or 0) to the given pin which must have been -// previously set as an output. -// WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW. - -IMPLEMENT(digitalWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - value = args[1]->NumberValue(); - - // Make sure value is strictly 1 or 0 - // §4.7/4 from the C++ Standard says (Integral Conversion) - // If the source type is bool, the value false is converted to zero and the value true is converted to one. - value = (value != 0); - - ::digitalWrite(pin, value); - - return scope.Close(Undefined()); -} - -// Func : void pwmWrite(int pin, int value) -// Description : Writes the value to the PWM register for the given pin. The Raspberry Pi has -// one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is 0-1024. Other PWM -// devices may have other PWM ranges. -// This function is not able to control the Pi's on-board PWM when in Sys mode. - -IMPLEMENT(pwmWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument types. Numbers expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - value = args[1]->NumberValue(); - - ::pwmWrite(pin, value); - - return scope.Close(Undefined()); -} - -// Func : int analogRead(int pin) -// Description : This returns the value read on the supplied analog input pin. You will need to -// register additional analog modules to enable this function for device such as the Gertboard, -// quick2Wire analog board, etc. - -IMPLEMENT(analogRead) { - HandleScope scope; - int pin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - res = ::analogRead(pin); - - return scope.Close(Int32::New(res)); -} - -// Func : void analogWrite(int pin, int value) -// Description : This writes the given value to the supplied analog pin. You will need to register -// additional analog modules to enable this function for devices such as the Gertboard. - -IMPLEMENT(analogWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - value = args[1]->NumberValue(); - - ::analogWrite(pin, value); - - return scope.Close(Undefined()); -} - -IMPLEMENT(pulseIn) { - HandleScope scope; - int pin; - int state; - int microseconds; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - state = args[1]->NumberValue(); - - microseconds = ::pulseIn(pin, state); - - return scope.Close(Int32::New(microseconds)); -} - -IMPLEMENT(delay) { - HandleScope scope; - unsigned int howLong; - - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - howLong = args[0]->Uint32Value(); - - ::delay(howLong); - - return scope.Close(Undefined()); -} - -IMPLEMENT(delayMicroseconds) { - HandleScope scope; - unsigned int howLong; - - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - howLong = args[0]->Uint32Value(); - - ::delay(howLong); - - return scope.Close(Undefined()); -} - -IMPLEMENT(millis) { - HandleScope scope; - - unsigned int ms = ::millis(); - - return scope.Close(Uint32::New(ms)); -} - -IMPLEMENT(micros) { - HandleScope scope; - - unsigned int us = ::micros(); - - return scope.Close(Uint32::New(us)); -} - -// === Raspberry Pi specific === - -// Func : int piBoardRev(void) -// Description : This returns the board revision of the Raspberry Pi. It will be either 1 or 2. -// Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, -// so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. - -IMPLEMENT(piBoardRev) { - HandleScope scope; - int res; - - //CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - res = ::piBoardRev(); - - return scope.Close(Int32::New(res)); -} - -IMPLEMENT(piBoardId) { - HandleScope scope; - int model; - int rev; - int mem; - char* marker; - - //CHECK: Number of argument - if (args.Length() != 0) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - ::piBoardId(&model, &rev, &mem, &marker); - - Local obj = Object::New(); - obj->Set(String::NewSymbol("model"), Int32::New(model)); - obj->Set(String::NewSymbol("rev"), Int32::New(rev)); - obj->Set(String::NewSymbol("mem"), Int32::New(mem)); - obj->Set(String::NewSymbol("marker"), String::New(marker)); - - return scope.Close(obj); -} - -// Func : int wpiPinToGpio(int wpiPin) -// Description : This returns the BCM_GPIO pin number of the supplied wiringPi pin. -// It takes the board revision into account. - -IMPLEMENT(wpiPinToGpio) { - HandleScope scope; - int wpiPin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - wpiPin = args[0]->NumberValue(); - res = ::wpiPinToGpio(wpiPin); - - return scope.Close(Int32::New(res)); -} - -// Func : int physPinToGpio (int physPin) -// Description : This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector. - -IMPLEMENT(physPinToGpio) { - HandleScope scope; - int physPin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - physPin = args[0]->NumberValue(); - res = ::physPinToGpio(physPin); - - return scope.Close(Int32::New(res)); -} - -// Func : void setPadDrive(int group, int value) -// Description : This sets the "strength" of the pad drivers for a particular group of pins. -// There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you -// know what you are doing. - -IMPLEMENT(setPadDrive) { - HandleScope scope; - int group; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - group = args[0]->NumberValue(); - value = args[1]->NumberValue(); - ::setPadDrive(group, value); - - return scope.Close(Undefined()); -} - -// Func : int getAlt(int pin) -// Description : Returns the ALT bits for a given port. Only really of-use -// for the gpio readall command (I think). - -IMPLEMENT(getAlt) { - HandleScope scope; - int pin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - res = ::getAlt(pin); - - return scope.Close(Int32::New(res)); -} - -// Func : void digitalWriteByte(int value) -// Description : This writes the 8-bit byte supplied to the first 8 GPIO pins. -// It’s the fastest way to set all 8 bits at once to a particular value, although it still takes -// two write operations to the Pi’s GPIO hardware. - -IMPLEMENT(digitalWriteByte) { - HandleScope scope; - int value; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - value = args[0]->NumberValue(); - ::digitalWriteByte(value); - - return scope.Close(Undefined()); -} - -// Func : void pwmSetMode(int mode) -// Description : The PWM generator can run in 2 modes – “balanced” and “mark:space”. -// The mark:space mode is traditional, however the default mode in the Pi is “balanced”. -// You can switch modes by supplying the parameter: PWM_MODE_BAL or PWM_MODE_MS. - -IMPLEMENT(pwmSetMode) { - HandleScope scope; - int mode; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - mode = args[0]->NumberValue(); - - //CHECK: Allowed values - if (mode != PWM_MODE_BAL && mode != PWM_MODE_MS) { - ThrowException(Exception::TypeError( - String::New("Incorrect mode value. PWM_MODE_BAL or PWM_MODE_MS expected."))); - return scope.Close(Undefined()); - } - - ::pwmSetMode(mode); - - return scope.Close(Undefined()); -} - -// Func : void pwmSetRange(unsigned int range) -// Description : This sets the range register in the PWM generator. The default is 1024. -// Note: The PWM control functions can not be used when in Sys mode. To understand more about -// the PWM system, you’ll need to read the Broadcom ARM peripherals manual. - -IMPLEMENT(pwmSetRange) { - HandleScope scope; - unsigned int range; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - range = args[0]->Uint32Value(); - ::pwmSetRange(range); - - return scope.Close(Undefined()); -} - -// Func : void pwmSetClock(int divisor) -// Description : This sets the divisor for the PWM clock. -// Note: The PWM control functions can not be used when in Sys mode. To understand more about -// the PWM system, you’ll need to read the Broadcom ARM peripherals manual. - -IMPLEMENT(pwmSetClock) { - HandleScope scope; - int divisor; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - divisor = args[0]->NumberValue(); - ::pwmSetClock(divisor); - - return scope.Close(Undefined()); -} - -// Func : void gpioClockSet(int pin, int freq) -// Description : Set the frequency on a GPIO clock pin - -IMPLEMENT(gpioClockSet) { - HandleScope scope; - int pin; - int freq; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->NumberValue(); - freq = args[1]->NumberValue(); - ::gpioClockSet(pin, freq); - - return scope.Close(Undefined()); -} - -// === Extensions === - -// Func : int drcSetupSerial(const int pinBase, const int numPins, const char* device, const int baud) -// Description : https://projects.drogon.net/drogon-remote-control/drc-protocol-arduino/ - -IMPLEMENT(drcSetupSerial) { - HandleScope scope; - int pinBase; - int numPins; - const char* device; - int baud; - int res; - - //CHECK: Number of argument - if (args.Length() != 4) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsString() || !args[3]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - numPins = args[1]->Int32Value(); - v8::String::AsciiValue deviceString(args[2]->ToString()); - device = *deviceString; - baud = args[3]->Int32Value(); - - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::drcSetupSerial(pinBase, numPins, device, baud); - - return scope.Close(Int32::New(res)); -} - -// Func : int max5233Setup(int pinBase, int spiChannel) - -IMPLEMENT(max5322Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::max5322Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func : int max31855Setup(int pinBase, int spiChannel) - -IMPLEMENT(max31855Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::max31855Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func int mcp23s08Setup(const int pinBase, const int spiPort, const int devId) - -IMPLEMENT(mcp23s08Setup) { - HandleScope scope; - int pinBase; - int spiPort; - int devId; - int res; - - //CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->NumberValue(); - spiPort = args[1]->NumberValue(); - devId = args[2]->NumberValue(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiPort != 0 && spiPort != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiPort value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - //MCP23S08 3bits addressing - if (devId < 0 || devId > 7) { - ThrowException(Exception::TypeError( - String::New("Incorrect devId value. Value from 0 to 7 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23s08Setup(pinBase, spiPort, devId); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp23s17Setup(int pinBase, int spiPort, int devId) -// Description : Initialise libWiringPi to be used with MCP23S17 -// pinBase is any number above 64 that doesn’t clash with any other wiringPi expansion module, -// spiPort is 0 or 1 for one of the two SPI ports on the Pi and devId is the ID of that MCP23s17 on the SPI port. - -IMPLEMENT(mcp23s17Setup) { - HandleScope scope; - int pinBase; - int spiPort; - int devId; - int res; - - //CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->NumberValue(); - spiPort = args[1]->NumberValue(); - devId = args[2]->NumberValue(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiPort != 0 && spiPort != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiPort value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - //MCP23S17 3bits addressing - if (devId < 0 || devId > 7) { - ThrowException(Exception::TypeError( - String::New("Incorrect devId value. Value from 0 to 7 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23s17Setup(pinBase, spiPort, devId); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp3002Setup(int pinBase, int spiChannel) - -IMPLEMENT(mcp3002Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp3002Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp3004Setup(int pinBase, int spiChannel) - -IMPLEMENT(mcp3004Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp3004Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp3422Setup(int pinBase, int i2cAddress, int sampleRate, int gain) - -IMPLEMENT(mcp3422Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int sampleRate; - int gain; - int res; - - //CHECK: Number of argument - if (args.Length() != 4) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - sampleRate = args[2]->Int32Value(); - gain = args[3]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (sampleRate < 0 || sampleRate > 3) { - ThrowException(Exception::TypeError( - String::New("Incorrect sampleRate value. MCP3422_SR_3_75, MCP3422_SR_15, MCP3422_SR_60 or MCP3422_SR_240 expected."))); - return scope.Close(Undefined()); - } - - if (gain < 0 || gain > 3) { - ThrowException(Exception::TypeError( - String::New("Incorrect gain value. MCP3422_GAIN_1, MCP3422_GAIN_2, MCP3422_GAIN_3 or MCP3422_GAIN_4 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp3422Setup(pinBase, i2cAddress, sampleRate, gain); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp4802Setup(int pinBase, int spiChannel) - -IMPLEMENT(mcp4802Setup) { - HandleScope scope; - int pinBase; - int spiChannel; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - spiChannel = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - if (spiChannel != 0 && spiChannel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect spiChannel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp4802Setup(pinBase, spiChannel); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp23008Setup(int pinBase, int i2cAddress) - -IMPLEMENT(mcp23008Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23008Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp23016Setup(const int pinBase, const int i2cAddress) - -IMPLEMENT(mcp23016Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23016Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int mcp23017Setup(const int pinBase, const int i2cAddress) - -IMPLEMENT(mcp23017Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::mcp23017Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int pcf8574Setup(const int pinBase, const int i2cAddress) - -IMPLEMENT(pcf8574Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::pcf8574Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int pcf8591Setup(const int pinBase, const int i2cAddress) - -IMPLEMENT(pcf8591Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::pcf8591Setup(pinBase, i2cAddress); - - return scope.Close(Int32::New(res)); -} - -// Func : int sn3128Setup(int pinBase) - -IMPLEMENT(sn3218Setup) { - HandleScope scope; - int pinBase; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::sn3218Setup(pinBase); - - return scope.Close(Int32::New(res)); -} - -// Func : int sr595Setup(const int pinBase, const int numPins, const int dataPin, const int clockPin, const int latchPin) - -IMPLEMENT(sr595Setup) { - HandleScope scope; - int pinBase; - int numPins; - int dataPin; - int clockPin; - int latchPin; - int res; - - //CHECK: Number of argument - if (args.Length() != 5) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() || !args[4]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - numPins = args[1]->Int32Value(); - dataPin = args[2]->Int32Value(); - clockPin = args[3]->Int32Value(); - latchPin = args[4]->Int32Value(); - - //CHECK: Allowed values - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected."))); - return scope.Close(Undefined()); - } - - res = ::sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin); - - return scope.Close(Int32::New(res)); -} - -IMPLEMENT(pca9685Setup) { - HandleScope scope; - int pinBase; - int i2cAddress; - int freq; - int res; - - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect arguments type. Number expected."))); - return scope.Close(Undefined()); - } - - pinBase = args[0]->Int32Value(); - i2cAddress = args[1]->Int32Value(); - freq = args[2]->Int32Value(); - - if (pinBase <= 64) { - ThrowException(Exception::TypeError( - String::New("Incorrect pinBase value. >64 expected"))); - return scope.Close(Undefined()); - } - - res = ::pca9685Setup(pinBase, i2cAddress, freq); - - return scope.Close(Int32::New(res)); -} - -// === Soft PWM === - -// Func : int softPwmCreate(int pin, int value, int range) -// Description : This creates a software controlled PWM pin. -// You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. -// Use 100 for the pwmRange, then the value can be anything from 0 (off) to 100 (fully on) for the given pin. -// The return value is 0 for success. Anything else and you should check the global errno variable to see what went wrong. -// NOTE : You must initialise wiringPi with one of wiringPiSetup(), wiringPiSetupGpio() or wiringPiSetupPhys() functions. -// wiringPiSetupSys() is not fast enough, so you must run your programs with sudo. -// NOTE2 : Each “cycle” of PWM output takes 10mS with the default range value of 100, -// so trying to change the PWM value more than 100 times a second will be futile. -// NOTE3 : Each pin activated in softPWM mode uses approximately 0.5% of the CPU. -// NOTE4 : There is currently no way to disable softPWM on a pin while the program in running. -// NOTE5 : You need to keep your program running to maintain the PWM output! - -IMPLEMENT(softPwmCreate) { - HandleScope scope; - int pin; - int value; - int range; - int res; - - //CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - value = args[1]->Int32Value(); - range = args[2]->Int32Value(); - - res = ::softPwmCreate(pin, value, range); - - return scope.Close(Int32::New(res)); -} - -// Func void softPwmWrite(int pin, int value) -// Description : This updates the PWM value on the given pin. -// The value is checked to be in-range and pins that haven’t previously been initialised via softPwmCreate will be silently ignored. - -IMPLEMENT(softPwmWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - value = args[1]->Int32Value(); - - ::softPwmWrite(pin, value); - - return scope.Close(Undefined()); -} - -IMPLEMENT(softPwmStop) { - HandleScope scope; - int pin; - - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - - ::softPwmStop(pin); - - return scope.Close(Undefined()); -} - -// === Soft Servo === - -// Func : void softServoWrite(int pin, int value) -// Description : Write a Servo value to the given pin - -IMPLEMENT(softServoWrite) { - HandleScope scope; - int pin; - int value; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - value = args[1]->Int32Value(); - - ::softServoWrite(pin, value); - - return scope.Close(Undefined()); -} - -// Func : int softServoSetup(int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) -// Description : Setup the software servo system - -IMPLEMENT(softServoSetup) { - HandleScope scope; - int p0; - int p1; - int p2; - int p3; - int p4; - int p5; - int p6; - int p7; - int res; - - //CHECK: Number of argument - if (args.Length() != 8) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber() - || !args[4]->IsNumber() || !args[5]->IsNumber() || !args[6]->IsNumber() || !args[7]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - p0 = args[0]->Int32Value(); - p1 = args[1]->Int32Value(); - p2 = args[2]->Int32Value(); - p3 = args[3]->Int32Value(); - p4 = args[4]->Int32Value(); - p5 = args[5]->Int32Value(); - p6 = args[6]->Int32Value(); - p7 = args[7]->Int32Value(); - - res = ::softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7); - - return scope.Close(Int32::New(res)); -} - -// === Soft Tone === - -// Func : int softToneCreate(int pin); -// Description : This creates a software controlled tone pin. -// You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. -// The return value is 0 for success. -// Anything else and you should check the global errno variable to see what went wrong. -// NOTE : You must initialise wiringPi with one of wiringPiSetup(), wiringPiSetupGpio() or wiringPiSetupPhys() functions. -// wiringPiSetupSys() is not fast enough, so you must run your programs with sudo. -// NOTE2 : Each pin activated in softTone mode uses approximately 0.5% of the CPU. -// NOTE3 : You need to keep your program running to maintain the sound output! - -IMPLEMENT(softToneCreate) { - HandleScope scope; - int pin; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - - res = ::softToneCreate(pin); - - return scope.Close(Int32::New(res)); -} - -// Func : void softToneWrite(int pin, int freq); -// Description : This updates the tone frequency value on the given pin. The tone will be played until you set the frequency to 0. - -IMPLEMENT(softToneWrite) { - HandleScope scope; - int pin; - int freq; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - freq = args[1]->Int32Value(); - - ::softToneWrite(pin, freq); - - return scope.Close(Undefined()); -} - -IMPLEMENT(softToneStop) { - HandleScope scope; - int pin; - - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - pin = args[0]->Int32Value(); - - ::softToneStop(pin); - - return scope.Close(Undefined()); -} - -// === WiringPI I2C === - -IMPLEMENT(wiringPiI2CRead) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CReadReg8) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CReadReg16) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CWrite) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CWriteReg8) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CWriteReg16) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CSetupInterface) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -IMPLEMENT(wiringPiI2CSetup) { - HandleScope scope; - ThrowException(Exception::TypeError( - String::New("Not implemented"))); - return scope.Close(Undefined()); -} - -// === WiringPI SPI === - -// Func : int wiringPiSPIGetFd(int channel) - -IMPLEMENT(wiringPiSPIGetFd) { - HandleScope scope; - int channel; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - channel = args[0]->Int32Value(); - - // CHECK: Allowed values - if (channel != 0 || channel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect channel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSPIGetFd(channel); - - return scope.Close(Int32::New(res)); -} - -// Func : wiringPiSPIDataRW(int channel, unsigned char* data, int len) - -IMPLEMENT(wiringPiSPIDataRW) { - HandleScope scope; - int channel; - unsigned char* data; - int len; - int res; - - //CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsString() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type."))); - return scope.Close(Undefined()); - } - - channel = args[0]->Int32Value(); - v8::String::AsciiValue dataString(args[1]->ToString()); - data = (unsigned char*)*dataString; - len = args[2]->Int32Value(); - - // CHECK: Allowed values - if (channel != 0 || channel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect channel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSPIDataRW(channel, data, len); - - return scope.Close(Int32::New(res)); -} - -// Func : int wiringPiSPISetup(int channel, int speed) - -IMPLEMENT(wiringPiSPISetup) { - HandleScope scope; - int channel; - int speed; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - channel = args[0]->Int32Value(); - speed = args[1]->Int32Value(); - - // CHECK: Allowed values - if (channel != 0 || channel != 1) { - ThrowException(Exception::TypeError( - String::New("Incorrect channel value. 0 or 1 expected."))); - return scope.Close(Undefined()); - } - - res = ::wiringPiSPISetup(channel, speed); - - return scope.Close(Int32::New(res)); -} - -// === WiringPi Serial === - -// Func : int serialOpen(const char* device, const int baud) - -IMPLEMENT(serialOpen) { - HandleScope scope; - const char* device; - int baud; - int res; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsString()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type."))); - return scope.Close(Undefined()); - } - - v8::String::AsciiValue deviceString(args[0]->ToString()); - device = *deviceString; - baud = args[1]->Int32Value(); - - res = ::serialOpen(device, baud); - - return scope.Close(Int32::New(res)); -} - -// Func : void serialClose(const int fd) - -IMPLEMENT(serialClose) { - HandleScope scope; - int fd; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - - ::serialClose(fd); - - return scope.Close(Undefined()); -} - -// Func : void serialFlush(const int fd); - -IMPLEMENT(serialFlush) { - HandleScope scope; - int fd; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - - ::serialFlush(fd); - - return scope.Close(Undefined()); -} - -// Func : void serialPutchar(const int fd, const unsigned char c) - -IMPLEMENT(serialPutchar) { - HandleScope scope; - int fd; - unsigned char c; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - c = (args[0]->Uint32Value() & 0xFF); - - ::serialPutchar(fd, c); - - return scope.Close(Undefined()); -} - -// Func : void serialPuts(const int fd, const char* s) - -IMPLEMENT(serialPuts) { - HandleScope scope; - int fd; - const char* s; - - //CHECK: Number of argument - if (args.Length() != 2) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsString()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - v8::String::AsciiValue sString(args[0]->ToString()); - s = *sString; - - ::serialPuts(fd, s); - - return scope.Close(Undefined()); -} - -// Func : void serialPrintf(const int fd, const char* message, ...) - -IMPLEMENT(serialPrintf) { - return serialPuts(args); -} - -// Func : int serialDataAvail(const int fd) - -IMPLEMENT(serialDataAvail) { - HandleScope scope; - int fd; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - - res = ::serialDataAvail(fd); - - return scope.Close(Int32::New(res)); -} - -// Func : int serialGetchar(const int fd) -// NOTE TO MYSELF : I don't understand why serialPutchar takes a unsigned char and on the other side -// serialGetchar returns a int ... serialGetchar should returns a unsigned char too. - -IMPLEMENT(serialGetchar) { - HandleScope scope; - int fd; - int res; - - //CHECK: Number of argument - if (args.Length() != 1) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - //CHECK: Argument types - if (!args[0]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - fd = args[0]->Int32Value(); - - res = ::serialGetchar(fd); - - return scope.Close(Int32::New(res)); -} - -// === WiringPi Shift === - -// Func : uint8_t shiftIn(uint8_t dPin, uint8_t cPin, uint8_t order) -// Description : This shifts an 8-bit data value in with the data appearing on the dPin and the clock being sent out on the cPin. -// Order is either LSBFIRST or MSBFIRST. -// The data is sampled after the cPin goes high. -// (So cPin high, sample data, cPin low, repeat for 8 bits) The 8-bit value is returned by the function. - -IMPLEMENT(shiftIn) { - HandleScope scope; - uint8_t dPin; - uint8_t cPin; - uint8_t order; - uint8_t res; - - // CHECK: Number of argument - if (args.Length() != 3) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - dPin = args[0]->Uint32Value(); - cPin = args[1]->Uint32Value(); - order = args[2]->Uint32Value(); - - // CHECK : Allowed values - if (order != LSBFIRST || order != MSBFIRST) { - ThrowException(Exception::TypeError( - String::New("Incorrect order value. LSBFIRT or MSBFIRST expected."))); - return scope.Close(Undefined()); - } - - res = ::shiftIn(dPin, cPin, order); - - return scope.Close(Uint32::New(res)); -} - -// Func : void shiftOut(uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; -// Description : The shifts an 8-bit data value val out with the data being sent out on dPin and the clock being sent out on the cPin. -// order is as above. -// Data is clocked out on the rising or falling edge – ie. dPin is set, then cPin is taken high then low – repeated for the 8 bits. - -IMPLEMENT(shiftOut) { - HandleScope scope; - uint8_t dPin; - uint8_t cPin; - uint8_t order; - uint8_t val; - - // CHECK: Number of argument - if (args.Length() != 4) { - ThrowException(Exception::TypeError( - String::New("Wrong number of arguments."))); - return scope.Close(Undefined()); - } - - // CHECK: Argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsNumber() || !args[3]->IsNumber()) { - ThrowException(Exception::TypeError( - String::New("Incorrect argument type. Number expected."))); - return scope.Close(Undefined()); - } - - dPin = args[0]->Uint32Value(); - cPin = args[1]->Uint32Value(); - order = args[2]->Uint32Value(); - val = args[3]->Uint32Value(); - - // CHECK : Allowed values - if (order != LSBFIRST || order != MSBFIRST) { - ThrowException(Exception::TypeError( - String::New("Incorrect order value. LSBFIRT or MSBFIRST expected."))); - return scope.Close(Undefined()); - } - - ::shiftOut(dPin, cPin, order, val); - - return scope.Close(Undefined()); -} - -void init(Handle target) { - // Setup - EXPORT(wiringPiSetup); - EXPORT(wiringPiSetupGpio); - EXPORT(wiringPiSetupSys); - EXPORT(wiringPiSetupPhys); - - // Core wiringPi functions - EXPORT(pinModeAlt); - EXPORT(pinMode); - EXPORT(pullUpDnControl); - EXPORT(digitalRead); - EXPORT(digitalWrite); - EXPORT(pwmWrite); - EXPORT(analogRead); - EXPORT(analogWrite); - EXPORT(pulseIn); - - EXPORT(delay); - EXPORT(delayMicroseconds); - EXPORT(millis); - EXPORT(micros); - - // PiFace specifics (Deprecated) - //EXPORT(wiringPiSetupPiFace); - //EXPORT(wiringPiSetupPiFaceForGpioProg); // Don't use this - for gpio program only - - // On-Board Rasberry Pi hardware specific stuff - EXPORT(piBoardRev); - EXPORT(piBoardId); - EXPORT(wpiPinToGpio); - EXPORT(physPinToGpio); - EXPORT(setPadDrive); - EXPORT(getAlt); - EXPORT(digitalWriteByte); - EXPORT(pwmSetMode); - EXPORT(pwmSetRange); - EXPORT(pwmSetClock); - EXPORT(gpioClockSet); - - // Extensions - EXPORT(drcSetupSerial); - EXPORT(max5322Setup); - EXPORT(max31855Setup); - EXPORT(mcp23s08Setup); - EXPORT(mcp23s17Setup); - EXPORT(mcp3002Setup); - EXPORT(mcp3004Setup); - EXPORT(mcp3422Setup); - EXPORT(mcp4802Setup); - EXPORT(mcp23008Setup); - EXPORT(mcp23016Setup); - EXPORT(mcp23017Setup); - EXPORT(pcf8574Setup); - EXPORT(pcf8591Setup); - EXPORT(sn3218Setup); - EXPORT(sr595Setup); - EXPORT(pca9685Setup); - - // Soft PWM - EXPORT(softPwmCreate); - EXPORT(softPwmWrite); - EXPORT(softPwmStop); - - // Soft Servo - EXPORT(softServoWrite); - EXPORT(softServoSetup); - - // Soft Tone - EXPORT(softToneCreate); - EXPORT(softToneWrite); - EXPORT(softToneStop); - - // WiringPI I2C - EXPORT(wiringPiI2CRead); - EXPORT(wiringPiI2CReadReg8); - EXPORT(wiringPiI2CReadReg16); - EXPORT(wiringPiI2CWrite); - EXPORT(wiringPiI2CWriteReg8); - EXPORT(wiringPiI2CWriteReg16); - EXPORT(wiringPiI2CSetupInterface); - EXPORT(wiringPiI2CSetup); - - // WiringPI SPI - EXPORT(wiringPiSPIGetFd); - EXPORT(wiringPiSPIDataRW); - EXPORT(wiringPiSPISetup); - - // WiringPi Serial - EXPORT(serialOpen); - EXPORT(serialClose); - EXPORT(serialFlush); - EXPORT(serialPutchar); - EXPORT(serialPuts); - EXPORT(serialPrintf); - EXPORT(serialDataAvail); - EXPORT(serialGetchar); - - // WiringPi Shift - EXPORT(shiftIn); - EXPORT(shiftOut); -} - -NODE_MODULE(wiringPi, init) \ No newline at end of file diff --git a/src/softPwm.cc b/src/softPwm.cc new file mode 100644 index 0000000..c602caf --- /dev/null +++ b/src/softPwm.cc @@ -0,0 +1,87 @@ +#include "softPwm.h" +#include +#include + +DECLARE(softPwmCreate); +DECLARE(softPwmWrite); +DECLARE(softPwmStop); + +// Func : int softPwmCreate(int pin, int value, int range) +// Description : This creates a software controlled PWM pin. +// You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. +// Use 100 for the pwmRange, then the value can be anything from 0 (off) to 100 (fully on) for the given pin. +// The return value is 0 for success. Anything else and you should check the global errno variable to see what went wrong. +// NOTE : You must initialise wiringPi with one of wiringPiSetup(), wiringPiSetupGpio() or wiringPiSetupPhys() functions. +// wiringPiSetupSys() is not fast enough, so you must run your programs with sudo. +// NOTE2 : Each “cycle” of PWM output takes 10mS with the default range value of 100, +// so trying to change the PWM value more than 100 times a second will be futile. +// NOTE3 : Each pin activated in softPWM mode uses approximately 0.5% of the CPU. +// NOTE4 : There is currently no way to disable softPWM on a pin while the program in running. +// NOTE5 : You need to keep your program running to maintain the PWM output! + +IMPLEMENT(softPwmCreate) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + SET_ARGUMENT_NAME(2, range); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + int range = GET_ARGUMENT_AS_INT32(2); + + int res = ::softPwmCreate(pin, value, range); + + SCOPE_CLOSE(INT32(res)); +} + +// Func void softPwmWrite(int pin, int value) +// Description : This updates the PWM value on the given pin. +// The value is checked to be in-range and pins that haven’t previously been initialised via softPwmCreate will be silently ignored. + +IMPLEMENT(softPwmWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::softPwmWrite(pin, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(softPwmStop) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + + ::softPwmStop(pin); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(softPwm) { + EXPORT_FUNCTION(softPwmCreate); + EXPORT_FUNCTION(softPwmWrite); + EXPORT_FUNCTION(softPwmStop); +} \ No newline at end of file diff --git a/src/softPwm.h b/src/softPwm.h new file mode 100644 index 0000000..33db755 --- /dev/null +++ b/src/softPwm.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SOFT_PWM_H_ +#define _WPI_SOFT_PWM_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(softPwm); + +#endif \ No newline at end of file diff --git a/src/softServo.cc b/src/softServo.cc new file mode 100644 index 0000000..60bdc5a --- /dev/null +++ b/src/softServo.cc @@ -0,0 +1,73 @@ +#include "softServo.h" +#include +#include + +DECLARE(softServoWrite); +DECLARE(softServoSetup); + +// Func : void softServoWrite(int pin, int value) +// Description : Write a Servo value to the given pin + +IMPLEMENT(softServoWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::softServoWrite(pin, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : int softServoSetup(int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) +// Description : Setup the software servo system + +IMPLEMENT(softServoSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, p0); + SET_ARGUMENT_NAME(1, p1); + SET_ARGUMENT_NAME(2, p2); + SET_ARGUMENT_NAME(3, p3); + SET_ARGUMENT_NAME(4, p4); + SET_ARGUMENT_NAME(5, p5); + SET_ARGUMENT_NAME(6, p6); + SET_ARGUMENT_NAME(7, p7); + + CHECK_ARGUMENTS_LENGTH_EQUAL(8); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + CHECK_ARGUMENT_TYPE_INT32(5); + CHECK_ARGUMENT_TYPE_INT32(6); + CHECK_ARGUMENT_TYPE_INT32(7); + + int p0 = GET_ARGUMENT_AS_INT32(0); + int p1 = GET_ARGUMENT_AS_INT32(1); + int p2 = GET_ARGUMENT_AS_INT32(2); + int p3 = GET_ARGUMENT_AS_INT32(3); + int p4 = GET_ARGUMENT_AS_INT32(4); + int p5 = GET_ARGUMENT_AS_INT32(5); + int p6 = GET_ARGUMENT_AS_INT32(6); + int p7 = GET_ARGUMENT_AS_INT32(7); + + int res = ::softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(softServo) { + EXPORT_FUNCTION(softServoWrite); + EXPORT_FUNCTION(softServoSetup); +} \ No newline at end of file diff --git a/src/softServo.h b/src/softServo.h new file mode 100644 index 0000000..f079730 --- /dev/null +++ b/src/softServo.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SOFT_SERVO_H_ +#define _WPI_SOFT_SERVO_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(softServo); + +#endif \ No newline at end of file diff --git a/src/softTone.cc b/src/softTone.cc new file mode 100644 index 0000000..48ab5b9 --- /dev/null +++ b/src/softTone.cc @@ -0,0 +1,77 @@ +#include "softTone.h" +#include +#include + +DECLARE(softToneCreate); +DECLARE(softToneWrite); +DECLARE(softToneStop); + +// Func : int softToneCreate(int pin); +// Description : This creates a software controlled tone pin. +// You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. +// The return value is 0 for success. +// Anything else and you should check the global errno variable to see what went wrong. +// NOTE : You must initialise wiringPi with one of wiringPiSetup(), wiringPiSetupGpio() or wiringPiSetupPhys() functions. +// wiringPiSetupSys() is not fast enough, so you must run your programs with sudo. +// NOTE2 : Each pin activated in softTone mode uses approximately 0.5% of the CPU. +// NOTE3 : You need to keep your program running to maintain the sound output! + +IMPLEMENT(softToneCreate) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + + int res = ::softToneCreate(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void softToneWrite(int pin, int freq); +// Description : This updates the tone frequency value on the given pin. The tone will be played until you set the frequency to 0. + +IMPLEMENT(softToneWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, frequency); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int frequency = GET_ARGUMENT_AS_INT32(1); + + ::softToneWrite(pin, frequency); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(softToneStop) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + + ::softToneStop(pin); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(softTone) { + EXPORT_FUNCTION(softToneCreate); + EXPORT_FUNCTION(softToneWrite); + EXPORT_FUNCTION(softToneStop); +} \ No newline at end of file diff --git a/src/softTone.h b/src/softTone.h new file mode 100644 index 0000000..a96682f --- /dev/null +++ b/src/softTone.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SOFT_TONE_H_ +#define _WPI_SOFT_TONE_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(softTone); + +#endif \ No newline at end of file diff --git a/src/wiringPi.cc b/src/wiringPi.cc new file mode 100644 index 0000000..2860d54 --- /dev/null +++ b/src/wiringPi.cc @@ -0,0 +1,709 @@ +#include "wiringPi.h" +#include + +// Setup +DECLARE(setup); +DECLARE(wiringPiSetup); +DECLARE(wiringPiSetupGpio); +DECLARE(wiringPiSetupSys); +DECLARE(wiringPiSetupPhys); + +// Core functions +DECLARE(pinModeAlt); +DECLARE(pinMode); +DECLARE(pullUpDnControl); +DECLARE(digitalRead); +DECLARE(digitalWrite); +DECLARE(pwmWrite); +DECLARE(analogRead); +DECLARE(analogWrite); +DECLARE(pulseIn); + +DECLARE(delay); +DECLARE(delayMicroseconds); +DECLARE(millis); +DECLARE(micros); + +// On-Board Rasberry Pi hardware specific stuff +DECLARE(piBoardRev); +DECLARE(piBoardId); +DECLARE(wpiPinToGpio); +DECLARE(physPinToGpio); +DECLARE(setPadDrive); +DECLARE(getAlt); +DECLARE(digitalWriteByte); +DECLARE(pwmSetMode); +DECLARE(pwmSetRange); +DECLARE(pwmSetClock); +DECLARE(gpioClockSet); + +IMPLEMENT(setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, mode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_STRING(0); + + String::AsciiValue mode(GET_ARGUMENT_AS_STRING(0)); + + CHECK_ARGUMENT_IN_STRINGS(0, mode, ("wpi", "gpio", "sys", "phys")); + + int res = 0; + if (!strcasecmp(*mode, "wpi")) { + res = ::wiringPiSetup(); + } + else if (!strcasecmp(*mode, "gpio")) { + res = ::wiringPiSetupGpio(); + } + else if (!strcasecmp(*mode, "sys")) { + res = ::wiringPiSetupSys(); + } + else if (!strcasecmp(*mode, "phys")) { + res = ::wiringPiSetupPhys(); + } + + // libWiringPi v2 setup functions always returns 0, so this check is kind of useless, unless v1 behaviour is restored + // NOTE: If you want to restore the v1 behaviour, then you need to set the + // environment variable: WIRINGPI_CODES (to any value, it just needs to exist) + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSetup(void) +// Returns : error code if v1 mode otherwise always returns 0 +// Description : Initialises wiringPi and assumes that the calling program is going +// to be using the wiringPi pin numbering scheme. +// This is a simplified numbering scheme which provides a mapping from virtual +// pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. +// see the pins page (https://projects.drogon.net/raspberry-pi/wiringpi/pins/) for a table +// which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location +// on the edge connector. +// This function needs to be called with root privileges. + +IMPLEMENT(wiringPiSetup) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::wiringPiSetup(); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSetupGpio(void) +// Returns : error code if v1 mode otherwise always returns 0 +// Description : This is indential to above, however it allows the calling programs to use +// the Broadcom GPIO pin numbers directly with no re-mapping. +// As above, this function needs to be called with root privileges, and note that some pins +// are different from revision 1 to revision 2 boards. + +IMPLEMENT(wiringPiSetupGpio) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::wiringPiSetupGpio(); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSetupSys(void) +// Returns : error code if v1 mode otherwise always returns 0 +// Description : This initialises wiringPi but uses the /sys/class/gpio interface rather than +// accessing the hardware directly. This can be called as a non-root user provided the GPIO pins +// have been exported before-hand using gpio program. Pin numbering in this mode is the native +// Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences +// between Rev 1 and Rev 2 boards. +// Note: In this mode you can only use the pins which have been exported via the +// /sys/class/gpio interface before you run your program. You can do this in a seperate +// shell script, or by using the system() function from inside your program to call the gpio program. +// Also note that some functions have no effect when using this mode as they're not currently +// possible to action unless called with root privileges. (although you can use system() to call +// gpio to set/change modes if needed). + +IMPLEMENT(wiringPiSetupSys) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::wiringPiSetupSys(); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSetupPhys(void) +// Returns : error code if v1 mode otherwise always returns 0 +// Description : Identical to above, however it allows the calling programs to use +// the physical pin numbers on the P1 connector only. +// As above, this function needs to be called with root priviliges. + +IMPLEMENT(wiringPiSetupPhys) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::wiringPiSetupPhys(); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void pinModeAlt(int pin, int mode) +// Description : This is an un-documented special to let you set any pin to any mode. +// Modes are WPI_MODE_PINS, WPI_MODE_PHYS, WPI_MODE_GPIO. + +IMPLEMENT(pinModeAlt) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, mode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int mode = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, mode, (WPI_MODE_PINS, WPI_MODE_PHYS, WPI_MODE_GPIO)); + + ::pinModeAlt(pin, mode); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pinMode(int pin, int mode) +// Description : This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. +// Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) +// supports CLOCK output modes. +// This function has no effect when in Sys mode. If you need to change the pin mode, the you can +// do it with the gpio program in a script before you start your program. + +IMPLEMENT(pinMode) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, mode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int mode = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, mode, (INPUT, OUTPUT, PWM_OUTPUT, GPIO_CLOCK, SOFT_PWM_OUTPUT, SOFT_TONE_OUTPUT)); + + ::pinMode(pin, mode); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pullUpDnControl(int pin, int pud) +// Description : This sets the pull-up or pull-down resistor mode on the given pin, which should be set +// as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. +// The parameter pud should be; PUD_OFF (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP (pull to 3.3v). +// The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. + +IMPLEMENT(pullUpDnControl) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, pud); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int pud = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, pud, (PUD_OFF, PUD_DOWN, PUD_UP)); + + ::pullUpDnControl(pin, pud); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : int digitalRead(int pin) +// Description : This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) +// depending on the logic level at the pin. + +IMPLEMENT(digitalRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::digitalRead(pin); + + // Make sure the function returns strictly 1 or 0 + // §4.7/4 from the C++ Standard says (Integral Conversion) + // If the source type is bool, the value false is converted to zero and the value true is converted to one. + res = (res != 0); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void digitalWrite(int pin, int value) +// Description : Write the value HIGH or LOW (1 or 0) to the given pin which must have been +// previously set as an output. +// WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW. + +IMPLEMENT(digitalWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, state, (HIGH, LOW)); + + ::digitalWrite(pin, state); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pwmWrite(int pin, int value) +// Description : Writes the value to the PWM register for the given pin. The Raspberry Pi has +// one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is 0-1024. Other PWM +// devices may have other PWM ranges. +// This function is not able to control the Pi's on-board PWM when in Sys mode. + +IMPLEMENT(pwmWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::pwmWrite(pin, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(analogRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::analogRead(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void analogWrite(int pin, int value) +// Description : This writes the given value to the supplied analog pin. You will need to register +// additional analog modules to enable this function for devices such as the Gertboard. + +IMPLEMENT(analogWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::analogWrite(pin, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(pulseIn) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, state, (HIGH, LOW)); + + int us = ::pulseIn(pin, state); + + SCOPE_CLOSE(INT32(us)); +} + +IMPLEMENT(delay) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, ms); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int ms = GET_ARGUMENT_AS_INT32(0); + + ::delay(ms); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(delayMicroseconds) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, us); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int us = GET_ARGUMENT_AS_INT32(0); + + ::delayMicroseconds(us); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(millis) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + unsigned int ms = ::millis(); + + SCOPE_CLOSE(UINT32(ms)); +} + +IMPLEMENT(micros) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + unsigned int us = ::micros(); + + SCOPE_CLOSE(UINT32(us)); +} + +// === Raspberry Pi specific === + +// Func : int piBoardRev(void) +// Description : This returns the board revision of the Raspberry Pi. It will be either 1 or 2. +// Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, +// so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. + +IMPLEMENT(piBoardRev) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::piBoardRev(); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT(piBoardId) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int model, rev, mem; + char* marker; + + ::piBoardId(&model, &rev, &mem, &marker); + + Local obj = Object::New(); + obj->Set(String::NewSymbol("model"), INT32(model)); + obj->Set(String::NewSymbol("rev"), INT32(rev)); + obj->Set(String::NewSymbol("mem"), INT32(mem)); + obj->Set(String::NewSymbol("marker"), String::New(marker)); + + SCOPE_CLOSE(obj); +} + +// Func : int wpiPinToGpio(int wpiPin) +// Description : This returns the BCM_GPIO pin number of the supplied wiringPi pin. +// It takes the board revision into account. + +IMPLEMENT(wpiPinToGpio) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::wpiPinToGpio(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int physPinToGpio (int physPin) +// Description : This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector. + +IMPLEMENT(physPinToGpio) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::physPinToGpio(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void setPadDrive(int group, int value) +// Description : This sets the "strength" of the pad drivers for a particular group of pins. +// There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you +// know what you are doing. + +IMPLEMENT(setPadDrive) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, group); + SET_ARGUMENT_NAME(1, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int group = GET_ARGUMENT_AS_INT32(0); + int value = GET_ARGUMENT_AS_INT32(1); + + ::setPadDrive(group, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : int getAlt(int pin) +// Description : Returns the ALT bits for a given port. Only really of-use +// for the gpio readall command (I think). + +IMPLEMENT(getAlt) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + int res = ::getAlt(pin); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void digitalWriteByte(int value) +// Description : This writes the 8-bit byte supplied to the first 8 GPIO pins. +// It’s the fastest way to set all 8 bits at once to a particular value, although it still takes +// two write operations to the Pi’s GPIO hardware. + +IMPLEMENT(digitalWriteByte) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, byte); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int byte = GET_ARGUMENT_AS_INT32(0); + ::digitalWriteByte(byte); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pwmSetMode(int mode) +// Description : The PWM generator can run in 2 modes – “balanced” and “mark:space”. +// The mark:space mode is traditional, however the default mode in the Pi is “balanced”. +// You can switch modes by supplying the parameter: PWM_MODE_BAL or PWM_MODE_MS. + +IMPLEMENT(pwmSetMode) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, mode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int mode = GET_ARGUMENT_AS_INT32(0); + + CHECK_ARGUMENT_IN_INTS(0, mode, (PWM_MODE_BAL, PWM_MODE_MS)); + + ::pwmSetMode(mode); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pwmSetRange(unsigned int range) +// Description : This sets the range register in the PWM generator. The default is 1024. +// Note: The PWM control functions can not be used when in Sys mode. To understand more about +// the PWM system, you’ll need to read the Broadcom ARM peripherals manual. + +IMPLEMENT(pwmSetRange) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, range); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_UINT32(0); + + unsigned int range = GET_ARGUMENT_AS_UINT32(0); + ::pwmSetRange(range); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void pwmSetClock(int divisor) +// Description : This sets the divisor for the PWM clock. +// Note: The PWM control functions can not be used when in Sys mode. To understand more about +// the PWM system, you’ll need to read the Broadcom ARM peripherals manual. + +IMPLEMENT(pwmSetClock) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, divisor); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int divisor = GET_ARGUMENT_AS_INT32(0); + ::pwmSetClock(divisor); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void gpioClockSet(int pin, int freq) +// Description : Set the frequency on a GPIO clock pin + +IMPLEMENT(gpioClockSet) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, frequency); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int frequency = GET_ARGUMENT_AS_INT32(1); + + ::gpioClockSet(pin, frequency); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(wiringPi) { + // Setup + EXPORT_FUNCTION(setup); + EXPORT_FUNCTION(wiringPiSetup); + EXPORT_FUNCTION(wiringPiSetupGpio); + EXPORT_FUNCTION(wiringPiSetupSys); + EXPORT_FUNCTION(wiringPiSetupPhys); + + // Core functions + EXPORT_FUNCTION(pinModeAlt); + EXPORT_FUNCTION(pinMode); + EXPORT_FUNCTION(pullUpDnControl); + EXPORT_FUNCTION(digitalRead); + EXPORT_FUNCTION(digitalWrite); + EXPORT_FUNCTION(pwmWrite); + EXPORT_FUNCTION(analogRead); + EXPORT_FUNCTION(analogWrite); + EXPORT_FUNCTION(pulseIn); + + EXPORT_FUNCTION(delay); + EXPORT_FUNCTION(delayMicroseconds); + EXPORT_FUNCTION(millis); + EXPORT_FUNCTION(micros); + + // On-Board Rasberry Pi hardware specific stuff + EXPORT_FUNCTION(piBoardRev); + EXPORT_FUNCTION(piBoardId); + EXPORT_FUNCTION(wpiPinToGpio); + EXPORT_FUNCTION(physPinToGpio); + EXPORT_FUNCTION(setPadDrive); + EXPORT_FUNCTION(getAlt); + EXPORT_FUNCTION(digitalWriteByte); + EXPORT_FUNCTION(pwmSetMode); + EXPORT_FUNCTION(pwmSetRange); + EXPORT_FUNCTION(pwmSetClock); + EXPORT_FUNCTION(gpioClockSet); + + // pinModeAlt + EXPORT_CONSTANT_INT(WPI_MODE_PINS); + EXPORT_CONSTANT_INT(WPI_MODE_PHYS); + EXPORT_CONSTANT_INT(WPI_MODE_GPIO); + + // pinMode + EXPORT_CONSTANT_INT(INPUT); + EXPORT_CONSTANT_INT(OUTPUT); + EXPORT_CONSTANT_INT(PWM_OUTPUT); + EXPORT_CONSTANT_INT(GPIO_CLOCK); + EXPORT_CONSTANT_INT(SOFT_PWM_OUTPUT); + EXPORT_CONSTANT_INT(SOFT_TONE_OUTPUT); + + // pullUpDnControl + EXPORT_CONSTANT_INT(PUD_OFF); + EXPORT_CONSTANT_INT(PUD_DOWN); + EXPORT_CONSTANT_INT(PUD_UP); + + // digitalRead/Write + EXPORT_CONSTANT_INT(HIGH); + EXPORT_CONSTANT_INT(LOW); + + // pwmSetMode + EXPORT_CONSTANT_INT(PWM_MODE_BAL); + EXPORT_CONSTANT_INT(PWM_MODE_MS); + + EXPORT_CONSTANT_INT(PI_MODEL_A); + EXPORT_CONSTANT_INT(PI_MODEL_B); + EXPORT_CONSTANT_INT(PI_MODEL_CM); + + /*EXPORT_CONSTANT_STRING_ARRAY(PI_MODEL_NAMES, piModelNames, 3); + EXPORT_CONSTANT_STRING_ARRAY(PI_REVISION_NAMES, piRevisionNames, 3); + EXPORT_CONSTANT_STRING_ARRAY(PI_COMPUTE_REVISION_NAMES, piComputeRevisionNames, 0);*/ +} + diff --git a/src/wiringPi.h b/src/wiringPi.h new file mode 100644 index 0000000..f6cde55 --- /dev/null +++ b/src/wiringPi.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_PI_H_ +#define _WPI_WIRING_PI_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringPi); + +#endif \ No newline at end of file diff --git a/src/wiringPiI2C.cc b/src/wiringPiI2C.cc new file mode 100644 index 0000000..e5e5481 --- /dev/null +++ b/src/wiringPiI2C.cc @@ -0,0 +1,197 @@ +#include "wiringPiI2C.h" +#include +#include + +DECLARE(wiringPiI2CRead); +DECLARE(wiringPiI2CReadReg8); +DECLARE(wiringPiI2CReadReg16); +DECLARE(wiringPiI2CWrite); +DECLARE(wiringPiI2CWriteReg8); +DECLARE(wiringPiI2CWriteReg16); +DECLARE(wiringPiI2CSetupInterface); +DECLARE(wiringPiI2CSetup); + +// Func : int wiringPiI2CRead (int fd); +// Simple device read. Some devices present data when you read them without having to do any register transactions. + +IMPLEMENT(wiringPiI2CRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + int res = ::wiringPiI2CRead(fd); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CRead (int fd, int reg); +// read an 8-bits value from the device register indicated. + +IMPLEMENT(wiringPiI2CReadReg8) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, reg); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int reg = GET_ARGUMENT_AS_INT32(1); + + int res = ::wiringPiI2CReadReg8(fd, reg); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CRead (int fd, int reg) +// read a 16-bits value from the device register indicated. + +IMPLEMENT(wiringPiI2CReadReg16) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, reg); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int reg = GET_ARGUMENT_AS_INT32(1); + + int res = ::wiringPiI2CReadReg16(fd, reg); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CWrite (int fd, int data) +// Simple device write. Some devices accept data this way without needing to access any internal registers. + +IMPLEMENT(wiringPiI2CWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int data = GET_ARGUMENT_AS_INT32(1); + data = data & 0xFF; + + int res = ::wiringPiI2CWrite(fd, data); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CWriteReg8 (int fd, int reg, int data) +// write an 8-bit data value into the device register indicated. + +IMPLEMENT(wiringPiI2CWriteReg8) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, reg); + SET_ARGUMENT_NAME(2, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int fd = GET_ARGUMENT_AS_INT32(0); + int reg = GET_ARGUMENT_AS_INT32(1); + int data = GET_ARGUMENT_AS_INT32(2); + data = data & 0xFF; + + int res = ::wiringPiI2CWriteReg8(fd, reg, data); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT(wiringPiI2CWriteReg16) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, reg); + SET_ARGUMENT_NAME(2, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int fd = GET_ARGUMENT_AS_INT32(0); + int reg = GET_ARGUMENT_AS_INT32(1); + int data = GET_ARGUMENT_AS_INT32(2); + data = data & 0xFFFF; + + int res = ::wiringPiI2CWriteReg16(fd, reg, data); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiI2CSetupInterface (const char *device, int devId) + +IMPLEMENT(wiringPiI2CSetupInterface) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, device); + SET_ARGUMENT_NAME(1, devId); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_STRING(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + String::AsciiValue device(GET_ARGUMENT_AS_STRING(0)); + int devId = GET_ARGUMENT_AS_INT32(1); + + int res = ::wiringPiI2CSetupInterface(*device, devId); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wirintPiI2CSetup (int devId) + +IMPLEMENT(wiringPiI2CSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, devId); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int devId = GET_ARGUMENT_AS_INT32(0); + + int res = ::wiringPiI2CSetup(devId); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(wiringPiI2C) { + EXPORT_FUNCTION(wiringPiI2CRead); + EXPORT_FUNCTION(wiringPiI2CReadReg8); + EXPORT_FUNCTION(wiringPiI2CReadReg16); + EXPORT_FUNCTION(wiringPiI2CWrite); + EXPORT_FUNCTION(wiringPiI2CWriteReg8); + EXPORT_FUNCTION(wiringPiI2CWriteReg16); + EXPORT_FUNCTION(wiringPiI2CSetupInterface); + EXPORT_FUNCTION(wiringPiI2CSetup); +} diff --git a/src/wiringPiI2C.h b/src/wiringPiI2C.h new file mode 100644 index 0000000..27fbe9d --- /dev/null +++ b/src/wiringPiI2C.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_PI_I2C_H_ +#define _WPI_WIRING_PI_I2C_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringPiI2C); + +#endif \ No newline at end of file diff --git a/src/wiringPiISR.cc b/src/wiringPiISR.cc new file mode 100644 index 0000000..12bad63 --- /dev/null +++ b/src/wiringPiISR.cc @@ -0,0 +1,227 @@ +#include "wiringPiISR.h" +#include +#include +#include + +using namespace v8; + +typedef struct js_work_t { + uv_work_t req; + int pin; + unsigned int delta; +} js_work_t; + +typedef void (*NATIVE_INTERRUPT_HANDLER_T)(void); + +static NATIVE_INTERRUPT_HANDLER_T nativeInterruptHandlers[64]; +static unsigned long int lastInterruptMicroseconds[64]; +static std::map > interruptCallbackMapping; + +#define DEFINE_NATIVE_INTERRUPT_HANDLER(pin) \ + static void nativeInterruptHandler##pin(void) { \ + processNativeInterrupt(pin); \ + } + +#define REGISTER_NATIVE_INTERRUPT_HANDLER(pin) nativeInterruptHandlers[pin] = &nativeInterruptHandler##pin + +#define GET_NATIVE_INTERRUPT_HANDLER(pin) nativeInterruptHandlers[pin] + +static void processInterrupt(uv_work_t* req, int status) { + js_work_t* work = static_cast(req->data); + + Persistent callback = interruptCallbackMapping[work->pin]; + + Local argv[] = { + Local::New(Int32::New(work->pin)), + Local::New(Uint32::New(work->delta)) + }; + + callback->Call(Context::GetCurrent()->Global(), 2, argv); + + delete work; +} + +static void UV_NOP(uv_work_t*) {} + +void processNativeInterrupt(int pin) { + unsigned int now = ::micros(); + + js_work_t* work = new js_work_t; + work->req.data = work; + work->pin = pin; + work->delta = now - lastInterruptMicroseconds[pin]; + + int r = uv_queue_work(uv_default_loop(), &work->req, &UV_NOP, &processInterrupt); + if (r != 0) { + delete work; + } + + lastInterruptMicroseconds[pin] = now; +} + +DEFINE_NATIVE_INTERRUPT_HANDLER(0); +DEFINE_NATIVE_INTERRUPT_HANDLER(1); +DEFINE_NATIVE_INTERRUPT_HANDLER(2); +DEFINE_NATIVE_INTERRUPT_HANDLER(3); +DEFINE_NATIVE_INTERRUPT_HANDLER(4); +DEFINE_NATIVE_INTERRUPT_HANDLER(5); +DEFINE_NATIVE_INTERRUPT_HANDLER(6); +DEFINE_NATIVE_INTERRUPT_HANDLER(7); +DEFINE_NATIVE_INTERRUPT_HANDLER(8); +DEFINE_NATIVE_INTERRUPT_HANDLER(9); +DEFINE_NATIVE_INTERRUPT_HANDLER(10); +DEFINE_NATIVE_INTERRUPT_HANDLER(11); +DEFINE_NATIVE_INTERRUPT_HANDLER(12); +DEFINE_NATIVE_INTERRUPT_HANDLER(13); +DEFINE_NATIVE_INTERRUPT_HANDLER(14); +DEFINE_NATIVE_INTERRUPT_HANDLER(15); +DEFINE_NATIVE_INTERRUPT_HANDLER(16); +DEFINE_NATIVE_INTERRUPT_HANDLER(17); +DEFINE_NATIVE_INTERRUPT_HANDLER(18); +DEFINE_NATIVE_INTERRUPT_HANDLER(19); +DEFINE_NATIVE_INTERRUPT_HANDLER(20); +DEFINE_NATIVE_INTERRUPT_HANDLER(21); +DEFINE_NATIVE_INTERRUPT_HANDLER(22); +DEFINE_NATIVE_INTERRUPT_HANDLER(23); +DEFINE_NATIVE_INTERRUPT_HANDLER(24); +DEFINE_NATIVE_INTERRUPT_HANDLER(25); +DEFINE_NATIVE_INTERRUPT_HANDLER(26); +DEFINE_NATIVE_INTERRUPT_HANDLER(27); +DEFINE_NATIVE_INTERRUPT_HANDLER(28); +DEFINE_NATIVE_INTERRUPT_HANDLER(29); +DEFINE_NATIVE_INTERRUPT_HANDLER(30); +DEFINE_NATIVE_INTERRUPT_HANDLER(31); +DEFINE_NATIVE_INTERRUPT_HANDLER(32); +DEFINE_NATIVE_INTERRUPT_HANDLER(33); +DEFINE_NATIVE_INTERRUPT_HANDLER(34); +DEFINE_NATIVE_INTERRUPT_HANDLER(35); +DEFINE_NATIVE_INTERRUPT_HANDLER(36); +DEFINE_NATIVE_INTERRUPT_HANDLER(37); +DEFINE_NATIVE_INTERRUPT_HANDLER(38); +DEFINE_NATIVE_INTERRUPT_HANDLER(39); +DEFINE_NATIVE_INTERRUPT_HANDLER(40); +DEFINE_NATIVE_INTERRUPT_HANDLER(41); +DEFINE_NATIVE_INTERRUPT_HANDLER(42); +DEFINE_NATIVE_INTERRUPT_HANDLER(43); +DEFINE_NATIVE_INTERRUPT_HANDLER(44); +DEFINE_NATIVE_INTERRUPT_HANDLER(45); +DEFINE_NATIVE_INTERRUPT_HANDLER(46); +DEFINE_NATIVE_INTERRUPT_HANDLER(47); +DEFINE_NATIVE_INTERRUPT_HANDLER(48); +DEFINE_NATIVE_INTERRUPT_HANDLER(49); +DEFINE_NATIVE_INTERRUPT_HANDLER(50); +DEFINE_NATIVE_INTERRUPT_HANDLER(51); +DEFINE_NATIVE_INTERRUPT_HANDLER(52); +DEFINE_NATIVE_INTERRUPT_HANDLER(53); +DEFINE_NATIVE_INTERRUPT_HANDLER(54); +DEFINE_NATIVE_INTERRUPT_HANDLER(55); +DEFINE_NATIVE_INTERRUPT_HANDLER(56); +DEFINE_NATIVE_INTERRUPT_HANDLER(57); +DEFINE_NATIVE_INTERRUPT_HANDLER(58); +DEFINE_NATIVE_INTERRUPT_HANDLER(59); +DEFINE_NATIVE_INTERRUPT_HANDLER(60); +DEFINE_NATIVE_INTERRUPT_HANDLER(61); +DEFINE_NATIVE_INTERRUPT_HANDLER(62); +DEFINE_NATIVE_INTERRUPT_HANDLER(63); + +DECLARE(wiringPiISR); +IMPLEMENT(wiringPiISR) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, edgeType); + SET_ARGUMENT_NAME(2, callback); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_FUNCTION(2); + + int pin = GET_ARGUMENT_AS_INT32(0); + int edgeType = GET_ARGUMENT_AS_INT32(1); + Persistent callback = GET_ARGUMENT_AS_PERSISTENT_FUNCTION(2); + + CHECK_ARGUMENT_IN_INTS(1, edgeType, (INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH, INT_EDGE_SETUP)); + + interruptCallbackMapping.insert(std::pair >(pin, callback)); + lastInterruptMicroseconds[pin] = ::micros(); + + ::wiringPiISR(pin, edgeType, GET_NATIVE_INTERRUPT_HANDLER(pin)); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(wiringPiISR) { + REGISTER_NATIVE_INTERRUPT_HANDLER(0); + REGISTER_NATIVE_INTERRUPT_HANDLER(1); + REGISTER_NATIVE_INTERRUPT_HANDLER(2); + REGISTER_NATIVE_INTERRUPT_HANDLER(3); + REGISTER_NATIVE_INTERRUPT_HANDLER(4); + REGISTER_NATIVE_INTERRUPT_HANDLER(5); + REGISTER_NATIVE_INTERRUPT_HANDLER(6); + REGISTER_NATIVE_INTERRUPT_HANDLER(7); + REGISTER_NATIVE_INTERRUPT_HANDLER(8); + REGISTER_NATIVE_INTERRUPT_HANDLER(9); + REGISTER_NATIVE_INTERRUPT_HANDLER(10); + REGISTER_NATIVE_INTERRUPT_HANDLER(11); + REGISTER_NATIVE_INTERRUPT_HANDLER(12); + REGISTER_NATIVE_INTERRUPT_HANDLER(13); + REGISTER_NATIVE_INTERRUPT_HANDLER(14); + REGISTER_NATIVE_INTERRUPT_HANDLER(15); + REGISTER_NATIVE_INTERRUPT_HANDLER(16); + REGISTER_NATIVE_INTERRUPT_HANDLER(17); + REGISTER_NATIVE_INTERRUPT_HANDLER(18); + REGISTER_NATIVE_INTERRUPT_HANDLER(19); + REGISTER_NATIVE_INTERRUPT_HANDLER(20); + REGISTER_NATIVE_INTERRUPT_HANDLER(21); + REGISTER_NATIVE_INTERRUPT_HANDLER(22); + REGISTER_NATIVE_INTERRUPT_HANDLER(23); + REGISTER_NATIVE_INTERRUPT_HANDLER(24); + REGISTER_NATIVE_INTERRUPT_HANDLER(25); + REGISTER_NATIVE_INTERRUPT_HANDLER(26); + REGISTER_NATIVE_INTERRUPT_HANDLER(27); + REGISTER_NATIVE_INTERRUPT_HANDLER(28); + REGISTER_NATIVE_INTERRUPT_HANDLER(29); + REGISTER_NATIVE_INTERRUPT_HANDLER(30); + REGISTER_NATIVE_INTERRUPT_HANDLER(31); + REGISTER_NATIVE_INTERRUPT_HANDLER(32); + REGISTER_NATIVE_INTERRUPT_HANDLER(33); + REGISTER_NATIVE_INTERRUPT_HANDLER(34); + REGISTER_NATIVE_INTERRUPT_HANDLER(35); + REGISTER_NATIVE_INTERRUPT_HANDLER(36); + REGISTER_NATIVE_INTERRUPT_HANDLER(37); + REGISTER_NATIVE_INTERRUPT_HANDLER(38); + REGISTER_NATIVE_INTERRUPT_HANDLER(39); + REGISTER_NATIVE_INTERRUPT_HANDLER(40); + REGISTER_NATIVE_INTERRUPT_HANDLER(41); + REGISTER_NATIVE_INTERRUPT_HANDLER(42); + REGISTER_NATIVE_INTERRUPT_HANDLER(43); + REGISTER_NATIVE_INTERRUPT_HANDLER(44); + REGISTER_NATIVE_INTERRUPT_HANDLER(45); + REGISTER_NATIVE_INTERRUPT_HANDLER(46); + REGISTER_NATIVE_INTERRUPT_HANDLER(47); + REGISTER_NATIVE_INTERRUPT_HANDLER(48); + REGISTER_NATIVE_INTERRUPT_HANDLER(49); + REGISTER_NATIVE_INTERRUPT_HANDLER(50); + REGISTER_NATIVE_INTERRUPT_HANDLER(51); + REGISTER_NATIVE_INTERRUPT_HANDLER(52); + REGISTER_NATIVE_INTERRUPT_HANDLER(53); + REGISTER_NATIVE_INTERRUPT_HANDLER(54); + REGISTER_NATIVE_INTERRUPT_HANDLER(55); + REGISTER_NATIVE_INTERRUPT_HANDLER(56); + REGISTER_NATIVE_INTERRUPT_HANDLER(57); + REGISTER_NATIVE_INTERRUPT_HANDLER(58); + REGISTER_NATIVE_INTERRUPT_HANDLER(59); + REGISTER_NATIVE_INTERRUPT_HANDLER(60); + REGISTER_NATIVE_INTERRUPT_HANDLER(61); + REGISTER_NATIVE_INTERRUPT_HANDLER(62); + REGISTER_NATIVE_INTERRUPT_HANDLER(63); + + EXPORT_FUNCTION(wiringPiISR); + + EXPORT_CONSTANT_INT(INT_EDGE_FALLING); + EXPORT_CONSTANT_INT(INT_EDGE_RISING); + EXPORT_CONSTANT_INT(INT_EDGE_BOTH); + EXPORT_CONSTANT_INT(INT_EDGE_SETUP); +} \ No newline at end of file diff --git a/src/wiringPiISR.h b/src/wiringPiISR.h new file mode 100644 index 0000000..c08ff1e --- /dev/null +++ b/src/wiringPiISR.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_PI_ISR_H_ +#define _WPI_WIRING_PI_ISR_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringPiISR); + +#endif \ No newline at end of file diff --git a/src/wiringPiSPI.cc b/src/wiringPiSPI.cc new file mode 100644 index 0000000..fcde1c0 --- /dev/null +++ b/src/wiringPiSPI.cc @@ -0,0 +1,80 @@ +#include "wiringPiSPI.h" +#include +#include + +DECLARE(wiringPiSPIGetFd); +DECLARE(wiringPiSPIDataRW); +DECLARE(wiringPiSPISetup); + +// Func : int wiringPiSPIGetFd(int channel) + +IMPLEMENT(wiringPiSPIGetFd) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, channel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int channel = GET_ARGUMENT_AS_INT32(0); + + CHECK_ARGUMENT_IN_INTS(0, channel, (0, 1)); + + int res = ::wiringPiSPIGetFd(channel); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : wiringPiSPIDataRW(int channel, unsigned char* data, int len) + +IMPLEMENT(wiringPiSPIDataRW) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, channel); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_NODE_BUFFER(1); + + int channel = GET_ARGUMENT_AS_INT32(0); + char* data = node::Buffer::Data(args[1]->ToObject()); + int length = node::Buffer::Length(args[1]->ToObject()); + + CHECK_ARGUMENT_IN_INTS(0, channel, (0, 1)); + + int res = ::wiringPiSPIDataRW(channel, reinterpret_cast(data), length); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int wiringPiSPISetup(int channel, int speed) + +IMPLEMENT(wiringPiSPISetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, channel); + SET_ARGUMENT_NAME(1, speed); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int channel = GET_ARGUMENT_AS_INT32(0); + int speed = GET_ARGUMENT_AS_INT32(0); + + CHECK_ARGUMENT_IN_INTS(0, channel, (0, 1)); + + int res = ::wiringPiSPISetup(channel, speed); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(wiringPiSPI) { + EXPORT_FUNCTION(wiringPiSPIGetFd); + EXPORT_FUNCTION(wiringPiSPIDataRW); + EXPORT_FUNCTION(wiringPiSPISetup); +} \ No newline at end of file diff --git a/src/wiringPiSPI.h b/src/wiringPiSPI.h new file mode 100644 index 0000000..4ff13a5 --- /dev/null +++ b/src/wiringPiSPI.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_PI_SPI_H_ +#define _WPI_WIRING_PI_SPI_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringPiSPI); + +#endif \ No newline at end of file diff --git a/src/wiringSerial.cc b/src/wiringSerial.cc new file mode 100644 index 0000000..51b8af1 --- /dev/null +++ b/src/wiringSerial.cc @@ -0,0 +1,167 @@ +#include "wiringSerial.h" +#include +#include + +DECLARE(serialOpen); +DECLARE(serialClose); +DECLARE(serialFlush); +DECLARE(serialPutchar); +DECLARE(serialPuts); +DECLARE(serialPrintf); +DECLARE(serialDataAvail); +DECLARE(serialGetchar); + +// Func : int serialOpen(const char* device, const int baud) + +IMPLEMENT(serialOpen) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, device); + SET_ARGUMENT_NAME(1, baudrate); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_STRING(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + String::AsciiValue device(GET_ARGUMENT_AS_STRING(0)); + int baudrate = GET_ARGUMENT_AS_INT32(1); + + int res = ::serialOpen(*device, baudrate); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : void serialClose(const int fd) + +IMPLEMENT(serialClose) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + ::serialClose(fd); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void serialFlush(const int fd); + +IMPLEMENT(serialFlush) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + ::serialFlush(fd); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void serialPutchar(const int fd, const unsigned char c) + +IMPLEMENT(serialPutchar) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, character); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + unsigned char character = GET_ARGUMENT_AS_UINT32(1); + + ::serialPutchar(fd, character); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void serialPuts(const int fd, const char* s) + +IMPLEMENT(serialPuts) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, string); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_STRING(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + String::AsciiValue string(GET_ARGUMENT_AS_STRING(1)); + + ::serialPuts(fd, *string); + + SCOPE_CLOSE(UNDEFINED()); +} + +// Func : void serialPrintf(const int fd, const char* message, ...) + +IMPLEMENT(serialPrintf) { + // Make serialPrintf a alias to serialPuts + return serialPuts(args); +} + +// Func : int serialDataAvail(const int fd) + +IMPLEMENT(serialDataAvail) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + int res = ::serialDataAvail(fd); + + SCOPE_CLOSE(INT32(res)); +} + +// Func : int serialGetchar(const int fd) +// NOTE TO MYSELF : I don't understand why serialPutchar takes a unsigned char and on the other side +// serialGetchar returns a int ... serialGetchar should returns a unsigned char too. + +IMPLEMENT(serialGetchar) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + int res = ::serialGetchar(fd); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(wiringSerial) { + EXPORT_FUNCTION(serialOpen); + EXPORT_FUNCTION(serialClose); + EXPORT_FUNCTION(serialFlush); + EXPORT_FUNCTION(serialPutchar); + EXPORT_FUNCTION(serialPuts); + EXPORT_FUNCTION(serialPrintf); + EXPORT_FUNCTION(serialDataAvail); + EXPORT_FUNCTION(serialGetchar); +} \ No newline at end of file diff --git a/src/wiringSerial.h b/src/wiringSerial.h new file mode 100644 index 0000000..2da6c1f --- /dev/null +++ b/src/wiringSerial.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_SERIAL_H_ +#define _WPI_WIRING_SERIAL_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringSerial); + +#endif \ No newline at end of file diff --git a/src/wiringShift.cc b/src/wiringShift.cc new file mode 100644 index 0000000..4d54780 --- /dev/null +++ b/src/wiringShift.cc @@ -0,0 +1,76 @@ +#include "wiringShift.h" +#include +#include + +DECLARE(shiftIn); +DECLARE(shiftOut); + +// Func : uint8_t shiftIn(uint8_t dPin, uint8_t cPin, uint8_t order) +// Description : This shifts an 8-bit data value in with the data appearing on the dPin and the clock being sent out on the cPin. +// Order is either LSBFIRST or MSBFIRST. +// The data is sampled after the cPin goes high. +// (So cPin high, sample data, cPin low, repeat for 8 bits) The 8-bit value is returned by the function. + +IMPLEMENT(shiftIn) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, dPin); + SET_ARGUMENT_NAME(1, cPin); + SET_ARGUMENT_NAME(2, order); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_UINT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + CHECK_ARGUMENT_TYPE_UINT32(2); + + uint8_t dPin = GET_ARGUMENT_AS_UINT32(0); + uint8_t cPin = GET_ARGUMENT_AS_UINT32(1); + uint8_t order = GET_ARGUMENT_AS_UINT32(2); + + CHECK_ARGUMENT_IN_INTS(2, order, (LSBFIRST, MSBFIRST)); + + uint8_t res = ::shiftIn(dPin, cPin, order); + + SCOPE_CLOSE(UINT32(res)); +} + +// Func : void shiftOut(uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; +// Description : The shifts an 8-bit data value val out with the data being sent out on dPin and the clock being sent out on the cPin. +// order is as above. +// Data is clocked out on the rising or falling edge – ie. dPin is set, then cPin is taken high then low – repeated for the 8 bits. + +IMPLEMENT(shiftOut) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, dPin); + SET_ARGUMENT_NAME(1, cPin); + SET_ARGUMENT_NAME(2, order); + SET_ARGUMENT_NAME(3, value); + + CHECK_ARGUMENTS_LENGTH_EQUAL(4); + + CHECK_ARGUMENT_TYPE_UINT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + CHECK_ARGUMENT_TYPE_UINT32(2); + CHECK_ARGUMENT_TYPE_UINT32(3); + + uint8_t dPin = GET_ARGUMENT_AS_UINT32(0); + uint8_t cPin = GET_ARGUMENT_AS_UINT32(1); + uint8_t order = GET_ARGUMENT_AS_UINT32(2); + uint8_t value = GET_ARGUMENT_AS_UINT32(3); + + CHECK_ARGUMENT_IN_INTS(2, order, (LSBFIRST, MSBFIRST)); + + ::shiftOut(dPin, cPin, order, value); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(wiringShift) { + EXPORT_FUNCTION(shiftIn); + EXPORT_FUNCTION(shiftOut); + + EXPORT_CONSTANT_INT(LSBFIRST); + EXPORT_CONSTANT_INT(MSBFIRST); +} \ No newline at end of file diff --git a/src/wiringShift.h b/src/wiringShift.h new file mode 100644 index 0000000..98ca11b --- /dev/null +++ b/src/wiringShift.h @@ -0,0 +1,8 @@ +#ifndef _WPI_WIRING_SHIFT_H_ +#define _WPI_WIRING_SHIFT_H_ + + #include "addon.h" + + DECLARE_EXPORT_INIT(wiringShift); + +#endif \ No newline at end of file diff --git a/src/wpi.cc b/src/wpi.cc new file mode 100644 index 0000000..991eec4 --- /dev/null +++ b/src/wpi.cc @@ -0,0 +1,15 @@ +#include "wpi.h" + +NODE_MODULE_INIT() { + INIT(wiringPi); + INIT(softPwm); + INIT(softServo); + INIT(softTone); + INIT(wiringPiI2C); + INIT(wiringPiSPI); + INIT(wiringSerial); + INIT(wiringShift); + INIT(wiringPiISR); +} + +NODE_MODULE_DECLARE(wiringPi); \ No newline at end of file diff --git a/src/wpi.h b/src/wpi.h new file mode 100644 index 0000000..301c9cf --- /dev/null +++ b/src/wpi.h @@ -0,0 +1,14 @@ +#ifndef _WPI_H_ +#define _WPI_H_ + + #include "wiringPi.h" + #include "softPwm.h" + #include "softServo.h" + #include "softTone.h" + #include "wiringPiI2C.h" + #include "wiringPiSPI.h" + #include "wiringSerial.h" + #include "wiringShift.h" + #include "wiringPiISR.h" + +#endif \ No newline at end of file From 79f804f86c1e2a27231ade127062ed31a1081c1c Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 2 Jul 2014 19:50:27 +0200 Subject: [PATCH 19/64] update documentation --- DOCUMENTATION.md | 85 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 9b9aa85..a1efb00 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -1,16 +1,30 @@ + + # Index @@ -39,6 +53,7 @@ var wpi = require('wiring-pi'); ## Setup ### `wiringPiSetup()` + >= 0.1.0 Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. @@ -46,6 +61,7 @@ see the pins page (http://wiringpi.com/pins/) for a table which maps the wiringP This function needs to be called with root privileges. ### `wiringPiSetupGpio()` + >= 0.1.1 This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards. @@ -55,23 +71,29 @@ This is indential to above, however it allows the calling programs to use the Br Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. As above, this function needs to be called with root priviliges. ### `wiringPiSetupSys()` + >= 0.1.1 This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed). ### `setup(mode)` + >= 0.1.1 An handy function to setup wiringPi `mode` can be one of the following values: * `wpi`: sets up pin numbering with wiringPiSetup + >= 0.1.1 * `gpio`: sets up pin numbering with wiringPiSetupGpio + >= 0.1.1 * `sys`: sets up pin numbering with wiringPiSetupSys + >= 0.1.1 * `phys`: sets up pin numbering with wiringPiSetupPhys + >= 1.0.0 More info about pin numbering systems at [wiringpi.com/pins/](http://wiringpi.com/pins/) -**NOTE: wiring-pi >= 2.0.0 no longer accept calling setup without mode specified. (defaulting to `wpi` in wiring-pi < 2.0.0)** +**NOTE: `>= 2.0.0` no longer accept calling setup without mode specified. (defaulting to `wpi` in `< 2.0.0`)** --- @@ -85,25 +107,39 @@ This is an un-documented special to let you set any pin to any mode. `mode` can be one of the following values: * `WPI_MODE_PINS` + >= 1.0.0 * `WPI_MODE_PHYS` + >= 1.0.0 * `WPI_MODE_GPIO` + >= 1.0.0 ### `pinMode(pin, mode)` + >= 0.1.0 This sets the mode of a pin. Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program. `mode` can be one of the following values: -* `modes.INPUT` **wiring-pi < 1.0.0** -* `modes.OUTPUT` **wiring-pi < 1.0.0** -* `modes.PWM_OUTPUT` **wiring-pi < 1.0.0** -* `modes.GPIO_CLOCK` **wiring-pi < 1.0.0** +* `modes.INPUT` + >= 0.1.1 < 2.0.0 removed +* `modes.OUTPUT` + >= 0.1.1 < 2.0.0 removed +* `modes.PWM_OUTPUT` + >= 0.1.1 < 2.0.0 removed +* `modes.GPIO_CLOCK` + >= 0.1.1 < 2.0.0 removed * `INPUT` + >= 1.0.0 * `OUTPUT` + >= 1.0.0 * `PWM_OUTPUT` + >= 1.0.0 * `GPIO_CLOCK` -* `SOFT_PWM_OUTPUT` **wiring-pi >= 1.1.0** -* `SOFT_TONE_OUTPUT` **wiring-pi >= 1.1.0** + >= 1.0.0 +* `SOFT_PWM_OUTPUT` + >= 1.1.0 +* `SOFT_TONE_OUTPUT` + >= 1.1.0 ### `pullUpDnControl(pin, pud)` >= 0.2.0 @@ -113,23 +149,31 @@ This sets the pull-up or pull-down resistor mode on the given pin, which should `pud` can be one of the following values: * `PUD_OFF` *no pull up/down* + >= 0.2.0 * `PUD_DOWN` *pull to ground* + >= 0.2.0 * `PUD_UP` *pull to 3.3v* + >= 0.2.0 ### `digitalRead(pin)` + >= 0.1.1 This function returns the value read at the given pin. It will be `HIGH` (1) or `LOW` (0) depending on the logic level at the pin. ### `digitalWrite(pin, state)` + >= 0.1.0 Write the value `HIGH` (1) or `LOW` (0) to the given pin which must have been previously set as an output. WiringPi treats any non-zero number as `HIGH`, however 0 is the only representation of `LOW`. `state` can be one of the following value: * `HIGH` + >= 0.1.2 * `LOW` + >= 0.1.2 ### `pwmWrite(pin, value)` + >= 0.1.1 Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024]. Other PWM devices may have other PWM ranges. This function is not able to control the Pi's on-board PWM when in Sys mode. @@ -151,7 +195,9 @@ This writes the given value to the supplied analog pin. You will need to registe `state` can be one of the following values: * `HIGH` + >= 0.1.2 * `LOW` + >= 0.1.2 ### `delay(milliseconds)` >= 1.1.0 @@ -170,6 +216,7 @@ This writes the given value to the supplied analog pin. You will need to registe ## Raspberry Pi hardware specific functions ### `piBoardRev()` + >= 0.1.1 This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. @@ -212,10 +259,12 @@ The PWM generator can run in 2 modes – “balanced” and “mark:space”. Th * `PWM_MODE_MS` *mark:space* ### `pwmSetRange(range)` + >= 0.1.1 This sets the range register in the PWM generator. The default is 1024. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. ### `pwmSetClock(divisor)` + >= 0.1.1 This sets the divisor for the PWM clock. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. From 77b5470513dec93a4e3aaa5e30db2de32223e3f9 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 12:48:56 +0200 Subject: [PATCH 20/64] update documentation --- DOCUMENTATION.html | 266 +++++++++++++++++++ README.md | 2 +- DOCUMENTATION.md => docs/DOCUMENTATION.md | 40 +-- docs/pandoc.css | 301 ++++++++++++++++++++++ 4 files changed, 569 insertions(+), 40 deletions(-) create mode 100644 DOCUMENTATION.html rename DOCUMENTATION.md => docs/DOCUMENTATION.md (95%) create mode 100644 docs/pandoc.css diff --git a/DOCUMENTATION.html b/DOCUMENTATION.html new file mode 100644 index 0000000..c795b0e --- /dev/null +++ b/DOCUMENTATION.html @@ -0,0 +1,266 @@ + + + + + + + + + + + + + +

Install

+
npm install wiring-pi
+

Usage

+
var wpi = require('wiring-pi');
+

APIs

+

Setup

+

wiringPiSetup()

+

>= 0.1.0

+

Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. see the pins page (http://wiringpi.com/pins/) for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. This function needs to be called with root privileges.

+

wiringPiSetupGpio()

+

>= 0.1.1

+

This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards.

+

wiringPiSetupPhys()

+

>= 1.0.0

+

Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. As above, this function needs to be called with root priviliges.

+

wiringPiSetupSys()

+

>= 0.1.1

+

This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed).

+

setup(mode)

+

>= 0.1.1

+

An handy function to setup wiringPi

+

mode can be one of the following values:

+
    +
  • wpi: sets up pin numbering with wiringPiSetup >= 0.1.1
  • +
  • gpio: sets up pin numbering with wiringPiSetupGpio >= 0.1.1
  • +
  • sys: sets up pin numbering with wiringPiSetupSys >= 0.1.1
  • +
  • phys: sets up pin numbering with wiringPiSetupPhys >= 1.0.0
  • +
+

More info about pin numbering systems at wiringpi.com/pins/

+

NOTE: >= 2.0.0 no longer accept calling setup without mode specified. (defaulting to wpi in < 2.0.0)

+
+

Core functions

+

pinModeAlt(pin, mode)

+

>= 1.0.0

+

This is an un-documented special to let you set any pin to any mode.

+

mode can be one of the following values:

+
    +
  • WPI_MODE_PINS >= 1.0.0
  • +
  • WPI_MODE_PHYS >= 1.0.0
  • +
  • WPI_MODE_GPIO >= 1.0.0
  • +
+

pinMode(pin, mode)

+

>= 0.1.0

+

This sets the mode of a pin. Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program.

+

mode can be one of the following values:

+
    +
  • modes.INPUT >= 0.1.1 < 2.0.0 removed
  • +
  • modes.OUTPUT >= 0.1.1 < 2.0.0 removed
  • +
  • modes.PWM_OUTPUT >= 0.1.1 < 2.0.0 removed
  • +
  • modes.GPIO_CLOCK >= 0.1.1 < 2.0.0 removed
  • +
  • INPUT >= 1.0.0
  • +
  • OUTPUT >= 1.0.0
  • +
  • PWM_OUTPUT >= 1.0.0
  • +
  • GPIO_CLOCK >= 1.0.0
  • +
  • SOFT_PWM_OUTPUT >= 1.1.0
  • +
  • SOFT_TONE_OUTPUT >= 1.1.0
  • +
+

pullUpDnControl(pin, pud)

+

>= 0.2.0

+

This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi.

+

pud can be one of the following values:

+
    +
  • PUD_OFF no pull up/down >= 0.2.0
  • +
  • PUD_DOWN pull to ground >= 0.2.0
  • +
  • PUD_UP pull to 3.3v >= 0.2.0
  • +
+

digitalRead(pin)

+

>= 0.1.1

+

This function returns the value read at the given pin. It will be HIGH (1) or LOW (0) depending on the logic level at the pin.

+

digitalWrite(pin, state)

+

>= 0.1.0

+

Write the value HIGH (1) or LOW (0) to the given pin which must have been previously set as an output. WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW.

+

state can be one of the following value:

+
    +
  • HIGH >= 0.1.2
  • +
  • LOW >= 0.1.2
  • +
+

pwmWrite(pin, value)

+

>= 0.1.1

+

Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024]. Other PWM devices may have other PWM ranges. This function is not able to control the Pi's on-board PWM when in Sys mode.

+

value must be in range of [0, 1024]

+

analogRead(pin)

+

>= 1.0.0

+

This returns the value read on the supplied analog input pin. You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc.

+

analogWrite(pin, value)

+

>= 1.0.0

+

This writes the given value to the supplied analog pin. You will need to register additional analog modules to enable this function for devices such as the Gertboard.

+

pulseIn(pin, state)

+

>= 1.1.0

+

state can be one of the following values:

+
    +
  • HIGH >= 0.1.2
  • +
  • LOW >= 0.1.2
  • +
+

delay(milliseconds)

+

>= 1.1.0

+

delayMicroseconds(microseconds)

+

>= 1.1.0

+

millis()

+

>= 1.1.0

+

micros()

+

>= 1.1.0

+
+

Raspberry Pi hardware specific functions

+

piBoardRev()

+

>= 0.1.1

+

This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences.

+

piBoardId()

+

>= 1.1.0

+

wpiPinToGpio(pin)

+

>= 1.0.0

+

This returns the BCM_GPIO pin number of the supplied wiringPi pin. It takes the board revision into account.

+

physPinToGpio(pin)

+

>= 1.0.0

+

This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector.

+

setPadDrive(group, value)

+

>= 1.0.0

+

This sets the "strength" of the pad drivers for a particular group of pins. There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you know what you are doing.

+

getAlt(pin)

+

>= 1.0.0

+

Returns the ALT bits for a given port.

+

digitalWriteByte(byte)

+

>= 1.0.0

+

This writes the 8-bit byte supplied to the first 8 GPIO pins. It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware.

+

pwmSetMode(mode)

+

>= 1.0.0

+

The PWM generator can run in 2 modes – “balanced” and “mark:space”. The mark:space mode is traditional, however the default mode in the Pi is “balanced”.

+

mode can be one of the following values:

+
    +
  • PWM_MODE_BAL balanced
  • +
  • PWM_MODE_MS mark:space
  • +
+

pwmSetRange(range)

+

>= 0.1.1

+

This sets the range register in the PWM generator. The default is 1024. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

+

pwmSetClock(divisor)

+

>= 0.1.1

+

This sets the divisor for the PWM clock. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

+

gpioClockSet(pin, frequency)

+

>= 1.0.0

+

Set the frequency on a GPIO clock pin

+
+

I2C

+

wiringPiI2CSetup(devId)

+

>= 2.0.0

+

wiringPiI2CSetupInterface(device, devId)

+

>= 2.0.0

+

wiringPiI2CRead(fd)

+

>= 2.0.0

+

wiringPiI2CReadReg8(fd, reg)

+

>= 2.0.0

+

wiringPiI2CReadReg16(fd, red)

+

>= 2.0.0

+

wiringPiI2CWrite(fd, data)

+

>= 2.0.0

+

wiringPiI2CWriteReg8(fd, reg, data)

+

>= 2.0.0

+

wiringPiI2CWriteReg16(fd, reg, data)

+

>= 2.0.0

+
+

SPI

+

wiringPiSPIGetFd(channel)

+

>= 1.0.0

+

wiringPiSPIDataRW(channel, data)

+

>= 1.0.0

+

wiringPiSPISetup(channel, speed)

+

>= 1.0.0

+
+

Serial

+

serialOpen(device, baudrate)

+

>= 1.0.0

+

serialClose(fd)

+

>= 1.0.0

+

serialFlush(fd)

+

>= 1.0.0

+

serialPutchar(fd, character)

+

>= 1.0.0

+

serialPuts(fd, string)

+

>= 1.0.0

+

serialPrintf(fd, string)

+

Alias: serialPuts >= 2.0.0

+

serialDataAvail(fd)

+

>= 1.0.0

+

serialGetchar(fd)

+

>= 1.0.0

+
+

Shift

+

shiftIn(dPin, cPin, order)

+

>= 1.0.0

+

shiftOut(dPin, cPin, order, value)

+

>= 1.0.0

+
+

Soft PWM

+

softPwmCreate(pin, value, range)

+

>= 1.0.0

+

softPwmWrite(pin, value)

+

>= 1.0.0

+

softPwmStop(pin)

+

>= 1.1.0

+
+

Soft Servo

+

softServoWrite(pin, value)

+

>= 1.0.0

+

softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7)

+

>= 1.0.0

+
+

Soft Tone

+

softToneCreate(pin);

+

>= 1.0.0

+

softToneWrite(pin, frequency);

+

>= 1.0.0

+

softToneStop(pin);

+

>= 1.1.0

+
+

Extensions

+ + diff --git a/README.md b/README.md index 0b563e9..f1e3d26 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ var wpi = require('wiring-pi'); ``` ## Documentation -See the [DOCUMENTATION.md](https://github.com/eugeneware/wiring-pi/blob/master/DOCUMENTATION.md) file for more detailed documentation. +See the [DOCUMENTATION.html](https://github.com/eugeneware/wiring-pi/blob/master/DOCUMENTATION.html) file for more detailed documentation. ## Contributing diff --git a/DOCUMENTATION.md b/docs/DOCUMENTATION.md similarity index 95% rename from DOCUMENTATION.md rename to docs/DOCUMENTATION.md index a1efb00..c6e98ad 100644 --- a/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -1,44 +1,6 @@ - - - - -# Index - -* [Install](#install) -* [Usage](#usage) -* [APIs](#apis) - * [Setup](#setup) - * [wiringPiSetup](#wiringpisetup) - * [wiringPiSetupGpio](#wiringpisetupgpio) - * [Shift](#shift) - # Install -```bash +``` npm install wiring-pi ``` diff --git a/docs/pandoc.css b/docs/pandoc.css new file mode 100644 index 0000000..dc4daf5 --- /dev/null +++ b/docs/pandoc.css @@ -0,0 +1,301 @@ +body { + font-family: Helvetica, arial, sans-serif; + font-size: 14px; + line-height: 1.6; + padding-top: 10px; + padding-bottom: 10px; + background-color: white; + padding: 30px; } + +body > *:first-child { + margin-top: 0 !important; } +body > *:last-child { + margin-bottom: 0 !important; } + +a { + color: #4183C4; } +a.absent { + color: #cc0000; } +a.anchor { + display: block; + padding-left: 30px; + margin-left: -30px; + cursor: pointer; + position: absolute; + top: 0; + left: 0; + bottom: 0; } + +h1, h2, h3, h4, h5, h6 { + margin: 20px 0 10px; + padding: 0; + font-weight: bold; + -webkit-font-smoothing: antialiased; + cursor: text; + position: relative; } + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { + background: url("../../images/modules/styleguide/para.png") no-repeat 10px center; + text-decoration: none; } + +h1 tt, h1 code { + font-size: inherit; } + +h2 tt, h2 code { + font-size: inherit; } + +h3 tt, h3 code { + font-size: inherit; } + +h4 tt, h4 code { + font-size: inherit; } + +h5 tt, h5 code { + font-size: inherit; } + +h6 tt, h6 code { + font-size: inherit; } + +h1 { + font-size: 28px; + color: black; } + +h2 { + font-size: 24px; + border-bottom: 1px solid #cccccc; + color: black; } + +h3 { + font-size: 18px; } + +h4 { + font-size: 16px; } + +h5 { + font-size: 14px; } + +h6 { + color: #777777; + font-size: 14px; } + +p, blockquote, ul, ol, dl, li, table, pre { + margin: 15px 0; } + +hr { + background: transparent url("../../images/modules/pulls/dirty-shade.png") repeat-x 0 0; + border: 0 none; + color: #cccccc; + height: 4px; + padding: 0; } + +body > h2:first-child { + margin-top: 0; + padding-top: 0; } +body > h1:first-child { + margin-top: 0; + padding-top: 0; } + body > h1:first-child + h2 { + margin-top: 0; + padding-top: 0; } +body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child { + margin-top: 0; + padding-top: 0; } + +a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { + margin-top: 0; + padding-top: 0; } + +h1 p, h2 p, h3 p, h4 p, h5 p, h6 p { + margin-top: 0; } + +li p.first { + display: inline-block; } + +ul, ol { + padding-left: 30px; } + +ul :first-child, ol :first-child { + margin-top: 0; } + +ul :last-child, ol :last-child { + margin-bottom: 0; } + +dl { + padding: 0; } + dl dt { + font-size: 14px; + font-weight: bold; + font-style: italic; + padding: 0; + margin: 15px 0 5px; } + dl dt:first-child { + padding: 0; } + dl dt > :first-child { + margin-top: 0; } + dl dt > :last-child { + margin-bottom: 0; } + dl dd { + margin: 0 0 15px; + padding: 0 15px; } + dl dd > :first-child { + margin-top: 0; } + dl dd > :last-child { + margin-bottom: 0; } + +blockquote { + border-left: 4px solid #dddddd; + padding: 0 15px; + color: #777777; } + blockquote > :first-child { + margin-top: 0; } + blockquote > :last-child { + margin-bottom: 0; } + +table { + padding: 0; } + table tr { + border-top: 1px solid #cccccc; + background-color: white; + margin: 0; + padding: 0; } + table tr:nth-child(2n) { + background-color: #f8f8f8; } + table tr th { + font-weight: bold; + border: 1px solid #cccccc; + text-align: left; + margin: 0; + padding: 6px 13px; } + table tr td { + border: 1px solid #cccccc; + text-align: left; + margin: 0; + padding: 6px 13px; } + table tr th :first-child, table tr td :first-child { + margin-top: 0; } + table tr th :last-child, table tr td :last-child { + margin-bottom: 0; } + +img { + max-width: 100%; } + +span.frame { + display: block; + overflow: hidden; } + span.frame > span { + border: 1px solid #dddddd; + display: block; + float: left; + overflow: hidden; + margin: 13px 0 0; + padding: 7px; + width: auto; } + span.frame span img { + display: block; + float: left; } + span.frame span span { + clear: both; + color: #333333; + display: block; + padding: 5px 0 0; } +span.align-center { + display: block; + overflow: hidden; + clear: both; } + span.align-center > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: center; } + span.align-center span img { + margin: 0 auto; + text-align: center; } +span.align-right { + display: block; + overflow: hidden; + clear: both; } + span.align-right > span { + display: block; + overflow: hidden; + margin: 13px 0 0; + text-align: right; } + span.align-right span img { + margin: 0; + text-align: right; } +span.float-left { + display: block; + margin-right: 13px; + overflow: hidden; + float: left; } + span.float-left span { + margin: 13px 0 0; } +span.float-right { + display: block; + margin-left: 13px; + overflow: hidden; + float: right; } + span.float-right > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: right; } + +code, tt { + margin: 0 2px; + padding: 0 5px; + white-space: nowrap; + border: 1px solid #eaeaea; + background-color: #f8f8f8; + border-radius: 3px; } + +pre code { + margin: 0; + padding: 0; + white-space: pre; + border: none; + background: transparent; } + +.highlight pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; } + +pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; } + pre code, pre tt { + background-color: transparent; + border: none; } + +.api-info { + display: block; + text-align: right; + margin-top: -40px; + font-style: italic; +} + +.api-info-list { + display: inline; + float:right; +} + +.api-info-deprecated { + background-color: #F90 !important; + color: #FFF !important; + text-transform: uppercase; +} + +.api-info-removed { + background-color: #D33 !important; + color: #FFF !important; + text-transform: uppercase; +} From fc5b5d54bffad118599e89b22f5c973a5fea0f20 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 15:35:08 +0200 Subject: [PATCH 21/64] Preparing wiring-pi 2.0.0 - UPD: documentation - UPD: install script (add gpio utility installation, make check, fix update) - ADD: drcSerial extension - UPD: examples --- binding.gyp | 3 +++ docs/dirty-shade.png | Bin 0 -> 939 bytes docs/gendoc.sh | 3 +++ docs/pandoc.css | 4 ++-- docs/para.png | Bin 0 -> 1048 bytes examples/blink.js | 2 +- examples/pwm.js | 2 +- install.sh | 30 +++++++++++++++++++++++++++++ src/extensions/drcSerial.cc | 37 ++++++++++++++++++++++++++++++++++++ src/extensions/drcSerial.h | 8 ++++++++ src/wpi.cc | 2 ++ src/wpi.h | 2 ++ 12 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 docs/dirty-shade.png create mode 100644 docs/gendoc.sh create mode 100644 docs/para.png create mode 100644 src/extensions/drcSerial.cc create mode 100644 src/extensions/drcSerial.h diff --git a/binding.gyp b/binding.gyp index b22d142..f4f8f55 100644 --- a/binding.gyp +++ b/binding.gyp @@ -12,6 +12,9 @@ 'src/wiringSerial.cc', 'src/wiringShift.cc', 'src/wiringPiISR.cc', + + 'src/extensions/drcSerial.cc', + 'src/wpi.cc' ], 'include_dirs': [ diff --git a/docs/dirty-shade.png b/docs/dirty-shade.png new file mode 100644 index 0000000000000000000000000000000000000000..3e0e9c90bdf0469caf1afc7f7b8e35dc41aa99ad GIT binary patch literal 939 zcmaJ=&yLbS9Bu?RX5%J%)r*sIm3CVGv`naLX~At`2>}v0I68E`#B(wv*x$VPM%sc<5`*!CP28u*qoIUzjFg2jXA466 zB8#!NBn(W+JctbO_ovSy2z*0))^MR4TVxSjZWA)v_Q&3K>9u_E;t^-VUUGa zQHnA{-032I&aY(=>>zAuh}S_)+ySs?LO?@;RSz~HXeyFYt81F}5U5arGE`+nttuL- zsR%-_|3vOB@n>jg_x8THWrz#LVkFD!^;%ljB$~`+rPXTX8me05h-$it7|yCuS}7E4 zl6pxHvw%h*SHx4gVur{gy-p#F53*6ZFB31AoZ(njB$%gE0A2V0&@eopQ#K?w@%~dd z9dBYH4@pW_iN_l^tK_a?WF-VMnv5yEDyleGP)5@Qje#|402g~fl-oPJ>mnyg8IC;S z*oMdzq#*E-ZdtvWshQ12(^Ql$>}Z|3sn>K(wbWLxt`}UJdaIB`tl;`L+|E&MJ_=#X zJ=-J+UJ}2T&=BlWM#1q|^rL!vu75n1)={p^gOT&b{?+K>ice2|Jd7-TSeeBn>xfn%HF?B~>feETarsWeTXe}C6gl9dganLhU$?bv4U>&^lNpMnERjTwcI_K$pnbJ{xI#Ff zH$r0c;=!Aq3I6~G(Qx5t;>i2#A6R>(50lDh68CTHRb0wr5tMH-4GwOBT` z){L~t&fWzxflLK#M060?>y9r68Mdh_({*^vv!DqfYZ>-DsTFkzzP>A!84k;!iWl@sj)1dXRG@55tWlbrzV$ofOtr6nNJYTQZxq5=b-YPGo z)9Fwn9*g4fyse-h-|#G#Sl9ufqF%upB*W57&#z#+9a+b3*+dQF1Ks5X z4u)5116B3^P}}aHeWIa@eE%uzmp5I+YskkNo+FsbT><%Ha+rnsugCC4YaW1y0f zVQDzdvP?Ohm!x!lE}lxkq97E6l$c5@sf41$b43y6l5MVnjSU+)q|G%ixQVXZux@OZ zMplq#y+CHs!!~I8BU{~bfnD`lT(f&FLRT(Nli|ZE_^T?~N3_(!Wv9mJrqdX-UbIgYT8!jmB(bV&|JMRl8 Td-L}vXeg#sSX2(?p1t}5UOquV literal 0 HcmV?d00001 diff --git a/examples/blink.js b/examples/blink.js index 66aa537..d3a0fb0 100644 --- a/examples/blink.js +++ b/examples/blink.js @@ -1,6 +1,6 @@ var wpi = require('wiring-pi'); -wpi.setup(); +wpi.setup('wpi'); var pin = 0; diff --git a/examples/pwm.js b/examples/pwm.js index ffdb0fe..f7f3ad4 100644 --- a/examples/pwm.js +++ b/examples/pwm.js @@ -2,7 +2,7 @@ var wpi = require('wiring-pi'); var async = require('async'); -wpi.setup(); +wpi.setup('wpi'); var pin = 1; wpi.pinMode(pin, wpi.PWM_OUTPUT); diff --git a/install.sh b/install.sh index ce9fd49..38d7c46 100644 --- a/install.sh +++ b/install.sh @@ -1,7 +1,37 @@ #!/bin/bash +check_make_ok() { + echo "" + echo "================================================================================" + if [ $2 == 1 ]; then + echo "FATAL: Making $1 failed." + else + echo "Making $1 failed." + fi + echo "Please check the messages and fix any problems. If you're still stuck," + echo "then please open a new issue then post all the output and as many details as you can to" + echo " https://github.com/eugeneware/wiring-pi/issues" + echo "================================================================================" + echo "" + if [ $2 == 1 ]; then + exit 1 + fi +} + git clone https://github.com/nekuz0r/wiringpi.git + cd ./wiringpi/wiringPi/ +make clean make static +check_make_ok "libWiringPi" 1 cd ../../ + +cd ./wiringpi/gpio/ +sudo make uninstall +make clean +make +check_make_ok "gpio utility" +sudo make install +check_make_ok "gpio utility" + node-gyp rebuild \ No newline at end of file diff --git a/src/extensions/drcSerial.cc b/src/extensions/drcSerial.cc new file mode 100644 index 0000000..02eb38b --- /dev/null +++ b/src/extensions/drcSerial.cc @@ -0,0 +1,37 @@ +#include "drcSerial.h" +#include +#include + +DECLARE(drcSetupSerial); + +// Func : int drcSetupSerial(const int pinBase, const int numPins, const char* device, const int baud) +// Description : https://projects.drogon.net/drogon-remote-control/drc-protocol-arduino/ + +IMPLEMENT(drcSetupSerial) { + SCOPE_START(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, numPins); + SET_ARGUMENT_NAME(2, device); + SET_ARGUMENT_NAME(3, baudrate); + + CHECK_ARGUMENTS_LENGTH_EQUAL(4); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_STRING(2); + CHECK_ARGUMENT_TYPE_INT32(3); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int numPins = GET_ARGUMENT_AS_INT32(1); + String::AsciiValue device(GET_ARGUMENT_AS_STRING(2)); + int baudrate = GET_ARGUMENT_AS_INT32(3); + + int res = ::drcSetupSerial(pinBase, numPins, device, baudrate); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(drcSerial) { + EXPORT_FUNCTION(drcSetupSerial); +} \ No newline at end of file diff --git a/src/extensions/drcSerial.h b/src/extensions/drcSerial.h new file mode 100644 index 0000000..76e3417 --- /dev/null +++ b/src/extensions/drcSerial.h @@ -0,0 +1,8 @@ +#ifndef _WPI_DRC_SERIAL_H_ +#define _WPI_DRC_SERIAL_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(drcSerial); + +#endif \ No newline at end of file diff --git a/src/wpi.cc b/src/wpi.cc index 991eec4..7b51d86 100644 --- a/src/wpi.cc +++ b/src/wpi.cc @@ -10,6 +10,8 @@ NODE_MODULE_INIT() { INIT(wiringSerial); INIT(wiringShift); INIT(wiringPiISR); + + INIT(drcSerial); } NODE_MODULE_DECLARE(wiringPi); \ No newline at end of file diff --git a/src/wpi.h b/src/wpi.h index 301c9cf..43bad4e 100644 --- a/src/wpi.h +++ b/src/wpi.h @@ -10,5 +10,7 @@ #include "wiringSerial.h" #include "wiringShift.h" #include "wiringPiISR.h" + + #include "extensions/drcSerial.h" #endif \ No newline at end of file From 9a140d1555aa272f9597ef5a8561f0488b85f74c Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 15:57:50 +0200 Subject: [PATCH 22/64] update install script --- .gitignore | 3 +- install.sh | 80 ++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 72bd1fa..1ad15a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build npm-debug.log -wiringpi/ \ No newline at end of file +wiringpi/ +install.log \ No newline at end of file diff --git a/install.sh b/install.sh index 38d7c46..d75b0b2 100644 --- a/install.sh +++ b/install.sh @@ -1,37 +1,77 @@ #!/bin/bash check_make_ok() { - echo "" - echo "================================================================================" - if [ $2 == 1 ]; then - echo "FATAL: Making $1 failed." - else - echo "Making $1 failed." + if [ $? != 0 ]; then + echo "failed." + echo "" + echo "================================================================================" + if [ $2 == 1 ]; then + echo "FATAL: Making $1 failed." + else + echo "Making $1 failed." + fi + echo "Please check install.log and fix any problems. If you're still stuck," + echo "then please open a new issue then post all the output and as many details as you can to" + echo " https://github.com/eugeneware/wiring-pi/issues" + echo "================================================================================" + echo "" + if [ $2 == 1 ]; then + exit 1 + fi fi - echo "Please check the messages and fix any problems. If you're still stuck," - echo "then please open a new issue then post all the output and as many details as you can to" - echo " https://github.com/eugeneware/wiring-pi/issues" - echo "================================================================================" - echo "" - if [ $2 == 1 ]; then +} + +check_git_clone() { + if [ $? != 0 ]; then + echo "failed." + echo "" + echo "================================================================================" + echo "FATAL: Cloning libWiringPi failed." + echo "Please check install.log and fix any problems. If you're still stuck," + echo "then please open a new issue then post all the output and as many details as you can to" + echo " https://github.com/eugeneware/wiring-pi/issues" + echo "================================================================================" + echo "" exit 1 fi } -git clone https://github.com/nekuz0r/wiringpi.git +rm ./install.log 2>/dev/null 1>&2 +echo -n "Cloning libWiringPi ... " +rm -Rf ./wiringpi 2>/dev/null 1>&2 +git clone https://github.com/nekuz0r/wiringpi.git 2>./install.log 1>&2 +check_git_clone +echo "done." + +echo -n "Making libWiringPi ... " cd ./wiringpi/wiringPi/ -make clean -make static +make clean 2>../../install.log 1>&2 +make static 2>../../install.log 1>&2 check_make_ok "libWiringPi" 1 cd ../../ +echo "done." cd ./wiringpi/gpio/ -sudo make uninstall -make clean -make +echo -n "Unistalling gpio utility ... " +sudo make uninstall 2>../../install.log 1>&2 +echo "done." + +echo -n "Making gpio utility ... " +make clean 2>../../install.log 1>&2 +make 2>../../install.log 1>&2 check_make_ok "gpio utility" -sudo make install +echo "done." + +echo -n "Installing gpio utility ... " +sudo make install 2>../../install.log 1>&2 check_make_ok "gpio utility" +cd ../../ +echo "done." + +echo -n "Making wiring-pi ... " +node-gyp rebuild 2>./install.log 1>&2 +check_make_ok "wiring-pi" 1 +echo "done." -node-gyp rebuild \ No newline at end of file +echo "Enjoy !" \ No newline at end of file From 804bf8659943139cf833d85c51e1a615f6fa3e7a Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 19:27:07 +0200 Subject: [PATCH 23/64] Remove c++11 requirement --- binding.gyp | 13 +------------ src/addon.h | 28 ++++++++++++++++++++++------ src/extensions/drcSerial.cc | 4 ++-- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/binding.gyp b/binding.gyp index f4f8f55..658f512 100644 --- a/binding.gyp +++ b/binding.gyp @@ -24,18 +24,7 @@ ' #include #include - #include + //#include using namespace v8; @@ -30,10 +30,10 @@ ThrowException(func(String::New(buffer))); } - template + /*template bool isInList(T value, std::initializer_list values) { return !(std::find(values.begin(), values.end(), value) == values.end()); - } + }*/ #define DECLARE(name) \ namespace nodemodule { \ @@ -113,7 +113,7 @@ #define CHECK_ARGUMENT_TYPE(id, istype) \ if (!args[id]->istype()) { \ - THROW_ERROR("%s: %s(%s) === false", __func__, #istype, GET_ARGUMENT_NAME(id)); \ + THROW_ERROR("%s: %s(arguments['%s']) === false", __func__, #istype, GET_ARGUMENT_NAME(id)); \ } #define CHECK_ARGUMENT_TYPE_INT32(id) CHECK_ARGUMENT_TYPE(id, IsInt32) @@ -124,7 +124,7 @@ #define CHECK_ARGUMENT_TYPE_OBJECT(id) CHECK_ARGUMENT_TYPE(id, IsObject) #define CHECK_ARGUMENT_TYPE_NODE_BUFFER(id) \ if (!(args[id]->IsObject() && node::Buffer::HasInstance(args[id]))) { \ - THROW_ERROR("%s: %s(%s) === false", __func__, "isBuffer", GET_ARGUMENT_NAME(id)); \ + THROW_ERROR("%s: %s(arguments['%s']) === false", __func__, "isBuffer", GET_ARGUMENT_NAME(id)); \ } #define GET_ARGUMENT_AS_TYPE(id, type) args[id]->type() @@ -137,7 +137,7 @@ #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) #define LIST(...) { __VA_ARGS__ } - #define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ + /*#define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ if (!isInList(std::string(*value), LIST T)) { \ THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ } @@ -145,6 +145,22 @@ #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ if (!isInList(value, LIST T)) { \ THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ + }*/ + + #define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ + { \ + std::string strings[] = LIST T; \ + if (std::find(strings, strings + sizeof_array(strings), std::string(*value)) == strings + sizeof_array(strings)) { \ + THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ + } \ + } + + #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ + { \ + int ints[] = LIST T; \ + if (std::find(ints, ints + sizeof_array(ints), value) == ints + sizeof_array(ints)) { \ + THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ + } \ } #endif \ No newline at end of file diff --git a/src/extensions/drcSerial.cc b/src/extensions/drcSerial.cc index 02eb38b..1a7bf1a 100644 --- a/src/extensions/drcSerial.cc +++ b/src/extensions/drcSerial.cc @@ -8,7 +8,7 @@ DECLARE(drcSetupSerial); // Description : https://projects.drogon.net/drogon-remote-control/drc-protocol-arduino/ IMPLEMENT(drcSetupSerial) { - SCOPE_START(); + SCOPE_OPEN(); SET_ARGUMENT_NAME(0, pinBase); SET_ARGUMENT_NAME(1, numPins); @@ -27,7 +27,7 @@ IMPLEMENT(drcSetupSerial) { String::AsciiValue device(GET_ARGUMENT_AS_STRING(2)); int baudrate = GET_ARGUMENT_AS_INT32(3); - int res = ::drcSetupSerial(pinBase, numPins, device, baudrate); + int res = ::drcSetupSerial(pinBase, numPins, *device, baudrate); SCOPE_CLOSE(INT32(res)); } From d5375379d5ccf9e2fd6251ed82795ae3f9452057 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 3 Jul 2014 21:43:39 +0200 Subject: [PATCH 24/64] Add all remaining extensions :) --- binding.gyp | 20 +++++++++++++-- src/addon.h | 8 ++++-- src/extensions/extensions.cc | 38 ++++++++++++++++++++++++++++ src/extensions/extensions.h | 8 ++++++ src/extensions/max31855.cc | 31 +++++++++++++++++++++++ src/extensions/max31855.h | 8 ++++++ src/extensions/max5322.cc | 32 ++++++++++++++++++++++++ src/extensions/max5322.h | 8 ++++++ src/extensions/mcp23008.cc | 29 ++++++++++++++++++++++ src/extensions/mcp23008.h | 8 ++++++ src/extensions/mcp23016.cc | 29 ++++++++++++++++++++++ src/extensions/mcp23016.h | 8 ++++++ src/extensions/mcp23017.cc | 29 ++++++++++++++++++++++ src/extensions/mcp23017.h | 8 ++++++ src/extensions/mcp23s08.cc | 37 +++++++++++++++++++++++++++ src/extensions/mcp23s08.h | 8 ++++++ src/extensions/mcp23s17.cc | 40 ++++++++++++++++++++++++++++++ src/extensions/mcp23s17.h | 8 ++++++ src/extensions/mcp3002.cc | 31 +++++++++++++++++++++++ src/extensions/mcp3002.h | 8 ++++++ src/extensions/mcp3004.cc | 31 +++++++++++++++++++++++ src/extensions/mcp3004.h | 8 ++++++ src/extensions/mcp3422.cc | 48 ++++++++++++++++++++++++++++++++++++ src/extensions/mcp3422.h | 8 ++++++ src/extensions/mcp4802.cc | 31 +++++++++++++++++++++++ src/extensions/mcp4802.h | 8 ++++++ src/extensions/pca9685.cc | 30 ++++++++++++++++++++++ src/extensions/pca9685.h | 8 ++++++ src/extensions/pcf8574.cc | 29 ++++++++++++++++++++++ src/extensions/pcf8574.h | 8 ++++++ src/extensions/pcf8591.cc | 29 ++++++++++++++++++++++ src/extensions/pcf8591.h | 8 ++++++ src/extensions/sn3218.cc | 26 +++++++++++++++++++ src/extensions/sn3218.h | 8 ++++++ src/extensions/sr595.cc | 38 ++++++++++++++++++++++++++++ src/extensions/sr595.h | 8 ++++++ src/softPwm.cc | 1 - src/softServo.cc | 1 - src/softTone.cc | 1 - src/wiringPiI2C.cc | 1 - src/wiringPiISR.cc | 2 +- src/wiringPiSPI.cc | 1 - src/wiringSerial.cc | 1 - src/wiringShift.cc | 1 - src/wpi.cc | 2 +- src/wpi.h | 2 +- 46 files changed, 721 insertions(+), 14 deletions(-) create mode 100644 src/extensions/extensions.cc create mode 100644 src/extensions/extensions.h create mode 100644 src/extensions/max31855.cc create mode 100644 src/extensions/max31855.h create mode 100644 src/extensions/max5322.cc create mode 100644 src/extensions/max5322.h create mode 100644 src/extensions/mcp23008.cc create mode 100644 src/extensions/mcp23008.h create mode 100644 src/extensions/mcp23016.cc create mode 100644 src/extensions/mcp23016.h create mode 100644 src/extensions/mcp23017.cc create mode 100644 src/extensions/mcp23017.h create mode 100644 src/extensions/mcp23s08.cc create mode 100644 src/extensions/mcp23s08.h create mode 100644 src/extensions/mcp23s17.cc create mode 100644 src/extensions/mcp23s17.h create mode 100644 src/extensions/mcp3002.cc create mode 100644 src/extensions/mcp3002.h create mode 100644 src/extensions/mcp3004.cc create mode 100644 src/extensions/mcp3004.h create mode 100644 src/extensions/mcp3422.cc create mode 100644 src/extensions/mcp3422.h create mode 100644 src/extensions/mcp4802.cc create mode 100644 src/extensions/mcp4802.h create mode 100644 src/extensions/pca9685.cc create mode 100644 src/extensions/pca9685.h create mode 100644 src/extensions/pcf8574.cc create mode 100644 src/extensions/pcf8574.h create mode 100644 src/extensions/pcf8591.cc create mode 100644 src/extensions/pcf8591.h create mode 100644 src/extensions/sn3218.cc create mode 100644 src/extensions/sn3218.h create mode 100644 src/extensions/sr595.cc create mode 100644 src/extensions/sr595.h diff --git a/binding.gyp b/binding.gyp index 658f512..9e3f67e 100644 --- a/binding.gyp +++ b/binding.gyp @@ -12,10 +12,26 @@ 'src/wiringSerial.cc', 'src/wiringShift.cc', 'src/wiringPiISR.cc', + 'src/wpi.cc', + 'src/extensions/extensions.cc', 'src/extensions/drcSerial.cc', - - 'src/wpi.cc' + 'src/extensions/max5322.cc', + 'src/extensions/max31855.cc', + 'src/extensions/mcp23s08.cc', + 'src/extensions/mcp23s17.cc', + 'src/extensions/mcp3002.cc', + 'src/extensions/mcp3004.cc', + 'src/extensions/mcp3422.cc', + 'src/extensions/mcp4802.cc', + 'src/extensions/mcp23008.cc', + 'src/extensions/mcp23016.cc', + 'src/extensions/mcp23017.cc', + 'src/extensions/pcf8574.cc', + 'src/extensions/pcf8591.cc', + 'src/extensions/sn3218.cc', + 'src/extensions/sr595.cc', + 'src/extensions/pca9685.cc' ], 'include_dirs': [ 'wiringpi/wiringPi' diff --git a/src/addon.h b/src/addon.h index 5fac119..414a4cf 100644 --- a/src/addon.h +++ b/src/addon.h @@ -4,8 +4,7 @@ #include #include #include - #include - #include + #include #include //#include @@ -162,5 +161,10 @@ THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ } \ } + + #define CHECK_ARGUMENT_IN_RANGE(id, value, min, max) \ + if (value < min || value > max) { \ + THROW_ERROR("%s: arguments['%s'] => inRange(%i, [%i, %i]) === false", __func__, GET_ARGUMENT_NAME(id), value, min, max); \ + } #endif \ No newline at end of file diff --git a/src/extensions/extensions.cc b/src/extensions/extensions.cc new file mode 100644 index 0000000..2f3002e --- /dev/null +++ b/src/extensions/extensions.cc @@ -0,0 +1,38 @@ +#include "extensions.h" + +#include "drcSerial.h" +#include "max5322.h" +#include "max31855.h" +#include "mcp23s08.h" +#include "mcp23s17.h" +#include "mcp3002.h" +#include "mcp3004.h" +#include "mcp3422.h" +#include "mcp4802.h" +#include "mcp23008.h" +#include "mcp23016.h" +#include "mcp23017.h" +#include "pcf8574.h" +#include "pcf8591.h" +#include "sn3218.h" +#include "sr595.h" +#include "pca9685.h" + +IMPLEMENT_EXPORT_INIT(extensions) { + INIT(drcSerial); + INIT(max5322); + INIT(max31855); + INIT(mcp23s08); + INIT(mcp23s17); + INIT(mcp3002); + INIT(mcp3004); + INIT(mcp3422); + INIT(mcp4802); + INIT(mcp23008); + INIT(mcp23016); + INIT(mcp23017); + INIT(pcf8574); + INIT(pcf8591); + INIT(sr595); + INIT(pca9685); +} \ No newline at end of file diff --git a/src/extensions/extensions.h b/src/extensions/extensions.h new file mode 100644 index 0000000..c2a90a4 --- /dev/null +++ b/src/extensions/extensions.h @@ -0,0 +1,8 @@ +#ifndef _WPI_EXTENSIONS_H_ +#define _WPI_EXTENSIONS_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(extensions); + +#endif \ No newline at end of file diff --git a/src/extensions/max31855.cc b/src/extensions/max31855.cc new file mode 100644 index 0000000..65a3f8c --- /dev/null +++ b/src/extensions/max31855.cc @@ -0,0 +1,31 @@ +#include "max31855.h" +#include + +DECLARE(max31855Setup); + +// Func : int max31855Setup(int pinBase, int spiChannel) + +IMPLEMENT(max31855Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::max31855Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(max31855) { + EXPORT_FUNCTION(max31855Setup); +} \ No newline at end of file diff --git a/src/extensions/max31855.h b/src/extensions/max31855.h new file mode 100644 index 0000000..caebaeb --- /dev/null +++ b/src/extensions/max31855.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MAX31855_H_ +#define _WPI_MAX31855_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(max31855); + +#endif \ No newline at end of file diff --git a/src/extensions/max5322.cc b/src/extensions/max5322.cc new file mode 100644 index 0000000..9b945b4 --- /dev/null +++ b/src/extensions/max5322.cc @@ -0,0 +1,32 @@ +#include "max5322.h" +#include + +DECLARE(max5322Setup); + +// Func : int max5233Setup(int pinBase, int spiChannel) + +IMPLEMENT(max5322Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::max5322Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + + +IMPLEMENT_EXPORT_INIT(max5322) { + EXPORT_FUNCTION(max5322Setup); +} \ No newline at end of file diff --git a/src/extensions/max5322.h b/src/extensions/max5322.h new file mode 100644 index 0000000..912d267 --- /dev/null +++ b/src/extensions/max5322.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MAX5322_H_ +#define _WPI_MAX5322_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(max5322); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23008.cc b/src/extensions/mcp23008.cc new file mode 100644 index 0000000..f254d34 --- /dev/null +++ b/src/extensions/mcp23008.cc @@ -0,0 +1,29 @@ +#include "mcp23008.h" +#include + +DECLARE(mcp23008Setup); + +// Func : int mcp23008Setup(int pinBase, int i2cAddress) + +IMPLEMENT(mcp23008Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::mcp23008Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23008) { + EXPORT_FUNCTION(mcp23008Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23008.h b/src/extensions/mcp23008.h new file mode 100644 index 0000000..5297854 --- /dev/null +++ b/src/extensions/mcp23008.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23008_H_ +#define _WPI_MCP23008_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23008); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23016.cc b/src/extensions/mcp23016.cc new file mode 100644 index 0000000..46f2751 --- /dev/null +++ b/src/extensions/mcp23016.cc @@ -0,0 +1,29 @@ +#include "mcp23016.h" +#include + +DECLARE(mcp23016Setup); + +// Func : int mcp23016Setup(int pinBase, int i2cAddress) + +IMPLEMENT(mcp23016Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::mcp23016Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23016) { + EXPORT_FUNCTION(mcp23016Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23016.h b/src/extensions/mcp23016.h new file mode 100644 index 0000000..64a6761 --- /dev/null +++ b/src/extensions/mcp23016.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23016_H_ +#define _WPI_MCP23016_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23016); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23017.cc b/src/extensions/mcp23017.cc new file mode 100644 index 0000000..aebdc8b --- /dev/null +++ b/src/extensions/mcp23017.cc @@ -0,0 +1,29 @@ +#include "mcp23017.h" +#include + +DECLARE(mcp23017Setup); + +// Func : int mcp23017Setup(int pinBase, int i2cAddress) + +IMPLEMENT(mcp23017Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::mcp23017Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23017) { + EXPORT_FUNCTION(mcp23017Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23017.h b/src/extensions/mcp23017.h new file mode 100644 index 0000000..4ca67ff --- /dev/null +++ b/src/extensions/mcp23017.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23017_H_ +#define _WPI_MCP23017_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23017); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23s08.cc b/src/extensions/mcp23s08.cc new file mode 100644 index 0000000..94bd38f --- /dev/null +++ b/src/extensions/mcp23s08.cc @@ -0,0 +1,37 @@ +#include "mcp23s08.h" +#include + +DECLARE(mcp23s08Setup); + +// Func int mcp23s08Setup(const int pinBase, const int spiChannel, const int devId) + +IMPLEMENT(mcp23s08Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + SET_ARGUMENT_NAME(2, devId); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + int devId = GET_ARGUMENT_AS_INT32(2); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + //MCP23S08 3bits addressing + CHECK_ARGUMENT_IN_RANGE(2, devId, 0, 7); + + int res = ::mcp23s08Setup(pinBase, spiChannel, devId); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23s08) { + EXPORT_FUNCTION(mcp23s08Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23s08.h b/src/extensions/mcp23s08.h new file mode 100644 index 0000000..2eabae4 --- /dev/null +++ b/src/extensions/mcp23s08.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23S08_H_ +#define _WPI_MCP23S08_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23s08); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp23s17.cc b/src/extensions/mcp23s17.cc new file mode 100644 index 0000000..3352812 --- /dev/null +++ b/src/extensions/mcp23s17.cc @@ -0,0 +1,40 @@ +#include "mcp23s17.h" +#include + +DECLARE(mcp23s17Setup); + +// Func : int mcp23s17Setup(int pinBase, int spiPort, int devId) +// Description : Initialise libWiringPi to be used with MCP23S17 +// pinBase is any number above 64 that doesn’t clash with any other wiringPi expansion module, +// spiPort is 0 or 1 for one of the two SPI ports on the Pi and devId is the ID of that MCP23s17 on the SPI port. + +IMPLEMENT(mcp23s17Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + SET_ARGUMENT_NAME(2, devId); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + int devId = GET_ARGUMENT_AS_INT32(2); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + //MCP23S17 3bits addressing + CHECK_ARGUMENT_IN_RANGE(2, devId, 0, 7); + + int res = ::mcp23s17Setup(pinBase, spiChannel, devId); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp23s17) { + EXPORT_FUNCTION(mcp23s17Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp23s17.h b/src/extensions/mcp23s17.h new file mode 100644 index 0000000..9e71198 --- /dev/null +++ b/src/extensions/mcp23s17.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP23S17_H_ +#define _WPI_MCP23S17_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp23s17); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp3002.cc b/src/extensions/mcp3002.cc new file mode 100644 index 0000000..1332690 --- /dev/null +++ b/src/extensions/mcp3002.cc @@ -0,0 +1,31 @@ +#include "mcp3002.h" +#include + +DECLARE(mcp3002Setup); + +// Func : int mcp3002Setup(int pinBase, int spiChannel) + +IMPLEMENT(mcp3002Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::mcp3002Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp3002) { + EXPORT_FUNCTION(mcp3002Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp3002.h b/src/extensions/mcp3002.h new file mode 100644 index 0000000..242c3b7 --- /dev/null +++ b/src/extensions/mcp3002.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP3002_H_ +#define _WPI_MCP3002_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp3002); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp3004.cc b/src/extensions/mcp3004.cc new file mode 100644 index 0000000..78bbc60 --- /dev/null +++ b/src/extensions/mcp3004.cc @@ -0,0 +1,31 @@ +#include "mcp3004.h" +#include + +DECLARE(mcp3004Setup); + +// Func : int mcp3004Setup(int pinBase, int spiChannel) + +IMPLEMENT(mcp3004Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::mcp3004Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp3004) { + EXPORT_FUNCTION(mcp3004Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp3004.h b/src/extensions/mcp3004.h new file mode 100644 index 0000000..176ca0b --- /dev/null +++ b/src/extensions/mcp3004.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP3004_H_ +#define _WPI_MCP3004_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp3004); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp3422.cc b/src/extensions/mcp3422.cc new file mode 100644 index 0000000..30211a0 --- /dev/null +++ b/src/extensions/mcp3422.cc @@ -0,0 +1,48 @@ +#include "mcp3422.h" +#include + +DECLARE(mcp3422Setup); + +// Func : int mcp3422Setup(int pinBase, int i2cAddress, int sampleRate, int gain) + +IMPLEMENT(mcp3422Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + SET_ARGUMENT_NAME(2, sampleRate); + SET_ARGUMENT_NAME(3, gain); + + CHECK_ARGUMENTS_LENGTH_EQUAL(4); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + int sampleRate = GET_ARGUMENT_AS_INT32(2); + int gain = GET_ARGUMENT_AS_INT32(3); + + CHECK_ARGUMENT_IN_INTS(2, sampleRate, (MCP3422_SR_3_75, MCP3422_SR_15, MCP3422_SR_60, MCP3422_SR_240)); + CHECK_ARGUMENT_IN_INTS(3, gain, (MCP3422_GAIN_1, MCP3422_GAIN_2, MCP3422_GAIN_4, MCP3422_GAIN_8)); + + int res = ::mcp3422Setup(pinBase, i2cAddress, sampleRate, gain); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp3422) { + EXPORT_FUNCTION(mcp3422Setup); + + EXPORT_CONSTANT_INT(MCP3422_SR_3_75); + EXPORT_CONSTANT_INT(MCP3422_SR_15); + EXPORT_CONSTANT_INT(MCP3422_SR_60); + EXPORT_CONSTANT_INT(MCP3422_SR_240); + + EXPORT_CONSTANT_INT(MCP3422_GAIN_1); + EXPORT_CONSTANT_INT(MCP3422_GAIN_2); + EXPORT_CONSTANT_INT(MCP3422_GAIN_4); + EXPORT_CONSTANT_INT(MCP3422_GAIN_8); +} \ No newline at end of file diff --git a/src/extensions/mcp3422.h b/src/extensions/mcp3422.h new file mode 100644 index 0000000..57bfe74 --- /dev/null +++ b/src/extensions/mcp3422.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP3422_H_ +#define _WPI_MCP3422_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp3422); + +#endif \ No newline at end of file diff --git a/src/extensions/mcp4802.cc b/src/extensions/mcp4802.cc new file mode 100644 index 0000000..f12732e --- /dev/null +++ b/src/extensions/mcp4802.cc @@ -0,0 +1,31 @@ +#include "mcp4802.h" +#include + +DECLARE(mcp4802Setup); + +// Func : int mcp4802Setup(int pinBase, int spiChannel) + +IMPLEMENT(mcp4802Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, spiChannel); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int spiChannel = GET_ARGUMENT_AS_INT32(1); + + CHECK_ARGUMENT_IN_INTS(1, spiChannel, (0, 1)); + + int res = ::mcp4802Setup(pinBase, spiChannel); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(mcp4802) { + EXPORT_FUNCTION(mcp4802Setup); +} \ No newline at end of file diff --git a/src/extensions/mcp4802.h b/src/extensions/mcp4802.h new file mode 100644 index 0000000..a8d887f --- /dev/null +++ b/src/extensions/mcp4802.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MCP4802_H_ +#define _WPI_MCP4802_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(mcp4802); + +#endif \ No newline at end of file diff --git a/src/extensions/pca9685.cc b/src/extensions/pca9685.cc new file mode 100644 index 0000000..309347c --- /dev/null +++ b/src/extensions/pca9685.cc @@ -0,0 +1,30 @@ +#include "pca9685.h" +#include + +DECLARE(pca9685Setup); + +IMPLEMENT(pca9685Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + SET_ARGUMENT_NAME(2, frequency); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + int freq = GET_ARGUMENT_AS_INT32(2); + + int res = ::pca9685Setup(pinBase, i2cAddress, freq); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(pca9685) { + EXPORT_FUNCTION(pca9685Setup); +} \ No newline at end of file diff --git a/src/extensions/pca9685.h b/src/extensions/pca9685.h new file mode 100644 index 0000000..bbf4dc3 --- /dev/null +++ b/src/extensions/pca9685.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PCA9685_H_ +#define _WPI_PCA9685_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(pca9685); + +#endif \ No newline at end of file diff --git a/src/extensions/pcf8574.cc b/src/extensions/pcf8574.cc new file mode 100644 index 0000000..7e10b5b --- /dev/null +++ b/src/extensions/pcf8574.cc @@ -0,0 +1,29 @@ +#include "pcf8574.h" +#include + +DECLARE(pcf8574Setup); + +// Func : int pcf8574Setup(const int pinBase, const int i2cAddress) + +IMPLEMENT(pcf8574Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::pcf8574Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(pcf8574) { + EXPORT_FUNCTION(pcf8574Setup); +} \ No newline at end of file diff --git a/src/extensions/pcf8574.h b/src/extensions/pcf8574.h new file mode 100644 index 0000000..53d42a2 --- /dev/null +++ b/src/extensions/pcf8574.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PCF8574_H_ +#define _WPI_PCF8574_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(pcf8574); + +#endif \ No newline at end of file diff --git a/src/extensions/pcf8591.cc b/src/extensions/pcf8591.cc new file mode 100644 index 0000000..fd9744a --- /dev/null +++ b/src/extensions/pcf8591.cc @@ -0,0 +1,29 @@ +#include "pcf8591.h" +#include + +DECLARE(pcf8591Setup); + +// Func : int pcf8591Setup(const int pinBase, const int i2cAddress) + +IMPLEMENT(pcf8591Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + + int res = ::pcf8591Setup(pinBase, i2cAddress); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(pcf8591) { + EXPORT_FUNCTION(pcf8591Setup); +} \ No newline at end of file diff --git a/src/extensions/pcf8591.h b/src/extensions/pcf8591.h new file mode 100644 index 0000000..2cfa1d9 --- /dev/null +++ b/src/extensions/pcf8591.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PCF8591_H_ +#define _WPI_PCF8591_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(pcf8591); + +#endif \ No newline at end of file diff --git a/src/extensions/sn3218.cc b/src/extensions/sn3218.cc new file mode 100644 index 0000000..d125cc4 --- /dev/null +++ b/src/extensions/sn3218.cc @@ -0,0 +1,26 @@ +#include "sn3218.h" +#include + +DECLARE(sn3218Setup); + +// Func : int sn3128Setup(int pinBase) + +IMPLEMENT(sn3218Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + + int res = ::sn3218Setup(pinBase); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(sn3218) { + EXPORT_FUNCTION(sn3218Setup); +} \ No newline at end of file diff --git a/src/extensions/sn3218.h b/src/extensions/sn3218.h new file mode 100644 index 0000000..a1ce2f4 --- /dev/null +++ b/src/extensions/sn3218.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SN3218_H_ +#define _WPI_SN3218_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(sn3218); + +#endif \ No newline at end of file diff --git a/src/extensions/sr595.cc b/src/extensions/sr595.cc new file mode 100644 index 0000000..0db70fd --- /dev/null +++ b/src/extensions/sr595.cc @@ -0,0 +1,38 @@ +#include "sr595.h" +#include + +DECLARE(sr595Setup); + +// Func : int sr595Setup(const int pinBase, const int numPins, const int dataPin, const int clockPin, const int latchPin) + +IMPLEMENT(sr595Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, numPins); + SET_ARGUMENT_NAME(2, dataPin); + SET_ARGUMENT_NAME(3, clockPin); + SET_ARGUMENT_NAME(4, latchPin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(5); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int numPins = GET_ARGUMENT_AS_INT32(1); + int dataPin = GET_ARGUMENT_AS_INT32(2); + int clockPin = GET_ARGUMENT_AS_INT32(3); + int latchPin = GET_ARGUMENT_AS_INT32(4); + + int res = ::sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(sr595) { + EXPORT_FUNCTION(sr595Setup); +} \ No newline at end of file diff --git a/src/extensions/sr595.h b/src/extensions/sr595.h new file mode 100644 index 0000000..e25bfb6 --- /dev/null +++ b/src/extensions/sr595.h @@ -0,0 +1,8 @@ +#ifndef _WPI_SR595_H_ +#define _WPI_SR595_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(sr595); + +#endif \ No newline at end of file diff --git a/src/softPwm.cc b/src/softPwm.cc index c602caf..a9cdd04 100644 --- a/src/softPwm.cc +++ b/src/softPwm.cc @@ -1,5 +1,4 @@ #include "softPwm.h" -#include #include DECLARE(softPwmCreate); diff --git a/src/softServo.cc b/src/softServo.cc index 60bdc5a..f082efb 100644 --- a/src/softServo.cc +++ b/src/softServo.cc @@ -1,5 +1,4 @@ #include "softServo.h" -#include #include DECLARE(softServoWrite); diff --git a/src/softTone.cc b/src/softTone.cc index 48ab5b9..61999e3 100644 --- a/src/softTone.cc +++ b/src/softTone.cc @@ -1,5 +1,4 @@ #include "softTone.h" -#include #include DECLARE(softToneCreate); diff --git a/src/wiringPiI2C.cc b/src/wiringPiI2C.cc index e5e5481..38203be 100644 --- a/src/wiringPiI2C.cc +++ b/src/wiringPiI2C.cc @@ -1,5 +1,4 @@ #include "wiringPiI2C.h" -#include #include DECLARE(wiringPiI2CRead); diff --git a/src/wiringPiISR.cc b/src/wiringPiISR.cc index 12bad63..101c43d 100644 --- a/src/wiringPiISR.cc +++ b/src/wiringPiISR.cc @@ -1,6 +1,6 @@ #include "wiringPiISR.h" -#include #include +#include #include using namespace v8; diff --git a/src/wiringPiSPI.cc b/src/wiringPiSPI.cc index fcde1c0..a8210f6 100644 --- a/src/wiringPiSPI.cc +++ b/src/wiringPiSPI.cc @@ -1,5 +1,4 @@ #include "wiringPiSPI.h" -#include #include DECLARE(wiringPiSPIGetFd); diff --git a/src/wiringSerial.cc b/src/wiringSerial.cc index 51b8af1..55360f6 100644 --- a/src/wiringSerial.cc +++ b/src/wiringSerial.cc @@ -1,5 +1,4 @@ #include "wiringSerial.h" -#include #include DECLARE(serialOpen); diff --git a/src/wiringShift.cc b/src/wiringShift.cc index 4d54780..4e34978 100644 --- a/src/wiringShift.cc +++ b/src/wiringShift.cc @@ -1,5 +1,4 @@ #include "wiringShift.h" -#include #include DECLARE(shiftIn); diff --git a/src/wpi.cc b/src/wpi.cc index 7b51d86..306d9c1 100644 --- a/src/wpi.cc +++ b/src/wpi.cc @@ -11,7 +11,7 @@ NODE_MODULE_INIT() { INIT(wiringShift); INIT(wiringPiISR); - INIT(drcSerial); + INIT(extensions); } NODE_MODULE_DECLARE(wiringPi); \ No newline at end of file diff --git a/src/wpi.h b/src/wpi.h index 43bad4e..a61262b 100644 --- a/src/wpi.h +++ b/src/wpi.h @@ -11,6 +11,6 @@ #include "wiringShift.h" #include "wiringPiISR.h" - #include "extensions/drcSerial.h" + #include "extensions/extensions.h" #endif \ No newline at end of file From 37c77210e9aff7be6259dbb5e1a1b329cedc7326 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 3 Jul 2014 23:29:42 +0200 Subject: [PATCH 25/64] fix some bugs --- install.sh | 22 +++++++++++----------- src/addon.h | 3 ++- src/wiringPi.cc | 1 + 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/install.sh b/install.sh index d75b0b2..8985f38 100644 --- a/install.sh +++ b/install.sh @@ -40,38 +40,38 @@ rm ./install.log 2>/dev/null 1>&2 echo -n "Cloning libWiringPi ... " rm -Rf ./wiringpi 2>/dev/null 1>&2 -git clone https://github.com/nekuz0r/wiringpi.git 2>./install.log 1>&2 +git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 check_git_clone echo "done." echo -n "Making libWiringPi ... " cd ./wiringpi/wiringPi/ -make clean 2>../../install.log 1>&2 -make static 2>../../install.log 1>&2 +make clean >> ../../install.log 2>&1 +make static >> ../../install.log 2>&1 check_make_ok "libWiringPi" 1 cd ../../ echo "done." cd ./wiringpi/gpio/ echo -n "Unistalling gpio utility ... " -sudo make uninstall 2>../../install.log 1>&2 +sudo make uninstall >> ../../install.log 2>&1 echo "done." echo -n "Making gpio utility ... " -make clean 2>../../install.log 1>&2 -make 2>../../install.log 1>&2 -check_make_ok "gpio utility" +make clean >> ../../install.log 2>&1 +make >> ../../install.log 2>&1 +check_make_ok "gpio utility" 0 echo "done." echo -n "Installing gpio utility ... " -sudo make install 2>../../install.log 1>&2 -check_make_ok "gpio utility" +sudo make install >> ../../install.log 2>&1 +check_make_ok "gpio utility" 0 cd ../../ echo "done." echo -n "Making wiring-pi ... " -node-gyp rebuild 2>./install.log 1>&2 +node-gyp rebuild 2>&1 | tee -a ./install.log check_make_ok "wiring-pi" 1 echo "done." -echo "Enjoy !" \ No newline at end of file +echo "Enjoy !" diff --git a/src/addon.h b/src/addon.h index 414a4cf..97e0ec7 100644 --- a/src/addon.h +++ b/src/addon.h @@ -6,6 +6,7 @@ #include #include #include + #include //#include using namespace v8; @@ -167,4 +168,4 @@ THROW_ERROR("%s: arguments['%s'] => inRange(%i, [%i, %i]) === false", __func__, GET_ARGUMENT_NAME(id), value, min, max); \ } -#endif \ No newline at end of file +#endif diff --git a/src/wiringPi.cc b/src/wiringPi.cc index 2860d54..16c2506 100644 --- a/src/wiringPi.cc +++ b/src/wiringPi.cc @@ -1,5 +1,6 @@ #include "wiringPi.h" #include +#include // Setup DECLARE(setup); From 5310c7218d800189ad52353a234de99a7dd338bf Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 09:48:04 +0200 Subject: [PATCH 26/64] Optimizing compilation time --- binding.gyp | 2 + src/addon.cc | 31 ++++++++++++ src/addon.h | 120 +++++++++++++++++---------------------------- src/wiringPiISR.cc | 1 + src/wpi.cc | 1 + 5 files changed, 81 insertions(+), 74 deletions(-) create mode 100644 src/addon.cc diff --git a/binding.gyp b/binding.gyp index 9e3f67e..43d8d9a 100644 --- a/binding.gyp +++ b/binding.gyp @@ -3,6 +3,8 @@ { 'target_name': 'wiringPi', 'sources': [ + 'src/addon.cc', + 'src/wiringPi.cc', 'src/softPwm.cc', 'src/softServo.cc', diff --git a/src/addon.cc b/src/addon.cc new file mode 100644 index 0000000..ab1dec3 --- /dev/null +++ b/src/addon.cc @@ -0,0 +1,31 @@ +#include "addon.h" +#include +#include + +bool find_string(const char* string, const char* array[], size_t s) { + for (size_t i = 0; i < s; i++) { + if (!strcasecmp(string, array[i])) { + return true; + } + } + return false; +} + +bool find_int(const int value, const int array[], size_t s) { + for (size_t i = 0; i < s; i++) { + if (value == array[i]) { + return true; + } + } + return false; +} + +void throw_error(const char* format, ...) { + char buffer[256]; + va_list args; + va_start(args, format); + vsnprintf(buffer, 156, format, args); + va_end(args); + + v8::ThrowException(v8::Exception::Error(v8::String::New(buffer))); +} \ No newline at end of file diff --git a/src/addon.h b/src/addon.h index 97e0ec7..ce3ed9e 100644 --- a/src/addon.h +++ b/src/addon.h @@ -1,106 +1,88 @@ #ifndef _ADDON_H_ #define _ADDON_H_ - - #include - #include + #include - #include - #include - #include - //#include using namespace v8; - template - struct type_of_size { typedef char type[N]; }; - - template - char (&sizeof_array_helper(T(&)[size]))[size]; - - #define sizeof_array(array) sizeof(sizeof_array_helper(array)) - - template - void ThrowError(T func, const char* format, ...) { - char buffer[256]; - va_list args; - va_start(args, format); - vsnprintf(buffer, 156, format, args); - va_end(args); - - ThrowException(func(String::New(buffer))); + // We don't want to include the whole node headers :) + namespace node { + namespace Buffer { + bool HasInstance(v8::Handle val); + bool HasInstance(v8::Handle val); + char* Data(v8::Handle val); + char* Data(v8::Handle val); + size_t Length(v8::Handle val); + size_t Length(v8::Handle val); + } } - - /*template - bool isInList(T value, std::initializer_list values) { - return !(std::find(values.begin(), values.end(), value) == values.end()); - }*/ + + bool find_string(const char* string, const char* array[], size_t s); + bool find_int(const int value, const int array[], size_t s); + void throw_error(const char* fmt, ...); #define DECLARE(name) \ namespace nodemodule { \ - static Handle name(const Arguments& args); \ + static v8::Handle name(const v8::Arguments& args); \ } #define IMPLEMENT(name) \ - Handle nodemodule::name(const Arguments& args) + v8::Handle nodemodule::name(const v8::Arguments& args) #define EXPORT_FUNCTION(name) \ - target->Set(String::NewSymbol(#name), \ - FunctionTemplate::New(nodemodule::name)->GetFunction()) + target->Set(v8::String::NewSymbol(#name), \ + v8::FunctionTemplate::New(nodemodule::name)->GetFunction()) #define EXPORT_CONSTANT_INT(name) \ - target->Set(String::NewSymbol(#name), \ - Int32::New(name), static_cast(ReadOnly | DontDelete)); + target->Set(v8::String::NewSymbol(#name), \ + v8::Int32::New(name), static_cast(v8::ReadOnly | v8::DontDelete)); #define EXPORT_CONSTANT_STRING(name) \ - target->Set(String::NewSymbol(#name), \ - String::New(name), static_cast(ReadOnly | DontDelete)); + target->Set(v8::String::NewSymbol(#name), \ + v8::String::New(name), static_cast(v8::ReadOnly | v8::DontDelete)); #define EXPORT_CONSTANT_INT_ARRAY(name, array, length) \ { \ - Local arr = Array::New(); \ + v8::Local arr = v8::Array::New(); \ for (int i = 0; i < length; i++) { \ - arr->Set(i, INT32(array[i])); \ + arr->Set(i, v8::Int32::New(array[i])); \ } \ - target->Set(String::NewSymbol(#name), arr, static_cast(ReadOnly | DontDelete)); \ + target->Set(v8::String::NewSymbol(#name), arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ } #define EXPORT_CONSTANT_STRING_ARRAY(name, array, length) \ { \ - Local arr = Array::New(); \ + v8::Local arr = v8::Array::New(); \ for (int i = 0; i < length; i++) { \ - arr->Set(i, STRING(array[i])); \ + arr->Set(i, v8::Int32::New(array[i])); \ } \ - target->Set(String::NewSymbol(#name), arr, static_cast(ReadOnly | DontDelete)); \ + target->Set(v8::String::NewSymbol(#name), arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ } #define NODE_MODULE_INIT() \ namespace nodemodule { \ - void init(Handle target); \ + void init(v8::Handle target); \ } \ - void nodemodule::init(Handle target) + void nodemodule::init(v8::Handle target) #define NODE_MODULE_DECLARE(name) NODE_MODULE(name, nodemodule::init) - #define IMPLEMENT_EXPORT_INIT(name) void nodemodule::init##name(Handle target) + #define IMPLEMENT_EXPORT_INIT(name) void nodemodule::init##name(v8::Handle target) #define DECLARE_EXPORT_INIT(name) \ namespace nodemodule { \ - void init##name(Handle target); \ + void init##name(v8::Handle target); \ } #define INIT(name) nodemodule::init##name(target); - #define SCOPE_OPEN() HandleScope scope + #define SCOPE_OPEN() v8::HandleScope scope #define SCOPE_CLOSE(obj) return scope.Close(obj) - #define UNDEFINED() Undefined() - #define INT32(v) Int32::New(v) - #define UINT32(v) Uint32::New(v) - #define STRING(v) String::New(v) + #define UNDEFINED() v8::Undefined() + #define INT32(v) v8::Int32::New(v) + #define UINT32(v) v8::Uint32::New(v) + #define STRING(v) v8::String::New(v) #define THROW_ERROR(fmt, ...) \ - ThrowError(Exception::Error, fmt, __VA_ARGS__); \ - SCOPE_CLOSE(UNDEFINED()) - - #define THROW_TYPE_ERROR(fmt, ...) \ - ThrowError(Exception::TypeError, fmt, __VA_ARGS__); \ + throw_error(fmt, __VA_ARGS__); \ SCOPE_CLOSE(UNDEFINED()) #define SET_ARGUMENT_NAME(id, name) static const char* arg##id = #name @@ -133,32 +115,22 @@ #define GET_ARGUMENT_AS_UINT32(id) GET_ARGUMENT_AS_TYPE(id, Uint32Value) #define GET_ARGUMENT_AS_NUMBER(id) GET_ARGUMENT_AS_TYPE(id, NumberValue) #define GET_ARGUMENT_AS_STRING(id) GET_ARGUMENT_AS_TYPE(id, ToString) - #define GET_ARGUMENT_AS_LOCAL_FUNCTION(id) Local::Cast(args[id]) - #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) + #define GET_ARGUMENT_AS_LOCAL_FUNCTION(id) v8::Local::Cast(args[id]) + #define GET_ARGUMENT_AS_PERSISTENT_FUNCTION(id) v8::Persistent::New(GET_ARGUMENT_AS_LOCAL_FUNCTION(id)) #define LIST(...) { __VA_ARGS__ } - /*#define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ - if (!isInList(std::string(*value), LIST T)) { \ - THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ - } - - #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ - if (!isInList(value, LIST T)) { \ - THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ - }*/ - #define CHECK_ARGUMENT_IN_STRINGS(id, value, T) \ { \ - std::string strings[] = LIST T; \ - if (std::find(strings, strings + sizeof_array(strings), std::string(*value)) == strings + sizeof_array(strings)) { \ - THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), std::string(*value).c_str(), #T); \ + static const char* strings[] = LIST T; \ + if (!find_string(*value, strings, sizeof(strings) / sizeof(char*))) { \ + THROW_ERROR("%s: arguments['%s'] => (\"%s\" in %s) === false", __func__, GET_ARGUMENT_NAME(id), *value, #T); \ } \ } #define CHECK_ARGUMENT_IN_INTS(id, value, T) \ { \ - int ints[] = LIST T; \ - if (std::find(ints, ints + sizeof_array(ints), value) == ints + sizeof_array(ints)) { \ + static const int ints[] = LIST T; \ + if (!find_int(value, ints, sizeof(ints) / sizeof(int))) { \ THROW_ERROR("%s: arguments['%s'] => (%i in %s) === false", __func__, GET_ARGUMENT_NAME(id), value, #T); \ } \ } diff --git a/src/wiringPiISR.cc b/src/wiringPiISR.cc index 101c43d..0a43e01 100644 --- a/src/wiringPiISR.cc +++ b/src/wiringPiISR.cc @@ -2,6 +2,7 @@ #include #include #include +#include using namespace v8; diff --git a/src/wpi.cc b/src/wpi.cc index 306d9c1..491f874 100644 --- a/src/wpi.cc +++ b/src/wpi.cc @@ -1,4 +1,5 @@ #include "wpi.h" +#include NODE_MODULE_INIT() { INIT(wiringPi); From 29e814eb6fc0b47c77fe4a4130c681711c3f03f9 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 10:22:31 +0200 Subject: [PATCH 27/64] fix gpio compilation and installation --- install.sh | 11 +++++++++++ patchs/devLib_Makefile.patch | 19 +++++++++++++++++++ patchs/gpio_Makefile.patch | 20 ++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 patchs/devLib_Makefile.patch create mode 100644 patchs/gpio_Makefile.patch diff --git a/install.sh b/install.sh index 8985f38..df4ab18 100644 --- a/install.sh +++ b/install.sh @@ -44,6 +44,9 @@ git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 check_git_clone echo "done." +patch ./wiringpi/devLib/Makefile < ./patchs/devLib-Makefile.patch +patch ./wiringpi/gpio/Makefile < ./patchs/gpio-Makefile.patch + echo -n "Making libWiringPi ... " cd ./wiringpi/wiringPi/ make clean >> ../../install.log 2>&1 @@ -52,6 +55,14 @@ check_make_ok "libWiringPi" 1 cd ../../ echo "done." +cd ./wiringpi/devLib/ +echo -n "Making devLib ..." +make clean >> ../../install.log 2>&1 +make statis >> ../../install.log 2>&1 +check_make_ok "devLib" 0 +cd ../../ +echo "done." + cd ./wiringpi/gpio/ echo -n "Unistalling gpio utility ... " sudo make uninstall >> ../../install.log 2>&1 diff --git a/patchs/devLib_Makefile.patch b/patchs/devLib_Makefile.patch new file mode 100644 index 0000000..a4080ac --- /dev/null +++ b/patchs/devLib_Makefile.patch @@ -0,0 +1,19 @@ +--- Makefile_org 2014-07-04 09:48:18.000000000 +0200 ++++ Makefile 2014-07-04 10:12:15.000000000 +0200 +@@ -26,6 +26,7 @@ + VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) + DESTDIR=/usr + PREFIX=/local ++PWD=`PWD` + + STATIC=libwiringPiDev.a + DYNAMIC=libwiringPiDev.so.$(VERSION) +@@ -33,7 +34,7 @@ + #DEBUG = -g -O0 + DEBUG = -O2 + CC = gcc +-INCLUDE = -I. ++INCLUDE = -I. -I$(PWD)/../wiringPi + CFLAGS = $(DEBUG) -Wformat=2 -Wall $(INCLUDE) -Winline -pipe -fPIC + + LIBS = diff --git a/patchs/gpio_Makefile.patch b/patchs/gpio_Makefile.patch new file mode 100644 index 0000000..73cec63 --- /dev/null +++ b/patchs/gpio_Makefile.patch @@ -0,0 +1,20 @@ +--- Makefile_org 2014-07-04 09:58:05.000000000 +0200 ++++ Makefile 2014-07-04 10:13:01.000000000 +0200 +@@ -25,14 +25,15 @@ + + DESTDIR=/usr + PREFIX=/local ++PWD=`pwd` + + #DEBUG = -g -O0 + DEBUG = -O2 + CC = gcc +-INCLUDE = -I$(DESTDIR)$(PREFIX)/include ++INCLUDE = -I$(PWD)/../wiringPi -I($PWD)/../devLib + CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +-LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib ++LDFLAGS = -L$(PWD)/../wiringPi -L$(PWD)/../devLib + LIBS = -lwiringPi -lwiringPiDev -lpthread -lm + + # May not need to alter anything below this line From 45e225176a9392b936cd867db3453f244e950270 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 10:25:54 +0200 Subject: [PATCH 28/64] fix typos :/ --- install.sh | 6 +++--- patchs/gpio_Makefile.patch | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/install.sh b/install.sh index df4ab18..5d0e3bc 100644 --- a/install.sh +++ b/install.sh @@ -44,8 +44,8 @@ git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 check_git_clone echo "done." -patch ./wiringpi/devLib/Makefile < ./patchs/devLib-Makefile.patch -patch ./wiringpi/gpio/Makefile < ./patchs/gpio-Makefile.patch +patch ./wiringpi/devLib/Makefile < ./patchs/devLib_Makefile.patch +patch ./wiringpi/gpio/Makefile < ./patchs/gpio_Makefile.patch echo -n "Making libWiringPi ... " cd ./wiringpi/wiringPi/ @@ -58,7 +58,7 @@ echo "done." cd ./wiringpi/devLib/ echo -n "Making devLib ..." make clean >> ../../install.log 2>&1 -make statis >> ../../install.log 2>&1 +make static >> ../../install.log 2>&1 check_make_ok "devLib" 0 cd ../../ echo "done." diff --git a/patchs/gpio_Makefile.patch b/patchs/gpio_Makefile.patch index 73cec63..e50bfe0 100644 --- a/patchs/gpio_Makefile.patch +++ b/patchs/gpio_Makefile.patch @@ -10,7 +10,7 @@ DEBUG = -O2 CC = gcc -INCLUDE = -I$(DESTDIR)$(PREFIX)/include -+INCLUDE = -I$(PWD)/../wiringPi -I($PWD)/../devLib ++INCLUDE = -I$(PWD)/../wiringPi -I$(PWD)/../devLib CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib From e8ac5750bb6fff13e91ef0238fbb90e1daf6aaa4 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 10:28:14 +0200 Subject: [PATCH 29/64] typo again ... --- patchs/devLib_Makefile.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patchs/devLib_Makefile.patch b/patchs/devLib_Makefile.patch index a4080ac..8ae4125 100644 --- a/patchs/devLib_Makefile.patch +++ b/patchs/devLib_Makefile.patch @@ -4,7 +4,7 @@ VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) DESTDIR=/usr PREFIX=/local -+PWD=`PWD` ++PWD=`pwd` STATIC=libwiringPiDev.a DYNAMIC=libwiringPiDev.so.$(VERSION) From 602e4f2d7400275c5d45ccc9a114de7dba9ba11e Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 12:09:09 +0200 Subject: [PATCH 30/64] wiringPiISR callback remove pin Useless since callback is associated with interrupt on a given pin --- src/wiringPiISR.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wiringPiISR.cc b/src/wiringPiISR.cc index 0a43e01..710bee2 100644 --- a/src/wiringPiISR.cc +++ b/src/wiringPiISR.cc @@ -33,11 +33,10 @@ static void processInterrupt(uv_work_t* req, int status) { Persistent callback = interruptCallbackMapping[work->pin]; Local argv[] = { - Local::New(Int32::New(work->pin)), Local::New(Uint32::New(work->delta)) }; - callback->Call(Context::GetCurrent()->Global(), 2, argv); + callback->Call(Context::GetCurrent()->Global(), 1, argv); delete work; } From fdb6ece97c910d2d485a08e17a7967b72f4cf348 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 13:30:31 +0200 Subject: [PATCH 31/64] update changelog --- CHANGELOG.md | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29..02d809a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,119 @@ +# CHANGELOG + +## v2.0.0 *[not released yet]* + * **Update:** split source code (based on libWiringPi hierarchy) `nekuz0r` + * **Update:** better types check `nekuz0r` + * **Update:** better allowed values check `nekuz0r` + * **Update:** better error messages `nekuz0r` + * **Update:** documentation `nekuz0r` + * **Update:** constants are exported from c++ (ReadOnly | DontDelete) `nekuz0r` + * **Update:** setup() is exported from c++ `nekuz0r` + * NOTE: it no longer accepts empty parameter 'mode' (breaks backward compatibility) + * **Update:** wiringPiSPIDataRW now takes a buffer as second parameter (no thrid anymore) `nekuz0r` + * **Remove:** backward compatibility constants `nekuz0r` + * **Add:** wiringPiISR `nekuz0r` + * **Add:** CHANGELOG.md `nekuz0r` + * **Add:** wiringPiI2C support `nekuz0r` + * **Add:** wiring-pi install gpio utilty (required for interrupts) `nekuz0r` + +## v1.1.1 *[not released yet]* + * **Fix:** missing constant in pinModeCheck `nekuz0r` + * **Fix:** missing constant PI_MODEL_CM `nekuz0r` + * **Add:** serialPrintf (alias to serialPuts) `nekuz0r` + +## v1.1.0 *[Jun 30 2014]* + * **Update:** libWiringPi to [custom](nekuz0r-libWiringPi) v2.15 `nekuz0r` + * **Fix:** mcp3422 constants again `nekuz0r` + * **Remove:** precompiled dependencies `nekuz0r` + * **Add:** install script + * **Add:** pca9685 support `nekuz0r` + * **Add:** pulseIn `nekuz0r` + * **Add:** piBoardId `nekuz0r` + * **Add:** softPwmStop `nekuz0r` + * **Add:** softToneStop `nekuz0r` + * **Add:** SOFT_PWM_OUTPUT, SOFT_TONE_OUTPUT `nekuz0r` + * **Add:** PI_MODEL_A, PI_MODEL_B, PI_MODEL_CM `nekuz0r` + * **Add:** PI_MODEL_NAMES, PI_REVISION_NAMES, PI_COMPUTE_REVISION_NAMES `nekuz0r` + * **Add:** delay `nekuz0r` + * **Add:** delayMicroseconds `nekuz0r` + * **Add:** millis `nekuz0r` + * **Add:** micros `nekuz0r` + +## v1.0.2 *[Mar 18 2014]* + * Releasing as Open Open Source `eugeneware` + +## v1.0.1 *[Mar 18 2014]* + * **Fix:** mcp3422 constants `nekuz0r` + +## v1.0.0 *[Nov 29 2013]* + * **Update:** libWiringPi to v2.13 `nekuz0r` + * **Update:** examples (blink, pwm) `nekuz0r` + * **Update:** documentation `nekuz0r` + * **Add:** physical numbering scheme support (setup) `nekuz0r` + * **Add:** drcSerial support `nekuz0r` + * **Add:** max5322 support `nekuz0r` + * **Add:** mcp23s08 support `nekuz0r` + * **Add:** mcp3002 support `nekuz0r` + * **Add:** mcp3004 support `nekuz0r` + * **Add:** mcp3422 support `nekuz0r` + * **Add:** mcp4802 support `nekuz0r` + * **Add:** mcp23008 support `nekuz0r` + * **Add:** mcp23016 support `nekuz0r` + * **Add:** mcp23017 support `nekuz0r` + * **Add:** pcf8574 support `nekuz0r` + * **Add:** pcf8591 support `nekuz0r` + * **Add:** softPWM support `nekuz0r` + * **Add:** softServo support `nekuz0r` + * **Add:** softTone support `nekuz0r` + * **Add:** sr595 support `nekuz0r` + * **Add:** wiringPiSPI support `nekuz0r` + * **Add:** wiringPiSerial support (serialPrintf not implemented yet) `nekuz0r` + * **Add:** wiringPiShift support `nekuz0r` + * **Add:** pinModeAlt `nekuz0r` + * **Add:** analogRead `nekuz0r` + * **Add:** analogWrite `nekuz0r` + * **Add:** wpiPinToGpio `nekuz0r` + * **Add:** physPinToGpio `nekuz0r` + * **Add:** setPadDrive `nekuz0r` + * **Add:** getAlt `nekuz0r` + * **Add:** digitalWriteByte `nekuz0r` + * **Add:** pwmSetMode `nekuz0r` + * **Add:** gpioClockSet `nekuz0r` + * **Add:** LSBFIRST, MSBFIRST `nekuz0r` + * **Add:** MCP3422_SR_3_75, MCP3422_SR_15, MCP3422_SR_60, MCP3422_SR_240 `nekuz0r` + * **Add:** MCP3422_GAIN_1, MCP3422_GAIN_2, MCP3422_GAIN_4, MCP3422_GAIN_8 `nekuz0r` + * **Add:** WPI_MODE_PINS, WPI_MODE_GPIO, WPI_MODE_GPIO_SYS, WPI_MODE_GPIO_PHYS, WPI_MODE_PIFACE, WPI_MODE_UNINITIALIZED `nekuz0r` + * **Add:** INPUT, OUTPUT, PWM_OUTPUT, GPIO_CLOCK `nekuz0r` + * **Add:** PUD_OFF, PUD_UP, PUD_DOWN `nekuz0r` + * **Add:** PWM_MODE_MS, PWM_MODE, BAL `nekuz0r` + * **Add:** INT_EDGE_SETUP, INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH `nekuz0r` + +## v0.2.0 *[Nov 5 2013]* + * **Add:** pullUpDnControl `nekuz0r` + * **Add:** pull.PUD_OFF, pull.PUD_UP, pull.PUD_DOWN `nekuz0r` + +## v0.1.2 *[Aug 2 2013]* + * **Add:** HIGH, LOW `csquared` + * **Fix:** typo in exports.js `csquared` + * **Update:** README.md `csquared` + +## v0.1.1 *[Jun 11 2013]* + * **Add:** PWM example `eugeneware` + * **Fix:** pwmWrite export `eugeneware` + +## v0.1.0 *[Dec 20 2013]* + * Initial version `soarez` + * wiringPiSetup + * wiringPiSetupGpio + * wiringPiSetupSys + * piBoardRev + * pinMode + * digitalWrite + * digitalRead + * pwmSetRange + * pwmSetClock + * pwmWrite + * setup + * blink example + +[nekuz0r-libWiringPi]: https://github.com/nekuz0r/wiringpi/ \ No newline at end of file From 97e2ac1fc5dd9efcec1866e9b4d506724197be97 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 13:31:39 +0200 Subject: [PATCH 32/64] fix typo in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02d809a..78996d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ * **Add:** serialPrintf (alias to serialPuts) `nekuz0r` ## v1.1.0 *[Jun 30 2014]* - * **Update:** libWiringPi to [custom](nekuz0r-libWiringPi) v2.15 `nekuz0r` + * **Update:** libWiringPi to [custom][nekuz0r-libWiringPi] v2.15 `nekuz0r` * **Fix:** mcp3422 constants again `nekuz0r` * **Remove:** precompiled dependencies `nekuz0r` * **Add:** install script From 2df87c193e97a4b745aaf025fb5d0530f9fe3b48 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 15:27:05 +0200 Subject: [PATCH 33/64] devLib support --- CHANGELOG.md | 9 ++ binding.gyp | 13 +- src/devlib/devlib.cc | 21 +++ src/devlib/devlib.h | 8 ++ src/devlib/ds1302.cc | 176 +++++++++++++++++++++++++ src/devlib/ds1302.h | 8 ++ src/devlib/gertboard.cc | 24 ++++ src/devlib/gertboard.h | 8 ++ src/devlib/lcd.cc | 284 ++++++++++++++++++++++++++++++++++++++++ src/devlib/lcd.h | 8 ++ src/devlib/lcd128x64.cc | 0 src/devlib/lcd128x64.h | 0 src/devlib/maxdetect.cc | 58 ++++++++ src/devlib/maxdetect.h | 8 ++ src/devlib/piFace.cc | 24 ++++ src/devlib/piFace.h | 8 ++ src/devlib/piGlow.cc | 97 ++++++++++++++ src/devlib/piGlow.h | 8 ++ src/devlib/piNes.cc | 58 ++++++++ src/devlib/piNes.h | 8 ++ src/wpi.cc | 1 + src/wpi.h | 1 + 22 files changed, 829 insertions(+), 1 deletion(-) create mode 100644 src/devlib/devlib.cc create mode 100644 src/devlib/devlib.h create mode 100644 src/devlib/ds1302.cc create mode 100644 src/devlib/ds1302.h create mode 100644 src/devlib/gertboard.cc create mode 100644 src/devlib/gertboard.h create mode 100644 src/devlib/lcd.cc create mode 100644 src/devlib/lcd.h create mode 100644 src/devlib/lcd128x64.cc create mode 100644 src/devlib/lcd128x64.h create mode 100644 src/devlib/maxdetect.cc create mode 100644 src/devlib/maxdetect.h create mode 100644 src/devlib/piFace.cc create mode 100644 src/devlib/piFace.h create mode 100644 src/devlib/piGlow.cc create mode 100644 src/devlib/piGlow.h create mode 100644 src/devlib/piNes.cc create mode 100644 src/devlib/piNes.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 78996d4..b2eae93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,15 @@ * **Add:** CHANGELOG.md `nekuz0r` * **Add:** wiringPiI2C support `nekuz0r` * **Add:** wiring-pi install gpio utilty (required for interrupts) `nekuz0r` + * **Add:** ds1302 support `nekuz0r` + * **Add:** gertboard support `nekuz0r` + * **Add:** lcd support `nekuz0r` + * **Add:** lcd128x64 support `nekuz0r` + * **Add:** maxdetect support `nekuz0r` + * **Add:** piFace support `nekuz0r` + * **Add:** piGlow support `nekuz0r` + * **Add:** piNes support `nekuz0r` + * **Fictitious:** this release eats Pi(e)s :) ## v1.1.1 *[not released yet]* * **Fix:** missing constant in pinModeCheck `nekuz0r` diff --git a/binding.gyp b/binding.gyp index 43d8d9a..3541dfe 100644 --- a/binding.gyp +++ b/binding.gyp @@ -34,12 +34,23 @@ 'src/extensions/sn3218.cc', 'src/extensions/sr595.cc', 'src/extensions/pca9685.cc' + + 'src/devlib/devlib.cc', + 'src/devlib/ds1302.cc', + 'src/devlib/gertboard.cc', + 'src/devlib/lcd.cc', + 'src/devlib/lcd128x64.cc', + 'src/devlib/maxdetect.cc', + 'src/devlib/piFace.cc', + 'src/devlib/piGlow.cc', + 'src/devlib/piNes.cc', ], 'include_dirs': [ 'wiringpi/wiringPi' ], 'libraries': [ - ' + +DECLARE(ds1302rtcRead); +DECLARE(ds1302rtcWrite); +DECLARE(ds1302ramRead); +DECLARE(ds1302ramWrite); +DECLARE(ds1302clockRead); +DECLARE(ds1302clockWrite); +DECLARE(ds1302trickleCharge); +DECLARE(ds1302setup); + +// Func: unsigned int ds1302rtcRead (const int reg) +// Description: Reads the data to/from the RTC register + +IMPLEMENT(ds1302rtcRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, reg); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int reg = GET_ARGUMENT_AS_INT32(0); + + unsigned int res = ::ds1302rtcRead(reg); + + SCOPE_CLOSE(UINT32(res)); +} + +// Func: void ds1302rtcWrite (int reg, unsigned int data) +// Description: Writes the data to/from the RTC register + +IMPLEMENT(ds1302rtcWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, reg); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int reg = GET_ARGUMENT_AS_INT32(0); + unsigned int data = GET_ARGUMENT_AS_UINT32(1); + + ::ds1302rtcWrite(reg, data); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(ds1302ramRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, address); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int address = GET_ARGUMENT_AS_INT32(0); + + unsigned int res = ::ds1302ramRead(address); + + SCOPE_CLOSE(UINT32(res)); +} + +IMPLEMENT(ds1302ramWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, address); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + + int address = GET_ARGUMENT_AS_INT32(0); + unsigned int data = GET_ARGUMENT_AS_UINT32(1); + + ::ds1302ramWrite(address, data); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(ds1302clockRead) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int clockData[8]; + ::ds1302clockRead(clockData); + + v8::Local res = v8::Array::New(8); + for (int i = 0; i < 8; i++) { + res->Set(i, v8::Int32::New(clockData[i])); + } + + SCOPE_CLOSE(res); +} + +IMPLEMENT(ds1302clockWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, clockData); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_ARRAY(0); + CHECK_ARGUMENT_ARRAY_LENGTH(0, 8); + + v8::Local clockData = v8::Local::Cast(args[0]); + + int ar[8]; + for (int i = 0; i < 8; i++) { + ar[i] = clockData->Get(i)->Int32Value(); + } + + ::ds1302clockWrite(ar); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(ds1302trickleCharge) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, diodes); + SET_ARGUMENT_NAME(1, resistors); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int diodes = GET_ARGUMENT_AS_INT32(0); + int resistors = GET_ARGUMENT_AS_INT32(1); + + ::ds1302trickleCharge(diodes, resistors); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(ds1302setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, clockPin); + SET_ARGUMENT_NAME(1, dataPin); + SET_ARGUMENT_NAME(2, csPin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int clockPin = GET_ARGUMENT_AS_INT32(0); + int dataPin = GET_ARGUMENT_AS_INT32(1); + int csPin = GET_ARGUMENT_AS_INT32(2); + + ::ds1302setup(clockPin, dataPin, csPin); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(ds1302) { + EXPORT_FUNCTION(ds1302rtcRead); + EXPORT_FUNCTION(ds1302rtcWrite); + EXPORT_FUNCTION(ds1302ramRead); + EXPORT_FUNCTION(ds1302ramWrite); + EXPORT_FUNCTION(ds1302clockRead); + EXPORT_FUNCTION(ds1302clockWrite); + EXPORT_FUNCTION(ds1302trickleCharge); + EXPORT_FUNCTION(ds1302setup); +} \ No newline at end of file diff --git a/src/devlib/ds1302.h b/src/devlib/ds1302.h new file mode 100644 index 0000000..349d2e5 --- /dev/null +++ b/src/devlib/ds1302.h @@ -0,0 +1,8 @@ +#ifndef _WPI_DS1302_H_ +#define _WPI_DS1302_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(ds1302); + +#endif \ No newline at end of file diff --git a/src/devlib/gertboard.cc b/src/devlib/gertboard.cc new file mode 100644 index 0000000..17387b3 --- /dev/null +++ b/src/devlib/gertboard.cc @@ -0,0 +1,24 @@ +#include "gertboard.h" +#include + +DECLARE(gertboardAnalogSetup); + +IMPLEMENT(gertboardAnalogSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + + int res = ::getboardAnalogSetup(pinBase); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(gertboard) { + EXPORT_FUNCTION(gertboardAnalogSetup); +} \ No newline at end of file diff --git a/src/devlib/gertboard.h b/src/devlib/gertboard.h new file mode 100644 index 0000000..f9d1ea1 --- /dev/null +++ b/src/devlib/gertboard.h @@ -0,0 +1,8 @@ +#ifndef _WPI_GERTBOARD_H_ +#define _WPI_GERTBOARD_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(gertboard); + +#endif \ No newline at end of file diff --git a/src/devlib/lcd.cc b/src/devlib/lcd.cc new file mode 100644 index 0000000..8866800 --- /dev/null +++ b/src/devlib/lcd.cc @@ -0,0 +1,284 @@ +#include "lcd.h" +#include + +DECLARE(lcdHome); +DECLARE(lcdClear); +DECLARE(lcdDisplay); +DECLARE(lcdCursor); +DECLARE(lcdCursorBlink); +DECLARE(lcdSendCommand); +DECLARE(lcdPosition); +DECLARE(lcdCharDef); +DECLARE(lcdPutchar); +DECLARE(lcdPuts); +DECLARE(lcdPrintf); +DECLARE(lcdInit); + +IMPLEMENT(lcdHome) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + ::lcdHome(fd); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdClear) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int fd = GET_ARGUMENT_AS_INT32(0); + + ::lcdClear(fd); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdDisplay) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + ::lcdDisplay(fd, state); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdCursor) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + ::lcdCursor(fd, state); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdCursorBlink) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, state); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int state = GET_ARGUMENT_AS_INT32(1); + + ::lcdCursorBlink(fd, state); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdSendCommand) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, command); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + int command = GET_ARGUMENT_AS_UINT32(1); + + ::lcdSendCommand(fd, command); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdPosition) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, x); + SET_ARGUMENT_NAME(2, y); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int fd = GET_ARGUMENT_AS_INT32(0); + int x = GET_ARGUMENT_AS_INT32(1); + int y = GET_ARGUMENT_AS_INT32(2); + + ::lcdPosition(fd, x, y); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdCharDef) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, index); + SET_ARGUMENT_NAME(2, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_ARRAY(2); + CHECK_ARGUMENT_ARRAY_LENGTH(8); + + int fd = GET_ARGUMENT_AS_INT32(0); + int index = GET_ARGUMENT_AS_INT32(1); + v8::Local data = v8::Local::Cast(args[2]); + + unsigned int ar[8]; + for (int i = 0; i < 8; i++) { + ar[i] = data->Get(i)->Uint32Value(); + } + + ::lcdCharDef(fd, index, ar); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdPutchar) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, data); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + unsigned int data = GET_ARGUMENT_AS_UINT32(1); + + ::lcdPutchar(fd, data); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdPuts) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, fd); + SET_ARGUMENT_NAME(1, string); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_STRING(1); + + int fd = GET_ARGUMENT_AS_INT32(0); + v8::String::AsciiValue data(GET_ARGUMENT_AS_STRING(1)); + + ::lcdPuts(fd, *data); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcdPrintf) { + return lcdPuts(args); +} + +IMPLEMENT(lcdInit) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, rows); + SET_ARGUMENT_NAME(1, cols); + SET_ARGUMENT_NAME(2, bits); + SET_ARGUMENT_NAME(3, rs); + SET_ARGUMENT_NAME(4, strb); + SET_ARGUMENT_NAME(5, d0); + SET_ARGUMENT_NAME(6, d1); + SET_ARGUMENT_NAME(7, d2); + SET_ARGUMENT_NAME(8, d3); + SET_ARGUMENT_NAME(9, d4); + SET_ARGUMENT_NAME(10, d5); + SET_ARGUMENT_NAME(11, d6); + SET_ARGUMENT_NAME(12, d7); + + CHECK_ARGUMENTS_LENGTH_EQUAL(13); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + CHECK_ARGUMENT_TYPE_INT32(5); + CHECK_ARGUMENT_TYPE_INT32(6); + CHECK_ARGUMENT_TYPE_INT32(7); + CHECK_ARGUMENT_TYPE_INT32(8); + CHECK_ARGUMENT_TYPE_INT32(9); + CHECK_ARGUMENT_TYPE_INT32(10); + CHECK_ARGUMENT_TYPE_INT32(11); + CHECK_ARGUMENT_TYPE_INT32(12); + + int rows = GET_ARGUMENT_AS_INT32(0); + int cols = GET_ARGUMENT_AS_INT32(1); + int bits = GET_ARGUMENT_AS_INT32(2); + int rs = GET_ARGUMENT_AS_INT32(3); + int strb = GET_ARGUMENT_AS_INT32(4); + int d0 = GET_ARGUMENT_AS_INT32(5); + int d1 = GET_ARGUMENT_AS_INT32(6); + int d2 = GET_ARGUMENT_AS_INT32(7); + int d3 = GET_ARGUMENT_AS_INT32(8); + int d4 = GET_ARGUMENT_AS_INT32(9); + int d5 = GET_ARGUMENT_AS_INT32(10); + int d6 = GET_ARGUMENT_AS_INT32(11); + int d7 = GET_ARGUMENT_AS_INT32(12); + + int res = ::lcdInit(rows, cols, bits, rs, strb, d0, d1, d2, d3, d4, d5, d6, d7); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(lcd) { + EXPORT_FUNCTION(lcdHome); + EXPORT_FUNCTION(lcdClear); + EXPORT_FUNCTION(lcdDisplay); + EXPORT_FUNCTION(lcdCursor); + EXPORT_FUNCTION(lcdCursorBlink); + EXPORT_FUNCTION(lcdSendCommand); + EXPORT_FUNCTION(lcdPosition); + EXPORT_FUNCTION(lcdCharDef); + EXPORT_FUNCTION(lcdPutchar); + EXPORT_FUNCTION(lcdPuts); + EXPORT_FUNCTION(lcdPrintf); + EXPORT_FUNCTION(lcdInit); + + EXPORT_CONSTANT_INT(MAX_LCDS); +} \ No newline at end of file diff --git a/src/devlib/lcd.h b/src/devlib/lcd.h new file mode 100644 index 0000000..1b66119 --- /dev/null +++ b/src/devlib/lcd.h @@ -0,0 +1,8 @@ +#ifndef _WPI_LCD_H_ +#define _WPI_LCD_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(lcd); + +#endif \ No newline at end of file diff --git a/src/devlib/lcd128x64.cc b/src/devlib/lcd128x64.cc new file mode 100644 index 0000000..e69de29 diff --git a/src/devlib/lcd128x64.h b/src/devlib/lcd128x64.h new file mode 100644 index 0000000..e69de29 diff --git a/src/devlib/maxdetect.cc b/src/devlib/maxdetect.cc new file mode 100644 index 0000000..3163dc3 --- /dev/null +++ b/src/devlib/maxdetect.cc @@ -0,0 +1,58 @@ +#include "maxdetect.h" +#include + +DECLARE(maxDetectRead); +DECLARE(readRHT03); + +IMPLEMENT(maxDetectRead) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32(0); + + unsigned char buffer[4]; + int res = ::maxDetectRead(pin, buffer); + + v8::Local data = v8::Array::New(4); + for (int i = 0; i < 4; i++) { + data->Set(i, Int32::New(buffer[i])); + } + + v8::Local ret = v8::Array::New(2); + ret->Set(0, Int32::New(res)); + ret->Set(1, data); + + SCOPE_CLOSE(ret); +} + +IMPLEMENT(readRHT03) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pin = GET_ARGUMENT_AS_INT32; + + int temp, int rh; + int res = ::readRHT03(pin, &temp, &rh); + + v8::Local ret = v8::Array::New(3); + ret->Set(0, v8::Int32::New(res)); + ret->Set(1, v8::Int32::New(temp)); + ret->Set(2, v8::Int32::New(rh)); + + SCOPE_CLOSE(ret); +} + +IMPLEMENT_EXPORT_INIT(maxdetect) { + EXPORT_FUNCTION(maxDetectRead); + EXPORT_FUNCTION(readRHT03); +} \ No newline at end of file diff --git a/src/devlib/maxdetect.h b/src/devlib/maxdetect.h new file mode 100644 index 0000000..d9e7d38 --- /dev/null +++ b/src/devlib/maxdetect.h @@ -0,0 +1,8 @@ +#ifndef _WPI_MAXDETECT_H_ +#define _WPI_MAXDETECT_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(maxdetect); + +#endif \ No newline at end of file diff --git a/src/devlib/piFace.cc b/src/devlib/piFace.cc new file mode 100644 index 0000000..1efba8b --- /dev/null +++ b/src/devlib/piFace.cc @@ -0,0 +1,24 @@ +#include "piFace.h" +#include + +DECLARE(piFaceSetup); + +IMPLEMENT(piFaceSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + + int res = ::piFaceSetup(pinBase); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(piFace) { + EXPORT_FUNCTION(piFaceSetup); +} \ No newline at end of file diff --git a/src/devlib/piFace.h b/src/devlib/piFace.h new file mode 100644 index 0000000..63bf848 --- /dev/null +++ b/src/devlib/piFace.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PI_FACE_H_ +#define _WPI_PI_FACE_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(piFace); + +#endif \ No newline at end of file diff --git a/src/devlib/piGlow.cc b/src/devlib/piGlow.cc new file mode 100644 index 0000000..ea66211 --- /dev/null +++ b/src/devlib/piGlow.cc @@ -0,0 +1,97 @@ +#include "piGlow.h" +#include + +DECLARE(piGlow1); +DECLARE(piGlowLeg); +DECLARE(piGlowRing); +DECLARE(piGlowSetup); + +IMPLEMENT(piGlow1) { + OPEN_SCOPE(); + + SET_ARGUMENT_NAME(0, leg); + SET_ARGUMENT_NAME(1, ring); + SET_ARGUMENT_NAME(2, intensity); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int leg = GET_ARGUMENT_AS_INT32(0); + int ring = GET_ARGUMENT_AS_INT32(1); + int intensity = GET_ARGUMENT_AS_INT32(2); + + ::piGlow1(leg, ring, intensity); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(piGlowLeg) { + OPEN_SCOPE(); + + SET_ARGUMENT_NAME(0, leg); + SET_ARGUMENT_NAME(1, intensity); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int leg = GET_ARGUMENT_AS_INT32(0); + int intensity = GET_ARGUMENT_AS_INT32(1); + + ::piGlowLeg(leg, intensity); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(piGlowRing) { + OPEN_SCOPE(); + + SET_ARGUMENT_NAME(0, ring); + SET_ARGUMENT_NAME(1, intensity); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int ring = GET_ARGUMENT_AS_INT32(0); + int intensity = GET_ARGUMENT_AS_INT32(1); + + ::piGlowRing(ring, intensity); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(piGlowSetup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, clear); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int clear = GET_ARGUMENT_AS_INT32(0); + + ::piGlowSetup(clear); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT_EXPORT_INIT(piGlow) { + EXPORT_FUNCTION(piGlow1); + EXPORT_FUNCTION(piGlowLeg); + EXPORT_FUNCTION(piGlowRing); + EXPORT_FUNCTION(piGlowSetup); + + EXPORT_CONSTANT_INT(PIGLOW_RED); + EXPORT_CONSTANT_INT(PIGLOW_YELLOW); + EXPORT_CONSTANT_INT(PIGLOW_ORANGE); + EXPORT_CONSTANT_INT(PIGLOW_GREEN); + EXPORT_CONSTANT_INT(PIGLOW_BLUE); + EXPORT_CONSTANT_INT(PIGLOW_WHITE); +} \ No newline at end of file diff --git a/src/devlib/piGlow.h b/src/devlib/piGlow.h new file mode 100644 index 0000000..b1dd98c --- /dev/null +++ b/src/devlib/piGlow.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PI_GLOW_H_ +#define _WPI_PI_GLOW_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(piGlow); + +#endif \ No newline at end of file diff --git a/src/devlib/piNes.cc b/src/devlib/piNes.cc new file mode 100644 index 0000000..f94d988 --- /dev/null +++ b/src/devlib/piNes.cc @@ -0,0 +1,58 @@ +#include "piNes.h" +#include + +DECLARE(setupNesJoystick); +DECLARE(readNesJoystick); + +IMPLEMENT(setupNesJoystick) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, dPin); + SET_ARGUMENT_NAME(1, cPin); + SET_ARGUMENT_NAME(2, lPin); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int dPin = GET_ARGUMENT_AS_INT32(0); + int cPin = GET_ARGUMENT_AS_INT32(1); + int lPin = GET_ARGUMENT_AS_INT32(2); + + int res = ::setupNesJoystick(dPin, cPin, lPin); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT(readNesJoystick) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, joystick); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int joystick = GET_ARGUMENT_AS_INT32(0); + + unsigned int res = ::readNesJoystick(joystick); + + SCOPE_CLOSE(UINT32(res)); +} + +IMPLEMENT_EXPORT_INIT(piNes) { + EXPORT_FUNCTION(setupNesJoystick); + EXPORT_FUNCTION(readNesJoystick); + + EXPORT_CONSTANT_INT(MAX_NES_JOYSTICKS); + EXPORT_CONSTANT_INT(NES_RIGHT); + EXPORT_CONSTANT_INT(NES_LEFT); + EXPORT_CONSTANT_INT(NES_DOWN); + EXPORT_CONSTANT_INT(NES_UP); + EXPORT_CONSTANT_INT(NES_START); + EXPORT_CONSTANT_INT(NES_SELECT); + EXPORT_CONSTANT_INT(NES_A); + EXPORT_CONSTANT_INT(NES_B); +} \ No newline at end of file diff --git a/src/devlib/piNes.h b/src/devlib/piNes.h new file mode 100644 index 0000000..f7125a8 --- /dev/null +++ b/src/devlib/piNes.h @@ -0,0 +1,8 @@ +#ifndef _WPI_PI_NES_H_ +#define _WPI_PI_NES_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(piNes); + +#endif \ No newline at end of file diff --git a/src/wpi.cc b/src/wpi.cc index 491f874..f04c705 100644 --- a/src/wpi.cc +++ b/src/wpi.cc @@ -13,6 +13,7 @@ NODE_MODULE_INIT() { INIT(wiringPiISR); INIT(extensions); + INIT(devlib); } NODE_MODULE_DECLARE(wiringPi); \ No newline at end of file diff --git a/src/wpi.h b/src/wpi.h index a61262b..a9c60df 100644 --- a/src/wpi.h +++ b/src/wpi.h @@ -12,5 +12,6 @@ #include "wiringPiISR.h" #include "extensions/extensions.h" + #include "devlib/devlib.h" #endif \ No newline at end of file From 7a1edfd2c29800ab5fe5108b39d0318a20ae13c2 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 18:04:08 +0200 Subject: [PATCH 34/64] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2eae93..00f3075 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ * **Add:** piNes support `nekuz0r` * **Fictitious:** this release eats Pi(e)s :) -## v1.1.1 *[not released yet]* +## v1.1.1 *[Jul 4 2014]* * **Fix:** missing constant in pinModeCheck `nekuz0r` * **Fix:** missing constant PI_MODEL_CM `nekuz0r` * **Add:** serialPrintf (alias to serialPuts) `nekuz0r` From d9962656c88d1c757722f0b3919743a182a395bc Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 19:47:46 +0200 Subject: [PATCH 35/64] devlib support --- binding.gyp | 4 +- src/addon.h | 6 + src/devlib/devlib.cc | 2 +- src/devlib/lcd128x64.cc | 355 ++++++++++++++++++++++++++++++++++++++++ src/devlib/lcd128x64.h | 8 + 5 files changed, 372 insertions(+), 3 deletions(-) diff --git a/binding.gyp b/binding.gyp index 3541dfe..2449a72 100644 --- a/binding.gyp +++ b/binding.gyp @@ -33,7 +33,7 @@ 'src/extensions/pcf8591.cc', 'src/extensions/sn3218.cc', 'src/extensions/sr595.cc', - 'src/extensions/pca9685.cc' + 'src/extensions/pca9685.cc', 'src/devlib/devlib.cc', 'src/devlib/ds1302.cc', @@ -43,7 +43,7 @@ 'src/devlib/maxdetect.cc', 'src/devlib/piFace.cc', 'src/devlib/piGlow.cc', - 'src/devlib/piNes.cc', + 'src/devlib/piNes.cc' ], 'include_dirs': [ 'wiringpi/wiringPi' diff --git a/src/addon.h b/src/addon.h index ce3ed9e..5a5100c 100644 --- a/src/addon.h +++ b/src/addon.h @@ -98,6 +98,7 @@ THROW_ERROR("%s: %s(arguments['%s']) === false", __func__, #istype, GET_ARGUMENT_NAME(id)); \ } + #define CHECK_ARGUMENT_TYPE_ARRAY(id) CHECK_ARGUMENT_TYPE(id, IsArray) #define CHECK_ARGUMENT_TYPE_INT32(id) CHECK_ARGUMENT_TYPE(id, IsInt32) #define CHECK_ARGUMENT_TYPE_UINT32(id) CHECK_ARGUMENT_TYPE(id, IsUint32) #define CHECK_ARGUMENT_TYPE_NUMBER(id) CHECK_ARGUMENT_TYPE(id, IsNumber) @@ -108,6 +109,11 @@ if (!(args[id]->IsObject() && node::Buffer::HasInstance(args[id]))) { \ THROW_ERROR("%s: %s(arguments['%s']) === false", __func__, "isBuffer", GET_ARGUMENT_NAME(id)); \ } + + #define CHECK_ARGUMENT_ARRAY_LENGTH(id, length) \ + if (!(v8::Local::Cast(args[id])->Length() == length)) { \ + THROW_ERROR("%s: (arguments['%s'].length === %i) === false", __func__, GET_ARGUMENT_NAME(id), length); \ + } #define GET_ARGUMENT_AS_TYPE(id, type) args[id]->type() diff --git a/src/devlib/devlib.cc b/src/devlib/devlib.cc index 1b9370b..bbb7103 100644 --- a/src/devlib/devlib.cc +++ b/src/devlib/devlib.cc @@ -7,7 +7,7 @@ #include "maxdetect.h" #include "piFace.h" #include "piGlow.h" -#include "piNew.h" +#include "piNes.h" IMPLEMENT_EXPORT_INIT(devlib) { INIT(ds1302); diff --git a/src/devlib/lcd128x64.cc b/src/devlib/lcd128x64.cc index e69de29..9f9717c 100644 --- a/src/devlib/lcd128x64.cc +++ b/src/devlib/lcd128x64.cc @@ -0,0 +1,355 @@ +#include "lcd128x64.h" +#include + +DECLARE(lcd128x64setOrigin); +DECLARE(lcd128x64setOrientation); +DECLARE(lcd128x64orientCoordinates); +DECLARE(lcd128x64getScreenSize); +DECLARE(lcd128x64point); +DECLARE(lcd128x64line); +DECLARE(lcd128x64lineTo); +DECLARE(lcd128x64rectangle); +DECLARE(lcd128x64circle); +DECLARE(lcd128x64ellipse); +DECLARE(lcd128x64putchar); +DECLARE(lcd128x64puts); +DECLARE(lcd128x64update); +DECLARE(lcd128x64clear); +DECLARE(lcd128x64setup); + +IMPLEMENT(lcd128x64setOrigin) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, x); + SET_ARGUMENT_NAME(0, y); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int x = GET_ARGUMENT_AS_INT32(0); + int y = GET_ARGUMENT_AS_INT32(1); + + ::lcd128x64setOrigin(x, y); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64setOrientation) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, orientation); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int orientation = GET_ARGUMENT_AS_INT32(0); + + ::lcd128x64setOrientation(orientation); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64orientCoordinates) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int x, y; + ::lcd128x64orientCoordinates(&x, &y); + + v8::Local res = v8::Array::New(2); + res->Set(i, v8::Int32::New(x)); + res->Set(i, v8::Int32::New(y)); + + SCOPE_CLOSE(res); +} + +IMPLEMENT(lcd128x64getScreenSize) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int x, y; + ::lcd128x64screenSize(&x, &y); + + v8::Local res = v8::Array::New(2); + res->Set(i, v8::Int32::New(x)); + res->Set(i, v8::Int32::New(y)); + + SCOPE_CLOSE(res); +} + +IMPLEMENT(lcd128x64point) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, x); + SET_ARGUMENT_NAME(1, y); + SET_ARGUMENT_NAME(2, color); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int x = GET_ARGUMENT_AS_INT32(0); + int y = GET_ARGUMENT_AS_INT32(1); + int color = GET_ARGUMENT_AS_INT32(2); + + ::lcd128x64point(x, y, color); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64line) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, x0); + SET_ARGUMENT_NAME(1, y0); + SET_ARGUMENT_NAME(2, x1); + SET_ARGUMENT_NAME(3, y1); + SET_ARGUMENT_NAME(4, color); + + CHECK_ARGUMENTS_LENGTH_EQUAL(5); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + + int x0 = GET_ARGUMENT_AS_INT32(0); + int y0 = GET_ARGUMENT_AS_INT32(1); + int x1 = GET_ARGUMENT_AS_INT32(2); + int y1 = GET_ARGUMENT_AS_INT32(3); + int color = GET_ARGUMENT_AS_INT32(4); + + ::lcd128x64line(x0, y0, x1, y1, color); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64lineTo) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, x); + SET_ARGUMENT_NAME(1, y); + SET_ARGUMENT_NAME(2, color); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int x = GET_ARGUMENT_AS_INT32(0); + int y = GET_ARGUMENT_AS_INT32(1); + int color = GET_ARGUMENT_AS_INT32(2); + + ::lcd128x64lineTo(x, y, color); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64rectangle) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, x1); + SET_ARGUMENT_NAME(1, y1); + SET_ARGUMENT_NAME(2, x2); + SET_ARGUMENT_NAME(3, y2); + SET_ARGUMENT_NAME(4, color); + SET_ARGUMENT_NAME(5, filled); + + CHECK_ARGUMENTS_LENGTH_EQUAL(6); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + CHECK_ARGUMENT_TYPE_INT32(5); + + int x1 = GET_ARGUMENT_AS_INT32(0); + int y1 = GET_ARGUMENT_AS_INT32(1); + int x2 = GET_ARGUMENT_AS_INT32(2); + int y2 = GET_ARGUMENT_AS_INT32(3); + int color = GET_ARGUMENT_AS_INT32(4); + int filled = GET_ARGUMENT_AS_INT32(5); + + ::lcd128x64rectangle(x1, y1, x2, y2, color, filled); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64circle) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, x); + SET_ARGUMENT_NAME(1, y); + SET_ARGUMENT_NAME(2, r); + SET_ARGUMENT_NAME(3, color); + SET_ARGUMENT_NAME(4, filled); + + CHECK_ARGUMENTS_LENGTH_EQUAL(5); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + + int x = GET_ARGUMENT_AS_INT32(0); + int y = GET_ARGUMENT_AS_INT32(1); + int r = GET_ARGUMENT_AS_INT32(2); + int color = GET_ARGUMENT_AS_INT32(3); + int filled = GET_ARGUMENT_AS_INT32(4); + + ::lcd128x64circle(x, y, r, color, filled); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64ellipse) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, cx); + SET_ARGUMENT_NAME(1, cy); + SET_ARGUMENT_NAME(2, xRadius); + SET_ARGUMENT_NAME(3, yRadius); + SET_ARGUMENT_NAME(4, color); + SET_ARGUMENT_NAME(5, filled); + + CHECK_ARGUMENTS_LENGTH_EQUAL(6); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + CHECK_ARGUMENT_TYPE_INT32(5); + + int cx = GET_ARGUMENT_AS_INT32(0); + int cy = GET_ARGUMENT_AS_INT32(1); + int xRadius = GET_ARGUMENT_AS_INT32(2); + int yRadius = GET_ARGUMENT_AS_INT32(3); + int color = GET_ARGUMENT_AS_INT32(4); + int filled = GET_ARGUMENT_AS_INT32(5); + + ::lcd128x64ellipse(cx, cy, xRadius, yRadius, color, filled); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64putchar) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, x); + SET_ARGUMENT_NAME(1, y); + SET_ARGUMENT_NAME(2, c); + SET_ARGUMENT_NAME(3, bgColor); + SET_ARGUMENT_NAME(4, fgColor); + + CHECK_ARGUMENTS_LENGTH_EQUAL(5); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + + int x = GET_ARGUMENT_AS_INT32(0); + int y = GET_ARGUMENT_AS_INT32(1); + int c = GET_ARGUMENT_AS_INT32(2); + int bgColor = GET_ARGUMENT_AS_INT32(3); + int fgColor = GET_ARGUMENT_AS_INT32(4); + + ::lcd128x64putchar(x, y, c, bgColor, fgColor); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64puts) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, x); + SET_ARGUMENT_NAME(1, y); + SET_ARGUMENT_NAME(2, string); + SET_ARGUMENT_NAME(3, bgColor); + SET_ARGUMENT_NAME(4, fgColor); + + CHECK_ARGUMENTS_LENGTH_EQUAL(5); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_STRING(2); + CHECK_ARGUMENT_TYPE_INT32(3); + CHECK_ARGUMENT_TYPE_INT32(4); + + int x = GET_ARGUMENT_AS_INT32(0); + int y = GET_ARGUMENT_AS_INT32(1); + v8::String::AsciiValue(GET_ARGUMENT_AS_STRING(2)) + int bgColor = GET_ARGUMENT_AS_INT32(3); + int fgColor = GET_ARGUMENT_AS_INT32(4); + + ::lcd128x64puts(x, y, c, bgColor, fgColor); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64update) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + ::lcd128x64update(); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64clear) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, color); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int color = GET_ARGUMENT_AS_INT32(0); + + ::lcd128x64clear(color); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(lcd128x64setup) { + SCOPE_OPEN(); + + CHECK_ARGUMENTS_LENGTH_EQUAL(0); + + int res = ::lcd128x64setup(); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(lcd128x64) { + EXPORT_FUNCTION(lcd128x64setOrigin); + EXPORT_FUNCTION(lcd128x64setOrientation); + EXPORT_FUNCTION(lcd128x64orientCoordinates); + EXPORT_FUNCTION(lcd128x64getScreenSize); + EXPORT_FUNCTION(lcd128x64point); + EXPORT_FUNCTION(lcd128x64line); + EXPORT_FUNCTION(lcd128x64lineTo); + EXPORT_FUNCTION(lcd128x64rectangle); + EXPORT_FUNCTION(lcd128x64circle); + EXPORT_FUNCTION(lcd128x64ellipse); + EXPORT_FUNCTION(lcd128x64putchar); + EXPORT_FUNCTION(lcd128x64puts); + EXPORT_FUNCTION(lcd128x64update); + EXPORT_FUNCTION(lcd128x64clear); + EXPORT_FUNCTION(lcd128x64setup); +} \ No newline at end of file diff --git a/src/devlib/lcd128x64.h b/src/devlib/lcd128x64.h index e69de29..5a7cb32 100644 --- a/src/devlib/lcd128x64.h +++ b/src/devlib/lcd128x64.h @@ -0,0 +1,8 @@ +#ifndef _WPI_LCD128X64_H_ +#define _WPI_LCD128X64_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(lcd128x64); + +#endif \ No newline at end of file From a7f7ac478fd80b7da09768f0309ea0f36b02c06b Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Fri, 4 Jul 2014 20:24:09 +0200 Subject: [PATCH 36/64] devlib support fix compilation errors --- binding.gyp | 3 ++- src/devlib/ds1302.cc | 3 ++- src/devlib/gertboard.cc | 2 +- src/devlib/lcd.cc | 6 +++--- src/devlib/lcd128x64.cc | 16 ++++++++-------- src/devlib/maxdetect.cc | 4 ++-- src/devlib/piGlow.cc | 6 +++--- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/binding.gyp b/binding.gyp index 2449a72..b122b75 100644 --- a/binding.gyp +++ b/binding.gyp @@ -46,7 +46,8 @@ 'src/devlib/piNes.cc' ], 'include_dirs': [ - 'wiringpi/wiringPi' + 'wiringpi/wiringPi', + 'wiringpi/devLib' ], 'libraries': [ ' DECLARE(ds1302rtcRead); @@ -41,6 +41,7 @@ IMPLEMENT(ds1302rtcWrite) { CHECK_ARGUMENTS_LENGTH_EQUAL(2); CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); int reg = GET_ARGUMENT_AS_INT32(0); unsigned int data = GET_ARGUMENT_AS_UINT32(1); diff --git a/src/devlib/gertboard.cc b/src/devlib/gertboard.cc index 17387b3..8cc9b37 100644 --- a/src/devlib/gertboard.cc +++ b/src/devlib/gertboard.cc @@ -14,7 +14,7 @@ IMPLEMENT(gertboardAnalogSetup) { int pinBase = GET_ARGUMENT_AS_INT32(0); - int res = ::getboardAnalogSetup(pinBase); + int res = ::gertboardAnalogSetup(pinBase); SCOPE_CLOSE(INT32(res)); } diff --git a/src/devlib/lcd.cc b/src/devlib/lcd.cc index 8866800..6fbd787 100644 --- a/src/devlib/lcd.cc +++ b/src/devlib/lcd.cc @@ -156,15 +156,15 @@ IMPLEMENT(lcdCharDef) { CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); CHECK_ARGUMENT_TYPE_ARRAY(2); - CHECK_ARGUMENT_ARRAY_LENGTH(8); + CHECK_ARGUMENT_ARRAY_LENGTH(2, 8); int fd = GET_ARGUMENT_AS_INT32(0); int index = GET_ARGUMENT_AS_INT32(1); v8::Local data = v8::Local::Cast(args[2]); - unsigned int ar[8]; + unsigned char ar[8]; for (int i = 0; i < 8; i++) { - ar[i] = data->Get(i)->Uint32Value(); + ar[i] = data->Get(i)->Uint32Value() & 0xFF; } ::lcdCharDef(fd, index, ar); diff --git a/src/devlib/lcd128x64.cc b/src/devlib/lcd128x64.cc index 9f9717c..2e4c2bb 100644 --- a/src/devlib/lcd128x64.cc +++ b/src/devlib/lcd128x64.cc @@ -21,7 +21,7 @@ IMPLEMENT(lcd128x64setOrigin) { SCOPE_OPEN(); SET_ARGUMENT_NAME(0, x); - SET_ARGUMENT_NAME(0, y); + SET_ARGUMENT_NAME(1, y); CHECK_ARGUMENTS_LENGTH_EQUAL(2); @@ -61,8 +61,8 @@ IMPLEMENT(lcd128x64orientCoordinates) { ::lcd128x64orientCoordinates(&x, &y); v8::Local res = v8::Array::New(2); - res->Set(i, v8::Int32::New(x)); - res->Set(i, v8::Int32::New(y)); + res->Set(0, v8::Int32::New(x)); + res->Set(1, v8::Int32::New(y)); SCOPE_CLOSE(res); } @@ -73,11 +73,11 @@ IMPLEMENT(lcd128x64getScreenSize) { CHECK_ARGUMENTS_LENGTH_EQUAL(0); int x, y; - ::lcd128x64screenSize(&x, &y); + ::lcd128x64getScreenSize(&x, &y); v8::Local res = v8::Array::New(2); - res->Set(i, v8::Int32::New(x)); - res->Set(i, v8::Int32::New(y)); + res->Set(0, v8::Int32::New(x)); + res->Set(1, v8::Int32::New(y)); SCOPE_CLOSE(res); } @@ -291,11 +291,11 @@ IMPLEMENT(lcd128x64puts) { int x = GET_ARGUMENT_AS_INT32(0); int y = GET_ARGUMENT_AS_INT32(1); - v8::String::AsciiValue(GET_ARGUMENT_AS_STRING(2)) + v8::String::AsciiValue string(GET_ARGUMENT_AS_STRING(2)); int bgColor = GET_ARGUMENT_AS_INT32(3); int fgColor = GET_ARGUMENT_AS_INT32(4); - ::lcd128x64puts(x, y, c, bgColor, fgColor); + ::lcd128x64puts(x, y, *string, bgColor, fgColor); SCOPE_CLOSE(UNDEFINED()); } diff --git a/src/devlib/maxdetect.cc b/src/devlib/maxdetect.cc index 3163dc3..75b674c 100644 --- a/src/devlib/maxdetect.cc +++ b/src/devlib/maxdetect.cc @@ -39,9 +39,9 @@ IMPLEMENT(readRHT03) { CHECK_ARGUMENT_TYPE_INT32(0); - int pin = GET_ARGUMENT_AS_INT32; + int pin = GET_ARGUMENT_AS_INT32(0); - int temp, int rh; + int temp, rh; int res = ::readRHT03(pin, &temp, &rh); v8::Local ret = v8::Array::New(3); diff --git a/src/devlib/piGlow.cc b/src/devlib/piGlow.cc index ea66211..ef89e11 100644 --- a/src/devlib/piGlow.cc +++ b/src/devlib/piGlow.cc @@ -7,7 +7,7 @@ DECLARE(piGlowRing); DECLARE(piGlowSetup); IMPLEMENT(piGlow1) { - OPEN_SCOPE(); + SCOPE_OPEN(); SET_ARGUMENT_NAME(0, leg); SET_ARGUMENT_NAME(1, ring); @@ -29,7 +29,7 @@ IMPLEMENT(piGlow1) { } IMPLEMENT(piGlowLeg) { - OPEN_SCOPE(); + SCOPE_OPEN(); SET_ARGUMENT_NAME(0, leg); SET_ARGUMENT_NAME(1, intensity); @@ -48,7 +48,7 @@ IMPLEMENT(piGlowLeg) { } IMPLEMENT(piGlowRing) { - OPEN_SCOPE(); + SCOPE_OPEN(); SET_ARGUMENT_NAME(0, ring); SET_ARGUMENT_NAME(1, intensity); From b449e81121dbe849ea33b6032f0b75f8f8588d5b Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 14:05:47 +0200 Subject: [PATCH 37/64] Update to libWiringPi 2.20 ADD: pwmToneWrite UPD: pi model constants ADD: pi version constants ADD: pi marker constants ADD: export pi maker names string table DEL: export pi compute revision names string table --- docs/DOCUMENTATION.md | 184 +++++++++++++++++++++++++++++++++++++++++- src/wiringPi.cc | 51 ++++++++++-- 2 files changed, 226 insertions(+), 9 deletions(-) diff --git a/docs/DOCUMENTATION.md b/docs/DOCUMENTATION.md index c6e98ad..f095de6 100644 --- a/docs/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -19,7 +19,7 @@ var wpi = require('wiring-pi'); Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. -see the pins page (http://wiringpi.com/pins/) for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. +see the [pins](http://wiringpi.com/pins/) page for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. This function needs to be called with root privileges. ### `wiringPiSetupGpio()` @@ -355,4 +355,184 @@ Set the frequency on a GPIO clock pin --- -## Extensions \ No newline at end of file +## Extensions + +### drcSerial + +#### `drcSetupSerial(pinBase, numPins, device, baudrate)` + +### max31855 + +Cold-junction compensated thermocouple-to-digital converter (SPI) + +### max5322 + +12-Bit DAC (SPI) + +#### `max31855Setup(pinBase, spiChannel)` + +### mcp23008 + +8-Bit I/O expander (I2C) + +#### `mcp23008Setup(pinBase, i2cAddress)` + +### mcp23016 + +16-Bit I/O expander (I2C) + +#### `mcp23016Setup(pinBase, i2cAddress)` + +### mpc23017 + +16-Bit I/O expander (I2C) + +#### `mcp23017Setup(pinBase, i2cAddress)` + +### mcp23s08 + +8-Bit I/O expander (SPI) + +#### `mcp23s08Setup(pinBase, spiChannel, devId)` + +### mcp23s17 + +16-Bit I/O expander (SPI) + +#### `mcp23s17Setup(pinBase, spiChannel, devId)` + +### mcp3002 + +2-Channel 10-Bit ADC (SPI) + +#### `mcp3002Setup(pinBase, spiChannel)` + +### mcp3004/8 + +4/8-Channel 10-Bit ADC (SPI) + +#### `mcp3004Setup(pinBase, spiChannel)` + +### mcp3422/3/4 + +2/4-Channel 18-Bit ADC (I2C) + +#### `mcp3422Setup(pinBase, i2cAddress, sampleRate, gain)` + +### mcp4802/12/22 + +2-Channel 8/10/12-Bit DAC (SPI) + +#### `mcp4802Setup(pinBase, spiChannel)` + +### pca9685 + +16-Channel 12-Bit PWM led/servo driver (I2C) + +#### `pca9685Setup(pinBase, i2cAddress, frequency)` + +### pcf8574 + +8-Bit I/O expander (I2C) + +#### `pcf8574Setup(pinBase, i2cAddress)` + +### pcf8591 + +8-Bit ADC and DAC (I2C) + +#### `pcf8591Setup(pinBase, i2cAddress)` + +### sn3218 + +18-Channel PWM led driver (I2C) + +#### `sn3218Setup(pinBase)` + +### sr595 + +74x595 shift register + +#### `sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin)` + +--- + +## DevLib + +### ds1302 + +Trickle-charge timekeeping chip + +#### `ds1302setup(clockPin, dataPin, csPin)` + +#### `ds1302rtcRead(reg)` + +#### `ds1302rtcWrite(reg, data)` + +#### `ds1302ramRead(address)` + +#### `ds1302ramWrite(address, data)` + +#### `ds1302clockRead()` + +#### `ds1302clockWrite(clockData[8])` + +#### `ds1302trickleCharge(diodes, resistors)` + +### GertBoard + +#### `getboardAnalogSetup(pinBase)` + +### LCD + +#### `lcdInit(rows, cols, bits, rs, strb, d0, d1, d2, d3, d4, d5, d6, d7)` + +#### `lcdHome(fd)` + +#### `lcdClear(fd)` + +#### `lcdDisplay(fd, state)` + +#### `lcdCursor(fd, state)` + +#### `lcdCursorBlink(fd, state)` + +#### `lcdSendCommand(fd, command)` + +#### `lcdPosition(fd, x, y)` + +#### `lcdCharDef(fd, index, data[8])` + +#### `lcdPutchar(fd, character)` + +#### `lcdPuts(fd, string)` + +#### `lcdPrintf(fd, string)` + +### LCD 128x64 + +### MaxDetect + +#### `maxDetectRead(pin)` + +#### `readRHT03(pin)` + +### piFace + +#### `piFaceSetup(pinBase)` + +### piGlow + +#### `piGlowSetup(clear)` + +#### `piGlow1(leg, ring, intensity)` + +#### `piGlowLeg(leg, intensity)` + +#### `piGlowRing(ring, intensity)` + +### piNes + +#### `setupNesJoystick(dPin, cPin, lPin)` + +#### `readNesJoystick(joystick)` \ No newline at end of file diff --git a/src/wiringPi.cc b/src/wiringPi.cc index 16c2506..d9f86ab 100644 --- a/src/wiringPi.cc +++ b/src/wiringPi.cc @@ -32,6 +32,7 @@ DECLARE(wpiPinToGpio); DECLARE(physPinToGpio); DECLARE(setPadDrive); DECLARE(getAlt); +DECLARE(pwmToneWrite); DECLARE(digitalWriteByte); DECLARE(pwmSetMode); DECLARE(pwmSetRange); @@ -437,16 +438,19 @@ IMPLEMENT(piBoardId) { CHECK_ARGUMENTS_LENGTH_EQUAL(0); - int model, rev, mem; - char* marker; + // libWiringPi 2.20 changes: + // maker is now a int indexing makerNames string tables + // a fifth arguments was added named overvolted + int model, rev, mem, marker, overvolted; - ::piBoardId(&model, &rev, &mem, &marker); + ::piBoardId(&model, &rev, &mem, &marker, &overvolted); Local obj = Object::New(); obj->Set(String::NewSymbol("model"), INT32(model)); obj->Set(String::NewSymbol("rev"), INT32(rev)); obj->Set(String::NewSymbol("mem"), INT32(mem)); - obj->Set(String::NewSymbol("marker"), String::New(marker)); + obj->Set(String::NewSymbol("marker"), INT32(marker)); + obj->Set(String::NewSymbol("overvolted"), INT32(overvolted)); SCOPE_CLOSE(obj); } @@ -531,6 +535,25 @@ IMPLEMENT(getAlt) { SCOPE_CLOSE(INT32(res)); } +IMPLEMENT(pwmToneWrite) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pin); + SET_ARGUMENT_NAME(1, frequency); + + CHECK_ARGUMENT_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int pin = GET_ARGUMENT_AS_INT32(0); + int frequency = GET_ARGUMENT_AS_INT32(1); + + ::pwmToneWrite(pin, frequency); + + SCOPE_CLOSE(UNDEFINED()); +} + // Func : void digitalWriteByte(int value) // Description : This writes the 8-bit byte supplied to the first 8 GPIO pins. // It’s the fastest way to set all 8 bits at once to a particular value, although it still takes @@ -667,6 +690,7 @@ IMPLEMENT_EXPORT_INIT(wiringPi) { EXPORT_FUNCTION(physPinToGpio); EXPORT_FUNCTION(setPadDrive); EXPORT_FUNCTION(getAlt); + EXPORT_FUNCTION(pwmToneWrite); EXPORT_FUNCTION(digitalWriteByte); EXPORT_FUNCTION(pwmSetMode); EXPORT_FUNCTION(pwmSetRange); @@ -699,12 +723,25 @@ IMPLEMENT_EXPORT_INIT(wiringPi) { EXPORT_CONSTANT_INT(PWM_MODE_BAL); EXPORT_CONSTANT_INT(PWM_MODE_MS); + EXPORT_CONSTANT_INT(PI_MODEL_UNKNOWN); EXPORT_CONSTANT_INT(PI_MODEL_A); EXPORT_CONSTANT_INT(PI_MODEL_B); + EXPORT_CONSTANT_INT(PI_MODEL_BP); EXPORT_CONSTANT_INT(PI_MODEL_CM); - /*EXPORT_CONSTANT_STRING_ARRAY(PI_MODEL_NAMES, piModelNames, 3); - EXPORT_CONSTANT_STRING_ARRAY(PI_REVISION_NAMES, piRevisionNames, 3); - EXPORT_CONSTANT_STRING_ARRAY(PI_COMPUTE_REVISION_NAMES, piComputeRevisionNames, 0);*/ + EXPORT_CONSTANT_INT(PI_VERSION_UNKNOWN); + EXPORT_CONSTANT_INT(PI_VERSION_1); + EXPORT_CONSTANT_INT(PI_VERSION_1_1); + EXPORT_CONSTANT_INT(PI_VERSION_1_2); + EXPORT_CONSTANT_INT(PI_VERSION_2); + + EXPORT_CONSTANT_INT(PI_MARKER_UNKNOWN); + EXPORT_CONSTANT_INT(PI_MARKER_EGOMAN); + EXPORT_CONSTANT_INT(PI_MARKER_SONY); + EXPORT_CONSTANT_INT(PI_MARKER_QISDA); + + EXPORT_CONSTANT_STRING_ARRAY(PI_MODEL_NAMES, piModelNames, 5); + EXPORT_CONSTANT_STRING_ARRAY(PI_REVISION_NAMES, piRevisionNames, 5); + EXPORT_CONSTANT_STRING_ARRAY(PI_MAKER_NAMES, piMakerNames, 4); } From 8053697569127398df7c42cd96db56104737af48 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 14:08:27 +0200 Subject: [PATCH 38/64] fix typos --- src/wiringPi.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wiringPi.cc b/src/wiringPi.cc index d9f86ab..0c0c36d 100644 --- a/src/wiringPi.cc +++ b/src/wiringPi.cc @@ -541,7 +541,7 @@ IMPLEMENT(pwmToneWrite) { SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, frequency); - CHECK_ARGUMENT_LENGTH_EQUAL(2); + CHECK_ARGUMENT_LENGTH_EQUALS(2); CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); @@ -735,10 +735,10 @@ IMPLEMENT_EXPORT_INIT(wiringPi) { EXPORT_CONSTANT_INT(PI_VERSION_1_2); EXPORT_CONSTANT_INT(PI_VERSION_2); - EXPORT_CONSTANT_INT(PI_MARKER_UNKNOWN); - EXPORT_CONSTANT_INT(PI_MARKER_EGOMAN); - EXPORT_CONSTANT_INT(PI_MARKER_SONY); - EXPORT_CONSTANT_INT(PI_MARKER_QISDA); + EXPORT_CONSTANT_INT(PI_MAKER_UNKNOWN); + EXPORT_CONSTANT_INT(PI_MAKER_EGOMAN); + EXPORT_CONSTANT_INT(PI_MAKER_SONY); + EXPORT_CONSTANT_INT(PI_MAKER_QISDA); EXPORT_CONSTANT_STRING_ARRAY(PI_MODEL_NAMES, piModelNames, 5); EXPORT_CONSTANT_STRING_ARRAY(PI_REVISION_NAMES, piRevisionNames, 5); From 7aed91bbf42c9bd64576741a6a76814b27e7b22e Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 14:10:21 +0200 Subject: [PATCH 39/64] fix macro EXPORT_CONSTANT_STRING_ARRAY --- src/addon.h | 2 +- src/wiringPi.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/addon.h b/src/addon.h index 5a5100c..666f552 100644 --- a/src/addon.h +++ b/src/addon.h @@ -54,7 +54,7 @@ { \ v8::Local arr = v8::Array::New(); \ for (int i = 0; i < length; i++) { \ - arr->Set(i, v8::Int32::New(array[i])); \ + arr->Set(i, v8::String::New(array[i])); \ } \ target->Set(v8::String::NewSymbol(#name), arr, static_cast(v8::ReadOnly | v8::DontDelete)); \ } diff --git a/src/wiringPi.cc b/src/wiringPi.cc index 0c0c36d..6f862f5 100644 --- a/src/wiringPi.cc +++ b/src/wiringPi.cc @@ -541,7 +541,7 @@ IMPLEMENT(pwmToneWrite) { SET_ARGUMENT_NAME(0, pin); SET_ARGUMENT_NAME(1, frequency); - CHECK_ARGUMENT_LENGTH_EQUALS(2); + CHECK_ARGUMENTS_LENGTH_EQUAL(2); CHECK_ARGUMENT_TYPE_INT32(0); CHECK_ARGUMENT_TYPE_INT32(1); From a56d08aa7cc09b1d50ae903ee0e29ca08b0fa1c8 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 14:39:34 +0200 Subject: [PATCH 40/64] update changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00f3075..1d91a36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## v2.0.0 *[not released yet]* + * **Update:** libWiringPi to [custom][nekuz0r-libWiringPi] v2.20 `nekuz0r` * **Update:** split source code (based on libWiringPi hierarchy) `nekuz0r` * **Update:** better types check `nekuz0r` * **Update:** better allowed values check `nekuz0r` @@ -10,8 +11,15 @@ * **Update:** setup() is exported from c++ `nekuz0r` * NOTE: it no longer accepts empty parameter 'mode' (breaks backward compatibility) * **Update:** wiringPiSPIDataRW now takes a buffer as second parameter (no thrid anymore) `nekuz0r` + * **Update:** piBoardId `nekuz0r` * **Remove:** backward compatibility constants `nekuz0r` + * **Remove:** export of piComputeModuleRevisionNames `nekuz0r` + * **Add:** export of PI_MODEL_* constants `nekuz0r` + * **Add:** export of PI_VERSION_* constants `nekuz0r` + * **Add:** export of PI_MAKER_* constants `nekuz0r` + * **Add:** export of piMakerNames string table `nekuz0r` * **Add:** wiringPiISR `nekuz0r` + * **Add:** pwmToneWrite `nekuz0r` * **Add:** CHANGELOG.md `nekuz0r` * **Add:** wiringPiI2C support `nekuz0r` * **Add:** wiring-pi install gpio utilty (required for interrupts) `nekuz0r` @@ -23,6 +31,7 @@ * **Add:** piFace support `nekuz0r` * **Add:** piGlow support `nekuz0r` * **Add:** piNes support `nekuz0r` + * **Add:** tcs34725 support `nekuz0r` * **Fictitious:** this release eats Pi(e)s :) ## v1.1.1 *[Jul 4 2014]* From 278b3dd7256227c8c38cf758ab898c3bd39ed5aa Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 16:13:47 +0200 Subject: [PATCH 41/64] tcs34725 support (experimental) --- CHANGELOG.md | 2 +- src/devlib/tcs34725.cc | 219 +++++++++++++++++++++++++++++++++++++++++ src/devlib/tcs34725.h | 8 ++ 3 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 src/devlib/tcs34725.cc create mode 100644 src/devlib/tcs34725.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d91a36..c75c049 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ * **Update:** constants are exported from c++ (ReadOnly | DontDelete) `nekuz0r` * **Update:** setup() is exported from c++ `nekuz0r` * NOTE: it no longer accepts empty parameter 'mode' (breaks backward compatibility) - * **Update:** wiringPiSPIDataRW now takes a buffer as second parameter (no thrid anymore) `nekuz0r` + * **Update:** wiringPiSPIDataRW now takes a buffer as second parameter (no third anymore) `nekuz0r` * **Update:** piBoardId `nekuz0r` * **Remove:** backward compatibility constants `nekuz0r` * **Remove:** export of piComputeModuleRevisionNames `nekuz0r` diff --git a/src/devlib/tcs34725.cc b/src/devlib/tcs34725.cc new file mode 100644 index 0000000..451e704 --- /dev/null +++ b/src/devlib/tcs34725.cc @@ -0,0 +1,219 @@ +#include +#include "tcs34725.h" + +DECLARE(tcs34725ReadRGBC); +DECLARE(tcs34725GetCorrelatedColorTemperature); +DECLARE(tcs34725GetIlluminance); +DECLARE(tcs34725SetInterrupt); +DECLARE(tcs34725ClearInterrupt); +DECLARE(tcs34725SetInterruptLimits); +DECLARE(tcs34725Enable); +DECLARE(tcs34725Disable); +DECLARE(tcs34725Setup); + +IMPLEMENT(tcs34725ReadRGBC) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, id); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int id = GET_ARGUMENT_AS_INT32(0); + unsigned short r, g, b, c; + + ::tcs34725ReadRGBC(id, &r, &g, &b, &c); + + Local obj = Object::New(); + obj->Set(String::NewSymbol("r"), UINT32(r)); + obj->Set(String::NewSymbol("g"), UINT32(g)); + obj->Set(String::NewSymbol("b"), UINT32(b)); + obj->Set(String::NewSymbol("c"), UINT32(c)); + + SCOPE_CLOSE(obj); +} + +IMPLEMENT(tcs34725GetCorrelatedColorTemperature) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, r); + SET_ARGUMENT_NAME(1, g); + SET_ARGUMENT_NAME(2, b); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_UINT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + CHECK_ARGUMENT_TYPE_UINT32(2); + + unsigned short r = GET_ARGUMENT_AS_UINT32(0); + unsigned short g = GET_ARGUMENT_AS_UINT32(1); + unsigned short b = GET_ARGUMENT_AS_UINT32(2); + + unsigned short k = ::tcs34725GetCorrelatedColorTemperature(r, g, b); + + SCOPE_CLOSE(UINT32(k)); +} + +IMPLEMENT(tcs34725GetIlluminance) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, r); + SET_ARGUMENT_NAME(1, g); + SET_ARGUMENT_NAME(2, b); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_UINT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + CHECK_ARGUMENT_TYPE_UINT32(2); + + unsigned short r = GET_ARGUMENT_AS_UINT32(0); + unsigned short g = GET_ARGUMENT_AS_UINT32(1); + unsigned short b = GET_ARGUMENT_AS_UINT32(2); + + unsigned short i = ::tcs34725GetIlluminance(r, g, b); + + SCOPE_CLOSE(UINT32(i)); +} + +IMPLEMENT(tcs34725SetInterrupt) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, id); + SET_ARGUMENT_NAME(1, aien); + + CHECK_ARGUMENTS_LENGTH_EQUAL(2); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + + int id = GET_ARGUMENT_AS_INT32(0); + int aien = GET_ARGUMENT_AS_INT32(1); + + ::tcs34725SetInterrupt(id, aien); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(tcs34725ClearInterrupt) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, id); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int id = GET_ARGUMENT_AS_INT32(0); + + ::tcs34725ClearInterrupt(id); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(tcs34725SetInterruptLimits) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, id); + SET_ARGUMENT_NAME(1, low); + SET_ARGUMENT_NAME(1, high); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_UINT32(1); + CHECK_ARGUMENT_TYPE_UINT32(2); + + int id = GET_ARGUMENT_AS_INT32(0); + int low = GET_ARGUMENT_AS_UINT32(1) & 0xFFFF; + int high = GET_ARGUMENT_AS_UINT32(2) & 0xFFFF; + + ::tcs34725SetInterruptLimits(id, low, high); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(tcs34725Enable) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, id); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int id = GET_ARGUMENT_AS_INT32(0); + + ::tcs34725Enable(id); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(tcs34725Disable) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, id); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int id = GET_ARGUMENT_AS_INT32(0); + + ::tcs34725Disable(id); + + SCOPE_CLOSE(UNDEFINED()); +} + +IMPLEMENT(tcs34725Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, i2cAddress); + SET_ARGUMENT_NAME(1, integrationTime); + SET_ARGUMENT_NAME(2, gain); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_INT32(2); + + int i2cAddress = GET_ARGUMENT_AS_INT32(0); + int integrationTime = GET_ARGUMENT_AS_INT32(1); + int gain = GET_ARGUMENT_AS_INT32(2); + + CHECK_ARGUMENT_IN_INTS(1, integrationTime, (TCS34725_ATIME_2_4MS, TCS34725_ATIME_24MS, TCS34725_ATIME_50MS, TCS34725_ATIME_101MS, TCS34725_ATIME_154MS, TCS34725_ATIME_700MS)); + CHECK_ARGUMENT_IN_INTS(2, gain, (TCS34725_GAIN_1, TCS34725_GAIN_4, TCS34725_GAIN_16, TCS34725_GAIN_60)); + + int id = ::tcs34725Setup(i2cAddress, integrationTime, gain); + + SCOPE_CLOSE(INT32(id)); +} + +IMPLEMENT_EXPORT_INIT(tcs34725) { + EXPORT_FUNCTION(tcs34725ReadRGBC); + EXPORT_FUNCTION(tcs34725GetCorrelatedColorTemperature); + EXPORT_FUNCTION(tcs34725GetIlluminance); + EXPORT_FUNCTION(tcs34725SetInterrupt); + EXPORT_FUNCTION(tcs34725ClearInterrupt); + EXPORT_FUNCTION(tcs34725SetInterruptLimits); + EXPORT_FUNCTION(tcs34725Enable); + EXPORT_FUNCTION(tcs34725Disable); + EXPORT_FUNCTION(tcs34725Setup); + + EXPORT_CONSTANT_INT(TCS34725_ATIME_2_4MS); + EXPORT_CONSTANT_INT(TCS34725_ATIME_24MS); + EXPORT_CONSTANT_INT(TCS34725_ATIME_50MS); + EXPORT_CONSTANT_INT(TCS34725_ATIME_101MS); + EXPORT_CONSTANT_INT(TCS34725_ATIME_154MS); + EXPORT_CONSTANT_INT(TCS34725_ATIME_700MS); + + EXPORT_CONSTANT_INT(TCS34725_GAIN_1); + EXPORT_CONSTANT_INT(TCS34725_GAIN_4); + EXPORT_CONSTANT_INT(TCS34725_GAIN_16); + EXPORT_CONSTANT_INT(TCS34725_GAIN_60); + + EXPORT_CONSTANT_INT(TCS34725_MAX_TCS34725); +} \ No newline at end of file diff --git a/src/devlib/tcs34725.h b/src/devlib/tcs34725.h new file mode 100644 index 0000000..7655481 --- /dev/null +++ b/src/devlib/tcs34725.h @@ -0,0 +1,8 @@ +#ifndef _WPI_TCS34725_H_ +#define _WPI_TCS34725_H_ + + #include "../addon.h" + + DECLARE_EXPORT_INIT(tcs34725); + +#endif \ No newline at end of file From f3d2b8e25d06b56f9c053efd8389ef88af4cacfe Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 16:15:29 +0200 Subject: [PATCH 42/64] tcs34725 support (experimental) --- binding.gyp | 3 ++- src/devlib/devlib.cc | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/binding.gyp b/binding.gyp index b122b75..7e83b4c 100644 --- a/binding.gyp +++ b/binding.gyp @@ -43,7 +43,8 @@ 'src/devlib/maxdetect.cc', 'src/devlib/piFace.cc', 'src/devlib/piGlow.cc', - 'src/devlib/piNes.cc' + 'src/devlib/piNes.cc', + 'src/devlib/tcs34725.cc' ], 'include_dirs': [ 'wiringpi/wiringPi', diff --git a/src/devlib/devlib.cc b/src/devlib/devlib.cc index bbb7103..ae4ec04 100644 --- a/src/devlib/devlib.cc +++ b/src/devlib/devlib.cc @@ -8,6 +8,7 @@ #include "piFace.h" #include "piGlow.h" #include "piNes.h" +#include "tcs34725.h" IMPLEMENT_EXPORT_INIT(devlib) { INIT(ds1302); @@ -18,4 +19,5 @@ IMPLEMENT_EXPORT_INIT(devlib) { INIT(piFace); INIT(piGlow); INIT(piNes); + INIT(tcs34725); } \ No newline at end of file From 6b219ba92ae49c1564e76b921660ba236192de16 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 16:17:21 +0200 Subject: [PATCH 43/64] fix tcs34725 compilation error --- src/devlib/tcs34725.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devlib/tcs34725.cc b/src/devlib/tcs34725.cc index 451e704..ed6a790 100644 --- a/src/devlib/tcs34725.cc +++ b/src/devlib/tcs34725.cc @@ -118,7 +118,7 @@ IMPLEMENT(tcs34725SetInterruptLimits) { SET_ARGUMENT_NAME(0, id); SET_ARGUMENT_NAME(1, low); - SET_ARGUMENT_NAME(1, high); + SET_ARGUMENT_NAME(2, high); CHECK_ARGUMENTS_LENGTH_EQUAL(3); From 9b5db433674d03d48a55827d82f51a011761ceab Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 20:32:12 +0200 Subject: [PATCH 44/64] libWiringPi as a submodule --- .gitignore | 1 - .gitmodules | 3 +++ install.sh | 8 ++++++-- wiringpi | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 .gitmodules create mode 160000 wiringpi diff --git a/.gitignore b/.gitignore index 1ad15a3..e2a5649 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ build npm-debug.log -wiringpi/ install.log \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c10aeaa --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "wiringpi"] + path = wiringpi + url = https://github.com/nekuz0r/wiringpi.git diff --git a/install.sh b/install.sh index 5d0e3bc..e28d080 100644 --- a/install.sh +++ b/install.sh @@ -39,8 +39,12 @@ check_git_clone() { rm ./install.log 2>/dev/null 1>&2 echo -n "Cloning libWiringPi ... " -rm -Rf ./wiringpi 2>/dev/null 1>&2 -git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 +#rm -Rf ./wiringpi 2>/dev/null 1>&2 +#git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 +#check_git_clone +git submodule init +check_git_clone +git submodule update check_git_clone echo "done." diff --git a/wiringpi b/wiringpi new file mode 160000 index 0000000..a939f02 --- /dev/null +++ b/wiringpi @@ -0,0 +1 @@ +Subproject commit a939f0223cccb01c7422e70419fa02ac6e1d5b9b From 5d1a329c45a272e770b1771eb4de662164590ae3 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 20:40:01 +0200 Subject: [PATCH 45/64] libWiringPi submodule switch to incoming branch --- .gitmodules | 1 + wiringpi | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index c10aeaa..a4252f7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "wiringpi"] path = wiringpi url = https://github.com/nekuz0r/wiringpi.git + branch = incoming diff --git a/wiringpi b/wiringpi index a939f02..6265f5a 160000 --- a/wiringpi +++ b/wiringpi @@ -1 +1 @@ -Subproject commit a939f0223cccb01c7422e70419fa02ac6e1d5b9b +Subproject commit 6265f5a8b59430cf8a17b8b26e0d49e574c8090c From 4d63f10f9e7e6b6f353ea9dcece4bfb7b5a8bc95 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 21:56:57 +0200 Subject: [PATCH 46/64] update documentation --- DOCUMENTATION.html | 392 ++++++++++++++++++++++++++++++------- docs/DOCUMENTATION.md | 443 +++++++++++++++++++++++++++++++++++------- 2 files changed, 695 insertions(+), 140 deletions(-) diff --git a/DOCUMENTATION.html b/DOCUMENTATION.html index c795b0e..ff9eccf 100644 --- a/DOCUMENTATION.html +++ b/DOCUMENTATION.html @@ -35,6 +35,7 @@
  • APIs
  • @@ -53,19 +55,29 @@

    Usage

    var wpi = require('wiring-pi');

    APIs

    Setup

    -

    wiringPiSetup()

    +

    wiringPiSetup()

    >= 0.1.0

    -

    Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. see the pins page (http://wiringpi.com/pins/) for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. This function needs to be called with root privileges.

    -

    wiringPiSetupGpio()

    +

    Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme.

    +

    This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers.

    +

    see the pins page for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector.

    +

    This function needs to be called with root privileges.

    +

    wiringPiSetupGpio()

    >= 0.1.1

    -

    This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards.

    -

    wiringPiSetupPhys()

    +

    This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping.

    +

    As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards.

    +

    wiringPiSetupPhys()

    >= 1.0.0

    -

    Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. As above, this function needs to be called with root priviliges.

    -

    wiringPiSetupSys()

    +

    Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only.

    +

    As above, this function needs to be called with root priviliges.

    +

    wiringPiSetupSys()

    >= 0.1.1

    -

    This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed).

    -

    setup(mode)

    +

    This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly.

    +

    This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program.

    +

    Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards.

    +

    NOTE: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program.

    +

    You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program.

    +

    Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed).

    +

    setup(mode)

    >= 0.1.1

    An handy function to setup wiringPi

    mode can be one of the following values:

    @@ -79,7 +91,7 @@

    setup(mode)

    NOTE: >= 2.0.0 no longer accept calling setup without mode specified. (defaulting to wpi in < 2.0.0)


    Core functions

    -

    pinModeAlt(pin, mode)

    +

    pinModeAlt(pin, mode)

    >= 1.0.0

    This is an un-documented special to let you set any pin to any mode.

    mode can be one of the following values:

    @@ -88,9 +100,12 @@

    pinModeAlt(pin, mode)

  • WPI_MODE_PHYS >= 1.0.0
  • WPI_MODE_GPIO >= 1.0.0
  • -

    pinMode(pin, mode)

    +

    pinMode(pin, mode)

    >= 0.1.0

    -

    This sets the mode of a pin. Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program.

    +

    This sets the mode of a pin.

    +

    Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes.

    +

    This function has no effect when in Sys mode.

    +

    If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program.

    mode can be one of the following values:

    • modes.INPUT >= 0.1.1 < 2.0.0 removed
    • @@ -104,146 +119,275 @@

      pinMode(pin, mode)

    • SOFT_PWM_OUTPUT >= 1.1.0
    • SOFT_TONE_OUTPUT >= 1.1.0
    -

    pullUpDnControl(pin, pud)

    +

    pullUpDnControl(pin, pud)

    >= 0.2.0

    -

    This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi.

    +

    This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input.

    +

    Unlike Arduino, the BCM2835 has both pull-up and down internal resistors.

    +

    The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi.

    pud can be one of the following values:

    • PUD_OFF no pull up/down >= 0.2.0
    • PUD_DOWN pull to ground >= 0.2.0
    • PUD_UP pull to 3.3v >= 0.2.0
    -

    digitalRead(pin)

    +

    digitalRead(pin)

    >= 0.1.1

    -

    This function returns the value read at the given pin. It will be HIGH (1) or LOW (0) depending on the logic level at the pin.

    -

    digitalWrite(pin, state)

    +

    This function returns the value read at the given pin.

    +

    It will be HIGH (1) or LOW (0) depending on the logic level at the pin.

    +

    digitalWrite(pin, state)

    >= 0.1.0

    -

    Write the value HIGH (1) or LOW (0) to the given pin which must have been previously set as an output. WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW.

    +

    Write the value HIGH (1) or LOW (0) to the given pin which must have been previously set as an output.

    +

    WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW.

    state can be one of the following value:

    • HIGH >= 0.1.2
    • LOW >= 0.1.2
    -

    pwmWrite(pin, value)

    +

    pwmWrite(pin, value)

    >= 0.1.1

    -

    Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024]. Other PWM devices may have other PWM ranges. This function is not able to control the Pi's on-board PWM when in Sys mode.

    -

    value must be in range of [0, 1024]

    -

    analogRead(pin)

    +

    Writes the value to the PWM register for the given pin.

    +

    The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024].

    +

    Other PWM devices may have other PWM ranges.

    +

    This function is not able to control the Pi's on-board PWM when in Sys mode.

    +

    analogRead(pin)

    >= 1.0.0

    -

    This returns the value read on the supplied analog input pin. You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc.

    -

    analogWrite(pin, value)

    +

    This returns the value read on the supplied analog input pin.

    +

    You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc.

    +

    analogWrite(pin, value)

    >= 1.0.0

    -

    This writes the given value to the supplied analog pin. You will need to register additional analog modules to enable this function for devices such as the Gertboard.

    -

    pulseIn(pin, state)

    +

    This writes the given value to the supplied analog pin.

    +

    You will need to register additional analog modules to enable this function for devices such as the Gertboard.

    +

    pulseIn(pin, state)

    >= 1.1.0

    +

    Reads a pulse (either HIGH or LOW) on a pin.

    +

    For example, if state is HIGH, pulseIn waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing.

    +

    Returns the length of the pulse in microseconds.

    +

    Gives up and returns 0 if no pulse starts within a specified time out.

    state can be one of the following values:

    • HIGH >= 0.1.2
    • LOW >= 0.1.2
    -

    delay(milliseconds)

    +

    delay(milliseconds)

    >= 1.1.0

    -

    delayMicroseconds(microseconds)

    +

    Pauses the program for the amount of time (in miliseconds) specified as parameter.

    +

    There are 1000 milliseconds in a second.

    +

    delayMicroseconds(microseconds)

    >= 1.1.0

    -

    millis()

    +

    Pauses the program for the amount of time (in microseconds) specified as parameter.

    +

    There are a thousand microseconds in a millisecond, and a million microseconds in a second.

    +

    For delays longer than a few thousand microseconds, you should use delay() instead.

    +

    millis()

    >= 1.1.0

    -

    micros()

    +

    Returns the number of milliseconds since the beginning running of the current program

    +

    micros()

    >= 1.1.0

    +

    Returns the number of microseconds since the beginning running of the current program

    +
    +

    Interrupts

    +

    wiringPiISR(pin, edgeType, callback)

    +

    >= 2.0.0

    +

    This function registers a function to received interrupts on the specified pin.

    +

    The edgeType parameter is either INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH or INT_EDGE_SETUP.

    +

    If it is INT_EDGE_SETUP then no initialisation of the pin will happen – it’s assumed that you have already setup the pin elsewhere (e.g. with the gpio program), but if you specify one of the other types, then the pin will be exported and initialised as specified.

    +

    This is accomplished via a suitable call to the gpio utility program, so it need to be available.

    +

    The pin number is supplied in the current mode – native wiringPi, BCM_GPIO, physical or Sys modes.

    +

    This function will work in any mode, and does not need root privileges to work.

    +

    The callback will be called when the interrupt triggers.

    +

    When it is triggered, it’s cleared in the dispatcher before calling your function, so if a subsequent interrupt fires before you finish your handler, then it won’t be missed.

    +

    However it can only track one more interrupt, if more than one interrupt fires while one is being handled then they will be ignored.

    +
    wpi.setup('wpi');
    +wpi.pinMode(7, wpi.INPUT);
    +wpi.pullUpDnControl(7, wpi.PUD_UP);
    +wpi.wiringPiISR(7, wpi.INT_EDGE_FALLING, function(delta) {
    +  console.log('Pin 7 changed to LOW (', delta, ')');
    +});

    Raspberry Pi hardware specific functions

    -

    piBoardRev()

    +

    piBoardRev()

    >= 0.1.1

    -

    This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences.

    -

    piBoardId()

    +

    This returns the board revision of the Raspberry Pi.

    +

    It will be either 1 or 2.

    +

    Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences.

    +

    piBoardId()

    >= 1.1.0

    -

    wpiPinToGpio(pin)

    +

    Do more digging into the board revision string as above, but return as much details as we can.

    +

    Returns an object with the following keys:

    +
      +
    • model: indexes to PI_MODEL_NAMES string table
    • +
    • rev: indexes to PI_REVISION_NAMES string table
    • +
    • mem: 256 or 512
    • +
    • maker: indexes to PI_MAKER_NAMES string table
    • +
    • overvolted: 0 or 1 >= 2.0.0
    • +
    +

    NOTE: maker was a string in versions >= 1.1.0 and < 2.0.0

    +

    Indexes of each string table have corresponding constants

    +
      +
    • PI_MODEL_NAME
    • +
    • PI_MODEL_UNKNOWN >= 2.0.0
    • +
    • PI_MODEL_A >= 1.1.0
    • +
    • PI_MODEL_B >= 1.1.0
    • +
    • PI_MODEL_BP >= 2.0.0
    • +
    • PI_MODEL_CM >= 1.1.1

    • +
    • PI_REVISION_NAMES
    • +
    • PI_VERSION_UNKNOWN >= 2.0.0
    • +
    • PI_VERSION_1 >= 2.0.0
    • +
    • PI_VERSION_1_1 >= 2.0.0
    • +
    • PI_VERSION_1_2 >= 2.0.0
    • +
    • PI_VERSION_2 >= 2.0.0

    • +
    • PI_MAKER_NAMES
    • +
    • PI_MAKER_UNKNOWN >= 2.0.0
    • +
    • PI_MAKER_EGOMAN >= 2.0.0
    • +
    • PI_MAKER_SONY >= 2.0.0
    • +
    • PI_MAKER_QISDA >= 2.0.0

    • +
    +

    wpiPinToGpio(pin)

    >= 1.0.0

    -

    This returns the BCM_GPIO pin number of the supplied wiringPi pin. It takes the board revision into account.

    -

    physPinToGpio(pin)

    +

    This returns the BCM_GPIO pin number of the supplied wiringPi pin.

    +

    It takes the board revision into account.

    +

    physPinToGpio(pin)

    >= 1.0.0

    This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector.

    -

    setPadDrive(group, value)

    +

    setPadDrive(group, value)

    >= 1.0.0

    -

    This sets the "strength" of the pad drivers for a particular group of pins. There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you know what you are doing.

    -

    getAlt(pin)

    +

    This sets the "strength" of the pad drivers for a particular group of pins.

    +

    There are 3 groups of pins and the drive strength is from 0 to 7.

    +

    NOTE: Do not use the unless you know what you are doing.

    +

    getAlt(pin)

    >= 1.0.0

    Returns the ALT bits for a given port.

    -

    digitalWriteByte(byte)

    +

    digitalWriteByte(byte)

    >= 1.0.0

    -

    This writes the 8-bit byte supplied to the first 8 GPIO pins. It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware.

    -

    pwmSetMode(mode)

    +

    This writes the 8-bit byte supplied to the first 8 GPIO pins.

    +

    It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware.

    +

    pwmSetMode(mode)

    >= 1.0.0

    -

    The PWM generator can run in 2 modes – “balanced” and “mark:space”. The mark:space mode is traditional, however the default mode in the Pi is “balanced”.

    +

    The PWM generator can run in 2 modes – “balanced” and “mark:space”.

    +

    The mark:space mode is traditional, however the default mode in the Pi is “balanced”.

    mode can be one of the following values:

    • PWM_MODE_BAL balanced
    • PWM_MODE_MS mark:space
    -

    pwmSetRange(range)

    +

    pwmSetRange(range)

    >= 0.1.1

    -

    This sets the range register in the PWM generator. The default is 1024. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

    -

    pwmSetClock(divisor)

    +

    This sets the range register in the PWM generator.

    +

    The default is 1024.

    +

    NOTE: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

    +

    pwmSetClock(divisor)

    >= 0.1.1

    -

    This sets the divisor for the PWM clock. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

    -

    gpioClockSet(pin, frequency)

    +

    This sets the divisor for the PWM clock.

    +

    NOTE: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

    +

    gpioClockSet(pin, frequency)

    >= 1.0.0

    Set the frequency on a GPIO clock pin


    I2C

    -

    wiringPiI2CSetup(devId)

    +

    wiringPiI2CSetup(devId)

    >= 2.0.0

    -

    wiringPiI2CSetupInterface(device, devId)

    +

    This initialises the I2C system with your given device identifier.

    +

    The ID is the I2C number of the device and you can use the i2cdetect program to find this out.

    +

    wiringPiI2CSetup() will work out which revision Raspberry Pi you have and open the appropriate device in /dev.

    +

    The return value is the standard Linux filehandle, or -1 if any error – in which case, you can consult errno as usual.

    +

    wiringPiI2CSetupInterface(device, devId)

    >= 2.0.0

    -

    wiringPiI2CRead(fd)

    +

    Undocumented access to set the interface explicitly - might be used for the Pi's 2nd I2C interface...

    +

    wiringPiI2CRead(fd)

    >= 2.0.0

    -

    wiringPiI2CReadReg8(fd, reg)

    +

    Simple device read.

    +

    Some devices present data when you read them without having to do any register transactions.

    +

    wiringPiI2CReadReg8(fd, reg)

    >= 2.0.0

    -

    wiringPiI2CReadReg16(fd, red)

    +

    This read an 8-bit value from the device register indicated.

    +

    wiringPiI2CReadReg16(fd, red)

    >= 2.0.0

    -

    wiringPiI2CWrite(fd, data)

    +

    This read an 16-bit value from the device register indicated.

    +

    wiringPiI2CWrite(fd, data)

    >= 2.0.0

    -

    wiringPiI2CWriteReg8(fd, reg, data)

    +

    Simple device write.

    +

    Some devices accept data this way without needing to access any internal registers.

    +

    wiringPiI2CWriteReg8(fd, reg, data)

    >= 2.0.0

    -

    wiringPiI2CWriteReg16(fd, reg, data)

    +

    This write an 8-bit data value into the device register indicated.

    +

    wiringPiI2CWriteReg16(fd, reg, data)

    >= 2.0.0

    +

    This write an 16-bit data value into the device register indicated.


    SPI

    -

    wiringPiSPIGetFd(channel)

    +

    wiringPiSPIGetFd(channel)

    >= 1.0.0

    -

    wiringPiSPIDataRW(channel, data)

    +

    Returns the file-descriptor for the given channel

    +

    wiringPiSPIDataRW(channel, data)

    >= 1.0.0

    -

    wiringPiSPISetup(channel, speed)

    +

    This performs a simultaneous write/read transaction over the selected SPI bus.

    +

    Data that was in your buffer is overwritten by data returned from the SPI bus.

    +

    It is possible to do simple read and writes over the SPI bus using the standard read() and write() system calls though – write() may be better to use for sending data to chains of shift registers, or those LED strings where you send RGB triplets of data.

    +

    Devices such as A/D and D/A converters usually need to perform a concurrent write/read transaction to work.

    +

    wiringPiSPISetup(channel, speed)

    >= 1.0.0

    +

    This is the way to initialise a channel (The Pi has 2 channels; 0 and 1).

    +

    The speed parameter is an integer in the range 500,000 through 32,000,000 and represents the SPI clock speed in Hz.

    +

    The returned value is the Linux file-descriptor for the device, or -1 on error.

    +

    If an error has happened, you may use the standard errno global variable to see why.


    Serial

    -

    serialOpen(device, baudrate)

    +

    serialOpen(device, baudrate)

    >= 1.0.0

    -

    serialClose(fd)

    +

    This opens and initialises the serial device and sets the baud rate.

    +

    It sets the port into “raw” mode (character at a time and no translations), and sets the read timeout to 10 seconds.

    +

    The return value is the file descriptor or -1 for any error, in which case errno will be set as appropriate.

    +

    NOTE: The file descriptor (fd) returned is a standard Linux file descriptor.

    +

    You can use the standard read(), write(), etc. system calls on this file descriptor as required.

    +

    E.g. you may wish to write a larger block of binary data where the serialPutchar() or serialPuts() function may not be the most appropriate function to use, in which case, you can use write() to send the data.

    +

    serialClose(fd)

    >= 1.0.0

    -

    serialFlush(fd)

    +

    Closes the device identified by the file descriptor given.

    +

    serialFlush(fd)

    >= 1.0.0

    -

    serialPutchar(fd, character)

    +

    This discards all data received, or waiting to be send down the given device.

    +

    serialPutchar(fd, character)

    >= 1.0.0

    -

    serialPuts(fd, string)

    +

    Sends the single byte to the serial device identified by the given file descriptor.

    +

    serialPuts(fd, string)

    >= 1.0.0

    -

    serialPrintf(fd, string)

    +

    Sends the nul-terminated string to the serial device identified by the given file descriptor.

    +

    serialPrintf(fd, string)

    Alias: serialPuts >= 2.0.0

    -

    serialDataAvail(fd)

    +

    serialDataAvail(fd)

    >= 1.0.0

    -

    serialGetchar(fd)

    +

    Returns the number of characters available for reading, or -1 for any error condition, in which case errno will be set appropriately.

    +

    serialGetchar(fd)

    >= 1.0.0

    +

    Returns the next character available on the serial device.

    +

    This call will block for up to 10 seconds if no data is available (when it will return -1)


    Shift

    -

    shiftIn(dPin, cPin, order)

    +

    shiftIn(dPin, cPin, order)

    >= 1.0.0

    -

    shiftOut(dPin, cPin, order, value)

    +

    This shifts an 8-bit data value in with the data appearing on the dPin and the clock being sent out on the cPin.

    +

    Order is either LSBFIRST or MSBFIRST.

    +

    The data is sampled after the cPin goes high. (So cPin high, sample data, cPin low, repeat for 8 bits) The 8-bit value is returned by the function.

    +

    shiftOut(dPin, cPin, order, value)

    >= 1.0.0

    +

    The shifts an 8-bit data value val out with the data being sent out on dPin and the clock being sent out on the cPin.

    +

    Order is as above.

    +

    Data is clocked out on the rising or falling edge – ie. dPin is set, then cPin is taken high then low – repeated for the 8 bits.


    Soft PWM

    -

    softPwmCreate(pin, value, range)

    +

    softPwmCreate(pin, value, range)

    >= 1.0.0

    +

    This creates a software controlled PWM pin.

    +

    You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used.

    +

    Use 100 for the pwmRange, then the value can be anything from 0 (off) to 100 (fully on) for the given pin.

    +

    The return value is 0 for success.

    +

    Anything else and you should check the global errno variable to see what went wrong.

    +

    NOTE: Each “cycle” of PWM output takes 10mS with the default range value of 100, so trying to change the PWM value more than 100 times a second will be futile.

    +

    NOTE: Each pin activated in softPWM mode uses approximately 0.5% of the CPU.

    +

    NOTE: You need to keep your program running to maintain the PWM output!

    softPwmWrite(pin, value)

    >= 1.0.0

    +

    This updates the PWM value on the given pin.

    +

    The value is checked to be in-range and pins that haven’t previously been initialised via softPwmCreate will be silently ignored.

    softPwmStop(pin)

    >= 1.1.0


    @@ -256,11 +400,119 @@

    softServoSetup(p0, p1, p2,

    Soft Tone

    softToneCreate(pin);

    >= 1.0.0

    +

    This creates a software controlled tone pin.

    +

    You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used.

    +

    The return value is 0 for success.

    +

    Anything else and you should check the global errno variable to see what went wrong.

    +

    NOTE: Each pin activated in softTone mode uses approximately 0.5% of the CPU.

    +

    NOTE: You need to keep your program running to maintain the sound output!

    softToneWrite(pin, frequency);

    >= 1.0.0

    +

    This updates the tone frequency value on the given pin.

    +

    The tone will be played until you set the frequency to 0.

    softToneStop(pin);

    >= 1.1.0


    Extensions

    +

    drcSerial

    +

    drcSetupSerial(pinBase, numPins, device, baudrate)

    +

    max31855

    +

    Cold-junction compensated thermocouple-to-digital converter (SPI)

    +

    max5322

    +

    12-Bit DAC (SPI)

    +

    max31855Setup(pinBase, spiChannel)

    +

    mcp23008

    +

    8-Bit I/O expander (I2C)

    +

    mcp23008Setup(pinBase, i2cAddress)

    +

    mcp23016

    +

    16-Bit I/O expander (I2C)

    +

    mcp23016Setup(pinBase, i2cAddress)

    +

    mpc23017

    +

    16-Bit I/O expander (I2C)

    +

    mcp23017Setup(pinBase, i2cAddress)

    +

    mcp23s08

    +

    8-Bit I/O expander (SPI)

    +

    mcp23s08Setup(pinBase, spiChannel, devId)

    +

    mcp23s17

    +

    16-Bit I/O expander (SPI)

    +

    mcp23s17Setup(pinBase, spiChannel, devId)

    +

    mcp3002

    +

    2-Channel 10-Bit ADC (SPI)

    +

    mcp3002Setup(pinBase, spiChannel)

    +

    mcp3004/8

    +

    4/8-Channel 10-Bit ADC (SPI)

    +

    mcp3004Setup(pinBase, spiChannel)

    +

    mcp3422/3/4

    +

    2/4-Channel 18-Bit ADC (I2C)

    +

    mcp3422Setup(pinBase, i2cAddress, sampleRate, gain)

    +

    mcp4802/12/22

    +

    2-Channel 8/10/12-Bit DAC (SPI)

    +

    mcp4802Setup(pinBase, spiChannel)

    +

    pca9685

    +

    16-Channel 12-Bit PWM led/servo driver (I2C)

    +

    pca9685Setup(pinBase, i2cAddress, frequency)

    +

    pcf8574

    +

    8-Bit I/O expander (I2C)

    +

    pcf8574Setup(pinBase, i2cAddress)

    +

    pcf8591

    +

    8-Bit ADC and DAC (I2C)

    +

    pcf8591Setup(pinBase, i2cAddress)

    +

    sn3218

    +

    18-Channel PWM led driver (I2C)

    +

    sn3218Setup(pinBase)

    +

    sr595

    +

    74x595 shift register

    +

    sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin)

    +
    +

    DevLib

    +

    ds1302

    +

    Trickle-charge timekeeping chip

    +

    ds1302setup(clockPin, dataPin, csPin)

    +

    ds1302rtcRead(reg)

    +

    ds1302rtcWrite(reg, data)

    +

    ds1302ramRead(address)

    +

    ds1302ramWrite(address, data)

    +

    ds1302clockRead()

    +

    ds1302clockWrite(clockData[8])

    +

    ds1302trickleCharge(diodes, resistors)

    +

    GertBoard

    +

    getboardAnalogSetup(pinBase)

    +

    LCD

    +

    lcdInit(rows, cols, bits, rs, strb, d0, d1, d2, d3, d4, d5, d6, d7)

    +

    lcdHome(fd)

    +

    lcdClear(fd)

    +

    lcdDisplay(fd, state)

    +

    lcdCursor(fd, state)

    +

    lcdCursorBlink(fd, state)

    +

    lcdSendCommand(fd, command)

    +

    lcdPosition(fd, x, y)

    +

    lcdCharDef(fd, index, data[8])

    +

    lcdPutchar(fd, character)

    +

    lcdPuts(fd, string)

    +

    lcdPrintf(fd, string)

    +

    LCD 128x64

    +

    MaxDetect

    +

    maxDetectRead(pin)

    +

    readRHT03(pin)

    +

    piFace

    +

    piFaceSetup(pinBase)

    +

    piGlow

    +

    piGlowSetup(clear)

    +

    piGlow1(leg, ring, intensity)

    +

    piGlowLeg(leg, intensity)

    +

    piGlowRing(ring, intensity)

    +

    piNes

    +

    setupNesJoystick(dPin, cPin, lPin)

    +

    readNesJoystick(joystick)

    +

    tcs34725

    +

    tcs34725ReadRGBC(id)

    +

    tcs34725GetCorrelatedColorTemperature(r, g, b)

    +

    tcs34725GetIlluminance(r, g, b)

    +

    tcs34725SetInterrupt(id, aien)

    +

    tcs34725ClearInterrupt(id)

    +

    tcs34725SetInterruptLimits(id, low, high)

    +

    tcs34725Enable(id)

    +

    tcs34725Disable(id)

    +

    tcs34725Setup(i2cAddress, integrationTime, gain)

    diff --git a/docs/DOCUMENTATION.md b/docs/DOCUMENTATION.md index f095de6..0bf44e6 100644 --- a/docs/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -14,30 +14,47 @@ var wpi = require('wiring-pi'); ## Setup -### `wiringPiSetup()` +### wiringPiSetup() >= 0.1.0 Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. + This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. + see the [pins](http://wiringpi.com/pins/) page for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector. + This function needs to be called with root privileges. -### `wiringPiSetupGpio()` +### wiringPiSetupGpio() >= 0.1.1 -This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards. +This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. -### `wiringPiSetupPhys()` +As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards. + +### wiringPiSetupPhys() >= 1.0.0 -Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. As above, this function needs to be called with root priviliges. +Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only. + +As above, this function needs to be called with root priviliges. -### `wiringPiSetupSys()` +### wiringPiSetupSys() >= 0.1.1 -This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program. Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed). +This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. + +This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program. + +Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards. + +**NOTE: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program.** + +**You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program.** -### `setup(mode)` +**Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed).** + +### setup(mode) >= 0.1.1 An handy function to setup wiringPi @@ -61,7 +78,7 @@ More info about pin numbering systems at [wiringpi.com/pins/](http://wiringpi.co ## Core functions -### `pinModeAlt(pin, mode)` +### pinModeAlt(pin, mode) >= 1.0.0 This is an un-documented special to let you set any pin to any mode. @@ -75,10 +92,16 @@ This is an un-documented special to let you set any pin to any mode. * `WPI_MODE_GPIO` >= 1.0.0 -### `pinMode(pin, mode)` +### pinMode(pin, mode) >= 0.1.0 -This sets the mode of a pin. Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. This function has no effect when in Sys mode. If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program. +This sets the mode of a pin. + +Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. + +This function has no effect when in Sys mode. + +If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program. `mode` can be one of the following values: @@ -103,10 +126,14 @@ This sets the mode of a pin. Note that only wiringPi pin 1 (BCM_GPIO 18) support * `SOFT_TONE_OUTPUT` >= 1.1.0 -### `pullUpDnControl(pin, pud)` +### pullUpDnControl(pin, pud) >= 0.2.0 -This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. +This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. + +Unlike Arduino, the BCM2835 has both pull-up and down internal resistors. + +The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi. `pud` can be one of the following values: @@ -117,15 +144,19 @@ This sets the pull-up or pull-down resistor mode on the given pin, which should * `PUD_UP` *pull to 3.3v* >= 0.2.0 -### `digitalRead(pin)` +### digitalRead(pin) >= 0.1.1 -This function returns the value read at the given pin. It will be `HIGH` (1) or `LOW` (0) depending on the logic level at the pin. +This function returns the value read at the given pin. -### `digitalWrite(pin, state)` +It will be `HIGH` (1) or `LOW` (0) depending on the logic level at the pin. + +### digitalWrite(pin, state) >= 0.1.0 -Write the value `HIGH` (1) or `LOW` (0) to the given pin which must have been previously set as an output. WiringPi treats any non-zero number as `HIGH`, however 0 is the only representation of `LOW`. +Write the value `HIGH` (1) or `LOW` (0) to the given pin which must have been previously set as an output. + +WiringPi treats any non-zero number as `HIGH`, however 0 is the only representation of `LOW`. `state` can be one of the following value: @@ -134,26 +165,42 @@ Write the value `HIGH` (1) or `LOW` (0) to the given pin which must have been pr * `LOW` >= 0.1.2 -### `pwmWrite(pin, value)` +### pwmWrite(pin, value) >= 0.1.1 -Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024]. Other PWM devices may have other PWM ranges. This function is not able to control the Pi's on-board PWM when in Sys mode. +Writes the value to the PWM register for the given pin. -`value` must be in range of [0, 1024] +The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024]. -### `analogRead(pin)` +Other PWM devices may have other PWM ranges. + +This function is not able to control the Pi's on-board PWM when in Sys mode. + +### analogRead(pin) >= 1.0.0 -This returns the value read on the supplied analog input pin. You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc. +This returns the value read on the supplied analog input pin. + +You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc. -### `analogWrite(pin, value)` +### analogWrite(pin, value) >= 1.0.0 -This writes the given value to the supplied analog pin. You will need to register additional analog modules to enable this function for devices such as the Gertboard. +This writes the given value to the supplied analog pin. -### `pulseIn(pin, state)` +You will need to register additional analog modules to enable this function for devices such as the Gertboard. + +### pulseIn(pin, state) >= 1.1.0 +Reads a pulse (either HIGH or LOW) on a pin. + +For example, if `state` is HIGH, pulseIn waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. + +Returns the length of the pulse in microseconds. + +Gives up and returns 0 if no pulse starts within a specified time out. + `state` can be one of the following values: * `HIGH` @@ -161,76 +208,194 @@ This writes the given value to the supplied analog pin. You will need to registe * `LOW` >= 0.1.2 -### `delay(milliseconds)` +### delay(milliseconds) >= 1.1.0 -### `delayMicroseconds(microseconds)` +Pauses the program for the amount of time (in miliseconds) specified as parameter. + +There are 1000 milliseconds in a second. + +### delayMicroseconds(microseconds) >= 1.1.0 -### `millis()` +Pauses the program for the amount of time (in microseconds) specified as parameter. + +There are a thousand microseconds in a millisecond, and a million microseconds in a second. + +For delays longer than a few thousand microseconds, you should use delay() instead. + +### millis() >= 1.1.0 -### `micros()` +Returns the number of milliseconds since the beginning running of the current program + +### micros() >= 1.1.0 +Returns the number of microseconds since the beginning running of the current program + +--- + +## Interrupts + +### wiringPiISR(pin, edgeType, callback) + >= 2.0.0 + +This function registers a function to received interrupts on the specified pin. + +The edgeType parameter is either `INT_EDGE_FALLING`, `INT_EDGE_RISING`, `INT_EDGE_BOTH` or `INT_EDGE_SETUP`. + +If it is `INT_EDGE_SETUP` then no initialisation of the pin will happen – it’s assumed that you have already setup the pin elsewhere (e.g. with the gpio program), but if you specify one of the other types, then the pin will be exported and initialised as specified. + +This is accomplished via a suitable call to the gpio utility program, so it need to be available. + +The pin number is supplied in the current mode – native wiringPi, BCM_GPIO, physical or Sys modes. + +This function will work in any mode, and does not need root privileges to work. + +The callback will be called when the interrupt triggers. + +When it is triggered, it’s cleared in the dispatcher before calling your function, so if a subsequent interrupt fires before you finish your handler, then it won’t be missed. + +However it can only track one more interrupt, if more than one interrupt fires while one is being handled then they will be ignored. + +```javascript +wpi.setup('wpi'); +wpi.pinMode(7, wpi.INPUT); +wpi.pullUpDnControl(7, wpi.PUD_UP); +wpi.wiringPiISR(7, wpi.INT_EDGE_FALLING, function(delta) { + console.log('Pin 7 changed to LOW (', delta, ')'); +}); +``` + --- ## Raspberry Pi hardware specific functions -### `piBoardRev()` +### piBoardRev() >= 0.1.1 -This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. +This returns the board revision of the Raspberry Pi. + +It will be either 1 or 2. + +Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences. -### `piBoardId()` +### piBoardId() >= 1.1.0 -### `wpiPinToGpio(pin)` +Do more digging into the board revision string as above, but return as much details as we can. + +Returns an object with the following keys: + +* `model`: indexes to `PI_MODEL_NAMES` string table +* `rev`: indexes to `PI_REVISION_NAMES` string table +* `mem`: 256 or 512 +* `maker`: indexes to `PI_MAKER_NAMES` string table +* `overvolted`: 0 or 1 + >= 2.0.0 + +**NOTE: `maker` was a string in versions >= 1.1.0 and < 2.0.0** + +Indexes of each string table have corresponding constants + +* `PI_MODEL_NAME` + * `PI_MODEL_UNKNOWN` + >= 2.0.0 + * `PI_MODEL_A` + >= 1.1.0 + * `PI_MODEL_B` + >= 1.1.0 + * `PI_MODEL_BP` + >= 2.0.0 + * `PI_MODEL_CM` + >= 1.1.1 + + +* `PI_REVISION_NAMES` + * `PI_VERSION_UNKNOWN` + >= 2.0.0 + * `PI_VERSION_1` + >= 2.0.0 + * `PI_VERSION_1_1` + >= 2.0.0 + * `PI_VERSION_1_2` + >= 2.0.0 + * `PI_VERSION_2` + >= 2.0.0 + +* `PI_MAKER_NAMES` + * `PI_MAKER_UNKNOWN` + >= 2.0.0 + * `PI_MAKER_EGOMAN` + >= 2.0.0 + * `PI_MAKER_SONY` + >= 2.0.0 + * `PI_MAKER_QISDA` + >= 2.0.0 + +### wpiPinToGpio(pin) >= 1.0.0 -This returns the BCM_GPIO pin number of the supplied wiringPi pin. It takes the board revision into account. +This returns the BCM_GPIO pin number of the supplied wiringPi pin. -### `physPinToGpio(pin)` +It takes the board revision into account. + +### physPinToGpio(pin) >= 1.0.0 This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector. -### `setPadDrive(group, value)` +### setPadDrive(group, value) >= 1.0.0 -This sets the "strength" of the pad drivers for a particular group of pins. There are 3 groups of pins and the drive strength is from 0 to 7. Do not use the unless you know what you are doing. +This sets the "strength" of the pad drivers for a particular group of pins. + +There are 3 groups of pins and the drive strength is from 0 to 7. -### `getAlt(pin)` +**NOTE: Do not use the unless you know what you are doing.** + +### getAlt(pin) >= 1.0.0 Returns the ALT bits for a given port. -### `digitalWriteByte(byte)` +### digitalWriteByte(byte) >= 1.0.0 -This writes the 8-bit byte supplied to the first 8 GPIO pins. It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware. +This writes the 8-bit byte supplied to the first 8 GPIO pins. + +It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware. -### `pwmSetMode(mode)` +### pwmSetMode(mode) >= 1.0.0 -The PWM generator can run in 2 modes – “balanced” and “mark:space”. The mark:space mode is traditional, however the default mode in the Pi is “balanced”. +The PWM generator can run in 2 modes – “balanced” and “mark:space”. + +The mark:space mode is traditional, however the default mode in the Pi is “balanced”. `mode` can be one of the following values: * `PWM_MODE_BAL` *balanced* * `PWM_MODE_MS` *mark:space* -### `pwmSetRange(range)` +### pwmSetRange(range) >= 0.1.1 -This sets the range register in the PWM generator. The default is 1024. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. +This sets the range register in the PWM generator. + +The default is 1024. -### `pwmSetClock(divisor)` +**NOTE: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.** + +### pwmSetClock(divisor) >= 0.1.1 -This sets the divisor for the PWM clock. Note: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual. +This sets the divisor for the PWM clock. + +**NOTE: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.** -### `gpioClockSet(pin, frequency)` +### gpioClockSet(pin, frequency) >= 1.0.0 Set the frequency on a GPIO clock pin @@ -239,94 +404,196 @@ Set the frequency on a GPIO clock pin ## I2C -### `wiringPiI2CSetup(devId)` +### wiringPiI2CSetup(devId) >= 2.0.0 -### `wiringPiI2CSetupInterface(device, devId)` +This initialises the I2C system with your given device identifier. + +The ID is the I2C number of the device and you can use the i2cdetect program to find this out. + +wiringPiI2CSetup() will work out which revision Raspberry Pi you have and open the appropriate device in /dev. + +The return value is the standard Linux filehandle, or -1 if any error – in which case, you can consult errno as usual. + +### wiringPiI2CSetupInterface(device, devId) >= 2.0.0 -### `wiringPiI2CRead(fd)` +Undocumented access to set the interface explicitly - might be used for the Pi's 2nd I2C interface... + +### wiringPiI2CRead(fd) >= 2.0.0 -### `wiringPiI2CReadReg8(fd, reg)` +Simple device read. + +Some devices present data when you read them without having to do any register transactions. + +### wiringPiI2CReadReg8(fd, reg) >= 2.0.0 -### `wiringPiI2CReadReg16(fd, red)` +This read an 8-bit value from the device register indicated. + +### wiringPiI2CReadReg16(fd, red) >= 2.0.0 -### `wiringPiI2CWrite(fd, data)` +This read an 16-bit value from the device register indicated. + +### wiringPiI2CWrite(fd, data) >= 2.0.0 -### `wiringPiI2CWriteReg8(fd, reg, data)` +Simple device write. + +Some devices accept data this way without needing to access any internal registers. + +### wiringPiI2CWriteReg8(fd, reg, data) >= 2.0.0 -### `wiringPiI2CWriteReg16(fd, reg, data)` +This write an 8-bit data value into the device register indicated. + +### wiringPiI2CWriteReg16(fd, reg, data) >= 2.0.0 +This write an 16-bit data value into the device register indicated. + --- ## SPI -### `wiringPiSPIGetFd(channel)` +### wiringPiSPIGetFd(channel) >= 1.0.0 -### `wiringPiSPIDataRW(channel, data)` +Returns the file-descriptor for the given channel + +### wiringPiSPIDataRW(channel, data) >= 1.0.0 -### `wiringPiSPISetup(channel, speed)` +This performs a simultaneous write/read transaction over the selected SPI bus. + +Data that was in your buffer is overwritten by data returned from the SPI bus. + +It is possible to do simple read and writes over the SPI bus using the standard read() and write() system calls though – write() may be better to use for sending data to chains of shift registers, or those LED strings where you send RGB triplets of data. + +Devices such as A/D and D/A converters usually need to perform a concurrent write/read transaction to work. + +### wiringPiSPISetup(channel, speed) >= 1.0.0 +This is the way to initialise a channel (The Pi has 2 channels; 0 and 1). + +The speed parameter is an integer in the range 500,000 through 32,000,000 and represents the SPI clock speed in Hz. + +The returned value is the Linux file-descriptor for the device, or -1 on error. + +If an error has happened, you may use the standard errno global variable to see why. + --- ## Serial -### `serialOpen(device, baudrate)` +### serialOpen(device, baudrate) >= 1.0.0 -### `serialClose(fd)` +This opens and initialises the serial device and sets the baud rate. + +It sets the port into “raw” mode (character at a time and no translations), and sets the read timeout to 10 seconds. + +The return value is the file descriptor or -1 for any error, in which case errno will be set as appropriate. + +**NOTE: The file descriptor (fd) returned is a standard Linux file descriptor.** + +**You can use the standard read(), write(), etc. system calls on this file descriptor as required.** + +**E.g. you may wish to write a larger block of binary data where the serialPutchar() or serialPuts() function may not be the most appropriate function to use, in which case, you can use write() to send the data.** + +### serialClose(fd) >= 1.0.0 -### `serialFlush(fd)` +Closes the device identified by the file descriptor given. + +### serialFlush(fd) >= 1.0.0 -### `serialPutchar(fd, character)` +This discards all data received, or waiting to be send down the given device. + +### serialPutchar(fd, character) >= 1.0.0 -### `serialPuts(fd, string)` +Sends the single byte to the serial device identified by the given file descriptor. + +### serialPuts(fd, string) >= 1.0.0 -### `serialPrintf(fd, string)` +Sends the nul-terminated string to the serial device identified by the given file descriptor. + +### serialPrintf(fd, string) Alias: serialPuts >= 2.0.0 -### `serialDataAvail(fd)` +### serialDataAvail(fd) >= 1.0.0 -### `serialGetchar(fd)` +Returns the number of characters available for reading, or -1 for any error condition, in which case errno will be set appropriately. + +### serialGetchar(fd) >= 1.0.0 +Returns the next character available on the serial device. + +This call will block for up to 10 seconds if no data is available (when it will return -1) + --- ## Shift -### `shiftIn(dPin, cPin, order)` +### shiftIn(dPin, cPin, order) >= 1.0.0 -### `shiftOut(dPin, cPin, order, value)` +This shifts an 8-bit data value in with the data appearing on the dPin and the clock being sent out on the cPin. + +Order is either `LSBFIRST` or `MSBFIRST`. + +The data is sampled after the cPin goes high. (So cPin high, sample data, cPin low, repeat for 8 bits) The 8-bit value is returned by the function. + +### shiftOut(dPin, cPin, order, value) >= 1.0.0 +The shifts an 8-bit data value val out with the data being sent out on dPin and the clock being sent out on the cPin. + +Order is as above. + +Data is clocked out on the rising or falling edge – ie. dPin is set, then cPin is taken high then low – repeated for the 8 bits. + --- ## Soft PWM -### `softPwmCreate(pin, value, range)` +### softPwmCreate(pin, value, range) >= 1.0.0 +This creates a software controlled PWM pin. + +You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. + +Use 100 for the pwmRange, then the value can be anything from 0 (off) to 100 (fully on) for the given pin. + +The return value is 0 for success. + +Anything else and you should check the global errno variable to see what went wrong. + +**NOTE: Each “cycle” of PWM output takes 10mS with the default range value of 100, so trying to change the PWM value more than 100 times a second will be futile.** + +**NOTE: Each pin activated in softPWM mode uses approximately 0.5% of the CPU.** + +**NOTE: You need to keep your program running to maintain the PWM output!** + ### `softPwmWrite(pin, value)` >= 1.0.0 +This updates the PWM value on the given pin. + +The value is checked to be in-range and pins that haven’t previously been initialised via softPwmCreate will be silently ignored. + ### `softPwmStop(pin)` >= 1.1.0 @@ -347,9 +614,25 @@ Set the frequency on a GPIO clock pin ### `softToneCreate(pin);` >= 1.0.0 +This creates a software controlled tone pin. + +You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used. + +The return value is 0 for success. + +Anything else and you should check the global errno variable to see what went wrong. + +**NOTE: Each pin activated in softTone mode uses approximately 0.5% of the CPU.** + +**NOTE: You need to keep your program running to maintain the sound output!** + ### `softToneWrite(pin, frequency);` >= 1.0.0 +This updates the tone frequency value on the given pin. + +The tone will be played until you set the frequency to 0. + ### `softToneStop(pin);` >= 1.1.0 @@ -535,4 +818,24 @@ Trickle-charge timekeeping chip #### `setupNesJoystick(dPin, cPin, lPin)` -#### `readNesJoystick(joystick)` \ No newline at end of file +#### `readNesJoystick(joystick)` + +### tcs34725 + +#### `tcs34725ReadRGBC(id)` + +#### `tcs34725GetCorrelatedColorTemperature(r, g, b)` + +#### `tcs34725GetIlluminance(r, g, b)` + +#### `tcs34725SetInterrupt(id, aien)` + +#### `tcs34725ClearInterrupt(id)` + +#### `tcs34725SetInterruptLimits(id, low, high)` + +#### `tcs34725Enable(id)` + +#### `tcs34725Disable(id)` + +#### `tcs34725Setup(i2cAddress, integrationTime, gain)` \ No newline at end of file From ec1abc88aab037caf1e7701a27787c8bf8c898e7 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Wed, 23 Jul 2014 22:23:36 +0200 Subject: [PATCH 47/64] update documentation --- docs/DOCUMENTATION.md | 234 +++++++++++++++++++++++++++++++----------- 1 file changed, 172 insertions(+), 62 deletions(-) diff --git a/docs/DOCUMENTATION.md b/docs/DOCUMENTATION.md index 0bf44e6..4dcccfb 100644 --- a/docs/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -587,31 +587,31 @@ Anything else and you should check the global errno variable to see what went wr **NOTE: You need to keep your program running to maintain the PWM output!** -### `softPwmWrite(pin, value)` +### softPwmWrite(pin, value) >= 1.0.0 This updates the PWM value on the given pin. The value is checked to be in-range and pins that haven’t previously been initialised via softPwmCreate will be silently ignored. -### `softPwmStop(pin)` +### softPwmStop(pin) >= 1.1.0 --- ## Soft Servo -### `softServoWrite(pin, value)` +### softServoWrite(pin, value) >= 1.0.0 -### `softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7)` +### softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7) >= 1.0.0 --- ## Soft Tone -### `softToneCreate(pin);` +### softToneCreate(pin); >= 1.0.0 This creates a software controlled tone pin. @@ -626,14 +626,14 @@ Anything else and you should check the global errno variable to see what went wr **NOTE: You need to keep your program running to maintain the sound output!** -### `softToneWrite(pin, frequency);` +### softToneWrite(pin, frequency); >= 1.0.0 This updates the tone frequency value on the given pin. The tone will be played until you set the frequency to 0. -### `softToneStop(pin);` +### softToneStop(pin); >= 1.1.0 --- @@ -642,101 +642,103 @@ The tone will be played until you set the frequency to 0. ### drcSerial -#### `drcSetupSerial(pinBase, numPins, device, baudrate)` +#### drcSetupSerial(pinBase, numPins, device, baudrate) ### max31855 Cold-junction compensated thermocouple-to-digital converter (SPI) +#### max31855Setup(pinBase, spiChannel) + ### max5322 12-Bit DAC (SPI) -#### `max31855Setup(pinBase, spiChannel)` +#### max5322Setup(pinBase, spiChannel) ### mcp23008 8-Bit I/O expander (I2C) -#### `mcp23008Setup(pinBase, i2cAddress)` +#### mcp23008Setup(pinBase, i2cAddress) ### mcp23016 16-Bit I/O expander (I2C) -#### `mcp23016Setup(pinBase, i2cAddress)` +#### mcp23016Setup(pinBase, i2cAddress) ### mpc23017 16-Bit I/O expander (I2C) -#### `mcp23017Setup(pinBase, i2cAddress)` +#### mcp23017Setup(pinBase, i2cAddress) ### mcp23s08 8-Bit I/O expander (SPI) -#### `mcp23s08Setup(pinBase, spiChannel, devId)` +#### mcp23s08Setup(pinBase, spiChannel, devId) ### mcp23s17 16-Bit I/O expander (SPI) -#### `mcp23s17Setup(pinBase, spiChannel, devId)` +#### mcp23s17Setup(pinBase, spiChannel, devId) ### mcp3002 2-Channel 10-Bit ADC (SPI) -#### `mcp3002Setup(pinBase, spiChannel)` +#### mcp3002Setup(pinBase, spiChannel) ### mcp3004/8 4/8-Channel 10-Bit ADC (SPI) -#### `mcp3004Setup(pinBase, spiChannel)` +#### mcp3004Setup(pinBase, spiChannel) ### mcp3422/3/4 2/4-Channel 18-Bit ADC (I2C) -#### `mcp3422Setup(pinBase, i2cAddress, sampleRate, gain)` +#### mcp3422Setup(pinBase, i2cAddress, sampleRate, gain) ### mcp4802/12/22 2-Channel 8/10/12-Bit DAC (SPI) -#### `mcp4802Setup(pinBase, spiChannel)` +#### mcp4802Setup(pinBase, spiChannel) ### pca9685 16-Channel 12-Bit PWM led/servo driver (I2C) -#### `pca9685Setup(pinBase, i2cAddress, frequency)` +#### pca9685Setup(pinBase, i2cAddress, frequency) ### pcf8574 8-Bit I/O expander (I2C) -#### `pcf8574Setup(pinBase, i2cAddress)` +#### pcf8574Setup(pinBase, i2cAddress) ### pcf8591 8-Bit ADC and DAC (I2C) -#### `pcf8591Setup(pinBase, i2cAddress)` +#### pcf8591Setup(pinBase, i2cAddress) ### sn3218 18-Channel PWM led driver (I2C) -#### `sn3218Setup(pinBase)` +#### sn3218Setup(pinBase) ### sr595 74x595 shift register -#### `sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin)` +#### sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin) --- @@ -746,96 +748,204 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) Trickle-charge timekeeping chip -#### `ds1302setup(clockPin, dataPin, csPin)` +#### ds1302setup(clockPin, dataPin, csPin) -#### `ds1302rtcRead(reg)` +#### ds1302rtcRead(reg) -#### `ds1302rtcWrite(reg, data)` +#### ds1302rtcWrite(reg, data) -#### `ds1302ramRead(address)` +#### ds1302ramRead(address) -#### `ds1302ramWrite(address, data)` +#### ds1302ramWrite(address, data) -#### `ds1302clockRead()` +#### ds1302clockRead() -#### `ds1302clockWrite(clockData[8])` +#### ds1302clockWrite(clockData[8]) -#### `ds1302trickleCharge(diodes, resistors)` +#### ds1302trickleCharge(diodes, resistors) ### GertBoard -#### `getboardAnalogSetup(pinBase)` +#### getboardAnalogSetup(pinBase) + +pinBase is the base pin that you want the analog ports to appear as. + +The setup routine allocates 2 pins and overlays the analog to digital input pins with the digital to analog output pins. + +So reading channel pinBase + 0 reads the first analog input channel (pin DA0 on the Gertboard), and writing pinBase + 0 outputs to the first analog output channel. (Pin AD0). + +**NOTE: The analog interface chips on the Gertboard are connected to the SPI bus. You need to load the SPI kernel modules with gpio load spi and make sure that the 5 SPI jumpers are in-place on the Gertboard – pins SCLK, MOSI, MISO, CSnA and CSnB.** + +**NOTE: The analog to digital convertor is a 10-bit device. Values returned will be in the range 0-1023 representing an input voltage of 0 to 3.3 volts.** + +**NOTE: Input Voltage calculation: volts = analogIn * 3.3 / 1023** + +**NOTE: The digital to analog converter is an 8-bit device. Values sent to it should be in the range 0-255 representing an output voltage on 0 to 2.047 volts.** + +**NOTE: Output voltage calculation: volts = analogOut / 255 * 2.047** + +**NOTE: The gpio program has commands to directly read and write the analog ports on the Gertboard: gpio gbr 0 will read input channel 0, gpio gbw 1 55 will write the value 55 output channel 1.** ### LCD -#### `lcdInit(rows, cols, bits, rs, strb, d0, d1, d2, d3, d4, d5, d6, d7)` +#### lcdInit(rows, cols, bits, rs, strb, d0, d1, d2, d3, d4, d5, d6, d7) + +This is the main initialisation function and must be called before you use any other LCD functions. + +Rows and cols are the rows and columns on the display (e.g. 2, 16 or 4,20). + +Bits is the number of bits wide on the interface (4 or 8). + +The rs and strb represent the pin numbers of the displays RS pin and Strobe (E) pin. + +The parameters d0 through d7 are the pin numbers of the 8 data pins connected from the Pi to the display. + +Only the first 4 are used if you are running the display in 4-bit mode. + +The return value is the ‘handle’ to be used for all subsequent calls to the lcd library when dealing with that LCD, or -1 to indicate a fault. (Usually incorrect parameters) + +#### lcdHome(fd) + +This home the cursor + +#### lcdClear(fd) + +This clear the screen + +#### lcdDisplay(fd, state) + +This turns the display on or off + +#### lcdCursor(fd, state) + +This turns the cursor on or off + +#### lcdCursorBlink(fd, state) + +This turns blinking cursor on or off + +#### lcdSendCommand(fd, command) -#### `lcdHome(fd)` +#### lcdPosition(fd, x, y) -#### `lcdClear(fd)` +Set the position of the cursor for subsequent text entry. -#### `lcdDisplay(fd, state)` +x is the column and 0 is the left-most edge. -#### `lcdCursor(fd, state)` +y is the line and 0 is the top line. -#### `lcdCursorBlink(fd, state)` +#### lcdCharDef(fd, index, data[8]) -#### `lcdSendCommand(fd, command)` +This allows you to re-define one of the 8 user-definable chanracters in the display. -#### `lcdPosition(fd, x, y)` +The data array is 8 bytes which represent the character from the top-line to the bottom line. -#### `lcdCharDef(fd, index, data[8])` +Note that the characters are actually 5×8, so only the lower 5 bits are used. -#### `lcdPutchar(fd, character)` +The index is from 0 to 7 and you can subsequently print the character defined using the lcdPutchar() call. -#### `lcdPuts(fd, string)` +#### lcdPutchar(fd, character) -#### `lcdPrintf(fd, string)` +#### lcdPuts(fd, string) + +#### lcdPrintf(fd, string) ### LCD 128x64 ### MaxDetect -#### `maxDetectRead(pin)` +#### maxDetectRead(pin) -#### `readRHT03(pin)` +#### readRHT03(pin) ### piFace -#### `piFaceSetup(pinBase)` +#### piFaceSetup(pinBase) + +pinBase is the base pin that you want your PiFace to appear as – the examples provided use 200 as the base pin. + +The setup assigns 32 pins, although the way it works is to overlay the 8 input pins with the 8 output pins. + +So you read from pin base + 0 to read the first input pin, and write to base + 0 to write to the first output pin. + +To read the state of the output latch, read from pin + 8 + outputPin. + +The remaining 16 pins are used by the underlying MCP23S17 driver and should not be used directly. + +**NOTE: The PiFace uses the MCP23S17 SPI GPIO expansion chip so you need to load the SPI kernel driver first. Use the gpio command: gpio load spi** + +**NOTE: If you want to use the input pins as outputs, then you need to use the mcp23s17 expansion module for wiringPI instead of the piFace expansion. Then setting up is relatively straighforward – pins 0 through 7 are the output pins, and 8 through 15 are the normal input pins which you can use pinMode() on to change to outputs, if required.** + +**NOTE: The gpio command supports the PiFace board directly using the -p flag, but assumes the pin-base is 200. So gpio -p write 200 1 will set the first output pin high – that’s the first relay.** ### piGlow -#### `piGlowSetup(clear)` +#### piGlowSetup(clear) + +This initialises the PiGlow devLib software. + +You need to make sure the I2C kernel module is pre-loaded and if you have not used the gpio program to load it, then you may have to run your program as root (ie. with sudo) + +The clear parameter is TRUE or FALSE. + +If TRUE, then all the LEDs will be turned off to start with. + +**NOTE: You need to load the I2C kernel modules before you can use I2C devices. Use the gpio command: gpio load i2c** + +**NOTE: If this is the only I2C device on your Pi (and it almost certianly will be unless you’re using some sort of break-out connector!), then it will run at 400KHz, so try: gpio load i2c 400** + +**NOTE: Use the i2cdetect program to scan your I2C bus to make sure the Pi can see the SN3218 which will show up as 0×54.** + +**NOTE: If you have a Rev 1 Pi, then the i2cdetect command is: i2cdetect -q -y 0 if you have a Rev. 2 Pi, then use i2cdetect -q -y 1** + +**NOTE: The gpio command supports the i2cdetect command and automatically caters for board revision. Simply type: gpio i2cd** + +**NOTE: The wiringPi SN3218 driver knows which revision Pi you have, so you know need to take any special precautions – your code will work on either a Revision 1 or 2 Pi.** + +**NOTE: Internally the PiGlow devLib extension adds 18 more pins to wiringPi’s pin map. These pin are normally at location 577. This should not be an issue as the PiGlow is designed to be the only peripheral on the Pi, but if you have used a breakout board to add other devices to it, then you should pick a pinBase that’s outside the range 577 through 595.** + +#### piGlow1(leg, ring, intensity) + +This lights up an individual LED to the intensity given. + +The leg and ring parameters specify the LED to set. + +#### piGlowLeg(leg, intensity) + +This will light up all 6 LEDs on the given led (0, 1 or 2) to the supplied intensity. + +The leg number will depend on which way up you have the Pi, but leg 0 is normally the one that points to the same edge the composite video connector in on, 1 is to the right (clockwise) and 2 is to the left (anticlockwise) + +#### piGlowRing(ring, intensity) -#### `piGlow1(leg, ring, intensity)` +This will light up all 3 LEDs on the given ring at the given intensity – 0 (off) to 255 (really bright!) The ring number is 0 from the outside to 5 for the inside. -#### `piGlowLeg(leg, intensity)` +You can use the constants: -#### `piGlowRing(ring, intensity)` +`PIGLOW_RED`, `PIGLOW_YELLOW`, `PIGLOW_ORANGE`, `PIGLOW_GREEN`, `PIGLOW_BLUE` or `PIGLOW_WHITE`. ### piNes -#### `setupNesJoystick(dPin, cPin, lPin)` +#### setupNesJoystick(dPin, cPin, lPin) -#### `readNesJoystick(joystick)` +#### readNesJoystick(joystick) ### tcs34725 -#### `tcs34725ReadRGBC(id)` +#### tcs34725Setup(i2cAddress, integrationTime, gain) -#### `tcs34725GetCorrelatedColorTemperature(r, g, b)` +#### tcs34725ReadRGBC(id) -#### `tcs34725GetIlluminance(r, g, b)` +#### tcs34725GetCorrelatedColorTemperature(r, g, b) -#### `tcs34725SetInterrupt(id, aien)` +#### tcs34725GetIlluminance(r, g, b) -#### `tcs34725ClearInterrupt(id)` +#### tcs34725SetInterrupt(id, aien) -#### `tcs34725SetInterruptLimits(id, low, high)` +#### tcs34725ClearInterrupt(id) -#### `tcs34725Enable(id)` +#### tcs34725SetInterruptLimits(id, low, high) -#### `tcs34725Disable(id)` +#### tcs34725Enable(id) -#### `tcs34725Setup(i2cAddress, integrationTime, gain)` \ No newline at end of file +#### tcs34725Disable(id) \ No newline at end of file From b4e03202a0d31d6dbb96385c8fba2f491f61304a Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 24 Jul 2014 09:50:29 +0200 Subject: [PATCH 48/64] update documentation Table of Content --- docs/DOCUMENTATION.md | 52 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/docs/DOCUMENTATION.md b/docs/DOCUMENTATION.md index 4dcccfb..22a9a0c 100644 --- a/docs/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -1,15 +1,65 @@ -# Install +# Table of Contents + +* [Install](#install) +* [Usage](#usage) +* [APIs](#apis) + * [Setup](#setup) + * [Core functions](#core) + * [Interrupts](#interrupts) + * [Raspberry Pi specific](#rpi-specific) + * [I2C](#i2c) + * [SPI](#spi) + * [Serial](#serial) + * [Shift](#shift) + * [Soft PWM](#soft-pwm) + * [Soft Servo](#soft-servo) + * [Soft Tone](#soft-tone) + * [Extensions](#extensions) + * [drcSerial](#drcserial) + * [max31855](#max31855) + * [max5322](#max5322) + * [mcp23008](#mcp23008) + * [mcp23016](#mcp23016) + * [mcp23017](#mcp23017) + * [mcp23s08](#mcp23s08) + * [mcp23s17](#mcp23s17) + * [mcp3002](#mcp3002) + * [mcp3004/8](#mcp3004-8) + * [mcp3422/3/4](#mcp3422-3-4) + * [mcp4802/12/22](#mcp4802-12-22) + * [pca9685](#pca9685) + * [pcf8574](#pcf8574) + * [pcf8591](#pcf8591) + * [sn3218](#sn3218) + * [sr595](#sr595) + * [DevLib](#devlib) + * [ds1302](#ds1302) + * [GetBoard](#getboard) + * [LCD](#lcd) + * [LCD 128x64](#lcd-128x64) + * [piFace](#piface) + * [piGlow](#piglow) + * [piNew](#pinew) + * [tcs34725](#tcs34725) + +--- + +# Install ``` npm install wiring-pi ``` +--- + # Usage ```javascript var wpi = require('wiring-pi'); ``` +--- + # APIs ## Setup From c44127098cf7fbcd0d91de9c277b0ecdbe38b740 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 24 Jul 2014 09:57:07 +0200 Subject: [PATCH 49/64] update documentation and readme --- DOCUMENTATION.html | 518 ---------------------- docs/DOCUMENTATION.md => DOCUMENTATION.md | 17 +- README.md | 2 +- docs/dirty-shade.png | Bin 939 -> 0 bytes docs/gendoc.sh | 3 - docs/pandoc.css | 301 ------------- docs/para.png | Bin 1048 -> 0 bytes 7 files changed, 12 insertions(+), 829 deletions(-) delete mode 100644 DOCUMENTATION.html rename docs/DOCUMENTATION.md => DOCUMENTATION.md (99%) delete mode 100644 docs/dirty-shade.png delete mode 100644 docs/gendoc.sh delete mode 100644 docs/pandoc.css delete mode 100644 docs/para.png diff --git a/DOCUMENTATION.html b/DOCUMENTATION.html deleted file mode 100644 index ff9eccf..0000000 --- a/DOCUMENTATION.html +++ /dev/null @@ -1,518 +0,0 @@ - - - - - - - - - - - - - -

    Install

    -
    npm install wiring-pi
    -

    Usage

    -
    var wpi = require('wiring-pi');
    -

    APIs

    -

    Setup

    -

    wiringPiSetup()

    -

    >= 0.1.0

    -

    Initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme.

    -

    This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers.

    -

    see the pins page for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector.

    -

    This function needs to be called with root privileges.

    -

    wiringPiSetupGpio()

    -

    >= 0.1.1

    -

    This is indential to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping.

    -

    As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards.

    -

    wiringPiSetupPhys()

    -

    >= 1.0.0

    -

    Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only.

    -

    As above, this function needs to be called with root priviliges.

    -

    wiringPiSetupSys()

    -

    >= 0.1.1

    -

    This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly.

    -

    This can be called as a non-root user provided the GPIO pins have been exported before-hand using gpio program.

    -

    Pin numbering in this mode is the native Broadcom GPIO numbers - the same as wiringPiSetGpio above, so be aware of the differences between Rev 1 and Rev 2 boards.

    -

    NOTE: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program.

    -

    You can do this in a seperate shell script, or by using the system() function from inside your program to call the gpio program.

    -

    Also note that some functions have no effect when using this mode as they're not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed).

    -

    setup(mode)

    -

    >= 0.1.1

    -

    An handy function to setup wiringPi

    -

    mode can be one of the following values:

    -
      -
    • wpi: sets up pin numbering with wiringPiSetup >= 0.1.1
    • -
    • gpio: sets up pin numbering with wiringPiSetupGpio >= 0.1.1
    • -
    • sys: sets up pin numbering with wiringPiSetupSys >= 0.1.1
    • -
    • phys: sets up pin numbering with wiringPiSetupPhys >= 1.0.0
    • -
    -

    More info about pin numbering systems at wiringpi.com/pins/

    -

    NOTE: >= 2.0.0 no longer accept calling setup without mode specified. (defaulting to wpi in < 2.0.0)

    -
    -

    Core functions

    -

    pinModeAlt(pin, mode)

    -

    >= 1.0.0

    -

    This is an un-documented special to let you set any pin to any mode.

    -

    mode can be one of the following values:

    -
      -
    • WPI_MODE_PINS >= 1.0.0
    • -
    • WPI_MODE_PHYS >= 1.0.0
    • -
    • WPI_MODE_GPIO >= 1.0.0
    • -
    -

    pinMode(pin, mode)

    -

    >= 0.1.0

    -

    This sets the mode of a pin.

    -

    Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes.

    -

    This function has no effect when in Sys mode.

    -

    If you need to change the pin mode, the you can do it with the gpio program in a script before you start your program.

    -

    mode can be one of the following values:

    -
      -
    • modes.INPUT >= 0.1.1 < 2.0.0 removed
    • -
    • modes.OUTPUT >= 0.1.1 < 2.0.0 removed
    • -
    • modes.PWM_OUTPUT >= 0.1.1 < 2.0.0 removed
    • -
    • modes.GPIO_CLOCK >= 0.1.1 < 2.0.0 removed
    • -
    • INPUT >= 1.0.0
    • -
    • OUTPUT >= 1.0.0
    • -
    • PWM_OUTPUT >= 1.0.0
    • -
    • GPIO_CLOCK >= 1.0.0
    • -
    • SOFT_PWM_OUTPUT >= 1.1.0
    • -
    • SOFT_TONE_OUTPUT >= 1.1.0
    • -
    -

    pullUpDnControl(pin, pud)

    -

    >= 0.2.0

    -

    This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input.

    -

    Unlike Arduino, the BCM2835 has both pull-up and down internal resistors.

    -

    The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi.

    -

    pud can be one of the following values:

    -
      -
    • PUD_OFF no pull up/down >= 0.2.0
    • -
    • PUD_DOWN pull to ground >= 0.2.0
    • -
    • PUD_UP pull to 3.3v >= 0.2.0
    • -
    -

    digitalRead(pin)

    -

    >= 0.1.1

    -

    This function returns the value read at the given pin.

    -

    It will be HIGH (1) or LOW (0) depending on the logic level at the pin.

    -

    digitalWrite(pin, state)

    -

    >= 0.1.0

    -

    Write the value HIGH (1) or LOW (0) to the given pin which must have been previously set as an output.

    -

    WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW.

    -

    state can be one of the following value:

    -
      -
    • HIGH >= 0.1.2
    • -
    • LOW >= 0.1.2
    • -
    -

    pwmWrite(pin, value)

    -

    >= 0.1.1

    -

    Writes the value to the PWM register for the given pin.

    -

    The Raspberry Pi has one on-board PWM pin, pin 1 (BCM_GPIO 18, Phys 12) and the range is [0, 1024].

    -

    Other PWM devices may have other PWM ranges.

    -

    This function is not able to control the Pi's on-board PWM when in Sys mode.

    -

    analogRead(pin)

    -

    >= 1.0.0

    -

    This returns the value read on the supplied analog input pin.

    -

    You will need to register additional analog modules to enable this function for device such as the Gertboard, quick2Wire analog board, etc.

    -

    analogWrite(pin, value)

    -

    >= 1.0.0

    -

    This writes the given value to the supplied analog pin.

    -

    You will need to register additional analog modules to enable this function for devices such as the Gertboard.

    -

    pulseIn(pin, state)

    -

    >= 1.1.0

    -

    Reads a pulse (either HIGH or LOW) on a pin.

    -

    For example, if state is HIGH, pulseIn waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing.

    -

    Returns the length of the pulse in microseconds.

    -

    Gives up and returns 0 if no pulse starts within a specified time out.

    -

    state can be one of the following values:

    -
      -
    • HIGH >= 0.1.2
    • -
    • LOW >= 0.1.2
    • -
    -

    delay(milliseconds)

    -

    >= 1.1.0

    -

    Pauses the program for the amount of time (in miliseconds) specified as parameter.

    -

    There are 1000 milliseconds in a second.

    -

    delayMicroseconds(microseconds)

    -

    >= 1.1.0

    -

    Pauses the program for the amount of time (in microseconds) specified as parameter.

    -

    There are a thousand microseconds in a millisecond, and a million microseconds in a second.

    -

    For delays longer than a few thousand microseconds, you should use delay() instead.

    -

    millis()

    -

    >= 1.1.0

    -

    Returns the number of milliseconds since the beginning running of the current program

    -

    micros()

    -

    >= 1.1.0

    -

    Returns the number of microseconds since the beginning running of the current program

    -
    -

    Interrupts

    -

    wiringPiISR(pin, edgeType, callback)

    -

    >= 2.0.0

    -

    This function registers a function to received interrupts on the specified pin.

    -

    The edgeType parameter is either INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH or INT_EDGE_SETUP.

    -

    If it is INT_EDGE_SETUP then no initialisation of the pin will happen – it’s assumed that you have already setup the pin elsewhere (e.g. with the gpio program), but if you specify one of the other types, then the pin will be exported and initialised as specified.

    -

    This is accomplished via a suitable call to the gpio utility program, so it need to be available.

    -

    The pin number is supplied in the current mode – native wiringPi, BCM_GPIO, physical or Sys modes.

    -

    This function will work in any mode, and does not need root privileges to work.

    -

    The callback will be called when the interrupt triggers.

    -

    When it is triggered, it’s cleared in the dispatcher before calling your function, so if a subsequent interrupt fires before you finish your handler, then it won’t be missed.

    -

    However it can only track one more interrupt, if more than one interrupt fires while one is being handled then they will be ignored.

    -
    wpi.setup('wpi');
    -wpi.pinMode(7, wpi.INPUT);
    -wpi.pullUpDnControl(7, wpi.PUD_UP);
    -wpi.wiringPiISR(7, wpi.INT_EDGE_FALLING, function(delta) {
    -  console.log('Pin 7 changed to LOW (', delta, ')');
    -});
    -
    -

    Raspberry Pi hardware specific functions

    -

    piBoardRev()

    -

    >= 0.1.1

    -

    This returns the board revision of the Raspberry Pi.

    -

    It will be either 1 or 2.

    -

    Some of the BCM_GPIO pins changed number and function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences.

    -

    piBoardId()

    -

    >= 1.1.0

    -

    Do more digging into the board revision string as above, but return as much details as we can.

    -

    Returns an object with the following keys:

    -
      -
    • model: indexes to PI_MODEL_NAMES string table
    • -
    • rev: indexes to PI_REVISION_NAMES string table
    • -
    • mem: 256 or 512
    • -
    • maker: indexes to PI_MAKER_NAMES string table
    • -
    • overvolted: 0 or 1 >= 2.0.0
    • -
    -

    NOTE: maker was a string in versions >= 1.1.0 and < 2.0.0

    -

    Indexes of each string table have corresponding constants

    -
      -
    • PI_MODEL_NAME
    • -
    • PI_MODEL_UNKNOWN >= 2.0.0
    • -
    • PI_MODEL_A >= 1.1.0
    • -
    • PI_MODEL_B >= 1.1.0
    • -
    • PI_MODEL_BP >= 2.0.0
    • -
    • PI_MODEL_CM >= 1.1.1

    • -
    • PI_REVISION_NAMES
    • -
    • PI_VERSION_UNKNOWN >= 2.0.0
    • -
    • PI_VERSION_1 >= 2.0.0
    • -
    • PI_VERSION_1_1 >= 2.0.0
    • -
    • PI_VERSION_1_2 >= 2.0.0
    • -
    • PI_VERSION_2 >= 2.0.0

    • -
    • PI_MAKER_NAMES
    • -
    • PI_MAKER_UNKNOWN >= 2.0.0
    • -
    • PI_MAKER_EGOMAN >= 2.0.0
    • -
    • PI_MAKER_SONY >= 2.0.0
    • -
    • PI_MAKER_QISDA >= 2.0.0

    • -
    -

    wpiPinToGpio(pin)

    -

    >= 1.0.0

    -

    This returns the BCM_GPIO pin number of the supplied wiringPi pin.

    -

    It takes the board revision into account.

    -

    physPinToGpio(pin)

    -

    >= 1.0.0

    -

    This returns the BCM_GPIO pin number of the suppled physical pin on the P1 connector.

    -

    setPadDrive(group, value)

    -

    >= 1.0.0

    -

    This sets the "strength" of the pad drivers for a particular group of pins.

    -

    There are 3 groups of pins and the drive strength is from 0 to 7.

    -

    NOTE: Do not use the unless you know what you are doing.

    -

    getAlt(pin)

    -

    >= 1.0.0

    -

    Returns the ALT bits for a given port.

    -

    digitalWriteByte(byte)

    -

    >= 1.0.0

    -

    This writes the 8-bit byte supplied to the first 8 GPIO pins.

    -

    It’s the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pi’s GPIO hardware.

    -

    pwmSetMode(mode)

    -

    >= 1.0.0

    -

    The PWM generator can run in 2 modes – “balanced” and “mark:space”.

    -

    The mark:space mode is traditional, however the default mode in the Pi is “balanced”.

    -

    mode can be one of the following values:

    -
      -
    • PWM_MODE_BAL balanced
    • -
    • PWM_MODE_MS mark:space
    • -
    -

    pwmSetRange(range)

    -

    >= 0.1.1

    -

    This sets the range register in the PWM generator.

    -

    The default is 1024.

    -

    NOTE: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

    -

    pwmSetClock(divisor)

    -

    >= 0.1.1

    -

    This sets the divisor for the PWM clock.

    -

    NOTE: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.

    -

    gpioClockSet(pin, frequency)

    -

    >= 1.0.0

    -

    Set the frequency on a GPIO clock pin

    -
    -

    I2C

    -

    wiringPiI2CSetup(devId)

    -

    >= 2.0.0

    -

    This initialises the I2C system with your given device identifier.

    -

    The ID is the I2C number of the device and you can use the i2cdetect program to find this out.

    -

    wiringPiI2CSetup() will work out which revision Raspberry Pi you have and open the appropriate device in /dev.

    -

    The return value is the standard Linux filehandle, or -1 if any error – in which case, you can consult errno as usual.

    -

    wiringPiI2CSetupInterface(device, devId)

    -

    >= 2.0.0

    -

    Undocumented access to set the interface explicitly - might be used for the Pi's 2nd I2C interface...

    -

    wiringPiI2CRead(fd)

    -

    >= 2.0.0

    -

    Simple device read.

    -

    Some devices present data when you read them without having to do any register transactions.

    -

    wiringPiI2CReadReg8(fd, reg)

    -

    >= 2.0.0

    -

    This read an 8-bit value from the device register indicated.

    -

    wiringPiI2CReadReg16(fd, red)

    -

    >= 2.0.0

    -

    This read an 16-bit value from the device register indicated.

    -

    wiringPiI2CWrite(fd, data)

    -

    >= 2.0.0

    -

    Simple device write.

    -

    Some devices accept data this way without needing to access any internal registers.

    -

    wiringPiI2CWriteReg8(fd, reg, data)

    -

    >= 2.0.0

    -

    This write an 8-bit data value into the device register indicated.

    -

    wiringPiI2CWriteReg16(fd, reg, data)

    -

    >= 2.0.0

    -

    This write an 16-bit data value into the device register indicated.

    -
    -

    SPI

    -

    wiringPiSPIGetFd(channel)

    -

    >= 1.0.0

    -

    Returns the file-descriptor for the given channel

    -

    wiringPiSPIDataRW(channel, data)

    -

    >= 1.0.0

    -

    This performs a simultaneous write/read transaction over the selected SPI bus.

    -

    Data that was in your buffer is overwritten by data returned from the SPI bus.

    -

    It is possible to do simple read and writes over the SPI bus using the standard read() and write() system calls though – write() may be better to use for sending data to chains of shift registers, or those LED strings where you send RGB triplets of data.

    -

    Devices such as A/D and D/A converters usually need to perform a concurrent write/read transaction to work.

    -

    wiringPiSPISetup(channel, speed)

    -

    >= 1.0.0

    -

    This is the way to initialise a channel (The Pi has 2 channels; 0 and 1).

    -

    The speed parameter is an integer in the range 500,000 through 32,000,000 and represents the SPI clock speed in Hz.

    -

    The returned value is the Linux file-descriptor for the device, or -1 on error.

    -

    If an error has happened, you may use the standard errno global variable to see why.

    -
    -

    Serial

    -

    serialOpen(device, baudrate)

    -

    >= 1.0.0

    -

    This opens and initialises the serial device and sets the baud rate.

    -

    It sets the port into “raw” mode (character at a time and no translations), and sets the read timeout to 10 seconds.

    -

    The return value is the file descriptor or -1 for any error, in which case errno will be set as appropriate.

    -

    NOTE: The file descriptor (fd) returned is a standard Linux file descriptor.

    -

    You can use the standard read(), write(), etc. system calls on this file descriptor as required.

    -

    E.g. you may wish to write a larger block of binary data where the serialPutchar() or serialPuts() function may not be the most appropriate function to use, in which case, you can use write() to send the data.

    -

    serialClose(fd)

    -

    >= 1.0.0

    -

    Closes the device identified by the file descriptor given.

    -

    serialFlush(fd)

    -

    >= 1.0.0

    -

    This discards all data received, or waiting to be send down the given device.

    -

    serialPutchar(fd, character)

    -

    >= 1.0.0

    -

    Sends the single byte to the serial device identified by the given file descriptor.

    -

    serialPuts(fd, string)

    -

    >= 1.0.0

    -

    Sends the nul-terminated string to the serial device identified by the given file descriptor.

    -

    serialPrintf(fd, string)

    -

    Alias: serialPuts >= 2.0.0

    -

    serialDataAvail(fd)

    -

    >= 1.0.0

    -

    Returns the number of characters available for reading, or -1 for any error condition, in which case errno will be set appropriately.

    -

    serialGetchar(fd)

    -

    >= 1.0.0

    -

    Returns the next character available on the serial device.

    -

    This call will block for up to 10 seconds if no data is available (when it will return -1)

    -
    -

    Shift

    -

    shiftIn(dPin, cPin, order)

    -

    >= 1.0.0

    -

    This shifts an 8-bit data value in with the data appearing on the dPin and the clock being sent out on the cPin.

    -

    Order is either LSBFIRST or MSBFIRST.

    -

    The data is sampled after the cPin goes high. (So cPin high, sample data, cPin low, repeat for 8 bits) The 8-bit value is returned by the function.

    -

    shiftOut(dPin, cPin, order, value)

    -

    >= 1.0.0

    -

    The shifts an 8-bit data value val out with the data being sent out on dPin and the clock being sent out on the cPin.

    -

    Order is as above.

    -

    Data is clocked out on the rising or falling edge – ie. dPin is set, then cPin is taken high then low – repeated for the 8 bits.

    -
    -

    Soft PWM

    -

    softPwmCreate(pin, value, range)

    -

    >= 1.0.0

    -

    This creates a software controlled PWM pin.

    -

    You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used.

    -

    Use 100 for the pwmRange, then the value can be anything from 0 (off) to 100 (fully on) for the given pin.

    -

    The return value is 0 for success.

    -

    Anything else and you should check the global errno variable to see what went wrong.

    -

    NOTE: Each “cycle” of PWM output takes 10mS with the default range value of 100, so trying to change the PWM value more than 100 times a second will be futile.

    -

    NOTE: Each pin activated in softPWM mode uses approximately 0.5% of the CPU.

    -

    NOTE: You need to keep your program running to maintain the PWM output!

    -

    softPwmWrite(pin, value)

    -

    >= 1.0.0

    -

    This updates the PWM value on the given pin.

    -

    The value is checked to be in-range and pins that haven’t previously been initialised via softPwmCreate will be silently ignored.

    -

    softPwmStop(pin)

    -

    >= 1.1.0

    -
    -

    Soft Servo

    -

    softServoWrite(pin, value)

    -

    >= 1.0.0

    -

    softServoSetup(p0, p1, p2, p3, p4, p5, p6, p7)

    -

    >= 1.0.0

    -
    -

    Soft Tone

    -

    softToneCreate(pin);

    -

    >= 1.0.0

    -

    This creates a software controlled tone pin.

    -

    You can use any GPIO pin and the pin numbering will be that of the wiringPiSetup() function you used.

    -

    The return value is 0 for success.

    -

    Anything else and you should check the global errno variable to see what went wrong.

    -

    NOTE: Each pin activated in softTone mode uses approximately 0.5% of the CPU.

    -

    NOTE: You need to keep your program running to maintain the sound output!

    -

    softToneWrite(pin, frequency);

    -

    >= 1.0.0

    -

    This updates the tone frequency value on the given pin.

    -

    The tone will be played until you set the frequency to 0.

    -

    softToneStop(pin);

    -

    >= 1.1.0

    -
    -

    Extensions

    -

    drcSerial

    -

    drcSetupSerial(pinBase, numPins, device, baudrate)

    -

    max31855

    -

    Cold-junction compensated thermocouple-to-digital converter (SPI)

    -

    max5322

    -

    12-Bit DAC (SPI)

    -

    max31855Setup(pinBase, spiChannel)

    -

    mcp23008

    -

    8-Bit I/O expander (I2C)

    -

    mcp23008Setup(pinBase, i2cAddress)

    -

    mcp23016

    -

    16-Bit I/O expander (I2C)

    -

    mcp23016Setup(pinBase, i2cAddress)

    -

    mpc23017

    -

    16-Bit I/O expander (I2C)

    -

    mcp23017Setup(pinBase, i2cAddress)

    -

    mcp23s08

    -

    8-Bit I/O expander (SPI)

    -

    mcp23s08Setup(pinBase, spiChannel, devId)

    -

    mcp23s17

    -

    16-Bit I/O expander (SPI)

    -

    mcp23s17Setup(pinBase, spiChannel, devId)

    -

    mcp3002

    -

    2-Channel 10-Bit ADC (SPI)

    -

    mcp3002Setup(pinBase, spiChannel)

    -

    mcp3004/8

    -

    4/8-Channel 10-Bit ADC (SPI)

    -

    mcp3004Setup(pinBase, spiChannel)

    -

    mcp3422/3/4

    -

    2/4-Channel 18-Bit ADC (I2C)

    -

    mcp3422Setup(pinBase, i2cAddress, sampleRate, gain)

    -

    mcp4802/12/22

    -

    2-Channel 8/10/12-Bit DAC (SPI)

    -

    mcp4802Setup(pinBase, spiChannel)

    -

    pca9685

    -

    16-Channel 12-Bit PWM led/servo driver (I2C)

    -

    pca9685Setup(pinBase, i2cAddress, frequency)

    -

    pcf8574

    -

    8-Bit I/O expander (I2C)

    -

    pcf8574Setup(pinBase, i2cAddress)

    -

    pcf8591

    -

    8-Bit ADC and DAC (I2C)

    -

    pcf8591Setup(pinBase, i2cAddress)

    -

    sn3218

    -

    18-Channel PWM led driver (I2C)

    -

    sn3218Setup(pinBase)

    -

    sr595

    -

    74x595 shift register

    -

    sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin)

    -
    -

    DevLib

    -

    ds1302

    -

    Trickle-charge timekeeping chip

    -

    ds1302setup(clockPin, dataPin, csPin)

    -

    ds1302rtcRead(reg)

    -

    ds1302rtcWrite(reg, data)

    -

    ds1302ramRead(address)

    -

    ds1302ramWrite(address, data)

    -

    ds1302clockRead()

    -

    ds1302clockWrite(clockData[8])

    -

    ds1302trickleCharge(diodes, resistors)

    -

    GertBoard

    -

    getboardAnalogSetup(pinBase)

    -

    LCD

    -

    lcdInit(rows, cols, bits, rs, strb, d0, d1, d2, d3, d4, d5, d6, d7)

    -

    lcdHome(fd)

    -

    lcdClear(fd)

    -

    lcdDisplay(fd, state)

    -

    lcdCursor(fd, state)

    -

    lcdCursorBlink(fd, state)

    -

    lcdSendCommand(fd, command)

    -

    lcdPosition(fd, x, y)

    -

    lcdCharDef(fd, index, data[8])

    -

    lcdPutchar(fd, character)

    -

    lcdPuts(fd, string)

    -

    lcdPrintf(fd, string)

    -

    LCD 128x64

    -

    MaxDetect

    -

    maxDetectRead(pin)

    -

    readRHT03(pin)

    -

    piFace

    -

    piFaceSetup(pinBase)

    -

    piGlow

    -

    piGlowSetup(clear)

    -

    piGlow1(leg, ring, intensity)

    -

    piGlowLeg(leg, intensity)

    -

    piGlowRing(ring, intensity)

    -

    piNes

    -

    setupNesJoystick(dPin, cPin, lPin)

    -

    readNesJoystick(joystick)

    -

    tcs34725

    -

    tcs34725ReadRGBC(id)

    -

    tcs34725GetCorrelatedColorTemperature(r, g, b)

    -

    tcs34725GetIlluminance(r, g, b)

    -

    tcs34725SetInterrupt(id, aien)

    -

    tcs34725ClearInterrupt(id)

    -

    tcs34725SetInterruptLimits(id, low, high)

    -

    tcs34725Enable(id)

    -

    tcs34725Disable(id)

    -

    tcs34725Setup(i2cAddress, integrationTime, gain)

    - - diff --git a/docs/DOCUMENTATION.md b/DOCUMENTATION.md similarity index 99% rename from docs/DOCUMENTATION.md rename to DOCUMENTATION.md index 22a9a0c..1f3ce42 100644 --- a/docs/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -6,7 +6,7 @@ * [Setup](#setup) * [Core functions](#core) * [Interrupts](#interrupts) - * [Raspberry Pi specific](#rpi-specific) + * [Raspberry Pi specific](#raspberry-pi-hardware-specific-functions) * [I2C](#i2c) * [SPI](#spi) * [Serial](#serial) @@ -24,9 +24,9 @@ * [mcp23s08](#mcp23s08) * [mcp23s17](#mcp23s17) * [mcp3002](#mcp3002) - * [mcp3004/8](#mcp3004-8) - * [mcp3422/3/4](#mcp3422-3-4) - * [mcp4802/12/22](#mcp4802-12-22) + * [mcp3004/8](#mcp30048) + * [mcp3422/3/4](#mcp342234) + * [mcp4802/12/22](#mcp48021222) * [pca9685](#pca9685) * [pcf8574](#pcf8574) * [pcf8591](#pcf8591) @@ -44,7 +44,7 @@ --- -# Install +# Install ``` npm install wiring-pi @@ -972,7 +972,12 @@ This will light up all 3 LEDs on the given ring at the given intensity – 0 (of You can use the constants: -`PIGLOW_RED`, `PIGLOW_YELLOW`, `PIGLOW_ORANGE`, `PIGLOW_GREEN`, `PIGLOW_BLUE` or `PIGLOW_WHITE`. +* `PIGLOW_RED` +* `PIGLOW_YELLOW` +* `PIGLOW_ORANGE` +* `PIGLOW_GREEN` +* `PIGLOW_BLUE` +* `PIGLOW_WHITE` ### piNes diff --git a/README.md b/README.md index f1e3d26..0b563e9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ var wpi = require('wiring-pi'); ``` ## Documentation -See the [DOCUMENTATION.html](https://github.com/eugeneware/wiring-pi/blob/master/DOCUMENTATION.html) file for more detailed documentation. +See the [DOCUMENTATION.md](https://github.com/eugeneware/wiring-pi/blob/master/DOCUMENTATION.md) file for more detailed documentation. ## Contributing diff --git a/docs/dirty-shade.png b/docs/dirty-shade.png deleted file mode 100644 index 3e0e9c90bdf0469caf1afc7f7b8e35dc41aa99ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 939 zcmaJ=&yLbS9Bu?RX5%J%)r*sIm3CVGv`naLX~At`2>}v0I68E`#B(wv*x$VPM%sc<5`*!CP28u*qoIUzjFg2jXA466 zB8#!NBn(W+JctbO_ovSy2z*0))^MR4TVxSjZWA)v_Q&3K>9u_E;t^-VUUGa zQHnA{-032I&aY(=>>zAuh}S_)+ySs?LO?@;RSz~HXeyFYt81F}5U5arGE`+nttuL- zsR%-_|3vOB@n>jg_x8THWrz#LVkFD!^;%ljB$~`+rPXTX8me05h-$it7|yCuS}7E4 zl6pxHvw%h*SHx4gVur{gy-p#F53*6ZFB31AoZ(njB$%gE0A2V0&@eopQ#K?w@%~dd z9dBYH4@pW_iN_l^tK_a?WF-VMnv5yEDyleGP)5@Qje#|402g~fl-oPJ>mnyg8IC;S z*oMdzq#*E-ZdtvWshQ12(^Ql$>}Z|3sn>K(wbWLxt`}UJdaIB`tl;`L+|E&MJ_=#X zJ=-J+UJ}2T&=BlWM#1q|^rL!vu75n1)={p^gOT&b{?+K>ice2|Jd7-TSeeBn>xfn%HF?B~>feETarsWeTXe}C *:first-child { - margin-top: 0 !important; } -body > *:last-child { - margin-bottom: 0 !important; } - -a { - color: #4183C4; } -a.absent { - color: #cc0000; } -a.anchor { - display: block; - padding-left: 30px; - margin-left: -30px; - cursor: pointer; - position: absolute; - top: 0; - left: 0; - bottom: 0; } - -h1, h2, h3, h4, h5, h6 { - margin: 20px 0 10px; - padding: 0; - font-weight: bold; - -webkit-font-smoothing: antialiased; - cursor: text; - position: relative; } - -h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { - background: url("para.png") no-repeat 10px center; - text-decoration: none; } - -h1 tt, h1 code { - font-size: inherit; } - -h2 tt, h2 code { - font-size: inherit; } - -h3 tt, h3 code { - font-size: inherit; } - -h4 tt, h4 code { - font-size: inherit; } - -h5 tt, h5 code { - font-size: inherit; } - -h6 tt, h6 code { - font-size: inherit; } - -h1 { - font-size: 28px; - color: black; } - -h2 { - font-size: 24px; - border-bottom: 1px solid #cccccc; - color: black; } - -h3 { - font-size: 18px; } - -h4 { - font-size: 16px; } - -h5 { - font-size: 14px; } - -h6 { - color: #777777; - font-size: 14px; } - -p, blockquote, ul, ol, dl, li, table, pre { - margin: 15px 0; } - -hr { - background: transparent url("dirty-shade.png") repeat-x 0 0; - border: 0 none; - color: #cccccc; - height: 4px; - padding: 0; } - -body > h2:first-child { - margin-top: 0; - padding-top: 0; } -body > h1:first-child { - margin-top: 0; - padding-top: 0; } - body > h1:first-child + h2 { - margin-top: 0; - padding-top: 0; } -body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child { - margin-top: 0; - padding-top: 0; } - -a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { - margin-top: 0; - padding-top: 0; } - -h1 p, h2 p, h3 p, h4 p, h5 p, h6 p { - margin-top: 0; } - -li p.first { - display: inline-block; } - -ul, ol { - padding-left: 30px; } - -ul :first-child, ol :first-child { - margin-top: 0; } - -ul :last-child, ol :last-child { - margin-bottom: 0; } - -dl { - padding: 0; } - dl dt { - font-size: 14px; - font-weight: bold; - font-style: italic; - padding: 0; - margin: 15px 0 5px; } - dl dt:first-child { - padding: 0; } - dl dt > :first-child { - margin-top: 0; } - dl dt > :last-child { - margin-bottom: 0; } - dl dd { - margin: 0 0 15px; - padding: 0 15px; } - dl dd > :first-child { - margin-top: 0; } - dl dd > :last-child { - margin-bottom: 0; } - -blockquote { - border-left: 4px solid #dddddd; - padding: 0 15px; - color: #777777; } - blockquote > :first-child { - margin-top: 0; } - blockquote > :last-child { - margin-bottom: 0; } - -table { - padding: 0; } - table tr { - border-top: 1px solid #cccccc; - background-color: white; - margin: 0; - padding: 0; } - table tr:nth-child(2n) { - background-color: #f8f8f8; } - table tr th { - font-weight: bold; - border: 1px solid #cccccc; - text-align: left; - margin: 0; - padding: 6px 13px; } - table tr td { - border: 1px solid #cccccc; - text-align: left; - margin: 0; - padding: 6px 13px; } - table tr th :first-child, table tr td :first-child { - margin-top: 0; } - table tr th :last-child, table tr td :last-child { - margin-bottom: 0; } - -img { - max-width: 100%; } - -span.frame { - display: block; - overflow: hidden; } - span.frame > span { - border: 1px solid #dddddd; - display: block; - float: left; - overflow: hidden; - margin: 13px 0 0; - padding: 7px; - width: auto; } - span.frame span img { - display: block; - float: left; } - span.frame span span { - clear: both; - color: #333333; - display: block; - padding: 5px 0 0; } -span.align-center { - display: block; - overflow: hidden; - clear: both; } - span.align-center > span { - display: block; - overflow: hidden; - margin: 13px auto 0; - text-align: center; } - span.align-center span img { - margin: 0 auto; - text-align: center; } -span.align-right { - display: block; - overflow: hidden; - clear: both; } - span.align-right > span { - display: block; - overflow: hidden; - margin: 13px 0 0; - text-align: right; } - span.align-right span img { - margin: 0; - text-align: right; } -span.float-left { - display: block; - margin-right: 13px; - overflow: hidden; - float: left; } - span.float-left span { - margin: 13px 0 0; } -span.float-right { - display: block; - margin-left: 13px; - overflow: hidden; - float: right; } - span.float-right > span { - display: block; - overflow: hidden; - margin: 13px auto 0; - text-align: right; } - -code, tt { - margin: 0 2px; - padding: 0 5px; - white-space: nowrap; - border: 1px solid #eaeaea; - background-color: #f8f8f8; - border-radius: 3px; } - -pre code { - margin: 0; - padding: 0; - white-space: pre; - border: none; - background: transparent; } - -.highlight pre { - background-color: #f8f8f8; - border: 1px solid #cccccc; - font-size: 13px; - line-height: 19px; - overflow: auto; - padding: 6px 10px; - border-radius: 3px; } - -pre { - background-color: #f8f8f8; - border: 1px solid #cccccc; - font-size: 13px; - line-height: 19px; - overflow: auto; - padding: 6px 10px; - border-radius: 3px; } - pre code, pre tt { - background-color: transparent; - border: none; } - -.api-info { - display: block; - text-align: right; - margin-top: -40px; - font-style: italic; -} - -.api-info-list { - display: inline; - float:right; -} - -.api-info-deprecated { - background-color: #F90 !important; - color: #FFF !important; - text-transform: uppercase; -} - -.api-info-removed { - background-color: #D33 !important; - color: #FFF !important; - text-transform: uppercase; -} diff --git a/docs/para.png b/docs/para.png deleted file mode 100644 index a76973862e1256fb1e8a9870ccf1119567db92e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1048 zcmaJ=&rj1(9Is4qA%PG>6gl9dganLhU$?bv4U>&^lNpMnERjTwcI_K$pnbJ{xI#Ff zH$r0c;=!Aq3I6~G(Qx5t;>i2#A6R>(50lDh68CTHRb0wr5tMH-4GwOBT` z){L~t&fWzxflLK#M060?>y9r68Mdh_({*^vv!DqfYZ>-DsTFkzzP>A!84k;!iWl@sj)1dXRG@55tWlbrzV$ofOtr6nNJYTQZxq5=b-YPGo z)9Fwn9*g4fyse-h-|#G#Sl9ufqF%upB*W57&#z#+9a+b3*+dQF1Ks5X z4u)5116B3^P}}aHeWIa@eE%uzmp5I+YskkNo+FsbT><%Ha+rnsugCC4YaW1y0f zVQDzdvP?Ohm!x!lE}lxkq97E6l$c5@sf41$b43y6l5MVnjSU+)q|G%ixQVXZux@OZ zMplq#y+CHs!!~I8BU{~bfnD`lT(f&FLRT(Nli|ZE_^T?~N3_(!Wv9mJrqdX-UbIgYT8!jmB(bV&|JMRl8 Td-L}vXeg#sSX2(?p1t}5UOquV From 70944b09f9db250827ad7db8c51261d2bc7759eb Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 24 Jul 2014 10:09:06 +0200 Subject: [PATCH 50/64] update documentation --- DOCUMENTATION.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 1f3ce42..eb81721 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -693,102 +693,119 @@ The tone will be played until you set the frequency to 0. ### drcSerial #### drcSetupSerial(pinBase, numPins, device, baudrate) + >= 1.0.0 ### max31855 Cold-junction compensated thermocouple-to-digital converter (SPI) #### max31855Setup(pinBase, spiChannel) + >= 1.0.0 ### max5322 12-Bit DAC (SPI) #### max5322Setup(pinBase, spiChannel) + >= 1.0.0 ### mcp23008 8-Bit I/O expander (I2C) #### mcp23008Setup(pinBase, i2cAddress) + >= 1.0.0 ### mcp23016 16-Bit I/O expander (I2C) #### mcp23016Setup(pinBase, i2cAddress) + >= 1.0.0 ### mpc23017 16-Bit I/O expander (I2C) #### mcp23017Setup(pinBase, i2cAddress) + >= 1.0.0 ### mcp23s08 8-Bit I/O expander (SPI) #### mcp23s08Setup(pinBase, spiChannel, devId) + >= 1.0.0 ### mcp23s17 16-Bit I/O expander (SPI) #### mcp23s17Setup(pinBase, spiChannel, devId) + >= 1.0.0 ### mcp3002 2-Channel 10-Bit ADC (SPI) #### mcp3002Setup(pinBase, spiChannel) + >= 1.0.0 ### mcp3004/8 4/8-Channel 10-Bit ADC (SPI) #### mcp3004Setup(pinBase, spiChannel) + >= 1.0.0 ### mcp3422/3/4 2/4-Channel 18-Bit ADC (I2C) #### mcp3422Setup(pinBase, i2cAddress, sampleRate, gain) + >= 1.0.0 ### mcp4802/12/22 2-Channel 8/10/12-Bit DAC (SPI) #### mcp4802Setup(pinBase, spiChannel) + >= 1.0.0 ### pca9685 16-Channel 12-Bit PWM led/servo driver (I2C) #### pca9685Setup(pinBase, i2cAddress, frequency) + >= 1.1.0 ### pcf8574 8-Bit I/O expander (I2C) #### pcf8574Setup(pinBase, i2cAddress) + >= 1.0.0 ### pcf8591 8-Bit ADC and DAC (I2C) #### pcf8591Setup(pinBase, i2cAddress) + >= 1.0.0 ### sn3218 18-Channel PWM led driver (I2C) #### sn3218Setup(pinBase) + >= 1.0.0 ### sr595 74x595 shift register #### sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin) + >= 1.0.0 --- @@ -799,24 +816,33 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) Trickle-charge timekeeping chip #### ds1302setup(clockPin, dataPin, csPin) + >= 2.0.0 #### ds1302rtcRead(reg) + >= 2.0.0 #### ds1302rtcWrite(reg, data) + >= 2.0.0 #### ds1302ramRead(address) + >= 2.0.0 #### ds1302ramWrite(address, data) + >= 2.0.0 #### ds1302clockRead() + >= 2.0.0 #### ds1302clockWrite(clockData[8]) + >= 2.0.0 #### ds1302trickleCharge(diodes, resistors) + >= 2.0.0 ### GertBoard #### getboardAnalogSetup(pinBase) + >= 2.0.0 pinBase is the base pin that you want the analog ports to appear as. @@ -839,6 +865,7 @@ So reading channel pinBase + 0 reads the first analog input channel (pin DA0 on ### LCD #### lcdInit(rows, cols, bits, rs, strb, d0, d1, d2, d3, d4, d5, d6, d7) + >= 2.0.0 This is the main initialisation function and must be called before you use any other LCD functions. @@ -855,28 +882,35 @@ Only the first 4 are used if you are running the display in 4-bit mode. The return value is the ‘handle’ to be used for all subsequent calls to the lcd library when dealing with that LCD, or -1 to indicate a fault. (Usually incorrect parameters) #### lcdHome(fd) + >= 2.0.0 This home the cursor #### lcdClear(fd) + >= 2.0.0 This clear the screen #### lcdDisplay(fd, state) + >= 2.0.0 This turns the display on or off #### lcdCursor(fd, state) + >= 2.0.0 This turns the cursor on or off #### lcdCursorBlink(fd, state) + >= 2.0.0 This turns blinking cursor on or off #### lcdSendCommand(fd, command) + >= 2.0.0 #### lcdPosition(fd, x, y) + >= 2.0.0 Set the position of the cursor for subsequent text entry. @@ -885,6 +919,7 @@ x is the column and 0 is the left-most edge. y is the line and 0 is the top line. #### lcdCharDef(fd, index, data[8]) + >= 2.0.0 This allows you to re-define one of the 8 user-definable chanracters in the display. @@ -895,22 +930,28 @@ Note that the characters are actually 5×8, so only the lower 5 bits are used. The index is from 0 to 7 and you can subsequently print the character defined using the lcdPutchar() call. #### lcdPutchar(fd, character) + >= 2.0.0 #### lcdPuts(fd, string) + >= 2.0.0 #### lcdPrintf(fd, string) + >= 2.0.0 ### LCD 128x64 ### MaxDetect #### maxDetectRead(pin) + >= 2.0.0 #### readRHT03(pin) + >= 2.0.0 ### piFace #### piFaceSetup(pinBase) + >= 2.0.0 pinBase is the base pin that you want your PiFace to appear as – the examples provided use 200 as the base pin. @@ -931,6 +972,7 @@ The remaining 16 pins are used by the underlying MCP23S17 driver and should not ### piGlow #### piGlowSetup(clear) + >= 2.0.0 This initialises the PiGlow devLib software. @@ -955,18 +997,21 @@ If TRUE, then all the LEDs will be turned off to start with. **NOTE: Internally the PiGlow devLib extension adds 18 more pins to wiringPi’s pin map. These pin are normally at location 577. This should not be an issue as the PiGlow is designed to be the only peripheral on the Pi, but if you have used a breakout board to add other devices to it, then you should pick a pinBase that’s outside the range 577 through 595.** #### piGlow1(leg, ring, intensity) + >= 2.0.0 This lights up an individual LED to the intensity given. The leg and ring parameters specify the LED to set. #### piGlowLeg(leg, intensity) + >= 2.0.0 This will light up all 6 LEDs on the given led (0, 1 or 2) to the supplied intensity. The leg number will depend on which way up you have the Pi, but leg 0 is normally the one that points to the same edge the composite video connector in on, 1 is to the right (clockwise) and 2 is to the left (anticlockwise) #### piGlowRing(ring, intensity) + >= 2.0.0 This will light up all 3 LEDs on the given ring at the given intensity – 0 (off) to 255 (really bright!) The ring number is 0 from the outside to 5 for the inside. @@ -982,25 +1027,36 @@ You can use the constants: ### piNes #### setupNesJoystick(dPin, cPin, lPin) + >= 2.0.0 #### readNesJoystick(joystick) + >= 2.0.0 ### tcs34725 #### tcs34725Setup(i2cAddress, integrationTime, gain) + >= 2.0.0 #### tcs34725ReadRGBC(id) + >= 2.0.0 #### tcs34725GetCorrelatedColorTemperature(r, g, b) + >= 2.0.0 #### tcs34725GetIlluminance(r, g, b) + >= 2.0.0 #### tcs34725SetInterrupt(id, aien) + >= 2.0.0 #### tcs34725ClearInterrupt(id) + >= 2.0.0 #### tcs34725SetInterruptLimits(id, low, high) + >= 2.0.0 #### tcs34725Enable(id) + >= 2.0.0 -#### tcs34725Disable(id) \ No newline at end of file +#### tcs34725Disable(id) + >= 2.0.0 From 215b202408a41d387ffb24f924b25ffd315196bb Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 24 Jul 2014 10:23:23 +0200 Subject: [PATCH 51/64] update documentation --- DOCUMENTATION.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index eb81721..7c005ef 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -699,6 +699,8 @@ The tone will be played until you set the frequency to 0. Cold-junction compensated thermocouple-to-digital converter (SPI) +*Datasheet*: http://datasheets.maximintegrated.com/en/ds/MAX31855.pdf + #### max31855Setup(pinBase, spiChannel) >= 1.0.0 @@ -706,6 +708,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 12-Bit DAC (SPI) +*Datasheet*: http://datasheets.maximintegrated.com/en/ds/MAX5322.pdf + #### max5322Setup(pinBase, spiChannel) >= 1.0.0 @@ -713,6 +717,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 8-Bit I/O expander (I2C) +*Datasheet*: http://ww1.microchip.com/downloads/en/DeviceDoc/21919e.pdf + #### mcp23008Setup(pinBase, i2cAddress) >= 1.0.0 @@ -720,6 +726,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 16-Bit I/O expander (I2C) +*Datasheet*: http://ww1.microchip.com/downloads/en/DeviceDoc/20090C.pdf + #### mcp23016Setup(pinBase, i2cAddress) >= 1.0.0 @@ -727,6 +735,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 16-Bit I/O expander (I2C) +*Datasheet*: http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf + #### mcp23017Setup(pinBase, i2cAddress) >= 1.0.0 @@ -734,6 +744,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 8-Bit I/O expander (SPI) +*Datasheet*: http://ww1.microchip.com/downloads/en/DeviceDoc/21919e.pdf + #### mcp23s08Setup(pinBase, spiChannel, devId) >= 1.0.0 @@ -741,6 +753,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 16-Bit I/O expander (SPI) +*Datasheet*: http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf + #### mcp23s17Setup(pinBase, spiChannel, devId) >= 1.0.0 @@ -748,6 +762,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 2-Channel 10-Bit ADC (SPI) +*Datasheet*: http://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf + #### mcp3002Setup(pinBase, spiChannel) >= 1.0.0 @@ -755,6 +771,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 4/8-Channel 10-Bit ADC (SPI) +*Datasheet*: http://ww1.microchip.com/downloads/en/DeviceDoc/21295C.pdf + #### mcp3004Setup(pinBase, spiChannel) >= 1.0.0 @@ -762,6 +780,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 2/4-Channel 18-Bit ADC (I2C) +*Datasheet*: http://ww1.microchip.com/downloads/en/DeviceDoc/22088b.pdf + #### mcp3422Setup(pinBase, i2cAddress, sampleRate, gain) >= 1.0.0 @@ -769,6 +789,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 2-Channel 8/10/12-Bit DAC (SPI) +*Datasheet*: http://ww1.microchip.com/downloads/en/DeviceDoc/22249A.pdf + #### mcp4802Setup(pinBase, spiChannel) >= 1.0.0 @@ -776,6 +798,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 16-Channel 12-Bit PWM led/servo driver (I2C) +*Datasheet*: http://www.adafruit.com/datasheets/PCA9685.pdf + #### pca9685Setup(pinBase, i2cAddress, frequency) >= 1.1.0 @@ -783,6 +807,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 8-Bit I/O expander (I2C) +*Datasheet*: http://www.nxp.com/documents/data_sheet/PCF8574.pdf + #### pcf8574Setup(pinBase, i2cAddress) >= 1.0.0 @@ -790,6 +816,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 8-Bit ADC and DAC (I2C) +*Datasheet*: http://www.nxp.com/documents/data_sheet/PCF8591.pdf + #### pcf8591Setup(pinBase, i2cAddress) >= 1.0.0 @@ -797,6 +825,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 18-Channel PWM led driver (I2C) +*Datasheet*: http://www.si-en.com/uploadpdf/s2011517171720.pdf + #### sn3218Setup(pinBase) >= 1.0.0 @@ -804,6 +834,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) 74x595 shift register +*Datasheet*: http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf + #### sr595Setup(pinBase, numPins, dataPin, clockPin, latchPin) >= 1.0.0 @@ -815,6 +847,8 @@ Cold-junction compensated thermocouple-to-digital converter (SPI) Trickle-charge timekeeping chip +*Datasheet*: http://datasheets.maximintegrated.com/en/ds/DS1302.pdf + #### ds1302setup(clockPin, dataPin, csPin) >= 2.0.0 @@ -1034,29 +1068,47 @@ You can use the constants: ### tcs34725 +Color light-to-digital converter with IR filter + +*Datasheet*: http://www.adafruit.com/datasheets/TCS34725.pdf + #### tcs34725Setup(i2cAddress, integrationTime, gain) >= 2.0.0 #### tcs34725ReadRGBC(id) >= 2.0.0 +Read the raw red, green, blue and clear channel values + #### tcs34725GetCorrelatedColorTemperature(r, g, b) >= 2.0.0 +Convert the raw R/G/B values to color temperature in degrees Kelvin + #### tcs34725GetIlluminance(r, g, b) >= 2.0.0 +Convert the raw R/G/B values to illuminance in Lux + #### tcs34725SetInterrupt(id, aien) >= 2.0.0 +Enable/Disable interrupt + #### tcs34725ClearInterrupt(id) >= 2.0.0 +Clear interrupt + #### tcs34725SetInterruptLimits(id, low, high) >= 2.0.0 #### tcs34725Enable(id) >= 2.0.0 +Enable the device + #### tcs34725Disable(id) >= 2.0.0 + +Disable the device (putting it in lower power sleep mode) From 4c01b969fe0ec385cd696d9a4cb734bef2fe2f1a Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 24 Jul 2014 10:38:52 +0200 Subject: [PATCH 52/64] update documentation ADD: pwmToneWrite in pi specific section --- DOCUMENTATION.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 7c005ef..6a83066 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -445,6 +445,11 @@ This sets the divisor for the PWM clock. **NOTE: The PWM control functions can not be used when in Sys mode. To understand more about the PWM system, you’ll need to read the Broadcom ARM peripherals manual.** +### pwmToneWrite(pin, frequency) + >= 2.0.0 + +Output the given frequency on the Pi's PWM pin + ### gpioClockSet(pin, frequency) >= 1.0.0 From 7d90f14bc953fecc1abc485a40dd6e8438313d25 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 24 Jul 2014 19:42:21 +0200 Subject: [PATCH 53/64] update tcs34725 (experimental) --- wiringpi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiringpi b/wiringpi index 6265f5a..c14cb14 160000 --- a/wiringpi +++ b/wiringpi @@ -1 +1 @@ -Subproject commit 6265f5a8b59430cf8a17b8b26e0d49e574c8090c +Subproject commit c14cb1454841fbc06450b40124a57c6fbdb71fc8 From f89a1e8c88d7c55317323244e7926cd84f067142 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 24 Jul 2014 19:53:50 +0200 Subject: [PATCH 54/64] tcs34725 (experimental) --- wiringpi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiringpi b/wiringpi index c14cb14..7e76571 160000 --- a/wiringpi +++ b/wiringpi @@ -1 +1 @@ -Subproject commit c14cb1454841fbc06450b40124a57c6fbdb71fc8 +Subproject commit 7e7657112499fe353dbb8da28d9795f7d5d273df From 58a3dc4e3229a57acef5ef2c982600968f608616 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 24 Jul 2014 19:58:58 +0200 Subject: [PATCH 55/64] i am done for today ! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i am doing bullshit … --- wiringpi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiringpi b/wiringpi index 7e76571..de74796 160000 --- a/wiringpi +++ b/wiringpi @@ -1 +1 @@ -Subproject commit 7e7657112499fe353dbb8da28d9795f7d5d273df +Subproject commit de747966c335efbbfcdc108a61f0cd3a9ba2b4e3 From 08007639158f42767228383ce14ce98625c73f7e Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 6 Nov 2014 21:11:56 +0100 Subject: [PATCH 56/64] git submodule and npm fix (test) --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 88eed48..28bc5a4 100644 --- a/package.json +++ b/package.json @@ -24,5 +24,8 @@ "Leandre Gohy ", "Eugene Ware " ], - "license": "BSD" + "license": "BSD", + "dependencies" : { + "wiringpi" : "git+https://github.com/nekuz0r/wiringpi" + } } From 43bda862806653dcfb8bfece0bb2bd3d70c42af7 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 6 Nov 2014 21:25:16 +0100 Subject: [PATCH 57/64] Revert "git submodule and npm fix (test)" This reverts commit 08007639158f42767228383ce14ce98625c73f7e. --- package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/package.json b/package.json index 28bc5a4..88eed48 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,5 @@ "Leandre Gohy ", "Eugene Ware " ], - "license": "BSD", - "dependencies" : { - "wiringpi" : "git+https://github.com/nekuz0r/wiringpi" - } + "license": "BSD" } From 4064858b11b95bdb51076e1a5b872181186bb446 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 6 Nov 2014 21:37:23 +0100 Subject: [PATCH 58/64] NPM and Git Submodule fix wiring is no longer linked as a git submodule, revert to cloning in install script --- .gitmodules | 4 ---- install.sh | 12 ++++++------ wiringpi | 1 - 3 files changed, 6 insertions(+), 11 deletions(-) delete mode 160000 wiringpi diff --git a/.gitmodules b/.gitmodules index a4252f7..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +0,0 @@ -[submodule "wiringpi"] - path = wiringpi - url = https://github.com/nekuz0r/wiringpi.git - branch = incoming diff --git a/install.sh b/install.sh index e28d080..aac9ed0 100644 --- a/install.sh +++ b/install.sh @@ -39,13 +39,13 @@ check_git_clone() { rm ./install.log 2>/dev/null 1>&2 echo -n "Cloning libWiringPi ... " -#rm -Rf ./wiringpi 2>/dev/null 1>&2 -#git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 -#check_git_clone -git submodule init -check_git_clone -git submodule update +rm -Rf ./wiringpi 2>/dev/null 1>&2 +git clone https://github.com/nekuz0r/wiringpi.git -b incoming-v2.x > ./install.log 2>&1 check_git_clone +#git submodule init +#check_git_clone +#git submodule update +#check_git_clone echo "done." patch ./wiringpi/devLib/Makefile < ./patchs/devLib_Makefile.patch diff --git a/wiringpi b/wiringpi deleted file mode 160000 index de74796..0000000 --- a/wiringpi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit de747966c335efbbfcdc108a61f0cd3a9ba2b4e3 From fbe4f01717794d67ecc112f71298619ad076d4bf Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 6 Nov 2014 21:43:59 +0100 Subject: [PATCH 59/64] fix typo --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index aac9ed0..1983eda 100644 --- a/install.sh +++ b/install.sh @@ -40,7 +40,7 @@ rm ./install.log 2>/dev/null 1>&2 echo -n "Cloning libWiringPi ... " rm -Rf ./wiringpi 2>/dev/null 1>&2 -git clone https://github.com/nekuz0r/wiringpi.git -b incoming-v2.x > ./install.log 2>&1 +git clone https://github.com/nekuz0r/wiringpi.git -b incoming > ./install.log 2>&1 check_git_clone #git submodule init #check_git_clone From 2dbc52586a0b29816d415bab87eff5b59f3b6450 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Thu, 25 Dec 2014 20:44:54 +0100 Subject: [PATCH 60/64] tcs34725, dac7678 ADD: dac7678 support ADD: tcs34725 readHSV --- src/devlib/tcs34725.cc | 23 +++++++++++++++++++++ src/extensions/dac7678.cc | 43 +++++++++++++++++++++++++++++++++++++++ src/extensions/dac7678.h | 8 ++++++++ 3 files changed, 74 insertions(+) create mode 100644 src/extensions/dac7678.cc create mode 100644 src/extensions/dac7678.h diff --git a/src/devlib/tcs34725.cc b/src/devlib/tcs34725.cc index ed6a790..185c24c 100644 --- a/src/devlib/tcs34725.cc +++ b/src/devlib/tcs34725.cc @@ -34,6 +34,28 @@ IMPLEMENT(tcs34725ReadRGBC) { SCOPE_CLOSE(obj); } +IMPLEMENT(tcs34725ReadHSV) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, id); + + CHECK_ARGUMENTS_LENGTH_EQUAL(1); + + CHECK_ARGUMENT_TYPE_INT32(0); + + int id = GET_ARGUMENT_AS_INT32(0); + unsigned short h, s, v; + + ::tcs34725ReadHSV(id, &h, &s, &v); + + Local obj = Object::New(); + obj->Set(String::NewSymbol("h"), UINT32(h)); + obj->Set(String::NewSymbol("s"), UINT32(s)); + obj->Set(String::NewSymbol("v"), UINT32(v)); + + SCOPE_CLOSE(obj); +} + IMPLEMENT(tcs34725GetCorrelatedColorTemperature) { SCOPE_OPEN(); @@ -194,6 +216,7 @@ IMPLEMENT(tcs34725Setup) { IMPLEMENT_EXPORT_INIT(tcs34725) { EXPORT_FUNCTION(tcs34725ReadRGBC); + EXPORT_FUNCTION(tcs34725ReadHSV); EXPORT_FUNCTION(tcs34725GetCorrelatedColorTemperature); EXPORT_FUNCTION(tcs34725GetIlluminance); EXPORT_FUNCTION(tcs34725SetInterrupt); diff --git a/src/extensions/dac7678.cc b/src/extensions/dac7678.cc new file mode 100644 index 0000000..03bce9c --- /dev/null +++ b/src/extensions/dac7678.cc @@ -0,0 +1,43 @@ +#include "dac7678.h" +#include +#include + +DECLARE(dac7678Setup); + +IMPLEMENT(dac7678Setup) { + SCOPE_OPEN(); + + SET_ARGUMENT_NAME(0, pinBase); + SET_ARGUMENT_NAME(1, i2cAddress); + SET_ARGUMENT_NAME(2, vrefMode); + + CHECK_ARGUMENTS_LENGTH_EQUAL(3); + + CHECK_ARGUMENT_TYPE_INT32(0); + CHECK_ARGUMENT_TYPE_INT32(1); + CHECK_ARGUMENT_TYPE_UINT32(2); + + CHECK_ARGUMENT_IN_INTS(2, vrefMode, (DAC7678_VREF_MODE_STATIC_ON, + DAC7678_VREF_MODE_STATIC_OFF, + DAC7678_VREF_MODE_FLEXIBLE_ON, + DAC7678_VREF_MODE_FLEXIBLE_ALWAYS_ON + DAC7678_VREF_MODE_FLEXIBLE_ALWAYS_OFF)); + + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + unsigned short vrefMode = GET_ARGUMENT_AS_UINT32(2); + + int res = ::dac7678Setup(pinBase, i2cAddress, vrefMode); + + SCOPE_CLOSE(INT32(res)); +} + +IMPLEMENT_EXPORT_INIT(dac7678) { + EXPORT_FUNCTION(dac7678Setup); + + EXPORT_CONSTANT_INT(DAC7678_VREF_MODE_STATIC_ON); + EXPORT_CONSTANT_INT(DAC7678_VREF_MODE_STATIC_OFF); + EXPORT_CONSTANT_INT(DAC7678_VREF_MODE_FLEXIBLE_ON); + EXPORT_CONSTANT_INT(DAC7678_VREF_MODE_FLEXIBLE_ALWAYS_ON); + EXPORT_CONSTANT_INT(DAC7678_VREF_MODE_FLEXIBLE_ALWAYS_OFF); +} \ No newline at end of file diff --git a/src/extensions/dac7678.h b/src/extensions/dac7678.h new file mode 100644 index 0000000..d0e8a6c --- /dev/null +++ b/src/extensions/dac7678.h @@ -0,0 +1,8 @@ +#ifndef _WPI_DAC7678_H_ +#define _WPI_DAC7678_H_ + +#include "../addon.h" + +DECLARE_EXPORT_INIT(dac7678); + +#endif \ No newline at end of file From 54fcb41e030062a7d26d9326447e3a572920375e Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Sat, 27 Dec 2014 23:44:37 +0100 Subject: [PATCH 61/64] dac7678, tcs34725 support --- binding.gyp | 1 + src/devlib/tcs34725.cc | 1 + src/extensions/dac7678.cc | 10 +++++----- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/binding.gyp b/binding.gyp index 7e83b4c..682c95e 100644 --- a/binding.gyp +++ b/binding.gyp @@ -34,6 +34,7 @@ 'src/extensions/sn3218.cc', 'src/extensions/sr595.cc', 'src/extensions/pca9685.cc', + 'src/extensions/dac7678.cc', 'src/devlib/devlib.cc', 'src/devlib/ds1302.cc', diff --git a/src/devlib/tcs34725.cc b/src/devlib/tcs34725.cc index 185c24c..79c3f81 100644 --- a/src/devlib/tcs34725.cc +++ b/src/devlib/tcs34725.cc @@ -2,6 +2,7 @@ #include "tcs34725.h" DECLARE(tcs34725ReadRGBC); +DECLARE(tcs34725ReadHSV); DECLARE(tcs34725GetCorrelatedColorTemperature); DECLARE(tcs34725GetIlluminance); DECLARE(tcs34725SetInterrupt); diff --git a/src/extensions/dac7678.cc b/src/extensions/dac7678.cc index 03bce9c..ca1ded0 100644 --- a/src/extensions/dac7678.cc +++ b/src/extensions/dac7678.cc @@ -17,16 +17,16 @@ IMPLEMENT(dac7678Setup) { CHECK_ARGUMENT_TYPE_INT32(1); CHECK_ARGUMENT_TYPE_UINT32(2); + int pinBase = GET_ARGUMENT_AS_INT32(0); + int i2cAddress = GET_ARGUMENT_AS_INT32(1); + unsigned short vrefMode = GET_ARGUMENT_AS_UINT32(2); + CHECK_ARGUMENT_IN_INTS(2, vrefMode, (DAC7678_VREF_MODE_STATIC_ON, DAC7678_VREF_MODE_STATIC_OFF, DAC7678_VREF_MODE_FLEXIBLE_ON, - DAC7678_VREF_MODE_FLEXIBLE_ALWAYS_ON + DAC7678_VREF_MODE_FLEXIBLE_ALWAYS_ON, DAC7678_VREF_MODE_FLEXIBLE_ALWAYS_OFF)); - int pinBase = GET_ARGUMENT_AS_INT32(0); - int i2cAddress = GET_ARGUMENT_AS_INT32(1); - unsigned short vrefMode = GET_ARGUMENT_AS_UINT32(2); - int res = ::dac7678Setup(pinBase, i2cAddress, vrefMode); SCOPE_CLOSE(INT32(res)); From 192d25326d507ef2f60ae57d67ac36fc1ea8668a Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Sun, 28 Dec 2014 15:41:03 +0100 Subject: [PATCH 62/64] tcs34725 update variable type --- src/devlib/tcs34725.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/devlib/tcs34725.cc b/src/devlib/tcs34725.cc index 79c3f81..d25026d 100644 --- a/src/devlib/tcs34725.cc +++ b/src/devlib/tcs34725.cc @@ -22,7 +22,7 @@ IMPLEMENT(tcs34725ReadRGBC) { CHECK_ARGUMENT_TYPE_INT32(0); int id = GET_ARGUMENT_AS_INT32(0); - unsigned short r, g, b, c; + unsigned char r, g, b, c; ::tcs34725ReadRGBC(id, &r, &g, &b, &c); @@ -45,7 +45,8 @@ IMPLEMENT(tcs34725ReadHSV) { CHECK_ARGUMENT_TYPE_INT32(0); int id = GET_ARGUMENT_AS_INT32(0); - unsigned short h, s, v; + unsigned short h; + unsigned char s, v; ::tcs34725ReadHSV(id, &h, &s, &v); From bd2ff91a09621d912c09b5ec229cc037faaf8ca9 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Tue, 30 Dec 2014 20:17:17 +0100 Subject: [PATCH 63/64] Update documentation & changelog --- CHANGELOG.md | 7 ++++++- DOCUMENTATION.md | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c75c049..56bee6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # CHANGELOG -## v2.0.0 *[not released yet]* +## v2.1.0 *[not released yes]* + * **Update:** libWiringPi to [custom][nekuz0r-libWiringPi] v2.21 `nekuz0r` + * **Add:** raspberry pi A+ support `nekuz0r` + +## v2.0.0 *[Jan 1 2015]* * **Update:** libWiringPi to [custom][nekuz0r-libWiringPi] v2.20 `nekuz0r` * **Update:** split source code (based on libWiringPi hierarchy) `nekuz0r` * **Update:** better types check `nekuz0r` @@ -32,6 +36,7 @@ * **Add:** piGlow support `nekuz0r` * **Add:** piNes support `nekuz0r` * **Add:** tcs34725 support `nekuz0r` + * **Add:** dac7678 support `nekuz0r` * **Fictitious:** this release eats Pi(e)s :) ## v1.1.1 *[Jul 4 2014]* diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 6a83066..b1548c6 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -15,6 +15,7 @@ * [Soft Servo](#soft-servo) * [Soft Tone](#soft-tone) * [Extensions](#extensions) + * [dac7678](#dac7678) * [drcSerial](#drcserial) * [max31855](#max31855) * [max5322](#max5322) @@ -695,6 +696,28 @@ The tone will be played until you set the frequency to 0. ## Extensions +### dac7678 + +12-Bit octal-channel DAC with 2.5V internal reference (I2C) + +*Datasheet*: http://www.ti.com/lit/ds/sbas493c/sbas493c.pdf + +#### dac7678Setup(pinBase, i2cAddress, vrefMode) + >= 2.0.0 + +`state` can be one of the following value: + +* `DAC7678_VREF_MODE_STATIC_ON` + >= 2.0.0 +* `DAC7678_VREF_MODE_STATIC_OFF` + >= 2.0.0 +* `DAC7678_VREF_MODE_FLEXIBLE_ON` + >= 2.0.0 +* `DAC7678_VREF_MODE_FLEXIBLE_ALWAYS_ON` + >= 2.0.0 +* `DAC7678_VREF_MODE_FLEXIBLE_ALWAYS_OFF` + >= 2.0.0 + ### drcSerial #### drcSetupSerial(pinBase, numPins, device, baudrate) @@ -1080,10 +1103,18 @@ Color light-to-digital converter with IR filter #### tcs34725Setup(i2cAddress, integrationTime, gain) >= 2.0.0 +Initialize the device and returns the assigned id. +Don't forget to call `tcs34725Enable`, the device is in power sleep mode after initialization. + #### tcs34725ReadRGBC(id) >= 2.0.0 -Read the raw red, green, blue and clear channel values +Read the raw red, green, blue and clear channel values (0 - 255) + +#### tcs34725ReadHSV(id) + >= 2.0.0 + +Returns the cylindrical-coordinate representation of the sensor red, green and blue channels. #### tcs34725GetCorrelatedColorTemperature(r, g, b) >= 2.0.0 From cf0ecd25747f10a69338365b3d3bf049ca3e5022 Mon Sep 17 00:00:00 2001 From: Leandre Gohy Date: Tue, 30 Dec 2014 20:22:15 +0100 Subject: [PATCH 64/64] Preparing the release --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 1983eda..001b72d 100644 --- a/install.sh +++ b/install.sh @@ -40,7 +40,7 @@ rm ./install.log 2>/dev/null 1>&2 echo -n "Cloning libWiringPi ... " rm -Rf ./wiringpi 2>/dev/null 1>&2 -git clone https://github.com/nekuz0r/wiringpi.git -b incoming > ./install.log 2>&1 +git clone https://github.com/nekuz0r/wiringpi.git > ./install.log 2>&1 check_git_clone #git submodule init #check_git_clone