Compare commits
No commits in common. 'a2ae4b1e69f5ee50e296ff8f7328697664ed9529' and '06ba753d70ad8b960becafbb8c0b84018b228d8a' have entirely different histories.
a2ae4b1e69
...
06ba753d70
43 changed files with 5221 additions and 55 deletions
@ -0,0 +1,36 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32" |
||||||
|
if [ ! -d "$ARDUINO_ESP32_PATH" ]; then |
||||||
|
echo "Installing ESP32 Arduino Core ..." |
||||||
|
script_init_path="$PWD" |
||||||
|
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif" |
||||||
|
cd "$ARDUINO_USR_PATH/hardware/espressif" |
||||||
|
|
||||||
|
echo "Installing Python Serial ..." |
||||||
|
pip install pyserial > /dev/null |
||||||
|
|
||||||
|
if [ "$OS_IS_WINDOWS" == "1" ]; then |
||||||
|
echo "Installing Python Requests ..." |
||||||
|
pip install requests > /dev/null |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then |
||||||
|
echo "Linking Core..." |
||||||
|
ln -s $GITHUB_WORKSPACE esp32 |
||||||
|
else |
||||||
|
echo "Cloning Core Repository..." |
||||||
|
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1 |
||||||
|
fi |
||||||
|
|
||||||
|
echo "Updating Submodules ..." |
||||||
|
cd esp32 |
||||||
|
git submodule update --init --recursive > /dev/null 2>&1 |
||||||
|
|
||||||
|
echo "Installing Platform Tools ..." |
||||||
|
cd tools && python get.py |
||||||
|
cd $script_init_path |
||||||
|
|
||||||
|
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'" |
||||||
|
echo "" |
||||||
|
fi |
@ -0,0 +1,220 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
#OSTYPE: 'linux-gnu', ARCH: 'x86_64' => linux64 |
||||||
|
#OSTYPE: 'msys', ARCH: 'x86_64' => win32 |
||||||
|
#OSTYPE: 'darwin18', ARCH: 'i386' => macos |
||||||
|
|
||||||
|
OSBITS=`arch` |
||||||
|
if [[ "$OSTYPE" == "linux"* ]]; then |
||||||
|
export OS_IS_LINUX="1" |
||||||
|
ARCHIVE_FORMAT="tar.xz" |
||||||
|
if [[ "$OSBITS" == "i686" ]]; then |
||||||
|
OS_NAME="linux32" |
||||||
|
elif [[ "$OSBITS" == "x86_64" ]]; then |
||||||
|
OS_NAME="linux64" |
||||||
|
elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then |
||||||
|
OS_NAME="linuxarm" |
||||||
|
else |
||||||
|
OS_NAME="$OSTYPE-$OSBITS" |
||||||
|
echo "Unknown OS '$OS_NAME'" |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
elif [[ "$OSTYPE" == "darwin"* ]]; then |
||||||
|
export OS_IS_MACOS="1" |
||||||
|
ARCHIVE_FORMAT="zip" |
||||||
|
OS_NAME="macosx" |
||||||
|
elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then |
||||||
|
export OS_IS_WINDOWS="1" |
||||||
|
ARCHIVE_FORMAT="zip" |
||||||
|
OS_NAME="windows" |
||||||
|
else |
||||||
|
OS_NAME="$OSTYPE-$OSBITS" |
||||||
|
echo "Unknown OS '$OS_NAME'" |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
export OS_NAME |
||||||
|
|
||||||
|
ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp" |
||||||
|
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp" |
||||||
|
|
||||||
|
if [ "$OS_IS_MACOS" == "1" ]; then |
||||||
|
export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java" |
||||||
|
export ARDUINO_USR_PATH="$HOME/Documents/Arduino" |
||||||
|
elif [ "$OS_IS_WINDOWS" == "1" ]; then |
||||||
|
export ARDUINO_IDE_PATH="$HOME/arduino_ide" |
||||||
|
export ARDUINO_USR_PATH="$HOME/Documents/Arduino" |
||||||
|
else |
||||||
|
export ARDUINO_IDE_PATH="$HOME/arduino_ide" |
||||||
|
export ARDUINO_USR_PATH="$HOME/Arduino" |
||||||
|
fi |
||||||
|
|
||||||
|
if [ ! -d "$ARDUINO_IDE_PATH" ]; then |
||||||
|
echo "Installing Arduino IDE on $OS_NAME ..." |
||||||
|
echo "Downloading 'arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..." |
||||||
|
if [ "$OS_IS_LINUX" == "1" ]; then |
||||||
|
wget -O "arduino.$ARCHIVE_FORMAT" "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1 |
||||||
|
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..." |
||||||
|
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null |
||||||
|
mv arduino-nightly "$ARDUINO_IDE_PATH" |
||||||
|
else |
||||||
|
curl -o "arduino.$ARCHIVE_FORMAT" -L "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1 |
||||||
|
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..." |
||||||
|
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null |
||||||
|
if [ "$OS_IS_MACOS" == "1" ]; then |
||||||
|
mv "Arduino.app" "/Applications/Arduino.app" |
||||||
|
else |
||||||
|
mv arduino-nightly "$ARDUINO_IDE_PATH" |
||||||
|
fi |
||||||
|
fi |
||||||
|
rm -rf "arduino.$ARCHIVE_FORMAT" |
||||||
|
|
||||||
|
mkdir -p "$ARDUINO_USR_PATH/libraries" |
||||||
|
mkdir -p "$ARDUINO_USR_PATH/hardware" |
||||||
|
|
||||||
|
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'" |
||||||
|
echo "" |
||||||
|
fi |
||||||
|
|
||||||
|
function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options] |
||||||
|
if [ "$#" -lt 2 ]; then |
||||||
|
echo "ERROR: Illegal number of parameters" |
||||||
|
echo "USAGE: build_sketch <fqbn> <path-to-ino> [extra-options]" |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
|
||||||
|
local fqbn="$1" |
||||||
|
local sketch="$2" |
||||||
|
local xtra_opts="$3" |
||||||
|
local win_opts="" |
||||||
|
if [ "$OS_IS_WINDOWS" == "1" ]; then |
||||||
|
local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"` |
||||||
|
local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"` |
||||||
|
win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version" |
||||||
|
fi |
||||||
|
|
||||||
|
echo "" |
||||||
|
echo "Compiling '"$(basename "$sketch")"' ..." |
||||||
|
mkdir -p "$ARDUINO_BUILD_DIR" |
||||||
|
mkdir -p "$ARDUINO_CACHE_DIR" |
||||||
|
$ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=10810 \ |
||||||
|
-fqbn=$fqbn \ |
||||||
|
-warnings="all" \ |
||||||
|
-tools "$ARDUINO_IDE_PATH/tools-builder" \ |
||||||
|
-tools "$ARDUINO_IDE_PATH/tools" \ |
||||||
|
-built-in-libraries "$ARDUINO_IDE_PATH/libraries" \ |
||||||
|
-hardware "$ARDUINO_IDE_PATH/hardware" \ |
||||||
|
-hardware "$ARDUINO_USR_PATH/hardware" \ |
||||||
|
-libraries "$ARDUINO_USR_PATH/libraries" \ |
||||||
|
-build-cache "$ARDUINO_CACHE_DIR" \ |
||||||
|
-build-path "$ARDUINO_BUILD_DIR" \ |
||||||
|
$win_opts $xtra_opts "$sketch" |
||||||
|
} |
||||||
|
|
||||||
|
function count_sketches() # count_sketches <examples-path> |
||||||
|
{ |
||||||
|
local examples="$1" |
||||||
|
rm -rf sketches.txt |
||||||
|
if [ ! -d "$examples" ]; then |
||||||
|
touch sketches.txt |
||||||
|
return 0 |
||||||
|
fi |
||||||
|
local sketches=$(find $examples -name *.ino) |
||||||
|
local sketchnum=0 |
||||||
|
for sketch in $sketches; do |
||||||
|
local sketchdir=$(dirname $sketch) |
||||||
|
local sketchdirname=$(basename $sketchdir) |
||||||
|
local sketchname=$(basename $sketch) |
||||||
|
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then |
||||||
|
continue |
||||||
|
fi; |
||||||
|
if [[ -f "$sketchdir/.test.skip" ]]; then |
||||||
|
continue |
||||||
|
fi |
||||||
|
echo $sketch >> sketches.txt |
||||||
|
sketchnum=$(($sketchnum + 1)) |
||||||
|
done |
||||||
|
return $sketchnum |
||||||
|
} |
||||||
|
|
||||||
|
function build_sketches() # build_sketches <fqbn> <examples-path> <chunk> <total-chunks> [extra-options] |
||||||
|
{ |
||||||
|
local fqbn=$1 |
||||||
|
local examples=$2 |
||||||
|
local chunk_idex=$3 |
||||||
|
local chunks_num=$4 |
||||||
|
local xtra_opts=$5 |
||||||
|
|
||||||
|
if [ "$#" -lt 2 ]; then |
||||||
|
echo "ERROR: Illegal number of parameters" |
||||||
|
echo "USAGE: build_sketches <fqbn> <examples-path> [<chunk> <total-chunks>] [extra-options]" |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$#" -lt 4 ]; then |
||||||
|
chunk_idex="0" |
||||||
|
chunks_num="1" |
||||||
|
xtra_opts=$3 |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$chunks_num" -le 0 ]; then |
||||||
|
echo "ERROR: Chunks count must be positive number" |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
if [ "$chunk_idex" -ge "$chunks_num" ]; then |
||||||
|
echo "ERROR: Chunk index must be less than chunks count" |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
|
||||||
|
set +e |
||||||
|
count_sketches "$examples" |
||||||
|
local sketchcount=$? |
||||||
|
set -e |
||||||
|
local sketches=$(cat sketches.txt) |
||||||
|
rm -rf sketches.txt |
||||||
|
|
||||||
|
local chunk_size=$(( $sketchcount / $chunks_num )) |
||||||
|
local all_chunks=$(( $chunks_num * $chunk_size )) |
||||||
|
if [ "$all_chunks" -lt "$sketchcount" ]; then |
||||||
|
chunk_size=$(( $chunk_size + 1 )) |
||||||
|
fi |
||||||
|
|
||||||
|
local start_index=$(( $chunk_idex * $chunk_size )) |
||||||
|
if [ "$sketchcount" -le "$start_index" ]; then |
||||||
|
echo "Skipping job" |
||||||
|
return 0 |
||||||
|
fi |
||||||
|
|
||||||
|
local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) |
||||||
|
if [ "$end_index" -gt "$sketchcount" ]; then |
||||||
|
end_index=$sketchcount |
||||||
|
fi |
||||||
|
|
||||||
|
local start_num=$(( $start_index + 1 )) |
||||||
|
echo "Found $sketchcount Sketches"; |
||||||
|
echo "Chunk Count : $chunks_num" |
||||||
|
echo "Chunk Size : $chunk_size" |
||||||
|
echo "Start Sketch: $start_num" |
||||||
|
echo "End Sketch : $end_index" |
||||||
|
|
||||||
|
local sketchnum=0 |
||||||
|
for sketch in $sketches; do |
||||||
|
local sketchdir=$(dirname $sketch) |
||||||
|
local sketchdirname=$(basename $sketchdir) |
||||||
|
local sketchname=$(basename $sketch) |
||||||
|
if [ "${sketchdirname}.ino" != "$sketchname" ] \ |
||||||
|
|| [ -f "$sketchdir/.test.skip" ]; then |
||||||
|
continue |
||||||
|
fi |
||||||
|
sketchnum=$(($sketchnum + 1)) |
||||||
|
if [ "$sketchnum" -le "$start_index" ] \ |
||||||
|
|| [ "$sketchnum" -gt "$end_index" ]; then |
||||||
|
continue |
||||||
|
fi |
||||||
|
build_sketch "$fqbn" "$sketch" "$xtra_opts" |
||||||
|
local result=$? |
||||||
|
if [ $result -ne 0 ]; then |
||||||
|
return $result |
||||||
|
fi |
||||||
|
done |
||||||
|
return 0 |
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
echo "Installing Python Wheel ..." |
||||||
|
pip install wheel > /dev/null 2>&1 |
||||||
|
|
||||||
|
echo "Installing PlatformIO ..." |
||||||
|
pip install -U platformio > /dev/null 2>&1 |
||||||
|
|
||||||
|
echo "PlatformIO has been installed" |
||||||
|
echo "" |
||||||
|
|
||||||
|
|
||||||
|
function build_pio_sketch(){ # build_pio_sketch <board> <path-to-ino> |
||||||
|
if [ "$#" -lt 2 ]; then |
||||||
|
echo "ERROR: Illegal number of parameters" |
||||||
|
echo "USAGE: build_pio_sketch <board> <path-to-ino>" |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
|
||||||
|
local board="$1" |
||||||
|
local sketch="$2" |
||||||
|
local sketch_dir=$(dirname "$sketch") |
||||||
|
echo "" |
||||||
|
echo "Compiling '"$(basename "$sketch")"' ..." |
||||||
|
python -m platformio ci -l '.' --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv" |
||||||
|
} |
||||||
|
|
||||||
|
function count_sketches() # count_sketches <examples-path> |
||||||
|
{ |
||||||
|
local examples="$1" |
||||||
|
rm -rf sketches.txt |
||||||
|
if [ ! -d "$examples" ]; then |
||||||
|
touch sketches.txt |
||||||
|
return 0 |
||||||
|
fi |
||||||
|
local sketches=$(find $examples -name *.ino) |
||||||
|
local sketchnum=0 |
||||||
|
for sketch in $sketches; do |
||||||
|
local sketchdir=$(dirname $sketch) |
||||||
|
local sketchdirname=$(basename $sketchdir) |
||||||
|
local sketchname=$(basename $sketch) |
||||||
|
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then |
||||||
|
continue |
||||||
|
fi; |
||||||
|
if [[ -f "$sketchdir/.test.skip" ]]; then |
||||||
|
continue |
||||||
|
fi |
||||||
|
echo $sketch >> sketches.txt |
||||||
|
sketchnum=$(($sketchnum + 1)) |
||||||
|
done |
||||||
|
return $sketchnum |
||||||
|
} |
||||||
|
|
||||||
|
function build_pio_sketches() # build_pio_sketches <board> <examples-path> <chunk> <total-chunks> |
||||||
|
{ |
||||||
|
if [ "$#" -lt 2 ]; then |
||||||
|
echo "ERROR: Illegal number of parameters" |
||||||
|
echo "USAGE: build_pio_sketches <board> <examples-path> [<chunk> <total-chunks>]" |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
|
||||||
|
local board=$1 |
||||||
|
local examples=$2 |
||||||
|
local chunk_idex=$3 |
||||||
|
local chunks_num=$4 |
||||||
|
|
||||||
|
if [ "$#" -lt 4 ]; then |
||||||
|
chunk_idex="0" |
||||||
|
chunks_num="1" |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$chunks_num" -le 0 ]; then |
||||||
|
echo "ERROR: Chunks count must be positive number" |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
if [ "$chunk_idex" -ge "$chunks_num" ]; then |
||||||
|
echo "ERROR: Chunk index must be less than chunks count" |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
|
||||||
|
set +e |
||||||
|
count_sketches "$examples" |
||||||
|
local sketchcount=$? |
||||||
|
set -e |
||||||
|
local sketches=$(cat sketches.txt) |
||||||
|
rm -rf sketches.txt |
||||||
|
|
||||||
|
local chunk_size=$(( $sketchcount / $chunks_num )) |
||||||
|
local all_chunks=$(( $chunks_num * $chunk_size )) |
||||||
|
if [ "$all_chunks" -lt "$sketchcount" ]; then |
||||||
|
chunk_size=$(( $chunk_size + 1 )) |
||||||
|
fi |
||||||
|
|
||||||
|
local start_index=$(( $chunk_idex * $chunk_size )) |
||||||
|
if [ "$sketchcount" -le "$start_index" ]; then |
||||||
|
echo "Skipping job" |
||||||
|
return 0 |
||||||
|
fi |
||||||
|
|
||||||
|
local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) |
||||||
|
if [ "$end_index" -gt "$sketchcount" ]; then |
||||||
|
end_index=$sketchcount |
||||||
|
fi |
||||||
|
|
||||||
|
local start_num=$(( $start_index + 1 )) |
||||||
|
echo "Found $sketchcount Sketches"; |
||||||
|
echo "Chunk Count : $chunks_num" |
||||||
|
echo "Chunk Size : $chunk_size" |
||||||
|
echo "Start Sketch: $start_num" |
||||||
|
echo "End Sketch : $end_index" |
||||||
|
|
||||||
|
local sketchnum=0 |
||||||
|
for sketch in $sketches; do |
||||||
|
local sketchdir=$(dirname $sketch) |
||||||
|
local sketchdirname=$(basename $sketchdir) |
||||||
|
local sketchname=$(basename $sketch) |
||||||
|
if [ "${sketchdirname}.ino" != "$sketchname" ] \ |
||||||
|
|| [ -f "$sketchdir/.test.skip" ]; then |
||||||
|
continue |
||||||
|
fi |
||||||
|
sketchnum=$(($sketchnum + 1)) |
||||||
|
if [ "$sketchnum" -le "$start_index" ] \ |
||||||
|
|| [ "$sketchnum" -gt "$end_index" ]; then |
||||||
|
continue |
||||||
|
fi |
||||||
|
build_pio_sketch "$board" "$sketch" |
||||||
|
local result=$? |
||||||
|
if [ $result -ne 0 ]; then |
||||||
|
return $result |
||||||
|
fi |
||||||
|
done |
||||||
|
return 0 |
||||||
|
} |
@ -0,0 +1,64 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
set -e |
||||||
|
|
||||||
|
if [ ! -z "$TRAVIS_BUILD_DIR" ]; then |
||||||
|
export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR" |
||||||
|
export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG" |
||||||
|
elif [ -z "$GITHUB_WORKSPACE" ]; then |
||||||
|
export GITHUB_WORKSPACE="$PWD" |
||||||
|
export GITHUB_REPOSITORY="me-no-dev/AsyncTCP" |
||||||
|
fi |
||||||
|
|
||||||
|
CHUNK_INDEX=$1 |
||||||
|
CHUNKS_CNT=$2 |
||||||
|
BUILD_PIO=0 |
||||||
|
if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then |
||||||
|
CHUNK_INDEX=0 |
||||||
|
CHUNKS_CNT=1 |
||||||
|
elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ]; then |
||||||
|
CHUNK_INDEX=$CHUNKS_CNT |
||||||
|
elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then |
||||||
|
BUILD_PIO=1 |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$BUILD_PIO" -eq 0 ]; then |
||||||
|
# ArduinoIDE Test |
||||||
|
source ./.github/scripts/install-arduino-ide.sh |
||||||
|
source ./.github/scripts/install-arduino-core-esp32.sh |
||||||
|
|
||||||
|
echo "Installing AsyncTCP ..." |
||||||
|
cp -rf "$GITHUB_WORKSPACE" "$ARDUINO_USR_PATH/libraries/AsyncTCP" |
||||||
|
|
||||||
|
FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app" |
||||||
|
build_sketches "$FQBN" "$GITHUB_WORKSPACE/examples" |
||||||
|
if [ ! "$OS_IS_WINDOWS" == "1" ]; then |
||||||
|
echo "Installing ESPAsyncWebServer ..." |
||||||
|
git clone https://github.com/me-no-dev/ESPAsyncWebServer "$ARDUINO_USR_PATH/libraries/ESPAsyncWebServer" > /dev/null 2>&1 |
||||||
|
|
||||||
|
echo "Installing ArduinoJson ..." |
||||||
|
git clone https://github.com/bblanchon/ArduinoJson "$ARDUINO_USR_PATH/libraries/ArduinoJson" > /dev/null 2>&1 |
||||||
|
|
||||||
|
build_sketches "$FQBN" "$ARDUINO_USR_PATH/libraries/ESPAsyncWebServer/examples" |
||||||
|
fi |
||||||
|
else |
||||||
|
# PlatformIO Test |
||||||
|
source ./.github/scripts/install-platformio.sh |
||||||
|
|
||||||
|
echo "Installing AsyncTCP ..." |
||||||
|
python -m platformio lib --storage-dir "$GITHUB_WORKSPACE" install |
||||||
|
|
||||||
|
BOARD="esp32dev" |
||||||
|
build_pio_sketches "$BOARD" "$GITHUB_WORKSPACE/examples" |
||||||
|
|
||||||
|
if [[ "$OSTYPE" != "cygwin" ]] && [[ "$OSTYPE" != "msys" ]] && [[ "$OSTYPE" != "win32" ]]; then |
||||||
|
echo "Installing ESPAsyncWebServer ..." |
||||||
|
python -m platformio lib -g install https://github.com/me-no-dev/ESPAsyncWebServer.git > /dev/null 2>&1 |
||||||
|
git clone https://github.com/me-no-dev/ESPAsyncWebServer "$HOME/ESPAsyncWebServer" > /dev/null 2>&1 |
||||||
|
|
||||||
|
echo "Installing ArduinoJson ..." |
||||||
|
python -m platformio lib -g install https://github.com/bblanchon/ArduinoJson.git > /dev/null 2>&1 |
||||||
|
|
||||||
|
build_pio_sketches "$BOARD" "$HOME/ESPAsyncWebServer/examples" |
||||||
|
fi |
||||||
|
fi |
@ -0,0 +1,31 @@ |
|||||||
|
# Configuration for probot-stale - https://github.com/probot/stale |
||||||
|
|
||||||
|
daysUntilStale: 60 |
||||||
|
daysUntilClose: 14 |
||||||
|
limitPerRun: 30 |
||||||
|
staleLabel: stale |
||||||
|
exemptLabels: |
||||||
|
- pinned |
||||||
|
- security |
||||||
|
- "to be implemented" |
||||||
|
- "for reference" |
||||||
|
- "move to PR" |
||||||
|
- "enhancement" |
||||||
|
|
||||||
|
only: issues |
||||||
|
onlyLabels: [] |
||||||
|
exemptProjects: false |
||||||
|
exemptMilestones: false |
||||||
|
exemptAssignees: false |
||||||
|
|
||||||
|
markComment: > |
||||||
|
[STALE_SET] This issue has been automatically marked as stale because it has not had |
||||||
|
recent activity. It will be closed in 14 days if no further activity occurs. Thank you |
||||||
|
for your contributions. |
||||||
|
|
||||||
|
unmarkComment: > |
||||||
|
[STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it openin the future. |
||||||
|
|
||||||
|
closeComment: > |
||||||
|
[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions. |
||||||
|
|
@ -0,0 +1,32 @@ |
|||||||
|
name: Async TCP CI |
||||||
|
|
||||||
|
on: |
||||||
|
push: |
||||||
|
branches: |
||||||
|
- master |
||||||
|
- release/* |
||||||
|
pull_request: |
||||||
|
|
||||||
|
jobs: |
||||||
|
|
||||||
|
build-arduino: |
||||||
|
name: Arduino on ${{ matrix.os }} |
||||||
|
runs-on: ${{ matrix.os }} |
||||||
|
strategy: |
||||||
|
matrix: |
||||||
|
os: [ubuntu-latest, macOS-latest] |
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v1 |
||||||
|
- name: Build Tests |
||||||
|
run: bash ./.github/scripts/on-push.sh 0 1 |
||||||
|
|
||||||
|
build-pio: |
||||||
|
name: PlatformIO on ${{ matrix.os }} |
||||||
|
runs-on: ${{ matrix.os }} |
||||||
|
strategy: |
||||||
|
matrix: |
||||||
|
os: [ubuntu-latest, macOS-latest] |
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v1 |
||||||
|
- name: Build Tests |
||||||
|
run: bash ./.github/scripts/on-push.sh 1 1 |
@ -0,0 +1,34 @@ |
|||||||
|
sudo: false |
||||||
|
language: python |
||||||
|
os: |
||||||
|
- linux |
||||||
|
|
||||||
|
git: |
||||||
|
depth: false |
||||||
|
|
||||||
|
stages: |
||||||
|
- build |
||||||
|
|
||||||
|
jobs: |
||||||
|
include: |
||||||
|
|
||||||
|
- name: "Arduino Build" |
||||||
|
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) |
||||||
|
stage: build |
||||||
|
script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh |
||||||
|
|
||||||
|
- name: "PlatformIO Build" |
||||||
|
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) |
||||||
|
stage: build |
||||||
|
script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 1 1 |
||||||
|
|
||||||
|
notifications: |
||||||
|
email: |
||||||
|
on_success: change |
||||||
|
on_failure: change |
||||||
|
webhooks: |
||||||
|
urls: |
||||||
|
- https://webhooks.gitter.im/e/60e65d0c78ea0a920347 |
||||||
|
on_success: change # options: [always|never|change] default: always |
||||||
|
on_failure: always # options: [always|never|change] default: always |
||||||
|
on_start: false # default: false |
@ -0,0 +1,15 @@ |
|||||||
|
set(COMPONENT_SRCDIRS |
||||||
|
"src" |
||||||
|
) |
||||||
|
|
||||||
|
set(COMPONENT_ADD_INCLUDEDIRS |
||||||
|
"src" |
||||||
|
) |
||||||
|
|
||||||
|
set(COMPONENT_REQUIRES |
||||||
|
"arduino-esp32" |
||||||
|
) |
||||||
|
|
||||||
|
register_component() |
||||||
|
|
||||||
|
target_compile_options(${COMPONENT_TARGET} PRIVATE -fno-rtti) |
@ -0,0 +1,30 @@ |
|||||||
|
menu "AsyncTCP Configuration" |
||||||
|
|
||||||
|
choice ASYNC_TCP_RUNNING_CORE |
||||||
|
bool "Core on which AsyncTCP's thread is running" |
||||||
|
default ASYNC_TCP_RUN_CORE1 |
||||||
|
help |
||||||
|
Select on which core AsyncTCP is running |
||||||
|
|
||||||
|
config ASYNC_TCP_RUN_CORE0 |
||||||
|
bool "CORE 0" |
||||||
|
config ASYNC_TCP_RUN_CORE1 |
||||||
|
bool "CORE 1" |
||||||
|
config ASYNC_TCP_RUN_NO_AFFINITY |
||||||
|
bool "BOTH" |
||||||
|
|
||||||
|
endchoice |
||||||
|
|
||||||
|
config ASYNC_TCP_RUNNING_CORE |
||||||
|
int |
||||||
|
default 0 if ASYNC_TCP_RUN_CORE0 |
||||||
|
default 1 if ASYNC_TCP_RUN_CORE1 |
||||||
|
default -1 if ASYNC_TCP_RUN_NO_AFFINITY |
||||||
|
|
||||||
|
config ASYNC_TCP_USE_WDT |
||||||
|
bool "Enable WDT for the AsyncTCP task" |
||||||
|
default "y" |
||||||
|
help |
||||||
|
Enable WDT for the AsyncTCP task, so it will trigger if a handler is locking the thread. |
||||||
|
|
||||||
|
endmenu |
@ -0,0 +1,165 @@ |
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE |
||||||
|
Version 3, 29 June 2007 |
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> |
||||||
|
Everyone is permitted to copy and distribute verbatim copies |
||||||
|
of this license document, but changing it is not allowed. |
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates |
||||||
|
the terms and conditions of version 3 of the GNU General Public |
||||||
|
License, supplemented by the additional permissions listed below. |
||||||
|
|
||||||
|
0. Additional Definitions. |
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser |
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU |
||||||
|
General Public License. |
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License, |
||||||
|
other than an Application or a Combined Work as defined below. |
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided |
||||||
|
by the Library, but which is not otherwise based on the Library. |
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode |
||||||
|
of using an interface provided by the Library. |
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an |
||||||
|
Application with the Library. The particular version of the Library |
||||||
|
with which the Combined Work was made is also called the "Linked |
||||||
|
Version". |
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the |
||||||
|
Corresponding Source for the Combined Work, excluding any source code |
||||||
|
for portions of the Combined Work that, considered in isolation, are |
||||||
|
based on the Application, and not on the Linked Version. |
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the |
||||||
|
object code and/or source code for the Application, including any data |
||||||
|
and utility programs needed for reproducing the Combined Work from the |
||||||
|
Application, but excluding the System Libraries of the Combined Work. |
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL. |
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License |
||||||
|
without being bound by section 3 of the GNU GPL. |
||||||
|
|
||||||
|
2. Conveying Modified Versions. |
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a |
||||||
|
facility refers to a function or data to be supplied by an Application |
||||||
|
that uses the facility (other than as an argument passed when the |
||||||
|
facility is invoked), then you may convey a copy of the modified |
||||||
|
version: |
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to |
||||||
|
ensure that, in the event an Application does not supply the |
||||||
|
function or data, the facility still operates, and performs |
||||||
|
whatever part of its purpose remains meaningful, or |
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of |
||||||
|
this License applicable to that copy. |
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files. |
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from |
||||||
|
a header file that is part of the Library. You may convey such object |
||||||
|
code under terms of your choice, provided that, if the incorporated |
||||||
|
material is not limited to numerical parameters, data structure |
||||||
|
layouts and accessors, or small macros, inline functions and templates |
||||||
|
(ten or fewer lines in length), you do both of the following: |
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the |
||||||
|
Library is used in it and that the Library and its use are |
||||||
|
covered by this License. |
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license |
||||||
|
document. |
||||||
|
|
||||||
|
4. Combined Works. |
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that, |
||||||
|
taken together, effectively do not restrict modification of the |
||||||
|
portions of the Library contained in the Combined Work and reverse |
||||||
|
engineering for debugging such modifications, if you also do each of |
||||||
|
the following: |
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that |
||||||
|
the Library is used in it and that the Library and its use are |
||||||
|
covered by this License. |
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license |
||||||
|
document. |
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during |
||||||
|
execution, include the copyright notice for the Library among |
||||||
|
these notices, as well as a reference directing the user to the |
||||||
|
copies of the GNU GPL and this license document. |
||||||
|
|
||||||
|
d) Do one of the following: |
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this |
||||||
|
License, and the Corresponding Application Code in a form |
||||||
|
suitable for, and under terms that permit, the user to |
||||||
|
recombine or relink the Application with a modified version of |
||||||
|
the Linked Version to produce a modified Combined Work, in the |
||||||
|
manner specified by section 6 of the GNU GPL for conveying |
||||||
|
Corresponding Source. |
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the |
||||||
|
Library. A suitable mechanism is one that (a) uses at run time |
||||||
|
a copy of the Library already present on the user's computer |
||||||
|
system, and (b) will operate properly with a modified version |
||||||
|
of the Library that is interface-compatible with the Linked |
||||||
|
Version. |
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise |
||||||
|
be required to provide such information under section 6 of the |
||||||
|
GNU GPL, and only to the extent that such information is |
||||||
|
necessary to install and execute a modified version of the |
||||||
|
Combined Work produced by recombining or relinking the |
||||||
|
Application with a modified version of the Linked Version. (If |
||||||
|
you use option 4d0, the Installation Information must accompany |
||||||
|
the Minimal Corresponding Source and Corresponding Application |
||||||
|
Code. If you use option 4d1, you must provide the Installation |
||||||
|
Information in the manner specified by section 6 of the GNU GPL |
||||||
|
for conveying Corresponding Source.) |
||||||
|
|
||||||
|
5. Combined Libraries. |
||||||
|
|
||||||
|
You may place library facilities that are a work based on the |
||||||
|
Library side by side in a single library together with other library |
||||||
|
facilities that are not Applications and are not covered by this |
||||||
|
License, and convey such a combined library under terms of your |
||||||
|
choice, if you do both of the following: |
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based |
||||||
|
on the Library, uncombined with any other library facilities, |
||||||
|
conveyed under the terms of this License. |
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it |
||||||
|
is a work based on the Library, and explaining where to find the |
||||||
|
accompanying uncombined form of the same work. |
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License. |
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions |
||||||
|
of the GNU Lesser General Public License from time to time. Such new |
||||||
|
versions will be similar in spirit to the present version, but may |
||||||
|
differ in detail to address new problems or concerns. |
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the |
||||||
|
Library as you received it specifies that a certain numbered version |
||||||
|
of the GNU Lesser General Public License "or any later version" |
||||||
|
applies to it, you have the option of following the terms and |
||||||
|
conditions either of that published version or of any later version |
||||||
|
published by the Free Software Foundation. If the Library as you |
||||||
|
received it does not specify a version number of the GNU Lesser |
||||||
|
General Public License, you may choose any version of the GNU Lesser |
||||||
|
General Public License ever published by the Free Software Foundation. |
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide |
||||||
|
whether future versions of the GNU Lesser General Public License shall |
||||||
|
apply, that proxy's public statement of acceptance of any version is |
||||||
|
permanent authorization for you to choose that version for the |
||||||
|
Library. |
@ -0,0 +1,13 @@ |
|||||||
|
# AsyncTCP |
||||||
|
[![Build Status](https://travis-ci.org/me-no-dev/AsyncTCP.svg?branch=master)](https://travis-ci.org/me-no-dev/AsyncTCP) ![](https://github.com/me-no-dev/AsyncTCP/workflows/Async%20TCP%20CI/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/2f7e4d1df8b446d192cbfec6dc174d2d)](https://www.codacy.com/manual/me-no-dev/AsyncTCP?utm_source=github.com&utm_medium=referral&utm_content=me-no-dev/AsyncTCP&utm_campaign=Badge_Grade) |
||||||
|
|
||||||
|
### Async TCP Library for ESP32 Arduino |
||||||
|
|
||||||
|
[![Join the chat at https://gitter.im/me-no-dev/ESPAsyncWebServer](https://badges.gitter.im/me-no-dev/ESPAsyncWebServer.svg)](https://gitter.im/me-no-dev/ESPAsyncWebServer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |
||||||
|
|
||||||
|
This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif's ESP32 MCUs. |
||||||
|
|
||||||
|
This library is the base for [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) |
||||||
|
|
||||||
|
## AsyncClient and AsyncServer |
||||||
|
The base classes on which everything else is built. They expose all possible scenarios, but are really raw and require more skills to use. |
@ -0,0 +1,3 @@ |
|||||||
|
COMPONENT_ADD_INCLUDEDIRS := src
|
||||||
|
COMPONENT_SRCDIRS := src
|
||||||
|
CXXFLAGS += -fno-rtti
|
@ -0,0 +1,22 @@ |
|||||||
|
{ |
||||||
|
"name":"AsyncTCP", |
||||||
|
"description":"Asynchronous TCP Library for ESP32", |
||||||
|
"keywords":"async,tcp", |
||||||
|
"authors": |
||||||
|
{ |
||||||
|
"name": "Hristo Gochkov", |
||||||
|
"maintainer": true |
||||||
|
}, |
||||||
|
"repository": |
||||||
|
{ |
||||||
|
"type": "git", |
||||||
|
"url": "https://github.com/me-no-dev/AsyncTCP.git" |
||||||
|
}, |
||||||
|
"version": "1.1.1", |
||||||
|
"license": "LGPL-3.0", |
||||||
|
"frameworks": "arduino", |
||||||
|
"platforms": "espressif32", |
||||||
|
"build": { |
||||||
|
"libCompatMode": 2 |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
name=AsyncTCP |
||||||
|
version=1.1.1 |
||||||
|
author=Me-No-Dev |
||||||
|
maintainer=Me-No-Dev |
||||||
|
sentence=Async TCP Library for ESP32 |
||||||
|
paragraph=Async TCP Library for ESP32 |
||||||
|
category=Other |
||||||
|
url=https://github.com/me-no-dev/AsyncTCP |
||||||
|
architectures=* |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,217 @@ |
|||||||
|
/*
|
||||||
|
Asynchronous TCP library for Espressif MCUs |
||||||
|
|
||||||
|
Copyright (c) 2016 Hristo Gochkov. All rights reserved. |
||||||
|
This file is part of the esp8266 core for Arduino environment. |
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or |
||||||
|
modify it under the terms of the GNU Lesser General Public |
||||||
|
License as published by the Free Software Foundation; either |
||||||
|
version 2.1 of the License, or (at your option) any later version. |
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
Lesser General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public |
||||||
|
License along with this library; if not, write to the Free Software |
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef ASYNCTCP_H_ |
||||||
|
#define ASYNCTCP_H_ |
||||||
|
|
||||||
|
#include "IPAddress.h" |
||||||
|
#include "sdkconfig.h" |
||||||
|
#include <functional> |
||||||
|
extern "C" { |
||||||
|
#include "freertos/semphr.h" |
||||||
|
#include "lwip/pbuf.h" |
||||||
|
} |
||||||
|
|
||||||
|
//If core is not defined, then we are running in Arduino or PIO
|
||||||
|
#ifndef CONFIG_ASYNC_TCP_RUNNING_CORE |
||||||
|
#define CONFIG_ASYNC_TCP_RUNNING_CORE -1 //any available core
|
||||||
|
#define CONFIG_ASYNC_TCP_USE_WDT 1 //if enabled, adds between 33us and 200us per event
|
||||||
|
#endif |
||||||
|
|
||||||
|
class AsyncClient; |
||||||
|
|
||||||
|
#define ASYNC_MAX_ACK_TIME 5000 |
||||||
|
#define ASYNC_WRITE_FLAG_COPY 0x01 //will allocate new buffer to hold the data while sending (else will hold reference to the data given)
|
||||||
|
#define ASYNC_WRITE_FLAG_MORE 0x02 //will not send PSH flag, meaning that there should be more data to be sent before the application should react.
|
||||||
|
|
||||||
|
typedef std::function<void(void*, AsyncClient*)> AcConnectHandler; |
||||||
|
typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)> AcAckHandler; |
||||||
|
typedef std::function<void(void*, AsyncClient*, int8_t error)> AcErrorHandler; |
||||||
|
typedef std::function<void(void*, AsyncClient*, void *data, size_t len)> AcDataHandler; |
||||||
|
typedef std::function<void(void*, AsyncClient*, struct pbuf *pb)> AcPacketHandler; |
||||||
|
typedef std::function<void(void*, AsyncClient*, uint32_t time)> AcTimeoutHandler; |
||||||
|
|
||||||
|
struct tcp_pcb; |
||||||
|
struct ip_addr; |
||||||
|
|
||||||
|
class AsyncClient { |
||||||
|
public: |
||||||
|
AsyncClient(tcp_pcb* pcb = 0); |
||||||
|
~AsyncClient(); |
||||||
|
|
||||||
|
AsyncClient & operator=(const AsyncClient &other); |
||||||
|
AsyncClient & operator+=(const AsyncClient &other); |
||||||
|
|
||||||
|
bool operator==(const AsyncClient &other); |
||||||
|
|
||||||
|
bool operator!=(const AsyncClient &other) { |
||||||
|
return !(*this == other); |
||||||
|
} |
||||||
|
bool connect(IPAddress ip, uint16_t port); |
||||||
|
bool connect(const char* host, uint16_t port); |
||||||
|
void close(bool now = false); |
||||||
|
void stop(); |
||||||
|
int8_t abort(); |
||||||
|
bool free(); |
||||||
|
|
||||||
|
bool canSend();//ack is not pending
|
||||||
|
size_t space();//space available in the TCP window
|
||||||
|
size_t add(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY);//add for sending
|
||||||
|
bool send();//send all data added with the method above
|
||||||
|
|
||||||
|
//write equals add()+send()
|
||||||
|
size_t write(const char* data); |
||||||
|
size_t write(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY); //only when canSend() == true
|
||||||
|
|
||||||
|
uint8_t state(); |
||||||
|
bool connecting(); |
||||||
|
bool connected(); |
||||||
|
bool disconnecting(); |
||||||
|
bool disconnected(); |
||||||
|
bool freeable();//disconnected or disconnecting
|
||||||
|
|
||||||
|
uint16_t getMss(); |
||||||
|
|
||||||
|
uint32_t getRxTimeout(); |
||||||
|
void setRxTimeout(uint32_t timeout);//no RX data timeout for the connection in seconds
|
||||||
|
|
||||||
|
uint32_t getAckTimeout(); |
||||||
|
void setAckTimeout(uint32_t timeout);//no ACK timeout for the last sent packet in milliseconds
|
||||||
|
|
||||||
|
void setNoDelay(bool nodelay); |
||||||
|
bool getNoDelay(); |
||||||
|
|
||||||
|
uint32_t getRemoteAddress(); |
||||||
|
uint16_t getRemotePort(); |
||||||
|
uint32_t getLocalAddress(); |
||||||
|
uint16_t getLocalPort(); |
||||||
|
|
||||||
|
//compatibility
|
||||||
|
IPAddress remoteIP(); |
||||||
|
uint16_t remotePort(); |
||||||
|
IPAddress localIP(); |
||||||
|
uint16_t localPort(); |
||||||
|
|
||||||
|
void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect
|
||||||
|
void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected
|
||||||
|
void onAck(AcAckHandler cb, void* arg = 0); //ack received
|
||||||
|
void onError(AcErrorHandler cb, void* arg = 0); //unsuccessful connect or error
|
||||||
|
void onData(AcDataHandler cb, void* arg = 0); //data received (called if onPacket is not used)
|
||||||
|
void onPacket(AcPacketHandler cb, void* arg = 0); //data received
|
||||||
|
void onTimeout(AcTimeoutHandler cb, void* arg = 0); //ack timeout
|
||||||
|
void onPoll(AcConnectHandler cb, void* arg = 0); //every 125ms when connected
|
||||||
|
|
||||||
|
void ackPacket(struct pbuf * pb);//ack pbuf from onPacket
|
||||||
|
size_t ack(size_t len); //ack data that you have not acked using the method below
|
||||||
|
void ackLater(){ _ack_pcb = false; } //will not ack the current packet. Call from onData
|
||||||
|
|
||||||
|
const char * errorToString(int8_t error); |
||||||
|
const char * stateToString(); |
||||||
|
|
||||||
|
//Do not use any of the functions below!
|
||||||
|
static int8_t _s_poll(void *arg, struct tcp_pcb *tpcb); |
||||||
|
static int8_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, int8_t err); |
||||||
|
static int8_t _s_fin(void *arg, struct tcp_pcb *tpcb, int8_t err); |
||||||
|
static int8_t _s_lwip_fin(void *arg, struct tcp_pcb *tpcb, int8_t err); |
||||||
|
static void _s_error(void *arg, int8_t err); |
||||||
|
static int8_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len); |
||||||
|
static int8_t _s_connected(void* arg, void* tpcb, int8_t err); |
||||||
|
static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg); |
||||||
|
|
||||||
|
int8_t _recv(tcp_pcb* pcb, pbuf* pb, int8_t err); |
||||||
|
tcp_pcb * pcb(){ return _pcb; } |
||||||
|
|
||||||
|
protected: |
||||||
|
tcp_pcb* _pcb; |
||||||
|
int8_t _closed_slot; |
||||||
|
|
||||||
|
AcConnectHandler _connect_cb; |
||||||
|
void* _connect_cb_arg; |
||||||
|
AcConnectHandler _discard_cb; |
||||||
|
void* _discard_cb_arg; |
||||||
|
AcAckHandler _sent_cb; |
||||||
|
void* _sent_cb_arg; |
||||||
|
AcErrorHandler _error_cb; |
||||||
|
void* _error_cb_arg; |
||||||
|
AcDataHandler _recv_cb; |
||||||
|
void* _recv_cb_arg; |
||||||
|
AcPacketHandler _pb_cb; |
||||||
|
void* _pb_cb_arg; |
||||||
|
AcTimeoutHandler _timeout_cb; |
||||||
|
void* _timeout_cb_arg; |
||||||
|
AcConnectHandler _poll_cb; |
||||||
|
void* _poll_cb_arg; |
||||||
|
|
||||||
|
bool _pcb_busy; |
||||||
|
uint32_t _pcb_sent_at; |
||||||
|
bool _ack_pcb; |
||||||
|
uint32_t _rx_ack_len; |
||||||
|
uint32_t _rx_last_packet; |
||||||
|
uint32_t _rx_since_timeout; |
||||||
|
uint32_t _ack_timeout; |
||||||
|
uint16_t _connect_port; |
||||||
|
|
||||||
|
int8_t _close(); |
||||||
|
void _free_closed_slot(); |
||||||
|
void _allocate_closed_slot(); |
||||||
|
int8_t _connected(void* pcb, int8_t err); |
||||||
|
void _error(int8_t err); |
||||||
|
int8_t _poll(tcp_pcb* pcb); |
||||||
|
int8_t _sent(tcp_pcb* pcb, uint16_t len); |
||||||
|
int8_t _fin(tcp_pcb* pcb, int8_t err); |
||||||
|
int8_t _lwip_fin(tcp_pcb* pcb, int8_t err); |
||||||
|
void _dns_found(struct ip_addr *ipaddr); |
||||||
|
|
||||||
|
public: |
||||||
|
AsyncClient* prev; |
||||||
|
AsyncClient* next; |
||||||
|
}; |
||||||
|
|
||||||
|
class AsyncServer { |
||||||
|
public: |
||||||
|
AsyncServer(IPAddress addr, uint16_t port); |
||||||
|
AsyncServer(uint16_t port); |
||||||
|
~AsyncServer(); |
||||||
|
void onClient(AcConnectHandler cb, void* arg); |
||||||
|
void begin(); |
||||||
|
void end(); |
||||||
|
void setNoDelay(bool nodelay); |
||||||
|
bool getNoDelay(); |
||||||
|
uint8_t status(); |
||||||
|
|
||||||
|
//Do not use any of the functions below!
|
||||||
|
static int8_t _s_accept(void *arg, tcp_pcb* newpcb, int8_t err); |
||||||
|
static int8_t _s_accepted(void *arg, AsyncClient* client); |
||||||
|
|
||||||
|
protected: |
||||||
|
uint16_t _port; |
||||||
|
IPAddress _addr; |
||||||
|
bool _noDelay; |
||||||
|
tcp_pcb* _pcb; |
||||||
|
AcConnectHandler _connect_cb; |
||||||
|
void* _connect_cb_arg; |
||||||
|
|
||||||
|
int8_t _accept(tcp_pcb* newpcb, int8_t err); |
||||||
|
int8_t _accepted(AsyncClient* client); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
#endif /* ASYNCTCP_H_ */ |
@ -0,0 +1,33 @@ |
|||||||
|
# License Summary for Repository |
||||||
|
``` |
||||||
|
Important Notice: |
||||||
|
Changes, suggestions and commits in this repository may only be done putting them |
||||||
|
under the same license of the respective file. |
||||||
|
All rights of the respective copyright holders shall be reserved. |
||||||
|
Brands and product names are trademarks of their respective owners. |
||||||
|
Referred and linked files/pages are out-of-scope of this repository and underly |
||||||
|
their respective licenses. |
||||||
|
``` |
||||||
|
## License |
||||||
|
|
||||||
|
Copyright (c) 2018 Infineon Technologies AG |
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the |
||||||
|
following conditions are met: |
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright notice, this list of conditions and the following |
||||||
|
disclaimer. |
||||||
|
|
||||||
|
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following |
||||||
|
disclaimer in the documentation and/or other materials provided with the distribution. |
||||||
|
|
||||||
|
Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote |
||||||
|
products derived from this software without specific prior written permission. |
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||||||
|
WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,70 @@ |
|||||||
|
# DPS310-Digital-Pressure-Sensor |
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/Infineon/DPS310-Pressure-Sensor.svg?branch=master)](https://travis-ci.org/Infineon/DPS310-Pressure-Sensor) |
||||||
|
|
||||||
|
<img src="https://github.com/Infineon/Assets/blob/master/Pictures/DPS310_PP.jpg" width=150><img src="https://github.com/Infineon/Assets/blob/master/Pictures/DPS310-Pressure-Shield2Go_Top.png" width=300> |
||||||
|
|
||||||
|
Library of Infineon's highly sensitive [DPS310 sensor](https://www.infineon.com/cms/de/product/sensor/capacitive-pressure-sensor-for-consumer-applications/DPS310/productType.html?productType=5546d462525dbac4015312b96a743801) for Arduino. |
||||||
|
|
||||||
|
## Summary |
||||||
|
|
||||||
|
The [DPS310](https://www.infineon.com/dgdl/Infineon-DPS310-DS-v01_00-EN.pdf?fileId=5546d462576f34750157750826c42242) is a miniaturized digital barometric air pressure sensor with a high accuracy and a low current consumption, capable of measuring both pressure and temperature. The internal signal processor converts the output from the pressure and temperature sensor elements to 24 bit results. Each unit is individually calibrated, the calibration coefficients calculated during this process are stored in the calibration registers. The available raw data of the sensor can be calibrated by using the pre-calibrated coefficients as they are used in the application to convert the measurement results to high accuracy pressure and temperature values. |
||||||
|
|
||||||
|
Sensor measurements and calibration coefficients are available through the serial I2C or SPI interface. |
||||||
|
|
||||||
|
## Key Features and Applications |
||||||
|
* Supply voltage range 1.7V to 3.6V |
||||||
|
* Operation range 300hPa – 1200hPa |
||||||
|
* Sensor’s precision 0.005hPa |
||||||
|
* Relative accuracy ±0.06hPa |
||||||
|
* Pressure temperature sensitivity of 0.5Pa/K |
||||||
|
* Temperature accuracy ±0.5C° |
||||||
|
* Applications |
||||||
|
* Wearable applications, sport and fitness activities tracking |
||||||
|
* Drones automatic pilot, fix point flying |
||||||
|
* Indoor navigation, altitude metering |
||||||
|
|
||||||
|
## Installation |
||||||
|
|
||||||
|
### Integration of Library |
||||||
|
|
||||||
|
Please download this repository from GitHub by clicking on the following field in the latest [release](https://github.com/Infineon/DPS310-Pressure-Sensor/releases) of this repository: |
||||||
|
|
||||||
|
![Download Library](https://raw.githubusercontent.com/infineon/assets/master/Pictures/Releases_Generic.jpg) |
||||||
|
|
||||||
|
To install the DPS310 pressure sensor library in the Arduino IDE, please go now to **Sketch** > **Include Library** > **Add .ZIP Library...** in the Arduino IDE and navigate to the downloaded .ZIP file of this repository. The library will be installed in your Arduino sketch folder in libraries and you can select as well as include this one to your project under **Sketch** > **Include Library** > **DPS310**. |
||||||
|
|
||||||
|
![Install Library](https://raw.githubusercontent.com/infineon/assets/master/Pictures/Library_Install_ZIP.png) |
||||||
|
|
||||||
|
## Usage |
||||||
|
Please see the example sketches in the `/examples` directory in this library to learn more about the usage of the library. Especially, take care of the respective SPI and I²C configuration of the sensor. |
||||||
|
For more information, please consult the datasheet [here](https://www.infineon.com/dgdl/Infineon-DPS310-DS-v01_00-EN.pdf?fileId=5546d462576f34750157750826c42242). |
||||||
|
|
||||||
|
Currently, there exists the DPS310 Pressure Shield2Go evaluation board as a break out board: |
||||||
|
|
||||||
|
* [DPS310 Pressure Shield2Go](https://www.infineon.com/cms/de/product/evaluation-boards/s2go-pressure-dps310/) |
||||||
|
|
||||||
|
### DPS310 Pressure Shield2Go |
||||||
|
The DPS310 Pressure Shield2Go is a standalone break out board with Infineon's Shield2Go formfactor and pin out. You can connect it easily to any microcontroller of your choice which is Arduino compatible and has 3.3 V logic level (please note that the Arduino UNO has 5 V logic level and cannot be used without level shifting). |
||||||
|
Please consult the [wiki](https://github.com/Infineon/DPS310-Pressure-Sensor/wiki) for additional details about the board. |
||||||
|
|
||||||
|
Each sensor can only work either SPI or I2C. To convert from SPI to I2C, for example, you have to re-solder the resistors on the Shield2Go. Please take care that every Shield2Go for the DPS310 is shipped as I2C configuration right now. |
||||||
|
|
||||||
|
* [Link](https://github.com/Infineon/DPS310-Pressure-Sensor/wiki) to the wiki with more information |
||||||
|
|
||||||
|
However, every Shield2Go is directly compatible with Infineon's XMC2Go and the recommended quick start is to use an XMC2Go for evaluation. Therefore, please install (if not already done) also the [XMC-for-Arduino](https://github.com/Infineon/XMC-for-Arduino) implementation and choose afterwards **XMC1100 XMC2Go** from the **Tools**>**Board** menu in the Arduino IDE if working with this evaluation board. To use it, please plug the DPS310 Pressure Shield2Go onto the XMC2Go as shown below. |
||||||
|
|
||||||
|
<img src="https://github.com/Infineon/Assets/blob/master/Pictures/DPS310_S2Go_w_XMC2Go.png" width=250> |
||||||
|
|
||||||
|
## Known Issues |
||||||
|
|
||||||
|
### Temperature Measurement Issue |
||||||
|
There could be a problem with temperature measurement of the DPS310. If your DPS310 indicates a temperature around 60 °C although you expect around room temperature, e.g. 20 °C, please call the function correctTemp() as included in the library to fix this issue. |
||||||
|
|
||||||
|
In case you need additional help, please do not hesitate to open an issue in this repository. |
||||||
|
|
||||||
|
### Interrupt mode |
||||||
|
Interrupt mode not working reliably on XMC2Go for DPS310 right now. |
||||||
|
|
||||||
|
### Additional Information |
||||||
|
Please find the datasheet of the DPS310 [here](https://www.infineon.com/dgdl/Infineon-DPS310-DS-v01_00-EN.pdf?fileId=5546d462576f34750157750826c42242). It depends on the evaluation board which you are using or the respective configuration of the sensor on your PCB which communication protocol as well as addresses you need to use for communicating with the sensor. |
@ -0,0 +1,98 @@ |
|||||||
|
#include <Dps310.h> |
||||||
|
|
||||||
|
// Dps310 Opject
|
||||||
|
Dps310 Dps310PressureSensor = Dps310(); |
||||||
|
|
||||||
|
void setup() |
||||||
|
{ |
||||||
|
Serial.begin(9600); |
||||||
|
while (!Serial); |
||||||
|
|
||||||
|
//Call begin to initialize Dps310PressureSensor
|
||||||
|
//The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given.
|
||||||
|
//Dps310PressureSensor.begin(Wire, 0x76);
|
||||||
|
//Use the commented line below instead to use the default I2C address.
|
||||||
|
Dps310PressureSensor.begin(Wire); |
||||||
|
|
||||||
|
//temperature measure rate (value from 0 to 7)
|
||||||
|
//2^temp_mr temperature measurement results per second
|
||||||
|
int16_t temp_mr = 2; |
||||||
|
//temperature oversampling rate (value from 0 to 7)
|
||||||
|
//2^temp_osr internal temperature measurements per result
|
||||||
|
//A higher value increases precision
|
||||||
|
int16_t temp_osr = 2; |
||||||
|
//pressure measure rate (value from 0 to 7)
|
||||||
|
//2^prs_mr pressure measurement results per second
|
||||||
|
int16_t prs_mr = 2; |
||||||
|
//pressure oversampling rate (value from 0 to 7)
|
||||||
|
//2^prs_osr internal pressure measurements per result
|
||||||
|
//A higher value increases precision
|
||||||
|
int16_t prs_osr = 2; |
||||||
|
//startMeasureBothCont enables background mode
|
||||||
|
//temperature and pressure ar measured automatically
|
||||||
|
//High precision and hgh measure rates at the same time are not available.
|
||||||
|
//Consult Datasheet (or trial and error) for more information
|
||||||
|
int16_t ret = Dps310PressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); |
||||||
|
//Use one of the commented lines below instead to measure only temperature or pressure
|
||||||
|
//int16_t ret = Dps310PressureSensor.startMeasureTempCont(temp_mr, temp_osr);
|
||||||
|
//int16_t ret = Dps310PressureSensor.startMeasurePressureCont(prs_mr, prs_osr);
|
||||||
|
|
||||||
|
|
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
Serial.print("Init FAILED! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.println("Init complete!"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void loop() |
||||||
|
{ |
||||||
|
uint8_t pressureCount = 20; |
||||||
|
float pressure[pressureCount]; |
||||||
|
uint8_t temperatureCount = 20; |
||||||
|
float temperature[temperatureCount]; |
||||||
|
|
||||||
|
//This function writes the results of continuous measurements to the arrays given as parameters
|
||||||
|
//The parameters temperatureCount and pressureCount should hold the sizes of the arrays temperature and pressure when the function is called
|
||||||
|
//After the end of the function, temperatureCount and pressureCount hold the numbers of values written to the arrays
|
||||||
|
//Note: The Dps310 cannot save more than 32 results. When its result buffer is full, it won't save any new measurement results
|
||||||
|
int16_t ret = Dps310PressureSensor.getContResults(temperature, temperatureCount, pressure, pressureCount); |
||||||
|
|
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
Serial.println(); |
||||||
|
Serial.println(); |
||||||
|
Serial.print("FAIL! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.println(); |
||||||
|
Serial.println(); |
||||||
|
Serial.print(temperatureCount); |
||||||
|
Serial.println(" temperature values found: "); |
||||||
|
for (int16_t i = 0; i < temperatureCount; i++) |
||||||
|
{ |
||||||
|
Serial.print(temperature[i]); |
||||||
|
Serial.println(" degrees of Celsius"); |
||||||
|
} |
||||||
|
|
||||||
|
Serial.println(); |
||||||
|
Serial.print(pressureCount); |
||||||
|
Serial.println(" pressure values found: "); |
||||||
|
for (int16_t i = 0; i < pressureCount; i++) |
||||||
|
{ |
||||||
|
Serial.print(pressure[i]); |
||||||
|
Serial.println(" Pascal"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//Wait some time, so that the Dps310 can refill its buffer
|
||||||
|
delay(10000); |
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
#include <Dps310.h> |
||||||
|
|
||||||
|
// Dps310 Opject
|
||||||
|
Dps310 Dps310PressureSensor = Dps310(); |
||||||
|
|
||||||
|
void setup() |
||||||
|
{ |
||||||
|
Serial.begin(9600); |
||||||
|
while (!Serial); |
||||||
|
|
||||||
|
|
||||||
|
//Call begin to initialize Dps310PressureSensor
|
||||||
|
//The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given.
|
||||||
|
//Dps310PressureSensor.begin(Wire, 0x76);
|
||||||
|
//Use the commented line below instead of the one above to use the default I2C address.
|
||||||
|
//if you are using the Pressure 3 click Board, you need 0x76
|
||||||
|
Dps310PressureSensor.begin(Wire); |
||||||
|
|
||||||
|
Serial.println("Init complete!"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void loop() |
||||||
|
{ |
||||||
|
float temperature; |
||||||
|
float pressure; |
||||||
|
uint8_t oversampling = 7; |
||||||
|
int16_t ret; |
||||||
|
Serial.println(); |
||||||
|
|
||||||
|
//lets the Dps310 perform a Single temperature measurement with the last (or standard) configuration
|
||||||
|
//The result will be written to the paramerter temperature
|
||||||
|
//ret = Dps310PressureSensor.measureTempOnce(temperature);
|
||||||
|
//the commented line below does exactly the same as the one above, but you can also config the precision
|
||||||
|
//oversampling can be a value from 0 to 7
|
||||||
|
//the Dps 310 will perform 2^oversampling internal temperature measurements and combine them to one result with higher precision
|
||||||
|
//measurements with higher precision take more time, consult datasheet for more information
|
||||||
|
ret = Dps310PressureSensor.measureTempOnce(temperature, oversampling); |
||||||
|
|
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
//Something went wrong.
|
||||||
|
//Look at the library code for more information about return codes
|
||||||
|
Serial.print("FAIL! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.print("Temperature: "); |
||||||
|
Serial.print(temperature); |
||||||
|
Serial.println(" degrees of Celsius"); |
||||||
|
} |
||||||
|
|
||||||
|
//Pressure measurement behaves like temperature measurement
|
||||||
|
//ret = Dps310PressureSensor.measurePressureOnce(pressure);
|
||||||
|
ret = Dps310PressureSensor.measurePressureOnce(pressure, oversampling); |
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
//Something went wrong.
|
||||||
|
//Look at the library code for more information about return codes
|
||||||
|
Serial.print("FAIL! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.print("Pressure: "); |
||||||
|
Serial.print(pressure); |
||||||
|
Serial.println(" Pascal"); |
||||||
|
} |
||||||
|
|
||||||
|
//Wait some time
|
||||||
|
delay(500); |
||||||
|
} |
@ -0,0 +1,112 @@ |
|||||||
|
#include <Dps310.h> |
||||||
|
|
||||||
|
// Dps310 Opject
|
||||||
|
Dps310 Dps310PressureSensor = Dps310(); |
||||||
|
|
||||||
|
void onFifoFull(); |
||||||
|
|
||||||
|
const unsigned char pressureLength = 50; |
||||||
|
unsigned char pressureCount = 0; |
||||||
|
float pressure[pressureLength]; |
||||||
|
unsigned char temperatureCount = 0; |
||||||
|
const unsigned char temperatureLength = 50; |
||||||
|
float temperature[temperatureLength]; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setup() |
||||||
|
{ |
||||||
|
Serial.begin(9600); |
||||||
|
while (!Serial); |
||||||
|
|
||||||
|
//Call begin to initialize Dps310PressureSensor
|
||||||
|
//The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given.
|
||||||
|
//Dps310PressureSensor.begin(Wire, 0x76);
|
||||||
|
//Use the commented line below instead to use the default I2C address.
|
||||||
|
Dps310PressureSensor.begin(Wire); |
||||||
|
|
||||||
|
//int16_t ret = Dps310PressureSensor.setInterruptPolarity(1);
|
||||||
|
int16_t ret = Dps310PressureSensor.setInterruptSources(1, 0); |
||||||
|
//clear interrupt flag by reading
|
||||||
|
Dps310PressureSensor.getIntStatusFifoFull(); |
||||||
|
|
||||||
|
//initialization of Interrupt for Controller unit
|
||||||
|
//SDO pin of Dps310 has to be connected with interrupt pin
|
||||||
|
int16_t interruptPin = 3; |
||||||
|
pinMode(interruptPin, INPUT); |
||||||
|
attachInterrupt(digitalPinToInterrupt(interruptPin), onFifoFull, RISING); |
||||||
|
|
||||||
|
//start of a continuous measurement just like before
|
||||||
|
int16_t temp_mr = 3; |
||||||
|
int16_t temp_osr = 2; |
||||||
|
int16_t prs_mr = 1; |
||||||
|
int16_t prs_osr = 3; |
||||||
|
ret = Dps310PressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); |
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
Serial.print("Init FAILED! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.println("Init complete!"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
void loop() |
||||||
|
{ |
||||||
|
//do other stuff
|
||||||
|
Serial.println("loop running"); |
||||||
|
delay(500); |
||||||
|
|
||||||
|
|
||||||
|
//if result arrays are full
|
||||||
|
//This could also be in the interrupt handler, but it would take too much time for a proper ISR
|
||||||
|
if (pressureCount == pressureLength && temperatureCount == temperatureLength) |
||||||
|
{ |
||||||
|
//print results
|
||||||
|
Serial.println(); |
||||||
|
Serial.println(); |
||||||
|
Serial.print(temperatureCount); |
||||||
|
Serial.println(" temperature values found: "); |
||||||
|
for (int16_t i = 0; i < temperatureCount; i++) |
||||||
|
{ |
||||||
|
Serial.print(temperature[i]); |
||||||
|
Serial.println(" degrees of Celsius"); |
||||||
|
} |
||||||
|
Serial.println(); |
||||||
|
Serial.print(pressureCount); |
||||||
|
Serial.println(" pressure values found: "); |
||||||
|
for (int16_t i = 0; i < pressureCount; i++) |
||||||
|
{ |
||||||
|
Serial.print(pressure[i]); |
||||||
|
Serial.println(" Pascal"); |
||||||
|
} |
||||||
|
Serial.println(); |
||||||
|
Serial.println(); |
||||||
|
//reset result counters
|
||||||
|
pressureCount = 0; |
||||||
|
temperatureCount = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
//interrupt handler
|
||||||
|
void onFifoFull() |
||||||
|
{ |
||||||
|
//message for debugging
|
||||||
|
Serial.println("Interrupt handler called"); |
||||||
|
|
||||||
|
//clear interrupt flag by reading
|
||||||
|
Dps310PressureSensor.getIntStatusFifoFull(); |
||||||
|
|
||||||
|
//calculate the number of free indexes in the result arrays
|
||||||
|
uint8_t prs_freespace = pressureLength - pressureCount; |
||||||
|
uint8_t temp_freespace = temperatureLength - temperatureCount; |
||||||
|
//read the results from Dps310, new results will be added at the end of the arrays
|
||||||
|
Dps310PressureSensor.getContResults(&temperature[temperatureCount], temp_freespace, &pressure[pressureCount], prs_freespace); |
||||||
|
//after reading the result counters are increased by the amount of new results
|
||||||
|
pressureCount += prs_freespace; |
||||||
|
temperatureCount += temp_freespace; |
||||||
|
} |
@ -0,0 +1,103 @@ |
|||||||
|
#include <Dps310.h> |
||||||
|
|
||||||
|
// Dps310 Opject
|
||||||
|
Dps310 Dps310PressureSensor = Dps310(); |
||||||
|
|
||||||
|
void setup() |
||||||
|
{ |
||||||
|
//pin number of your slave select line
|
||||||
|
//XMC2GO
|
||||||
|
int16_t pin_cs = 3; |
||||||
|
//for XMC 1100 Bootkit & XMC4700 Relax Kit uncomment the following line
|
||||||
|
//int16_t pin_cs = 10;
|
||||||
|
|
||||||
|
Serial.begin(9600); |
||||||
|
while (!Serial); |
||||||
|
|
||||||
|
|
||||||
|
//Call begin to initialize Dps310
|
||||||
|
//The parameter pin_nr is the number of the CS pin on your Microcontroller
|
||||||
|
Dps310PressureSensor.begin(SPI, pin_cs); |
||||||
|
|
||||||
|
//temperature measure rate (value from 0 to 7)
|
||||||
|
//2^temp_mr temperature measurement results per second
|
||||||
|
int16_t temp_mr = 2; |
||||||
|
//temperature oversampling rate (value from 0 to 7)
|
||||||
|
//2^temp_osr internal temperature measurements per result
|
||||||
|
//A higher value increases precision
|
||||||
|
int16_t temp_osr = 2; |
||||||
|
//pressure measure rate (value from 0 to 7)
|
||||||
|
//2^prs_mr pressure measurement results per second
|
||||||
|
int16_t prs_mr = 2; |
||||||
|
//pressure oversampling rate (value from 0 to 7)
|
||||||
|
//2^prs_osr internal pressure measurements per result
|
||||||
|
//A higher value increases precision
|
||||||
|
int16_t prs_osr = 2; |
||||||
|
//startMeasureBothCont enables background mode
|
||||||
|
//temperature and pressure ar measured automatically
|
||||||
|
//High precision and hgh measure rates at the same time are not available.
|
||||||
|
//Consult Datasheet (or trial and error) for more information
|
||||||
|
int16_t ret = Dps310PressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); |
||||||
|
//Use one of the commented lines below instead to measure only temperature or pressure
|
||||||
|
//int16_t ret = Dps310PressureSensor.startMeasureTempCont(temp_mr, temp_osr);
|
||||||
|
//int16_t ret = Dps310PressureSensor.startMeasurePressureCont(prs_mr, prs_osr);
|
||||||
|
|
||||||
|
|
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
Serial.print("Init FAILED! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.println("Init complete!"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void loop() |
||||||
|
{ |
||||||
|
uint8_t pressureCount = 20; |
||||||
|
float pressure[pressureCount]; |
||||||
|
uint8_t temperatureCount = 20; |
||||||
|
float temperature[temperatureCount]; |
||||||
|
|
||||||
|
//This function writes the results of continuous measurements to the arrays given as parameters
|
||||||
|
//The parameters temperatureCount and pressureCount should hold the sizes of the arrays temperature and pressure when the function is called
|
||||||
|
//After the end of the function, temperatureCount and pressureCount hold the numbers of values written to the arrays
|
||||||
|
//Note: The Dps310 cannot save more than 32 results. When its result buffer is full, it won't save any new measurement results
|
||||||
|
int16_t ret = Dps310PressureSensor.getContResults(temperature, temperatureCount, pressure, pressureCount); |
||||||
|
|
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
Serial.println(); |
||||||
|
Serial.println(); |
||||||
|
Serial.print("FAIL! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.println(); |
||||||
|
Serial.println(); |
||||||
|
Serial.print(temperatureCount); |
||||||
|
Serial.println(" temperature values found: "); |
||||||
|
for (int16_t i = 0; i < temperatureCount; i++) |
||||||
|
{ |
||||||
|
Serial.print(temperature[i]); |
||||||
|
Serial.println(" degrees of Celsius"); |
||||||
|
} |
||||||
|
|
||||||
|
Serial.println(); |
||||||
|
Serial.print(pressureCount); |
||||||
|
Serial.println(" pressure values found: "); |
||||||
|
for (int16_t i = 0; i < pressureCount; i++) |
||||||
|
{ |
||||||
|
Serial.print(pressure[i]); |
||||||
|
Serial.println(" Pascal"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//Wait some time, so that the Dps310 can refill its buffer
|
||||||
|
delay(10000); |
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
#include <Dps310.h> |
||||||
|
|
||||||
|
// Dps310 Opject
|
||||||
|
Dps310 Dps310PressureSensor = Dps310(); |
||||||
|
|
||||||
|
void setup() |
||||||
|
{ |
||||||
|
//pin number of your slave select line
|
||||||
|
//XMC2GO
|
||||||
|
int16_t pin_cs = 3; |
||||||
|
//for XMC 1100 Bootkit & XMC4700 Relax Kit uncomment the following line
|
||||||
|
//int16_t pin_cs = 10;
|
||||||
|
|
||||||
|
Serial.begin(9600); |
||||||
|
while (!Serial); |
||||||
|
|
||||||
|
|
||||||
|
//Call begin to initialize Dps310PressureSensor
|
||||||
|
//The parameter pin_nr is the number of the CS pin on your Microcontroller
|
||||||
|
Dps310PressureSensor.begin(SPI, pin_cs); |
||||||
|
|
||||||
|
Serial.println("Init complete!"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void loop() |
||||||
|
{ |
||||||
|
float temperature; |
||||||
|
float pressure; |
||||||
|
uint8_t oversampling = 7; |
||||||
|
int16_t ret; |
||||||
|
Serial.println(); |
||||||
|
|
||||||
|
//lets the Dps310 perform a Single temperature measurement with the last (or standard) configuration
|
||||||
|
//The result will be written to the paramerter temperature
|
||||||
|
//ret = Dps310PressureSensor.measureTempOnce(temperature);
|
||||||
|
//the commented line below does exactly the same as the one above, but you can also config the precision
|
||||||
|
//oversampling can be a value from 0 to 7
|
||||||
|
//the Dps 310 will perform 2^oversampling internal temperature measurements and combine them to one result with higher precision
|
||||||
|
//measurements with higher precision take more time, consult datasheet for more information
|
||||||
|
ret = Dps310PressureSensor.measureTempOnce(temperature, oversampling); |
||||||
|
|
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
//Something went wrong.
|
||||||
|
//Look at the library code for more information about return codes
|
||||||
|
Serial.print("FAIL! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.print("Temperature: "); |
||||||
|
Serial.print(temperature); |
||||||
|
Serial.println(" degrees of Celsius"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
//ret = Dps310PressureSensor.measurePressureOnce(pressure);
|
||||||
|
ret = Dps310PressureSensor.measurePressureOnce(pressure, oversampling); |
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
//Something went wrong.
|
||||||
|
//Look at the library code for more information about return codes
|
||||||
|
Serial.print("FAIL! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.print("Pressure: "); |
||||||
|
Serial.print(pressure); |
||||||
|
Serial.println(" Pascal"); |
||||||
|
} |
||||||
|
|
||||||
|
//Wait some time
|
||||||
|
delay(1000); |
||||||
|
} |
@ -0,0 +1,130 @@ |
|||||||
|
#include <Dps310.h> |
||||||
|
|
||||||
|
// Dps310 Opject
|
||||||
|
Dps310 Dps310PressureSensor = Dps310(); |
||||||
|
|
||||||
|
void onFifoFull(); |
||||||
|
|
||||||
|
const unsigned char pressureLength = 50; |
||||||
|
unsigned char pressureCount = 0; |
||||||
|
float pressure[pressureLength]; |
||||||
|
unsigned char temperatureCount = 0; |
||||||
|
const unsigned char temperatureLength = 50; |
||||||
|
float temperature[temperatureLength]; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setup() |
||||||
|
{ |
||||||
|
//pin number of your slave select line
|
||||||
|
//XMC2GO
|
||||||
|
int16_t pin_cs = 3; |
||||||
|
//for XMC 1100 Bootkit & XMC4700 Relax Kit uncomment the following line
|
||||||
|
//int16_t pin_cs = 10;
|
||||||
|
|
||||||
|
Serial.begin(9600); |
||||||
|
while (!Serial); |
||||||
|
|
||||||
|
//Call begin to initialize Dps310PressureSensor
|
||||||
|
//The third parameter has to be 1 and enables 3-wire SPI interface
|
||||||
|
//This is necessary, because SDO will be used to indicate interrupts
|
||||||
|
//ATTENTION: Make sure you have connected your MISO and MOSI pins right!
|
||||||
|
// There may NEVER be a direct Connection between MOSI and SDI when 3-wire SPI is enabled
|
||||||
|
// Otherwise, you will cause shortcuts and seriously damage your equipment.
|
||||||
|
// For three wire interface, MISO has to be connected to SDI and there hase to be a resistor between MISO and MOSI
|
||||||
|
// I successfully tested this with a resistor of 1k, but I won't give you any warranty that this works for your equipment too
|
||||||
|
Dps310PressureSensor.begin(SPI, pin_cs, 1); |
||||||
|
|
||||||
|
//config Dps310 for Interrupts
|
||||||
|
// int16_t ret = Dps310PressureSensor.setInterruptPolarity(1);
|
||||||
|
int16_t ret = Dps310PressureSensor.setInterruptSources(1, 0); |
||||||
|
//clear interrupt flag by reading
|
||||||
|
Dps310PressureSensor.getIntStatusFifoFull(); |
||||||
|
|
||||||
|
//initialization of Interrupt for Controller unit
|
||||||
|
//SDO pin of Dps310 has to be connected with interrupt pin
|
||||||
|
int16_t interruptPin = 2; |
||||||
|
pinMode(interruptPin, INPUT); |
||||||
|
Serial.println(digitalPinToInterrupt(interruptPin)); |
||||||
|
attachInterrupt(digitalPinToInterrupt(interruptPin), onFifoFull, RISING); |
||||||
|
|
||||||
|
//start of a continuous measurement just like before
|
||||||
|
int16_t temp_mr = 3; |
||||||
|
int16_t temp_osr = 2; |
||||||
|
int16_t prs_mr = 1; |
||||||
|
int16_t prs_osr = 3; |
||||||
|
ret = Dps310PressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); |
||||||
|
if (ret != 0) |
||||||
|
{ |
||||||
|
Serial.print("Init FAILED! ret = "); |
||||||
|
Serial.println(ret); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
Serial.println("Init complete!"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
void loop() |
||||||
|
{ |
||||||
|
|
||||||
|
//do other stuff
|
||||||
|
Serial.println("loop running"); |
||||||
|
delay(500); |
||||||
|
|
||||||
|
|
||||||
|
//if result arrays are full
|
||||||
|
//This could also be in the interrupt handler, but it would take too much time for an interrupt
|
||||||
|
if (pressureCount == pressureLength && temperatureCount == temperatureLength) |
||||||
|
{ |
||||||
|
//print results
|
||||||
|
Serial.println(); |
||||||
|
Serial.println(); |
||||||
|
Serial.print(temperatureCount); |
||||||
|
Serial.println(" temperature values found: "); |
||||||
|
for (int16_t i = 0; i < temperatureCount; i++) |
||||||
|
{ |
||||||
|
Serial.print(temperature[i]); |
||||||
|
Serial.println(" degrees of Celsius"); |
||||||
|
} |
||||||
|
|
||||||
|
Serial.println(); |
||||||
|
Serial.print(pressureCount); |
||||||
|
Serial.println(" pressure values found: "); |
||||||
|
for (int16_t i = 0; i < pressureCount; i++) |
||||||
|
{ |
||||||
|
Serial.print(pressure[i]); |
||||||
|
Serial.println(" Pascal"); |
||||||
|
} |
||||||
|
Serial.println(); |
||||||
|
Serial.println(); |
||||||
|
|
||||||
|
//reset result counters
|
||||||
|
pressureCount = 0; |
||||||
|
temperatureCount = 0; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
void onFifoFull() |
||||||
|
{ |
||||||
|
//message for debugging
|
||||||
|
Serial.println("Interrupt handler called"); |
||||||
|
|
||||||
|
//clear interrupt flag by reading
|
||||||
|
Dps310PressureSensor.getIntStatusFifoFull(); |
||||||
|
|
||||||
|
//calculate the number of free indexes in the result arrays
|
||||||
|
uint8_t prs_freespace = pressureLength - pressureCount; |
||||||
|
uint8_t temp_freespace = temperatureLength - temperatureCount; |
||||||
|
//read the results from Dps310, new results will be added at the end of the arrays
|
||||||
|
Dps310PressureSensor.getContResults(&temperature[temperatureCount], temp_freespace, &pressure[pressureCount], prs_freespace); |
||||||
|
//after reading the result counters are increased by the amount of new results
|
||||||
|
pressureCount += prs_freespace; |
||||||
|
temperatureCount += temp_freespace; |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
####################################### |
||||||
|
# Syntax Coloring Map For IFX Dps310 |
||||||
|
####################################### |
||||||
|
|
||||||
|
####################################### |
||||||
|
# Datatypes (KEYWORD1) |
||||||
|
####################################### |
||||||
|
|
||||||
|
####################################### |
||||||
|
# Methods and Functions (KEYWORD2) |
||||||
|
####################################### |
||||||
|
|
||||||
|
begin KEYWORD2 |
||||||
|
end KEYWORD2 |
||||||
|
getProductId KEYWORD2 |
||||||
|
getRevisionId KEYWORD2 |
||||||
|
standby KEYWORD2 |
||||||
|
measureTempOnce KEYWORD2 |
||||||
|
startMeasureTempOnce KEYWORD2 |
||||||
|
measurePressureOnce KEYWORD2 |
||||||
|
startMeasurePressureOnce KEYWORD2 |
||||||
|
getSingleResult KEYWORD2 |
||||||
|
startMeasureTempCont KEYWORD2 |
||||||
|
startMeasurePressureCont KEYWORD2 |
||||||
|
startMeasureBothCont KEYWORD2 |
||||||
|
getContResults KEYWORD2 |
||||||
|
setInterruptPolarity KEYWORD2 |
||||||
|
setInterruptSources KEYWORD2 |
||||||
|
getIntFiofoFull KEYWORD2 |
||||||
|
getIntStatusTempReady KEYWORD2 |
||||||
|
getIntStatusPrsReady KEYWORD2 |
||||||
|
correctTemp KEYWORD2 |
||||||
|
|
||||||
|
|
||||||
|
####################################### |
||||||
|
# Instances (KEYWORD2) |
||||||
|
####################################### |
||||||
|
|
||||||
|
Dps310 KEYWORD2 |
||||||
|
|
||||||
|
####################################### |
||||||
|
# Constants (LITERAL1) |
||||||
|
####################################### |
||||||
|
|
@ -0,0 +1,13 @@ |
|||||||
|
{ |
||||||
|
"name": "Digital-Pressure-Sensor", |
||||||
|
"keywords": "barometric, pressure, temperature, sensor, shield2go", |
||||||
|
"description": "Library of Infineon's highly sensitive DPS310 sensor and DPS422 sensor for Arduino.", |
||||||
|
"repository": |
||||||
|
{ |
||||||
|
"type": "git", |
||||||
|
"url": "https://github.com/Infineon/DPS310-Pressure-Sensor.git" |
||||||
|
}, |
||||||
|
"version": "1.0.6", |
||||||
|
"frameworks": "arduino", |
||||||
|
"platforms": "infineonxmc" |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
name=DigitalPressureSensor |
||||||
|
version=1.0.7 |
||||||
|
author=Infineon Technologies |
||||||
|
maintainer=Infineon Technologies <www.infineon.com> |
||||||
|
sentence=This library provides an Interface for Infineon's DPS310 Pressure Sensor. |
||||||
|
paragraph=The DPS series are highly-sensitive pressure sensors (with temperature compensation) that can be connected via SPI or I2C. |
||||||
|
category=Sensors |
||||||
|
url=http://www.infineon.com/cms/de/product/sensor/capacitive-pressure-sensor-for-consumer-applications/DPS310/productType.html?productType=5546d462525dbac4015312b96a743801 |
||||||
|
architectures=* |
@ -0,0 +1,190 @@ |
|||||||
|
#include "Dps310.h" |
||||||
|
|
||||||
|
using namespace dps; |
||||||
|
using namespace dps310; |
||||||
|
|
||||||
|
int16_t Dps310::getContResults(float *tempBuffer, |
||||||
|
uint8_t &tempCount, |
||||||
|
float *prsBuffer, |
||||||
|
uint8_t &prsCount) |
||||||
|
{ |
||||||
|
return DpsClass::getContResults(tempBuffer, tempCount, prsBuffer, prsCount, registers[FIFO_EMPTY]); |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
int16_t Dps310::setInterruptSources(uint8_t intr_source, uint8_t polarity) |
||||||
|
{ |
||||||
|
//Interrupts are not supported with 4 Wire SPI
|
||||||
|
if (!m_SpiI2c & !m_threeWire) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
return writeByteBitfield(intr_source, registers[INT_SEL]) || writeByteBitfield(polarity, registers[INT_HL]); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
void Dps310::init(void) |
||||||
|
{ |
||||||
|
int16_t prodId = readByteBitfield(registers[PROD_ID]); |
||||||
|
if (prodId < 0) |
||||||
|
{ |
||||||
|
//Connected device is not a Dps310
|
||||||
|
m_initFail = 1U; |
||||||
|
return; |
||||||
|
} |
||||||
|
m_productID = prodId; |
||||||
|
|
||||||
|
int16_t revId = readByteBitfield(registers[REV_ID]); |
||||||
|
if (revId < 0) |
||||||
|
{ |
||||||
|
m_initFail = 1U; |
||||||
|
return; |
||||||
|
} |
||||||
|
m_revisionID = revId; |
||||||
|
|
||||||
|
//find out which temperature sensor is calibrated with coefficients...
|
||||||
|
int16_t sensor = readByteBitfield(registers[TEMP_SENSORREC]); |
||||||
|
if (sensor < 0) |
||||||
|
{ |
||||||
|
m_initFail = 1U; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
//...and use this sensor for temperature measurement
|
||||||
|
m_tempSensor = sensor; |
||||||
|
if (writeByteBitfield((uint8_t)sensor, registers[TEMP_SENSOR]) < 0) |
||||||
|
{ |
||||||
|
m_initFail = 1U; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
//read coefficients
|
||||||
|
if (readcoeffs() < 0) |
||||||
|
{ |
||||||
|
m_initFail = 1U; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
//set to standby for further configuration
|
||||||
|
standby(); |
||||||
|
|
||||||
|
//set measurement precision and rate to standard values;
|
||||||
|
configTemp(DPS__MEASUREMENT_RATE_4, DPS__OVERSAMPLING_RATE_8); |
||||||
|
configPressure(DPS__MEASUREMENT_RATE_4, DPS__OVERSAMPLING_RATE_8); |
||||||
|
|
||||||
|
//perform a first temperature measurement
|
||||||
|
//the most recent temperature will be saved internally
|
||||||
|
//and used for compensation when calculating pressure
|
||||||
|
float trash; |
||||||
|
measureTempOnce(trash); |
||||||
|
|
||||||
|
//make sure the DPS310 is in standby after initialization
|
||||||
|
standby(); |
||||||
|
|
||||||
|
// Fix IC with a fuse bit problem, which lead to a wrong temperature
|
||||||
|
// Should not affect ICs without this problem
|
||||||
|
correctTemp(); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t Dps310::readcoeffs(void) |
||||||
|
{ |
||||||
|
// TODO: remove magic number
|
||||||
|
uint8_t buffer[18]; |
||||||
|
//read COEF registers to buffer
|
||||||
|
int16_t ret = readBlock(coeffBlock, buffer); |
||||||
|
|
||||||
|
//compose coefficients from buffer content
|
||||||
|
m_c0Half = ((uint32_t)buffer[0] << 4) | (((uint32_t)buffer[1] >> 4) & 0x0F); |
||||||
|
getTwosComplement(&m_c0Half, 12); |
||||||
|
//c0 is only used as c0*0.5, so c0_half is calculated immediately
|
||||||
|
m_c0Half = m_c0Half / 2U; |
||||||
|
|
||||||
|
//now do the same thing for all other coefficients
|
||||||
|
m_c1 = (((uint32_t)buffer[1] & 0x0F) << 8) | (uint32_t)buffer[2]; |
||||||
|
getTwosComplement(&m_c1, 12); |
||||||
|
m_c00 = ((uint32_t)buffer[3] << 12) | ((uint32_t)buffer[4] << 4) | (((uint32_t)buffer[5] >> 4) & 0x0F); |
||||||
|
getTwosComplement(&m_c00, 20); |
||||||
|
m_c10 = (((uint32_t)buffer[5] & 0x0F) << 16) | ((uint32_t)buffer[6] << 8) | (uint32_t)buffer[7]; |
||||||
|
getTwosComplement(&m_c10, 20); |
||||||
|
|
||||||
|
m_c01 = ((uint32_t)buffer[8] << 8) | (uint32_t)buffer[9]; |
||||||
|
getTwosComplement(&m_c01, 16); |
||||||
|
|
||||||
|
m_c11 = ((uint32_t)buffer[10] << 8) | (uint32_t)buffer[11]; |
||||||
|
getTwosComplement(&m_c11, 16); |
||||||
|
m_c20 = ((uint32_t)buffer[12] << 8) | (uint32_t)buffer[13]; |
||||||
|
getTwosComplement(&m_c20, 16); |
||||||
|
m_c21 = ((uint32_t)buffer[14] << 8) | (uint32_t)buffer[15]; |
||||||
|
getTwosComplement(&m_c21, 16); |
||||||
|
m_c30 = ((uint32_t)buffer[16] << 8) | (uint32_t)buffer[17]; |
||||||
|
getTwosComplement(&m_c30, 16); |
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t Dps310::configTemp(uint8_t tempMr, uint8_t tempOsr) |
||||||
|
{ |
||||||
|
int16_t ret = DpsClass::configTemp(tempMr, tempOsr); |
||||||
|
|
||||||
|
writeByteBitfield(m_tempSensor, registers[TEMP_SENSOR]); |
||||||
|
//set TEMP SHIFT ENABLE if oversampling rate higher than eight(2^3)
|
||||||
|
if (tempOsr > DPS310__OSR_SE) |
||||||
|
{ |
||||||
|
ret = writeByteBitfield(1U, registers[TEMP_SE]); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
ret = writeByteBitfield(0U, registers[TEMP_SE]); |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t Dps310::configPressure(uint8_t prsMr, uint8_t prsOsr) |
||||||
|
{ |
||||||
|
int16_t ret = DpsClass::configPressure(prsMr, prsOsr); |
||||||
|
//set PM SHIFT ENABLE if oversampling rate higher than eight(2^3)
|
||||||
|
if (prsOsr > DPS310__OSR_SE) |
||||||
|
{ |
||||||
|
ret = writeByteBitfield(1U, registers[PRS_SE]); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
ret = writeByteBitfield(0U, registers[PRS_SE]); |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
float Dps310::calcTemp(int32_t raw) |
||||||
|
{ |
||||||
|
float temp = raw; |
||||||
|
|
||||||
|
//scale temperature according to scaling table and oversampling
|
||||||
|
temp /= scaling_facts[m_tempOsr]; |
||||||
|
|
||||||
|
//update last measured temperature
|
||||||
|
//it will be used for pressure compensation
|
||||||
|
m_lastTempScal = temp; |
||||||
|
|
||||||
|
//Calculate compensated temperature
|
||||||
|
temp = m_c0Half + m_c1 * temp; |
||||||
|
|
||||||
|
return temp; |
||||||
|
} |
||||||
|
|
||||||
|
float Dps310::calcPressure(int32_t raw) |
||||||
|
{ |
||||||
|
float prs = raw; |
||||||
|
|
||||||
|
//scale pressure according to scaling table and oversampling
|
||||||
|
prs /= scaling_facts[m_prsOsr]; |
||||||
|
|
||||||
|
//Calculate compensated pressure
|
||||||
|
prs = m_c00 + prs * (m_c10 + prs * (m_c20 + prs * m_c30)) + m_lastTempScal * (m_c01 + prs * (m_c11 + prs * m_c21)); |
||||||
|
|
||||||
|
//return pressure
|
||||||
|
return prs; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t Dps310::flushFIFO() |
||||||
|
{ |
||||||
|
return writeByteBitfield(1U, registers[FIFO_FL]); |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
#ifndef DPS310_H_INCLUDED |
||||||
|
#define DPS310_H_INCLUDED |
||||||
|
|
||||||
|
#include "DpsClass.h" |
||||||
|
#include "util/dps310_config.h" |
||||||
|
|
||||||
|
class Dps310 : public DpsClass |
||||||
|
{ |
||||||
|
public: |
||||||
|
int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the source of interrupt (FIFO full, measurement values ready) |
||||||
|
*
|
||||||
|
* @param intr_source Interrupt source as defined by Interrupt_source_310_e |
||||||
|
* @param polarity
|
||||||
|
* @return status code
|
||||||
|
*/ |
||||||
|
int16_t setInterruptSources(uint8_t intr_source, uint8_t polarity = 1); |
||||||
|
|
||||||
|
protected: |
||||||
|
uint8_t m_tempSensor; |
||||||
|
|
||||||
|
//compensation coefficients
|
||||||
|
int32_t m_c0Half; |
||||||
|
int32_t m_c1; |
||||||
|
|
||||||
|
/////// implement pure virtual functions ///////
|
||||||
|
|
||||||
|
void init(void); |
||||||
|
int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr); |
||||||
|
int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr); |
||||||
|
int16_t readcoeffs(void); |
||||||
|
int16_t flushFIFO(); |
||||||
|
float calcTemp(int32_t raw); |
||||||
|
float calcPressure(int32_t raw); |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,176 @@ |
|||||||
|
#include "Dps422.h" |
||||||
|
|
||||||
|
using namespace dps; |
||||||
|
using namespace dps422; |
||||||
|
|
||||||
|
//////// public /////////
|
||||||
|
|
||||||
|
int16_t Dps422::measureBothOnce(float &prs, float &temp) |
||||||
|
{ |
||||||
|
measureBothOnce(prs, temp, m_prsOsr, m_tempOsr); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t Dps422::measureBothOnce(float &prs, float &temp, uint8_t prs_osr, uint8_t temp_osr) |
||||||
|
{ |
||||||
|
if (prs_osr != m_prsOsr) |
||||||
|
{ |
||||||
|
if (configPressure(0U, prs_osr)) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (temp_osr != m_tempOsr) |
||||||
|
{ |
||||||
|
if (configPressure(0U, temp_osr)) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
setOpMode(CMD_BOTH); |
||||||
|
delay(((calcBusyTime(0U, m_tempOsr) + calcBusyTime(0U, m_prsOsr)) / DPS__BUSYTIME_SCALING)); |
||||||
|
// config_registers defined in namespace dps
|
||||||
|
int16_t rdy = readByteBitfield(config_registers[PRS_RDY]) & readByteBitfield(config_registers[TEMP_RDY]); |
||||||
|
switch (rdy) |
||||||
|
{ |
||||||
|
case DPS__FAIL_UNKNOWN: //could not read ready flag
|
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
case 0: //ready flag not set, measurement still in progress
|
||||||
|
standby(); |
||||||
|
return DPS__FAIL_UNFINISHED; |
||||||
|
case 1: //measurement ready, expected case
|
||||||
|
m_opMode = IDLE; |
||||||
|
int32_t raw_temp; |
||||||
|
int32_t raw_psr; |
||||||
|
if (getRawResult(&raw_temp, registerBlocks[TEMP]) || getRawResult(&raw_psr, registerBlocks[PRS])) |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
prs = calcPressure(raw_psr); |
||||||
|
temp = calcTemp(raw_temp); |
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int16_t Dps422::getContResults(float *tempBuffer, |
||||||
|
uint8_t &tempCount, |
||||||
|
float *prsBuffer, |
||||||
|
uint8_t &prsCount) |
||||||
|
{ |
||||||
|
return DpsClass::getContResults(tempBuffer, tempCount, prsBuffer, prsCount, registers[FIFO_EMPTY]); |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
int16_t Dps422::setInterruptSources(uint8_t intr_source, uint8_t polarity) |
||||||
|
{ |
||||||
|
// Intrrupt only supported by I2C or 3-Wire SPI
|
||||||
|
if (!m_SpiI2c & !m_threeWire) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
|
||||||
|
return writeByteBitfield(intr_source, registers[INTR_SEL]) || writeByteBitfield(polarity, registers[INTR_POL]); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
//////// private /////////
|
||||||
|
void Dps422::init(void) |
||||||
|
{ |
||||||
|
// m_lastTempScal = 0.08716583251; // in case temperature reading disabled, the default raw temperature value correspond the reference temperature of 27 degress.
|
||||||
|
standby(); |
||||||
|
if (readcoeffs() < 0 || writeByteBitfield(0x01, registers[MUST_SET]) < 0) |
||||||
|
{ |
||||||
|
m_initFail = 1U; |
||||||
|
return; |
||||||
|
} |
||||||
|
configTemp(DPS__MEASUREMENT_RATE_4, DPS__OVERSAMPLING_RATE_8); |
||||||
|
configPressure(DPS__MEASUREMENT_RATE_4, DPS__OVERSAMPLING_RATE_8); |
||||||
|
// get one temperature measurement for pressure compensation
|
||||||
|
float trash; |
||||||
|
measureTempOnce(trash); |
||||||
|
standby(); |
||||||
|
correctTemp(); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t Dps422::readcoeffs(void) |
||||||
|
{ |
||||||
|
uint8_t buffer_temp[3]; |
||||||
|
uint8_t buffer_prs[20]; |
||||||
|
readBlock(coeffBlocks[COEF_TEMP], buffer_temp); |
||||||
|
readBlock(coeffBlocks[COEF_PRS], buffer_prs); |
||||||
|
|
||||||
|
// refer to datasheet
|
||||||
|
// 1. read T_Vbe, T_dVbe and T_gain
|
||||||
|
int32_t t_gain = buffer_temp[0]; // 8 bits
|
||||||
|
int32_t t_dVbe = (uint32_t)buffer_temp[1] >> 1; // 7 bits
|
||||||
|
int32_t t_Vbe = ((uint32_t)buffer_temp[1] & 0x01) | ((uint32_t)buffer_temp[2] << 1); // 9 bits
|
||||||
|
|
||||||
|
getTwosComplement(&t_gain, 8); |
||||||
|
getTwosComplement(&t_dVbe, 7); |
||||||
|
getTwosComplement(&t_Vbe, 9); |
||||||
|
|
||||||
|
// 2. Vbe, dVbe and Aadc
|
||||||
|
float Vbe = t_Vbe * 1.05031e-4 + 0.463232422; |
||||||
|
float dVbe = t_dVbe * 1.25885e-5 + 0.04027621; |
||||||
|
float Aadc = t_gain * 8.4375e-5 + 0.675; |
||||||
|
// 3. Vbe_cal and dVbe_cal
|
||||||
|
float Vbe_cal = Vbe / Aadc; |
||||||
|
float dVbe_cal = dVbe / Aadc; |
||||||
|
// 4. T_calib
|
||||||
|
float T_calib = DPS422_A_0 * dVbe_cal - 273.15; |
||||||
|
// 5. Vbe_cal(T_ref): Vbe value at reference temperature
|
||||||
|
float Vbe_cal_tref = Vbe_cal - (T_calib - DPS422_T_REF) * DPS422_T_C_VBE; |
||||||
|
// 6. alculate PTAT correction coefficient
|
||||||
|
float k_ptat = (DPS422_V_BE_TARGET - Vbe_cal_tref) * DPS422_K_PTAT_CORNER + DPS422_K_PTAT_CURVATURE; |
||||||
|
// 7. calculate A' and B'
|
||||||
|
a_prime = DPS422_A_0 * (Vbe_cal + DPS422_ALPHA * dVbe_cal) * (1 + k_ptat); |
||||||
|
b_prime = -273.15 * (1 + k_ptat) - k_ptat * T_calib; |
||||||
|
|
||||||
|
// c00, c01, c02, c10 : 20 bits
|
||||||
|
// c11, c12: 17 bits
|
||||||
|
// c20: 15 bits; c21: 14 bits; c30 12 bits
|
||||||
|
m_c00 = ((uint32_t)buffer_prs[0] << 12) | ((uint32_t)buffer_prs[1] << 4) | (((uint32_t)buffer_prs[2] & 0xF0) >> 4); |
||||||
|
m_c10 = ((uint32_t)(buffer_prs[2] & 0x0F) << 16) | ((uint32_t)buffer_prs[3] << 8) | (uint32_t)buffer_prs[4]; |
||||||
|
m_c01 = ((uint32_t)buffer_prs[5] << 12) | ((uint32_t)buffer_prs[6] << 4) | (((uint32_t)buffer_prs[7] & 0xF0) >> 4); |
||||||
|
m_c02 = ((uint32_t)(buffer_prs[7] & 0x0F) << 16) | ((uint32_t)buffer_prs[8] << 8) | (uint32_t)buffer_prs[9]; |
||||||
|
m_c20 = ((uint32_t)(buffer_prs[10] & 0x7F) << 8) | (uint32_t)buffer_prs[11]; |
||||||
|
m_c30 = ((uint32_t)(buffer_prs[12] & 0x0F) << 8) | (uint32_t)buffer_prs[13]; |
||||||
|
m_c11 = ((uint32_t)buffer_prs[14] << 9) | ((uint32_t)buffer_prs[15] << 1) | (((uint32_t)buffer_prs[16] & 0x80) >> 7); |
||||||
|
m_c12 = (((uint32_t)buffer_prs[16] & 0x7F) << 10) | ((uint32_t)buffer_prs[17] << 2) | (((uint32_t)buffer_prs[18] & 0xC0) >> 6); |
||||||
|
m_c21 = (((uint32_t)buffer_prs[18] & 0x3F) << 8) | ((uint32_t)buffer_prs[19]); |
||||||
|
|
||||||
|
getTwosComplement(&m_c00, 20); |
||||||
|
getTwosComplement(&m_c01, 20); |
||||||
|
getTwosComplement(&m_c02, 20); |
||||||
|
getTwosComplement(&m_c10, 20); |
||||||
|
getTwosComplement(&m_c11, 17); |
||||||
|
getTwosComplement(&m_c12, 17); |
||||||
|
getTwosComplement(&m_c20, 15); |
||||||
|
getTwosComplement(&m_c21, 14); |
||||||
|
getTwosComplement(&m_c30, 12); |
||||||
|
|
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t Dps422::flushFIFO() |
||||||
|
{ |
||||||
|
return writeByteBitfield(1U, registers[FIFO_FL]); |
||||||
|
} |
||||||
|
|
||||||
|
float Dps422::calcTemp(int32_t raw) |
||||||
|
{ |
||||||
|
m_lastTempScal = (float)raw / 1048576; |
||||||
|
float u = m_lastTempScal / (1 + DPS422_ALPHA * m_lastTempScal); |
||||||
|
return (a_prime * u + b_prime); |
||||||
|
} |
||||||
|
|
||||||
|
float Dps422::calcPressure(int32_t raw_prs) |
||||||
|
{ |
||||||
|
float prs = raw_prs; |
||||||
|
prs /= scaling_facts[m_prsOsr]; |
||||||
|
|
||||||
|
float temp = (8.5 * m_lastTempScal) / (1 + 8.8 * m_lastTempScal); |
||||||
|
|
||||||
|
prs = m_c00 + m_c10 * prs + m_c01 * temp + m_c20 * prs * prs + m_c02 * temp * temp + m_c30 * prs * prs * prs + |
||||||
|
m_c11 * temp * prs + m_c12 * prs * temp * temp + m_c21 * prs * prs * temp; |
||||||
|
return prs; |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* Temperature measurements must be enabled for the DPS422 to compensate for temperature drift in the pressure measurement. |
||||||
|
* @file Dps422.h |
||||||
|
* @author Infineon Technologies |
||||||
|
* @date 2018-08-22 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef DPS422_H_INCLUDED |
||||||
|
#define DPS422_H_INCLUDED |
||||||
|
#include "DpsClass.h" |
||||||
|
#include "util/dps422_config.h" |
||||||
|
|
||||||
|
class Dps422 : public DpsClass |
||||||
|
{ |
||||||
|
public: |
||||||
|
int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the source of interrupt (FIFO full, measurement values ready) |
||||||
|
*
|
||||||
|
* @param intr_source Source of interrupt as defined by Interrupt_source_420_e |
||||||
|
* @param polarity
|
||||||
|
* @return int16_t
|
||||||
|
*/ |
||||||
|
int16_t setInterruptSources(uint8_t intr_source, uint8_t polarity = 1); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief measures both temperature and pressure values, when op mode is set to CMD_BOTH |
||||||
|
*
|
||||||
|
* @param prs reference to the pressure value |
||||||
|
* @param temp prs reference to the temperature value |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t measureBothOnce(float &prs, float &temp); // might make sense to declare in base class for future sensors
|
||||||
|
|
||||||
|
int16_t measureBothOnce(float &prs, float &temp, uint8_t prs_osr, uint8_t temp_osr); |
||||||
|
|
||||||
|
protected: |
||||||
|
//compensation coefficients (for simplicity use 32 bits)
|
||||||
|
float a_prime; |
||||||
|
float b_prime; |
||||||
|
int32_t m_c02; |
||||||
|
int32_t m_c12; |
||||||
|
|
||||||
|
/////// implement pure virtual functions ///////
|
||||||
|
void init(void); |
||||||
|
int16_t readcoeffs(void); |
||||||
|
int16_t flushFIFO(); |
||||||
|
float calcTemp(int32_t raw); |
||||||
|
float calcPressure(int32_t raw); |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,803 @@ |
|||||||
|
#include "DpsClass.h" |
||||||
|
using namespace dps; |
||||||
|
|
||||||
|
const int32_t DpsClass::scaling_facts[DPS__NUM_OF_SCAL_FACTS] = {524288, 1572864, 3670016, 7864320, 253952, 516096, 1040384, 2088960}; |
||||||
|
|
||||||
|
//////// Constructor, Destructor, begin, end ////////
|
||||||
|
|
||||||
|
DpsClass::DpsClass(void) |
||||||
|
{ |
||||||
|
//assume that initialization has failed before it has been done
|
||||||
|
m_initFail = 1U; |
||||||
|
} |
||||||
|
|
||||||
|
DpsClass::~DpsClass(void) |
||||||
|
{ |
||||||
|
end(); |
||||||
|
} |
||||||
|
|
||||||
|
void DpsClass::begin(TwoWire &bus) |
||||||
|
{ |
||||||
|
begin(bus, DPS__STD_SLAVE_ADDRESS); |
||||||
|
} |
||||||
|
|
||||||
|
void DpsClass::begin(TwoWire &bus, uint8_t slaveAddress) |
||||||
|
{ |
||||||
|
//this flag will show if the initialization was successful
|
||||||
|
m_initFail = 0U; |
||||||
|
|
||||||
|
//Set I2C bus connection
|
||||||
|
m_SpiI2c = 1U; |
||||||
|
m_i2cbus = &bus; |
||||||
|
m_slaveAddress = slaveAddress; |
||||||
|
|
||||||
|
// Init bus
|
||||||
|
m_i2cbus->begin(); |
||||||
|
|
||||||
|
delay(50); //startup time of Dps310
|
||||||
|
|
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
void DpsClass::begin(SPIClass &bus, int32_t chipSelect) |
||||||
|
{ |
||||||
|
begin(bus, chipSelect, 0U); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
void DpsClass::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) |
||||||
|
{ |
||||||
|
//this flag will show if the initialization was successful
|
||||||
|
m_initFail = 0U; |
||||||
|
|
||||||
|
//Set SPI bus connection
|
||||||
|
m_SpiI2c = 0U; |
||||||
|
m_spibus = &bus; |
||||||
|
m_chipSelect = chipSelect; |
||||||
|
|
||||||
|
// Init bus
|
||||||
|
m_spibus->begin(); |
||||||
|
m_spibus->setDataMode(SPI_MODE3); |
||||||
|
|
||||||
|
pinMode(m_chipSelect, OUTPUT); |
||||||
|
digitalWrite(m_chipSelect, HIGH); |
||||||
|
|
||||||
|
delay(50); //startup time of Dps310
|
||||||
|
|
||||||
|
//switch to 3-wire mode if necessary
|
||||||
|
//do not use writeByteBitfield or check option to set SPI mode!
|
||||||
|
//Reading is not possible until SPI-mode is valid
|
||||||
|
if (threeWire) |
||||||
|
{ |
||||||
|
m_threeWire = 1U; |
||||||
|
if (writeByte(DPS310__REG_ADR_SPI3W, DPS310__REG_CONTENT_SPI3W)) |
||||||
|
{ |
||||||
|
m_initFail = 1U; |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
init(); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
void DpsClass::end(void) |
||||||
|
{ |
||||||
|
standby(); |
||||||
|
} |
||||||
|
|
||||||
|
//////// Declaration of other public functions starts here ////////
|
||||||
|
|
||||||
|
uint8_t DpsClass::getProductId(void) |
||||||
|
{ |
||||||
|
return m_productID; |
||||||
|
} |
||||||
|
|
||||||
|
uint8_t DpsClass::getRevisionId(void) |
||||||
|
{ |
||||||
|
return m_revisionID; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::getContResults(float *tempBuffer, |
||||||
|
uint8_t &tempCount, |
||||||
|
float *prsBuffer, |
||||||
|
uint8_t &prsCount, RegMask_t fifo_empty_reg) |
||||||
|
{ |
||||||
|
if (m_initFail) |
||||||
|
{ |
||||||
|
return DPS__FAIL_INIT_FAILED; |
||||||
|
} |
||||||
|
//abort if device is not in background mode
|
||||||
|
if (!(m_opMode & 0x04)) |
||||||
|
{ |
||||||
|
return DPS__FAIL_TOOBUSY; |
||||||
|
} |
||||||
|
|
||||||
|
if (!tempBuffer || !prsBuffer) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
tempCount = 0U; |
||||||
|
prsCount = 0U; |
||||||
|
|
||||||
|
//while FIFO is not empty
|
||||||
|
while (readByteBitfield(fifo_empty_reg) == 0) |
||||||
|
{ |
||||||
|
int32_t raw_result; |
||||||
|
float result; |
||||||
|
//read next result from FIFO
|
||||||
|
int16_t type = getFIFOvalue(&raw_result); |
||||||
|
switch (type) |
||||||
|
{ |
||||||
|
case 0: //temperature
|
||||||
|
if (tempCount < DPS__FIFO_SIZE) |
||||||
|
{ |
||||||
|
result = calcTemp(raw_result); |
||||||
|
tempBuffer[tempCount++] = result; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: //pressure
|
||||||
|
if (prsCount < DPS__FIFO_SIZE) |
||||||
|
{ |
||||||
|
result = calcPressure(raw_result); |
||||||
|
prsBuffer[prsCount++] = result; |
||||||
|
} |
||||||
|
break; |
||||||
|
case -1: //read failed
|
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::getSingleResult(float &result) |
||||||
|
{ |
||||||
|
//abort if initialization failed
|
||||||
|
if (m_initFail) |
||||||
|
{ |
||||||
|
return DPS__FAIL_INIT_FAILED; |
||||||
|
} |
||||||
|
|
||||||
|
//read finished bit for current opMode
|
||||||
|
int16_t rdy; |
||||||
|
switch (m_opMode) |
||||||
|
{ |
||||||
|
case CMD_TEMP: //temperature
|
||||||
|
rdy = readByteBitfield(config_registers[TEMP_RDY]); |
||||||
|
break; |
||||||
|
case CMD_PRS: //pressure
|
||||||
|
rdy = readByteBitfield(config_registers[PRS_RDY]); |
||||||
|
break; |
||||||
|
default: //DPS310 not in command mode
|
||||||
|
return DPS__FAIL_TOOBUSY; |
||||||
|
} |
||||||
|
//read new measurement result
|
||||||
|
switch (rdy) |
||||||
|
{ |
||||||
|
case DPS__FAIL_UNKNOWN: //could not read ready flag
|
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
case 0: //ready flag not set, measurement still in progress
|
||||||
|
return DPS__FAIL_UNFINISHED; |
||||||
|
case 1: //measurement ready, expected case
|
||||||
|
Mode oldMode = m_opMode; |
||||||
|
m_opMode = IDLE; //opcode was automatically reseted by DPS310
|
||||||
|
int32_t raw_val; |
||||||
|
switch (oldMode) |
||||||
|
{ |
||||||
|
case CMD_TEMP: //temperature
|
||||||
|
getRawResult(&raw_val, registerBlocks[TEMP]); |
||||||
|
result = calcTemp(raw_val); |
||||||
|
return DPS__SUCCEEDED; // TODO
|
||||||
|
case CMD_PRS: //pressure
|
||||||
|
getRawResult(&raw_val, registerBlocks[PRS]); |
||||||
|
result = calcPressure(raw_val); |
||||||
|
return DPS__SUCCEEDED; // TODO
|
||||||
|
default: |
||||||
|
return DPS__FAIL_UNKNOWN; //should already be filtered above
|
||||||
|
} |
||||||
|
} |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::measureTempOnce(float &result) |
||||||
|
{ |
||||||
|
return measureTempOnce(result, m_tempOsr); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::measureTempOnce(float &result, uint8_t oversamplingRate) |
||||||
|
{ |
||||||
|
//Start measurement
|
||||||
|
int16_t ret = startMeasureTempOnce(oversamplingRate); |
||||||
|
if (ret != DPS__SUCCEEDED) |
||||||
|
{ |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
//wait until measurement is finished
|
||||||
|
delay(calcBusyTime(0U, m_tempOsr) / DPS__BUSYTIME_SCALING); |
||||||
|
delay(DPS310__BUSYTIME_FAILSAFE); |
||||||
|
|
||||||
|
ret = getSingleResult(result); |
||||||
|
if (ret != DPS__SUCCEEDED) |
||||||
|
{ |
||||||
|
standby(); |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::startMeasureTempOnce(void) |
||||||
|
{ |
||||||
|
return startMeasureTempOnce(m_tempOsr); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::startMeasureTempOnce(uint8_t oversamplingRate) |
||||||
|
{ |
||||||
|
//abort if initialization failed
|
||||||
|
if (m_initFail) |
||||||
|
{ |
||||||
|
return DPS__FAIL_INIT_FAILED; |
||||||
|
} |
||||||
|
//abort if device is not in idling mode
|
||||||
|
if (m_opMode != IDLE) |
||||||
|
{ |
||||||
|
return DPS__FAIL_TOOBUSY; |
||||||
|
} |
||||||
|
|
||||||
|
if (oversamplingRate != m_tempOsr) |
||||||
|
{ |
||||||
|
//configuration of oversampling rate
|
||||||
|
if (configTemp(0U, oversamplingRate) != DPS__SUCCEEDED) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//set device to temperature measuring mode
|
||||||
|
return setOpMode(CMD_TEMP); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::measurePressureOnce(float &result) |
||||||
|
{ |
||||||
|
return measurePressureOnce(result, m_prsOsr); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::measurePressureOnce(float &result, uint8_t oversamplingRate) |
||||||
|
{ |
||||||
|
//start the measurement
|
||||||
|
int16_t ret = startMeasurePressureOnce(oversamplingRate); |
||||||
|
if (ret != DPS__SUCCEEDED) |
||||||
|
{ |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
//wait until measurement is finished
|
||||||
|
delay(calcBusyTime(0U, m_prsOsr) / DPS__BUSYTIME_SCALING); |
||||||
|
delay(DPS310__BUSYTIME_FAILSAFE); |
||||||
|
|
||||||
|
ret = getSingleResult(result); |
||||||
|
if (ret != DPS__SUCCEEDED) |
||||||
|
{ |
||||||
|
standby(); |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::startMeasurePressureOnce(void) |
||||||
|
{ |
||||||
|
return startMeasurePressureOnce(m_prsOsr); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::startMeasurePressureOnce(uint8_t oversamplingRate) |
||||||
|
{ |
||||||
|
//abort if initialization failed
|
||||||
|
if (m_initFail) |
||||||
|
{ |
||||||
|
return DPS__FAIL_INIT_FAILED; |
||||||
|
} |
||||||
|
//abort if device is not in idling mode
|
||||||
|
if (m_opMode != IDLE) |
||||||
|
{ |
||||||
|
return DPS__FAIL_TOOBUSY; |
||||||
|
} |
||||||
|
//configuration of oversampling rate, lowest measure rate to avoid conflicts
|
||||||
|
if (oversamplingRate != m_prsOsr) |
||||||
|
{ |
||||||
|
if (configPressure(0U, oversamplingRate)) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
} |
||||||
|
//set device to pressure measuring mode
|
||||||
|
return setOpMode(CMD_PRS); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate) |
||||||
|
{ |
||||||
|
//abort if initialization failed
|
||||||
|
if (m_initFail) |
||||||
|
{ |
||||||
|
return DPS__FAIL_INIT_FAILED; |
||||||
|
} |
||||||
|
//abort if device is not in idling mode
|
||||||
|
if (m_opMode != IDLE) |
||||||
|
{ |
||||||
|
return DPS__FAIL_TOOBUSY; |
||||||
|
} |
||||||
|
//abort if speed and precision are too high
|
||||||
|
if (calcBusyTime(measureRate, oversamplingRate) >= DPS310__MAX_BUSYTIME) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNFINISHED; |
||||||
|
} |
||||||
|
//update precision and measuring rate
|
||||||
|
if (configTemp(measureRate, oversamplingRate)) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
|
||||||
|
if (enableFIFO()) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
//Start measuring in background mode
|
||||||
|
if (DpsClass::setOpMode(CONT_TMP)) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate) |
||||||
|
{ |
||||||
|
//abort if initialization failed
|
||||||
|
if (m_initFail) |
||||||
|
{ |
||||||
|
return DPS__FAIL_INIT_FAILED; |
||||||
|
} |
||||||
|
//abort if device is not in idling mode
|
||||||
|
if (m_opMode != IDLE) |
||||||
|
{ |
||||||
|
return DPS__FAIL_TOOBUSY; |
||||||
|
} |
||||||
|
//abort if speed and precision are too high
|
||||||
|
if (calcBusyTime(measureRate, oversamplingRate) >= DPS310__MAX_BUSYTIME) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNFINISHED; |
||||||
|
} |
||||||
|
//update precision and measuring rate
|
||||||
|
if (configPressure(measureRate, oversamplingRate)) |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
//enable result FIFO
|
||||||
|
if (enableFIFO()) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
//Start measuring in background mode
|
||||||
|
if (DpsClass::setOpMode(CONT_PRS)) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::startMeasureBothCont(uint8_t tempMr, |
||||||
|
uint8_t tempOsr, |
||||||
|
uint8_t prsMr, |
||||||
|
uint8_t prsOsr) |
||||||
|
{ |
||||||
|
//abort if initialization failed
|
||||||
|
if (m_initFail) |
||||||
|
{ |
||||||
|
return DPS__FAIL_INIT_FAILED; |
||||||
|
} |
||||||
|
//abort if device is not in idling mode
|
||||||
|
if (m_opMode != IDLE) |
||||||
|
{ |
||||||
|
return DPS__FAIL_TOOBUSY; |
||||||
|
} |
||||||
|
//abort if speed and precision are too high
|
||||||
|
if (calcBusyTime(tempMr, tempOsr) + calcBusyTime(prsMr, prsOsr) >= DPS310__MAX_BUSYTIME) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNFINISHED; |
||||||
|
} |
||||||
|
//update precision and measuring rate
|
||||||
|
if (configTemp(tempMr, tempOsr)) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
//update precision and measuring rate
|
||||||
|
if (configPressure(prsMr, prsOsr)) |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
//enable result FIFO
|
||||||
|
if (enableFIFO()) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
//Start measuring in background mode
|
||||||
|
if (setOpMode(CONT_BOTH)) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::standby(void) |
||||||
|
{ |
||||||
|
//abort if initialization failed
|
||||||
|
if (m_initFail) |
||||||
|
{ |
||||||
|
return DPS__FAIL_INIT_FAILED; |
||||||
|
} |
||||||
|
//set device to idling mode
|
||||||
|
int16_t ret = setOpMode(IDLE); |
||||||
|
if (ret != DPS__SUCCEEDED) |
||||||
|
{ |
||||||
|
return ret; |
||||||
|
} |
||||||
|
ret = disableFIFO(); |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::correctTemp(void) |
||||||
|
{ |
||||||
|
if (m_initFail) |
||||||
|
{ |
||||||
|
return DPS__FAIL_INIT_FAILED; |
||||||
|
} |
||||||
|
writeByte(0x0E, 0xA5); |
||||||
|
writeByte(0x0F, 0x96); |
||||||
|
writeByte(0x62, 0x02); |
||||||
|
writeByte(0x0E, 0x00); |
||||||
|
writeByte(0x0F, 0x00); |
||||||
|
|
||||||
|
//perform a first temperature measurement (again)
|
||||||
|
//the most recent temperature will be saved internally
|
||||||
|
//and used for compensation when calculating pressure
|
||||||
|
float trash; |
||||||
|
measureTempOnce(trash); |
||||||
|
|
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::getIntStatusFifoFull(void) |
||||||
|
{ |
||||||
|
return readByteBitfield(config_registers[INT_FLAG_FIFO]); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::getIntStatusTempReady(void) |
||||||
|
{ |
||||||
|
return readByteBitfield(config_registers[INT_FLAG_TEMP]); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::getIntStatusPrsReady(void) |
||||||
|
{ |
||||||
|
return readByteBitfield(config_registers[INT_FLAG_PRS]); |
||||||
|
} |
||||||
|
|
||||||
|
//////// Declaration of private functions starts here ////////
|
||||||
|
|
||||||
|
int16_t DpsClass::setOpMode(uint8_t opMode) |
||||||
|
{ |
||||||
|
if (writeByteBitfield(opMode, config_registers[MSR_CTRL]) == -1) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
m_opMode = (Mode)opMode; |
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::configTemp(uint8_t tempMr, uint8_t tempOsr) |
||||||
|
{ |
||||||
|
tempMr &= 0x07; |
||||||
|
tempOsr &= 0x07; |
||||||
|
// two accesses to the same register; for readability
|
||||||
|
int16_t ret = writeByteBitfield(tempMr, config_registers[TEMP_MR]); |
||||||
|
ret = writeByteBitfield(tempOsr, config_registers[TEMP_OSR]); |
||||||
|
|
||||||
|
//abort immediately on fail
|
||||||
|
if (ret != DPS__SUCCEEDED) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
m_tempMr = tempMr; |
||||||
|
m_tempOsr = tempOsr; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::configPressure(uint8_t prsMr, uint8_t prsOsr) |
||||||
|
{ |
||||||
|
prsMr &= 0x07; |
||||||
|
prsOsr &= 0x07; |
||||||
|
int16_t ret = writeByteBitfield(prsMr, config_registers[PRS_MR]); |
||||||
|
ret = writeByteBitfield(prsOsr, config_registers[PRS_OSR]); |
||||||
|
|
||||||
|
//abort immediately on fail
|
||||||
|
if (ret != DPS__SUCCEEDED) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
m_prsMr = prsMr; |
||||||
|
m_prsOsr = prsOsr; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::enableFIFO() |
||||||
|
{ |
||||||
|
return writeByteBitfield(1U, config_registers[FIFO_EN]); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::disableFIFO() |
||||||
|
{ |
||||||
|
int16_t ret = flushFIFO(); |
||||||
|
ret = writeByteBitfield(0U, config_registers[FIFO_EN]); |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
uint16_t DpsClass::calcBusyTime(uint16_t mr, uint16_t osr) |
||||||
|
{ |
||||||
|
//formula from datasheet (optimized)
|
||||||
|
return ((uint32_t)20U << mr) + ((uint32_t)16U << (osr + mr)); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::getFIFOvalue(int32_t *value) |
||||||
|
{ |
||||||
|
uint8_t buffer[DPS__RESULT_BLOCK_LENGTH] = {0}; |
||||||
|
|
||||||
|
//abort on invalid argument or failed block reading
|
||||||
|
if (value == NULL || readBlock(registerBlocks[PRS], buffer) != DPS__RESULT_BLOCK_LENGTH) |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
*value = (uint32_t)buffer[0] << 16 | (uint32_t)buffer[1] << 8 | (uint32_t)buffer[2]; |
||||||
|
getTwosComplement(value, 24); |
||||||
|
return buffer[2] & 0x01; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::readByte(uint8_t regAddress) |
||||||
|
{ |
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
//delegate to specialized function if Dps310 is connected via SPI
|
||||||
|
if (m_SpiI2c == 0) |
||||||
|
{ |
||||||
|
return readByteSPI(regAddress); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
m_i2cbus->beginTransmission(m_slaveAddress); |
||||||
|
m_i2cbus->write(regAddress); |
||||||
|
m_i2cbus->endTransmission(false); |
||||||
|
//request 1 byte from slave
|
||||||
|
if (m_i2cbus->requestFrom(m_slaveAddress, 1U, 1U) > 0) |
||||||
|
{ |
||||||
|
return m_i2cbus->read(); //return this byte on success
|
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; //if 0 bytes were read successfully
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
int16_t DpsClass::readByteSPI(uint8_t regAddress) |
||||||
|
{ |
||||||
|
//this function is only made for communication via SPI
|
||||||
|
if (m_SpiI2c != 0) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
//mask regAddress
|
||||||
|
regAddress &= ~DPS310__SPI_RW_MASK; |
||||||
|
//reserve and initialize bus
|
||||||
|
m_spibus->beginTransaction(SPISettings(DPS310__SPI_MAX_FREQ, |
||||||
|
MSBFIRST, |
||||||
|
SPI_MODE3)); |
||||||
|
//enable ChipSelect for Dps310
|
||||||
|
digitalWrite(m_chipSelect, LOW); |
||||||
|
//send address with read command to Dps310
|
||||||
|
m_spibus->transfer(regAddress | DPS310__SPI_READ_CMD); |
||||||
|
//receive register content from Dps310
|
||||||
|
uint8_t ret = m_spibus->transfer(0xFF); //send a dummy byte while receiving
|
||||||
|
//disable ChipSelect for Dps310
|
||||||
|
digitalWrite(m_chipSelect, HIGH); |
||||||
|
//close current SPI transaction
|
||||||
|
m_spibus->endTransaction(); |
||||||
|
//return received data
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
int16_t DpsClass::readBlockSPI(RegBlock_t regBlock, uint8_t *buffer) |
||||||
|
{ |
||||||
|
//this function is only made for communication via SPI
|
||||||
|
if (m_SpiI2c != 0) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
//do not read if there is no buffer
|
||||||
|
if (buffer == NULL) |
||||||
|
{ |
||||||
|
return 0; //0 bytes were read successfully
|
||||||
|
} |
||||||
|
//mask regAddress
|
||||||
|
regBlock.regAddress &= ~DPS310__SPI_RW_MASK; |
||||||
|
//reserve and initialize bus
|
||||||
|
m_spibus->beginTransaction(SPISettings(DPS310__SPI_MAX_FREQ, |
||||||
|
MSBFIRST, |
||||||
|
SPI_MODE3)); |
||||||
|
//enable ChipSelect for Dps310
|
||||||
|
digitalWrite(m_chipSelect, LOW); |
||||||
|
//send address with read command to Dps310
|
||||||
|
m_spibus->transfer(regBlock.regAddress | DPS310__SPI_READ_CMD); |
||||||
|
|
||||||
|
//receive register contents from Dps310
|
||||||
|
for (uint8_t count = 0; count < regBlock.length; count++) |
||||||
|
{ |
||||||
|
buffer[count] = m_spibus->transfer(0xFF); //send a dummy byte while receiving
|
||||||
|
} |
||||||
|
|
||||||
|
//disable ChipSelect for Dps310
|
||||||
|
digitalWrite(m_chipSelect, HIGH); |
||||||
|
//close current SPI transaction
|
||||||
|
m_spibus->endTransaction(); |
||||||
|
//return received data
|
||||||
|
return regBlock.length; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
int16_t DpsClass::writeByte(uint8_t regAddress, uint8_t data) |
||||||
|
{ |
||||||
|
return writeByte(regAddress, data, 0U); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::writeByte(uint8_t regAddress, uint8_t data, uint8_t check) |
||||||
|
{ |
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
//delegate to specialized function if Dps310 is connected via SPI
|
||||||
|
if (m_SpiI2c == 0) |
||||||
|
{ |
||||||
|
return writeByteSpi(regAddress, data, check); |
||||||
|
} |
||||||
|
#endif |
||||||
|
m_i2cbus->beginTransmission(m_slaveAddress); |
||||||
|
m_i2cbus->write(regAddress); //Write Register number to buffer
|
||||||
|
m_i2cbus->write(data); //Write data to buffer
|
||||||
|
if (m_i2cbus->endTransmission() != 0) //Send buffer content to slave
|
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
if (check == 0) |
||||||
|
return 0; //no checking
|
||||||
|
if (readByte(regAddress) == data) //check if desired by calling function
|
||||||
|
{ |
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
int16_t DpsClass::writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check) |
||||||
|
{ |
||||||
|
//this function is only made for communication via SPI
|
||||||
|
if (m_SpiI2c != 0) |
||||||
|
{ |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
//mask regAddress
|
||||||
|
regAddress &= ~DPS310__SPI_RW_MASK; |
||||||
|
//reserve and initialize bus
|
||||||
|
m_spibus->beginTransaction(SPISettings(DPS310__SPI_MAX_FREQ, |
||||||
|
MSBFIRST, |
||||||
|
SPI_MODE3)); |
||||||
|
//enable ChipSelect for Dps310
|
||||||
|
digitalWrite(m_chipSelect, LOW); |
||||||
|
//send address with read command to Dps310
|
||||||
|
m_spibus->transfer(regAddress | DPS310__SPI_WRITE_CMD); |
||||||
|
|
||||||
|
//write register content from Dps310
|
||||||
|
m_spibus->transfer(data); |
||||||
|
|
||||||
|
//disable ChipSelect for Dps310
|
||||||
|
digitalWrite(m_chipSelect, HIGH); |
||||||
|
//close current SPI transaction
|
||||||
|
m_spibus->endTransaction(); |
||||||
|
|
||||||
|
//check if necessary
|
||||||
|
if (check == 0) |
||||||
|
{ |
||||||
|
//no checking necessary
|
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
//checking necessary
|
||||||
|
if (readByte(regAddress) == data) |
||||||
|
{ |
||||||
|
//check passed
|
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
//check failed
|
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
int16_t DpsClass::writeByteBitfield(uint8_t data, RegMask_t regMask) |
||||||
|
{ |
||||||
|
return writeByteBitfield(data, regMask.regAddress, regMask.mask, regMask.shift, 0U); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::writeByteBitfield(uint8_t data, |
||||||
|
uint8_t regAddress, |
||||||
|
uint8_t mask, |
||||||
|
uint8_t shift, |
||||||
|
uint8_t check) |
||||||
|
{ |
||||||
|
int16_t old = readByte(regAddress); |
||||||
|
if (old < 0) |
||||||
|
{ |
||||||
|
//fail while reading
|
||||||
|
return old; |
||||||
|
} |
||||||
|
return writeByte(regAddress, ((uint8_t)old & ~mask) | ((data << shift) & mask), check); |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::readByteBitfield(RegMask_t regMask) |
||||||
|
{ |
||||||
|
int16_t ret = readByte(regMask.regAddress); |
||||||
|
if (ret < 0) |
||||||
|
{ |
||||||
|
return ret; |
||||||
|
} |
||||||
|
return (((uint8_t)ret) & regMask.mask) >> regMask.shift; |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::readBlock(RegBlock_t regBlock, uint8_t *buffer) |
||||||
|
{ |
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
//delegate to specialized function if Dps310 is connected via SPI
|
||||||
|
if (m_SpiI2c == 0) |
||||||
|
{ |
||||||
|
return readBlockSPI(regBlock, buffer); |
||||||
|
} |
||||||
|
#endif |
||||||
|
//do not read if there is no buffer
|
||||||
|
if (buffer == NULL) |
||||||
|
{ |
||||||
|
return 0; //0 bytes read successfully
|
||||||
|
} |
||||||
|
|
||||||
|
m_i2cbus->beginTransmission(m_slaveAddress); |
||||||
|
m_i2cbus->write(regBlock.regAddress); |
||||||
|
m_i2cbus->endTransmission(false); |
||||||
|
//request length bytes from slave
|
||||||
|
int16_t ret = m_i2cbus->requestFrom(m_slaveAddress, regBlock.length, 1U); |
||||||
|
//read all received bytes to buffer
|
||||||
|
for (int16_t count = 0; count < ret; count++) |
||||||
|
{ |
||||||
|
buffer[count] = m_i2cbus->read(); |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void DpsClass::getTwosComplement(int32_t *raw, uint8_t length) |
||||||
|
{ |
||||||
|
if (*raw & ((uint32_t)1 << (length - 1))) |
||||||
|
{ |
||||||
|
*raw -= (uint32_t)1 << length; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int16_t DpsClass::getRawResult(int32_t *raw, RegBlock_t reg) |
||||||
|
{ |
||||||
|
uint8_t buffer[DPS__RESULT_BLOCK_LENGTH] = {0}; |
||||||
|
if (readBlock(reg, buffer) != DPS__RESULT_BLOCK_LENGTH) |
||||||
|
return DPS__FAIL_UNKNOWN; |
||||||
|
|
||||||
|
*raw = (uint32_t)buffer[0] << 16 | (uint32_t)buffer[1] << 8 | (uint32_t)buffer[2]; |
||||||
|
getTwosComplement(raw, 24); |
||||||
|
return DPS__SUCCEEDED; |
||||||
|
} |
@ -0,0 +1,485 @@ |
|||||||
|
/**
|
||||||
|
* Arduino library to control Dps310 |
||||||
|
* |
||||||
|
* "Dps310" represents Infineon's high-sensetive pressure and temperature sensor.
|
||||||
|
* It measures in ranges of 300 - 1200 hPa and -40 and 85 °C.
|
||||||
|
* The sensor can be connected via SPI or I2C.
|
||||||
|
* It is able to perform single measurements |
||||||
|
* or to perform continuous measurements of temperature and pressure at the same time,
|
||||||
|
* and stores the results in a FIFO to reduce bus communication.
|
||||||
|
* |
||||||
|
* Have a look at the datasheet for more information.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef DPSCLASS_H_INCLUDED |
||||||
|
#define DPSCLASS_H_INCLUDED |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
#include <SPI.h> |
||||||
|
#endif |
||||||
|
#include <Wire.h> |
||||||
|
#include "util/dps_config.h" |
||||||
|
#include <Arduino.h> |
||||||
|
|
||||||
|
class DpsClass |
||||||
|
{ |
||||||
|
public: |
||||||
|
//constructor
|
||||||
|
DpsClass(void); |
||||||
|
//destructor
|
||||||
|
~DpsClass(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* I2C begin function with standard address |
||||||
|
*/ |
||||||
|
void begin(TwoWire &bus); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard I2C begin function |
||||||
|
* |
||||||
|
* @param &bus: I2CBus which connects MC to the sensor |
||||||
|
* @param slaveAddress: I2C address of the sensor (0x77 or 0x76) |
||||||
|
*/ |
||||||
|
void begin(TwoWire &bus, uint8_t slaveAddress); |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
/**
|
||||||
|
* SPI begin function for Dps310 with 4-wire SPI |
||||||
|
*/ |
||||||
|
void begin(SPIClass &bus, int32_t chipSelect); |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
/**
|
||||||
|
* Standard SPI begin function |
||||||
|
* |
||||||
|
* @param &bus: SPI bus which connects MC to Dps310 |
||||||
|
* @param chipSelect: Number of the CS line for the Dps310 |
||||||
|
* @param threeWire: 1 if Dps310 is connected with 3-wire SPI |
||||||
|
* 0 if Dps310 is connected with 4-wire SPI (standard) |
||||||
|
*/ |
||||||
|
void begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire); |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* End function for Dps310 |
||||||
|
* Sets the sensor to idle mode |
||||||
|
*/ |
||||||
|
void end(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the Product ID of the connected Dps310 sensor |
||||||
|
*/ |
||||||
|
uint8_t getProductId(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the Revision ID of the connected Dps310 sensor |
||||||
|
*/ |
||||||
|
uint8_t getRevisionId(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Dps310 to standby mode |
||||||
|
* |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t standby(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* performs one temperature measurement |
||||||
|
* |
||||||
|
* @param &result: reference to a float value where the result will be written |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t measureTempOnce(float &result); |
||||||
|
|
||||||
|
/**
|
||||||
|
* performs one temperature measurement with specified oversamplingRate |
||||||
|
* |
||||||
|
* @param &result: reference to a float where the result will be written |
||||||
|
* @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128, which are defined as integers 0 - 7 |
||||||
|
* The number of measurements equals to 2^n, if the value written to the register field is n. 2^n internal measurements are combined to return a more exact measurement |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t measureTempOnce(float &result, uint8_t oversamplingRate); |
||||||
|
|
||||||
|
/**
|
||||||
|
* starts a single temperature measurement |
||||||
|
* |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t startMeasureTempOnce(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* starts a single temperature measurement with specified oversamplingRate |
||||||
|
* |
||||||
|
* @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128, which are defined as integers 0 - 7 |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t startMeasureTempOnce(uint8_t oversamplingRate); |
||||||
|
|
||||||
|
/**
|
||||||
|
* performs one pressure measurement |
||||||
|
* |
||||||
|
* @param &result: reference to a float value where the result will be written |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t measurePressureOnce(float &result); |
||||||
|
|
||||||
|
/**
|
||||||
|
* performs one pressure measurement with specified oversamplingRate |
||||||
|
* |
||||||
|
* @param &result: reference to a float where the result will be written |
||||||
|
* @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t measurePressureOnce(float &result, uint8_t oversamplingRate); |
||||||
|
|
||||||
|
/**
|
||||||
|
* starts a single pressure measurement |
||||||
|
* |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t startMeasurePressureOnce(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* starts a single pressure measurement with specified oversamplingRate |
||||||
|
* |
||||||
|
* @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t startMeasurePressureOnce(uint8_t oversamplingRate); |
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the result a single temperature or pressure measurement in °C or Pa |
||||||
|
* |
||||||
|
* @param &result: reference to a float value where the result will be written |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t getSingleResult(float &result); |
||||||
|
|
||||||
|
/**
|
||||||
|
* starts a continuous temperature measurement with specified measurement rate and oversampling rate |
||||||
|
* If measure rate is n and oversampling rate is m, the DPS310 performs 2^(n+m) internal measurements per second.
|
||||||
|
* The DPS310 cannot operate with high precision and high speed at the same time. Consult the datasheet for more information. |
||||||
|
*
|
||||||
|
* @param measureRate: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 |
||||||
|
* @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 |
||||||
|
*
|
||||||
|
* @return status code |
||||||
|
*
|
||||||
|
*/ |
||||||
|
int16_t startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate); |
||||||
|
|
||||||
|
/**
|
||||||
|
* starts a continuous temperature measurement with specified measurement rate and oversampling rate |
||||||
|
* |
||||||
|
* @param measureRate: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 |
||||||
|
* @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate); |
||||||
|
|
||||||
|
/**
|
||||||
|
* starts a continuous temperature and pressure measurement with specified measurement rate and oversampling rate for temperature and pressure measurement respectvely. |
||||||
|
* |
||||||
|
* @param tempMr measure rate for temperature |
||||||
|
* @param tempOsr oversampling rate for temperature |
||||||
|
* @param prsMr measure rate for pressure |
||||||
|
* @param prsOsr oversampling rate for pressure |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t startMeasureBothCont(uint8_t tempMr, uint8_t tempOsr, uint8_t prsMr, uint8_t prsOsr); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the interrupt status flag of the FIFO |
||||||
|
* |
||||||
|
* @return 1 if the FIFO is full and caused an interrupt |
||||||
|
* 0 if the FIFO is not full or FIFO interrupt is disabled |
||||||
|
* -1 on fail |
||||||
|
*/ |
||||||
|
int16_t getIntStatusFifoFull(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the interrupt status flag that indicates a finished temperature measurement |
||||||
|
* |
||||||
|
* @return 1 if a finished temperature measurement caused an interrupt; |
||||||
|
* 0 if there is no finished temperature measurement or interrupts are disabled; |
||||||
|
* -1 on fail. |
||||||
|
*/ |
||||||
|
int16_t getIntStatusTempReady(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the interrupt status flag that indicates a finished pressure measurement |
||||||
|
* |
||||||
|
* @return 1 if a finished pressure measurement caused an interrupt;
|
||||||
|
* 0 if there is no finished pressure measurement or interrupts are disabled; |
||||||
|
* -1 on fail. |
||||||
|
*/ |
||||||
|
int16_t getIntStatusPrsReady(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to fix a hardware problem on some devices |
||||||
|
* You have this problem if you measure a temperature which is too high (e.g. 60°C when temperature is around 20°C) |
||||||
|
* Call correctTemp() directly after begin() to fix this issue |
||||||
|
*/ |
||||||
|
int16_t correctTemp(void); |
||||||
|
|
||||||
|
protected: |
||||||
|
//scaling factor table
|
||||||
|
static const int32_t scaling_facts[DPS__NUM_OF_SCAL_FACTS]; |
||||||
|
|
||||||
|
dps::Mode m_opMode; |
||||||
|
|
||||||
|
//flags
|
||||||
|
uint8_t m_initFail; |
||||||
|
|
||||||
|
uint8_t m_productID; |
||||||
|
uint8_t m_revisionID; |
||||||
|
|
||||||
|
//settings
|
||||||
|
uint8_t m_tempMr; |
||||||
|
uint8_t m_tempOsr; |
||||||
|
uint8_t m_prsMr; |
||||||
|
uint8_t m_prsOsr; |
||||||
|
|
||||||
|
// compensation coefficients for both dps310 and dps422
|
||||||
|
int32_t m_c00; |
||||||
|
int32_t m_c10; |
||||||
|
int32_t m_c01; |
||||||
|
int32_t m_c11; |
||||||
|
int32_t m_c20; |
||||||
|
int32_t m_c21; |
||||||
|
int32_t m_c30; |
||||||
|
|
||||||
|
// last measured scaled temperature (necessary for pressure compensation)
|
||||||
|
float m_lastTempScal; |
||||||
|
|
||||||
|
//bus specific
|
||||||
|
uint8_t m_SpiI2c; //0=SPI, 1=I2C
|
||||||
|
|
||||||
|
//used for I2C
|
||||||
|
TwoWire *m_i2cbus; |
||||||
|
uint8_t m_slaveAddress; |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
//used for SPI
|
||||||
|
SPIClass *m_spibus; |
||||||
|
int32_t m_chipSelect; |
||||||
|
uint8_t m_threeWire; |
||||||
|
#endif |
||||||
|
/**
|
||||||
|
* Initializes the sensor. |
||||||
|
* This function has to be called from begin() |
||||||
|
* and requires a valid bus initialization. |
||||||
|
*/ |
||||||
|
virtual void init(void) = 0; |
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the compensation coefficients from the sensor |
||||||
|
* this is called once from init(), which is called from begin() |
||||||
|
* |
||||||
|
* @return 0 on success, -1 on fail |
||||||
|
*/ |
||||||
|
virtual int16_t readcoeffs(void) = 0; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Operation Mode of the sensor |
||||||
|
*
|
||||||
|
* @param opMode: the new OpMode as defined by dps::Mode; CMD_BOTH should not be used for DPS310 |
||||||
|
* @return 0 on success, -1 on fail |
||||||
|
*/ |
||||||
|
int16_t setOpMode(uint8_t opMode); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures temperature measurement |
||||||
|
* |
||||||
|
* @param temp_mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 |
||||||
|
* @param temp_osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 |
||||||
|
*
|
||||||
|
* @return 0 normally or -1 on fail |
||||||
|
*/ |
||||||
|
virtual int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures pressure measurement |
||||||
|
* |
||||||
|
* @param prs_mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 |
||||||
|
* @param prs_osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 |
||||||
|
* @return 0 normally or -1 on fail |
||||||
|
*/ |
||||||
|
virtual int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr); |
||||||
|
|
||||||
|
virtual int16_t flushFIFO() = 0; |
||||||
|
|
||||||
|
virtual float calcTemp(int32_t raw) = 0; |
||||||
|
|
||||||
|
virtual float calcPressure(int32_t raw) = 0; |
||||||
|
|
||||||
|
int16_t enableFIFO(); |
||||||
|
|
||||||
|
int16_t disableFIFO(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* calculates the time that the sensor needs for 2^mr measurements with an oversampling rate of 2^osr (see table "pressure measurement time (ms) versus oversampling rate") |
||||||
|
* Note that the total measurement time for temperature and pressure must not be more than 1 second. |
||||||
|
* Timing behavior of pressure and temperature sensors can be considered the same. |
||||||
|
*
|
||||||
|
* @param mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 |
||||||
|
* @param osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 |
||||||
|
* @return time that the sensor needs for this measurement |
||||||
|
*/ |
||||||
|
uint16_t calcBusyTime(uint16_t temp_rate, uint16_t temp_osr); |
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the next raw value from the FIFO |
||||||
|
* |
||||||
|
* @param value: the raw pressure or temperature value read from the pressure register blocks, where the LSB of PRS_B0 marks wheather the value is a temperatur or a pressure. |
||||||
|
*
|
||||||
|
* @return -1 on fail |
||||||
|
* 0 if result is a temperature raw value |
||||||
|
* 1 if result is a pressure raw value |
||||||
|
*/ |
||||||
|
int16_t getFIFOvalue(int32_t *value); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the results from continuous measurements and writes them to given arrays |
||||||
|
* |
||||||
|
* @param *tempBuffer: The start address of the buffer where the temperature results are written |
||||||
|
* If this is NULL, no temperature results will be written out |
||||||
|
* @param &tempCount: The size of the buffer for temperature results. |
||||||
|
* When the function ends, it will contain the number of bytes written to the buffer. |
||||||
|
* @param *prsBuffer: The start address of the buffer where the pressure results are written |
||||||
|
* If this is NULL, no pressure results will be written out |
||||||
|
* @param &prsCount: The size of the buffer for pressure results. |
||||||
|
* When the function ends, it will contain the number of bytes written to the buffer. |
||||||
|
* @param reg The FIFO empty register field; needed since this field is different for each sensor |
||||||
|
* @return status code |
||||||
|
*/ |
||||||
|
int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount, RegMask_t reg); |
||||||
|
|
||||||
|
/**
|
||||||
|
* reads a byte from the sensor |
||||||
|
* |
||||||
|
* @param regAdress: Address that has to be read |
||||||
|
* @return register content or -1 on fail |
||||||
|
*/ |
||||||
|
int16_t readByte(uint8_t regAddress); |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
/**
|
||||||
|
* reads a byte from the sensor via SPI |
||||||
|
* this function is automatically called by readByte |
||||||
|
* if the sensor is connected via SPI |
||||||
|
* |
||||||
|
* @param regAdress: Address that has to be read |
||||||
|
* @return register content or -1 on fail |
||||||
|
*/ |
||||||
|
int16_t readByteSPI(uint8_t regAddress); |
||||||
|
#endif |
||||||
|
/**
|
||||||
|
* reads a block from the sensor |
||||||
|
* |
||||||
|
* @param regAdress: Address that has to be read |
||||||
|
* @param length: Length of data block |
||||||
|
* @param buffer: Buffer where data will be stored |
||||||
|
* @return number of bytes that have been read successfully, which might not always equal to length due to rx-Buffer overflow etc. |
||||||
|
*/ |
||||||
|
int16_t readBlock(RegBlock_t regBlock, uint8_t *buffer); |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
/**
|
||||||
|
* reads a block from the sensor via SPI |
||||||
|
* |
||||||
|
* @param regAdress: Address that has to be read |
||||||
|
* @param length: Length of data block |
||||||
|
* @param readbuffer: Buffer where data will be stored |
||||||
|
* @return number of bytes that have been read successfully, which might not always equal to length due to rx-Buffer overflow etc. |
||||||
|
*/ |
||||||
|
int16_t readBlockSPI(RegBlock_t regBlock, uint8_t *readbuffer); |
||||||
|
#endif |
||||||
|
/**
|
||||||
|
* writes a byte to a given register of the sensor without checking |
||||||
|
* |
||||||
|
* @param regAdress: Address of the register that has to be updated |
||||||
|
* @param data: Byte that will be written to the register |
||||||
|
* @return 0 if byte was written successfully |
||||||
|
* or -1 on fail |
||||||
|
*/ |
||||||
|
int16_t writeByte(uint8_t regAddress, uint8_t data); |
||||||
|
|
||||||
|
/**
|
||||||
|
* writes a byte to a register of the sensor |
||||||
|
* |
||||||
|
* @param regAdress: Address of the register that has to be updated |
||||||
|
* @param data: Byte that will be written to the register |
||||||
|
* @param check: If this is true, register content will be read after writing |
||||||
|
* to check if update was successful |
||||||
|
* @return 0 if byte was written successfully |
||||||
|
* or -1 on fail |
||||||
|
*/ |
||||||
|
int16_t writeByte(uint8_t regAddress, uint8_t data, uint8_t check); |
||||||
|
|
||||||
|
#ifndef DPS_DISABLESPI |
||||||
|
/**
|
||||||
|
* writes a byte to a register of the sensor via SPI |
||||||
|
* |
||||||
|
* @param regAdress: Address of the register that has to be updated |
||||||
|
* @param data: Byte that will be written to the register |
||||||
|
* @param check: If this is true, register content will be read after writing |
||||||
|
* to check if update was successful |
||||||
|
* @return 0 if byte was written successfully |
||||||
|
* or -1 on fail |
||||||
|
*/ |
||||||
|
int16_t writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check); |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* updates a bit field of the sensor without checking |
||||||
|
* |
||||||
|
* @param regMask: Mask of the register that has to be updated |
||||||
|
* @param data: BitValues that will be written to the register |
||||||
|
* @return 0 if byte was written successfully |
||||||
|
* or -1 on fail |
||||||
|
*/ |
||||||
|
int16_t writeByteBitfield(uint8_t data, RegMask_t regMask); |
||||||
|
|
||||||
|
/**
|
||||||
|
* updates a bit field of the sensor |
||||||
|
* |
||||||
|
* regMask: Mask of the register that has to be updated |
||||||
|
* data: BitValues that will be written to the register |
||||||
|
* check: enables/disables check after writing; 0 disables check. |
||||||
|
* if check fails, -1 will be returned |
||||||
|
* @return 0 if byte was written successfully |
||||||
|
* or -1 on fail |
||||||
|
*/ |
||||||
|
int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift, uint8_t check); |
||||||
|
|
||||||
|
/**
|
||||||
|
* reads a bit field from the sensor |
||||||
|
* regMask: Mask of the register that has to be updated |
||||||
|
* data: BitValues that will be written to the register |
||||||
|
* @return read and processed bits |
||||||
|
* or -1 on fail |
||||||
|
*/ |
||||||
|
int16_t readByteBitfield(RegMask_t regMask); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief converts non-32-bit negative numbers to 32-bit negative numbers with 2's complement |
||||||
|
*
|
||||||
|
* @param raw The raw number of less than 32 bits |
||||||
|
* @param length The bit length |
||||||
|
*/ |
||||||
|
void getTwosComplement(int32_t *raw, uint8_t length); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a raw result from a given register block |
||||||
|
*
|
||||||
|
* @param raw The address where the raw value is to be written |
||||||
|
* @param reg The register block to be read from |
||||||
|
* @return status code
|
||||||
|
*/ |
||||||
|
int16_t getRawResult(int32_t *raw, RegBlock_t reg); |
||||||
|
}; |
||||||
|
|
||||||
|
#endif //DPSCLASS_H_INCLUDED
|
@ -0,0 +1,19 @@ |
|||||||
|
#ifndef DPSREGISTER_H_INCLUDED |
||||||
|
#define DPSREGISTER_H_INCLUDED |
||||||
|
|
||||||
|
#include <Arduino.h> |
||||||
|
|
||||||
|
typedef struct |
||||||
|
{ |
||||||
|
uint8_t regAddress; |
||||||
|
uint8_t mask; |
||||||
|
uint8_t shift; |
||||||
|
} RegMask_t; |
||||||
|
|
||||||
|
typedef struct |
||||||
|
{ |
||||||
|
uint8_t regAddress; |
||||||
|
uint8_t length; |
||||||
|
} RegBlock_t; |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,49 @@ |
|||||||
|
#ifndef DPS310_CONFIG_H_ |
||||||
|
#define DPS310_CONFIG_H_ |
||||||
|
|
||||||
|
#define DPS310_NUM_OF_REGMASKS 16 |
||||||
|
|
||||||
|
enum Interrupt_source_310_e |
||||||
|
{ |
||||||
|
DPS310_NO_INTR = 0, |
||||||
|
DPS310_PRS_INTR = 1, |
||||||
|
DPS310_TEMP_INTR = 2, |
||||||
|
DPS310_BOTH_INTR = 3, |
||||||
|
DPS310_FIFO_FULL_INTR = 4, |
||||||
|
}; |
||||||
|
|
||||||
|
namespace dps310 |
||||||
|
{ |
||||||
|
|
||||||
|
enum Registers_e |
||||||
|
{ |
||||||
|
PROD_ID = 0, |
||||||
|
REV_ID, |
||||||
|
TEMP_SENSOR, // internal vs external
|
||||||
|
TEMP_SENSORREC, //temperature sensor recommendation
|
||||||
|
TEMP_SE, //temperature shift enable (if temp_osr>3)
|
||||||
|
PRS_SE, //pressure shift enable (if prs_osr>3)
|
||||||
|
FIFO_FL, //FIFO flush
|
||||||
|
FIFO_EMPTY, //FIFO empty
|
||||||
|
FIFO_FULL, //FIFO full
|
||||||
|
INT_HL, |
||||||
|
INT_SEL, //interrupt select
|
||||||
|
}; |
||||||
|
|
||||||
|
const RegMask_t registers[DPS310_NUM_OF_REGMASKS] = { |
||||||
|
{0x0D, 0x0F, 0}, // PROD_ID
|
||||||
|
{0x0D, 0xF0, 4}, // REV_ID
|
||||||
|
{0x07, 0x80, 7}, // TEMP_SENSOR
|
||||||
|
{0x28, 0x80, 7}, // TEMP_SENSORREC
|
||||||
|
{0x09, 0x08, 3}, // TEMP_SE
|
||||||
|
{0x09, 0x04, 2}, // PRS_SE
|
||||||
|
{0x0C, 0x80, 7}, // FIFO_FL
|
||||||
|
{0x0B, 0x01, 0}, // FIFO_EMPTY
|
||||||
|
{0x0B, 0x02, 1}, // FIFO_FULL
|
||||||
|
{0x09, 0x80, 7}, // INT_HL
|
||||||
|
{0x09, 0x70, 4}, // INT_SEL
|
||||||
|
}; |
||||||
|
|
||||||
|
const RegBlock_t coeffBlock = {0x10, 18}; |
||||||
|
} // namespace dps310
|
||||||
|
#endif |
@ -0,0 +1,86 @@ |
|||||||
|
|
||||||
|
#ifndef DPS422_CONFIG_H_ |
||||||
|
#define DPS422_CONFIG_H_ |
||||||
|
|
||||||
|
// consts for temperature calculation
|
||||||
|
#define DPS422_T_REF 27 |
||||||
|
#define DPS422_V_BE_TARGET 0.687027 |
||||||
|
#define DPS422_ALPHA 9.45 |
||||||
|
#define DPS422_T_C_VBE -1.735e-3 |
||||||
|
#define DPS422_K_PTAT_CORNER -0.8 |
||||||
|
#define DPS422_K_PTAT_CURVATURE 0.039 |
||||||
|
#define DPS422_A_0 5030 |
||||||
|
|
||||||
|
#define DPS422_NUM_OF_REGMASKS 20 |
||||||
|
|
||||||
|
enum Interrupt_source_420_e |
||||||
|
{ |
||||||
|
DPS422_NO_INTR = 0, |
||||||
|
DPS422_PRS_INTR = 1, |
||||||
|
DPS422_TEMP_INTR = 2, |
||||||
|
DPS422_BOTH_INTR = 3, |
||||||
|
DPS422_FIFO_WM_INTR = 4, |
||||||
|
DPS422_FIFO_FULL_INTR = 8, |
||||||
|
}; |
||||||
|
|
||||||
|
namespace dps422 |
||||||
|
{ |
||||||
|
enum Registers_e |
||||||
|
{ |
||||||
|
// flags
|
||||||
|
CONT_FLAG = 0, // continuous mode flag
|
||||||
|
INIT_DONE, // set when initialisation procedure is complete
|
||||||
|
// interrupt config
|
||||||
|
INTR_SEL, // interrupt select
|
||||||
|
INTR_POL, // interrupt active polarity
|
||||||
|
// fifo config
|
||||||
|
WM, // watermark level
|
||||||
|
FIFO_FL, // FIFO flush
|
||||||
|
FIFO_EMPTY, // FIFO empty
|
||||||
|
FIFO_FULL, // if FIFO is full or reaches watermark level
|
||||||
|
FIFO_FULL_CONF, // Configures FIFO behaviour when full
|
||||||
|
FIFO_FILL_LEVEL, //contains the number of pressure and/or temperature measurements currently stored in FIFO
|
||||||
|
// misc
|
||||||
|
PROD_ID, |
||||||
|
REV_ID, |
||||||
|
SPI_MODE, // 4- or 3-wire SPI
|
||||||
|
SOFT_RESET, |
||||||
|
MUST_SET, // bit 7 of TEMP_CFG, according to datasheet should always be set
|
||||||
|
}; |
||||||
|
|
||||||
|
const RegMask_t registers[DPS422_NUM_OF_REGMASKS] = { |
||||||
|
// flags
|
||||||
|
{0x08, 0x40, 6}, // CONT_FLAG
|
||||||
|
{0x08, 0x80, 7}, // INIT_DONE
|
||||||
|
// interrupt config
|
||||||
|
{0x09, 0xF0, 4}, // INTR_SEL
|
||||||
|
{0x09, 0x80, 3}, // INTR_POL
|
||||||
|
// /fifo config
|
||||||
|
{0x0B, 0x1F, 0}, // WM
|
||||||
|
{0x0D, 0x80, 7}, // FIFO_FL
|
||||||
|
{0x0C, 0x01, 0}, // FIFO_EMPTY
|
||||||
|
{0x0C, 0x02, 1}, // FIFO_FULL
|
||||||
|
{0x09, 0x04, 2}, // FIFO_FULL_CONF
|
||||||
|
{0x0C, 0xFC, 2}, // FIFO_FILL_LEVEL
|
||||||
|
// misc
|
||||||
|
{0x1D, 0x0F, 0}, // PROD_ID
|
||||||
|
{0x1D, 0xF0, 0}, // REV_ID
|
||||||
|
{0x09, 0x01, 0}, // SPI_MODE
|
||||||
|
{0x0D, 0x0F, 0}, // SOFT_RESET
|
||||||
|
{0x07, 0x80, 7}, // MUST_SET
|
||||||
|
}; |
||||||
|
|
||||||
|
enum RegisterBlocks_e |
||||||
|
{ |
||||||
|
COEF_TEMP, // compensation coefficients
|
||||||
|
COEF_PRS, |
||||||
|
}; |
||||||
|
|
||||||
|
const RegBlock_t coeffBlocks[4] = { |
||||||
|
{0x20, 3}, |
||||||
|
{0x26, 20}, |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace dps422
|
||||||
|
|
||||||
|
#endif /* DPS422_CONSTS_H_ */ |
@ -0,0 +1,130 @@ |
|||||||
|
|
||||||
|
#ifndef DPS_CONSTS_H_ |
||||||
|
#define DPS_CONSTS_H_ |
||||||
|
#include "util/DpsRegister.h" |
||||||
|
|
||||||
|
/////////// DPS310 ///////////
|
||||||
|
#define DPS310__PROD_ID 0x00 |
||||||
|
#define DPS310__SPI_WRITE_CMD 0x00U |
||||||
|
#define DPS310__SPI_READ_CMD 0x80U |
||||||
|
#define DPS310__SPI_RW_MASK 0x80U |
||||||
|
#define DPS310__SPI_MAX_FREQ 1000000U |
||||||
|
|
||||||
|
#define DPS310__OSR_SE 3U |
||||||
|
|
||||||
|
// DPS310 has 10 milliseconds of spare time for each synchronous measurement / per second for asynchronous measurements
|
||||||
|
// this is for error prevention on friday-afternoon-products :D
|
||||||
|
// you can set it to 0 if you dare, but there is no warranty that it will still work
|
||||||
|
#define DPS310__BUSYTIME_FAILSAFE 10U |
||||||
|
#define DPS310__MAX_BUSYTIME ((1000U - DPS310__BUSYTIME_FAILSAFE) * DPS__BUSYTIME_SCALING) |
||||||
|
|
||||||
|
#define DPS310__REG_ADR_SPI3W 0x09U |
||||||
|
#define DPS310__REG_CONTENT_SPI3W 0x01U |
||||||
|
|
||||||
|
/////////// DPS422 ///////////
|
||||||
|
#define DPS422__PROD_ID 0x0A |
||||||
|
|
||||||
|
/////////// common ///////////
|
||||||
|
|
||||||
|
// slave address same for 422 and 310 (to be proved for future sensors)
|
||||||
|
#define DPS__FIFO_SIZE 32 |
||||||
|
#define DPS__STD_SLAVE_ADDRESS 0x77U |
||||||
|
#define DPS__RESULT_BLOCK_LENGTH 3 |
||||||
|
#define NUM_OF_COMMON_REGMASKS 16 |
||||||
|
|
||||||
|
#define DPS__MEASUREMENT_RATE_1 0 |
||||||
|
#define DPS__MEASUREMENT_RATE_2 1 |
||||||
|
#define DPS__MEASUREMENT_RATE_4 2 |
||||||
|
#define DPS__MEASUREMENT_RATE_8 3 |
||||||
|
#define DPS__MEASUREMENT_RATE_16 4 |
||||||
|
#define DPS__MEASUREMENT_RATE_32 5 |
||||||
|
#define DPS__MEASUREMENT_RATE_64 6 |
||||||
|
#define DPS__MEASUREMENT_RATE_128 7 |
||||||
|
|
||||||
|
#define DPS__OVERSAMPLING_RATE_1 DPS__MEASUREMENT_RATE_1 |
||||||
|
#define DPS__OVERSAMPLING_RATE_2 DPS__MEASUREMENT_RATE_2 |
||||||
|
#define DPS__OVERSAMPLING_RATE_4 DPS__MEASUREMENT_RATE_4 |
||||||
|
#define DPS__OVERSAMPLING_RATE_8 DPS__MEASUREMENT_RATE_8 |
||||||
|
#define DPS__OVERSAMPLING_RATE_16 DPS__MEASUREMENT_RATE_16 |
||||||
|
#define DPS__OVERSAMPLING_RATE_32 DPS__MEASUREMENT_RATE_32 |
||||||
|
#define DPS__OVERSAMPLING_RATE_64 DPS__MEASUREMENT_RATE_64 |
||||||
|
#define DPS__OVERSAMPLING_RATE_128 DPS__MEASUREMENT_RATE_128 |
||||||
|
|
||||||
|
//we use 0.1 ms units for time calculations, so 10 units are one millisecond
|
||||||
|
#define DPS__BUSYTIME_SCALING 10U |
||||||
|
|
||||||
|
#define DPS__NUM_OF_SCAL_FACTS 8 |
||||||
|
|
||||||
|
// status code
|
||||||
|
#define DPS__SUCCEEDED 0 |
||||||
|
#define DPS__FAIL_UNKNOWN -1 |
||||||
|
#define DPS__FAIL_INIT_FAILED -2 |
||||||
|
#define DPS__FAIL_TOOBUSY -3 |
||||||
|
#define DPS__FAIL_UNFINISHED -4 |
||||||
|
|
||||||
|
namespace dps |
||||||
|
{ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Operating mode. |
||||||
|
*
|
||||||
|
*/ |
||||||
|
enum Mode |
||||||
|
{ |
||||||
|
IDLE = 0x00, |
||||||
|
CMD_PRS = 0x01, |
||||||
|
CMD_TEMP = 0x02, |
||||||
|
CMD_BOTH = 0x03, // only for DPS422
|
||||||
|
CONT_PRS = 0x05, |
||||||
|
CONT_TMP = 0x06, |
||||||
|
CONT_BOTH = 0x07 |
||||||
|
}; |
||||||
|
|
||||||
|
enum RegisterBlocks_e |
||||||
|
{ |
||||||
|
PRS = 0, // pressure value
|
||||||
|
TEMP, // temperature value
|
||||||
|
}; |
||||||
|
|
||||||
|
const RegBlock_t registerBlocks[2] = { |
||||||
|
{0x00, 3}, |
||||||
|
{0x03, 3}, |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief registers for configuration and flags; these are the same for both 310 and 422, might need to be adapted for future sensors |
||||||
|
*
|
||||||
|
*/ |
||||||
|
enum Config_Registers_e |
||||||
|
{ |
||||||
|
TEMP_MR = 0, // temperature measure rate
|
||||||
|
TEMP_OSR, // temperature measurement resolution
|
||||||
|
PRS_MR, // pressure measure rate
|
||||||
|
PRS_OSR, // pressure measurement resolution
|
||||||
|
MSR_CTRL, // measurement control
|
||||||
|
FIFO_EN, |
||||||
|
|
||||||
|
TEMP_RDY, |
||||||
|
PRS_RDY, |
||||||
|
INT_FLAG_FIFO, |
||||||
|
INT_FLAG_TEMP, |
||||||
|
INT_FLAG_PRS, |
||||||
|
}; |
||||||
|
|
||||||
|
const RegMask_t config_registers[NUM_OF_COMMON_REGMASKS] = { |
||||||
|
{0x07, 0x70, 4}, // TEMP_MR
|
||||||
|
{0x07, 0x07, 0}, // TEMP_OSR
|
||||||
|
{0x06, 0x70, 4}, // PRS_MR
|
||||||
|
{0x06, 0x07, 0}, // PRS_OSR
|
||||||
|
{0x08, 0x07, 0}, // MSR_CTRL
|
||||||
|
{0x09, 0x02, 1}, // FIFO_EN
|
||||||
|
|
||||||
|
{0x08, 0x20, 5}, // TEMP_RDY
|
||||||
|
{0x08, 0x10, 4}, // PRS_RDY
|
||||||
|
{0x0A, 0x04, 2}, // INT_FLAG_FIFO
|
||||||
|
{0x0A, 0x02, 1}, // INT_FLAG_TEMP
|
||||||
|
{0x0A, 0x01, 0}, // INT_FLAG_PRS
|
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace dps
|
||||||
|
#endif /* DPS_CONSTS_H_ */ |
Loading…
Reference in new issue