mirror of
https://github.com/eclipse/upm.git
synced 2025-07-06 20:01:12 +03:00
Compare commits
219 Commits
v1.1.0
...
iio_change
Author | SHA1 | Date | |
---|---|---|---|
93054c382b | |||
6ac2557b7d | |||
cc3721128e | |||
28380f2bfa | |||
303323fa3a | |||
0bf4a38f5e | |||
e441c343d8 | |||
60816d8f2a | |||
ef681a0ab5 | |||
f37236fa01 | |||
aa047d6b5c | |||
0345a8e9f1 | |||
5bdd7a4c03 | |||
3ca7889755 | |||
c5cdfc702c | |||
a99e32fc13 | |||
9e09f899cf | |||
ae77966204 | |||
b0a842229a | |||
0f3f0e02ae | |||
287d716401 | |||
db89d872b4 | |||
c46fb64cac | |||
1f97840fee | |||
7bee29ba62 | |||
24b6cbcc85 | |||
ab4eeea61e | |||
98811b0fb7 | |||
f92c0c120e | |||
01036f7dae | |||
5e7a8b41a3 | |||
f59f3131bb | |||
539fbe7c75 | |||
5a1f27a92d | |||
f4da94a06e | |||
e190bb9d60 | |||
bac9e3bbc0 | |||
1647d8bc08 | |||
6bfb07e46a | |||
c25fa47e2f | |||
7cd290901d | |||
aaf733f41b | |||
ac4a10e248 | |||
8a4e06d856 | |||
9482d6bb74 | |||
0cb93331ee | |||
f01c89b95a | |||
4344151405 | |||
74cb3504f3 | |||
ac031ba9a8 | |||
65726087bc | |||
dc03eec56f | |||
c1903b8c39 | |||
0cb7d3f9b4 | |||
874eacf12e | |||
3e6fb61a20 | |||
8e7ac713c4 | |||
54c1b0ce4b | |||
53456d9138 | |||
7ec1765766 | |||
bb122bfac4 | |||
0f8e578c62 | |||
dcee721cb3 | |||
b11ec1638e | |||
fb6ae47b6d | |||
be718d79af | |||
87ffc81b65 | |||
afd9dd07e4 | |||
ce9742b355 | |||
c402fbb5e8 | |||
b757ccc617 | |||
c5c57b523b | |||
bb4ce17d44 | |||
d4396c2ce3 | |||
780b5df024 | |||
60379fca37 | |||
b90c5a7710 | |||
28f964cb48 | |||
b68eb5f6a6 | |||
50bb4ae1be | |||
da18bac925 | |||
2b70bea44f | |||
c64d04d084 | |||
8186d093ec | |||
b2eb392a07 | |||
274fd9b608 | |||
27eec52e29 | |||
ee0aaa89eb | |||
886deabfbb | |||
e740349355 | |||
34f2799c53 | |||
a03d8eb52f | |||
07f3029f10 | |||
a56b83fa37 | |||
b4bc15201b | |||
c70f378f72 | |||
106b6c7062 | |||
6c3b161702 | |||
c484056cf0 | |||
2931a9c24d | |||
aeefc758ee | |||
21a1860ec2 | |||
c78da687d4 | |||
6c383dbd42 | |||
7688e5f230 | |||
1db6bd826a | |||
e7ca8cf18b | |||
cdb735c34e | |||
90e4b5d385 | |||
6a37edcdac | |||
563519ae4f | |||
7b812284c5 | |||
0082f54902 | |||
b32e4911ab | |||
fe9254c004 | |||
e3a8b2fc13 | |||
21ecbd90eb | |||
0bd68e4e2b | |||
b2aa2515b0 | |||
5cc4e2120a | |||
fe4e97f5dc | |||
6e4faefe15 | |||
460e9de94f | |||
1f5f466691 | |||
12c59a6aca | |||
19c58ebba2 | |||
d9fd1af272 | |||
78eb975435 | |||
a0ea3d5f3d | |||
f77863dfb5 | |||
7e5f6e9856 | |||
d004aa68b7 | |||
3aef2ea70e | |||
39df7fd10f | |||
b8738b32ca | |||
cdb697fd7b | |||
27dc4a5742 | |||
e2fe04927f | |||
a655235c70 | |||
96b219d2fb | |||
52879b0b04 | |||
048f1ac08e | |||
76a12af15f | |||
e6ed49427a | |||
c57a0d2c30 | |||
8d43c431f2 | |||
336251740d | |||
356f0348ed | |||
dc7c012c24 | |||
96eb834e9b | |||
b239866e99 | |||
6a4f06d51b | |||
e765dcf57b | |||
a594036778 | |||
c014ffddcd | |||
aeaf84ccc6 | |||
7d789ec208 | |||
3d0461b40a | |||
5aed632782 | |||
3c5a5b87c8 | |||
22a6c52795 | |||
b8fa948f7d | |||
f61b615704 | |||
8dcd22794b | |||
33f3c882b8 | |||
5943dad78c | |||
2f051a202c | |||
a760f2952a | |||
9549529faf | |||
65969462d1 | |||
13eea53090 | |||
fa8ab6194d | |||
8048e8734f | |||
8262a4203b | |||
01f9dd2f41 | |||
ccb9fa2a4f | |||
05435eed4f | |||
54a84af1c3 | |||
27c6ac1d31 | |||
8779700d82 | |||
f9b5d7c52c | |||
a10e798682 | |||
8cd91624ee | |||
68e42a22d6 | |||
fdef953859 | |||
3f334ed1f3 | |||
1a0bdf00cf | |||
54cd191d43 | |||
9fa4dad1ab | |||
080c121e07 | |||
545e288967 | |||
aecdac255d | |||
5c837f22cb | |||
12c81adeba | |||
8342b4c079 | |||
e83b8ef114 | |||
fabf4287d6 | |||
4ea01180a1 | |||
ab171573f9 | |||
d965b92af1 | |||
cc0174910b | |||
c4a506f5a3 | |||
58cdfadf4e | |||
b3a5275183 | |||
b314f56c00 | |||
d4b536b593 | |||
2bdde21a2f | |||
6ceebc9a17 | |||
65fc70a31a | |||
51a181a14f | |||
cfb4105dd8 | |||
b7faba556f | |||
95801b395d | |||
1f18369fbe | |||
f8663c90f3 | |||
1d6d660769 | |||
b57710cd78 | |||
6d41566e93 | |||
7a60cd5abe |
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
Dockerfile
|
||||
docker-compose.yaml
|
||||
build
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -11,3 +11,6 @@ build*/
|
||||
# Temp files
|
||||
*.swp
|
||||
*~
|
||||
|
||||
# Node modules
|
||||
**/node_modules
|
||||
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[submodule "doxy/doxygen2jsdoc"]
|
||||
path = doxy/doxygen2jsdoc
|
||||
url = https://github.com/intel-iot-devkit/doxygen2jsdoc
|
||||
[submodule "doxy/doxyport"]
|
||||
path = doxy/doxyport
|
||||
url = https://github.com/intel-iot-devkit/doxyport
|
127
.travis.yml
127
.travis.yml
@ -1,48 +1,81 @@
|
||||
dist: trusty
|
||||
sudo: required
|
||||
|
||||
language: cpp
|
||||
env:
|
||||
global:
|
||||
- MRAA_ROOT=/tmp/mraa
|
||||
- MRAA_BUILD=$MRAA_ROOT/build
|
||||
- UPM_ROOT=$TRAVIS_BUILD_DIR
|
||||
- UPM_BUILD=$UPM_ROOT/build
|
||||
- JAVA_HOME=/usr/lib/jvm/java-8-oracle
|
||||
matrix:
|
||||
- NODE010=true
|
||||
- NODE012=true
|
||||
- NODE4=true
|
||||
- NODE5=true
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
install:
|
||||
- sudo add-apt-repository --yes ppa:rosmo/swig3.0.7
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -y --force-yes -qq swig3.0 git
|
||||
- sudo ln -s /usr/bin/swig3.0 /usr/bin/swig
|
||||
- sudo update-java-alternatives -s java-8-oracle
|
||||
before_script:
|
||||
# Turn off JAVA SWIG for clang++, use 4.8 for all g++ builds
|
||||
- if [ "$CC" == "gcc" ]; then export BUILDJAVA=ON; export CC=gcc-4.8; export CXX=g++-4.8; else export BUILDJAVA=OFF; fi
|
||||
- if [ "${NODE012}" ]; then nvm install 0.12; fi
|
||||
- if [ "${NODE4}" ]; then nvm install 4.1; fi
|
||||
- if [ "${NODE5}" ]; then nvm install 5; fi
|
||||
# Handle 0.10 NODE_ROOT_DIR differently than other versions
|
||||
- if [ -z ${NODE010} ]; then export NODE_ROOT_DIR="/home/travis/.nvm/versions/node/`nvm version`"; else export NODE_ROOT_DIR=/home/travis/.nvm/v0.10.36; fi
|
||||
script:
|
||||
# Build/install MRAA
|
||||
- echo "CC=$CC BUILDJAVA=$BUILDJAVA NODE010=$NODE010 NODE012=$NODE012 NODE4=$NODE4 NODE5=$NODE5 NODE_ROOT_DIR=$NODE_ROOT_DIR"
|
||||
- git clone https://github.com/intel-iot-devkit/mraa.git $MRAA_ROOT
|
||||
- mkdir -p $MRAA_BUILD && cd $_ && cmake -DBUILDSWIGJAVA=$BUILDJAVA -DBUILDSWIGNODE=OFF -DBUILDSWIGPYTHON=ON -DFIRMATA=ON -DENABLEEXAMPLES=OFF $MRAA_ROOT
|
||||
- sudo make install
|
||||
- sudo ldconfig
|
||||
# Build/install UPM
|
||||
- cd $UPM_ROOT && mkdir $UPM_BUILD && cd $_ && cmake -DNODE_ROOT_DIR:PATH="${NODE_ROOT_DIR}" -DBUILDSWIGJAVA=$BUILDJAVA -DBUILDEXAMPLES=ON -DBUILDTESTS=ON -DBUILDFTI=ON .. && sudo make install && sudo ldconfig && ctest --output-on-failure -E examplenames_js
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- george-edison55-precise-backports
|
||||
packages:
|
||||
- cmake
|
||||
- cmake-data
|
||||
- g++-4.8
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
before_install:
|
||||
- sudo rm /usr/local/bin/docker-compose
|
||||
- curl -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-`uname -s`-`uname -m` > docker-compose
|
||||
- chmod +x docker-compose
|
||||
- sudo mv docker-compose /usr/local/bin
|
||||
|
||||
jobs:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- env: TARGET=ipk
|
||||
include:
|
||||
- &run-with-clang
|
||||
stage: Clang 3.8
|
||||
env: TARGET=python
|
||||
before_script: docker-compose pull ${TARGET}
|
||||
script:
|
||||
- export CC=clang-3.8 CXX=clang++-3.8
|
||||
- docker-compose run ${TARGET}
|
||||
- <<: *run-with-clang
|
||||
env: TARGET=node4
|
||||
- <<: *run-with-clang
|
||||
env: TARGET=node5
|
||||
- <<: *run-with-clang
|
||||
env: TARGET=node6
|
||||
- <<: *run-with-clang
|
||||
env: TARGET=java
|
||||
- &run-with-gcc-5
|
||||
stage: Gcc 5
|
||||
env: TARGET=python
|
||||
before_script: docker-compose pull ${TARGET}
|
||||
script:
|
||||
- export CC=gcc-5 CXX=g++-5
|
||||
- docker-compose run ${TARGET}
|
||||
- <<: *run-with-gcc-5
|
||||
env: TARGET=node4
|
||||
- <<: *run-with-gcc-5
|
||||
env: TARGET=node5
|
||||
- <<: *run-with-gcc-5
|
||||
env: TARGET=node6
|
||||
- <<: *run-with-gcc-5
|
||||
env: TARGET=java
|
||||
- &run-with-gcc-6
|
||||
stage: Gcc 6
|
||||
env: TARGET=python
|
||||
before_script: docker-compose pull ${TARGET}
|
||||
script:
|
||||
- export CC=gcc-6 CXX=g++-6
|
||||
- docker-compose run ${TARGET}
|
||||
- <<: *run-with-gcc-6
|
||||
env: TARGET=node4
|
||||
- <<: *run-with-gcc-6
|
||||
env: TARGET=node5
|
||||
- <<: *run-with-gcc-6
|
||||
env: TARGET=node6
|
||||
- <<: *run-with-gcc-6
|
||||
env: TARGET=java
|
||||
- &run-additional-jobs
|
||||
stage: Additional Jobs
|
||||
env: TARGET=doc
|
||||
before_script: docker-compose pull ${TARGET}
|
||||
script:
|
||||
- export CC=clang-3.8 CXX=clang++-3.8
|
||||
- docker-compose run ${TARGET}
|
||||
- <<: *run-additional-jobs
|
||||
env: TARGET=android
|
||||
- <<: *run-additional-jobs
|
||||
env: TARGET=sonar-scan
|
||||
- <<: *run-additional-jobs
|
||||
env: TARGET=ipk
|
||||
- <<: *run-additional-jobs
|
||||
env: TARGET=rpm
|
||||
- <<: *run-additional-jobs
|
||||
env: TARGET=npm
|
||||
|
@ -95,7 +95,7 @@ set (C_CXX_WARNING_FLAGS -Wall -Wno-misleading-indentation -Wno-strict-aliasing)
|
||||
|
||||
# Warnings as errors?
|
||||
if (WERROR)
|
||||
set (C_CXX_WARNING_FLAGS "-Werror ${C_CXX_WARNING_FLAGS}")
|
||||
list (APPEND C_CXX_WARNING_FLAGS -Werror)
|
||||
message (STATUS "Warnings as errors enabled (-Werror), disable with -DWERROR=off")
|
||||
endif (WERROR)
|
||||
|
||||
@ -113,15 +113,26 @@ upm_add_compile_flags(CXX ${C_CXX_WARNING_FLAGS}
|
||||
-Woverloaded-virtual
|
||||
-Wreorder)
|
||||
|
||||
# Allow exception error handling for Android C++
|
||||
if (ANDROID)
|
||||
upm_add_compile_flags(CXX -fexceptions)
|
||||
endif (ANDROID)
|
||||
|
||||
find_package (Threads REQUIRED)
|
||||
find_package (PkgConfig REQUIRED)
|
||||
|
||||
# Force a libmraa search and minimum required version every time a config is generated
|
||||
unset(MRAA_FOUND CACHE)
|
||||
set(MRAA_MINIMUM 1.4.0)
|
||||
set(MRAA_MINIMUM 1.8.0)
|
||||
pkg_check_modules (MRAA REQUIRED mraa>=${MRAA_MINIMUM})
|
||||
# Also, get full path to the mraa library
|
||||
find_library(MRAA_LIBRARY NAMES mraa PATHS ${MRAA_LIBDIR} NO_DEFAULT_PATH)
|
||||
find_library(MRAA_LIBRARY NAMES mraa HINTS ${MRAA_LIBDIR})
|
||||
|
||||
# Test MRAA for various compile options
|
||||
include (CheckLibraryExists)
|
||||
check_library_exists (${MRAA_LIBRARIES} mraa_iio_init "${MRAA_LIBDIR}" MRAA_IIO_FOUND)
|
||||
check_library_exists (${MRAA_LIBRARIES} mraa_firmata_init "${MRAA_LIBDIR}" MRAA_FIRMATA_FOUND)
|
||||
check_library_exists (${MRAA_LIBRARIES} mraa_uart_ow_init "${MRAA_LIBDIR}" MRAA_OW_FOUND)
|
||||
|
||||
# Check for BACNET
|
||||
pkg_check_modules (BACNET libbacnet)
|
||||
@ -138,15 +149,23 @@ find_package (JPEG)
|
||||
# Find nodejs
|
||||
if (BUILDSWIGNODE)
|
||||
find_package (Node REQUIRED)
|
||||
if (BUILDTESTS)
|
||||
find_package (Npm REQUIRED)
|
||||
if(NPM_EXECUTABLE)
|
||||
message(STATUS "NPM Executable found at: ${NPM_EXECUTABLE}")
|
||||
else()
|
||||
message(FATAL_ERROR "Please install NPM first, you can't run tests without it")
|
||||
endif()
|
||||
endif (BUILDTESTS)
|
||||
endif (BUILDSWIGNODE)
|
||||
|
||||
# Find JAVA/JNI
|
||||
if (BUILDSWIGJAVA)
|
||||
find_package (Java REQUIRED)
|
||||
find_package (JNI REQUIRED)
|
||||
pkg_check_modules (MRAAJAVA REQUIRED mraajava>=0.8.0)
|
||||
pkg_check_modules (MRAAJAVA REQUIRED mraajava>=${MRAA_MINIMUM})
|
||||
# Also, get full path to the mraajava library
|
||||
find_library(MRAAJAVA_LIBRARY NAMES mraajava PATHS ${MRAA_LIBDIR} NO_DEFAULT_PATH)
|
||||
find_library(MRAAJAVA_LIBRARY NAMES mraajava HINTS ${MRAA_LIBDIR})
|
||||
endif (BUILDSWIGJAVA)
|
||||
|
||||
# Find swig if any wrapper is enabled
|
||||
@ -197,7 +216,7 @@ include (GetGitRevisionDescription)
|
||||
git_describe (VERSION "--tags")
|
||||
# If git_describe fails, use a dirty version
|
||||
if (${VERSION} MATCHES -NOTFOUND)
|
||||
set (VERSION "v1.1.0")
|
||||
set (VERSION "v1.3.0")
|
||||
message (WARNING "Failed to retrieve UPM version with 'git describe' (using "
|
||||
"${VERSION}). Check that git is installed and this is a valid git repo.")
|
||||
endif ()
|
||||
@ -225,11 +244,6 @@ include (TargetArch)
|
||||
target_architecture (DETECTED_ARCH)
|
||||
message (STATUS "Target arch is ${DETECTED_ARCH}")
|
||||
|
||||
#-march=native for ARM when not defined/forced
|
||||
if (DETECTED_ARCH MATCHES "arm.*" AND NOT CMAKE_CXX_FLAGS MATCHES "-march")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
|
||||
endif()
|
||||
|
||||
# enable c++11 standards support unconditionally
|
||||
include(CheckCXXCompilerFlag)
|
||||
if (CMAKE_VERSION VERSION_LESS "3.1")
|
||||
@ -312,7 +326,7 @@ if (BUILDDOC)
|
||||
COMMENT "Generating API documentation with Doxygen" VERBATIM
|
||||
)
|
||||
|
||||
# Check if Sphinx is installed and add target to generate API documentationa
|
||||
# Check if Sphinx is installed and add target to generate API documentation
|
||||
# Currently, the per-module documentation for python is generated from the
|
||||
# python2 modules.
|
||||
if(BUILDSWIGPYTHON)
|
||||
@ -337,14 +351,10 @@ if (BUILDDOC)
|
||||
# Check if Yuidoc is installed and add target for API documentation
|
||||
if(BUILDSWIGNODE)
|
||||
find_package(Yuidoc REQUIRED)
|
||||
file(GLOB_RECURSE JSDOC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/doxy/node doxy/node/*)
|
||||
foreach(JSDOC_FILE ${JSDOC_FILES})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxy/node/${JSDOC_FILE} ${CMAKE_CURRENT_BINARY_DIR}/${JSDOC_FILE} COPYONLY)
|
||||
endforeach()
|
||||
add_custom_target(jsdoc ALL
|
||||
COMMAND ${NODEJS_EXECUTABLE} docgen -m upm -i xml -t ${CMAKE_CURRENT_SOURCE_DIR}/src -g ../../
|
||||
COMMAND ${YUIDOC_EXECUTABLE} -C --no-sort --helpers generators/yuidoc/helper.js --themedir generators/yuidoc/tmpl -o html/node jsdoc/yuidoc/upm
|
||||
COMMAND ${NODEJS_EXECUTABLE} tolower -i html/node
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/doxy/doxygen2jsdoc/docgen.js -m upm -i xml -o jsdoc -t ${CMAKE_CURRENT_SOURCE_DIR}/src -g ../../
|
||||
COMMAND ${YUIDOC_EXECUTABLE} -C --no-sort --helpers ${CMAKE_SOURCE_DIR}/doxy/node/generators/yuidoc/helper.js --themedir ${CMAKE_SOURCE_DIR}/doxy/node/generators/yuidoc/tmpl -o html/node jsdoc/yuidoc/upm
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/doxy/doxygen2jsdoc/tolower.js -i html/node
|
||||
DEPENDS doc
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Yuidoc" VERBATIM
|
||||
@ -415,22 +425,16 @@ if (RPM)
|
||||
endif()
|
||||
|
||||
# UPM common headers
|
||||
set (UPM_COMMON_HEADER_DIRS
|
||||
${CMAKE_HOME_DIRECTORY}/include
|
||||
${CMAKE_HOME_DIRECTORY}/include/fti)
|
||||
set (UPM_COMMON_HEADER_DIRS ${CMAKE_HOME_DIRECTORY}/include)
|
||||
|
||||
# Generate a build-only C++ header to add functionality to SWIG'ed modules
|
||||
configure_file (${PROJECT_SOURCE_DIR}/cmake/modules/version.hpp.in ${PROJECT_BINARY_DIR}/src/version.hpp @ONLY)
|
||||
|
||||
# UPM source
|
||||
add_subdirectory (src)
|
||||
if(BUILDEXAMPLES)
|
||||
add_subdirectory (examples/c)
|
||||
if(BUILDCPP)
|
||||
add_subdirectory (examples/c++)
|
||||
endif(BUILDCPP)
|
||||
endif()
|
||||
|
||||
# Build java examples
|
||||
if(BUILDSWIGJAVA AND BUILDEXAMPLES)
|
||||
add_subdirectory (examples/java)
|
||||
endif()
|
||||
# UPM examples
|
||||
add_subdirectory (examples)
|
||||
|
||||
# Python interp is previously found if BUILDTESTS=ON
|
||||
if (BUILDTESTS)
|
||||
|
23
README.md
23
README.md
@ -30,36 +30,28 @@ sensors and actuators and provide feedback on interface design.
|
||||
A sensor/actuator is expected to work as such (here is the MMA7660 accelerometer API):
|
||||
```C++
|
||||
// Instantiate an MMA7660 on I2C bus 0
|
||||
upm::MMA7660 *accel = new upm::MMA7660(MMA7660_I2C_BUS,
|
||||
upm::MMA7660 *accel = new upm::MMA7660(MMA7660_DEFAULT_I2C_BUS,
|
||||
MMA7660_DEFAULT_I2C_ADDR);
|
||||
|
||||
// place device in standby mode so we can write registers
|
||||
accel->setModeStandby();
|
||||
|
||||
// enable 64 samples per second
|
||||
accel->setSampleRate(upm::MMA7660::AUTOSLEEP_64);
|
||||
|
||||
accel->setSampleRate(MMA7660_AUTOSLEEP_64);
|
||||
|
||||
// place device into active mode
|
||||
accel->setModeActive();
|
||||
|
||||
while (shouldRun)
|
||||
{
|
||||
int x, y, z;
|
||||
|
||||
accel->getRawValues(&x, &y, &z);
|
||||
cout << "Raw values: x = " << x
|
||||
<< " y = " << y
|
||||
<< " z = " << z
|
||||
<< endl;
|
||||
|
||||
float ax, ay, az;
|
||||
|
||||
|
||||
accel->getAcceleration(&ax, &ay, &az);
|
||||
cout << "Acceleration: x = " << ax
|
||||
cout << "Acceleration: x = " << ax
|
||||
<< "g y = " << ay
|
||||
<< "g z = " << az
|
||||
<< "g" << endl;
|
||||
|
||||
|
||||
usleep(500000);
|
||||
}
|
||||
```
|
||||
@ -136,7 +128,8 @@ our API in a way that will break backwards compatibility. If you find yourself
|
||||
unable to compile code that was working fine before a library update, make sure
|
||||
you check the [API changes](docs/apichanges.md) section first.
|
||||
|
||||
**NOTE** - Our **C++ header files** changed extension from *.h* to *.hpp*!
|
||||
**NOTE** - Several important API changes are currently underway for some of our
|
||||
widely used libraries including `libupm-grove` and `libupm-i2clcd`!
|
||||
|
||||
### Changelog
|
||||
Version changelog [here](docs/changelog.md).
|
||||
|
@ -23,13 +23,16 @@ if (UV_ROOT_DIR)
|
||||
endif()
|
||||
|
||||
# Now look for node. Flag an error if not found
|
||||
find_path (NODE_ROOT_DIR "include/node/node.h" "include/src/node.h"
|
||||
find_path (NODE_ROOT_DIR "include/node/node.h" "include/src/node.h" "src/node.h"
|
||||
PATHS /usr/include/nodejs /usr/local/include/nodejs /usr/local/include)
|
||||
if (NODE_ROOT_DIR)
|
||||
add_include_dir(${NODE_ROOT_DIR}/include/src)
|
||||
add_include_dir(${NODE_ROOT_DIR}/src)
|
||||
add_include_dir(${NODE_ROOT_DIR}/include/node)
|
||||
add_include_dir(${NODE_ROOT_DIR}/include/deps/v8/include)
|
||||
add_include_dir(${NODE_ROOT_DIR}/deps/v8/include)
|
||||
add_include_dir(${NODE_ROOT_DIR}/include/deps/uv/include)
|
||||
add_include_dir(${NODE_ROOT_DIR}/deps/uv/include)
|
||||
else()
|
||||
unset(NODEJS_INCLUDE_DIRS)
|
||||
message(ERROR " - node.h not found")
|
||||
|
13
cmake/modules/FindNpm.cmake
Normal file
13
cmake/modules/FindNpm.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
# Finding and pointing a variable to the npm executable if found
|
||||
# Only works on Linux systems as of now
|
||||
|
||||
find_program(NPM_EXECUTABLE NAMES npm
|
||||
HINTS
|
||||
/usr
|
||||
)
|
||||
|
||||
if(NPM_EXECUTABLE)
|
||||
message(STATUS "NPM Executable found at ${NPM_EXECUTABLE}")
|
||||
else()
|
||||
message(ERROR "Unable to find NPM installation, please install NPM")
|
||||
endif()
|
@ -1,4 +0,0 @@
|
||||
#include "version.h"
|
||||
|
||||
const char* gVERSION = "@VERSION@";
|
||||
const char* gVERSION_SHORT = "@VERSION_SHORT@";
|
6
cmake/modules/version.hpp.in
Normal file
6
cmake/modules/version.hpp.in
Normal file
@ -0,0 +1,6 @@
|
||||
#include <string>
|
||||
|
||||
inline std::string getVersion()
|
||||
{
|
||||
return "@upm_VERSION_STRING@";
|
||||
}
|
112
docker-compose.yaml
Normal file
112
docker-compose.yaml
Normal file
@ -0,0 +1,112 @@
|
||||
version: '2.1'
|
||||
|
||||
services:
|
||||
|
||||
base:
|
||||
image: dnoliver/upm-base
|
||||
environment:
|
||||
- http_proxy
|
||||
- https_proxy
|
||||
- no_proxy
|
||||
- BUILDDOC=${BUILDDOC:-OFF}
|
||||
- BUILDCPP=${BUILDCPP:-ON}
|
||||
- BUILDFTI=${BUILDFTI:-ON}
|
||||
- BUILDSWIGPYTHON=${BUILDSWIGPYTHON:-OFF}
|
||||
- BUILDSWIGJAVA=${BUILDSWIGJAVA:-OFF}
|
||||
- BUILDSWIGNODE=${BUILDSWIGNODE:-OFF}
|
||||
- BUILDEXAMPLES=${BUILDEXAMPLES:-ON}
|
||||
- IPK=${IPK:-OFF}
|
||||
- RPM=${RPM:-OFF}
|
||||
- NPM=${NPM:-OFF}
|
||||
- BUILDTESTS=${BUILDTESTS:-ON}
|
||||
- CC=${CC:-clang-3.8}
|
||||
- CXX=${CXX:-clang++-3.8}
|
||||
- NODE_VERSION=${NODE_VERSION:-v4.4.7}
|
||||
- WERROR=${WERROR:-ON}
|
||||
volumes:
|
||||
- .:${UPM_SRC_DIR:-/usr/src/app}
|
||||
|
||||
doc:
|
||||
extends: base
|
||||
image: dnoliver/upm-all
|
||||
environment:
|
||||
- BUILDSWIGPYTHON=ON
|
||||
- BUILDSWIGJAVA=ON
|
||||
- BUILDSWIGNODE=ON
|
||||
- BUILDDOC=ON
|
||||
command: bash -c "./scripts/run-cmake.sh && ./scripts/build-doc.sh"
|
||||
|
||||
ipk:
|
||||
extends: base
|
||||
environment:
|
||||
- IPK=ON
|
||||
- BUILDDOC=OFF
|
||||
command: bash -c "./scripts/run-cmake.sh && make -Cbuild -j8 package"
|
||||
|
||||
rpm:
|
||||
extends: doc
|
||||
environment:
|
||||
- RPM=ON
|
||||
- BUILDDOC=OFF
|
||||
command: bash -c "./scripts/run-cmake.sh && make -Cbuild -j8 package"
|
||||
|
||||
npm:
|
||||
extends: doc
|
||||
environment:
|
||||
- NPM=ON
|
||||
- BUILDDOC=OFF
|
||||
command: bash -c "./scripts/run-cmake.sh && make -Cbuild -j8 npmpkg"
|
||||
|
||||
sonar-scan:
|
||||
extends: base
|
||||
image: dnoliver/upm-all
|
||||
environment:
|
||||
- BUILDSWIGPYTHON=ON
|
||||
- BUILDSWIGNODE=ON
|
||||
- BUILDSWIGJAVA=ON
|
||||
- BUILDSWIGEXAMPLES=ON
|
||||
- SONAR_TOKEN
|
||||
- SONAR_ORG
|
||||
- SONAR_PROJ_KEY
|
||||
- TRAVIS_BRANCH
|
||||
- TRAVIS_PULL_REQUEST
|
||||
- TRAVIS_REPO_SLUG
|
||||
- TRAVIS_PULL_REQUEST_SLUG
|
||||
- GITHUB_TOKEN
|
||||
command: bash -c "./scripts/run-cmake.sh && cd build && ../scripts/sonar-scan.sh"
|
||||
|
||||
python:
|
||||
extends: base
|
||||
image: dnoliver/upm-python
|
||||
environment:
|
||||
- BUILDSWIGPYTHON=ON
|
||||
command: bash -c "./scripts/run-cmake.sh && cd build && make -j8 && make -j8 install && ldconfig && ctest --output-on-failure"
|
||||
|
||||
java:
|
||||
extends: base
|
||||
image: dnoliver/upm-java
|
||||
environment:
|
||||
- BUILDSWIGJAVA=ON
|
||||
command: bash -c "./scripts/run-cmake.sh && cd build && make -j8 && make -j8 install && ldconfig && ctest --output-on-failure"
|
||||
|
||||
android:
|
||||
extends: java
|
||||
image: dnoliver/upm-android
|
||||
environment:
|
||||
- BUILDTESTS=OFF
|
||||
command: bash -c "./scripts/build-android.sh"
|
||||
|
||||
node4:
|
||||
extends: base
|
||||
image: dnoliver/upm-node4
|
||||
environment:
|
||||
- BUILDSWIGNODE=ON
|
||||
command: bash -c "./scripts/run-cmake.sh && cd build && make -j8 && make -j8 install && ldconfig && ctest --output-on-failure -E examplenames_js"
|
||||
|
||||
node5:
|
||||
extends: node4
|
||||
image: dnoliver/upm-node5
|
||||
|
||||
node6:
|
||||
extends: node4
|
||||
image: dnoliver/upm-node6
|
@ -4,6 +4,178 @@ API Changes {#apichanges}
|
||||
Here's a list of other API changes made to the library that break source/binary
|
||||
compatibility between releases:
|
||||
|
||||
# v1.3.0
|
||||
|
||||
* **The lsm303 driver has been renamed** There are a variety of
|
||||
LSM303 devices out there with various incompatibilities and differing
|
||||
capabilities. The current lsm303 driver in UPM only supports the
|
||||
LSM303DLH variant, so it has been renamed to lsm303dlh to avoid
|
||||
confusion and to make it clear which variant is actually supported.
|
||||
|
||||
All examples and source files have been renamed, including header
|
||||
files. In addition, the class name, LSM303, has been renamed to
|
||||
LSM303DLH. No other functionality or behavior has been changed.
|
||||
|
||||
# v1.2.0
|
||||
|
||||
* **Note for all drivers ported to C** As a general note concerning
|
||||
all of the drivers that have been ported to C: **external constants
|
||||
have likely been renamed**. Previously in C++, most of these constants
|
||||
were defined as enums in the *upm::classname* namespace.
|
||||
|
||||
For drivers written in C, all of these constants are no longer in
|
||||
a class (or UPM) namespace, and instead have the driver name
|
||||
prefixed to the original value.
|
||||
|
||||
The driver name is prefixed to these constants to avoid name
|
||||
collisions when using multiple drivers in a given application, and
|
||||
to make it clear which constants belong to which driver.
|
||||
|
||||
For drivers that used *#define* for constants, only the prefix has
|
||||
been added if not already present. In some cases, names that were
|
||||
not very descriptive were changed, for example *ADDR* renamed to
|
||||
*BMPX8X_DEFAULT_I2C_ADDR*.
|
||||
|
||||
So for example, a constant that might once have been referred to
|
||||
in a C++ example as *upm::MMA7660::AUTOSLEEP_64*, would now be
|
||||
referenced as *MMA7660_AUTOSLEEP_64*.
|
||||
|
||||
This holds true for most, if not all drivers that have been ported
|
||||
to C. Not all of these changes are listed in this file due to the
|
||||
sheer number of them.
|
||||
|
||||
If you run into problems with constants that were working
|
||||
previously, and now cannot be found, this is likely the reason.
|
||||
Check the driver documentation and the source code to see what the
|
||||
new name is.
|
||||
|
||||
In C, constants are now usually implemented in a separate header
|
||||
file named *drivername_defs.h* or *drivername_regs.h*, for easier
|
||||
integration into the SWIG languages, and shared use between C++ and
|
||||
C implementations.
|
||||
|
||||
* **bmpx8x** This driver has been rewritten from scratch in C, with a
|
||||
C++ wrapper.
|
||||
|
||||
All exported symbols have been renamed for consistency and to
|
||||
avoid symbol collisions by having a *BMPX8X_* prefix. As an example,
|
||||
*ADDR* has been renamed to *BMPX8X_DEFAULT_I2C_ADDR*. Most C
|
||||
ported drivers follow this rule.
|
||||
|
||||
The *getPressureRaw()* and *getTemperatureRaw()* functions have
|
||||
been removed. This functionality was only needed internally to
|
||||
the driver.
|
||||
|
||||
The constructor no longer accepts a mode argument. Only the I2C
|
||||
bus and I2C address are accepted. By default, the device will be
|
||||
configured for it's maximum resolution *BMPX8X_OSS_ULTRAHIGHRES*,
|
||||
the previous default. You can use the new method
|
||||
*setOversampling()* to change the mode to something else if
|
||||
desired.
|
||||
|
||||
The methods related to calibration, like *computeB5()* are no
|
||||
longer exposed.
|
||||
|
||||
New methods, *init()* and *reset()* have been added. *reset()*
|
||||
resets the device to a freshly powered up state. *init()* can be
|
||||
used to re-initialize the device after a reset (reload calibration
|
||||
data) and set a default oversampling mode.
|
||||
|
||||
A new method, *update()* has been added. This method will update
|
||||
all internal state from the device, and **must** be called before
|
||||
querying the pressure, temperature, sea level and altitude values.
|
||||
|
||||
The *getSeaLevelPressure()* method has been split into two
|
||||
overloaded methods. One which **requires** an argument in meters
|
||||
(previously, a default was provided), and another which does not
|
||||
accept arguments at all and computes the sea level pressure based
|
||||
on current altitude.
|
||||
|
||||
The *i2cReadReg_16()*, *i2CWriteReg()* and *i2cReadReg_8()* have
|
||||
been replaced with *readReg()*, *readRegs()*, and *writeReg()*, in
|
||||
line with other I2C/SPI drivers of this type. They are marked
|
||||
protected (in C++) now as well. Please see the updated
|
||||
documentation and examples for this driver.
|
||||
|
||||
* **mma7660** This driver has been rewritten in C. Some exported
|
||||
symbols have been changed, for example, *MMA7660_I2C_BUS* was renamed
|
||||
to *MMA7660_DEFAULT_I2C_BUS*.
|
||||
|
||||
See updated documentation and examples for other changes.
|
||||
|
||||
* **bmx055, bmi055, bmc150, bma250e, bmg160, bmm150** This driver has
|
||||
been split up. The *bma250e*, *bmg160*, *bmm150* drivers have been
|
||||
rewritten in C (with C++ wrappers) and now reside in their own
|
||||
libraries. The versions of these drivers that used to be present in
|
||||
*bmx055* have been removed, and *bmx055* now uses the new libraries
|
||||
for it's functionality. The other two composite devices, *bmi055*,
|
||||
and *bmc150* are still contained within the *bmx055* library, and
|
||||
also use the new libraries for their functionality.
|
||||
|
||||
In addition, for all of these drivers some private methods are no
|
||||
longer exposed (such as the compensation routines).
|
||||
|
||||
The C++ driver methods that once returned pointers to a floating
|
||||
point array now return *std::vectors* of the appropriate type.
|
||||
The SWIG language examples for these drivers have been modified to
|
||||
use these methods instead of the C pointer based SWIG methods
|
||||
previously used.
|
||||
|
||||
* **sainsmartks** This driver has been renamed to *lcdks* (LCD Keypad
|
||||
Shield) and moved into it's own library. It uses the *lcm1602*
|
||||
library to do most of it's work. In addition, an additional argument
|
||||
was added to the constructor to optionally allow specifying a GPIO
|
||||
pin to be used to control the backlight. This driver supports the
|
||||
SainsmartKS and DFRobot LCD Keypad Shields. Similar devices from
|
||||
other manufacturers should also work with this driver.
|
||||
|
||||
* **lcm1602/jhd1313m1** These drivers had been rewritten in C, with
|
||||
C++ wrappers and placed into their own libraries in the previous
|
||||
version of UPM, however, the original C++ implementation was kept in
|
||||
the lcd/i2clcd library for compatibility reasons with existing code.
|
||||
To avoid collisions with the header files, the new *lcm1602* and
|
||||
*jhd1313m1* drivers had their C++ headers renamed to use a **.hxx**
|
||||
suffix.
|
||||
|
||||
In this version of UPM, the *lcm1602* and *jhd1313m1* drivers have
|
||||
been removed from the lcd/i2clcd library. In addition, the header
|
||||
files for the new implementation have been renamed from their
|
||||
**.hxx** suffix to the normal **.hpp** suffix.
|
||||
|
||||
A change was also made to the new *lcm1602* and *jhd1313m1* C++
|
||||
drivers. The *createChar()* function now accepts a byte vector
|
||||
*std::vector<uint8_t>* rather than the *char ** pointer that was
|
||||
used previously. This should make it easier to use with the SWIG
|
||||
language bindings (Python, JavaScript, and especially Java).
|
||||
|
||||
* **bmp280/bme280** Some private methods are no longer exposed (such
|
||||
as the calibration and compensation routines). In addition,
|
||||
the *getHumidity()* method no longer accepts an argument representing
|
||||
pressure at sea level. A separate method is provided to set this now.
|
||||
|
||||
* **bno055** This module no longer uses std::strings to pass around
|
||||
binary data (*read/writeCalibrationData()*). Rather, now *std::vectors* of
|
||||
the appropriate type are used. In addition, methods that previously
|
||||
returned certain data in the form of an array, like *getEulerAngles()*,
|
||||
now return a *std::vector* instead. This simplifies the Python,
|
||||
JavaScript, and Java bindings considerably, and leads to more
|
||||
"natural" looking Python/JavaScript/Java code. For JavaScript, Java,
|
||||
and Python, the examples have been modified to use these methods
|
||||
rather than the methods that return data in argument pointers or
|
||||
arrays.
|
||||
|
||||
* **lpd8806** The constructor for this driver was updated to allow specifying
|
||||
a SPI bus number. This is now the first parameter, the number of LEDs on the
|
||||
strip is now the last (3rd) parameter instead.
|
||||
|
||||
* **max31723** The constructor for this driver was updated to allow specifying
|
||||
a SPI bus number. This is now the first parameter, CS pin second.
|
||||
|
||||
* **tcs3414cs** The constructor for this can now accept an I2C bus and
|
||||
address.
|
||||
|
||||
# v1.1.0 and prior
|
||||
|
||||
* **i2clcd/jhd1313m1/lcm1602** LCD devices supported by the i2clcd module are
|
||||
being separated into individual libraries. The APIs will be preserved, but
|
||||
we recommend changing your code to use the new libraries as they become
|
||||
|
102
docs/building.md
102
docs/building.md
@ -64,10 +64,6 @@ Building with an older version of swig (swig 2.0+) requires the disabling of jav
|
||||
~~~~~~~~~~~~~
|
||||
-DBUILDSWIGNODE=OFF
|
||||
~~~~~~~~~~~~~
|
||||
Generating python3 modules instead of python2.7
|
||||
~~~~~~~~~~~~~
|
||||
-DBUILDPYTHON3=ON
|
||||
~~~~~~~~~~~~~
|
||||
Disabling python module building
|
||||
~~~~~~~~~~~~~
|
||||
-DBUILDSWIGPYTHON=OFF
|
||||
@ -130,3 +126,101 @@ autotools on linux.
|
||||
~~~~~~~~~~~
|
||||
pkg-config --cflags --libs upm-i2clcd
|
||||
~~~~~~~~~~~
|
||||
|
||||
## Building with Docker
|
||||
|
||||
You can use `docker` and `docker-compose` to generate a complete build environment
|
||||
for upm without having to install any other tool.
|
||||
|
||||
Requirements:
|
||||
* [docker](https://www.docker.com/get-docker) >= 1.12.6
|
||||
* [docker-compose](https://docs.docker.com/compose/install/) >= 1.9.0
|
||||
|
||||
**NOTE:** docker-compose is an optional requirement. It actually make running complex
|
||||
docker build and run command easier. But you can just use docker to build and run.
|
||||
|
||||
### Using Docker Images to build Upm
|
||||
|
||||
**tl;dr:** Just use this commands to build upm:
|
||||
|
||||
```sh
|
||||
# Build upm documentation
|
||||
$ docker-compose run doc
|
||||
# Build upm python2 and python3 packages and run python tests
|
||||
$ docker-compose run python
|
||||
# Build upm java package and run java tests
|
||||
$ docker-compose run java
|
||||
# Build upm node4 package and run node tests
|
||||
$ docker-compose run node4
|
||||
# Build upm node5 package and run node tests
|
||||
$ docker-compose run node5
|
||||
# Build upm node6 package and run node tests
|
||||
$ docker-compose run node6
|
||||
# Build upm for android things package
|
||||
$ docker-compose run android
|
||||
```
|
||||
|
||||
**docker-compose** will take a look at the `docker-compose.yaml` file in the repository
|
||||
root directory, and run an specific command to build upm for the requested target.
|
||||
Once the build is completed, you will have a `build/` folder in the repository root with all
|
||||
the compiled code. This `build/` folder is created by using a docker volume. The `build\`
|
||||
folder contents is reused each time you execute `docker-compose run [TARGET]`.
|
||||
To know more about volumes in Docker, visit the [Docker Volume Documentation](https://docs.docker.com/engine/tutorials/dockervolumes/).
|
||||
|
||||
You can also start an interactive session inside the docker container if you need to run some
|
||||
custom build commands:
|
||||
|
||||
```sh
|
||||
# Start an interactive bash shell inside the container
|
||||
$ docker-compose run python bash
|
||||
# From now, all the commands are executed inside the container
|
||||
$ cd build && cmake -DBUILDSWIGPYTHON=ON .. && make clean all
|
||||
```
|
||||
|
||||
If you don't want to use docker-compose, you can also use `docker run` to build upm.
|
||||
For example, to build upm for python, you can do:
|
||||
|
||||
```sh
|
||||
# From the repository root folder
|
||||
$ docker run \
|
||||
--volume=$(pwd):/usr/src/app \
|
||||
--env BUILDSWIGPYTHON=ON \
|
||||
--env BUILDSWIGJAVA=OFF \
|
||||
--env BUILDSWIGNODE=OFF \
|
||||
dnoliver/upm-python \
|
||||
bash -c "./scripts/run-cmake.sh && make -Cbuild"
|
||||
```
|
||||
|
||||
### Proxy considerations
|
||||
|
||||
If, for some reason, you are behind a proxy, find below a list of common problems related
|
||||
to proxy settings:
|
||||
|
||||
**docker cannot pull images from docker.io**
|
||||
|
||||
Visit [this link](https://docs.docker.com/engine/admin/systemd/#httphttps-proxy)
|
||||
to configure docker daemon behind a proxy.
|
||||
|
||||
**docker run fails to access the internet**
|
||||
|
||||
docker-compose will automatically take `http_proxy`, `https_proxy`, and `no_proxy`
|
||||
environment variables and use it as build arguments. Be sure to properly configure
|
||||
this variables before building.
|
||||
|
||||
docker, unlinke docker-compose, do not take the proxy settings from the environment
|
||||
automatically. You need to send them as environment arguments:
|
||||
|
||||
```sh
|
||||
# From the repository root folder
|
||||
$ docker run \
|
||||
--volume=$(pwd):/usr/src/app \
|
||||
--env BUILDSWIG=ON \
|
||||
--env BUILDSWIGPYTHON=ON \
|
||||
--env BUILDSWIGJAVA=OFF \
|
||||
--env BUILDSWIGNODE=OFF \
|
||||
--env http_proxy=$http_proxy \
|
||||
--env https_proxy=$https_proxy \
|
||||
--env no_proxy=$no_proxy \
|
||||
dnoliver/upm-python \
|
||||
bash -c "./scripts/run-cmake.sh && make -Cbuild"
|
||||
```
|
||||
|
@ -4,6 +4,31 @@ Changelog {#changelog}
|
||||
Here's a list summarizing some of the key undergoing changes to our library
|
||||
from earlier versions:
|
||||
|
||||
### v1.3.0
|
||||
|
||||
* Finalized all required build system and JAVA binding changes to release the
|
||||
UPM libraries for Android Things targets
|
||||
* Enhanced the modules for lsm303 and tmp006 to support newer variants of the
|
||||
chips
|
||||
* Fixed Node.js detection on Ubuntu when installed with apt using official
|
||||
packages
|
||||
* Minor documentation changes
|
||||
* New sensors: lsm303agr, lsm303d, veml6070, tca9548a, rn2903
|
||||
|
||||
### v1.2.0
|
||||
|
||||
* Improved JAVA binding compiler compatibility and added JAVA interfaces that
|
||||
match existing C++ interfaces
|
||||
* Ported Bosch drivers to C thus now they can be used on supported MCUs
|
||||
* Completely redesigned C/C++ example handling by cmake to avoid maintaining
|
||||
a list by hand
|
||||
* Fixed several existing drivers, mostly based on static code analysis reports
|
||||
* Added a sensor driver template plus bash script that can be easily used by
|
||||
developers to start writing their own sensor driver
|
||||
* Numerous documentation improvements
|
||||
* New sensors: p9813, abp, rsc, mmc35240, tcs37727, tmp006, mma8x6x, mag3110,
|
||||
hdc1000
|
||||
|
||||
### v1.1.0
|
||||
|
||||
* Reworked cmake handling of internal and external dependencies
|
||||
|
@ -94,3 +94,56 @@ then you just add a line to each of your commits with `--signoff` saying
|
||||
|
||||
using your real name (sorry, no pseudonyms or anonymous contributions.)
|
||||
Unsigned commits will not be accepted.
|
||||
|
||||
|
||||
Creating a new sensor library using the sensortemplate
|
||||
=======================================
|
||||
|
||||
A stubbed-out sensor library is available which can be leveraged to get
|
||||
up-and-running quickly when writing a new sensor library. Use the shell
|
||||
commands below to generate collateral files for your new sensor library.
|
||||
|
||||
|
||||
```shell
|
||||
#!/bin/bash
|
||||
|
||||
function make_new_sensor {
|
||||
export SensorName=$1
|
||||
# Get a lowercase version of the string
|
||||
export sensorname=${SensorName,,}
|
||||
|
||||
# Make sure this is run from the root UPM directory
|
||||
if ! grep -q 'UPM ' README.md; then echo "Please run from the root UPM directory"; return -1; fi
|
||||
|
||||
printf "Generating new sensor: ${SensorName}\n"
|
||||
# Copy sensortemplate files to ${sensorname}
|
||||
find docs/ examples/ src/ -name '*sensortemplate*' -exec bash -c 'cp -r $0 ${0/sensortemplate/${sensorname}}' {} \;
|
||||
# Copy SensorTemplate files to ${SensorName}
|
||||
find examples/ src/ -name '*SensorTemplate*' -exec bash -c 'cp -r $0 ${0/SensorTemplate/${SensorName}}' {} \;
|
||||
# Rename sernsortemplate src files
|
||||
rename "s/sensortemplate/${sensorname}/" src/${sensorname}/*
|
||||
# Search/replace the new files, replacing all instances of sensortemplate
|
||||
perl -p -i -e "s/SensorTemplate/${SensorName}/g" src/${sensorname}/* examples/*/*${sensorname}* examples/*/*${SensorName}*
|
||||
perl -p -i -e "s/sensortemplate/${sensorname}/g" src/${sensorname}/* examples/*/*${sensorname}* examples/*/*${SensorName}*
|
||||
# Add mynewmodule example target for java
|
||||
perl -p -i -e "s/^((.*)SensorTemplateSample sensortemplate(.*))/\1\n\2${SensorName}Sample ${sensorname}\3/g" examples/java/CMakeLists.txt
|
||||
# Add mynewmodule example mappings for doxygen
|
||||
perl -p -i -e "s/^(.*SensorTemplateSample.*)$/\1\n${sensorname}.cxx\t${SensorName}Sample.java\t${sensorname}.js\t${sensorname}.py/g" doxy/samples.mapping.txt
|
||||
# Display TODO's
|
||||
printf "Generation complete for sensor library: ${SensorName}\n"
|
||||
printf "TODO's:\n"
|
||||
printf "\t1. Update src/hdr files: src/${sensorname}/${sensorname}.hpp src/${sensorname}/${sensorname}.cxx\n"
|
||||
printf "\t\tChange the Author\n"
|
||||
printf "\t\tChange the Copyright\n"
|
||||
printf "\t\tUpdate all doxygen tags (follow directions for @tags)\n"
|
||||
printf "\t2. Update examples: examples/*/${sensorname}.* examples/java/*${SensorName}*.java\n"
|
||||
printf "\t3. Overwrite docs/images/${sensorname}.png with a valid image of your sensor\n"
|
||||
}
|
||||
|
||||
# Call make_new_sensor with your new sensor name, example: 'MyNewSensor1234'
|
||||
make_new_sensor MyNewSensor1234
|
||||
```
|
||||
|
||||
Once all files have been created, they can be used as a starting-point for your
|
||||
new library. They will need additional customization (your name/email address,
|
||||
documentation, sensor images, etc).
|
||||
|
BIN
docs/images/lidarlitev3.jpg
Normal file
BIN
docs/images/lidarlitev3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 156 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
BIN
docs/images/p9813.jpg
Normal file
BIN
docs/images/p9813.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
BIN
docs/images/sensortemplate.png
Normal file
BIN
docs/images/sensortemplate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
BIN
docs/images/tca9548a.jpg
Normal file
BIN
docs/images/tca9548a.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 616 KiB |
@ -7,6 +7,9 @@ such sensors and known workarounds if they exist.
|
||||
|
||||
#### Grove Sensors
|
||||
|
||||
* **RN2903** Click 2 version. This device will not work using the
|
||||
Edison UART on the Arduino breakout. It does work on Edison using a
|
||||
USB->serial interface.
|
||||
* **Grove LCD RGB Backlit** (JHD1313M1) requires 5V and should be used with an
|
||||
external power supply connected to the board to function properly. Although
|
||||
some high powered USB ports might be enough, in most cases you will encounter
|
||||
@ -50,11 +53,11 @@ such sensors and known workarounds if they exist.
|
||||
* **Grove BLE** (HM-11) does not return data on the Intel Galileo board due to
|
||||
known UART limitation.
|
||||
* **Grove Hall Sensor** (A11X) if the base shield is set to 3V on Intel Edison,
|
||||
it will trigger continous callbacks when the sensor is not reading anything.
|
||||
it will trigger continuous callbacks when the sensor is not reading anything.
|
||||
* **Grove RTC** (DS1307) is not compatible with the Intel Edison Arduino board
|
||||
but will work with the Mini-breakout.
|
||||
* **Grove Tempture & Humidity (High-Accuracy & Mini) Sensor** (TH02) only works
|
||||
with the Intel Edison Arduino board when powered from the 3.3V rail.
|
||||
* **Grove Temperature & Humidity (High-Accuracy & Mini) Sensor** (TH02) only
|
||||
works with the Intel Edison Arduino board when powered from the 3.3V rail.
|
||||
|
||||
#### Adafruit Sensors
|
||||
|
||||
@ -75,6 +78,8 @@ This affects the **DS18B20**, **DS2413** and **DFREC** drivers.
|
||||
|
||||
#### Other Sensors
|
||||
|
||||
* **HTU21D** is unstable on the Intel Edison with the Arduino breakout and
|
||||
will throw an error when it can't complete an update call.
|
||||
* **MLX90614** is not compatible with the Intel Galileo due to the inability
|
||||
to change the I2C bus speed to 100 KHz.
|
||||
* **MICSV89** is not compatible with the Intel Galileo due to the inability to
|
||||
@ -89,10 +94,9 @@ This affects the **DS18B20**, **DS2413** and **DFREC** drivers.
|
||||
|
||||
Some *I2C* sensors add too much capacitance to the SDA line of the Intel Edison
|
||||
Arduino breakout board, thus the signal sticks to a logic 1. When this happens,
|
||||
other sensors connected to the I2C bus are unusable. While there is no generic
|
||||
solution for this limitation, in most cases the sensor works on the Intel
|
||||
Edison Mini-breakout. When this board is not an option, the sensor can be
|
||||
sometimes replaced with the same model from a different vendor.
|
||||
other sensors connected to the I2C bus also become unusable. In order to solve
|
||||
this problem, an I2C repeater that isolates the capacitance on the bus, such as
|
||||
the PCA9517 can be used.
|
||||
|
||||
The Intel Edison *SPI* bus can corrupt data being sent across when certain
|
||||
sensors are connected to it, if using an old image. This has been resolved with
|
||||
|
@ -129,8 +129,6 @@ ABBREVIATE_BRIEF = "The $name class" \
|
||||
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
|
||||
DETAILS_AT_TOP = YES
|
||||
|
||||
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
|
||||
# inherited members of a class in the documentation of that class as if those
|
||||
# members were ordinary class members. Constructors, destructors and assignment
|
||||
@ -156,7 +154,7 @@ FULL_PATH_NAMES = YES
|
||||
# will be relative from the directory where doxygen is started.
|
||||
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
||||
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@
|
||||
|
||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
||||
# path mentioned in the documentation of a class, which tells the reader which
|
||||
@ -1861,18 +1859,6 @@ GENERATE_XML = YES
|
||||
|
||||
XML_OUTPUT = xml
|
||||
|
||||
# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_SCHEMA =
|
||||
|
||||
# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_DTD =
|
||||
|
||||
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
|
||||
# listings (including syntax highlighting and cross-referencing information) to
|
||||
# the XML output. Note that enabling this will significantly increase the size
|
||||
|
@ -129,8 +129,6 @@ ABBREVIATE_BRIEF = "The $name class" \
|
||||
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
|
||||
DETAILS_AT_TOP = YES
|
||||
|
||||
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
|
||||
# inherited members of a class in the documentation of that class as if those
|
||||
# members were ordinary class members. Constructors, destructors and assignment
|
||||
@ -1818,18 +1816,6 @@ GENERATE_XML = YES
|
||||
|
||||
XML_OUTPUT = xml
|
||||
|
||||
# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_SCHEMA =
|
||||
|
||||
# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_DTD =
|
||||
|
||||
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
|
||||
# listings (including syntax highlighting and cross-referencing information) to
|
||||
# the XML output. Note that enabling this will significantly increase the size
|
||||
|
@ -15,7 +15,7 @@ sensor in order to reduce load when doing multiple reads to sensor data.
|
||||
### Example
|
||||
|
||||
A sensor/actuator is expected to work as such (here is the servo ES08A API):
|
||||
@snippet es08a.cxx Interesting
|
||||
@snippet servo-es08a.cxx Interesting
|
||||
|
||||
However implementation and API design is completely up to the developer, some
|
||||
enumerable sensors for example may provide much clever instantiation. Displays
|
||||
|
1
doxy/doxygen2jsdoc
Submodule
1
doxy/doxygen2jsdoc
Submodule
Submodule doxy/doxygen2jsdoc added at 67cad69272
1
doxy/doxyport
Submodule
1
doxy/doxyport
Submodule
Submodule doxy/doxyport added at db3e1a6eb8
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var xml2js = require('./xml2js')
|
||||
, fs = require('fs')
|
||||
, Promise = require('bluebird')
|
||||
, opts = require('commander')
|
||||
, _ = require('lodash')
|
||||
, mkdirp = require('mkdirp');
|
||||
|
||||
|
||||
// parse command line arguments
|
||||
_.extend(opts, { addOptions: function(module) { return module.addOptions(opts); } });
|
||||
opts
|
||||
.option('-m, --module [module]', 'module name for which to build documentation', 'mraa')
|
||||
.option('-f, --formats [formats]', 'format for js comments', 'yuidoc,ternjs')
|
||||
.option('-o, --outdir [directory]', 'top directory to build documentation', __dirname + '/jsdoc')
|
||||
.addOptions(xml2js)
|
||||
.parse(process.argv);
|
||||
|
||||
|
||||
// use promise-style programming rather than spaghetti callbacks
|
||||
Promise.promisifyAll(fs);
|
||||
Promise.promisifyAll(mkdirp);
|
||||
|
||||
|
||||
// main
|
||||
xml2js.parse().then(function(specjs) {
|
||||
var formats = opts.formats.split(',');
|
||||
Promise.all(_.map(formats, function(format) {
|
||||
var generateDocs = require(__dirname + '/generators/' + format + '/generator');
|
||||
var dir = opts.outdir + '/' + format + '/' + specjs.MODULE;
|
||||
return mkdirp.mkdirpAsync(dir).then(function() {
|
||||
return fs.writeFileAsync(dir + '/doc.js', generateDocs(specjs));
|
||||
});
|
||||
}));
|
||||
});
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"templates": {
|
||||
"default": {
|
||||
"outputSourceFiles": false
|
||||
}
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var _ = require('lodash');
|
||||
|
||||
|
||||
// generate JSDoc-style documentation
|
||||
function generateDocs(specjs) {
|
||||
var docs = GENERATE_MODULE(specjs.MODULE);
|
||||
docs = _.reduce(specjs.METHODS, function(memo, methodSpec, methodName) {
|
||||
return memo += GENERATE_METHOD(methodName, methodSpec);
|
||||
}, docs);
|
||||
docs = _.reduce(specjs.ENUMS, function(memo, enumSpec, enumName) {
|
||||
return memo += GENERATE_ENUM(enumName, enumSpec);
|
||||
}, docs);
|
||||
docs = _.reduce(specjs.CLASSES, function(memo, classSpec, parentClass) {
|
||||
return _.reduce(classSpec.methods, function(memo, methodSpec, methodName) {
|
||||
return memo += GENERATE_METHOD(methodName, methodSpec, parentClass);
|
||||
}, memo);
|
||||
}, docs);
|
||||
return docs;
|
||||
}
|
||||
|
||||
|
||||
// comment wrapper around entire spec
|
||||
function GENERATE_DOC(text) {
|
||||
return '/**\n' + text + ' */\n';
|
||||
}
|
||||
|
||||
|
||||
// generate module spec
|
||||
function GENERATE_MODULE(module) {
|
||||
return GENERATE_DOC('@module ' + module + '\n');
|
||||
}
|
||||
|
||||
|
||||
// generate method spec with parent module/class
|
||||
function GENERATE_METHOD(name, spec, parent) {
|
||||
name = name.replace(/!+$/, '');
|
||||
return GENERATE_DOC(spec.description + '\n'
|
||||
+ '@method ' + name + '\n'
|
||||
+ '@instance\n'
|
||||
+ (parent ? ('@memberof ' + parent + '\n') : '')
|
||||
+ _.reduce(spec.params, function(memo, paramSpec, paramName) {
|
||||
return '@param {' + paramSpec.type + '} ' + paramName + ' ' + paramSpec.description + '\n';
|
||||
}, '')
|
||||
+ ( !_.isEmpty(spec.return) ? ('@return {' + spec.return.type + '} ' + spec.return.description + '\n') : ''));
|
||||
}
|
||||
|
||||
|
||||
// generate enum spec
|
||||
function GENERATE_ENUM(name, spec) {
|
||||
return GENERATE_DOC(spec.description + '\n\n'
|
||||
+ '@var ' + name + '\n'
|
||||
+ '@type Enum(' + spec.type + ')\n'
|
||||
+ '@instance\n');
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
// generate link spec
|
||||
function GENERATE_LINK(text) {
|
||||
return '{@link ' + text + '}';
|
||||
}
|
||||
|
||||
|
||||
module.exports = generateDocs;
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var _ = require('lodash');
|
||||
|
||||
|
||||
// generate json for ternjs input
|
||||
function generateDocs(specjs) {
|
||||
GENERATE_TYPE = (function(enums) {
|
||||
return function(type) {
|
||||
return (_.contains(enums, type) ? ('Enum ' + type) : type);
|
||||
}
|
||||
})(_.keys(specjs.ENUMS_BY_GROUP));
|
||||
var docs = { '!name': specjs.MODULE + 'library' };
|
||||
_.extend(docs, GENERATE_MODULE(specjs.MODULE));
|
||||
_.each(specjs.ENUMS, function(enumSpec, enumName) {
|
||||
_.extend(docs[specjs.MODULE], GENERATE_ENUM(enumName, enumSpec));
|
||||
});
|
||||
_.each(specjs.METHODS, function(methodSpec, methodName) {
|
||||
_.extend(docs[specjs.MODULE], GENERATE_METHOD(methodName, methodSpec));
|
||||
});
|
||||
|
||||
if (_.isEmpty(specjs.CLASSGROUPS)) {
|
||||
_.extend(docs[specjs.MODULE], GENERATE_CLASSES(specjs.CLASSES));
|
||||
} else {
|
||||
var grouped = _.flatten(_.pluck(_.values(specjs.CLASSGROUPS), 'classes'));
|
||||
var ungrouped = _.difference(_.keys(specjs.CLASSES), grouped);
|
||||
_.extend(docs[specjs.MODULE], GENERATE_CLASSES(_.pick(specjs.CLASSES, ungrouped)));
|
||||
_.each(specjs.CLASSGROUPS, function(groupSpec, groupName) {
|
||||
_.extend(docs, GENERATE_MODULE(groupName));
|
||||
_.extend(docs[groupName], GENERATE_CLASSES(_.pick(specjs.CLASSES, groupSpec.classes), groupName));
|
||||
});
|
||||
}
|
||||
return JSON.stringify(docs, null, 2);
|
||||
}
|
||||
|
||||
|
||||
// generate module spec
|
||||
function GENERATE_MODULE(module) {
|
||||
var docs = {};
|
||||
docs[module] = {};
|
||||
return docs;
|
||||
}
|
||||
|
||||
|
||||
// generate the spec for the given list of classes
|
||||
function GENERATE_CLASSES(classes) {
|
||||
var docs = {};
|
||||
_.each(classes, function(classSpec, parentClass) {
|
||||
var constructor = classSpec.methods[parentClass];
|
||||
_.extend(docs, GENERATE_METHOD(parentClass, constructor ? constructor : { params: {}, return: {}, description: '' } ));
|
||||
if (_.has(docs, parentClass)) {
|
||||
_.each(classSpec.enums, function(enumSpec, enumName) {
|
||||
_.extend(docs[parentClass], GENERATE_ENUM(enumName, enumSpec));
|
||||
});
|
||||
docs[parentClass].prototype = {};
|
||||
_.each(_.omit(classSpec.methods, parentClass), function(methodSpec, methodName) {
|
||||
_.extend(docs[parentClass].prototype, GENERATE_METHOD(methodName, methodSpec));
|
||||
});
|
||||
_.each(classSpec.variables, function(variableSpec, variableName) {
|
||||
_.extend(docs[parentClass].prototype, GENERATE_VARIABLE(variableName, variableSpec));
|
||||
});
|
||||
}
|
||||
});
|
||||
return docs;
|
||||
}
|
||||
|
||||
|
||||
// generate method spec
|
||||
function GENERATE_METHOD(name, spec) {
|
||||
var doc = {};
|
||||
doc[name] = {
|
||||
'!type': 'fn(' + GENERATE_PARAMS(spec.params) + ')' + GENERATE_RETURN(spec.return),
|
||||
'!doc': spec.description
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
// generate parameter signatures for method
|
||||
function GENERATE_PARAMS(spec) {
|
||||
return _.map(spec, function(paramSpec, paramName) {
|
||||
return paramName + ': ' + paramSpec.type;
|
||||
}).join(', ');
|
||||
}
|
||||
|
||||
|
||||
// generate return signature for method
|
||||
function GENERATE_RETURN(spec) {
|
||||
return (_.isEmpty(spec) ? '' : (' -> ' + spec.type));
|
||||
}
|
||||
|
||||
|
||||
// generate enum spec
|
||||
function GENERATE_ENUM(name, spec) {
|
||||
var doc = {};
|
||||
doc[name] = 'Enum ' + spec.type ;
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
// generate variable spec
|
||||
function GENERATE_VARIABLE(name, spec) {
|
||||
var doc = {};
|
||||
doc[name]= spec.type ;
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
module.exports = generateDocs;
|
144
doxy/node/generators/yuidoc/generator.js
vendored
144
doxy/node/generators/yuidoc/generator.js
vendored
@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var _ = require('lodash');
|
||||
|
||||
|
||||
// generate YuiDocs-style documentation
|
||||
function generateDocs(specjs) {
|
||||
var docs = GENERATE_MODULE(specjs.MODULE, '');
|
||||
GENERATE_TYPE = (function(enums) {
|
||||
return function(type) {
|
||||
return (_.contains(enums, type) ? ('Enum ' + type) : type);
|
||||
}
|
||||
})(_.keys(specjs.ENUMS_BY_GROUP));
|
||||
docs = _.reduce(specjs.METHODS, function(memo, methodSpec, methodName) {
|
||||
return memo += GENERATE_METHOD(methodName, methodSpec);
|
||||
}, docs);
|
||||
docs = _.reduce(specjs.ENUMS, function(memo, enumSpec, enumName) {
|
||||
return memo += GENERATE_ENUM(enumName, enumSpec);
|
||||
}, docs);
|
||||
if (_.isEmpty(specjs.CLASSGROUPS)) {
|
||||
docs += GENERATE_CLASSES(specjs.CLASSES);
|
||||
} else {
|
||||
docs += GENERATE_MODULE('common', '');
|
||||
var grouped = _.flatten(_.pluck(_.values(specjs.CLASSGROUPS), 'classes'));
|
||||
var ungrouped = _.difference(_.keys(specjs.CLASSES), grouped);
|
||||
docs += GENERATE_CLASSES(_.pick(specjs.CLASSES, ungrouped), 'common');
|
||||
_.each(specjs.CLASSGROUPS, function(groupSpec, groupName) {
|
||||
docs += GENERATE_CLASSES(_.pick(specjs.CLASSES, groupSpec.classes), groupName);
|
||||
});
|
||||
// TODO: figure out why yuidoc won't associate the class with the right module if module definitions are interspersed
|
||||
_.each(specjs.CLASSGROUPS, function(groupSpec, groupName) {
|
||||
docs += GENERATE_MODULE(groupName, groupSpec.description);
|
||||
});
|
||||
}
|
||||
return docs;
|
||||
}
|
||||
|
||||
|
||||
// comment wrapper around entire spec
|
||||
function GENERATE_DOC(text) {
|
||||
return '/**\n' + text + ' */\n';
|
||||
}
|
||||
|
||||
|
||||
// generate module spec
|
||||
function GENERATE_MODULE(name, description) {
|
||||
return GENERATE_DOC(description + '\n'
|
||||
+ '@module ' + name + '\n');
|
||||
}
|
||||
|
||||
|
||||
// generate spec for the given list of classes
|
||||
function GENERATE_CLASSES(classes, parent) {
|
||||
return _.reduce(classes, function(memo, classSpec, className) {
|
||||
return memo
|
||||
+ GENERATE_CLASS(className, classSpec.description, parent, classSpec.parent)
|
||||
+ _.reduce(classSpec.methods, function(memo, methodSpec, methodName) {
|
||||
return memo += GENERATE_METHOD(methodName, methodSpec, className);
|
||||
}, '')
|
||||
+ _.reduce(classSpec.variables, function(memo, variableSpec, variableName) {
|
||||
return memo += GENERATE_VAR(variableName, variableSpec, className);
|
||||
}, '')
|
||||
+ _.reduce(classSpec.enums, function(memo, enumSpec, enumName) {
|
||||
return memo += GENERATE_ENUM(enumName, enumSpec, className);
|
||||
}, '');
|
||||
}, '');
|
||||
}
|
||||
|
||||
|
||||
// generate class spec
|
||||
function GENERATE_CLASS(name, description, namespace, parent) {
|
||||
return GENERATE_DOC(description + '\n'
|
||||
+ '@class ' + name + '\n'
|
||||
+ (namespace ? ('@module ' + namespace + '\n') : '')
|
||||
/*
|
||||
TODO: leave out until figure out what swig does with inheritance
|
||||
+ (parent ? ('@extends ' + parent + '\n') : '')
|
||||
*/
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// generate method spec with parent module/class
|
||||
function GENERATE_METHOD(name, spec, parent) {
|
||||
name = name.replace(/!+$/, '');
|
||||
return GENERATE_DOC(spec.description + '\n'
|
||||
+ '@method ' + name + '\n'
|
||||
+ (parent ? ('@for ' + parent + '\n') : '@for common\n')
|
||||
+ _.reduce(spec.params, function(memo, paramSpec, paramName) {
|
||||
return memo + '@param {' + GENERATE_TYPE(paramSpec.type) + '} ' + paramName + ' ' + paramSpec.description + '\n';
|
||||
}, '')
|
||||
+ ( !_.isEmpty(spec.return) ? ('@return {' + GENERATE_TYPE(spec.return.type) + '} ' + spec.return.description + '\n') : ''));
|
||||
}
|
||||
|
||||
|
||||
// generate enum spec
|
||||
function GENERATE_ENUM(name, spec, parent) {
|
||||
return GENERATE_DOC(spec.description + '\n'
|
||||
+ '@property ' + name + '\n'
|
||||
+ '@type Enum ' + spec.type + '\n'
|
||||
+ '@for ' + (parent ? parent : 'common') + '\n');
|
||||
}
|
||||
|
||||
|
||||
// generate variable specs
|
||||
function GENERATE_VAR(name, spec, parent) {
|
||||
return GENERATE_DOC(spec.description + '\n'
|
||||
+ '@property ' + name + '\n'
|
||||
+ '@type ' + spec.type + '\n'
|
||||
+ '@for ' + parent + '\n');
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
// generate link spec
|
||||
function GENERATE_LINK(text) {
|
||||
return '{{#crossLink "' + text + '"}}{{/crossLink}}';
|
||||
}
|
||||
|
||||
|
||||
module.exports = generateDocs;
|
@ -1,45 +0,0 @@
|
||||
document
|
||||
= _ ignore* _ "<doxygen " _ attr:attr* _ ">" body:elements _ "</doxygen>" _ { return body; }
|
||||
|
||||
|
||||
elements
|
||||
= element*
|
||||
|
||||
element
|
||||
= _ "<" startTag:id _ attr:attr* _ ">" _ children:elements _ "</" endTag:id ">" _ {
|
||||
if (startTag != endTag) {
|
||||
throw new Error("Expected </" + startTag + "> but </" + endTag + "> found.");
|
||||
}
|
||||
return {name: startTag, attr: attr, children: children }
|
||||
}
|
||||
/ "<" tag:id _ attr:attr* _ "/>" _ {
|
||||
return {name: tag, attr: attr }
|
||||
}
|
||||
/ _ text:text _ { return text }
|
||||
|
||||
ignore
|
||||
= "<?xml" _ attr* _ "?>" { return }
|
||||
|
||||
attr
|
||||
= name:id _ "=" _ value:string { return { name:name, value:value } }
|
||||
|
||||
string
|
||||
= '"' '"' _ { return ""; }
|
||||
/ "'" "'" _ { return ""; }
|
||||
/ '"' text:quoted '"' _ { return text; }
|
||||
/ "'" text:quoted "'" _ { return text; }
|
||||
|
||||
quoted
|
||||
= chars:[^<>'" \t\n\r]+ { return chars.join(""); }
|
||||
|
||||
text
|
||||
= chars:[^<> \t\n\r]+ { return chars.join(""); }
|
||||
|
||||
id
|
||||
= chars:[^<>/'"=? \t\n\r]+ { return chars.join(""); }
|
||||
|
||||
_ "whitespace"
|
||||
= whitespace*
|
||||
|
||||
whitespace
|
||||
= [ \t\n\r]
|
@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Author: Dina M Suehiro <dina.m.suehiro@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var opts = require('commander'), // for command line args
|
||||
fs = require('fs'), // for file system access
|
||||
path = require('path'); // for file path parsing
|
||||
|
||||
// parse command line arguments
|
||||
opts
|
||||
.option('-i, --inputdir [directory]', 'product documents directory', __dirname + '/docs/yuidoc/upm')
|
||||
.parse(process.argv);
|
||||
|
||||
// Set to true for console output
|
||||
var debug = true;
|
||||
|
||||
// Global arrays tracking the files that have been renamed
|
||||
var originalFiles = [];
|
||||
var renamedFiles = [];
|
||||
|
||||
// Filter to get html files from different directories
|
||||
var rootFiles = getHtmlFilenames(opts.inputdir);
|
||||
var classesFiles = getHtmlFilenames(opts.inputdir + "/classes");
|
||||
var modulesFiles = getHtmlFilenames(opts.inputdir + "/modules");
|
||||
|
||||
// Rename files in the classes directory to have lower-cased file names.
|
||||
renameFiles(classesFiles);
|
||||
|
||||
classesFiles = getHtmlFilenames(opts.inputdir + "/classes");
|
||||
|
||||
// Go through the html files and update links to reflect the file names that we changed.
|
||||
renameLinks(rootFiles);
|
||||
renameLinks(classesFiles);
|
||||
renameLinks(modulesFiles);
|
||||
|
||||
// Helper function that returns paths to the html files in the specified directory
|
||||
function getHtmlFilenames (directory)
|
||||
{
|
||||
return fs.readdirSync(directory).map(function (file) {
|
||||
return path.join(directory, file);
|
||||
}).filter(function (file) {
|
||||
return fs.statSync(file).isFile();
|
||||
}).filter(function (file) {
|
||||
return path.extname(file).toLowerCase() == ".html";
|
||||
});
|
||||
}
|
||||
|
||||
// Goes through the files and renames them to be lower-cased and tracks them the
|
||||
// renamed files in the originalFiles[] and renamedFiles[] arrays.
|
||||
function renameFiles(files)
|
||||
{
|
||||
files.forEach(function (file)
|
||||
{
|
||||
var originalName = path.basename(file);
|
||||
var newFileName = originalName.toLowerCase();
|
||||
var directory = path.dirname(file);
|
||||
if (originalName != newFileName)
|
||||
{
|
||||
fs.renameSync(file, directory + "/" + newFileName); //, function(err)
|
||||
|
||||
if (debug)
|
||||
console.log('Renamed: %s --> %s', originalName, newFileName);
|
||||
|
||||
originalFiles.push(originalName);
|
||||
renamedFiles.push(newFileName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Helper function goes through the specified files and does a file/replace of the
|
||||
// originalFiles to the renamedFiles so that the .html links match what has been renamed.
|
||||
function renameLinks (files)
|
||||
{
|
||||
if (originalFiles.length <= 0)
|
||||
{
|
||||
if (debug)
|
||||
console.log("No links to rename.");
|
||||
return;
|
||||
}
|
||||
|
||||
files.forEach(function (file)
|
||||
{
|
||||
// Read the file
|
||||
data = fs.readFileSync(file, 'ascii');
|
||||
|
||||
// Find/replace the file names that were renamed
|
||||
for (var i = 0; i < originalFiles.length; i++)
|
||||
{
|
||||
var findString = '/' + originalFiles[i] + '\"';
|
||||
var replaceString = '/' + renamedFiles[i] + '\"';
|
||||
|
||||
data = data.replace(findString, replaceString);
|
||||
}
|
||||
|
||||
// Write back
|
||||
fs.writeFile(file, data, 'ascii', function (err) {
|
||||
if (err)
|
||||
throw err;
|
||||
});
|
||||
|
||||
if (debug)
|
||||
console.log('Renamed links in: %s', file);
|
||||
});
|
||||
}
|
@ -1,935 +0,0 @@
|
||||
/*
|
||||
* Author: Heidi Pan <heidi.pan@intel.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// dependencies
|
||||
var peg = require('pegjs')
|
||||
, fs = require('fs')
|
||||
, path = require('path')
|
||||
, Promise = require('bluebird')
|
||||
, _ = require('lodash')
|
||||
, util = require('util');
|
||||
|
||||
|
||||
// use promise-style programming rather than spaghetti callbacks
|
||||
Promise.promisifyAll(fs);
|
||||
|
||||
|
||||
var xml2js = {
|
||||
|
||||
// js-format specs
|
||||
// MODULE: <module name>
|
||||
// ENUMS: {
|
||||
// <enum name>: {
|
||||
// type: <enum type>,
|
||||
// description: <enum description>
|
||||
// }, ...
|
||||
// }
|
||||
// ENUMS_BY_GROUP: {
|
||||
// <enum type>: {
|
||||
// description: <enum group description>
|
||||
// members: [ <enum name>, ... ]
|
||||
// }, ...
|
||||
// }
|
||||
// METHODS: {
|
||||
// <method name>: {
|
||||
// description: <method description>,
|
||||
// params: {
|
||||
// <param name>: {
|
||||
// type: <param type>,
|
||||
// description: <param description >
|
||||
// }, ...
|
||||
// },
|
||||
// return: {
|
||||
// type: <return type>,
|
||||
// description: <return description>
|
||||
// }
|
||||
// }, ...
|
||||
// }
|
||||
// CLASSES: {
|
||||
// <class name>: {
|
||||
// description: <class description>,
|
||||
// parent: <parent class name>,
|
||||
// group: <group name>,
|
||||
// methods: { ... },
|
||||
// variables: {
|
||||
// <variable name>: {
|
||||
// type: <variable type>,
|
||||
// description: <variable description>
|
||||
// }
|
||||
// },
|
||||
// enums: { ... },
|
||||
// enums_by_group: { ... }
|
||||
// }, ...
|
||||
// }
|
||||
// CLASSGROUPS: {
|
||||
// <group name>: {
|
||||
// description: <group description>,
|
||||
// classes: [ <class name>, ... ],
|
||||
// enums: { ... },
|
||||
// enums_by_group: { ... }
|
||||
// }, ...
|
||||
// }
|
||||
MODULE: '',
|
||||
ENUMS: {},
|
||||
ENUMS_BY_GROUP: {},
|
||||
METHODS: {},
|
||||
CLASSES: {},
|
||||
CLASSGROUPS: {},
|
||||
|
||||
|
||||
// baseline c -> js type mapping
|
||||
TYPEMAPS: {
|
||||
'^(const)?\\s*(unsigned|signed)?\\s*(int|short|long|float|double|size_t|u?int\\d{1,2}_t)?$': 'Number',
|
||||
'^bool$': 'Boolean',
|
||||
'^(const)?\\s*(unsigned|signed)?\\s*(char|char\\s*\\*|std::string)$': 'String', // TODO: verify that swig does this mapping
|
||||
'^void\\s*\\(\\s*\\*\\s*\\)\\s*\\(\\s*void\\s*\\*\\)\\s*$': 'Function'
|
||||
},
|
||||
|
||||
|
||||
// custom c -> js type mapping for pointers
|
||||
// ARRAY_TYPEMAPS: {
|
||||
// <pointer data type>: {
|
||||
// arrayType: <swig generated array type that will replace pointers of data type>,
|
||||
// classes: [ <class that contains arrayType>, ... ]
|
||||
// }, ...
|
||||
// }
|
||||
// POINTER_TYPEMAPS: {
|
||||
// <class that contains pointerType>: {
|
||||
// <c pointer data type>: <js swig generated pointer type that will replace pointers of data type>, ...
|
||||
// }, ...
|
||||
// }
|
||||
ARRAY_TYPEMAPS: {},
|
||||
POINTER_TYPEMAPS: {},
|
||||
|
||||
|
||||
// add command line options for this module
|
||||
addOptions: function(opts) {
|
||||
xml2js.opts = opts;
|
||||
return opts
|
||||
.option('-i, --inputdir [directory]', 'directory for xml files', __dirname + '/xml/mraa')
|
||||
.option('-c, --custom [file]', 'json for customizations')
|
||||
.option('-t, --typemaps [directory]', 'directory for custom pointer type maps')
|
||||
.option('-g, --imagedir [directory]', 'directory to link to where the images will be kept', '')
|
||||
.option('-s, --strict', 'leave out methods/variables if unknown type')
|
||||
},
|
||||
|
||||
|
||||
// parse doxygen xml -> js-format specs
|
||||
// TODO: figure out whether we need to document any protected methods/variables
|
||||
parse: function() {
|
||||
var XML_GRAMMAR_SPEC = 'grammars/xml.peg';
|
||||
var NAMESPACE_SPEC = xml2js.opts.inputdir + '/namespace' + xml2js.opts.module + '.xml';
|
||||
var CLASS_SPEC = function(c) { return xml2js.opts.inputdir + '/' + c + '.xml'; }
|
||||
var TYPES_SPEC = xml2js.opts.inputdir + '/types_8h.xml';
|
||||
xml2js.MODULE = xml2js.opts.module;
|
||||
return Promise.join(createXmlParser(XML_GRAMMAR_SPEC),
|
||||
xml2js.opts.typemaps ? initCustomPointerTypemaps(xml2js.opts.typemaps) : Promise.resolve(),
|
||||
fs.readFileAsync(NAMESPACE_SPEC, 'utf8'),
|
||||
fs.existsSync(TYPES_SPEC) ? fs.readFileAsync(TYPES_SPEC, 'utf8') : Promise.resolve(null),
|
||||
function(xmlparser, ignore, xml, xml_types) {
|
||||
if (xml_types != null) {
|
||||
_.extend(xml2js.ENUMS, getEnums(xmlparser.parse(xml_types)[0], false));
|
||||
_.extend(xml2js.ENUMS_BY_GROUP, getEnums(xmlparser.parse(xml_types)[0], true));
|
||||
}
|
||||
var spec_c = xmlparser.parse(xml)[0];
|
||||
_.extend(xml2js.ENUMS, getEnums(spec_c, false));
|
||||
_.extend(xml2js.ENUMS_BY_GROUP, getEnums(spec_c, true));
|
||||
_.extend(xml2js.METHODS, getMethods(spec_c));
|
||||
_.each(getSubclassNames(spec_c), function(className) { xml2js.CLASSES[className] = {} });
|
||||
var parseClasses = _.map(getSubclasses(spec_c), function(c) {
|
||||
return fs.readFileAsync(CLASS_SPEC(c), 'utf8').then(function(xml) {
|
||||
try {
|
||||
var spec_c = xmlparser.parse(xml)[0];
|
||||
var className = getName(spec_c);
|
||||
_.extend(xml2js.CLASSES[className], {
|
||||
description: getDescription(spec_c),
|
||||
parent: getParent(spec_c, className),
|
||||
enums: getEnums(spec_c, false, className),
|
||||
enums_by_group: getEnums(spec_c, true, className),
|
||||
variables: getVariables(spec_c, className),
|
||||
methods: getMethods(spec_c, className)
|
||||
});
|
||||
} catch(e) {
|
||||
console.log(e.toString() + ': class ' + className + ' was not parsed correctly.');
|
||||
}
|
||||
});
|
||||
});
|
||||
var parseGroups = fs.readdirAsync(xml2js.opts.inputdir).then(function(files) {
|
||||
var groupxmlfiles = _.filter(files, function(fn) {
|
||||
return ((path.extname(fn) == '.xml') && (path.basename(fn).search(/^group/) != -1));
|
||||
});
|
||||
return Promise.all(_.map(groupxmlfiles, function(fn) {
|
||||
return fs.readFileAsync(xml2js.opts.inputdir + '/' + fn, 'utf8').then(function(xml) {
|
||||
var spec_c = xmlparser.parse(xml)[0];
|
||||
if (_.isEmpty(getSubmodules(spec_c))) {
|
||||
var group = getName(spec_c);
|
||||
var classes = getSubclassNames(spec_c);
|
||||
xml2js.CLASSGROUPS[group] = {
|
||||
description: getDescription(spec_c),
|
||||
classes: classes
|
||||
};
|
||||
_.each(classes, function(c) {
|
||||
if (_.has(xml2js.CLASSES, c)) {
|
||||
xml2js.CLASSES[c].group = group;
|
||||
} else {
|
||||
console.log('Warning: Group ' + group + ' has unknown class ' + c);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
});
|
||||
return Promise.all(parseClasses.concat(parseGroups));
|
||||
}).then(function() {
|
||||
if (!_.isEmpty(xml2js.CLASSGROUPS)) {
|
||||
// try to categorize ungrouped classes, if any
|
||||
var grouped = _.flatten(_.pluck(_.values(xml2js.CLASSGROUPS), 'classes'));
|
||||
var ungrouped = _.difference(_.keys(xml2js.CLASSES), grouped);
|
||||
_.each(ungrouped, function(c) {
|
||||
_.each(findUsage(c), function(group) {
|
||||
xml2js.CLASSGROUPS[group].classes.push(c);
|
||||
});
|
||||
});
|
||||
grouped = _.flatten(_.pluck(_.values(xml2js.CLASSGROUPS), 'classes'));
|
||||
ungrouped = _.difference(_.keys(xml2js.CLASSES), grouped);
|
||||
// try to categorize ungrouped enums, if any
|
||||
_.each(xml2js.ENUMS_BY_GROUP, function(enumGroupSpec, enumGroupName) {
|
||||
_.each(findUsage(enumGroupName, true), function(c) {
|
||||
xml2js.CLASSES[c].enums_by_group[enumGroupName] = enumGroupSpec;
|
||||
_.each(enumGroupSpec.members, function(enumName) {
|
||||
xml2js.CLASSES[c].enums[enumName] = xml2js.ENUMS[enumName];
|
||||
delete xml2js.ENUMS[enumName];
|
||||
});
|
||||
delete xml2js.ENUMS_BY_GROUP[enumGroupName];
|
||||
});
|
||||
});
|
||||
}
|
||||
}).then(function() {
|
||||
if (xml2js.opts.custom && fs.existsSync(xml2js.opts.custom)) {
|
||||
return fs.readFileAsync(xml2js.opts.custom, 'utf8').then(function(custom) {
|
||||
try {
|
||||
customizeMethods(JSON.parse(custom));
|
||||
} catch(e) {
|
||||
console.log('invalid custom.json, ignored. ' + e.toString());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log(xml2js.opts.custom ? ('Error: No such customization file exists: ' + xml2js.opts.custom) : 'No customizations given.');
|
||||
}
|
||||
}).then(function() {
|
||||
generateCustomPointerClasses();
|
||||
validateMethods();
|
||||
validateVars();
|
||||
return _.pick(xml2js, 'MODULE', 'ENUMS', 'ENUMS_BY_GROUP', 'METHODS', 'CLASSES', 'CLASSGROUPS');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// create an xml parser
|
||||
function createXmlParser(XML_GRAMMAR_SPEC) {
|
||||
return fs.readFileAsync(XML_GRAMMAR_SPEC, 'utf8').then(function(xmlgrammar) {
|
||||
return peg.buildParser(xmlgrammar);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// configure c->js typemaps from custom swig directives
|
||||
// TODO: many built in assumptions based on current upm file structures & .i customizations
|
||||
function initCustomPointerTypemaps(typemapsdir) {
|
||||
return fs.readdirAsync(typemapsdir).then(function(dirs) {
|
||||
return Promise.all(_.map(dirs, function(dir) {
|
||||
// get all js*.i directives from class-specific subdirectories, to be parsed below for %typemaps directives
|
||||
return fs.readdirAsync(typemapsdir + '/' + dir).then(function(files) {
|
||||
var directive = _.find(files, function(fn) {
|
||||
return ((path.extname(fn) == '.i') && (path.basename(fn).search(/^js/) != -1));
|
||||
});
|
||||
var data = {};
|
||||
if (directive) {
|
||||
data[dir] = typemapsdir + '/' + dir + '/' + directive;
|
||||
}
|
||||
return data;
|
||||
}).catch(function(e) {
|
||||
// get all .i directives from top level directory, and parse for %array_class directives
|
||||
if (e.code == 'ENOTDIR') {
|
||||
var fn = dir;
|
||||
if (path.extname(fn) == '.i') {
|
||||
return fs.readFileAsync(typemapsdir + '/' + fn, 'utf8').then(function(directives) {
|
||||
var arraytypes = _.filter(directives.split(/\n/), function(line) {
|
||||
return (line.search(/^%array_class/) != -1);
|
||||
});
|
||||
_.each(arraytypes, function(arraytype) {
|
||||
var parsed = arraytype.match(/%array_class\(([A-Za-z0-9_]+)[\s]*,[\s]*([A-Za-z0-9_]+)\)/);
|
||||
if (parsed) {
|
||||
var from = parsed[1];
|
||||
var to = parsed[2];
|
||||
xml2js.ARRAY_TYPEMAPS[from] = { arrayType: to, classes: [] };
|
||||
} else {
|
||||
console.log('Incorrectly parsed array_class from ' + fn + ': ' + arraytype);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}));
|
||||
}).then(function(__directivesFiles) {
|
||||
// parse for %typemaps & %pointer_functions directives
|
||||
var _directivesFiles = _.filter(__directivesFiles, function(data) { return !_.isEmpty(data); });
|
||||
var directivesFiles = _.object(_.map(_directivesFiles, _.keys), _.flatten(_.map(_directivesFiles, _.values)));
|
||||
return Promise.all(_.map(directivesFiles, function(directivesFn, className) {
|
||||
return fs.readFileAsync(directivesFn, 'utf8').then(function(directives) {
|
||||
var typemaps = _.filter(directives.split(/\n/), function(line) {
|
||||
return (line.search(/^%typemap/) != -1);
|
||||
});
|
||||
_.each(typemaps, function(typemap) {
|
||||
var parsed = typemap.match(/%typemap\((in|out)\)[\s]+([A-Za-z0-9_]+[\s]*[\*])/);
|
||||
if (parsed) {
|
||||
var dir = parsed[1]; // TODO: ignored for now
|
||||
var type = normalizePointer(parsed[2]);
|
||||
var datatype = getPointerDataType(type);
|
||||
if (_.has(xml2js.ARRAY_TYPEMAPS, datatype)) {
|
||||
xml2js.ARRAY_TYPEMAPS[datatype].classes.push(className);
|
||||
} else {
|
||||
console.log('Ignored typemap from ' + directivesFn + ': ' + typemap.replace('{', '') + ' (no %array_class directive found for ' + datatype + ')');
|
||||
}
|
||||
} else {
|
||||
console.log('Ignored typemap from ' + directivesFn + ': ' + typemap.replace('{', '') + ' (only considering in/out typemaps of pointer types)');
|
||||
}
|
||||
});
|
||||
var ptrfns = _.filter(directives.split(/\n/), function(line) {
|
||||
return (line.search(/^%pointer_functions/) != -1);
|
||||
});
|
||||
_.each(ptrfns, function(ptrfn) {
|
||||
var parsed = ptrfn.match(/%pointer_functions\(([A-Za-z0-9_]+)[\s]*,[\s]*([A-Za-z0-9_]+)\)/);
|
||||
if (parsed) {
|
||||
var from = parsed[1];
|
||||
var to = parsed[2];
|
||||
if (!_.has(xml2js.POINTER_TYPEMAPS, className)) {
|
||||
xml2js.POINTER_TYPEMAPS[className] = {};
|
||||
}
|
||||
xml2js.POINTER_TYPEMAPS[className][from] = to;
|
||||
}
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// generate class specs for custom pointer types
|
||||
function generateCustomPointerClasses() {
|
||||
var arrayTypes = _.pluck(_.values(xml2js.ARRAY_TYPEMAPS), 'arrayType');
|
||||
var pointerTypes = _.uniq(_.flatten(_.map(_.values(xml2js.POINTER_TYPEMAPS), _.values)));
|
||||
_.each(arrayTypes, function(arrayType) {
|
||||
var dataType = _.findKey(xml2js.ARRAY_TYPEMAPS, function(to) { return to.arrayType == arrayType; });
|
||||
xml2js.CLASSES[arrayType] = {
|
||||
description: 'Array of type ' + dataType + '.',
|
||||
enums: {},
|
||||
enums_by_group: {},
|
||||
variables: {},
|
||||
methods: {}
|
||||
};
|
||||
xml2js.CLASSES[arrayType].methods[arrayType] = {
|
||||
description: 'Instantiates the array.',
|
||||
params: {
|
||||
nelements: {
|
||||
type: 'Number',
|
||||
description: 'number of elements in the array'
|
||||
}
|
||||
},
|
||||
return: {}
|
||||
};
|
||||
xml2js.CLASSES[arrayType].methods.getitem = {
|
||||
description: 'Access a particular element in the array.',
|
||||
params: {
|
||||
index: {
|
||||
type: 'Number',
|
||||
description: 'index of array to read from'
|
||||
},
|
||||
},
|
||||
return: {
|
||||
type: getType(dataType),
|
||||
description: 'the value of the element found at the given index of the array'
|
||||
}
|
||||
};
|
||||
xml2js.CLASSES[arrayType].methods.setitem = {
|
||||
description: 'Modify a particular element in the array.',
|
||||
params: {
|
||||
index: {
|
||||
type: 'Number',
|
||||
description: 'index of array to write to'
|
||||
},
|
||||
value: {
|
||||
type: getType(dataType),
|
||||
description: 'the value to set the element found at the given index of the array'
|
||||
}
|
||||
},
|
||||
return: {}
|
||||
};
|
||||
});
|
||||
var pointerDataTypeMap = _.reduce(_.map(_.values(xml2js.POINTER_TYPEMAPS), _.invert), function(memo, typemap) {
|
||||
return _.extend(memo, typemap);
|
||||
}, {});
|
||||
_.each(pointerTypes, function(pointerType) {
|
||||
var dataType = pointerDataTypeMap[pointerType];
|
||||
xml2js.CLASSES[pointerType] = {
|
||||
description: 'Proxy object to data of type ' + dataType + '.',
|
||||
enums: {},
|
||||
enums_by_group: {},
|
||||
variables: {},
|
||||
methods: {}
|
||||
};
|
||||
xml2js.CLASSES[pointerType].methods[pointerType] = {
|
||||
description: 'Instantiates the proxy object.',
|
||||
params: {},
|
||||
return: {}
|
||||
};
|
||||
xml2js.CLASSES[pointerType].methods.value = {
|
||||
description: 'Get the value of the object.',
|
||||
params: {},
|
||||
return: {
|
||||
type: getType(dataType),
|
||||
description: 'the value of the object'
|
||||
}
|
||||
};
|
||||
xml2js.CLASSES[pointerType].methods.assign = {
|
||||
description: 'Set the value of the object.',
|
||||
params: {
|
||||
value: {
|
||||
type: getType(dataType),
|
||||
description: 'the value to set the object to'
|
||||
}
|
||||
},
|
||||
return: {}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// search for usage of a type
|
||||
function findUsage(type, classOnly) {
|
||||
var filterClasses = function(fn) { return _.without(_.map(xml2js.CLASSES, fn), undefined); };
|
||||
var usesType = function(classSpec, className) {
|
||||
var methodsOfType = (_.find(classSpec.methods, function(methodSpec, methodName) {
|
||||
return ((!_.isEmpty(methodSpec.return) && methodSpec.return.type == type) ||
|
||||
(_.contains(_.pluck(methodSpec.params, 'type'), type)));
|
||||
}) != undefined);
|
||||
var variablesOfType = _.contains(_.pluck(classSpec.variable, 'type'), type);
|
||||
return ((methodsOfType || variablesOfType) ? className : undefined);
|
||||
};
|
||||
var extendsType = function(classSpec, className) {
|
||||
return ((classSpec.parent == type) ? className : undefined);
|
||||
};
|
||||
var classes = _.union(filterClasses(usesType), filterClasses(extendsType));
|
||||
if (classOnly) {
|
||||
return classes;
|
||||
} else {
|
||||
return _.without(_.uniq(_.pluck(_.pick(xml2js.CLASSES, classes), 'group')), undefined);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// override autogenerated methods with custom configuration
|
||||
function customizeMethods(custom) {
|
||||
_.each(custom, function(classMethods, className) {
|
||||
_.extend(xml2js.CLASSES[className].methods, _.pick(classMethods, function(methodSpec, methodName) {
|
||||
return isValidMethodSpec(methodSpec, className + '.' + methodName);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// make sure methods have valid types, otherwise warn (& don't include if strict)
|
||||
function validateMethods() {
|
||||
xml2js.METHODS = _.pick(xml2js.METHODS, function(methodSpec, methodName) {
|
||||
return hasValidTypes(methodSpec, methodName);
|
||||
});
|
||||
_.each(xml2js.CLASSES, function(classSpec, className) {
|
||||
var valid = _.pick(classSpec.methods, function(methodSpec, methodName) {
|
||||
return hasValidTypes(methodSpec, className + '.' + methodName, className);
|
||||
});
|
||||
if (xml2js.opts.strict) {
|
||||
xml2js.CLASSES[className].methods = valid;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// make sure variables have valid types, otherwise warn (& don't include if strict)
|
||||
function validateVars() {
|
||||
_.each(xml2js.CLASSES, function(classSpec, className) {
|
||||
var valid = _.pick(classSpec.variables, function(varSpec, varName) {
|
||||
return ofValidType(varSpec, className + '.' + varName, className);
|
||||
});
|
||||
if (xml2js.opts.strict) {
|
||||
xml2js.CLASSES[className].variables = valid;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// verify that the json spec is well formatted
|
||||
function isValidMethodSpec(methodSpec, methodName) {
|
||||
var valid = true;
|
||||
var printIgnoredMethodOnce = _.once(function() { console.log(methodName + ' from ' + path.basename(xml2js.opts.custom) + ' is omitted from JS documentation.'); });
|
||||
function checkRule(rule, errMsg) {
|
||||
if (!rule) {
|
||||
printIgnoredMethodOnce();
|
||||
console.log(' ' + errMsg);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
checkRule(_.has(methodSpec, 'description'), 'no description given');
|
||||
checkRule(_.has(methodSpec, 'params'), 'no params given (specify "params": {} for no params)');
|
||||
_.each(methodSpec.params, function(paramSpec, paramName) {
|
||||
checkRule(_.has(paramSpec, 'type'), 'no type given for param ' + paramName);
|
||||
checkRule(_.has(paramSpec, 'description'), 'no description given for param ' + paramName);
|
||||
});
|
||||
checkRule(_.has(methodSpec, 'return'), 'no return given (specify "return": {} for no return value)');
|
||||
checkRule(_.has(methodSpec.return, 'type'), 'no type given for return value');
|
||||
checkRule(_.has(methodSpec.return, 'description'), 'no description given for return value');
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
// get enum specifications
|
||||
function getEnums(spec_c, bygroup, parent) {
|
||||
var spec_js = {};
|
||||
var enumGroups = _.find(getChildren(spec_c, 'sectiondef'), function(section) {
|
||||
var kind = getAttr(section, 'kind');
|
||||
return ((kind == 'enum') || (kind == 'public-type'));
|
||||
});
|
||||
if (enumGroups) {
|
||||
_.each(enumGroups.children, function(enumGroup) {
|
||||
var enumGroupName = getText(getChild(enumGroup, 'name'), 'name');
|
||||
var enumGroupDescription = getText(getChild(enumGroup, 'detaileddescription'), 'description');
|
||||
var enumGroupVals = getChildren(enumGroup, 'enumvalue');
|
||||
if (bygroup) {
|
||||
spec_js[enumGroupName] = {
|
||||
description: enumGroupDescription,
|
||||
members: []
|
||||
};
|
||||
}
|
||||
_.each(enumGroupVals, function(e) {
|
||||
// TODO: get prefix as option
|
||||
var enumName = getText(getChild(e, 'name'), 'name').replace(/^MRAA_/, '');
|
||||
var enumDescription = getText(getChild(e, 'detaileddescription'), 'description');
|
||||
if (!bygroup) {
|
||||
spec_js[enumName] = {
|
||||
type: enumGroupName,
|
||||
description: enumDescription
|
||||
};
|
||||
} else {
|
||||
spec_js[enumGroupName].members.push(enumName);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return spec_js;
|
||||
}
|
||||
|
||||
|
||||
// get the name for the module/group/class
|
||||
function getName(spec_c) {
|
||||
return getText(getChild(spec_c, 'compoundname'), 'name').replace(xml2js.opts.module + '::', '');
|
||||
}
|
||||
|
||||
|
||||
// get the description for the module/group/class
|
||||
function getDescription(spec_c) {
|
||||
return getText(getChild(spec_c, 'detaileddescription'), 'description');
|
||||
}
|
||||
|
||||
|
||||
// get the classes (xml file names) for the given module
|
||||
function getSubclasses(spec_c) {
|
||||
return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) {
|
||||
return getAttr(innerclass, 'refid');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// get the classes (class names) for the given module
|
||||
function getSubclassNames(spec_c) {
|
||||
return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) {
|
||||
return getText(innerclass).replace(xml2js.opts.module + '::', '');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// get the submodules (xml file names) for the given module
|
||||
function getSubmodules(spec_c) {
|
||||
return _.map(getChildren(spec_c, 'innergroup'), function(innergroup) {
|
||||
return getAttr(innergroup, 'refid');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// get parent class, if any
|
||||
function getParent(spec_c, className) {
|
||||
var parent = getChild(spec_c, 'basecompoundref');
|
||||
if (parent) {
|
||||
parent = getText(parent);
|
||||
if (!_.has(xml2js.CLASSES, parent)) {
|
||||
console.log('WARNING: Class ' + className + ' has unknown parent class ' + parent);
|
||||
}
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
function hasParams(paramsSpec) {
|
||||
return !(_.isEmpty(paramsSpec) ||
|
||||
((_.size(paramsSpec) == 1) && getText(getChild(paramsSpec[0], 'type')) == 'void'));
|
||||
}
|
||||
|
||||
|
||||
// get method specifications for top-level module or a given class
|
||||
// TODO: overloaded functions
|
||||
// TODO: functions w/ invalid parameter(s)/return
|
||||
function getMethods(spec_c, parent) {
|
||||
var spec_js = {};
|
||||
var methods = _.find(getChildren(spec_c, 'sectiondef'), function(section) {
|
||||
var kind = getAttr(section, 'kind');
|
||||
return ((kind == 'public-func') || (kind == 'func'));
|
||||
});
|
||||
if (methods) {
|
||||
_.each(methods.children, function(method) {
|
||||
var methodName = getText(getChild(method, 'name'), 'name');
|
||||
if (methodName[0] != '~') { // filter out destructors
|
||||
try {
|
||||
var description = getChild(method, 'detaileddescription');
|
||||
var methodDescription = getText(description, 'description');
|
||||
var paramsSpec = getChildren(method, 'param');
|
||||
var params = {};
|
||||
if (hasParams(paramsSpec)) {
|
||||
params = getParams(paramsSpec, getParamsDetails(description), methodName, parent);
|
||||
}
|
||||
var returnSpec = getChild(method, 'type');
|
||||
var retval = {};
|
||||
if (!_.isEmpty(returnSpec)) {
|
||||
retval = getReturn(returnSpec, getReturnDetails(description), methodName, parent);
|
||||
}
|
||||
methodName = getUniqueMethodName(methodName, spec_js, parent);
|
||||
spec_js[methodName] = {
|
||||
description: methodDescription,
|
||||
params: params,
|
||||
return: retval
|
||||
};
|
||||
} catch(e) {
|
||||
console.log((parent ? (parent + '.') : '') + methodName + ' is omitted from JS documentation.');
|
||||
console.log(' ' + e.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return spec_js;
|
||||
}
|
||||
|
||||
|
||||
// get a unique string to represent the name of an overloaded method
|
||||
function getUniqueMethodName(methodName, module, parent) {
|
||||
if (methodName in module) {
|
||||
do {
|
||||
methodName += '!';
|
||||
} while (methodName in module);
|
||||
}
|
||||
return methodName;
|
||||
}
|
||||
|
||||
|
||||
// get variable specifications for a class
|
||||
function getVariables(spec_c, parent) {
|
||||
var spec_js = {};
|
||||
var vars = _.find(getChildren(spec_c, 'sectiondef'), function(section) {
|
||||
var kind = getAttr(section, 'kind');
|
||||
return (kind == 'public-attrib');
|
||||
});
|
||||
if (vars) {
|
||||
_.each(_.filter(vars.children, function(variable) {
|
||||
return (getAttr(variable, 'kind') == 'variable');
|
||||
}), function(variable) {
|
||||
var varName = getText(getChild(variable, 'name'), 'name');
|
||||
var varType = getType(getText(getChild(variable, 'type')), parent);
|
||||
var varDescription = getText(getChild(variable, 'detaileddescription'));
|
||||
spec_js[varName] = {
|
||||
type: varType,
|
||||
description: varDescription
|
||||
}
|
||||
});
|
||||
}
|
||||
return spec_js;
|
||||
}
|
||||
|
||||
|
||||
// get return value specs of a method
|
||||
function getReturn(spec_c, details, method, parent) {
|
||||
var retType = getType(getText(spec_c, 'type'), parent);
|
||||
var retDescription = (details ? getText(details, 'description') : '');
|
||||
return ((retType == 'void') ? {} : {
|
||||
type: retType,
|
||||
description: retDescription
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// get paramater specs of a method
|
||||
function getParams(spec_c, details, method, parent) {
|
||||
var spec_js = {};
|
||||
_.each(spec_c, function(param) {
|
||||
try {
|
||||
var paramType = getType(getText(getChild(param, 'type'), 'type'), parent);
|
||||
var paramName = getText(getChild(param, 'declname'), 'name');
|
||||
spec_js[paramName] = { type: paramType };
|
||||
} catch(e) {
|
||||
if (paramType == '...') {
|
||||
spec_js['arguments'] = { type: paramType };
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
_.each(details, function(param) {
|
||||
var getParamName = function(p) { return getText(getChild(getChild(p, 'parameternamelist'), 'parametername'), 'name'); }
|
||||
var paramName = getParamName(param);
|
||||
var paramDescription = getText(getChild(param, 'parameterdescription'), 'description');
|
||||
if (_.has(spec_js, paramName)) {
|
||||
spec_js[paramName].description = paramDescription;
|
||||
} else {
|
||||
var msg = ' has documentation for an unknown parameter: ' + paramName + '. ';
|
||||
var suggestions = _.difference(_.keys(spec_js), _.map(details, getParamName));
|
||||
var msgAddendum = (!_.isEmpty(suggestions) ? ('Did you mean ' + suggestions.join(', or ') + '?') : '');
|
||||
console.log('Warning: ' + (parent ? (parent + '.') : '') + method + msg + msgAddendum);
|
||||
}
|
||||
});
|
||||
return spec_js;
|
||||
}
|
||||
|
||||
|
||||
// get the equivalent javascript type from the given c type
|
||||
function getType(type_c, parent) {
|
||||
var type_js = type_c;
|
||||
_.find(xml2js.TYPEMAPS, function(to, from) {
|
||||
var pattern = new RegExp(from, 'i');
|
||||
if (type_c.search(pattern) == 0) {
|
||||
type_js = to;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (isPointer(type_js)) {
|
||||
var dataType = getPointerDataType(type_js);
|
||||
var className = parent.toLowerCase();
|
||||
if (_.has(xml2js.ARRAY_TYPEMAPS, dataType) && _.contains(xml2js.ARRAY_TYPEMAPS[dataType].classes, className)) {
|
||||
type_js = xml2js.ARRAY_TYPEMAPS[dataType].arrayType;
|
||||
} else if (_.has(xml2js.POINTER_TYPEMAPS, className) && _.has(xml2js.POINTER_TYPEMAPS[className], dataType)) {
|
||||
type_js = xml2js.POINTER_TYPEMAPS[className][dataType];
|
||||
} else if (_.has(xml2js.CLASSES, dataType)) { // TODO: verify that swig does this mapping
|
||||
type_js = dataType;
|
||||
} else {
|
||||
type_js = dataType + ' *'
|
||||
}
|
||||
}
|
||||
return type_js;
|
||||
}
|
||||
|
||||
|
||||
// verify that all types associated with the method are valid
|
||||
function hasValidTypes(methodSpec, methodName, parent) {
|
||||
var valid = true;
|
||||
var msg = (xml2js.opts.strict ? ' is omitted from JS documentation.' : ' has invalid type(s).');
|
||||
var printIgnoredMethodOnce = _.once(function() { console.log(methodName + msg); });
|
||||
_.each(methodSpec.params, function(paramSpec, paramName) {
|
||||
if (!isValidType(paramSpec.type, parent)) {
|
||||
valid = false;
|
||||
printIgnoredMethodOnce();
|
||||
console.log(' Error: parameter ' + paramName + ' has invalid type ' + typeToString(paramSpec.type));
|
||||
}
|
||||
});
|
||||
if (!_.isEmpty(methodSpec.return) && !isValidType(methodSpec.return.type, parent)) {
|
||||
valid = false;
|
||||
printIgnoredMethodOnce();
|
||||
console.log(' Error: returns invalid type ' + typeToString(methodSpec.return.type));
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
// verify that type of variable is valid
|
||||
function ofValidType(varSpec, varName, parent) {
|
||||
if (isValidType(varSpec.type, parent)) {
|
||||
return true;
|
||||
} else {
|
||||
var msgAddendum = (xml2js.opts.strict ? ' Omitted from JS documentation.' : '');
|
||||
console.log('Error: ' + varName + ' is of invalid type ' + typeToString(varSpec.type) + '.' + msgAddendum);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// verify whether the given type is valid JS
|
||||
function isValidType(type, parent) {
|
||||
return (_.contains(_.values(xml2js.TYPEMAPS), type) ||
|
||||
_.has(xml2js.CLASSES, type) ||
|
||||
_.has(xml2js.ENUMS_BY_GROUP, type) ||
|
||||
_.contains(['Buffer', 'Function', 'mraa_result_t'], type) ||
|
||||
_.has((parent ? xml2js.CLASSES[parent].enums_by_group : []), type) ||
|
||||
isValidPointerType(type, parent));
|
||||
}
|
||||
|
||||
|
||||
function isValidPointerType(type, parent) {
|
||||
var className = parent.toLowerCase();
|
||||
var arrayTypemap = _.find(xml2js.ARRAY_TYPEMAPS, function(to) { return to.arrayType == type; });
|
||||
var valid = ((arrayTypemap && _.contains(arrayTypemap.classes, className)) ||
|
||||
(_.has(xml2js.POINTER_TYPEMAPS, className) && (_.contains(_.values(xml2js.POINTER_TYPEMAPS[className]), type))));
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
// determines whether a type looks like a c pointer
|
||||
function isPointer(type) {
|
||||
return (type.search(/\w+\s*(\*|&)$/) != -1);
|
||||
}
|
||||
|
||||
|
||||
// remove extraneous whitespace from pointer types as canonical representation
|
||||
function normalizePointer(ptr) {
|
||||
return ptr.replace(/\s*$/, '');
|
||||
}
|
||||
|
||||
|
||||
// get the data type of a pointer (e.g. int is the data type of int*)
|
||||
function getPointerDataType(ptr) {
|
||||
return ptr.replace(/\s*(\*|&)$/, '');
|
||||
}
|
||||
|
||||
|
||||
// print more human friendly type for error messages
|
||||
function typeToString(type) {
|
||||
return type.replace('*', '*');
|
||||
}
|
||||
|
||||
|
||||
// get the detailed description of a method's parameters
|
||||
function getParamsDetails(spec_c) {
|
||||
var paras = getChildren(spec_c, 'para');
|
||||
var details = _.find(_.map(paras, function(para) {
|
||||
return getChild(para, 'parameterlist');
|
||||
}), function(obj) { return (obj != undefined); });
|
||||
return (details ? details.children : undefined);
|
||||
}
|
||||
|
||||
|
||||
// get the detailed description of a method's return value
|
||||
function getReturnDetails(spec_c) {
|
||||
var paras = getChildren(spec_c, 'para');
|
||||
return _.find(_.map(paras, function(para) {
|
||||
return getChild(para, 'simplesect');
|
||||
}), function(obj) { return ((obj != undefined) && (getAttr(obj, 'kind') == 'return')); });
|
||||
}
|
||||
|
||||
|
||||
// get (and flatten) the text of the given object
|
||||
function getText(obj, why) {
|
||||
// TODO: links ignored for now, patched for types for
|
||||
var GENERATE_LINK = function(x) { return x + ' '; }
|
||||
return _.reduce(obj.children, function(text, elem) {
|
||||
if (_.isString(elem)) {
|
||||
return text += elem.trim() + ' ';
|
||||
} else if (_.isPlainObject(elem)) {
|
||||
switch(elem.name) {
|
||||
case 'para':
|
||||
return text += getText(elem, why) + ' \n';
|
||||
case 'ref':
|
||||
return text += GENERATE_LINK(getText(elem, why));
|
||||
case 'parameterlist':
|
||||
case 'simplesect':
|
||||
return text; // to be handled elsewhere
|
||||
case 'programlisting':
|
||||
case 'htmlonly':
|
||||
return text; // ignored
|
||||
// TODO: html doesn't seem to work for yuidoc, using markdown for now
|
||||
case 'itemizedlist':
|
||||
return text += '\n' + getText(elem, why) + ' \n \n';
|
||||
case 'listitem':
|
||||
return text += '+ ' + getText(elem, why) + '\n';
|
||||
case 'bold':
|
||||
return text += '__' + getText(elem, why).trim() + '__ ';
|
||||
case 'ulink':
|
||||
return text += '[' + getText(elem, why).trim() + '](' + getAttr(elem, 'url').trim() + ') ';
|
||||
case 'image':
|
||||
// TODO: copy images over; hard coded for now
|
||||
var fn = getAttr(elem, 'name');
|
||||
return text += ' \n \n ';
|
||||
case 'linebreak':
|
||||
return text += ' \n';
|
||||
case 'ndash':
|
||||
return text += '– ';
|
||||
default:
|
||||
// TODO: incomplete list of doxygen xsd implemented
|
||||
console.warn('NYI Unknown Object Type: ' + elem.name);
|
||||
return text;
|
||||
//throw new Error('NYI Unknown Object Type: ' + elem.name);
|
||||
}
|
||||
} else {
|
||||
throw new Error('NYI Unknown Type: ' + (typeof elem));
|
||||
}
|
||||
}, '').trim();
|
||||
}
|
||||
|
||||
|
||||
// get the value of attribute with the given name of the given object
|
||||
function getAttr(obj, name) {
|
||||
return _.find(obj.attr, function(item) {
|
||||
return item.name == name;
|
||||
}).value;
|
||||
}
|
||||
|
||||
|
||||
// get the child object with the given name of the given object
|
||||
function getChild(obj, name) {
|
||||
return _.find(obj.children, function(child) {
|
||||
return child.name == name;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// get all children objects with the given name of the given object
|
||||
function getChildren(obj, name) {
|
||||
return _.filter(obj.children, function(child) {
|
||||
return child.name == name;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// debug helper: print untruncated object
|
||||
function printObj(obj) {
|
||||
console.log(util.inspect(obj, false, null));
|
||||
}
|
||||
|
||||
|
||||
module.exports = xml2js;
|
@ -5,15 +5,16 @@ adc121c021.cxx ADC121C021Sample.java adc121c021.js adc121c021.py
|
||||
adxl345.cxx Adxl345Sample.java adxl345.js adxl345.py
|
||||
biss0001.cxx BISS0001Sample.java biss0001.js biss0001.py
|
||||
bmpx8x.cxx BMPX8XSample.java bmpx8x.js bmpx8x.py
|
||||
bno055.cxx BNO055_Example.java bno055.js bno055.py
|
||||
button.cxx ButtonSample.java button.js button.py
|
||||
buzzer.cxx BuzzerSample.java buzzer.js buzzer.py
|
||||
cjq4435.cxx CJQ4435Sample.java cjq4435.js cjq4435.py
|
||||
ds1307.cxx DS1307Sample.java ds1307.js ds1307.py
|
||||
enc03r.cxx ENC03RSample.java enc03r.js enc03r.py
|
||||
es08a.cxx ES08ASample.java es08a.js es08a.py
|
||||
servo-es08a.cxx ES08ASample.java es08a.js es08a.py
|
||||
groveehr.cxx GroveEHRSample.java groveehr.js groveehr.py
|
||||
groveledbar.cxx GroveLEDBar.java groveledbar.js groveledbar.py
|
||||
groveled.cxx GroveLEDSample.java groveled.js groveled.py
|
||||
my9221-groveledbar.cxx GroveLEDBar.java groveledbar.js groveledbar.py
|
||||
grove-groveled.cxx GroveLEDSample.java groveled.js groveled.py
|
||||
grovelinefinder.cxx GroveLineFinderSample.java grovelinefinder.js grovelinefinder.py
|
||||
grovemoisture.cxx GroveMoistureSample.java grovemoisture.js grovemoisture.py
|
||||
grovescam.cxx GROVESCAMSample.java grovescam.js grovescam.py
|
||||
@ -32,7 +33,7 @@ lcm1602-i2c.cxx Lcm1602_i2cSample.java lcm1602-i2c.js lcm1602-i2c.py
|
||||
ldt0028.cxx LDT0028Sample.java ldt0028.js ldt0028.py
|
||||
light.cxx LightSample.java light.js light.py
|
||||
lol.cxx LoLSample.java lol.js lol.py
|
||||
lsm303.cxx LSM303Sample.java lsm303.js lsm303.py
|
||||
lsm303dlh.cxx LSM303DLHSample.java lsm303dlh.js lsm303dlh.py
|
||||
m24lr64e.cxx M24LR64ESample.java m24lr64e.js m24lr64e.py
|
||||
max44000.cxx MAX44000Sample.java max44000.js max44000.py
|
||||
mic.cxx MicrophoneSample.java mic.js mic.py
|
||||
@ -41,9 +42,9 @@ mma7660.cxx MMA7660Sample.java mma7660.js mma7660.py
|
||||
mpl3115a2.cxx MPL3115A2Sample.java mpl3115a2.js mpl3115a2.py
|
||||
mpr121.cxx MPR121Sample.java mpr121.js mpr121.py
|
||||
mpu9150.cxx MPU9150Sample.java mpu9150.js mpu9150.py
|
||||
mq2.cxx MQ2Sample.java mq2.js mq2.py
|
||||
gas-mq2.cxx MQ2Sample.java mq2.js mq2.py
|
||||
mq303a.cxx MQ303ASample.java mq303a.js mq303a.py
|
||||
mq5.cxx MQ5Sample.java mq5.js mq5.py
|
||||
gas-mq5.cxx MQ5Sample.java mq5.js mq5.py
|
||||
nrf24l01-receiver.cxx NRF24L01_receiverSample.java nrf24l01-receiver.js nrf24l01-receiver.py
|
||||
nrf24l01-transmitter.cxx NRF24L01_transmitterSample.java nrf24l01-transmitter.js nrf24l01-transmitter.py
|
||||
nunchuck.cxx NUNCHUCKSample.java nunchuck.js nunchuck.py
|
||||
@ -58,12 +59,12 @@ rpr220.cxx RPR220Sample.java rpr220.js rpr220.py
|
||||
rpr220-intr.cxx RPR220_intrSample.java rpr220-intr.js rpr220-intr.py
|
||||
slide.cxx SlideSample.java slide.js slide.py
|
||||
speaker.cxx SpeakerSample.java speaker.js speaker.py
|
||||
ssd1308-oled.cxx SSD1308_oledSample.java ssd1308-oled.js ssd1308-oled.py
|
||||
ssd1327-oled.cxx SSD1327_oledSample.java ssd1327-oled.js ssd1327-oled.py
|
||||
i2clcd-ssd1308-oled.cxx SSD1308_oledSample.java ssd1308-oled.js ssd1308-oled.py
|
||||
i2clcd-ssd1327-oled.cxx SSD1327_oledSample.java ssd1327-oled.js ssd1327-oled.py
|
||||
st7735.cxx ST7735Sample.java st7735.js st7735.py
|
||||
stepmotor.cxx StepMotorSample.java stepmotor.js stepmotor.py
|
||||
tm1637.cxx TM1637Sample.java tm1637.js tm1637.py
|
||||
tp401.cxx TP401Sample.java tp401.js tp401.py
|
||||
gas-tp401.cxx TP401Sample.java tp401.js tp401.py
|
||||
tsl2561.cxx TSL2561Sample.java tsl2561.js tsl2561.py
|
||||
ttp223.cxx TTP223Sample.java ttp223.js ttp223.py
|
||||
uln200xa.cxx ULN200XASample.java uln200xa.js uln200xa.py
|
||||
@ -71,3 +72,10 @@ vdiv.cxx VDivSample.java vdiv.js vdiv.py
|
||||
water.cxx WaterSample.java water.js water.py
|
||||
wt5001.cxx WT5001Sample.java wt5001.js wt5001.py
|
||||
yg1006.cxx YG1006Sample.java yg1006.js yg1006.py
|
||||
sensortemplate.cxx SensorTemplateSample.java sensortemplate.js sensortemplate.py
|
||||
p9813.cxx P9813Sample.java p9813.js p9813.py
|
||||
tcs37727.cxx tcs37727.py
|
||||
tmp006.cxx tmp006.py
|
||||
mma8x5x.cxx mma8x5x.py
|
||||
mag3110.cxx mag3110.py
|
||||
hdc1000.cxx hdc1000.py
|
||||
|
120
examples/CMakeLists.txt
Normal file
120
examples/CMakeLists.txt
Normal file
@ -0,0 +1,120 @@
|
||||
# Add an example executable target for the provided source file which depends
|
||||
# on a UPM library target. Strings after the first '-' are ignored.
|
||||
#
|
||||
# Usage:
|
||||
# add_example(source_file TARGETS <target0> <target1> <targetn> SUFFIX <target_suffix>)
|
||||
#
|
||||
# Parameters:
|
||||
# source_file - C/C++ source file. Filename must follow a specific format:
|
||||
# <library>-[additional].c(xx)
|
||||
# library: Name of UPM library required by example
|
||||
# -additional: Any other string used to identify the example
|
||||
# TARGETS - Additional dependency target/s required to BUILD/RUN this example. If TARGETS is
|
||||
# set, these are in addition to the dependency library provided by the example filename.
|
||||
# SUFFIX - Provide a means to differentiate between C/C++ dependency targets and
|
||||
# example names. Leave empty for CXX examples. Use '-c' for c targets.
|
||||
# SUFFIX Example file Dependency target Example binary
|
||||
# ------ ------------ ----------------- --------------
|
||||
# "-c" foo.c foo-c foo-example-c
|
||||
# foo.cxx foo foo-example-cxx
|
||||
#
|
||||
# Parent scope variable:
|
||||
# example_src_list - Any example target which is successfully created by
|
||||
# add_example will be removed from the parent scope variable
|
||||
# example_src_list (if it exists). This provides a means to handle
|
||||
# special case examples BEFORE handling all files in example_src_list.
|
||||
#
|
||||
# Examples:
|
||||
# # Creates sensorfoo-example-cxx, depends on target: sensorfoo
|
||||
# add_example(sensorfoo.cxx)
|
||||
#
|
||||
# # Creates sensorfoo-example-c, depends on target: sensorfoo-c
|
||||
# add_example(sensorfoo.c SUFFIX "-c")
|
||||
#
|
||||
# # Creates sensorfoo-bar-example-c, depends on target: sensorfoo-c
|
||||
# add_example(sensorfoo-bar.c SUFFIX "-c")
|
||||
#
|
||||
# # Creates testfoobar-cxx, depends on targets: blib, blah
|
||||
# add_example(testfoobar.c TARGETS blib blah)
|
||||
#
|
||||
# Examples:
|
||||
# a110x.c Requires libupmc-a110x
|
||||
# lcm1602-i2c.c Requires libupmc-lcm1602
|
||||
# bmp280-bme280.c Requires libupmc-bmp280
|
||||
# i2clcd-eboled.cxx Requires libupm-i2clcd
|
||||
#
|
||||
#
|
||||
function (add_example example_src)
|
||||
set (oneValueArgs SUFFIX)
|
||||
set (multiValueArgs TARGETS)
|
||||
# Parse function parameters
|
||||
cmake_parse_arguments(add_example "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
# Attempt to remove this example source file from a list of example
|
||||
# sources. This allows for handling special case examples.
|
||||
list (REMOVE_ITEM example_src_list ${example_src})
|
||||
set (example_src_list ${example_src_list} PARENT_SCOPE)
|
||||
|
||||
# Get the base filename from the full filename
|
||||
# For file /some/path/to/sensorfoo-bar.c, example_name = sensorfoo-bar
|
||||
get_filename_component(example_name ${example_src} NAME_WE)
|
||||
|
||||
# Parse out <library>
|
||||
# Example: sensorfoo-bar.c, library = sensorfoo
|
||||
string (REPLACE "-" ";" split_name ${example_name})
|
||||
list (GET split_name 0 library_name)
|
||||
|
||||
# Parse dependency target name from example_src filename (add on suffix)
|
||||
# For sensorfoo, lib_target_names = sensorfoo-c
|
||||
set (lib_target_names "${library_name}${add_example_SUFFIX}")
|
||||
|
||||
# If TARGETS is provided, add additional dependency targets
|
||||
if (add_example_TARGETS)
|
||||
list (APPEND lib_target_names "${add_example_TARGETS}")
|
||||
endif ()
|
||||
|
||||
# Unfortunately, c++ and c library targets are not named the same. If
|
||||
# no suffix is provided, assume C++ and add a suffix of -cxx to the
|
||||
# example target name
|
||||
# library example target
|
||||
# c: sensorfoo-c sensorfoo-bar-example-c
|
||||
# cxx: sensorfoo sensorfoo-bar-example-cxx
|
||||
if (NOT add_example_SUFFIX)
|
||||
set(add_example_SUFFIX "-cxx")
|
||||
endif ()
|
||||
|
||||
# Create the target name for this example: mylibrary-bar-example-c
|
||||
set (this_target_name "${example_name}-example${add_example_SUFFIX}")
|
||||
|
||||
# If a dependency target does NOT exist, print a warning and skip
|
||||
foreach(_dep_target ${lib_target_names})
|
||||
if (NOT TARGET ${_dep_target})
|
||||
message(STATUS "Example ${example_src} is missing a required CMake target (${_dep_target}), skipping...")
|
||||
return()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# Create an executable target for this example
|
||||
add_executable (${this_target_name} ${example_src})
|
||||
|
||||
# Add each dependency to the library target
|
||||
foreach(_dep_target ${lib_target_names})
|
||||
target_link_libraries(${this_target_name} ${_dep_target} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endforeach ()
|
||||
endfunction (add_example example_src)
|
||||
|
||||
# Add subdirectories if BUILDEXAMPLES=on
|
||||
if(BUILDEXAMPLES)
|
||||
# Add C examples
|
||||
add_subdirectory (c)
|
||||
|
||||
# Add C++ examples?
|
||||
if (BUILDCPP)
|
||||
add_subdirectory (c++)
|
||||
endif ()
|
||||
|
||||
# Add java examples?
|
||||
if(BUILDSWIGJAVA)
|
||||
add_subdirectory (java)
|
||||
endif()
|
||||
endif()
|
@ -1,378 +1,20 @@
|
||||
# Selectively disable certain warnings for the examples
|
||||
# nrf examples flag -Wtautological-compare
|
||||
set (CXX_DISABLED_WARNINGS -Wno-tautological-compare)
|
||||
# Create an list of all C++ source files in this directory
|
||||
file (GLOB example_src_list RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cxx")
|
||||
|
||||
# Extract module name from non-standard example name
|
||||
macro(get_module_name example_name module_name)
|
||||
string(LENGTH ${example_name} length)
|
||||
string(FIND ${example_name} "-" index)
|
||||
if (${index} GREATER 1)
|
||||
string(SUBSTRING ${example_name} 0 ${index} substr)
|
||||
set(${module_name} ${substr})
|
||||
elseif (${example_name} MATCHES "^grove")
|
||||
set (${module_name} "grove")
|
||||
elseif ((${example_name} MATCHES "^mq" AND ${length} EQUAL 3) OR ${example_name} STREQUAL "tp401")
|
||||
set (${module_name} "gas")
|
||||
else()
|
||||
set(${module_name} ${example_name})
|
||||
endif()
|
||||
endmacro()
|
||||
# - Handle special cases here --------------------------------------------------
|
||||
|
||||
# Set source file, include and linker settings for an example
|
||||
# If example cannot be built, example_bin is cleared
|
||||
macro(add_custom_example example_bin example_src example_module_list)
|
||||
set(found_all_modules TRUE)
|
||||
foreach (module ${example_module_list})
|
||||
if (NOT EXISTS "${PROJECT_SOURCE_DIR}/src/${module}")
|
||||
set(found_all_modules FALSE)
|
||||
endif()
|
||||
if (MODULE_LIST)
|
||||
list(FIND MODULE_LIST ${module} index)
|
||||
if (${index} EQUAL -1)
|
||||
set(found_all_modules FALSE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
if (found_all_modules)
|
||||
add_executable (${example_bin} ${example_src})
|
||||
target_link_libraries (${example_bin} ${CMAKE_THREAD_LIBS_INIT})
|
||||
# Test humidity interface for 2 sensor libraries
|
||||
add_example(interfaces-humiditysensor.cxx TARGETS si7005 bmp280)
|
||||
# Test pressure interface for 2 sensor libraries
|
||||
add_example(interfaces-pressuresensor.cxx TARGETS bmp280 bmpx8x)
|
||||
# Test temperature interface for 3 sensor libraries
|
||||
add_example(interfaces-temperaturesensor.cxx TARGETS bmp280 bmpx8x si7005)
|
||||
# Test light interface for 2 sensor libraries
|
||||
add_example(interfaces-lightsensor.cxx TARGETS si1132 max44009)
|
||||
# Test light controller interface for 3 sensor libraries
|
||||
add_example(interfaces-lightcontroller.cxx TARGETS lp8860 ds1808lc hlg150h)
|
||||
|
||||
# Disable warnings from CXX_DISABLED_WARNINGS
|
||||
foreach(flag ${CXX_DISABLED_WARNINGS})
|
||||
compiler_flag_supported(CXX is_supported ${flag})
|
||||
if (is_supported)
|
||||
target_compile_options(${example_bin} PRIVATE "${flag}")
|
||||
endif(is_supported)
|
||||
endforeach(flag ${CXX_DISABLED_WARNINGS})
|
||||
|
||||
foreach (module ${example_module_list})
|
||||
set(module_dir "${PROJECT_SOURCE_DIR}/src/${module}")
|
||||
include_directories (${module_dir})
|
||||
if (${module} STREQUAL "lcd")
|
||||
set(module "i2clcd")
|
||||
endif()
|
||||
target_link_libraries (${example_bin} ${module})
|
||||
endforeach()
|
||||
else()
|
||||
message (WARNING "Ignored ${example_bin}")
|
||||
set (example_bin "")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
# Add specified example by name
|
||||
# Note special case for grove based examples
|
||||
macro(add_example example_name)
|
||||
set(example_src "${example_name}.cxx")
|
||||
set(example_bin "${example_name}-example-cxx")
|
||||
get_module_name(${example_name} module_name)
|
||||
set(module_dir "${PROJECT_SOURCE_DIR}/src/${module_name}")
|
||||
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${example_src}"
|
||||
AND EXISTS ${module_dir}
|
||||
AND IS_DIRECTORY ${module_dir})
|
||||
add_custom_example(${example_bin} ${example_src} ${module_name})
|
||||
if ((NOT ${example_bin} STREQUAL "") AND (${module_name} STREQUAL "grove"))
|
||||
set(grove_module_path "${PROJECT_SOURCE_DIR}/src/${example_name}")
|
||||
if (EXISTS ${grove_module_path})
|
||||
include_directories(${grove_module_path})
|
||||
target_link_libraries (${example_bin} ${example_name})
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message (WARNING "Ignored ${example_bin}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples)
|
||||
|
||||
# UPM c include directories
|
||||
include_directories (${PROJECT_SOURCE_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/src/utilities)
|
||||
|
||||
# Set the mraa include and link directories prior to adding examples
|
||||
include_directories (${MRAA_INCLUDE_DIRS})
|
||||
link_directories (${MRAA_LIBDIR})
|
||||
|
||||
# If your sample source file matches the name of the module it tests, add it here
|
||||
# Exceptions are as follows:
|
||||
# string after first '-' is ignored (e.g. nrf24l01-transmitter maps to nrf24l01)
|
||||
# mq? will use module gas
|
||||
# grove* will use module grove
|
||||
add_example (hmc5883l)
|
||||
add_example (led)
|
||||
add_example (groveled)
|
||||
add_example (relay)
|
||||
add_example (groverelay)
|
||||
add_example (light)
|
||||
add_example (grovelight)
|
||||
add_example (temperature)
|
||||
add_example (grovetemp)
|
||||
add_example (button)
|
||||
add_example (grovebutton)
|
||||
add_example (rotary)
|
||||
add_example (groverotary)
|
||||
add_example (slide)
|
||||
add_example (groveslide)
|
||||
add_example (buzzer)
|
||||
add_example (nrf24l01-transmitter)
|
||||
add_example (nrf24l01-receiver)
|
||||
add_example (nrf24l01-broadcast)
|
||||
add_example (hcsr04)
|
||||
add_example (max44000)
|
||||
add_example (mma7455)
|
||||
add_example (st7735)
|
||||
add_example (max31855)
|
||||
add_example (bmpx8x)
|
||||
add_example (stepmotor)
|
||||
add_example (pulsensor)
|
||||
add_example (mic)
|
||||
add_example (mpu9150)
|
||||
add_example (maxds3231m)
|
||||
add_example (max31723)
|
||||
add_example (max5487)
|
||||
add_example (nrf8001-broadcast)
|
||||
add_example (nrf8001-helloworld)
|
||||
add_example (lpd8806)
|
||||
add_example (mlx90614)
|
||||
add_example (ecs1030)
|
||||
add_example (mq2)
|
||||
add_example (mq3)
|
||||
add_example (mq4)
|
||||
add_example (mq5)
|
||||
add_example (mq6)
|
||||
add_example (mq7)
|
||||
add_example (mq8)
|
||||
add_example (mq9)
|
||||
add_example (tp401)
|
||||
add_example (tcs3414cs)
|
||||
add_example (th02)
|
||||
add_example (ttp223)
|
||||
add_example (lsm303)
|
||||
add_example (joystick12)
|
||||
add_example (lol)
|
||||
add_example (tsl2561)
|
||||
add_example (htu21d)
|
||||
add_example (mpl3115a2)
|
||||
add_example (ldt0028)
|
||||
add_example (am2315)
|
||||
add_example (itg3200)
|
||||
add_example (enc03r)
|
||||
add_example (adc121c021)
|
||||
add_example (ds1307)
|
||||
add_example (a110x)
|
||||
add_example (gp2y0a)
|
||||
add_example (moisture)
|
||||
add_example (grovemoisture)
|
||||
add_example (ehr)
|
||||
add_example (groveehr)
|
||||
add_example (ta12200)
|
||||
add_example (grovelinefinder)
|
||||
add_example (linefinder)
|
||||
add_example (vdiv)
|
||||
add_example (grovevdiv)
|
||||
add_example (water)
|
||||
add_example (grovewater)
|
||||
add_example (guvas12d)
|
||||
add_example (mpr121)
|
||||
add_example (yg1006)
|
||||
add_example (wt5001)
|
||||
add_example (ppd42ns)
|
||||
add_example (mq303a)
|
||||
add_example (speaker)
|
||||
add_example (grovespeaker)
|
||||
add_example (rfr359f)
|
||||
add_example (biss0001)
|
||||
add_example (rotaryencoder)
|
||||
add_example (adxl345)
|
||||
add_example (rpr220)
|
||||
add_example (rpr220-intr)
|
||||
add_example (mma7660)
|
||||
add_example (cjq4435)
|
||||
add_example (adxl335)
|
||||
add_example (hmtrp)
|
||||
add_example (nunchuck)
|
||||
add_example (otp538u)
|
||||
add_example (collision)
|
||||
add_example (grovecollision)
|
||||
add_example (electromagnet)
|
||||
add_example (groveelectromagnet)
|
||||
add_example (emg)
|
||||
add_example (groveemg)
|
||||
add_example (o2)
|
||||
add_example (groveo2)
|
||||
add_example (gsr)
|
||||
add_example (grovegsr)
|
||||
add_example (ina132)
|
||||
add_example (l298)
|
||||
add_example (l298-stepper)
|
||||
add_example (at42qt1070)
|
||||
add_example (grovemd)
|
||||
add_example (md)
|
||||
add_example (grovemd-stepper)
|
||||
add_example (md-stepper)
|
||||
add_example (pca9685)
|
||||
add_example (eldriver)
|
||||
add_example (groveeldriver)
|
||||
add_example (adafruitss)
|
||||
add_example (adafruitms1438)
|
||||
add_example (adafruitms1438-stepper)
|
||||
add_example (hx711)
|
||||
add_example (flex)
|
||||
add_example (a110x-intr)
|
||||
add_example (mhz16)
|
||||
add_example (apds9002)
|
||||
add_example (waterlevel)
|
||||
add_example (tm1637)
|
||||
add_example (zfm20)
|
||||
add_example (zfm20-register)
|
||||
add_example (uln200xa)
|
||||
add_example (grovewfs)
|
||||
add_example (wfs)
|
||||
add_example (isd1820)
|
||||
add_example (sx6119)
|
||||
add_example (si114x)
|
||||
add_example (maxsonarez)
|
||||
add_example (hm11)
|
||||
add_example (ht9170)
|
||||
add_example (h3lis331dl)
|
||||
add_example (ad8232)
|
||||
add_example (grovescam)
|
||||
add_example (scam)
|
||||
add_example (m24lr64e)
|
||||
add_example (rgbringcoder)
|
||||
add_example (hp20x)
|
||||
add_example (pn532)
|
||||
add_example (pn532-writeurl)
|
||||
add_example (lsm9ds0)
|
||||
add_example (loudness)
|
||||
add_example (mg811)
|
||||
add_example (wheelencoder)
|
||||
add_example (sm130)
|
||||
add_example (gprs)
|
||||
add_example (grovegprs)
|
||||
add_example (lm35)
|
||||
add_example (micsv89)
|
||||
add_example (xbee)
|
||||
add_example (urm37)
|
||||
add_example (urm37-uart)
|
||||
add_example (adxrs610)
|
||||
add_example (bma220)
|
||||
add_example (dfrph)
|
||||
add_example (mcp9808)
|
||||
add_example (groveultrasonic)
|
||||
add_example (ultrasonic)
|
||||
add_example (sx1276-lora)
|
||||
add_example (sx1276-fsk)
|
||||
add_example (ili9341)
|
||||
add_example (nlgpio16)
|
||||
add_example (ads1x15)
|
||||
if (MODBUS_FOUND)
|
||||
include_directories(${MODBUS_INCLUDE_DIRS})
|
||||
add_example (t3311)
|
||||
add_example (hwxpxx)
|
||||
add_example (h803x)
|
||||
endif()
|
||||
add_example (hdxxvxta)
|
||||
add_example (rhusb)
|
||||
add_example (apds9930)
|
||||
add_example (kxcjk1013)
|
||||
add_example (ssd1351)
|
||||
add_example (ds1808lc)
|
||||
add_example (hlg150h)
|
||||
add_example (lp8860)
|
||||
add_example (max44009)
|
||||
add_example (si1132)
|
||||
add_example (si7005)
|
||||
add_example (t6713)
|
||||
add_example (cwlsxxa)
|
||||
add_example (teams)
|
||||
add_example (apa102)
|
||||
add_example (tex00)
|
||||
add_example (bmi160)
|
||||
add_example (smartdrive)
|
||||
if (HAVE_FIRMATA)
|
||||
add_example (curieimu)
|
||||
endif ()
|
||||
if (BACNET_FOUND)
|
||||
include_directories(${BACNET_INCLUDE_DIRS})
|
||||
# we need access to bacnetmstp headers too
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src/bacnetmstp)
|
||||
add_example (e50hx)
|
||||
add_example (t8100)
|
||||
add_example (tb7300)
|
||||
endif()
|
||||
if (JPEG_FOUND)
|
||||
add_example (vcap)
|
||||
endif (JPEG_FOUND)
|
||||
add_example (ds2413)
|
||||
add_example (ds18b20)
|
||||
add_example (bmp280)
|
||||
add_example (bno055)
|
||||
add_example (l3gd20)
|
||||
add_example (l3gd20-i2c)
|
||||
add_example (bmx055)
|
||||
add_example (ms5611)
|
||||
add_example (nmea_gps)
|
||||
add_example (mma7361)
|
||||
add_example (bh1750)
|
||||
add_example (hka5)
|
||||
add_example (dfrorp)
|
||||
add_example (dfrec)
|
||||
add_example (sht1x)
|
||||
add_example (ms5803)
|
||||
add_example (ims)
|
||||
add_example (ecezo)
|
||||
add_example (mb704x)
|
||||
add_example (rf22-server)
|
||||
add_example (rf22-client)
|
||||
add_example (mcp2515)
|
||||
add_example (max30100)
|
||||
|
||||
# These are special cases where you specify example binary, source file and module(s)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src)
|
||||
add_custom_example (groveled-multi-example-cxx groveled-multi.cxx grove)
|
||||
add_custom_example (lcm1602-i2c-example-cxx lcm1602-i2c.cxx lcd)
|
||||
add_custom_example (lcm1602-parallel-example-cxx lcm1602-parallel.cxx lcd)
|
||||
add_custom_example (jhd1313m1-lcd-example-cxx jhd1313m1-lcd.cxx lcd)
|
||||
add_custom_example (es08a-example-cxx es08a.cxx servo)
|
||||
add_custom_example (ssd1306-oled-example-cxx ssd1306-oled.cxx lcd)
|
||||
add_custom_example (ssd1308-oled-example-cxx ssd1308-oled.cxx lcd)
|
||||
add_custom_example (ssd1327-oled-example-cxx ssd1327-oled.cxx lcd)
|
||||
add_custom_example (sainsmartks-example-cxx sainsmartks.cxx lcd)
|
||||
add_custom_example (eboled-example-cxx eboled.cxx lcd)
|
||||
add_custom_example (mpu60x0-example-cxx mpu60x0.cxx mpu9150)
|
||||
add_custom_example (ak8975-example-cxx ak8975.cxx mpu9150)
|
||||
add_custom_example (mpu9250-example-cxx mpu9250.cxx mpu9150)
|
||||
add_custom_example (groveledbar-example-cxx groveledbar.cxx my9221)
|
||||
add_custom_example (grovecircularled-example-cxx grovecircularled.cxx my9221)
|
||||
add_custom_example (temperature-sensor-example-cxx temperature-sensor.cxx "si7005;bmpx8x;bmp280")
|
||||
add_custom_example (humidity-sensor-example-cxx humidity-sensor.cxx "si7005;bmp280")
|
||||
add_custom_example (pressure-sensor-example-cxx pressure-sensor.cxx "bmpx8x;bmp280")
|
||||
add_custom_example (co2-sensor-example-cxx co2-sensor.cxx "t6713")
|
||||
add_custom_example (adc-example-cxx adc-sensor.cxx "ads1x15")
|
||||
add_custom_example (light-sensor-example-cxx light-sensor.cxx "si1132;max44009")
|
||||
add_custom_example (light-controller-example-cxx light-controller.cxx "lp8860;ds1808lc;hlg150h")
|
||||
add_custom_example (bme280-example-cxx bme280.cxx bmp280)
|
||||
add_custom_example (bma250e-example-cxx bma250e.cxx bmx055)
|
||||
add_custom_example (bmg160-example-cxx bmg160.cxx bmx055)
|
||||
add_custom_example (bmm150-example-cxx bmm150.cxx bmx055)
|
||||
add_custom_example (bmc150-example-cxx bmc150.cxx bmx055)
|
||||
add_custom_example (bmi055-example-cxx bmi055.cxx bmx055)
|
||||
if (OPENZWAVE_FOUND)
|
||||
include_directories(${OPENZWAVE_INCLUDE_DIRS})
|
||||
|
||||
add_custom_example (ozwdump-example-cxx ozwdump.cxx ozw)
|
||||
add_custom_example (aeotecss6-example-cxx aeotecss6.cxx ozw)
|
||||
add_custom_example (aeotecsdg2-example-cxx aeotecsdg2.cxx ozw)
|
||||
add_custom_example (aeotecdw2e-example-cxx aeotecdw2e.cxx ozw)
|
||||
add_custom_example (aeotecdsb09104-example-cxx aeotecdsb09104.cxx ozw)
|
||||
add_custom_example (tzemt400-example-cxx tzemt400.cxx ozw)
|
||||
endif()
|
||||
add_custom_example (nmea_gps_i2c_example-cxx nmea_gps_i2c.cxx nmea_gps)
|
||||
add_custom_example (mcp2515-txrx-example-cxx mcp2515-txrx.cxx mcp2515)
|
||||
add_custom_example (ads1015-example-cxx ads1015.cxx ads1x15)
|
||||
add_custom_example (le910-example-cxx le910.cxx uartat)
|
||||
add_custom_example (speaker_pwm-example-cxx speaker_pwm.cxx speaker)
|
||||
add_custom_example (ads1115-example-cxx ads1015.cxx ads1x15)
|
||||
# - Create an executable for all other src files in this directory -------------
|
||||
foreach (_example_src ${example_src_list})
|
||||
add_example(${_example_src})
|
||||
endforeach ()
|
||||
|
61
examples/c++/abp.cxx
Normal file
61
examples/c++/abp.cxx
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Author: Abhishek Malik <abhishek.malik@intel.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include "abp.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int shouldRun = true;
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
if (signo == SIGINT)
|
||||
shouldRun = false;
|
||||
}
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
//! [Interesting]
|
||||
// Instantiate an ABP sensor on i2c bus 0
|
||||
upm::ABP* abp = new upm::ABP(0, ABP_DEFAULT_ADDRESS);
|
||||
while (shouldRun) {
|
||||
abp->update();
|
||||
cout << "Retrieved pressure: " << abp->getPressure() << endl;
|
||||
cout << "Retrieved Temperature: " << abp->getTemperature() << endl;
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
//! [Interesting]
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete abp;
|
||||
return 0;
|
||||
}
|
@ -40,7 +40,7 @@
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
|
||||
#include "adis16448.h"
|
||||
#include "adis16448.hpp"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
|
@ -49,6 +49,7 @@ void stop()
|
||||
|
||||
int main()
|
||||
{
|
||||
//! [Interesting]
|
||||
long id = 0; // Sample number
|
||||
string fileName = "./ads1015.data"; // Output filename
|
||||
ofstream f;
|
||||
@ -97,6 +98,7 @@ int main()
|
||||
return 1;
|
||||
}
|
||||
cout << "Wrote " << id << " samples to file: " << fileName << endl;
|
||||
//! [Interesting]
|
||||
return 0;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ void stop()
|
||||
|
||||
int main()
|
||||
{
|
||||
//! [Interesting]
|
||||
long id = 0; // Sample number
|
||||
string fileName = "./ads1115.data"; // Output filename
|
||||
ofstream f;
|
||||
@ -100,6 +101,7 @@ int main()
|
||||
return 1;
|
||||
}
|
||||
cout << "Wrote " << id << " samples to file: " << fileName << endl;
|
||||
//! [Interesting]
|
||||
return 0;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ int main()
|
||||
using namespace std;
|
||||
using namespace upm;
|
||||
int command;
|
||||
//! [Interesting]
|
||||
//Select the device you are testing here and adjust case 6 for the correct sample rates.
|
||||
//upm::ADS1015 *ads = new upm::ADS1015(1);
|
||||
upm::ADS1115 *ads = new upm::ADS1115(1, 0x49);
|
||||
@ -315,6 +316,7 @@ int main()
|
||||
}while (command != -1 );
|
||||
|
||||
delete ads;
|
||||
//! [Interesting]
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ int main(int argc, char **argv)
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an BMA250E using default I2C parameters
|
||||
upm::BMA250E *sensor = new upm::BMA250E();
|
||||
upm::BMA250E sensor;
|
||||
|
||||
// For SPI, bus 0, you would pass -1 as the address, and a valid pin
|
||||
// for CS: BMA250E(0, -1, 10);
|
||||
@ -54,9 +54,9 @@ int main(int argc, char **argv)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
sensor->update();
|
||||
sensor.update();
|
||||
|
||||
sensor->getAccelerometer(&x, &y, &z);
|
||||
sensor.getAccelerometer(&x, &y, &z);
|
||||
cout << "Accelerometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
@ -64,8 +64,8 @@ int main(int argc, char **argv)
|
||||
<< endl;
|
||||
|
||||
// we show both C and F for temperature
|
||||
cout << "Compensation Temperature: " << sensor->getTemperature()
|
||||
<< " C / " << sensor->getTemperature(true) << " F"
|
||||
cout << "Compensation Temperature: " << sensor.getTemperature()
|
||||
<< " C / " << sensor.getTemperature(true) << " F"
|
||||
<< endl;
|
||||
|
||||
cout << endl;
|
||||
@ -77,7 +77,5 @@ int main(int argc, char **argv)
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ int main(int argc, char **argv)
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an BMG160 using default I2C parameters
|
||||
upm::BMG160 *sensor = new upm::BMG160();
|
||||
upm::BMG160 sensor;
|
||||
|
||||
// For SPI, bus 0, you would pass -1 as the address, and a valid pin
|
||||
// for CS: BMG160(0, -1, 10);
|
||||
@ -54,9 +54,9 @@ int main(int argc, char **argv)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
sensor->update();
|
||||
sensor.update();
|
||||
|
||||
sensor->getGyroscope(&x, &y, &z);
|
||||
sensor.getGyroscope(&x, &y, &z);
|
||||
cout << "Gyroscope x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
@ -64,8 +64,8 @@ int main(int argc, char **argv)
|
||||
<< endl;
|
||||
|
||||
// we show both C and F for temperature
|
||||
cout << "Compensation Temperature: " << sensor->getTemperature()
|
||||
<< " C / " << sensor->getTemperature(true) << " F"
|
||||
cout << "Compensation Temperature: " << sensor.getTemperature()
|
||||
<< " C / " << sensor.getTemperature(true) << " F"
|
||||
<< endl;
|
||||
|
||||
cout << endl;
|
||||
@ -77,7 +77,5 @@ int main(int argc, char **argv)
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ int main(int argc, char **argv)
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an BMM150 using default I2C parameters
|
||||
upm::BMM150 *sensor = new upm::BMM150();
|
||||
upm::BMM150 sensor;
|
||||
|
||||
// For SPI, bus 0, you would pass -1 as the address, and a valid pin
|
||||
// for CS: BMM150(0, -1, 10);
|
||||
@ -54,9 +54,9 @@ int main(int argc, char **argv)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
sensor->update();
|
||||
sensor.update();
|
||||
|
||||
sensor->getMagnetometer(&x, &y, &z);
|
||||
sensor.getMagnetometer(&x, &y, &z);
|
||||
cout << "Magnetometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
@ -72,7 +72,5 @@ int main(int argc, char **argv)
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
using namespace std;
|
||||
using namespace upm;
|
||||
|
||||
int shouldRun = true;
|
||||
bool shouldRun = true;
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
* Copyright (c) 2016-2017 Intel Corporation.
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -31,7 +33,7 @@
|
||||
using namespace std;
|
||||
using namespace upm;
|
||||
|
||||
int shouldRun = true;
|
||||
bool shouldRun = true;
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
|
@ -1,6 +1,11 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* This driver was rewritten based on the original driver written by:
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -24,57 +29,50 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include "bmpx8x.hpp"
|
||||
#include <signal.h>
|
||||
|
||||
int doWork = 0;
|
||||
upm::BMPX8X *sensor = NULL;
|
||||
#include "bmpx8x.hpp"
|
||||
|
||||
void
|
||||
sig_handler(int signo)
|
||||
using namespace std;
|
||||
|
||||
bool shouldRun = true;
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
printf("got signal\n");
|
||||
if (signo == SIGINT) {
|
||||
printf("exiting application\n");
|
||||
doWork = 1;
|
||||
}
|
||||
if (signo == SIGINT)
|
||||
shouldRun = false;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
//! [Interesting]
|
||||
uint32_t presure = 0;
|
||||
float temperature = 0;
|
||||
float altitude = 0;
|
||||
uint32_t sealevel = 0;
|
||||
signal(SIGINT, sig_handler);
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate a BMPX8X sensor on I2C
|
||||
sensor = new upm::BMPX8X(0, ADDR);
|
||||
// Instantiate a BMPX8X sensor on I2C using defaults.
|
||||
upm::BMPX8X sensor;
|
||||
|
||||
// Print the pressure, altitude, sea level, and
|
||||
// temperature values every 0.1 seconds
|
||||
while (!doWork) {
|
||||
presure = sensor->getPressure ();
|
||||
temperature = sensor->getTemperature ();
|
||||
altitude = sensor->getAltitude ();
|
||||
sealevel = sensor->getSealevelPressure ();
|
||||
// temperature values every 0.5 seconds
|
||||
while (shouldRun)
|
||||
{
|
||||
sensor.update();
|
||||
|
||||
std::cout << "pressure value = " <<
|
||||
presure <<
|
||||
", altitude value = " <<
|
||||
altitude <<
|
||||
", sealevel value = " <<
|
||||
sealevel <<
|
||||
", temperature = " <<
|
||||
temperature << std::endl;
|
||||
usleep (100000);
|
||||
cout << "Pressure: "
|
||||
<< sensor.getPressure()
|
||||
<< " Pa, Temperature: "
|
||||
<< sensor.getTemperature()
|
||||
<< " C, Altitude: "
|
||||
<< sensor.getAltitude()
|
||||
<< " m, Sea level: "
|
||||
<< sensor.getSealevelPressure()
|
||||
<< " Pa"
|
||||
<< endl;
|
||||
|
||||
usleep(500000);
|
||||
}
|
||||
//! [Interesting]
|
||||
|
||||
std::cout << "exiting application" << std::endl;
|
||||
|
||||
delete sensor;
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
//! [Interesting]
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,23 +44,23 @@ int main(int argc, char **argv)
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an BMC150 using default I2C parameters
|
||||
upm::BMC150 *sensor = new upm::BMC150();
|
||||
upm::BMC150 sensor;
|
||||
|
||||
// now output data every 250 milliseconds
|
||||
while (shouldRun)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
sensor->update();
|
||||
sensor.update();
|
||||
|
||||
sensor->getAccelerometer(&x, &y, &z);
|
||||
sensor.getAccelerometer(&x, &y, &z);
|
||||
cout << "Accelerometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
<< " g"
|
||||
<< endl;
|
||||
|
||||
sensor->getMagnetometer(&x, &y, &z);
|
||||
sensor.getMagnetometer(&x, &y, &z);
|
||||
cout << "Magnetometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
@ -76,7 +76,5 @@ int main(int argc, char **argv)
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
@ -44,23 +44,23 @@ int main(int argc, char **argv)
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an BMI055 using default I2C parameters
|
||||
upm::BMI055 *sensor = new upm::BMI055();
|
||||
upm::BMI055 sensor;
|
||||
|
||||
// now output data every 250 milliseconds
|
||||
while (shouldRun)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
sensor->update();
|
||||
sensor.update();
|
||||
|
||||
sensor->getAccelerometer(&x, &y, &z);
|
||||
sensor.getAccelerometer(&x, &y, &z);
|
||||
cout << "Accelerometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
<< " g"
|
||||
<< endl;
|
||||
|
||||
sensor->getGyroscope(&x, &y, &z);
|
||||
sensor.getGyroscope(&x, &y, &z);
|
||||
cout << "Gyroscope x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
@ -76,7 +76,5 @@ int main(int argc, char **argv)
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
@ -44,30 +44,30 @@ int main(int argc, char **argv)
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an BMX055 using default I2C parameters
|
||||
upm::BMX055 *sensor = new upm::BMX055();
|
||||
upm::BMX055 sensor;
|
||||
|
||||
// now output data every 250 milliseconds
|
||||
while (shouldRun)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
sensor->update();
|
||||
sensor.update();
|
||||
|
||||
sensor->getAccelerometer(&x, &y, &z);
|
||||
sensor.getAccelerometer(&x, &y, &z);
|
||||
cout << "Accelerometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
<< " g"
|
||||
<< endl;
|
||||
|
||||
sensor->getGyroscope(&x, &y, &z);
|
||||
sensor.getGyroscope(&x, &y, &z);
|
||||
cout << "Gyroscope x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
<< " degrees/s"
|
||||
<< endl;
|
||||
|
||||
sensor->getMagnetometer(&x, &y, &z);
|
||||
sensor.getMagnetometer(&x, &y, &z);
|
||||
cout << "Magnetometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
@ -83,7 +83,5 @@ int main(int argc, char **argv)
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include "buzzer.hpp"
|
||||
#include "upm_utilities.h"
|
||||
|
||||
|
||||
int
|
||||
|
@ -76,6 +76,7 @@ main(int argc, char **argv)
|
||||
printf("motion is: %d, %d, %d, %d, %d, %d\n", m, n, o, p, q, r);
|
||||
|
||||
delete sensor;
|
||||
//! [Interesting]
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,51 +1,43 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "ds1808lc.hpp"
|
||||
|
||||
#define EDISON_I2C_BUS 1 // Edison I2C-1
|
||||
#define DS1808_GPIO_PWR 15 // Edison GP165
|
||||
|
||||
void printState(upm::ILightController *lightController)
|
||||
{
|
||||
if (lightController->isPowered())
|
||||
{
|
||||
std::cout << "Light is powered, brightness = " << lightController->getBrightness() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Light is not powered." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "ds1808lc.hpp"
|
||||
|
||||
#define EDISON_I2C_BUS 1 // Edison I2C-1
|
||||
#define DS1808_GPIO_PWR 15 // Edison GP165
|
||||
|
||||
void printState(upm::ILightController &lightController)
|
||||
{
|
||||
if (lightController.isPowered())
|
||||
{
|
||||
std::cout << "Light is powered, brightness = " << lightController.getBrightness() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Light is not powered." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
int status = 0;
|
||||
upm::ILightController* lightController = nullptr;
|
||||
|
||||
try {
|
||||
lightController = new upm::DS1808LC(DS1808_GPIO_PWR, EDISON_I2C_BUS);
|
||||
std::cout << "Existing state: "; printState(lightController);
|
||||
if (argc == 2)
|
||||
{
|
||||
std::string arg = argv[1];
|
||||
int brightness = ::atoi(argv[1]);
|
||||
if (brightness > 0) {
|
||||
lightController->setPowerOn();
|
||||
lightController->setBrightness(brightness);
|
||||
} else
|
||||
lightController->setPowerOff();
|
||||
}
|
||||
std::cout << "Now: ";printState(lightController);
|
||||
} catch (std::exception& e) {
|
||||
std::cout << "Error: " << e.what() << std::endl;
|
||||
status = 1;
|
||||
}
|
||||
|
||||
delete lightController;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//! [Interesting]
|
||||
upm::DS1808LC lightController(DS1808_GPIO_PWR, EDISON_I2C_BUS);
|
||||
std::cout << "Existing state: "; printState(lightController);
|
||||
if (argc == 2)
|
||||
{
|
||||
std::string arg = argv[1];
|
||||
int brightness = ::atoi(argv[1]);
|
||||
if (brightness > 0)
|
||||
{
|
||||
lightController.setPowerOn();
|
||||
lightController.setBrightness(brightness);
|
||||
}
|
||||
else
|
||||
lightController.setPowerOff();
|
||||
}
|
||||
std::cout << "Now: ";printState(lightController);
|
||||
//! [Interesting]
|
||||
return 0;
|
||||
}
|
||||
|
@ -29,15 +29,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
upm::HCSR04 *sonar = NULL;
|
||||
int shouldRun = true;
|
||||
|
||||
void
|
||||
sig_handler(int signo)
|
||||
{
|
||||
printf("got signal\n");
|
||||
if (signo == SIGINT) {
|
||||
printf("exiting application\n");
|
||||
sonar->m_doWork = 1;
|
||||
shouldRun = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,20 +43,20 @@ sig_handler(int signo)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
sonar = new upm::HCSR04(5, 6);
|
||||
upm::HCSR04 *sonar = new upm::HCSR04(2, 4);
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
sleep(1);
|
||||
|
||||
for(;;){
|
||||
while(shouldRun){
|
||||
std::cout << "get distance" << std::endl;
|
||||
double distance = sonar->getDistance(CM);
|
||||
double distance = sonar->getDistance(HCSR04_CM);
|
||||
std::cout << "distance " << distance << std::endl;
|
||||
sleep(5);
|
||||
sleep(2);
|
||||
}
|
||||
std::cout << "Exiting... " << std::endl;
|
||||
|
||||
delete sonar;
|
||||
|
||||
return 0;
|
||||
}
|
||||
//! [Interesting]
|
||||
|
67
examples/c++/hdc1000.cxx
Normal file
67
examples/c++/hdc1000.cxx
Normal file
@ -0,0 +1,67 @@
|
||||
/* Author: Norbert Wesp <nwesp@phytec.de>
|
||||
* Copyright (c) 2017 Phytec Messtechnik GmbH.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
|
||||
#include "hdc1000.hpp"
|
||||
|
||||
using namespace upm;
|
||||
|
||||
bool run = true;
|
||||
|
||||
void sig_handler(int sig)
|
||||
{
|
||||
if (sig == SIGINT)
|
||||
run = false;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
//! [Interesting]
|
||||
std::cout << "Initializing test-application..." << std::endl;
|
||||
|
||||
// Instantiate an HDC1000 instance on bus 1
|
||||
upm::HDC1000 *mySensor = new upm::HDC1000(1);
|
||||
|
||||
// update and print available values every second
|
||||
while (run)
|
||||
{
|
||||
std::cout << "Humidity: " << mySensor->getHumidity(true) << std::endl
|
||||
<< "Temperature: " << mySensor->getTemperature(true) << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
std::cout << "Exiting test-application..." << std::endl;
|
||||
|
||||
delete mySensor;
|
||||
//! [Interesting]
|
||||
|
||||
return 0;
|
||||
}
|
@ -8,44 +8,37 @@
|
||||
#define HLG150H_GPIO_RELAY 21
|
||||
#define HLG150H_GPIO_PWM 22
|
||||
|
||||
void printState(upm::ILightController *lightController)
|
||||
void printState(upm::ILightController &lightController)
|
||||
{
|
||||
if (lightController->isPowered())
|
||||
{
|
||||
std::cout << "Light is powered, brightness = " << lightController->getBrightness() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Light is not powered." << std::endl;
|
||||
}
|
||||
if (lightController.isPowered())
|
||||
{
|
||||
std::cout << "Light is powered, brightness = " << lightController.getBrightness() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Light is not powered." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
int status = 0;
|
||||
upm::ILightController* lightController;
|
||||
//! [Interesting]
|
||||
upm::HLG150H lightController(HLG150H_GPIO_RELAY, HLG150H_GPIO_PWM);
|
||||
std::cout << "Existing state: "; printState(lightController);
|
||||
if (argc == 2)
|
||||
{
|
||||
std::string arg = argv[1];
|
||||
int brightness = ::atoi(argv[1]);
|
||||
if (brightness > 0)
|
||||
{
|
||||
lightController.setPowerOn();
|
||||
lightController.setBrightness(brightness);
|
||||
}
|
||||
else
|
||||
lightController.setPowerOff();
|
||||
}
|
||||
std::cout << "Now: ";printState(lightController);
|
||||
//! [Interesting]
|
||||
|
||||
try {
|
||||
lightController = new upm::HLG150H(HLG150H_GPIO_RELAY, HLG150H_GPIO_PWM);
|
||||
std::cout << "Existing state: "; printState(lightController);
|
||||
if (argc == 2)
|
||||
{
|
||||
std::string arg = argv[1];
|
||||
int brightness = ::atoi(argv[1]);
|
||||
if (brightness > 0) {
|
||||
lightController->setPowerOn();
|
||||
lightController->setBrightness(brightness);
|
||||
} else
|
||||
lightController->setPowerOff();
|
||||
}
|
||||
std::cout << "Now: ";printState(lightController);
|
||||
delete lightController;
|
||||
} catch (std::exception& e) {
|
||||
std::cout << "Error: " << e.what() << std::endl;
|
||||
status = 1;
|
||||
}
|
||||
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,19 +46,25 @@ int main(int argc, char **argv)
|
||||
// Instantiate a IMS instance using i2c bus 0 and default address
|
||||
upm::IMS sensor(0);
|
||||
|
||||
int i2c_addr_cur = IMS_ADDRESS_DEFAULT + 1;
|
||||
while (shouldRun)
|
||||
{
|
||||
std::cout << "Version: "
|
||||
std::cout << std::hex << "Version: 0x"
|
||||
<< sensor.get_version()
|
||||
<< " light: "
|
||||
<< " light: 0x"
|
||||
<< sensor.get_light()
|
||||
<< " moisture: "
|
||||
<< " moisture: 0x"
|
||||
<< sensor.get_moisture()
|
||||
<< " temp: "
|
||||
<< sensor.get_temperature()
|
||||
<< " C"
|
||||
<< std::endl;
|
||||
|
||||
// Change the address and continue
|
||||
if (i2c_addr_cur >= 128) i2c_addr_cur = 1;
|
||||
std::cout << "Changing device address to 0x" << i2c_addr_cur
|
||||
<< std::endl;
|
||||
sensor.reset_i2c_address(i2c_addr_cur++);
|
||||
sleep(1);
|
||||
}
|
||||
//! [Interesting]
|
||||
|
@ -95,4 +95,4 @@ int main( int argc, char **argv )
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//! [Interesting]
|
@ -23,7 +23,10 @@
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <string>
|
||||
|
||||
#include "jhd1313m1.hpp"
|
||||
#include "upm_utilities.h"
|
||||
|
||||
int shouldRun = true;
|
||||
|
||||
@ -64,7 +67,7 @@ main(int argc, char **argv)
|
||||
// Echo via printf
|
||||
printf("Hello World %d rgb: 0x%02x%02x%02x\n", ndx++, r, g, b);
|
||||
|
||||
sleep(1);
|
||||
upm_delay(1);
|
||||
}
|
||||
|
||||
//! [Interesting]
|
||||
|
@ -41,7 +41,7 @@ sig_handler(int signo)
|
||||
}
|
||||
|
||||
void
|
||||
data_callback(char* data)
|
||||
data_callback(char* data, void* args)
|
||||
{
|
||||
float x, y, z;
|
||||
accelerometer->extract3Axis(data, &x, &y, &z);
|
||||
|
@ -41,7 +41,7 @@ sig_handler(int signo)
|
||||
}
|
||||
|
||||
void
|
||||
data_callback(char* data)
|
||||
data_callback(char* data, void* args)
|
||||
{
|
||||
float x, y, z;
|
||||
if (gyroscope->extract3Axis(data, &x, &y, &z)) {
|
||||
|
73
examples/c++/lcdks.cxx
Normal file
73
examples/c++/lcdks.cxx
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "lcdks.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool shouldRun = true;
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
if (signo == SIGINT)
|
||||
shouldRun = false;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate a LCDKS (LCD Keypad Shield) using default pins
|
||||
|
||||
// NOTE: The default pins do not include support for a gpio
|
||||
// controlled backlight. If you need one, you will need to specify
|
||||
// all neccessary pins to the constructor.
|
||||
upm::LCDKS* lcd = new upm::LCDKS();
|
||||
|
||||
lcd->setCursor(0,0);
|
||||
lcd->write("LCDKS driver");
|
||||
lcd->setCursor(1,2);
|
||||
lcd->write("Hello World");
|
||||
|
||||
// output current key value every second.
|
||||
while (shouldRun)
|
||||
{
|
||||
cout << "Button value: " << lcd->getKeyValue() << endl;
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
delete lcd;
|
||||
|
||||
//! [Interesting]
|
||||
return 0;
|
||||
}
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "lcm1602.hpp"
|
||||
#include "upm_utilities.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -32,16 +33,16 @@ main(int argc, char **argv)
|
||||
lcd->setCursor(0,0);
|
||||
lcd->write("Hello World");
|
||||
//! [Interesting]
|
||||
sleep(3);
|
||||
upm_delay(3);
|
||||
lcd->setCursor(1,2);
|
||||
lcd->write("Hello World");
|
||||
sleep(3);
|
||||
upm_delay(3);
|
||||
lcd->setCursor(2,4);
|
||||
lcd->write("Hello World");
|
||||
sleep(3);
|
||||
upm_delay(3);
|
||||
lcd->setCursor(3,6);
|
||||
lcd->write("Hello World");
|
||||
sleep(3);
|
||||
upm_delay(3);
|
||||
delete lcd;
|
||||
|
||||
return 0;
|
||||
|
@ -23,7 +23,8 @@
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <lcm1602.hpp>
|
||||
#include "lcm1602.hpp"
|
||||
#include "upm_utilities.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@ -47,7 +48,7 @@ main(int argc, char **argv)
|
||||
lcd->write("Hello World");
|
||||
|
||||
printf("Sleeping for 5 seconds\n");
|
||||
sleep(5);
|
||||
upm_delay(5);
|
||||
delete lcd;
|
||||
//! [Interesting]
|
||||
return 0;
|
||||
|
@ -44,7 +44,7 @@ main(int argc, char **argv)
|
||||
std::cout << "For the next " << NUMBER_OF_SECONDS << " seconds, "
|
||||
<< SAMPLES_PER_SECOND << " samples will be taken every second."
|
||||
<< std::endl << std::endl;
|
||||
uint16_t* buffer = new uint16_t[NUMBER_OF_SECONDS * SAMPLES_PER_SECOND];
|
||||
uint16_t buffer[NUMBER_OF_SECONDS * SAMPLES_PER_SECOND];
|
||||
for (int i=0; i < NUMBER_OF_SECONDS * SAMPLES_PER_SECOND; i++) {
|
||||
buffer[i] = (uint16_t) sensor->getSample();
|
||||
usleep(MICROSECONDS_PER_SECOND / SAMPLES_PER_SECOND);
|
||||
|
64
examples/c++/lidarlitev3.cxx
Normal file
64
examples/c++/lidarlitev3.cxx
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Author: Saloni Jain <saloni.jain@tcs.com>
|
||||
* Author: Niti Rohilla <niti.rohilla@tcs.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include "lidarlitev3.hpp"
|
||||
|
||||
volatile int doWork = 0;
|
||||
|
||||
void
|
||||
sig_handler(int signo)
|
||||
{
|
||||
if (signo == SIGINT) {
|
||||
printf("\nCtrl-C received.\n");
|
||||
doWork = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
||||
// Register signal handler
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
//! [Interesting]
|
||||
upm::LIDARLITEV3 *sensor = new upm::LIDARLITEV3(0, ADDR);
|
||||
|
||||
while (!doWork) {
|
||||
std::cout << "Distance = " << sensor->getDistance () << std::endl;
|
||||
usleep (50000);
|
||||
}
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
std::cout << "exiting application" << std::endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
@ -34,10 +34,11 @@ main(int argc, char **argv)
|
||||
// Create the light sensor object using AIO pin 0
|
||||
upm::Light* light = new upm::Light(0);
|
||||
|
||||
// Read the input and print both the raw value and a rough lux value,
|
||||
// waiting one second between readings
|
||||
// Read the input and print both the normalized ADC value and a
|
||||
// rough lux value, waiting one second between readings
|
||||
while( 1 ) {
|
||||
std::cout << light->name() << " raw value is " << light->raw_value() <<
|
||||
std::cout << light->name() << " normalized value is "
|
||||
<< light->getNormalized() <<
|
||||
", which is roughly " << light->value() << " lux" << std::endl;
|
||||
sleep(1);
|
||||
}
|
||||
|
81
examples/c++/lis2ds12.cxx
Normal file
81
examples/c++/lis2ds12.cxx
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include "lis2ds12.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int shouldRun = true;
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
if (signo == SIGINT)
|
||||
shouldRun = false;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
signal(SIGINT, sig_handler);
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an LIS2DS12 using default I2C parameters
|
||||
upm::LIS2DS12 sensor;
|
||||
|
||||
// For SPI, bus 0, you would pass -1 as the address, and a valid pin
|
||||
// for CS: LIS2DS12(0, -1, 10);
|
||||
|
||||
// now output data every 250 milliseconds
|
||||
while (shouldRun)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
sensor.update();
|
||||
|
||||
sensor.getAccelerometer(&x, &y, &z);
|
||||
cout << "Accelerometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
<< " g"
|
||||
<< endl;
|
||||
|
||||
// we show both C and F for temperature
|
||||
cout << "Compensation Temperature: " << sensor.getTemperature()
|
||||
<< " C / " << sensor.getTemperature(true) << " F"
|
||||
<< endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
usleep(250000);
|
||||
}
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -9,44 +9,37 @@
|
||||
#define LP8860_GPIO_PWR 45 // Edison GP45
|
||||
|
||||
|
||||
void printState(upm::ILightController *lightController)
|
||||
void printState(upm::ILightController &lightController)
|
||||
{
|
||||
if (lightController->isPowered())
|
||||
{
|
||||
std::cout << "Light is powered, brightness = " << lightController->getBrightness() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Light is not powered." << std::endl;
|
||||
}
|
||||
if (lightController.isPowered())
|
||||
{
|
||||
std::cout << "Light is powered, brightness = " << lightController.getBrightness() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Light is not powered." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
int status = 0;
|
||||
upm::LP8860* lightController;
|
||||
//! [Interesting]
|
||||
upm::LP8860 lightController(LP8860_GPIO_PWR, EDISON_I2C_BUS);
|
||||
std::cout << "Existing state: "; printState(lightController);
|
||||
if (argc == 2)
|
||||
{
|
||||
std::string arg = argv[1];
|
||||
int brightness = ::atoi(argv[1]);
|
||||
if (brightness > 0)
|
||||
{
|
||||
lightController.setPowerOn();
|
||||
lightController.setBrightness(brightness);
|
||||
}
|
||||
else
|
||||
lightController.setPowerOff();
|
||||
}
|
||||
std::cout << "Now: ";printState(lightController);
|
||||
//! [Interesting]
|
||||
|
||||
try {
|
||||
lightController = new upm::LP8860(LP8860_GPIO_PWR, EDISON_I2C_BUS);
|
||||
std::cout << "Existing state: "; printState(lightController);
|
||||
if (argc == 2)
|
||||
{
|
||||
std::string arg = argv[1];
|
||||
int brightness = ::atoi(argv[1]);
|
||||
if (brightness > 0) {
|
||||
lightController->setPowerOn();
|
||||
lightController->setBrightness(brightness);
|
||||
} else
|
||||
lightController->setPowerOff();
|
||||
}
|
||||
std::cout << "Now: ";printState(lightController);
|
||||
delete lightController;
|
||||
} catch (std::exception& e) {
|
||||
std::cout << "Error: " << e.what() << std::endl;
|
||||
status = 1;
|
||||
}
|
||||
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
//! [Interesting]
|
||||
sensor = new upm::LPD8806(10, 7);
|
||||
sensor = new upm::LPD8806(0, 7, 10);
|
||||
usleep (1000000);
|
||||
|
||||
sensor->show ();
|
||||
|
87
examples/c++/lsm303agr.cxx
Normal file
87
examples/c++/lsm303agr.cxx
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include "lsm303agr.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int shouldRun = true;
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
if (signo == SIGINT)
|
||||
shouldRun = false;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
signal(SIGINT, sig_handler);
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an LSM303AGR using default I2C parameters
|
||||
upm::LSM303AGR sensor;
|
||||
|
||||
// now output data every 250 milliseconds
|
||||
while (shouldRun)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
sensor.update();
|
||||
|
||||
sensor.getAccelerometer(&x, &y, &z);
|
||||
cout << "Accelerometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
<< " g"
|
||||
<< endl;
|
||||
|
||||
sensor.getMagnetometer(&x, &y, &z);
|
||||
cout << "Magnetometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
<< " uT"
|
||||
<< endl;
|
||||
|
||||
cout << "Temperature: "
|
||||
<< sensor.getTemperature()
|
||||
<< " C"
|
||||
<< endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
usleep(250000);
|
||||
}
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
return 0;
|
||||
}
|
87
examples/c++/lsm303d.cxx
Normal file
87
examples/c++/lsm303d.cxx
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2017 Intel Corporation.
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include "lsm303d.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int shouldRun = true;
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
if (signo == SIGINT)
|
||||
shouldRun = false;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
signal(SIGINT, sig_handler);
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an LSM303D using default I2C parameters
|
||||
upm::LSM303D sensor;
|
||||
|
||||
// now output data every 250 milliseconds
|
||||
while (shouldRun)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
sensor.update();
|
||||
|
||||
sensor.getAccelerometer(&x, &y, &z);
|
||||
cout << "Accelerometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
<< " g"
|
||||
<< endl;
|
||||
|
||||
sensor.getMagnetometer(&x, &y, &z);
|
||||
cout << "Magnetometer x: " << x
|
||||
<< " y: " << y
|
||||
<< " z: " << z
|
||||
<< " uT"
|
||||
<< endl;
|
||||
|
||||
cout << "Temperature: "
|
||||
<< sensor.getTemperature()
|
||||
<< " C"
|
||||
<< endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
usleep(250000);
|
||||
}
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -25,19 +25,19 @@
|
||||
#include <iostream>
|
||||
|
||||
//! [Interesting]
|
||||
#include "lsm303.hpp"
|
||||
#include "lsm303dlh.hpp"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
// Instantiate LSM303 compass on I2C
|
||||
upm::LSM303 *sensor = new upm::LSM303(0);
|
||||
// Instantiate LSM303DLH compass on I2C
|
||||
upm::LSM303DLH *sensor = new upm::LSM303DLH(0);
|
||||
|
||||
// Get the coordinate data
|
||||
sensor->getCoordinates();
|
||||
int16_t* coor = sensor->getRawCoorData(); // in XYZ order.
|
||||
int16_t* coor = sensor->getRawCoorData(); // in XYZ order.
|
||||
// The sensor returns XZY, but the driver compensates and makes it XYZ
|
||||
|
||||
|
||||
// Print out the X, Y, and Z coordinate data using two different methods
|
||||
std::cout << "coor: rX " << (int)coor[0]
|
||||
<< " - rY " << (int)coor[1]
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user